From 436f3f8eb5b45620842351a1f29ba49571043515 Mon Sep 17 00:00:00 2001 From: Andreas Heinisch Date: Mon, 22 May 2023 22:46:55 +0200 Subject: tdf#38742 - Start Center: introduce push pins to favorite documents Change-Id: I879e4d93e1da222d9acabb776552ca1cf819574b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152136 Tested-by: Andreas Heinisch Reviewed-by: Andreas Heinisch --- dbaccess/source/ui/app/AppController.cxx | 2 +- icon-themes/breeze/res/recentdoc_pin.png | Bin 0 -> 437 bytes .../breeze/res/recentdoc_pin_highlighted.png | Bin 0 -> 281 bytes icon-themes/breeze_dark/res/recentdoc_pin.png | Bin 0 -> 437 bytes .../breeze_dark/res/recentdoc_pin_highlighted.png | Bin 0 -> 281 bytes icon-themes/breeze_dark_svg/res/recentdoc_pin.svg | 1 + .../res/recentdoc_pin_highlighted.svg | 14 ++ icon-themes/breeze_svg/res/recentdoc_pin.svg | 1 + .../breeze_svg/res/recentdoc_pin_highlighted.svg | 14 ++ icon-themes/colibre/res/recentdoc_pin.png | Bin 0 -> 437 bytes .../colibre/res/recentdoc_pin_highlighted.png | Bin 0 -> 281 bytes icon-themes/colibre_dark/res/recentdoc_pin.png | Bin 0 -> 437 bytes .../colibre_dark/res/recentdoc_pin_highlighted.png | Bin 0 -> 281 bytes icon-themes/colibre_dark_svg/res/recentdoc_pin.svg | 1 + .../res/recentdoc_pin_highlighted.svg | 14 ++ icon-themes/colibre_svg/res/recentdoc_pin.svg | 1 + .../colibre_svg/res/recentdoc_pin_highlighted.svg | 14 ++ icon-themes/elementary/res/recentdoc_pin.png | Bin 0 -> 437 bytes .../elementary/res/recentdoc_pin_highlighted.png | Bin 0 -> 281 bytes icon-themes/elementary_svg/res/recentdoc_pin.svg | 1 + .../res/recentdoc_pin_highlighted.svg | 14 ++ icon-themes/sifr/res/recentdoc_pin.png | Bin 0 -> 437 bytes icon-themes/sifr/res/recentdoc_pin_highlighted.png | Bin 0 -> 281 bytes icon-themes/sifr_dark/res/recentdoc_pin.png | Bin 0 -> 437 bytes .../sifr_dark/res/recentdoc_pin_highlighted.png | Bin 0 -> 281 bytes icon-themes/sifr_dark_svg/res/recentdoc_pin.svg | 1 + .../res/recentdoc_pin_highlighted.svg | 14 ++ icon-themes/sifr_svg/res/recentdoc_pin.svg | 1 + .../sifr_svg/res/recentdoc_pin_highlighted.svg | 14 ++ icon-themes/sukapura/res/pin_document.png | Bin 0 -> 358 bytes icon-themes/sukapura/res/recentdoc_pin.png | Bin 0 -> 437 bytes .../sukapura/res/recentdoc_pin_highlighted.png | Bin 0 -> 281 bytes icon-themes/sukapura/res/unpin_document.png | Bin 0 -> 475 bytes icon-themes/sukapura_dark/res/pin_document.png | Bin 0 -> 358 bytes icon-themes/sukapura_dark/res/recentdoc_pin.png | Bin 0 -> 437 bytes .../res/recentdoc_pin_highlighted.png | Bin 0 -> 281 bytes icon-themes/sukapura_dark/res/unpin_document.png | Bin 0 -> 475 bytes icon-themes/sukapura_dark_svg/res/pin_document.svg | 7 + .../sukapura_dark_svg/res/recentdoc_pin.svg | 1 + .../res/recentdoc_pin_highlighted.svg | 14 ++ .../sukapura_dark_svg/res/unpin_document.svg | 17 +++ icon-themes/sukapura_svg/res/recentdoc_pin.svg | 1 + .../sukapura_svg/res/recentdoc_pin_highlighted.svg | 14 ++ include/sfx2/thumbnailviewitem.hxx | 10 ++ include/unotools/historyoptions.hxx | 25 +++- .../schema/org/openoffice/Office/Histories.xcs | 5 + sfx2/inc/bitmaps.hlst | 2 + sfx2/inc/recentdocsview.hxx | 3 +- sfx2/source/appl/newhelp.cxx | 4 +- sfx2/source/appl/sfxpicklist.cxx | 3 +- sfx2/source/control/recentdocsview.cxx | 10 +- sfx2/source/control/recentdocsviewitem.cxx | 14 +- sfx2/source/control/recentdocsviewitem.hxx | 6 +- sfx2/source/control/thumbnailview.cxx | 14 ++ sfx2/source/control/thumbnailviewitem.cxx | 47 +++++- unotools/source/config/historyoptions.cxx | 165 +++++++++++++++++---- 56 files changed, 421 insertions(+), 48 deletions(-) create mode 100755 icon-themes/breeze/res/recentdoc_pin.png create mode 100755 icon-themes/breeze/res/recentdoc_pin_highlighted.png create mode 100755 icon-themes/breeze_dark/res/recentdoc_pin.png create mode 100755 icon-themes/breeze_dark/res/recentdoc_pin_highlighted.png create mode 100755 icon-themes/breeze_dark_svg/res/recentdoc_pin.svg create mode 100755 icon-themes/breeze_dark_svg/res/recentdoc_pin_highlighted.svg create mode 100755 icon-themes/breeze_svg/res/recentdoc_pin.svg create mode 100755 icon-themes/breeze_svg/res/recentdoc_pin_highlighted.svg create mode 100755 icon-themes/colibre/res/recentdoc_pin.png create mode 100755 icon-themes/colibre/res/recentdoc_pin_highlighted.png create mode 100755 icon-themes/colibre_dark/res/recentdoc_pin.png create mode 100755 icon-themes/colibre_dark/res/recentdoc_pin_highlighted.png create mode 100755 icon-themes/colibre_dark_svg/res/recentdoc_pin.svg create mode 100755 icon-themes/colibre_dark_svg/res/recentdoc_pin_highlighted.svg create mode 100755 icon-themes/colibre_svg/res/recentdoc_pin.svg create mode 100755 icon-themes/colibre_svg/res/recentdoc_pin_highlighted.svg create mode 100755 icon-themes/elementary/res/recentdoc_pin.png create mode 100755 icon-themes/elementary/res/recentdoc_pin_highlighted.png create mode 100755 icon-themes/elementary_svg/res/recentdoc_pin.svg create mode 100755 icon-themes/elementary_svg/res/recentdoc_pin_highlighted.svg create mode 100755 icon-themes/sifr/res/recentdoc_pin.png create mode 100755 icon-themes/sifr/res/recentdoc_pin_highlighted.png create mode 100755 icon-themes/sifr_dark/res/recentdoc_pin.png create mode 100755 icon-themes/sifr_dark/res/recentdoc_pin_highlighted.png create mode 100755 icon-themes/sifr_dark_svg/res/recentdoc_pin.svg create mode 100755 icon-themes/sifr_dark_svg/res/recentdoc_pin_highlighted.svg create mode 100755 icon-themes/sifr_svg/res/recentdoc_pin.svg create mode 100755 icon-themes/sifr_svg/res/recentdoc_pin_highlighted.svg create mode 100755 icon-themes/sukapura/res/pin_document.png create mode 100755 icon-themes/sukapura/res/recentdoc_pin.png create mode 100755 icon-themes/sukapura/res/recentdoc_pin_highlighted.png create mode 100755 icon-themes/sukapura/res/unpin_document.png create mode 100755 icon-themes/sukapura_dark/res/pin_document.png create mode 100755 icon-themes/sukapura_dark/res/recentdoc_pin.png create mode 100755 icon-themes/sukapura_dark/res/recentdoc_pin_highlighted.png create mode 100755 icon-themes/sukapura_dark/res/unpin_document.png create mode 100755 icon-themes/sukapura_dark_svg/res/pin_document.svg create mode 100755 icon-themes/sukapura_dark_svg/res/recentdoc_pin.svg create mode 100755 icon-themes/sukapura_dark_svg/res/recentdoc_pin_highlighted.svg create mode 100755 icon-themes/sukapura_dark_svg/res/unpin_document.svg create mode 100755 icon-themes/sukapura_svg/res/recentdoc_pin.svg create mode 100755 icon-themes/sukapura_svg/res/recentdoc_pin_highlighted.svg diff --git a/dbaccess/source/ui/app/AppController.cxx b/dbaccess/source/ui/app/AppController.cxx index ad18bff5892c..175f56b39724 100644 --- a/dbaccess/source/ui/app/AppController.cxx +++ b/dbaccess/source/ui/app/AppController.cxx @@ -361,7 +361,7 @@ void SAL_CALL OApplicationController::disposing() aURL.GetURLNoPass( INetURLObject::DecodeMechanism::NONE ), aFilter, getStrippedDatabaseName(), - std::nullopt, std::nullopt); + std::nullopt, std::nullopt, std::nullopt); // add to recent document list if ( aURL.GetProtocol() == INetProtocol::File ) diff --git a/icon-themes/breeze/res/recentdoc_pin.png b/icon-themes/breeze/res/recentdoc_pin.png new file mode 100755 index 000000000000..a022906f65c6 Binary files /dev/null and b/icon-themes/breeze/res/recentdoc_pin.png differ diff --git a/icon-themes/breeze/res/recentdoc_pin_highlighted.png b/icon-themes/breeze/res/recentdoc_pin_highlighted.png new file mode 100755 index 000000000000..877b80bfafe0 Binary files /dev/null and b/icon-themes/breeze/res/recentdoc_pin_highlighted.png differ diff --git a/icon-themes/breeze_dark/res/recentdoc_pin.png b/icon-themes/breeze_dark/res/recentdoc_pin.png new file mode 100755 index 000000000000..a022906f65c6 Binary files /dev/null and b/icon-themes/breeze_dark/res/recentdoc_pin.png differ diff --git a/icon-themes/breeze_dark/res/recentdoc_pin_highlighted.png b/icon-themes/breeze_dark/res/recentdoc_pin_highlighted.png new file mode 100755 index 000000000000..877b80bfafe0 Binary files /dev/null and b/icon-themes/breeze_dark/res/recentdoc_pin_highlighted.png differ diff --git a/icon-themes/breeze_dark_svg/res/recentdoc_pin.svg b/icon-themes/breeze_dark_svg/res/recentdoc_pin.svg new file mode 100755 index 000000000000..a4578679d18d --- /dev/null +++ b/icon-themes/breeze_dark_svg/res/recentdoc_pin.svg @@ -0,0 +1 @@ + 20 Education Icon Set 64px \ No newline at end of file diff --git a/icon-themes/breeze_dark_svg/res/recentdoc_pin_highlighted.svg b/icon-themes/breeze_dark_svg/res/recentdoc_pin_highlighted.svg new file mode 100755 index 000000000000..fd8b1afa65ee --- /dev/null +++ b/icon-themes/breeze_dark_svg/res/recentdoc_pin_highlighted.svg @@ -0,0 +1,14 @@ + + + + + diff --git a/icon-themes/breeze_svg/res/recentdoc_pin.svg b/icon-themes/breeze_svg/res/recentdoc_pin.svg new file mode 100755 index 000000000000..a4578679d18d --- /dev/null +++ b/icon-themes/breeze_svg/res/recentdoc_pin.svg @@ -0,0 +1 @@ + 20 Education Icon Set 64px \ No newline at end of file diff --git a/icon-themes/breeze_svg/res/recentdoc_pin_highlighted.svg b/icon-themes/breeze_svg/res/recentdoc_pin_highlighted.svg new file mode 100755 index 000000000000..fd8b1afa65ee --- /dev/null +++ b/icon-themes/breeze_svg/res/recentdoc_pin_highlighted.svg @@ -0,0 +1,14 @@ + + + + + diff --git a/icon-themes/colibre/res/recentdoc_pin.png b/icon-themes/colibre/res/recentdoc_pin.png new file mode 100755 index 000000000000..a022906f65c6 Binary files /dev/null and b/icon-themes/colibre/res/recentdoc_pin.png differ diff --git a/icon-themes/colibre/res/recentdoc_pin_highlighted.png b/icon-themes/colibre/res/recentdoc_pin_highlighted.png new file mode 100755 index 000000000000..877b80bfafe0 Binary files /dev/null and b/icon-themes/colibre/res/recentdoc_pin_highlighted.png differ diff --git a/icon-themes/colibre_dark/res/recentdoc_pin.png b/icon-themes/colibre_dark/res/recentdoc_pin.png new file mode 100755 index 000000000000..a022906f65c6 Binary files /dev/null and b/icon-themes/colibre_dark/res/recentdoc_pin.png differ diff --git a/icon-themes/colibre_dark/res/recentdoc_pin_highlighted.png b/icon-themes/colibre_dark/res/recentdoc_pin_highlighted.png new file mode 100755 index 000000000000..877b80bfafe0 Binary files /dev/null and b/icon-themes/colibre_dark/res/recentdoc_pin_highlighted.png differ diff --git a/icon-themes/colibre_dark_svg/res/recentdoc_pin.svg b/icon-themes/colibre_dark_svg/res/recentdoc_pin.svg new file mode 100755 index 000000000000..a4578679d18d --- /dev/null +++ b/icon-themes/colibre_dark_svg/res/recentdoc_pin.svg @@ -0,0 +1 @@ + 20 Education Icon Set 64px \ No newline at end of file diff --git a/icon-themes/colibre_dark_svg/res/recentdoc_pin_highlighted.svg b/icon-themes/colibre_dark_svg/res/recentdoc_pin_highlighted.svg new file mode 100755 index 000000000000..fd8b1afa65ee --- /dev/null +++ b/icon-themes/colibre_dark_svg/res/recentdoc_pin_highlighted.svg @@ -0,0 +1,14 @@ + + + + + diff --git a/icon-themes/colibre_svg/res/recentdoc_pin.svg b/icon-themes/colibre_svg/res/recentdoc_pin.svg new file mode 100755 index 000000000000..a4578679d18d --- /dev/null +++ b/icon-themes/colibre_svg/res/recentdoc_pin.svg @@ -0,0 +1 @@ + 20 Education Icon Set 64px \ No newline at end of file diff --git a/icon-themes/colibre_svg/res/recentdoc_pin_highlighted.svg b/icon-themes/colibre_svg/res/recentdoc_pin_highlighted.svg new file mode 100755 index 000000000000..fd8b1afa65ee --- /dev/null +++ b/icon-themes/colibre_svg/res/recentdoc_pin_highlighted.svg @@ -0,0 +1,14 @@ + + + + + diff --git a/icon-themes/elementary/res/recentdoc_pin.png b/icon-themes/elementary/res/recentdoc_pin.png new file mode 100755 index 000000000000..a022906f65c6 Binary files /dev/null and b/icon-themes/elementary/res/recentdoc_pin.png differ diff --git a/icon-themes/elementary/res/recentdoc_pin_highlighted.png b/icon-themes/elementary/res/recentdoc_pin_highlighted.png new file mode 100755 index 000000000000..877b80bfafe0 Binary files /dev/null and b/icon-themes/elementary/res/recentdoc_pin_highlighted.png differ diff --git a/icon-themes/elementary_svg/res/recentdoc_pin.svg b/icon-themes/elementary_svg/res/recentdoc_pin.svg new file mode 100755 index 000000000000..a4578679d18d --- /dev/null +++ b/icon-themes/elementary_svg/res/recentdoc_pin.svg @@ -0,0 +1 @@ + 20 Education Icon Set 64px \ No newline at end of file diff --git a/icon-themes/elementary_svg/res/recentdoc_pin_highlighted.svg b/icon-themes/elementary_svg/res/recentdoc_pin_highlighted.svg new file mode 100755 index 000000000000..fd8b1afa65ee --- /dev/null +++ b/icon-themes/elementary_svg/res/recentdoc_pin_highlighted.svg @@ -0,0 +1,14 @@ + + + + + diff --git a/icon-themes/sifr/res/recentdoc_pin.png b/icon-themes/sifr/res/recentdoc_pin.png new file mode 100755 index 000000000000..a022906f65c6 Binary files /dev/null and b/icon-themes/sifr/res/recentdoc_pin.png differ diff --git a/icon-themes/sifr/res/recentdoc_pin_highlighted.png b/icon-themes/sifr/res/recentdoc_pin_highlighted.png new file mode 100755 index 000000000000..877b80bfafe0 Binary files /dev/null and b/icon-themes/sifr/res/recentdoc_pin_highlighted.png differ diff --git a/icon-themes/sifr_dark/res/recentdoc_pin.png b/icon-themes/sifr_dark/res/recentdoc_pin.png new file mode 100755 index 000000000000..a022906f65c6 Binary files /dev/null and b/icon-themes/sifr_dark/res/recentdoc_pin.png differ diff --git a/icon-themes/sifr_dark/res/recentdoc_pin_highlighted.png b/icon-themes/sifr_dark/res/recentdoc_pin_highlighted.png new file mode 100755 index 000000000000..877b80bfafe0 Binary files /dev/null and b/icon-themes/sifr_dark/res/recentdoc_pin_highlighted.png differ diff --git a/icon-themes/sifr_dark_svg/res/recentdoc_pin.svg b/icon-themes/sifr_dark_svg/res/recentdoc_pin.svg new file mode 100755 index 000000000000..a4578679d18d --- /dev/null +++ b/icon-themes/sifr_dark_svg/res/recentdoc_pin.svg @@ -0,0 +1 @@ + 20 Education Icon Set 64px \ No newline at end of file diff --git a/icon-themes/sifr_dark_svg/res/recentdoc_pin_highlighted.svg b/icon-themes/sifr_dark_svg/res/recentdoc_pin_highlighted.svg new file mode 100755 index 000000000000..fd8b1afa65ee --- /dev/null +++ b/icon-themes/sifr_dark_svg/res/recentdoc_pin_highlighted.svg @@ -0,0 +1,14 @@ + + + + + diff --git a/icon-themes/sifr_svg/res/recentdoc_pin.svg b/icon-themes/sifr_svg/res/recentdoc_pin.svg new file mode 100755 index 000000000000..a4578679d18d --- /dev/null +++ b/icon-themes/sifr_svg/res/recentdoc_pin.svg @@ -0,0 +1 @@ + 20 Education Icon Set 64px \ No newline at end of file diff --git a/icon-themes/sifr_svg/res/recentdoc_pin_highlighted.svg b/icon-themes/sifr_svg/res/recentdoc_pin_highlighted.svg new file mode 100755 index 000000000000..fd8b1afa65ee --- /dev/null +++ b/icon-themes/sifr_svg/res/recentdoc_pin_highlighted.svg @@ -0,0 +1,14 @@ + + + + + diff --git a/icon-themes/sukapura/res/pin_document.png b/icon-themes/sukapura/res/pin_document.png new file mode 100755 index 000000000000..59c3038c7a59 Binary files /dev/null and b/icon-themes/sukapura/res/pin_document.png differ diff --git a/icon-themes/sukapura/res/recentdoc_pin.png b/icon-themes/sukapura/res/recentdoc_pin.png new file mode 100755 index 000000000000..a022906f65c6 Binary files /dev/null and b/icon-themes/sukapura/res/recentdoc_pin.png differ diff --git a/icon-themes/sukapura/res/recentdoc_pin_highlighted.png b/icon-themes/sukapura/res/recentdoc_pin_highlighted.png new file mode 100755 index 000000000000..877b80bfafe0 Binary files /dev/null and b/icon-themes/sukapura/res/recentdoc_pin_highlighted.png differ diff --git a/icon-themes/sukapura/res/unpin_document.png b/icon-themes/sukapura/res/unpin_document.png new file mode 100755 index 000000000000..0b6fa261c62e Binary files /dev/null and b/icon-themes/sukapura/res/unpin_document.png differ diff --git a/icon-themes/sukapura_dark/res/pin_document.png b/icon-themes/sukapura_dark/res/pin_document.png new file mode 100755 index 000000000000..59c3038c7a59 Binary files /dev/null and b/icon-themes/sukapura_dark/res/pin_document.png differ diff --git a/icon-themes/sukapura_dark/res/recentdoc_pin.png b/icon-themes/sukapura_dark/res/recentdoc_pin.png new file mode 100755 index 000000000000..a022906f65c6 Binary files /dev/null and b/icon-themes/sukapura_dark/res/recentdoc_pin.png differ diff --git a/icon-themes/sukapura_dark/res/recentdoc_pin_highlighted.png b/icon-themes/sukapura_dark/res/recentdoc_pin_highlighted.png new file mode 100755 index 000000000000..877b80bfafe0 Binary files /dev/null and b/icon-themes/sukapura_dark/res/recentdoc_pin_highlighted.png differ diff --git a/icon-themes/sukapura_dark/res/unpin_document.png b/icon-themes/sukapura_dark/res/unpin_document.png new file mode 100755 index 000000000000..0b6fa261c62e Binary files /dev/null and b/icon-themes/sukapura_dark/res/unpin_document.png differ diff --git a/icon-themes/sukapura_dark_svg/res/pin_document.svg b/icon-themes/sukapura_dark_svg/res/pin_document.svg new file mode 100755 index 000000000000..881bbb3cdd11 --- /dev/null +++ b/icon-themes/sukapura_dark_svg/res/pin_document.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/icon-themes/sukapura_dark_svg/res/recentdoc_pin.svg b/icon-themes/sukapura_dark_svg/res/recentdoc_pin.svg new file mode 100755 index 000000000000..a4578679d18d --- /dev/null +++ b/icon-themes/sukapura_dark_svg/res/recentdoc_pin.svg @@ -0,0 +1 @@ + 20 Education Icon Set 64px \ No newline at end of file diff --git a/icon-themes/sukapura_dark_svg/res/recentdoc_pin_highlighted.svg b/icon-themes/sukapura_dark_svg/res/recentdoc_pin_highlighted.svg new file mode 100755 index 000000000000..fd8b1afa65ee --- /dev/null +++ b/icon-themes/sukapura_dark_svg/res/recentdoc_pin_highlighted.svg @@ -0,0 +1,14 @@ + + + + + diff --git a/icon-themes/sukapura_dark_svg/res/unpin_document.svg b/icon-themes/sukapura_dark_svg/res/unpin_document.svg new file mode 100755 index 000000000000..89a49ea1e267 --- /dev/null +++ b/icon-themes/sukapura_dark_svg/res/unpin_document.svg @@ -0,0 +1,17 @@ + + + + + + + diff --git a/icon-themes/sukapura_svg/res/recentdoc_pin.svg b/icon-themes/sukapura_svg/res/recentdoc_pin.svg new file mode 100755 index 000000000000..a4578679d18d --- /dev/null +++ b/icon-themes/sukapura_svg/res/recentdoc_pin.svg @@ -0,0 +1 @@ + 20 Education Icon Set 64px \ No newline at end of file diff --git a/icon-themes/sukapura_svg/res/recentdoc_pin_highlighted.svg b/icon-themes/sukapura_svg/res/recentdoc_pin_highlighted.svg new file mode 100755 index 000000000000..fd8b1afa65ee --- /dev/null +++ b/icon-themes/sukapura_svg/res/recentdoc_pin_highlighted.svg @@ -0,0 +1,14 @@ + + + + + diff --git a/include/sfx2/thumbnailviewitem.hxx b/include/sfx2/thumbnailviewitem.hxx index bd72ee30c9d6..e34985c799d3 100644 --- a/include/sfx2/thumbnailviewitem.hxx +++ b/include/sfx2/thumbnailviewitem.hxx @@ -72,11 +72,16 @@ public: bool mbBorder; bool mbSelected; bool mbHover; + bool mbPinned; BitmapEx maPreview1; OUString maTitle; OUString maHelpText; css::uno::Reference< css::accessibility::XAccessible > mxAcc; + bool mbPinnedDocumentHighlighted; + BitmapEx maPinnedDocumentBitmap; + BitmapEx maPinnedDocumentBitmapHiglighted; + ThumbnailViewItem(ThumbnailView& rView, sal_uInt16 nId); virtual ~ThumbnailViewItem (); @@ -93,6 +98,10 @@ public: void setHighlight (bool state); + bool isPinned () const { return mbPinned; } + + void setPinned (bool state); + /** Updates own highlight status based on the aPoint position. Returns rectangle that needs to be invalidated. @@ -132,6 +141,7 @@ protected: Point maTextPos; Point maPrev1Pos; + Point maPinPos; tools::Rectangle maDrawArea; }; diff --git a/include/unotools/historyoptions.hxx b/include/unotools/historyoptions.hxx index 1f743e062cb2..8cf1aa744e31 100644 --- a/include/unotools/historyoptions.hxx +++ b/include/unotools/historyoptions.hxx @@ -44,7 +44,7 @@ namespace SvtHistoryOptions @param eHistory select right history. */ - UNOTOOLS_DLLPUBLIC void Clear(EHistoryType eHistory); + UNOTOOLS_DLLPUBLIC void Clear(EHistoryType eHistory, bool bClearPinned = false); /** Return the complete specified history list. @@ -59,6 +59,7 @@ namespace SvtHistoryOptions OUString sPassword; OUString sThumbnail; bool isReadOnly = false; + bool isPinned = false; }; UNOTOOLS_DLLPUBLIC std::vector< HistoryItem > GetList(EHistoryType eHistory); @@ -66,18 +67,26 @@ namespace SvtHistoryOptions The oldest entry is deleted automatically when the size reaches the maximum. - @param eHistory select right history. - @param sURL URL to save in history - @param sFilter filter name to save in history - @param sTitle document title to save in history + @param eHistory select right history. + @param sURL URL to save in history + @param sFilter filter name to save in history + @param sTitle document title to save in history + @param sThumbnail base64 encoded thumbnail of the item + @param oIsReadOnly item was opened editable or read-only + @param oIsPinned item is pinned in the user-interface */ - UNOTOOLS_DLLPUBLIC void AppendItem(EHistoryType eHistory, - const OUString& sURL, const OUString& sFilter, const OUString& sTitle, - const std::optional& sThumbnail, std::optional oIsReadOnly); + UNOTOOLS_DLLPUBLIC void AppendItem(EHistoryType eHistory, const OUString& sURL, + const OUString& sFilter, const OUString& sTitle, + const std::optional& sThumbnail, + std::optional oIsReadOnly, + std::optional oIsPinned); /** Delete item from the specified list. */ UNOTOOLS_DLLPUBLIC void DeleteItem(EHistoryType eHistory, const OUString& sURL); + + // tdf#38742 - toggle pinned state of an item + UNOTOOLS_DLLPUBLIC void TogglePinItem(EHistoryType eHistory, const OUString& sURL); }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/officecfg/registry/schema/org/openoffice/Office/Histories.xcs b/officecfg/registry/schema/org/openoffice/Office/Histories.xcs index 0f4894477d4c..e01534fb9aea 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Histories.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Histories.xcs @@ -52,6 +52,11 @@ Stores whether the document was opened editable or read-only. + + + Stores whether the document is pinned in the user-interface. + + diff --git a/sfx2/inc/bitmaps.hlst b/sfx2/inc/bitmaps.hlst index 84b1e2946427..70597c881300 100644 --- a/sfx2/inc/bitmaps.hlst +++ b/sfx2/inc/bitmaps.hlst @@ -67,6 +67,8 @@ inline constexpr OUStringLiteral SFX_THUMBNAIL_BASE_256 = u"res/base_thumbnail_2 inline constexpr OUStringLiteral BMP_RECENTDOC_REMOVE = u"res/recentdoc_remove.png"; inline constexpr OUStringLiteral BMP_RECENTDOC_REMOVE_HIGHLIGHTED = u"res/recentdoc_remove_highlighted.png"; +inline constexpr OUStringLiteral BMP_PIN_DOC = u"res/recentdoc_pin.png"; +inline constexpr OUStringLiteral BMP_PIN_DOC_HIGHLIGHTED = u"res/recentdoc_pin_highlighted.png"; inline constexpr OUStringLiteral BMP_DEFAULT = u"res/templatestar.png"; inline constexpr OUStringLiteral BMP_128X128_CALC_DOC = u"sfx2/res/128x128_calc_doc-p.png"; diff --git a/sfx2/inc/recentdocsview.hxx b/sfx2/inc/recentdocsview.hxx index 119bf6ee7267..38199818a34e 100644 --- a/sfx2/inc/recentdocsview.hxx +++ b/sfx2/inc/recentdocsview.hxx @@ -63,7 +63,8 @@ public: RecentDocsView(std::unique_ptr xWindow, std::unique_ptr xMenu); virtual ~RecentDocsView() override; - void insertItem(const OUString &rURL, const OUString &rTitle, const OUString& rThumbnail, bool isReadOnly, sal_uInt16 nId); + void insertItem(const OUString& rURL, const OUString& rTitle, const OUString& rThumbnail, + bool isReadOnly, bool isPinned, sal_uInt16 nId); static bool typeMatchesExtension(ApplicationType type, std::u16string_view rExt); diff --git a/sfx2/source/appl/newhelp.cxx b/sfx2/source/appl/newhelp.cxx index aae69dff4db2..5c2d7cf6c0e1 100644 --- a/sfx2/source/appl/newhelp.cxx +++ b/sfx2/source/appl/newhelp.cxx @@ -1174,7 +1174,9 @@ BookmarksTabPage_Impl::~BookmarksTabPage_Impl() const sal_Int32 nCount = m_xBookmarksBox->n_children(); for (sal_Int32 i = 0; i < nCount; ++i) { - SvtHistoryOptions::AppendItem(EHistoryType::HelpBookmarks, m_xBookmarksBox->get_id(i), "", m_xBookmarksBox->get_text(i), std::nullopt, std::nullopt); + SvtHistoryOptions::AppendItem(EHistoryType::HelpBookmarks, m_xBookmarksBox->get_id(i), "", + m_xBookmarksBox->get_text(i), std::nullopt, std::nullopt, + std::nullopt); } m_xBookmarksBox.reset(); diff --git a/sfx2/source/appl/sfxpicklist.cxx b/sfx2/source/appl/sfxpicklist.cxx index fb676d981d35..2451a8d0cad8 100644 --- a/sfx2/source/appl/sfxpicklist.cxx +++ b/sfx2/source/appl/sfxpicklist.cxx @@ -131,7 +131,8 @@ void SfxPickListImpl::AddDocumentToPickList( const SfxObjectShell* pDocSh ) aFilter, aTitle, aThumbnail, - oIsReadOnly); + oIsReadOnly, + std::nullopt); if ( aURL.GetProtocol() == INetProtocol::File ) Application::AddToRecentDocumentList( aURL.GetURLNoPass( INetURLObject::DecodeMechanism::NONE ), diff --git a/sfx2/source/control/recentdocsview.cxx b/sfx2/source/control/recentdocsview.cxx index c7c9efeb1c16..c094a4c966f8 100644 --- a/sfx2/source/control/recentdocsview.cxx +++ b/sfx2/source/control/recentdocsview.cxx @@ -144,9 +144,12 @@ bool RecentDocsView::isAcceptedFile(const INetURLObject& rURL) const (mnFileTypes & ApplicationType::TYPE_OTHER && typeMatchesExtension(ApplicationType::TYPE_OTHER, aExt)); } -void RecentDocsView::insertItem(const OUString &rURL, const OUString &rTitle, const OUString& rThumbnail, bool isReadOnly, sal_uInt16 nId) +void RecentDocsView::insertItem(const OUString& rURL, const OUString& rTitle, + const OUString& rThumbnail, bool isReadOnly, bool isPinned, + sal_uInt16 nId) { - AppendItem( std::make_unique(*this, rURL, rTitle, rThumbnail, nId, mnItemMaxSize, isReadOnly) ); + AppendItem(std::make_unique(*this, rURL, rTitle, rThumbnail, nId, + mnItemMaxSize, isReadOnly, isPinned)); } void RecentDocsView::Reload() @@ -168,7 +171,8 @@ void RecentDocsView::Reload() //Remove extension from url's last segment and use it as title const OUString aTitle = aURLObj.GetBase(); //DecodeMechanism::WithCharset - insertItem(aURL, aTitle, rRecentEntry.sThumbnail, rRecentEntry.isReadOnly, i+1); + insertItem(aURL, aTitle, rRecentEntry.sThumbnail, rRecentEntry.isReadOnly, + rRecentEntry.isPinned, i + 1); } CalculateItemPositions(); diff --git a/sfx2/source/control/recentdocsviewitem.cxx b/sfx2/source/control/recentdocsviewitem.cxx index 9af2c114988f..57a670b37c53 100644 --- a/sfx2/source/control/recentdocsviewitem.cxx +++ b/sfx2/source/control/recentdocsviewitem.cxx @@ -123,11 +123,12 @@ BitmapEx getModuleOverlay(std::u16string_view rURL) RecentDocsViewItem::RecentDocsViewItem(sfx2::RecentDocsView &rView, const OUString &rURL, const OUString &rTitle, std::u16string_view const sThumbnailBase64, sal_uInt16 const nId, tools::Long const nThumbnailSize, - bool const isReadOnly) + bool const isReadOnly, bool const isPinned) : ThumbnailViewItem(rView, nId), mrParentView(rView), maURL(rURL), m_isReadOnly(isReadOnly), + m_isPinned(isPinned), m_bRemoveIconHighlighted(false), m_aRemoveRecentBitmap(BMP_RECENTDOC_REMOVE), m_aRemoveRecentBitmapHighlighted(BMP_RECENTDOC_REMOVE_HIGHLIGHTED) @@ -230,6 +231,7 @@ RecentDocsViewItem::RecentDocsViewItem(sfx2::RecentDocsView &rView, const OUStri maTitle = aTitle; maPreview1 = aThumbnail; + mbPinned = m_isPinned; } ::tools::Rectangle RecentDocsViewItem::updateHighlight(bool bVisible, const Point& rPoint) @@ -273,7 +275,7 @@ void RecentDocsViewItem::Paint(drawinglayer::processor2d::BaseProcessor2D *pProc { ThumbnailViewItem::Paint(pProcessor, pAttrs); - // paint the remove icon when highlighted + // paint the remove icon when hovered if (isHighlighted()) { drawinglayer::primitive2d::Primitive2DContainer aSeq(1); @@ -299,6 +301,14 @@ void RecentDocsViewItem::MouseButtonUp(const MouseEvent& rMEvt) return; } + const ::tools::Rectangle aPinPosRectangle(maPinPos, maPinnedDocumentBitmap.GetSizePixel()); + if (aPinPosRectangle.Contains(rMEvt.GetPosPixel())) + { + SvtHistoryOptions::TogglePinItem(EHistoryType::PickList, maURL); + mrParent.Reload(); + return; + } + OpenDocument(); return; } diff --git a/sfx2/source/control/recentdocsviewitem.hxx b/sfx2/source/control/recentdocsviewitem.hxx index 3f5f6d3faab2..0fe399a1fe3b 100644 --- a/sfx2/source/control/recentdocsviewitem.hxx +++ b/sfx2/source/control/recentdocsviewitem.hxx @@ -20,8 +20,9 @@ namespace sfx2 class RecentDocsViewItem final : public ThumbnailViewItem { public: - RecentDocsViewItem(sfx2::RecentDocsView &rView, const OUString &rURL, - const OUString &rTitle, std::u16string_view sThumbnailBase64, sal_uInt16 nId, tools::Long nThumbnailSize, bool isReadOnly); + RecentDocsViewItem(sfx2::RecentDocsView& rView, const OUString& rURL, const OUString& rTitle, + std::u16string_view sThumbnailBase64, sal_uInt16 nId, + tools::Long nThumbnailSize, bool isReadOnly, bool isPinned); /** Updates own highlight status based on the aPoint position. @@ -51,6 +52,7 @@ private: OUString maURL; bool m_isReadOnly = false; + bool m_isPinned = false; OUString m_sHelpText; diff --git a/sfx2/source/control/thumbnailview.cxx b/sfx2/source/control/thumbnailview.cxx index e48dea30e7d5..ca839162f0a2 100644 --- a/sfx2/source/control/thumbnailview.cxx +++ b/sfx2/source/control/thumbnailview.cxx @@ -411,11 +411,25 @@ void ThumbnailView::CalculateItemPositions(bool bScrollBarUsed) // If want also draw parts of items in the last line, // then we add one more line if parts of this line are visible + bool bPinnedItems = true; size_t nCurCount = 0; for ( size_t i = 0; i < nItemCount; i++ ) { ThumbnailViewItem *const pItem = mFilteredItemList[i]; + // tdf#38742 - show pinned items in a separate line + if (bPinnedItems && !pItem->isPinned()) + { + bPinnedItems = false; + // Start a new line only if the entire line is not filled + if ((nCurCount + 1) % mnCols && nCurCount > nFirstItem) + { + x = nStartX; + y += mnItemHeight + nVItemSpace; + } + nCurCount = 0; + } + if ((nCurCount >= nFirstItem) && (nCurCount < nLastItem)) { if( !pItem->isVisible()) diff --git a/sfx2/source/control/thumbnailviewitem.cxx b/sfx2/source/control/thumbnailviewitem.cxx index 8b2b8a4ea2a4..077a9b3c6bcc 100644 --- a/sfx2/source/control/thumbnailviewitem.cxx +++ b/sfx2/source/control/thumbnailviewitem.cxx @@ -33,10 +33,15 @@ #include #include #include +#include #include #include #include #include +#include +#include +#include + using namespace basegfx; using namespace basegfx::utils; @@ -51,6 +56,10 @@ ThumbnailViewItem::ThumbnailViewItem(ThumbnailView& rView, sal_uInt16 nId) , mbBorder(true) , mbSelected(false) , mbHover(false) + , mbPinned(false) + , mbPinnedDocumentHighlighted(false) + , maPinnedDocumentBitmap(BMP_PIN_DOC) + , maPinnedDocumentBitmapHiglighted(BMP_PIN_DOC_HIGHLIGHTED) { } @@ -77,6 +86,11 @@ void ThumbnailViewItem::setHighlight (bool state) mbHover = state; } +void ThumbnailViewItem::setPinned (bool state) +{ + mbPinned = state; +} + ::tools::Rectangle ThumbnailViewItem::updateHighlight(bool bVisible, const Point& rPoint) { bool bNeedsPaint = false; @@ -94,6 +108,20 @@ void ThumbnailViewItem::setHighlight (bool state) setHighlight(false); } + const ::tools::Rectangle aPinPosRectangle(maPinPos, maPinnedDocumentBitmap.GetSizePixel()); + if (bVisible && aPinPosRectangle.Contains(rPoint)) + { + if (!mbPinnedDocumentHighlighted) + bNeedsPaint = true; + mbPinnedDocumentHighlighted = true; + } + else + { + if (mbPinnedDocumentHighlighted) + bNeedsPaint = true; + mbPinnedDocumentHighlighted = false; + } + if (bNeedsPaint) return getDrawArea(); @@ -134,6 +162,9 @@ void ThumbnailViewItem::calculateItemsPosition (const tools::Long nThumbnailHeig const Point aPos = maDrawArea.TopCenter(); maPrev1Pos = aPos + Point(-aImageSize.Width() / 2, nPadding + (nThumbnailHeight - aImageSize.Height()) / 2); + // Calculate pin position + maPinPos = maDrawArea.TopLeft() + Point(nPadding, nPadding); + // Calculate text position maTextPos = aPos + Point(-aTextDev.getTextWidth(maTitle, 0, nMaxTextLength) / 2, nThumbnailHeight + nPadding * 2); } @@ -142,7 +173,7 @@ void ThumbnailViewItem::Paint (drawinglayer::processor2d::BaseProcessor2D *pProc const ThumbnailItemAttributes *pAttrs) { BColor aFillColor = pAttrs->aFillColor; - drawinglayer::primitive2d::Primitive2DContainer aSeq(4); + drawinglayer::primitive2d::Primitive2DContainer aSeq(5); double fTransparence = 0.0; // Draw background @@ -176,6 +207,20 @@ void ThumbnailViewItem::Paint (drawinglayer::processor2d::BaseProcessor2D *pProc false) )); + // tdf#38742 - draw pinned icon + if (mbPinned) + { + const BitmapEx& aBitmapEx + = mbHover ? maPinnedDocumentBitmapHiglighted : maPinnedDocumentBitmap; + aSeq[nPrimitive++] = drawinglayer::primitive2d::Primitive2DReference( + new DiscreteBitmapPrimitive2D(aBitmapEx, B2DPoint(maPinPos.X(), maPinPos.Y()))); + } + else if (mbHover) + aSeq[nPrimitive++] + = drawinglayer::primitive2d::Primitive2DReference(new DiscreteBitmapPrimitive2D( + maPinnedDocumentBitmap, B2DPoint(maPinPos.X(), maPinPos.Y()))); + + if (mbBorder) { // draw thumbnail borders diff --git a/unotools/source/config/historyoptions.cxx b/unotools/source/config/historyoptions.cxx index 27cd3a2d97b8..7578bd190d47 100644 --- a/unotools/source/config/historyoptions.cxx +++ b/unotools/source/config/historyoptions.cxx @@ -43,6 +43,7 @@ namespace { constexpr OUStringLiteral s_sPassword = u"Password"; constexpr OUStringLiteral s_sThumbnail = u"Thumbnail"; constexpr OUStringLiteral s_sReadOnly = u"ReadOnly"; + constexpr OUStringLiteral s_sPinned = u"Pinned"; } static uno::Reference GetConfig(); @@ -54,6 +55,14 @@ static void TruncateList( const uno::Reference& xCfg, const uno::Reference& xList, sal_uInt32 nSize); + +static void PrependItem(const uno::Reference& xCfg, + uno::Reference& xList, std::u16string_view sURL); +static void MoveItemToUnpinned(const uno::Reference& xCfg, + uno::Reference& xOrderList, + uno::Reference& xItemList, + std::u16string_view sURL); + static sal_uInt32 GetCapacity(const uno::Reference& xCommonXCU, EHistoryType eHistory); namespace SvtHistoryOptions @@ -125,6 +134,8 @@ std::vector< HistoryItem > GetList( EHistoryType eHistory ) xSet->getPropertyValue(s_sPassword) >>= aItem.sPassword; xSet->getPropertyValue(s_sThumbnail) >>= aItem.sThumbnail; xSet->getPropertyValue(s_sReadOnly) >>= aItem.isReadOnly; + xSet->getPropertyValue(s_sPinned) >>= aItem.isPinned; + aRet.push_back(aItem); } catch(const uno::Exception&) @@ -147,10 +158,9 @@ std::vector< HistoryItem > GetList( EHistoryType eHistory ) return aRet; } -void AppendItem(EHistoryType eHistory, - const OUString& sURL, const OUString& sFilter, const OUString& sTitle, - const std::optional& sThumbnail, - ::std::optional const oIsReadOnly) +void AppendItem(EHistoryType eHistory, const OUString& sURL, const OUString& sFilter, + const OUString& sTitle, const std::optional& sThumbnail, + ::std::optional const oIsReadOnly, ::std::optional const oIsPinned) { try { @@ -184,33 +194,17 @@ void AppendItem(EHistoryType eHistory, { xSet->setPropertyValue(s_sReadOnly, uno::Any(*oIsReadOnly)); } - - for (sal_Int32 i=0; igetByName(OUString::number(i)) >>= xSet; - xSet->getPropertyValue(s_sHistoryItemRef) >>= aItem; - - if (aItem == sURL) - { - for (sal_Int32 j = i - 1; j >= 0; --j) - { - uno::Reference xPrevSet; - uno::Reference xNextSet; - xOrderList->getByName(OUString::number(j+1)) >>= xPrevSet; - xOrderList->getByName(OUString::number(j)) >>= xNextSet; - - OUString sTemp; - xNextSet->getPropertyValue(s_sHistoryItemRef) >>= sTemp; - xPrevSet->setPropertyValue(s_sHistoryItemRef, uno::Any(sTemp)); - } - xOrderList->getByName(OUString::number(0)) >>= xSet; - xSet->setPropertyValue(s_sHistoryItemRef, uno::Any(aItem)); - break; - } + xSet->setPropertyValue(s_sPinned, uno::Any(*oIsPinned)); + if (*oIsPinned) + PrependItem(xCfg, xOrderList, sURL); + else + MoveItemToUnpinned(xCfg, xOrderList, xItemList, sURL); } + else + MoveItemToUnpinned(xCfg, xOrderList, xItemList, sURL); - ::comphelper::ConfigurationHelper::flush(xCfg); } else // The item to be appended does not exist yet { @@ -276,6 +270,10 @@ void AppendItem(EHistoryType eHistory, { xSet->setPropertyValue(s_sReadOnly, uno::Any(*oIsReadOnly)); } + if (oIsPinned) + { + xSet->setPropertyValue(s_sPinned, uno::Any(*oIsPinned)); + } ::comphelper::ConfigurationHelper::flush(xCfg); } @@ -348,6 +346,43 @@ void DeleteItem(EHistoryType eHistory, const OUString& sURL) } } +void TogglePinItem(EHistoryType eHistory, const OUString& sURL) +{ + try + { + uno::Reference xCfg = GetConfig(); + uno::Reference xListAccess(GetListAccess(xCfg, eHistory)); + + uno::Reference xItemList; + xListAccess->getByName(s_sItemList) >>= xItemList; + + // Check if item exists + if (xItemList->hasByName(sURL)) + { + // Toggle pinned option + uno::Reference xSet; + xItemList->getByName(sURL) >>= xSet; + bool bIsItemPinned = false; + if (xSet->getPropertySetInfo()->hasPropertyByName(s_sPinned)) + xSet->getPropertyValue(s_sPinned) >>= bIsItemPinned; + xSet->setPropertyValue(s_sPinned, uno::Any(!bIsItemPinned)); + + uno::Reference xOrderList; + xListAccess->getByName(s_sOrderList) >>= xOrderList; + + // Shift item to the beginning of the document list if is not pinned now + if (bIsItemPinned) + MoveItemToUnpinned(xCfg, xOrderList, xItemList, sURL); + else + PrependItem(xCfg, xOrderList, sURL); + } + } + catch (const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("unotools.config"); + } +} + } // namespace @@ -417,7 +452,81 @@ static void TruncateList( ::comphelper::ConfigurationHelper::flush(xCfg); } +static void PrependItem(const uno::Reference& xCfg, + uno::Reference& xList, std::u16string_view sURL) +{ + uno::Reference xSet; + const sal_Int32 nLength = xList->getElementNames().getLength(); + for (sal_Int32 i = 0; i < nLength; i++) + { + OUString aItem; + xList->getByName(OUString::number(i)) >>= xSet; + xSet->getPropertyValue(s_sHistoryItemRef) >>= aItem; + + if (aItem == sURL) + { + for (sal_Int32 j = i - 1; j >= 0; --j) + { + uno::Reference xPrevSet; + uno::Reference xNextSet; + xList->getByName(OUString::number(j + 1)) >>= xPrevSet; + xList->getByName(OUString::number(j)) >>= xNextSet; + OUString sTemp; + xNextSet->getPropertyValue(s_sHistoryItemRef) >>= sTemp; + xPrevSet->setPropertyValue(s_sHistoryItemRef, uno::Any(sTemp)); + } + xList->getByName(OUString::number(0)) >>= xSet; + xSet->setPropertyValue(s_sHistoryItemRef, uno::Any(aItem)); + ::comphelper::ConfigurationHelper::flush(xCfg); + return; + } + } +} + +static void MoveItemToUnpinned(const uno::Reference& xCfg, + uno::Reference& xOrderList, + uno::Reference& xItemList, + std::u16string_view sURL) +{ + uno::Reference xSet; + const sal_Int32 nLength = xOrderList->getElementNames().getLength(); + // Search for item in the ordered list list + for (sal_Int32 i = 0; i < nLength; i++) + { + OUString aItem; + xOrderList->getByName(OUString::number(i)) >>= xSet; + xSet->getPropertyValue(s_sHistoryItemRef) >>= aItem; + + if (aItem == sURL) + { + // Move item to the unpinned document section + for (sal_Int32 j = i + 1; j < nLength - 1; j++) + { + uno::Reference xNextSet; + xOrderList->getByName(OUString::number(j)) >>= xNextSet; + + OUString aNextItem; + xNextSet->getPropertyValue(s_sHistoryItemRef) >>= aNextItem; + + uno::Reference xNextItemSet; + xItemList->getByName(aNextItem) >>= xNextItemSet; + bool bIsItemPinned = false; + if (xNextItemSet->getPropertySetInfo()->hasPropertyByName(s_sPinned)) + xNextItemSet->getPropertyValue(s_sPinned) >>= bIsItemPinned; + if (bIsItemPinned) + { + xSet->setPropertyValue(s_sHistoryItemRef, uno::Any(aNextItem)); + xNextSet->setPropertyValue(s_sHistoryItemRef, uno::Any(aItem)); + } + else + break; + } + ::comphelper::ConfigurationHelper::flush(xCfg); + return; + } + } +} static sal_uInt32 GetCapacity(const uno::Reference& xCommonXCU, EHistoryType eHistory) { -- cgit