* Added BTextView derived class HyperTextView, which allows for
associating text with an action performed when clicked. Very bare-bones, but sufficient for our purposes. * Turned all URLs into proper URLs (i.e. prepended "http://" where missing). * Added new AboutView::AddCopyrightEntry() versions. One can take an additional licenses list, the other extracts all info from a supplied BMessage. * The displayed licenses and URLs are hyperlinks now. Clicking the former opens the license file in /etc/licenses, the latter try to open a browser (works with NetPositive at least). * The "COPYRIGHTS" attribute of the executable can contain descriptions of optional packages. Those are read, parsed, and added as copyright entries. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25049 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -7,6 +7,10 @@
|
|||||||
* René Gollent
|
* René Gollent
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include <AppFileInfo.h>
|
#include <AppFileInfo.h>
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
@@ -14,6 +18,7 @@
|
|||||||
#include <File.h>
|
#include <File.h>
|
||||||
#include <FindDirectory.h>
|
#include <FindDirectory.h>
|
||||||
#include <Font.h>
|
#include <Font.h>
|
||||||
|
#include <fs_attr.h>
|
||||||
#include <MessageRunner.h>
|
#include <MessageRunner.h>
|
||||||
#include <Messenger.h>
|
#include <Messenger.h>
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
@@ -24,7 +29,6 @@
|
|||||||
#include <ScrollView.h>
|
#include <ScrollView.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <StringView.h>
|
#include <StringView.h>
|
||||||
#include <TextView.h>
|
|
||||||
#include <TranslationUtils.h>
|
#include <TranslationUtils.h>
|
||||||
#include <TranslatorFormats.h>
|
#include <TranslatorFormats.h>
|
||||||
#include <View.h>
|
#include <View.h>
|
||||||
@@ -32,11 +36,13 @@
|
|||||||
#include <VolumeRoster.h>
|
#include <VolumeRoster.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include <AppMisc.h>
|
||||||
|
#include <AutoDeleter.h>
|
||||||
#include <cpu_type.h>
|
#include <cpu_type.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "HyperTextActions.h"
|
||||||
#include <time.h>
|
#include "HyperTextView.h"
|
||||||
#include <sys/utsname.h>
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
|
||||||
#define SCROLL_CREDITS_VIEW 'mviv'
|
#define SCROLL_CREDITS_VIEW 'mviv'
|
||||||
@@ -78,15 +84,20 @@ class AboutView : public BView {
|
|||||||
virtual void MessageReceived(BMessage *msg);
|
virtual void MessageReceived(BMessage *msg);
|
||||||
virtual void MouseDown(BPoint pt);
|
virtual void MouseDown(BPoint pt);
|
||||||
|
|
||||||
|
void AddCopyrightEntry(const char *name, const char *text,
|
||||||
|
const Licenses& licenses, const char *url);
|
||||||
void AddCopyrightEntry(const char *name, const char *text,
|
void AddCopyrightEntry(const char *name, const char *text,
|
||||||
const char *url = NULL);
|
const char *url = NULL);
|
||||||
|
void AddCopyrightEntry(const BMessage& packageDescription);
|
||||||
void PickRandomHaiku();
|
void PickRandomHaiku();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void _AddCopyrightsFromAttribute();
|
||||||
|
|
||||||
BStringView *fMemView;
|
BStringView *fMemView;
|
||||||
BStringView *fUptimeView;
|
BStringView *fUptimeView;
|
||||||
BView *fInfoView;
|
BView *fInfoView;
|
||||||
BTextView *fCreditsView;
|
HyperTextView *fCreditsView;
|
||||||
|
|
||||||
BBitmap *fLogo;
|
BBitmap *fLogo;
|
||||||
|
|
||||||
@@ -318,7 +329,7 @@ AboutView::AboutView(const BRect &rect)
|
|||||||
r.left += fInfoView->Bounds().right + 1;
|
r.left += fInfoView->Bounds().right + 1;
|
||||||
r.right -= B_V_SCROLL_BAR_WIDTH;
|
r.right -= B_V_SCROLL_BAR_WIDTH;
|
||||||
|
|
||||||
fCreditsView = new BTextView(r, "credits",
|
fCreditsView = new HyperTextView(r, "credits",
|
||||||
r.OffsetToCopy(0, 0).InsetByCopy(5, 5), B_FOLLOW_ALL);
|
r.OffsetToCopy(0, 0).InsetByCopy(5, 5), B_FOLLOW_ALL);
|
||||||
fCreditsView->SetFlags(fCreditsView->Flags() | B_FRAME_EVENTS );
|
fCreditsView->SetFlags(fCreditsView->Flags() | B_FRAME_EVENTS );
|
||||||
fCreditsView->SetStylable(true);
|
fCreditsView->SetStylable(true);
|
||||||
@@ -352,7 +363,9 @@ AboutView::AboutView(const BRect &rect)
|
|||||||
fCreditsView->Insert(string);
|
fCreditsView->Insert(string);
|
||||||
|
|
||||||
fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kLinkBlue);
|
fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kLinkBlue);
|
||||||
fCreditsView->Insert("http://haiku-os.org\n\n");
|
fCreditsView->InsertHyperText("http://haiku-os.org",
|
||||||
|
new URLAction("http://haiku-os.org"));
|
||||||
|
fCreditsView->Insert("\n\n");
|
||||||
|
|
||||||
fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange);
|
fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange);
|
||||||
fCreditsView->Insert("Team Leads:\n");
|
fCreditsView->Insert("Team Leads:\n");
|
||||||
@@ -507,7 +520,8 @@ AboutView::AboutView(const BRect &rect)
|
|||||||
"gdb, wget, ncurses, termcap, "
|
"gdb, wget, ncurses, termcap, "
|
||||||
"Bourne Again Shell.\n"
|
"Bourne Again Shell.\n"
|
||||||
"Copyright " B_UTF8_COPYRIGHT " The Free Software Foundation.",
|
"Copyright " B_UTF8_COPYRIGHT " The Free Software Foundation.",
|
||||||
"www.gnu.org");
|
Licenses("GNU LGPL v2.1", "GNU GPL v2", "GNU GPL v3", NULL),
|
||||||
|
"http://www.gnu.org");
|
||||||
|
|
||||||
// FreeBSD copyrights
|
// FreeBSD copyrights
|
||||||
AddCopyrightEntry("The FreeBSD Project",
|
AddCopyrightEntry("The FreeBSD Project",
|
||||||
@@ -516,7 +530,7 @@ AboutView::AboutView(const BRect &rect)
|
|||||||
"ping, telnet, telnetd, traceroute\n"
|
"ping, telnet, telnetd, traceroute\n"
|
||||||
"Copyright " B_UTF8_COPYRIGHT " 1994-2008 The FreeBSD Project. "
|
"Copyright " B_UTF8_COPYRIGHT " 1994-2008 The FreeBSD Project. "
|
||||||
"All rights reserved.",
|
"All rights reserved.",
|
||||||
"www.freebsd.org");
|
"http://www.freebsd.org");
|
||||||
|
|
||||||
// NetBSD copyrights
|
// NetBSD copyrights
|
||||||
AddCopyrightEntry("The NetBSD Project",
|
AddCopyrightEntry("The NetBSD Project",
|
||||||
@@ -525,36 +539,36 @@ AboutView::AboutView(const BRect &rect)
|
|||||||
"ftp\n"
|
"ftp\n"
|
||||||
"Copyright " B_UTF8_COPYRIGHT " 1996-2008 The NetBSD Foundation, Inc. "
|
"Copyright " B_UTF8_COPYRIGHT " 1996-2008 The NetBSD Foundation, Inc. "
|
||||||
"All rights reserved.",
|
"All rights reserved.",
|
||||||
"www.netbsd.org");
|
"http://www.netbsd.org");
|
||||||
|
|
||||||
// FFMpeg copyrights
|
// FFMpeg copyrights
|
||||||
AddCopyrightEntry("FFMpeg libavcodec",
|
AddCopyrightEntry("FFMpeg libavcodec",
|
||||||
"Copyright " B_UTF8_COPYRIGHT " 2000-2007 Fabrice Bellard, et al.",
|
"Copyright " B_UTF8_COPYRIGHT " 2000-2007 Fabrice Bellard, et al.",
|
||||||
"www.ffmpeg.org");
|
"http://www.ffmpeg.org");
|
||||||
|
|
||||||
// AGG copyrights
|
// AGG copyrights
|
||||||
AddCopyrightEntry("AntiGrain Geometry",
|
AddCopyrightEntry("AntiGrain Geometry",
|
||||||
"Copyright " B_UTF8_COPYRIGHT " 2002-2006 Maxim Shemanarev (McSeem).",
|
"Copyright " B_UTF8_COPYRIGHT " 2002-2006 Maxim Shemanarev (McSeem).",
|
||||||
"www.antigrain.com");
|
"http://www.antigrain.com");
|
||||||
|
|
||||||
// PDFLib copyrights
|
// PDFLib copyrights
|
||||||
AddCopyrightEntry("PDFLib",
|
AddCopyrightEntry("PDFLib",
|
||||||
"Copyright " B_UTF8_COPYRIGHT " 1997-2006 PDFlib GmbH and Thomas Merz. "
|
"Copyright " B_UTF8_COPYRIGHT " 1997-2006 PDFlib GmbH and Thomas Merz. "
|
||||||
"All rights reserved.\n"
|
"All rights reserved.\n"
|
||||||
"PDFlib and PDFlib logo are registered trademarks of PDFlib GmbH.",
|
"PDFlib and PDFlib logo are registered trademarks of PDFlib GmbH.",
|
||||||
"www.pdflib.com");
|
"http://www.pdflib.com");
|
||||||
|
|
||||||
// FreeType copyrights
|
// FreeType copyrights
|
||||||
AddCopyrightEntry("FreeType2",
|
AddCopyrightEntry("FreeType2",
|
||||||
"Portions of this software are copyright " B_UTF8_COPYRIGHT " 1996-2006 "
|
"Portions of this software are copyright " B_UTF8_COPYRIGHT " 1996-2006 "
|
||||||
"The FreeType Project. All rights reserved.",
|
"The FreeType Project. All rights reserved.",
|
||||||
"www.freetype.org");
|
"http://www.freetype.org");
|
||||||
|
|
||||||
// Mesa3D (http://www.mesa3d.org) copyrights
|
// Mesa3D (http://www.mesa3d.org) copyrights
|
||||||
AddCopyrightEntry("Mesa",
|
AddCopyrightEntry("Mesa",
|
||||||
"Copyright " B_UTF8_COPYRIGHT " 1999-2006 Brian Paul. "
|
"Copyright " B_UTF8_COPYRIGHT " 1999-2006 Brian Paul. "
|
||||||
"Mesa3D project. All rights reserved.",
|
"Mesa3D project. All rights reserved.",
|
||||||
"www.mesa3d.org");
|
"http://www.mesa3d.org");
|
||||||
|
|
||||||
// SGI's GLU implementation copyrights
|
// SGI's GLU implementation copyrights
|
||||||
AddCopyrightEntry("GLU",
|
AddCopyrightEntry("GLU",
|
||||||
@@ -619,7 +633,7 @@ AboutView::AboutView(const BRect &rect)
|
|||||||
// Bullet copyrights
|
// Bullet copyrights
|
||||||
AddCopyrightEntry("Bullet",
|
AddCopyrightEntry("Bullet",
|
||||||
"Copyright " B_UTF8_COPYRIGHT " 2003-2008 Erwin Coumans",
|
"Copyright " B_UTF8_COPYRIGHT " 2003-2008 Erwin Coumans",
|
||||||
"www.bulletphysics.com");
|
"http://www.bulletphysics.com");
|
||||||
|
|
||||||
// atftp copyrights
|
// atftp copyrights
|
||||||
AddCopyrightEntry("atftp",
|
AddCopyrightEntry("atftp",
|
||||||
@@ -673,12 +687,14 @@ AboutView::AboutView(const BRect &rect)
|
|||||||
AddCopyrightEntry("Xiph.org Foundation",
|
AddCopyrightEntry("Xiph.org Foundation",
|
||||||
"libvorbis, libogg, libtheora, libspeex"
|
"libvorbis, libogg, libtheora, libspeex"
|
||||||
"Copyright " B_UTF8_COPYRIGHT " 1994-2008 Xiph.Org. All rights "
|
"Copyright " B_UTF8_COPYRIGHT " 1994-2008 Xiph.Org. All rights "
|
||||||
"reserved.", "www.xiph.org");
|
"reserved.", "http://www.xiph.org");
|
||||||
|
|
||||||
// The Tcpdump Group
|
// The Tcpdump Group
|
||||||
AddCopyrightEntry("The Tcpdump Group",
|
AddCopyrightEntry("The Tcpdump Group",
|
||||||
"tcpdump, libpcap",
|
"tcpdump, libpcap",
|
||||||
"www.tcpdump.org");
|
"http://www.tcpdump.org");
|
||||||
|
|
||||||
|
_AddCopyrightsFromAttribute();
|
||||||
|
|
||||||
// Build a list of installed applications and show their
|
// Build a list of installed applications and show their
|
||||||
// long version info. Well-behaved apps usually give
|
// long version info. Well-behaved apps usually give
|
||||||
@@ -848,6 +864,14 @@ AboutView::MessageReceived(BMessage *msg)
|
|||||||
void
|
void
|
||||||
AboutView::AddCopyrightEntry(const char *name, const char *text,
|
AboutView::AddCopyrightEntry(const char *name, const char *text,
|
||||||
const char *url)
|
const char *url)
|
||||||
|
{
|
||||||
|
AddCopyrightEntry(name, text, NULL, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AboutView::AddCopyrightEntry(const char *name, const char *text,
|
||||||
|
const Licenses& licenses, const char *url)
|
||||||
{
|
{
|
||||||
BFont font(be_bold_font);
|
BFont font(be_bold_font);
|
||||||
//font.SetSize(be_bold_font->Size());
|
//font.SetSize(be_bold_font->Size());
|
||||||
@@ -859,14 +883,61 @@ AboutView::AddCopyrightEntry(const char *name, const char *text,
|
|||||||
fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey);
|
fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey);
|
||||||
fCreditsView->Insert(text);
|
fCreditsView->Insert(text);
|
||||||
fCreditsView->Insert("\n");
|
fCreditsView->Insert("\n");
|
||||||
|
|
||||||
|
if (licenses.CountLicenses() > 0) {
|
||||||
|
if (licenses.CountLicenses() > 1)
|
||||||
|
fCreditsView->Insert("Licenses: ");
|
||||||
|
else
|
||||||
|
fCreditsView->Insert("License: ");
|
||||||
|
|
||||||
|
for (int32 i = 0; i < licenses.CountLicenses(); i++) {
|
||||||
|
const char* license = licenses.LicenseAt(i);
|
||||||
|
BString licensePath("/etc/licenses/");
|
||||||
|
licensePath += license;
|
||||||
|
|
||||||
|
if (i > 0)
|
||||||
|
fCreditsView->Insert(", ");
|
||||||
|
|
||||||
|
fCreditsView->InsertHyperText(license,
|
||||||
|
new OpenFileAction(licensePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
fCreditsView->Insert("\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kLinkBlue);
|
fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kLinkBlue);
|
||||||
fCreditsView->Insert(url);
|
fCreditsView->InsertHyperText(url, new URLAction(url));
|
||||||
fCreditsView->Insert("\n");
|
fCreditsView->Insert("\n");
|
||||||
}
|
}
|
||||||
fCreditsView->Insert("\n");
|
fCreditsView->Insert("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AboutView::AddCopyrightEntry(const BMessage& packageDescription)
|
||||||
|
{
|
||||||
|
const char* package;
|
||||||
|
const char* copyright;
|
||||||
|
const char* url;
|
||||||
|
|
||||||
|
// package and copyright are mandatory
|
||||||
|
if (packageDescription.FindString("Package", &package) != B_OK
|
||||||
|
|| packageDescription.FindString("Copyright", ©right) != B_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL is optional
|
||||||
|
if (packageDescription.FindString("URL", &url) != B_OK)
|
||||||
|
url = NULL;
|
||||||
|
|
||||||
|
BString copyrightLine("Copyright " B_UTF8_COPYRIGHT " ");
|
||||||
|
copyrightLine += copyright;
|
||||||
|
|
||||||
|
AddCopyrightEntry(package, copyrightLine.String(), packageDescription, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AboutView::PickRandomHaiku()
|
AboutView::PickRandomHaiku()
|
||||||
{
|
{
|
||||||
@@ -918,6 +989,91 @@ AboutView::PickRandomHaiku()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AboutView::_AddCopyrightsFromAttribute()
|
||||||
|
{
|
||||||
|
// open the app executable file
|
||||||
|
char appPath[B_PATH_NAME_LENGTH];
|
||||||
|
int appFD;
|
||||||
|
if (BPrivate::get_app_path(appPath) != B_OK
|
||||||
|
|| (appFD = open(appPath, O_RDONLY)) < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// open the attribute
|
||||||
|
int attrFD = fs_open_attr(appFD, "COPYRIGHTS", B_STRING_TYPE, O_RDONLY);
|
||||||
|
close(appFD);
|
||||||
|
if (attrFD < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// attach it to a FILE
|
||||||
|
FILE* attrFile = fdopen(attrFD, "r");
|
||||||
|
if (attrFile == NULL) {
|
||||||
|
close(attrFD);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CObjectDeleter<FILE, int> _(attrFile, fclose);
|
||||||
|
|
||||||
|
// read and parse the copyrights
|
||||||
|
BMessage package;
|
||||||
|
BString fieldName;
|
||||||
|
BString fieldValue;
|
||||||
|
char lineBuffer[LINE_MAX];
|
||||||
|
while (char* line = fgets(lineBuffer, sizeof(lineBuffer), attrFile)) {
|
||||||
|
// chop off line break
|
||||||
|
size_t lineLen = strlen(line);
|
||||||
|
if (lineLen > 0 && line[lineLen - 1] == '\n')
|
||||||
|
line[--lineLen] = '\0';
|
||||||
|
|
||||||
|
// flush previous field, if a new field begins, otherwise append
|
||||||
|
if (lineLen == 0 || !isspace(line[0])) {
|
||||||
|
// new field -- flush the previous one
|
||||||
|
if (fieldName.Length() > 0) {
|
||||||
|
fieldValue = trim_string(fieldValue.String(),
|
||||||
|
fieldValue.Length());
|
||||||
|
package.AddString(fieldName.String(), fieldValue);
|
||||||
|
fieldName = "";
|
||||||
|
}
|
||||||
|
} else if (fieldName.Length() > 0) {
|
||||||
|
// append to current field
|
||||||
|
fieldValue += line;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// bogus line -- ignore
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lineLen == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// parse new field
|
||||||
|
char* colon = strchr(line, ':');
|
||||||
|
if (colon == NULL) {
|
||||||
|
// bogus line -- ignore
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldName.SetTo(line, colon - line);
|
||||||
|
fieldName = trim_string(line, colon - line);
|
||||||
|
if (fieldName.Length() == 0) {
|
||||||
|
// invalid field name
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldValue = colon + 1;
|
||||||
|
|
||||||
|
if (fieldName == "Package") {
|
||||||
|
// flush the current package
|
||||||
|
AddCopyrightEntry(package);
|
||||||
|
package.MakeEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// flush current package
|
||||||
|
AddCopyrightEntry(package);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "HyperTextActions.h"
|
||||||
|
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <Roster.h>
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - URLAction
|
||||||
|
|
||||||
|
|
||||||
|
URLAction::URLAction(const BString& url)
|
||||||
|
:
|
||||||
|
fURL(url)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
URLAction::~URLAction()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
URLAction::Clicked(HyperTextView* view, BPoint where, BMessage* message)
|
||||||
|
{
|
||||||
|
// be lazy and let /bin/open open the URL
|
||||||
|
entry_ref ref;
|
||||||
|
if (get_ref_for_path("/bin/open", &ref))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char* args[] = { "/bin/open", fURL.String(), NULL };
|
||||||
|
be_roster->Launch(&ref, 2, args);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - OpenFileAction
|
||||||
|
|
||||||
|
|
||||||
|
OpenFileAction::OpenFileAction(const BString& file)
|
||||||
|
:
|
||||||
|
fFile(file)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OpenFileAction::~OpenFileAction()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
OpenFileAction::Clicked(HyperTextView* view, BPoint where, BMessage* message)
|
||||||
|
{
|
||||||
|
// get the entry ref and let Tracker open the file
|
||||||
|
entry_ref ref;
|
||||||
|
if (get_ref_for_path(fFile.String(), &ref) != B_OK
|
||||||
|
|| !BEntry(&ref).Exists()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessenger tracker("application/x-vnd.Be-TRAK");
|
||||||
|
if (tracker.IsValid()) {
|
||||||
|
BMessage message(B_REFS_RECEIVED);
|
||||||
|
message.AddRef("refs", &ref);
|
||||||
|
tracker.SendMessage(&message);
|
||||||
|
} else
|
||||||
|
be_roster->Launch(&ref);
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT license.
|
||||||
|
*/
|
||||||
|
#ifndef HYPER_TEXT_ACTIONS_H
|
||||||
|
#define HYPER_TEXT_ACTIONS_H
|
||||||
|
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
#include "HyperTextView.h"
|
||||||
|
|
||||||
|
|
||||||
|
class URLAction : public HyperTextAction {
|
||||||
|
public:
|
||||||
|
URLAction(const BString& url);
|
||||||
|
virtual ~URLAction();
|
||||||
|
|
||||||
|
virtual void Clicked(HyperTextView* view, BPoint where,
|
||||||
|
BMessage* message);
|
||||||
|
private:
|
||||||
|
BString fURL;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class OpenFileAction : public HyperTextAction {
|
||||||
|
public:
|
||||||
|
OpenFileAction(const BString& file);
|
||||||
|
virtual ~OpenFileAction();
|
||||||
|
|
||||||
|
virtual void Clicked(HyperTextView* view, BPoint where,
|
||||||
|
BMessage* message);
|
||||||
|
private:
|
||||||
|
BString fFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HYPER_TEXT_ACTIONS_H
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "HyperTextView.h"
|
||||||
|
|
||||||
|
#include <Message.h>
|
||||||
|
#include <Region.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include <ObjectList.h>
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - HyperTextAction
|
||||||
|
|
||||||
|
|
||||||
|
HyperTextAction::HyperTextAction()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HyperTextAction::~HyperTextAction()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
HyperTextAction::Clicked(HyperTextView* view, BPoint where, BMessage* message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - HyperTextView
|
||||||
|
|
||||||
|
|
||||||
|
struct HyperTextView::ActionInfo {
|
||||||
|
ActionInfo(int32 startOffset, int32 endOffset, HyperTextAction* action)
|
||||||
|
:
|
||||||
|
startOffset(startOffset),
|
||||||
|
endOffset(endOffset),
|
||||||
|
action(action)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~ActionInfo()
|
||||||
|
{
|
||||||
|
delete action;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Compare(const ActionInfo* a, const ActionInfo* b)
|
||||||
|
{
|
||||||
|
return a->startOffset - b->startOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CompareEqualIfIntersecting(const ActionInfo* a,
|
||||||
|
const ActionInfo* b)
|
||||||
|
{
|
||||||
|
if (a->startOffset < b->endOffset && b->startOffset < a->endOffset)
|
||||||
|
return 0;
|
||||||
|
return a->startOffset - b->startOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 startOffset;
|
||||||
|
int32 endOffset;
|
||||||
|
HyperTextAction* action;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class HyperTextView::ActionInfoList
|
||||||
|
: public BObjectList<HyperTextView::ActionInfo> {
|
||||||
|
public:
|
||||||
|
ActionInfoList(int32 itemsPerBlock = 20, bool owning = false)
|
||||||
|
: BObjectList<HyperTextView::ActionInfo>(itemsPerBlock, owning)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
HyperTextView::HyperTextView(BRect frame, const char* name, BRect textRect,
|
||||||
|
uint32 resizeMask, uint32 flags)
|
||||||
|
:
|
||||||
|
BTextView(frame, name, textRect, resizeMask, flags),
|
||||||
|
fActionInfos(new ActionInfoList(100, true))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HyperTextView::~HyperTextView()
|
||||||
|
{
|
||||||
|
delete fActionInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
HyperTextView::MouseDown(BPoint where)
|
||||||
|
{
|
||||||
|
// We eat all mouse button events.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
HyperTextView::MouseUp(BPoint where)
|
||||||
|
{
|
||||||
|
BMessage* message = Window()->CurrentMessage();
|
||||||
|
|
||||||
|
int32 offset = OffsetAt(where);
|
||||||
|
|
||||||
|
ActionInfo pointer(offset, offset + 1, NULL);
|
||||||
|
|
||||||
|
const ActionInfo* action = fActionInfos->BinarySearch(pointer,
|
||||||
|
ActionInfo::CompareEqualIfIntersecting);
|
||||||
|
if (action != NULL) {
|
||||||
|
// verify that the text region was hit
|
||||||
|
BRegion textRegion;
|
||||||
|
GetTextRegion(action->startOffset, action->endOffset, &textRegion);
|
||||||
|
if (textRegion.Contains(where))
|
||||||
|
action->action->Clicked(this, where, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
HyperTextView::AddHyperTextAction(int32 startOffset, int32 endOffset,
|
||||||
|
HyperTextAction* action)
|
||||||
|
{
|
||||||
|
if (action == NULL || startOffset >= endOffset) {
|
||||||
|
delete action;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fActionInfos->BinaryInsert(new ActionInfo(startOffset, endOffset, action),
|
||||||
|
ActionInfo::Compare);
|
||||||
|
|
||||||
|
// TODO: Of course we should check for overlaps...
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
HyperTextView::InsertHyperText(const char* inText, HyperTextAction* action,
|
||||||
|
const text_run_array* inRuns)
|
||||||
|
{
|
||||||
|
int32 startOffset = TextLength();
|
||||||
|
Insert(inText, inRuns);
|
||||||
|
int32 endOffset = TextLength();
|
||||||
|
|
||||||
|
AddHyperTextAction(startOffset, endOffset, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
HyperTextView::InsertHyperText(const char* inText, int32 inLength,
|
||||||
|
HyperTextAction* action, const text_run_array* inRuns)
|
||||||
|
{
|
||||||
|
int32 startOffset = TextLength();
|
||||||
|
Insert(inText, inLength, inRuns);
|
||||||
|
int32 endOffset = TextLength();
|
||||||
|
|
||||||
|
AddHyperTextAction(startOffset, endOffset, action);
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT license.
|
||||||
|
*/
|
||||||
|
#ifndef HYPER_TEXT_VIEW_H
|
||||||
|
#define HYPER_TEXT_VIEW_H
|
||||||
|
|
||||||
|
#include <TextView.h>
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: The current implementation works correctly only for insertions at the
|
||||||
|
// end of the text. It doesn't keep track of any other insertions or deletions.
|
||||||
|
|
||||||
|
|
||||||
|
class HyperTextView;
|
||||||
|
|
||||||
|
|
||||||
|
class HyperTextAction {
|
||||||
|
public:
|
||||||
|
HyperTextAction();
|
||||||
|
virtual ~HyperTextAction();
|
||||||
|
|
||||||
|
virtual void Clicked(HyperTextView* view, BPoint where,
|
||||||
|
BMessage* message);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class HyperTextView : public BTextView {
|
||||||
|
public:
|
||||||
|
HyperTextView(BRect frame, const char* name,
|
||||||
|
BRect textRect, uint32 resizeMask,
|
||||||
|
uint32 flags = B_WILL_DRAW
|
||||||
|
| B_PULSE_NEEDED);
|
||||||
|
virtual ~HyperTextView();
|
||||||
|
|
||||||
|
virtual void MouseDown(BPoint where);
|
||||||
|
virtual void MouseUp(BPoint where);
|
||||||
|
|
||||||
|
void AddHyperTextAction(int32 startOffset,
|
||||||
|
int32 endOffset, HyperTextAction* action);
|
||||||
|
|
||||||
|
void InsertHyperText(const char* inText,
|
||||||
|
HyperTextAction* action,
|
||||||
|
const text_run_array* inRuns = NULL);
|
||||||
|
void InsertHyperText(const char* inText,
|
||||||
|
int32 inLength, HyperTextAction* action,
|
||||||
|
const text_run_array* inRuns = NULL);
|
||||||
|
private:
|
||||||
|
struct ActionInfo;
|
||||||
|
class ActionInfoList;
|
||||||
|
|
||||||
|
ActionInfoList* fActionInfos;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HYPER_TEXT_VIEW_H
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
SubDir HAIKU_TOP src apps aboutsystem ;
|
SubDir HAIKU_TOP src apps aboutsystem ;
|
||||||
|
|
||||||
UsePrivateHeaders shared ;
|
UsePrivateHeaders app shared ;
|
||||||
|
|
||||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
|
||||||
@@ -16,6 +16,9 @@ if $(TARGET_PLATFORM) = dano {
|
|||||||
|
|
||||||
Application AboutSystem :
|
Application AboutSystem :
|
||||||
AboutSystem.cpp
|
AboutSystem.cpp
|
||||||
|
HyperTextActions.cpp
|
||||||
|
HyperTextView.cpp
|
||||||
|
Utilities.cpp
|
||||||
: be translation
|
: be translation
|
||||||
: AboutSystem.rdef
|
: AboutSystem.rdef
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <Message.h>
|
||||||
|
|
||||||
|
|
||||||
|
BString
|
||||||
|
trim_string(const char* string, size_t len)
|
||||||
|
{
|
||||||
|
BString trimmed;
|
||||||
|
size_t i = 0;
|
||||||
|
bool addSpace = false;
|
||||||
|
|
||||||
|
while (i < len) {
|
||||||
|
// skip space block
|
||||||
|
while (i < len && isspace(string[i]))
|
||||||
|
i++;
|
||||||
|
|
||||||
|
// write non-spaced (if any)
|
||||||
|
if (i < len && !isspace(string[i])) {
|
||||||
|
// pad with a single space, for all but the first block
|
||||||
|
if (addSpace)
|
||||||
|
trimmed << ' ';
|
||||||
|
else
|
||||||
|
addSpace = true;
|
||||||
|
|
||||||
|
// append chars
|
||||||
|
while (i < len && !isspace(string[i]))
|
||||||
|
trimmed << string[i++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return trimmed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - Licenses
|
||||||
|
|
||||||
|
|
||||||
|
Licenses::Licenses(const char* license,...)
|
||||||
|
:
|
||||||
|
fLicenses(NULL),
|
||||||
|
fCount(0)
|
||||||
|
{
|
||||||
|
if (license == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
va_list list;
|
||||||
|
|
||||||
|
// count licenses
|
||||||
|
va_start(list, license);
|
||||||
|
fCount = 1;
|
||||||
|
while (va_arg(list, const char*) != NULL)
|
||||||
|
fCount++;
|
||||||
|
va_end(list);
|
||||||
|
|
||||||
|
// create array and copy them
|
||||||
|
fLicenses = new BString[fCount];
|
||||||
|
fLicenses[0] = license;
|
||||||
|
|
||||||
|
va_start(list, license);
|
||||||
|
for (int32 i = 1; i < fCount; i++)
|
||||||
|
fLicenses[i] = va_arg(list, const char*);
|
||||||
|
va_end(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Licenses::Licenses(const BMessage& licenses)
|
||||||
|
:
|
||||||
|
fLicenses(NULL),
|
||||||
|
fCount(0)
|
||||||
|
{
|
||||||
|
type_code type;
|
||||||
|
int32 count;
|
||||||
|
if (licenses.GetInfo("License", &type, &count) != B_OK
|
||||||
|
|| type != B_STRING_TYPE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fLicenses = new BString[count];
|
||||||
|
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
if (licenses.FindString("License", i, &fLicenses[i]) != B_OK)
|
||||||
|
return;
|
||||||
|
fCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Licenses::~Licenses()
|
||||||
|
{
|
||||||
|
delete[] fLicenses;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
Licenses::LicenseAt(int32 index) const
|
||||||
|
{
|
||||||
|
return (index >= 0 && index < fCount ? fLicenses[index].String() : NULL);
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT license.
|
||||||
|
*/
|
||||||
|
#ifndef UTILITIES_H
|
||||||
|
#define UTILITIES_H
|
||||||
|
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
|
||||||
|
class BMessage;
|
||||||
|
|
||||||
|
|
||||||
|
BString trim_string(const char* string, size_t len);
|
||||||
|
// Removes leading and trailing white space and replaces all sequences
|
||||||
|
// of white space by a single space.
|
||||||
|
|
||||||
|
|
||||||
|
class Licenses {
|
||||||
|
public:
|
||||||
|
Licenses(const char* license,...);
|
||||||
|
// NULL terminated list
|
||||||
|
Licenses(const BMessage& licenses);
|
||||||
|
// all elements of field "License"
|
||||||
|
~Licenses();
|
||||||
|
|
||||||
|
int32 CountLicenses() const { return fCount; }
|
||||||
|
const char* LicenseAt(int32 index) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BString* fLicenses;
|
||||||
|
int32 fCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // UTILITIES_H
|
||||||
Reference in New Issue
Block a user