mirror of
https://review.haiku-os.org/haiku
synced 2025-02-22 21:48:35 +01:00
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@pulkomandy.tk> 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:
parent
a5a3b2d9a3
commit
632e56d8e5
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user