1 /* 2 * Copyright 2005-2012, Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * Robert Polic 7 * 8 * Copyright 1999, Be Incorporated. All Rights Reserved. 9 * This file may be used under the terms of the Be Sample Code License. 10 */ 11 12 13 #include "AttributeTextControl.h" 14 15 #include <string.h> 16 #include <malloc.h> 17 18 #include <Catalog.h> 19 #include <Cursor.h> 20 #include <Font.h> 21 #include <Roster.h> 22 #include <StorageKit.h> 23 24 25 #undef B_TRANSLATION_CONTEXT 26 #define B_TRANSLATION_CONTEXT "People" 27 28 #define B_URL_MIME "application/x-vnd.Be.URL." 29 30 AttributeTextControl::AttributeTextControl(const char* label, 31 const char* attribute) 32 : 33 BTextControl(NULL, "", NULL), 34 fAttribute(attribute), 35 fOriginalValue() 36 { 37 if (label != NULL && label[0] != 0) { 38 SetLabel(BString(B_TRANSLATE("%attribute_label:")) 39 .ReplaceFirst("%attribute_label", label)); 40 } 41 SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT); 42 } 43 44 45 AttributeTextControl::~AttributeTextControl() 46 { 47 } 48 49 void 50 AttributeTextControl::MouseDown(BPoint mousePosition) 51 { 52 if(_VisibleLabelBounds().Contains(mousePosition) && _ContainsUrl()) 53 _HandleLabelClicked(Text()); 54 else 55 BTextControl::MouseDown(mousePosition); 56 } 57 58 59 void 60 AttributeTextControl::MouseMoved(BPoint mousePosition, uint32 transit, const BMessage* dragMessage) 61 { 62 if (_VisibleLabelBounds().Contains(mousePosition) && _ContainsUrl()) { 63 BCursor linkCursor(B_CURSOR_ID_FOLLOW_LINK); 64 SetViewCursor(&linkCursor, true); 65 } else 66 SetViewCursor(B_CURSOR_SYSTEM_DEFAULT, true); 67 68 BTextControl::MouseMoved(mousePosition, transit, dragMessage); 69 } 70 71 72 bool 73 AttributeTextControl::HasChanged() 74 { 75 return fOriginalValue != Text(); 76 } 77 78 79 void 80 AttributeTextControl::Revert() 81 { 82 if (HasChanged()) 83 SetText(fOriginalValue); 84 } 85 86 87 void 88 AttributeTextControl::Update() 89 { 90 fOriginalValue = Text(); 91 } 92 93 94 void 95 AttributeTextControl::_HandleLabelClicked(const char *text) 96 { 97 BString argument(text); 98 99 if (Attribute() == "META:url") { 100 _MakeUniformUrl(argument); 101 102 BString mimeType = B_URL_MIME; 103 _BuildMimeString(mimeType, argument); 104 105 if (mimeType != "") { 106 const char *args[] = {argument.String(), 0}; 107 be_roster->Launch(mimeType.String(), 1, const_cast<char**>(args)); 108 } 109 } else if (Attribute() == "META:email") { 110 if (argument.IFindFirst("mailto:") != 0 && argument != "") 111 argument.Prepend("mailto:"); 112 113 // TODO: Could check for possible e-mail patterns. 114 if (argument != "") { 115 const char *args[] = {argument.String(), 0}; 116 be_roster->Launch("text/x-email", 1, const_cast<char**>(args)); 117 } 118 } 119 } 120 121 122 const BString& 123 AttributeTextControl::_MakeUniformUrl(BString &url) const 124 { 125 if (url.StartsWith("www")) 126 url.Prepend("http://"); 127 else if (url.StartsWith("ftp.")) 128 url.Prepend("ftp://"); 129 130 return url; 131 } 132 133 134 const BString& 135 AttributeTextControl::_BuildMimeString(BString &mimeType, const BString &url) 136 const 137 { 138 if (url.IFindFirst("http://") == 0 || url.IFindFirst("ftp://") == 0 139 || url.IFindFirst("https://") || url.IFindFirst("gopher://") == 0) { 140 141 mimeType.Append(url, url.FindFirst(':')); 142 } 143 144 if (!BMimeType::IsValid(mimeType.String())) 145 mimeType = ""; 146 147 return mimeType; 148 } 149 150 151 bool 152 AttributeTextControl::_ContainsUrl() const 153 { 154 BString argument(Text()); 155 156 if (Attribute() == "META:url") { 157 BString mimeType = B_URL_MIME; 158 if (_BuildMimeString(mimeType, _MakeUniformUrl(argument)) != "") 159 return true; 160 } 161 else if (Attribute() == "META:email") { 162 if (argument != "") 163 return true; 164 } 165 166 return false; 167 } 168 169 170 BRect 171 AttributeTextControl::_VisibleLabelBounds() const 172 { 173 // TODO: Could actually check current alignment of the label. 174 // The code below works only for right aligned labels. 175 BRect bounds(Bounds()); 176 bounds.right = Divider(); 177 bounds.left = bounds.right - StringWidth(Label()); 178 return bounds; 179 } 180