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 <[email protected]> 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.
This commit is contained in:
committed by
Adrien Destugues
parent
a5a3b2d9a3
commit
632e56d8e5
@@ -15,13 +15,17 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
#include <Font.h>
|
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
|
#include <Cursor.h>
|
||||||
|
#include <Font.h>
|
||||||
|
#include <Roster.h>
|
||||||
|
#include <StorageKit.h>
|
||||||
|
|
||||||
|
|
||||||
#undef B_TRANSLATION_CONTEXT
|
#undef B_TRANSLATION_CONTEXT
|
||||||
#define B_TRANSLATION_CONTEXT "People"
|
#define B_TRANSLATION_CONTEXT "People"
|
||||||
|
|
||||||
|
#define B_URL_MIME "application/x-vnd.Be.URL."
|
||||||
|
|
||||||
AttributeTextControl::AttributeTextControl(const char* label,
|
AttributeTextControl::AttributeTextControl(const char* label,
|
||||||
const char* attribute)
|
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
|
bool
|
||||||
AttributeTextControl::HasChanged()
|
AttributeTextControl::HasChanged()
|
||||||
@@ -63,3 +89,91 @@ AttributeTextControl::Update()
|
|||||||
{
|
{
|
||||||
fOriginalValue = Text();
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ public:
|
|||||||
const char* attribute);
|
const char* attribute);
|
||||||
virtual ~AttributeTextControl();
|
virtual ~AttributeTextControl();
|
||||||
|
|
||||||
|
virtual void MouseDown(BPoint);
|
||||||
|
virtual void MouseMoved(BPoint, uint32, const BMessage*);
|
||||||
|
|
||||||
bool HasChanged();
|
bool HasChanged();
|
||||||
void Revert();
|
void Revert();
|
||||||
void Update();
|
void Update();
|
||||||
@@ -28,6 +31,16 @@ public:
|
|||||||
const BString& Attribute() const
|
const BString& Attribute() const
|
||||||
{ return fAttribute; }
|
{ 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:
|
private:
|
||||||
BString fAttribute;
|
BString fAttribute;
|
||||||
BString fOriginalValue;
|
BString fOriginalValue;
|
||||||
|
|||||||
Reference in New Issue
Block a user