* 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:
parent
d2e1e87261
commit
b14a49c9bd
@ -7,6 +7,10 @@
|
||||
* René Gollent
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <AppFileInfo.h>
|
||||
#include <Application.h>
|
||||
@ -14,6 +18,7 @@
|
||||
#include <File.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Font.h>
|
||||
#include <fs_attr.h>
|
||||
#include <MessageRunner.h>
|
||||
#include <Messenger.h>
|
||||
#include <OS.h>
|
||||
@ -24,7 +29,6 @@
|
||||
#include <ScrollView.h>
|
||||
#include <String.h>
|
||||
#include <StringView.h>
|
||||
#include <TextView.h>
|
||||
#include <TranslationUtils.h>
|
||||
#include <TranslatorFormats.h>
|
||||
#include <View.h>
|
||||
@ -32,11 +36,13 @@
|
||||
#include <VolumeRoster.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include <AppMisc.h>
|
||||
#include <AutoDeleter.h>
|
||||
#include <cpu_type.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <sys/utsname.h>
|
||||
#include "HyperTextActions.h"
|
||||
#include "HyperTextView.h"
|
||||
#include "Utilities.h"
|
||||
|
||||
|
||||
#define SCROLL_CREDITS_VIEW 'mviv'
|
||||
@ -78,15 +84,20 @@ class AboutView : public BView {
|
||||
virtual void MessageReceived(BMessage *msg);
|
||||
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,
|
||||
const char *url = NULL);
|
||||
void AddCopyrightEntry(const BMessage& packageDescription);
|
||||
void PickRandomHaiku();
|
||||
|
||||
private:
|
||||
void _AddCopyrightsFromAttribute();
|
||||
|
||||
BStringView *fMemView;
|
||||
BStringView *fUptimeView;
|
||||
BView *fInfoView;
|
||||
BTextView *fCreditsView;
|
||||
HyperTextView *fCreditsView;
|
||||
|
||||
BBitmap *fLogo;
|
||||
|
||||
@ -318,7 +329,7 @@ AboutView::AboutView(const BRect &rect)
|
||||
r.left += fInfoView->Bounds().right + 1;
|
||||
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);
|
||||
fCreditsView->SetFlags(fCreditsView->Flags() | B_FRAME_EVENTS );
|
||||
fCreditsView->SetStylable(true);
|
||||
@ -352,7 +363,9 @@ AboutView::AboutView(const BRect &rect)
|
||||
fCreditsView->Insert(string);
|
||||
|
||||
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->Insert("Team Leads:\n");
|
||||
@ -507,7 +520,8 @@ AboutView::AboutView(const BRect &rect)
|
||||
"gdb, wget, ncurses, termcap, "
|
||||
"Bourne Again Shell.\n"
|
||||
"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
|
||||
AddCopyrightEntry("The FreeBSD Project",
|
||||
@ -516,7 +530,7 @@ AboutView::AboutView(const BRect &rect)
|
||||
"ping, telnet, telnetd, traceroute\n"
|
||||
"Copyright " B_UTF8_COPYRIGHT " 1994-2008 The FreeBSD Project. "
|
||||
"All rights reserved.",
|
||||
"www.freebsd.org");
|
||||
"http://www.freebsd.org");
|
||||
|
||||
// NetBSD copyrights
|
||||
AddCopyrightEntry("The NetBSD Project",
|
||||
@ -525,36 +539,36 @@ AboutView::AboutView(const BRect &rect)
|
||||
"ftp\n"
|
||||
"Copyright " B_UTF8_COPYRIGHT " 1996-2008 The NetBSD Foundation, Inc. "
|
||||
"All rights reserved.",
|
||||
"www.netbsd.org");
|
||||
"http://www.netbsd.org");
|
||||
|
||||
// FFMpeg copyrights
|
||||
AddCopyrightEntry("FFMpeg libavcodec",
|
||||
"Copyright " B_UTF8_COPYRIGHT " 2000-2007 Fabrice Bellard, et al.",
|
||||
"www.ffmpeg.org");
|
||||
"http://www.ffmpeg.org");
|
||||
|
||||
// AGG copyrights
|
||||
AddCopyrightEntry("AntiGrain Geometry",
|
||||
"Copyright " B_UTF8_COPYRIGHT " 2002-2006 Maxim Shemanarev (McSeem).",
|
||||
"www.antigrain.com");
|
||||
"http://www.antigrain.com");
|
||||
|
||||
// PDFLib copyrights
|
||||
AddCopyrightEntry("PDFLib",
|
||||
"Copyright " B_UTF8_COPYRIGHT " 1997-2006 PDFlib GmbH and Thomas Merz. "
|
||||
"All rights reserved.\n"
|
||||
"PDFlib and PDFlib logo are registered trademarks of PDFlib GmbH.",
|
||||
"www.pdflib.com");
|
||||
"http://www.pdflib.com");
|
||||
|
||||
// FreeType copyrights
|
||||
AddCopyrightEntry("FreeType2",
|
||||
"Portions of this software are copyright " B_UTF8_COPYRIGHT " 1996-2006 "
|
||||
"The FreeType Project. All rights reserved.",
|
||||
"www.freetype.org");
|
||||
"http://www.freetype.org");
|
||||
|
||||
// Mesa3D (http://www.mesa3d.org) copyrights
|
||||
AddCopyrightEntry("Mesa",
|
||||
"Copyright " B_UTF8_COPYRIGHT " 1999-2006 Brian Paul. "
|
||||
"Mesa3D project. All rights reserved.",
|
||||
"www.mesa3d.org");
|
||||
"http://www.mesa3d.org");
|
||||
|
||||
// SGI's GLU implementation copyrights
|
||||
AddCopyrightEntry("GLU",
|
||||
@ -619,7 +633,7 @@ AboutView::AboutView(const BRect &rect)
|
||||
// Bullet copyrights
|
||||
AddCopyrightEntry("Bullet",
|
||||
"Copyright " B_UTF8_COPYRIGHT " 2003-2008 Erwin Coumans",
|
||||
"www.bulletphysics.com");
|
||||
"http://www.bulletphysics.com");
|
||||
|
||||
// atftp copyrights
|
||||
AddCopyrightEntry("atftp",
|
||||
@ -673,12 +687,14 @@ AboutView::AboutView(const BRect &rect)
|
||||
AddCopyrightEntry("Xiph.org Foundation",
|
||||
"libvorbis, libogg, libtheora, libspeex"
|
||||
"Copyright " B_UTF8_COPYRIGHT " 1994-2008 Xiph.Org. All rights "
|
||||
"reserved.", "www.xiph.org");
|
||||
"reserved.", "http://www.xiph.org");
|
||||
|
||||
// The Tcpdump Group
|
||||
AddCopyrightEntry("The Tcpdump Group",
|
||||
"tcpdump, libpcap",
|
||||
"www.tcpdump.org");
|
||||
"http://www.tcpdump.org");
|
||||
|
||||
_AddCopyrightsFromAttribute();
|
||||
|
||||
// Build a list of installed applications and show their
|
||||
// long version info. Well-behaved apps usually give
|
||||
@ -848,6 +864,14 @@ AboutView::MessageReceived(BMessage *msg)
|
||||
void
|
||||
AboutView::AddCopyrightEntry(const char *name, const char *text,
|
||||
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);
|
||||
//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->Insert(text);
|
||||
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) {
|
||||
fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kLinkBlue);
|
||||
fCreditsView->Insert(url);
|
||||
fCreditsView->InsertHyperText(url, new URLAction(url));
|
||||
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
|
||||
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 -
|
||||
|
||||
|
||||
|
74
src/apps/aboutsystem/HyperTextActions.cpp
Normal file
74
src/apps/aboutsystem/HyperTextActions.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* 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);
|
||||
}
|
37
src/apps/aboutsystem/HyperTextActions.h
Normal file
37
src/apps/aboutsystem/HyperTextActions.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* 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
|
162
src/apps/aboutsystem/HyperTextView.cpp
Normal file
162
src/apps/aboutsystem/HyperTextView.cpp
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* 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);
|
||||
}
|
56
src/apps/aboutsystem/HyperTextView.h
Normal file
56
src/apps/aboutsystem/HyperTextView.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* 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 ;
|
||||
|
||||
UsePrivateHeaders shared ;
|
||||
UsePrivateHeaders app shared ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
@ -16,6 +16,9 @@ if $(TARGET_PLATFORM) = dano {
|
||||
|
||||
Application AboutSystem :
|
||||
AboutSystem.cpp
|
||||
HyperTextActions.cpp
|
||||
HyperTextView.cpp
|
||||
Utilities.cpp
|
||||
: be translation
|
||||
: AboutSystem.rdef
|
||||
;
|
||||
|
107
src/apps/aboutsystem/Utilities.cpp
Normal file
107
src/apps/aboutsystem/Utilities.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* 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);
|
||||
}
|
36
src/apps/aboutsystem/Utilities.h
Normal file
36
src/apps/aboutsystem/Utilities.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* 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
|
Loading…
Reference in New Issue
Block a user