diff --git a/src/apps/haikudepot/textview/TextDocument.cpp b/src/apps/haikudepot/textview/TextDocument.cpp index ba4faa0aba..73114fd9f3 100644 --- a/src/apps/haikudepot/textview/TextDocument.cpp +++ b/src/apps/haikudepot/textview/TextDocument.cpp @@ -180,6 +180,48 @@ TextDocument::CharacterStyleAt(int32 textOffset) const } +const BMessage* +TextDocument::ClickMessageAt(int32 textOffset) const +{ + int32 paragraphOffset; + const Paragraph& paragraph = ParagraphAt(textOffset, paragraphOffset); + + textOffset -= paragraphOffset; + int32 index; + int32 count = paragraph.CountTextSpans(); + + for (index = 0; index < count; index++) { + const TextSpan& span = paragraph.TextSpanAtIndex(index); + if (textOffset - span.CountChars() < 0) + return span.ClickMessage(); + textOffset -= span.CountChars(); + } + + return NULL; +} + + +BCursor +TextDocument::CursorAt(int32 textOffset) const +{ + int32 paragraphOffset; + const Paragraph& paragraph = ParagraphAt(textOffset, paragraphOffset); + + textOffset -= paragraphOffset; + int32 index; + int32 count = paragraph.CountTextSpans(); + + for (index = 0; index < count; index++) { + const TextSpan& span = paragraph.TextSpanAtIndex(index); + if (textOffset - span.CountChars() < 0) + return span.Cursor(); + textOffset -= span.CountChars(); + } + + return BCursor((BMessage*)NULL); +} + + const ParagraphStyle& TextDocument::ParagraphStyleAt(int32 textOffset) const { diff --git a/src/apps/haikudepot/textview/TextDocument.h b/src/apps/haikudepot/textview/TextDocument.h index 5cb838487e..a36dc95467 100644 --- a/src/apps/haikudepot/textview/TextDocument.h +++ b/src/apps/haikudepot/textview/TextDocument.h @@ -55,6 +55,8 @@ public: // Style access const CharacterStyle& CharacterStyleAt(int32 textOffset) const; const ParagraphStyle& ParagraphStyleAt(int32 textOffset) const; + BCursor CursorAt(int32 textOffset) const; + const BMessage* ClickMessageAt(int32 textOffset) const; int32 CountParagraphs() const; const Paragraph& ParagraphAtIndex(int32 index) const; diff --git a/src/apps/haikudepot/textview/TextDocumentView.cpp b/src/apps/haikudepot/textview/TextDocumentView.cpp index e474646766..379d0b872f 100644 --- a/src/apps/haikudepot/textview/TextDocumentView.cpp +++ b/src/apps/haikudepot/textview/TextDocumentView.cpp @@ -137,14 +137,28 @@ TextDocumentView::MakeFocus(bool focus) void TextDocumentView::MouseDown(BPoint where) { + BMessage* currentMessage = NULL; + if (Window() != NULL) + currentMessage = Window()->CurrentMessage(); + + // First of all, check for links and other clickable things + bool unused; + int32 offset = fTextDocumentLayout.TextOffsetAt(where.x, where.y, unused); + const BMessage* message = fTextDocument->ClickMessageAt(offset); + if (message != NULL) { + BMessage clickMessage(*message); + clickMessage.Append(*currentMessage); + Invoke(&clickMessage); + } + if (!fSelectionEnabled) return; MakeFocus(); int32 modifiers = 0; - if (Window() != NULL && Window()->CurrentMessage() != NULL) - Window()->CurrentMessage()->FindInt32("modifiers", &modifiers); + if (currentMessage != NULL) + currentMessage->FindInt32("modifiers", &modifiers); fMouseDown = true; SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); @@ -165,11 +179,22 @@ void TextDocumentView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) { + BCursor cursor(B_CURSOR_ID_I_BEAM); + + if (transit != B_EXITED_VIEW) { + bool unused; + int32 offset = fTextDocumentLayout.TextOffsetAt(where.x, where.y, unused); + const BCursor& newCursor = fTextDocument->CursorAt(offset); + if (newCursor.InitCheck() == B_OK) { + cursor = newCursor; + SetViewCursor(&cursor); + } + } + if (!fSelectionEnabled) return; - BCursor iBeamCursor(B_CURSOR_ID_I_BEAM); - SetViewCursor(&iBeamCursor); + SetViewCursor(&cursor); if (fMouseDown) SetCaret(where, true); diff --git a/src/apps/haikudepot/textview/TextDocumentView.h b/src/apps/haikudepot/textview/TextDocumentView.h index c5b8c705a4..ffd33e340a 100644 --- a/src/apps/haikudepot/textview/TextDocumentView.h +++ b/src/apps/haikudepot/textview/TextDocumentView.h @@ -5,6 +5,7 @@ #ifndef TEXT_DOCUMENT_VIEW_H #define TEXT_DOCUMENT_VIEW_H +#include #include #include @@ -17,7 +18,7 @@ class BClipboard; class BMessageRunner; -class TextDocumentView : public BView { +class TextDocumentView : public BView, public BInvoker { public: TextDocumentView(const char* name = NULL); virtual ~TextDocumentView(); diff --git a/src/apps/haikudepot/textview/TextSpan.cpp b/src/apps/haikudepot/textview/TextSpan.cpp index f9fbd588e1..504b0426ed 100644 --- a/src/apps/haikudepot/textview/TextSpan.cpp +++ b/src/apps/haikudepot/textview/TextSpan.cpp @@ -10,7 +10,9 @@ TextSpan::TextSpan() : fText(), fCharCount(0), - fStyle() + fStyle(), + fCursor((BMessage*)NULL), + fClickMessage() { } @@ -19,7 +21,9 @@ TextSpan::TextSpan(const BString& text, const CharacterStyle& style) : fText(text), fCharCount(text.CountChars()), - fStyle(style) + fStyle(style), + fCursor((BMessage*)NULL), + fClickMessage() { } @@ -28,7 +32,9 @@ TextSpan::TextSpan(const TextSpan& other) : fText(other.fText), fCharCount(other.fCharCount), - fStyle(other.fStyle) + fStyle(other.fStyle), + fCursor(other.fCursor), + fClickMessage(other.fClickMessage) { } @@ -39,6 +45,8 @@ TextSpan::operator=(const TextSpan& other) fText = other.fText; fCharCount = other.fCharCount; fStyle = other.fStyle; + fCursor = other.fCursor; + fClickMessage = other.fClickMessage; return *this; } @@ -49,7 +57,10 @@ TextSpan::operator==(const TextSpan& other) const { return fCharCount == other.fCharCount && fStyle == other.fStyle - && fText == other.fText; + && fText == other.fText + && fCursor == other.fCursor + && fClickMessage.what == other.fClickMessage.what + && fClickMessage.HasSameData(other.fClickMessage); } @@ -75,6 +86,20 @@ TextSpan::SetStyle(const CharacterStyle& style) } +void +TextSpan::SetCursor(const BCursor& cursor) +{ + fCursor = cursor; +} + + +void +TextSpan::SetClickMessage(BMessage* message) +{ + fClickMessage = *message; +} + + bool TextSpan::Append(const BString& text) { diff --git a/src/apps/haikudepot/textview/TextSpan.h b/src/apps/haikudepot/textview/TextSpan.h index efa5d9d460..6a20bcaa7e 100644 --- a/src/apps/haikudepot/textview/TextSpan.h +++ b/src/apps/haikudepot/textview/TextSpan.h @@ -6,6 +6,7 @@ #define TEXT_SPAN_H +#include #include #include "CharacterStyle.h" @@ -39,6 +40,12 @@ public: TextSpan SubSpan(int32 start, int32 count) const; + void SetCursor(const BCursor& cursor); + inline const BCursor& Cursor() const + { return fCursor; } + void SetClickMessage(BMessage* message); + inline const BMessage* ClickMessage() const + { return fClickMessage.IsEmpty() ? NULL : &fClickMessage; } private: void _TruncateInsert(int32& start) const; void _TruncateRemove(int32& start, @@ -48,6 +55,9 @@ private: BString fText; int32 fCharCount; CharacterStyle fStyle; + + BCursor fCursor; + BMessage fClickMessage; };