hrev50089 adds 1 changeset to branch 'master'
old head: a5a3b2d9a3d95cbae71eaf371708c73a1780ac0d
new head: 632e56d8e514ba6ac41f582ce580e51a3cd8922e
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=632e56d8e514+%5Ea5a3b2d9a3d9
----------------------------------------------------------------------------
632e56d8e514: URL linkification in People
url and email label are now marked as a link and open the address
in the browser/mail-app on click
Signed-off-by: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Fixes #3825
A few extra changes from the original patch:
- Remove "smart" parsing (detection of "ftp", etc) as it could lead to
ftp://ftp://url or other strangeness,
- Add gopher protocol, because mmu_man may have an home page there.
[ Alexander Sulfrian <alexander@xxxxxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev50089
Commit: 632e56d8e514ba6ac41f582ce580e51a3cd8922e
URL: http://cgit.haiku-os.org/haiku/commit/?id=632e56d8e514
Author: Alexander Sulfrian <alexander@xxxxxxxxxxxx>
Date: Fri Apr 6 15:08:15 2012 UTC
Committer: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Commit-Date: Sun Feb 14 13:28:38 2016 UTC
Ticket: https://dev.haiku-os.org/ticket/3825
----------------------------------------------------------------------------
2 files changed, 128 insertions(+), 1 deletion(-)
src/apps/people/AttributeTextControl.cpp | 116 ++++++++++++++++++++++++++-
src/apps/people/AttributeTextControl.h | 13 +++
----------------------------------------------------------------------------
diff --git a/src/apps/people/AttributeTextControl.cpp
b/src/apps/people/AttributeTextControl.cpp
index e3197f6..7142d48 100644
--- a/src/apps/people/AttributeTextControl.cpp
+++ b/src/apps/people/AttributeTextControl.cpp
@@ -15,13 +15,17 @@
#include <string.h>
#include <malloc.h>
-#include <Font.h>
#include <Catalog.h>
+#include <Cursor.h>
+#include <Font.h>
+#include <Roster.h>
+#include <StorageKit.h>
#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<char**>(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<char**>(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 2374353..b1d55aa 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();
@@ -29,6 +32,16 @@ public:
{
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;
};