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
AttributeTextControl(const char * label,const char * attribute)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
~AttributeTextControl()45 AttributeTextControl::~AttributeTextControl()
46 {
47 }
48
49 void
MouseDown(BPoint mousePosition)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
MouseMoved(BPoint mousePosition,uint32 transit,const BMessage * dragMessage)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
HasChanged()73 AttributeTextControl::HasChanged()
74 {
75 return fOriginalValue != Text();
76 }
77
78
79 void
Revert()80 AttributeTextControl::Revert()
81 {
82 if (HasChanged())
83 SetText(fOriginalValue);
84 }
85
86
87 void
Update()88 AttributeTextControl::Update()
89 {
90 fOriginalValue = Text();
91 }
92
93
94 void
_HandleLabelClicked(const char * text)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&
_MakeUniformUrl(BString & url) const123 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&
_BuildMimeString(BString & mimeType,const BString & url) const135 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
_ContainsUrl() const152 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
_VisibleLabelBounds() const171 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