hrev46510 adds 3 changesets to branch 'master' old head: e36ad522d60cd032a1ab15229b1a56bd7288c348 new head: d543cbfcf635e2ca662172561252ba642c6debfb overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=d543cbf+%5Ee36ad52 ---------------------------------------------------------------------------- a9fcf3d: Paragraph+TextDocument: Added GetText() method * GetText() extracts the text from a certain range as BString. * Probably fixed TextDocument::ParagraphAt(), though it is still untested. 1aa7edf: TextDocumentView: Added plain-text copying to the clipboard * Make the focus view on MouseDown() * Also added reaction to focus and window activation changes. d543cbf: HaikuDepot: Show message when no package is selected. the instable layout was irritating. Clicking a package and having the package info area expand upward could even lead to the clicked packed to be hidden in the listview. Now a message is displayed and the package info area already has the correct height. [ Stephan Aßmus <superstippi@xxxxxx> ] ---------------------------------------------------------------------------- 8 files changed, 227 insertions(+), 19 deletions(-) src/apps/haiku-depot/PackageInfoView.cpp | 34 +++++-- src/apps/haiku-depot/PackageInfoView.h | 4 +- src/apps/haiku-depot/textview/Paragraph.cpp | 46 +++++++++ src/apps/haiku-depot/textview/Paragraph.h | 2 + src/apps/haiku-depot/textview/TextDocument.cpp | 46 ++++++++- src/apps/haiku-depot/textview/TextDocument.h | 2 + .../haiku-depot/textview/TextDocumentView.cpp | 100 +++++++++++++++++-- src/apps/haiku-depot/textview/TextDocumentView.h | 12 +++ ############################################################################ Commit: a9fcf3d6b58e0e41c778a308c0bb0f6efd64b9ae URL: http://cgit.haiku-os.org/haiku/commit/?id=a9fcf3d Author: Stephan Aßmus <superstippi@xxxxxx> Date: Sat Dec 7 21:49:21 2013 UTC Paragraph+TextDocument: Added GetText() method * GetText() extracts the text from a certain range as BString. * Probably fixed TextDocument::ParagraphAt(), though it is still untested. ---------------------------------------------------------------------------- diff --git a/src/apps/haiku-depot/textview/Paragraph.cpp b/src/apps/haiku-depot/textview/Paragraph.cpp index 07fb11e..df96825 100644 --- a/src/apps/haiku-depot/textview/Paragraph.cpp +++ b/src/apps/haiku-depot/textview/Paragraph.cpp @@ -5,6 +5,8 @@ #include "Paragraph.h" +#include <algorithm> + Paragraph::Paragraph() : @@ -149,3 +151,47 @@ Paragraph::IsEmpty() const { return fTextSpans.CountItems() == 0; } + + +BString +Paragraph::GetText(int32 start, int32 length) const +{ + if (start < 0) + start = 0; + + BString text; + + int32 count = fTextSpans.CountItems(); + for (int32 i = 0; i < count; i++) { + const TextSpan& span = fTextSpans.ItemAtFast(i); + int32 spanLength = span.CharCount(); + if (spanLength == 0) + continue; + if (start > spanLength) { + // Skip span if its before start + start -= spanLength; + continue; + } + + // Remaining span length after start + spanLength -= start; + int32 copyLength = std::min(spanLength, length); + + if (start == 0 && length == spanLength) { + text << span.Text(); + } else { + BString subString; + span.Text().CopyCharsInto(subString, start, copyLength); + text << subString; + } + + length -= copyLength; + if (length == 0) + break; + + // Next span is copied from its beginning + start = 0; + } + + return text; +} diff --git a/src/apps/haiku-depot/textview/Paragraph.h b/src/apps/haiku-depot/textview/Paragraph.h index 2c8ead0..98d4fd1 100644 --- a/src/apps/haiku-depot/textview/Paragraph.h +++ b/src/apps/haiku-depot/textview/Paragraph.h @@ -37,6 +37,8 @@ public: int32 Length() const; bool IsEmpty() const; + BString GetText(int32 start, int32 length) const; + private: ParagraphStyle fStyle; TextSpanList fTextSpans; diff --git a/src/apps/haiku-depot/textview/TextDocument.cpp b/src/apps/haiku-depot/textview/TextDocument.cpp index 2ec8e0b..58b0dcd 100644 --- a/src/apps/haiku-depot/textview/TextDocument.cpp +++ b/src/apps/haiku-depot/textview/TextDocument.cpp @@ -5,6 +5,8 @@ #include "TextDocument.h" +#include <algorithm> + TextDocument::TextDocument() : @@ -172,9 +174,11 @@ TextDocument::ParagraphAt(int32 textOffset, int32& paragraphOffset) const int32 count = fParagraphs.CountItems(); for (int32 i = 0; i < count; i++) { const Paragraph& paragraph = fParagraphs.ItemAtFast(i); - paragraphOffset = textLength; - if (textLength + paragraph.Length() > textOffset) + paragraphOffset = textOffset - textLength; + int32 paragraphLength = paragraph.Length(); + if (textLength + paragraphLength > textOffset) return paragraph; + textLength += paragraphLength; } return fEmptyLastParagraph; } @@ -211,3 +215,41 @@ TextDocument::Length() const } +BString +TextDocument::GetText(int32 start, int32 length) const +{ + if (start < 0) + start = 0; + + BString text; + + int32 count = fParagraphs.CountItems(); + for (int32 i = 0; i < count; i++) { + const Paragraph& paragraph = fParagraphs.ItemAtFast(i); + int32 paragraphLength = paragraph.Length(); + if (paragraphLength == 0) + continue; + if (start > paragraphLength) { + // Skip paragraph if its before start + start -= paragraphLength; + continue; + } + + // Remaining paragraph length after start + paragraphLength -= start; + int32 copyLength = std::min(paragraphLength, length); + + text << paragraph.GetText(start, copyLength); + + length -= copyLength; + if (length == 0) + break; + else if (i < count - 1) + text << '\n'; + + // Next paragraph is copied from its beginning + start = 0; + } + + return text; +} diff --git a/src/apps/haiku-depot/textview/TextDocument.h b/src/apps/haiku-depot/textview/TextDocument.h index 7ccc5c2..6f385f8 100644 --- a/src/apps/haiku-depot/textview/TextDocument.h +++ b/src/apps/haiku-depot/textview/TextDocument.h @@ -65,6 +65,8 @@ public: // Query information int32 Length() const; + BString GetText(int32 start, int32 length) const; + private: ParagraphList fParagraphs; Paragraph fEmptyLastParagraph; ############################################################################ Commit: 1aa7edf0c31cf8f0c0c657c8c98b9dec686df6e3 URL: http://cgit.haiku-os.org/haiku/commit/?id=1aa7edf Author: Stephan Aßmus <superstippi@xxxxxx> Date: Sat Dec 7 21:51:08 2013 UTC TextDocumentView: Added plain-text copying to the clipboard * Make the focus view on MouseDown() * Also added reaction to focus and window activation changes. ---------------------------------------------------------------------------- diff --git a/src/apps/haiku-depot/textview/TextDocumentView.cpp b/src/apps/haiku-depot/textview/TextDocumentView.cpp index 727801e..7ef8f99 100644 --- a/src/apps/haiku-depot/textview/TextDocumentView.cpp +++ b/src/apps/haiku-depot/textview/TextDocumentView.cpp @@ -8,6 +8,7 @@ #include <algorithm> #include <stdio.h> +#include <Clipboard.h> #include <Cursor.h> #include <ScrollBar.h> #include <Shape.h> @@ -42,6 +43,20 @@ TextDocumentView::~TextDocumentView() void +TextDocumentView::MessageReceived(BMessage* message) +{ + switch (message->what) { + case B_COPY: + Copy(be_clipboard); + break; + + default: + BView::MessageReceived(message); + } +} + + +void TextDocumentView::Draw(BRect updateRect) { FillRect(updateRect, B_SOLID_LOW); @@ -54,13 +69,7 @@ TextDocumentView::Draw(BRect updateRect) int32 start; int32 end; - if (fSelectionAnchorOffset <= fCaretOffset) { - start = fSelectionAnchorOffset; - end = fCaretOffset; - } else { - start = fCaretOffset; - end = fSelectionAnchorOffset; - } + GetSelection(start, end); BShape shape; _GetSelectionShape(shape, start, end); @@ -69,8 +78,10 @@ TextDocumentView::Draw(BRect updateRect) SetLineMode(B_ROUND_CAP, B_ROUND_JOIN); MovePenTo(fInsetLeft - 0.5f, fInsetTop - 0.5f); - SetHighColor(30, 30, 30); - FillShape(&shape); + if (IsFocus() && Window() != NULL && Window()->IsActive()) { + SetHighColor(30, 30, 30); + FillShape(&shape); + } SetHighColor(40, 40, 40); StrokeShape(&shape); @@ -93,8 +104,26 @@ TextDocumentView::FrameResized(float width, float height) void +TextDocumentView::WindowActivated(bool active) +{ + Invalidate(); +} + + +void +TextDocumentView::MakeFocus(bool focus) +{ + if (focus != IsFocus()) + Invalidate(); + BView::MakeFocus(focus); +} + + +void TextDocumentView::MouseDown(BPoint where) { + MakeFocus(); + int32 modifiers = 0; if (Window() != NULL && Window()->CurrentMessage() != NULL) Window()->CurrentMessage()->FindInt32("modifiers", &modifiers); @@ -237,6 +266,59 @@ TextDocumentView::SetCaret(const BPoint& location, bool extendSelection) } +bool +TextDocumentView::HasSelection() const +{ + return fSelectionAnchorOffset != fCaretOffset; +} + + +void +TextDocumentView::GetSelection(int32& start, int32& end) const +{ + if (fSelectionAnchorOffset <= fCaretOffset) { + start = fSelectionAnchorOffset; + end = fCaretOffset; + } else { + start = fCaretOffset; + end = fSelectionAnchorOffset; + } +} + + +void +TextDocumentView::Copy(BClipboard* clipboard) +{ + if (fSelectionAnchorOffset == fCaretOffset + || fTextDocument.Get() == NULL) { + // Nothing to copy, don't clear clipboard contents for now reason. + return; + } + + if (clipboard == NULL || !clipboard->Lock()) + return; + + clipboard->Clear(); + + BMessage* clip = clipboard->Data(); + if (clip != NULL) { + int32 start; + int32 end; + GetSelection(start, end); + + BString text = fTextDocument->GetText(start, end - start); + clip->AddData("text/plain", B_MIME_TYPE, text.String(), + text.Length()); + + // TODO: Support for "application/x-vnd.Be-text_run_array" + + clipboard->Commit(); + } + + clipboard->Unlock(); +} + + // #pragma mark - private diff --git a/src/apps/haiku-depot/textview/TextDocumentView.h b/src/apps/haiku-depot/textview/TextDocumentView.h index 9860284..7cf4fe6 100644 --- a/src/apps/haiku-depot/textview/TextDocumentView.h +++ b/src/apps/haiku-depot/textview/TextDocumentView.h @@ -12,15 +12,22 @@ #include "TextDocumentLayout.h" +class BClipboard; + + class TextDocumentView : public BView { public: TextDocumentView(const char* name = NULL); virtual ~TextDocumentView(); + virtual void MessageReceived(BMessage* message); + virtual void Draw(BRect updateRect); virtual void AttachedToWindow(); virtual void FrameResized(float width, float height); + virtual void WindowActivated(bool active); + virtual void MakeFocus(bool focus = true); virtual void MouseDown(BPoint where); virtual void MouseUp(BPoint where); @@ -46,6 +53,11 @@ public: void SetCaret(const BPoint& where, bool extendSelection); + bool HasSelection() const; + void GetSelection(int32& start, int32& end) const; + + void Copy(BClipboard* clipboard); + private: float _TextLayoutWidth(float viewWidth) const; ############################################################################ Revision: hrev46510 Commit: d543cbfcf635e2ca662172561252ba642c6debfb URL: http://cgit.haiku-os.org/haiku/commit/?id=d543cbf Author: Stephan Aßmus <superstippi@xxxxxx> Date: Sun Dec 8 13:14:39 2013 UTC HaikuDepot: Show message when no package is selected. the instable layout was irritating. Clicking a package and having the package info area expand upward could even lead to the clicked packed to be hidden in the listview. Now a message is displayed and the package info area already has the correct height. ---------------------------------------------------------------------------- diff --git a/src/apps/haiku-depot/PackageInfoView.cpp b/src/apps/haiku-depot/PackageInfoView.cpp index 9042386..0ab5a54 100644 --- a/src/apps/haiku-depot/PackageInfoView.cpp +++ b/src/apps/haiku-depot/PackageInfoView.cpp @@ -1303,17 +1303,39 @@ private: PackageInfoView::PackageInfoView(BLocker* modelLock, PackageActionHandler* handler) : - BGroupView("package info view", B_VERTICAL), + BView("package info view", 0), fModelLock(modelLock), fPackageListener(new(std::nothrow) Listener(this)) { + fCardLayout = new BCardLayout(); + SetLayout(fCardLayout); + + BGroupView* noPackageCard = new BGroupView("no package card", B_VERTICAL); + AddChild(noPackageCard); + + BStringView* noPackageView = new BStringView("no package view", + B_TRANSLATE("Click a package to view information")); + noPackageView->SetHighColor(kLightBlack); + noPackageView->SetExplicitAlignment(BAlignment( + B_ALIGN_HORIZONTAL_CENTER, B_ALIGN_VERTICAL_CENTER)); + + BLayoutBuilder::Group<>(noPackageCard) + .Add(noPackageView) + .SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)) + ; + + BGroupView* packageCard = new BGroupView("package card", B_VERTICAL); + AddChild(packageCard); + + fCardLayout->SetVisibleItem(0L); + fTitleView = new TitleView(); fPackageActionView = new PackageActionView(handler); fPackageActionView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); fPagesView = new PagesView(); - BLayoutBuilder::Group<>(this) + BLayoutBuilder::Group<>(packageCard) .AddGroup(B_HORIZONTAL, 0.0f) .Add(fTitleView, 6.0f) .Add(fPackageActionView, 1.0f) @@ -1378,7 +1400,7 @@ PackageInfoView::MessageReceived(BMessage* message) break; } default: - BGroupView::MessageReceived(message); + BView::MessageReceived(message); break; } } @@ -1395,8 +1417,7 @@ PackageInfoView::SetPackage(const PackageInfoRef& packageRef) fPackageActionView->SetPackage(package); fPagesView->SetPackage(package); - if (fPagesView->IsHidden(fPagesView)) - fPagesView->Show(); + fCardLayout->SetVisibleItem(1L); fPackageListener->SetPackage(packageRef); } @@ -1409,8 +1430,7 @@ PackageInfoView::Clear() fPackageActionView->Clear(); fPagesView->Clear(); - if (!fPagesView->IsHidden(fPagesView)) - fPagesView->Hide(); + fCardLayout->SetVisibleItem(0L); BAutolock _(fModelLock); diff --git a/src/apps/haiku-depot/PackageInfoView.h b/src/apps/haiku-depot/PackageInfoView.h index c5dac54..eb2848f 100644 --- a/src/apps/haiku-depot/PackageInfoView.h +++ b/src/apps/haiku-depot/PackageInfoView.h @@ -11,6 +11,7 @@ #include "PackageInfoListener.h" +class BCardLayout; class BLocker; class TitleView; class PackageActionHandler; @@ -23,7 +24,7 @@ enum { }; -class PackageInfoView : public BGroupView { +class PackageInfoView : public BView { public: PackageInfoView(BLocker* modelLock, PackageActionHandler* handler); @@ -41,6 +42,7 @@ private: private: BLocker* fModelLock; + BCardLayout* fCardLayout; TitleView* fTitleView; PackageActionView* fPackageActionView; PagesView* fPagesView;