xref: /haiku/src/apps/people/AttributeTextControl.cpp (revision bab64f65bb775dc23060e276f1f1c4498ab7af6c)
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