From 3e8c60c4e81345a9623264a8857a87c159608b87 Mon Sep 17 00:00:00 2001
From: Kacper Kasper <kacperkasper@gmail.com>
Date: Fri, 19 Aug 2016 23:31:02 +0000
Subject: [PATCH] Expander: fix status view.
* Truncate() would cut Unicode characters in the middle.
* This commit removes arbitrary message length limit as well as workaround
it was needed for and fixes #5289.
* Status view now expands to maximum possible width and cuts the status
message if necessary using TruncateString().
---
src/apps/expander/ExpanderWindow.cpp | 74 ++++++++++++++++++++++--------------
src/apps/expander/ExpanderWindow.h | 4 +-
2 files changed, 47 insertions(+), 31 deletions(-)
diff --git a/src/apps/expander/ExpanderWindow.cpp b/src/apps/expander/ExpanderWindow.cpp
index 59b657d..11e7a41 100644
a
|
b
|
const uint32 MSG_SOURCETEXT = 'mSTX';
|
45 | 45 | const uint32 MSG_DESTTEXT = 'mDTX'; |
46 | 46 | const uint32 MSG_SHOWCONTENTS = 'mSCT'; |
47 | 47 | |
48 | | const int32 MAX_STATUS_LENGTH = 35; |
| 48 | |
| 49 | class StatusView : public BStringView { |
| 50 | public: |
| 51 | StatusView() |
| 52 | : |
| 53 | BStringView(NULL, "") |
| 54 | { |
| 55 | } |
| 56 | virtual ~StatusView() |
| 57 | { |
| 58 | } |
| 59 | |
| 60 | void SetStatus(const BString &text) |
| 61 | { |
| 62 | fStatus = text; |
| 63 | Invalidate(); |
| 64 | } |
| 65 | |
| 66 | void Draw(BRect updateRect) |
| 67 | { |
| 68 | BString truncated = fStatus; |
| 69 | if(fStatus.IsEmpty() == false) { |
| 70 | be_plain_font->TruncateString(&truncated, B_TRUNCATE_END, |
| 71 | Bounds().Width()); |
| 72 | } |
| 73 | |
| 74 | SetText(truncated); |
| 75 | BStringView::Draw(updateRect); |
| 76 | } |
| 77 | |
| 78 | private: |
| 79 | BString fStatus; |
| 80 | }; |
49 | 81 | |
50 | 82 | |
51 | 83 | #undef B_TRANSLATION_CONTEXT |
… |
… |
ExpanderWindow::ExpanderWindow(BRect frame, const entry_ref* ref,
|
94 | 126 | fScrollView = new BScrollView("", fListingText, B_INVALIDATE_AFTER_LAYOUT, |
95 | 127 | true, true); |
96 | 128 | |
97 | | // workaround to let the layout manager estimate |
98 | | // the width of status view and fix the #5289 |
99 | | // we assume that spaces are twice narrower than normal chars |
100 | | BString statusPlaceholderString; |
101 | | statusPlaceholderString.SetTo(' ', MAX_STATUS_LENGTH * 2); |
102 | | |
103 | 129 | const float spacing = be_control_look->DefaultItemSpacing(); |
104 | 130 | BGroupLayout* pathLayout; |
105 | 131 | BLayoutBuilder::Group<>(this, B_VERTICAL, 0) |
… |
… |
ExpanderWindow::ExpanderWindow(BRect frame, const entry_ref* ref,
|
122 | 148 | .Add(fShowContents = new BCheckBox( |
123 | 149 | B_TRANSLATE("Show contents"), |
124 | 150 | new BMessage(MSG_SHOWCONTENTS))) |
125 | | .Add(fStatusView = new BStringView(NULL, |
126 | | statusPlaceholderString)) |
| 151 | .Add(fStatusView = new StatusView()) |
127 | 152 | .End() |
128 | 153 | .End() |
129 | 154 | .Add(fScrollView) |
… |
… |
ExpanderWindow::ExpanderWindow(BRect frame, const entry_ref* ref,
|
134 | 159 | size = GetLayout()->View()->PreferredSize(); |
135 | 160 | fSizeLimit = size.Height() - fScrollView->PreferredSize().height - spacing; |
136 | 161 | |
| 162 | fStatusView->SetExplicitMinSize(BSize(50.0f, B_SIZE_UNSET)); |
| 163 | fStatusView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); |
| 164 | |
137 | 165 | ResizeTo(Bounds().Width(), fSizeLimit); |
138 | 166 | SetSizeLimits(size.Width(), 32767.0f, fSizeLimit, fSizeLimit); |
139 | 167 | SetZoomLimits(Bounds().Width(), fSizeLimit); |
… |
… |
ExpanderWindow::MessageReceived(BMessage* message)
|
443 | 471 | // (finished, quit, killed, we don't know) |
444 | 472 | // reset window state |
445 | 473 | if (fExpandingStarted) { |
446 | | SetStatus(B_TRANSLATE("File expanded")); |
| 474 | fStatusView->SetStatus(B_TRANSLATE("File expanded")); |
447 | 475 | StopExpanding(); |
448 | 476 | OpenDestFolder(); |
449 | 477 | CloseWindowOrKeepOpen(); |
… |
… |
ExpanderWindow::MessageReceived(BMessage* message)
|
452 | 480 | StopListing(); |
453 | 481 | _ExpandListingText(); |
454 | 482 | } else |
455 | | SetStatus(""); |
| 483 | fStatusView->SetStatus(""); |
456 | 484 | break; |
457 | 485 | |
458 | 486 | case 'exrr': |
459 | 487 | // thread has finished |
460 | 488 | // reset window state |
461 | 489 | |
462 | | SetStatus(B_TRANSLATE("Error when expanding archive")); |
| 490 | fStatusView->SetStatus(B_TRANSLATE("Error when expanding archive")); |
463 | 491 | CloseWindowOrKeepOpen(); |
464 | 492 | break; |
465 | 493 | |
… |
… |
ExpanderWindow::StartExpanding()
|
649 | 677 | |
650 | 678 | BEntry entry(&fSourceRef); |
651 | 679 | BPath path(&entry); |
652 | | BString text(B_TRANSLATE("Expanding '%s'")); |
| 680 | BString text(B_TRANSLATE("Expanding '%s'" B_UTF8_ELLIPSIS)); |
653 | 681 | text.ReplaceFirst("%s", path.Leaf()); |
654 | | SetStatus(text.String()); |
| 682 | fStatusView->SetStatus(text.String()); |
655 | 683 | |
656 | 684 | fExpandingThread = new ExpanderThread(&message, new BMessenger(this)); |
657 | 685 | fExpandingThread->Start(); |
… |
… |
ExpanderWindow::_UpdateWindowSize(bool showContents)
|
751 | 779 | |
752 | 780 | |
753 | 781 | void |
754 | | ExpanderWindow::SetStatus(BString text) |
755 | | { |
756 | | if (text.Length() >= MAX_STATUS_LENGTH) { |
757 | | text.Truncate(MAX_STATUS_LENGTH - 1); |
758 | | text << B_UTF8_ELLIPSIS; |
759 | | } |
760 | | |
761 | | fStatusView->SetText(text); |
762 | | } |
763 | | |
764 | | |
765 | | void |
766 | 782 | ExpanderWindow::StartListing() |
767 | 783 | { |
768 | 784 | _UpdateWindowSize(true); |
… |
… |
ExpanderWindow::StartListing()
|
797 | 813 | |
798 | 814 | BEntry entry(&fSourceRef); |
799 | 815 | BPath path(&entry); |
800 | | BString text(B_TRANSLATE("Creating listing for '%s'")); |
| 816 | BString text(B_TRANSLATE("Creating listing for '%s'" B_UTF8_ELLIPSIS)); |
801 | 817 | text.ReplaceFirst("%s", path.Leaf()); |
802 | | SetStatus(text.String()); |
| 818 | fStatusView->SetStatus(text.String()); |
803 | 819 | fListingText->SetText(""); |
804 | 820 | |
805 | 821 | fListingThread = new ExpanderThread(&message, new BMessenger(this)); |
… |
… |
ExpanderWindow::StopListing(void)
|
830 | 846 | fSourceButton->SetEnabled(true); |
831 | 847 | fDestButton->SetEnabled(true); |
832 | 848 | fExpandButton->SetEnabled(true); |
833 | | SetStatus(""); |
| 849 | fStatusView->SetStatus(""); |
834 | 850 | } |
835 | 851 | |
836 | 852 | |
diff --git a/src/apps/expander/ExpanderWindow.h b/src/apps/expander/ExpanderWindow.h
index fbbfac7..3cf18c6 100644
a
|
b
|
class BTextView;
|
27 | 27 | |
28 | 28 | class ExpanderThread; |
29 | 29 | class ExpanderPreferences; |
| 30 | class StatusView; |
30 | 31 | |
31 | 32 | |
32 | 33 | class ExpanderWindow : public BWindow { |
… |
… |
private:
|
55 | 56 | void _ExpandListingText(); |
56 | 57 | void StartListing(); |
57 | 58 | void StopListing(); |
58 | | void SetStatus(BString text); |
59 | 59 | bool ValidateDest(); |
60 | 60 | |
61 | 61 | private: |
… |
… |
private:
|
79 | 79 | BCheckBox* fShowContents; |
80 | 80 | BTextControl* fSourceText; |
81 | 81 | BTextControl* fDestText; |
82 | | BStringView* fStatusView; |
| 82 | StatusView* fStatusView; |
83 | 83 | BTextView* fListingText; |
84 | 84 | BScrollView* fScrollView; |
85 | 85 | |