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
30AttributeTextControl::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
45AttributeTextControl::~AttributeTextControl()
46{
47}
48
49void
50AttributeTextControl::MouseDown(BPoint mousePosition)
51{
52	if(_VisibleLabelBounds().Contains(mousePosition) && _ContainsUrl())
53		_HandleLabelClicked(Text());
54	else
55		BTextControl::MouseDown(mousePosition);
56}
57
58
59void
60AttributeTextControl::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
72bool
73AttributeTextControl::HasChanged()
74{
75	return fOriginalValue != Text();
76}
77
78
79void
80AttributeTextControl::Revert()
81{
82	if (HasChanged())
83		SetText(fOriginalValue);
84}
85
86
87void
88AttributeTextControl::Update()
89{
90	fOriginalValue = Text();
91}
92
93
94void
95AttributeTextControl::_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
122const BString&
123AttributeTextControl::_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
134const BString&
135AttributeTextControl::_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
151bool
152AttributeTextControl::_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
170BRect
171AttributeTextControl::_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