diff --git a/src/apps/people/AttributeTextControl.cpp b/src/apps/people/AttributeTextControl.cpp index e3197f6bfd..7142d48c25 100644 --- a/src/apps/people/AttributeTextControl.cpp +++ b/src/apps/people/AttributeTextControl.cpp @@ -15,13 +15,17 @@ #include #include -#include #include +#include +#include +#include +#include #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "People" +#define B_URL_MIME "application/x-vnd.Be.URL." AttributeTextControl::AttributeTextControl(const char* label, const char* attribute) @@ -42,6 +46,28 @@ AttributeTextControl::~AttributeTextControl() { } +void +AttributeTextControl::MouseDown(BPoint mousePosition) +{ + if(_VisibleLabelBounds().Contains(mousePosition) && _ContainsUrl()) + _HandleLabelClicked(Text()); + else + BTextControl::MouseDown(mousePosition); +} + + +void +AttributeTextControl::MouseMoved(BPoint mousePosition, uint32 transit, const BMessage* dragMessage) +{ + if (_VisibleLabelBounds().Contains(mousePosition) && _ContainsUrl()) { + BCursor linkCursor(B_CURSOR_ID_FOLLOW_LINK); + SetViewCursor(&linkCursor, true); + } else + SetViewCursor(B_CURSOR_SYSTEM_DEFAULT, true); + + BTextControl::MouseMoved(mousePosition, transit, dragMessage); +} + bool AttributeTextControl::HasChanged() @@ -63,3 +89,91 @@ AttributeTextControl::Update() { fOriginalValue = Text(); } + + +void +AttributeTextControl::_HandleLabelClicked(const char *text) +{ + BString argument(text); + + if (Attribute() == "META:url") { + _MakeUniformUrl(argument); + + BString mimeType = B_URL_MIME; + _BuildMimeString(mimeType, argument); + + if (mimeType != "") { + const char *args[] = {argument.String(), 0}; + be_roster->Launch(mimeType.String(), 1, const_cast(args)); + } + } else if (Attribute() == "META:email") { + if (argument.IFindFirst("mailto:") != 0 && argument != "") + argument.Prepend("mailto:"); + + // TODO: Could check for possible e-mail patterns. + if (argument != "") { + const char *args[] = {argument.String(), 0}; + be_roster->Launch("text/x-email", 1, const_cast(args)); + } + } +} + + +const BString& +AttributeTextControl::_MakeUniformUrl(BString &url) const +{ + if (url.StartsWith("www")) + url.Prepend("http://"); + else if (url.StartsWith("ftp.")) + url.Prepend("ftp://"); + + return url; +} + + +const BString& +AttributeTextControl::_BuildMimeString(BString &mimeType, const BString &url) + const +{ + if (url.IFindFirst("http://") == 0 || url.IFindFirst("ftp://") == 0 + || url.IFindFirst("https://") || url.IFindFirst("gopher://") == 0) { + + mimeType.Append(url, url.FindFirst(':')); + } + + if (!BMimeType::IsValid(mimeType.String())) + mimeType = ""; + + return mimeType; +} + + +bool +AttributeTextControl::_ContainsUrl() const +{ + BString argument(Text()); + + if (Attribute() == "META:url") { + BString mimeType = B_URL_MIME; + if (_BuildMimeString(mimeType, _MakeUniformUrl(argument)) != "") + return true; + } + else if (Attribute() == "META:email") { + if (argument != "") + return true; + } + + return false; +} + + +BRect +AttributeTextControl::_VisibleLabelBounds() const +{ + // TODO: Could actually check current alignment of the label. + // The code below works only for right aligned labels. + BRect bounds(Bounds()); + bounds.right = Divider(); + bounds.left = bounds.right - StringWidth(Label()); + return bounds; +} diff --git a/src/apps/people/AttributeTextControl.h b/src/apps/people/AttributeTextControl.h index 23743530a4..b1d55aade6 100644 --- a/src/apps/people/AttributeTextControl.h +++ b/src/apps/people/AttributeTextControl.h @@ -21,6 +21,9 @@ public: const char* attribute); virtual ~AttributeTextControl(); + virtual void MouseDown(BPoint); + virtual void MouseMoved(BPoint, uint32, const BMessage*); + bool HasChanged(); void Revert(); void Update(); @@ -28,6 +31,16 @@ public: const BString& Attribute() const { return fAttribute; } +private: + const BString& _MakeUniformUrl(BString &url) const; + const BString& _BuildMimeString(BString &mimeType, + const BString &url) const; + + bool _ContainsUrl() const; + + BRect _VisibleLabelBounds() const; + void _HandleLabelClicked(const char*); + private: BString fAttribute; BString fOriginalValue;