include/vcl/weld.hxx | 7 sd/Library_sd.mk | 1 sd/source/ui/sidebar/AllMasterPagesSelector.cxx | 12 sd/source/ui/sidebar/CurrentMasterPagesSelector.cxx | 25 - sd/source/ui/sidebar/MasterPagesSelector.cxx | 271 +++++++++----------- sd/source/ui/sidebar/MasterPagesSelector.hxx | 33 +- sd/source/ui/sidebar/PreviewValueSet.cxx | 127 --------- sd/source/ui/sidebar/PreviewValueSet.hxx | 59 ---- sd/source/ui/sidebar/RecentMasterPagesSelector.cxx | 28 -- sd/source/ui/sidebar/RecentMasterPagesSelector.hxx | 14 - sd/uiconfig/simpress/ui/masterpagepanel.ui | 41 ++- sd/uiconfig/simpress/ui/masterpagepanelall.ui | 41 ++- sd/uiconfig/simpress/ui/masterpagepanelrecent.ui | 41 ++- solenv/clang-format/excludelist | 1 vcl/inc/salvtables.hxx | 16 + vcl/source/app/salvtables.cxx | 94 ++++++ vcl/unx/gtk3/gtkinst.cxx | 101 +++++++ 17 files changed, 484 insertions(+), 428 deletions(-)
New commits: commit a36a58933a1e07d3f54bacd5c2fe8ca53063a63a Author: Rashesh <[email protected]> AuthorDate: Mon Nov 25 17:07:59 2024 +0530 Commit: Tomaž Vajngerl <[email protected]> CommitDate: Wed Dec 4 07:40:30 2024 +0100 sd: convert sidebar masterpage panels from drawingview to iconview - also removes unused PreviewValueSet Change-Id: I5e7dacb4f472de526a61366295bc91edca12e9ac Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177642 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <[email protected]> diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index d68bced12c04..715beb742a4e 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -1484,8 +1484,14 @@ public: virtual OUString get_selected_text() const = 0; //by index. Don't select when frozen, select after thaw. Note selection doesn't survive a freeze. + virtual OUString get_id(int pos) const = 0; virtual void select(int pos) = 0; virtual void unselect(int pos) = 0; + virtual void set_image(int pos, VirtualDevice* pDevice) = 0; + virtual void set_text(int pos, const OUString& rText) = 0; + virtual void set_id(int pos, const OUString& rId) = 0; + virtual void remove(int pos) = 0; + virtual tools::Rectangle get_rect(int pos) const = 0; //via iter virtual std::unique_ptr<TreeIter> make_iterator(const TreeIter* pOrig = nullptr) const = 0; @@ -1495,6 +1501,7 @@ public: virtual bool get_iter_first(TreeIter& rIter) const = 0; virtual OUString get_id(const TreeIter& rIter) const = 0; virtual OUString get_text(const TreeIter& rIter) const = 0; + virtual bool iter_next_sibling(TreeIter& rIter) const = 0; virtual void scroll_to_item(const TreeIter& rIter) = 0; // call func on each selected element until func returns true or we run out of elements diff --git a/sd/Library_sd.mk b/sd/Library_sd.mk index 0a85cd6229ca..df3309c6d78d 100644 --- a/sd/Library_sd.mk +++ b/sd/Library_sd.mk @@ -362,7 +362,6 @@ $(eval $(call gb_Library_add_exception_objects,sd,\ sd/source/ui/sidebar/MasterPagesSelector \ sd/source/ui/sidebar/NavigatorWrapper \ sd/source/ui/sidebar/PanelFactory \ - sd/source/ui/sidebar/PreviewValueSet \ sd/source/ui/sidebar/RecentlyUsedMasterPages \ sd/source/ui/sidebar/RecentMasterPagesSelector \ sd/source/ui/sidebar/SlideBackground \ diff --git a/sd/source/ui/sidebar/AllMasterPagesSelector.cxx b/sd/source/ui/sidebar/AllMasterPagesSelector.cxx index 70251b8cc740..fdd8ea4618f8 100644 --- a/sd/source/ui/sidebar/AllMasterPagesSelector.cxx +++ b/sd/source/ui/sidebar/AllMasterPagesSelector.cxx @@ -97,14 +97,14 @@ std::unique_ptr<PanelLayout> AllMasterPagesSelector::Create ( return xSelector; } -AllMasterPagesSelector::AllMasterPagesSelector ( - weld::Widget* pParent, - SdDrawDocument& rDocument, - ViewShellBase& rBase, +AllMasterPagesSelector::AllMasterPagesSelector( + weld::Widget* pParent, SdDrawDocument& rDocument, ViewShellBase& rBase, const std::shared_ptr<MasterPageContainer>& rpContainer, const css::uno::Reference<css::ui::XSidebar>& rxSidebar) - : MasterPagesSelector(pParent, rDocument, rBase, rpContainer, rxSidebar, u"modules/simpress/ui/masterpagepanelall.ui"_ustr, u"allvalueset"_ustr), - mpSortedMasterPages(new SortedMasterPageDescriptorList()) + : MasterPagesSelector(pParent, rDocument, rBase, rpContainer, rxSidebar, + u"modules/simpress/ui/masterpagepanelall.ui"_ustr, + u"masterpageall_icons"_ustr) + , mpSortedMasterPages(new SortedMasterPageDescriptorList()) { MasterPagesSelector::Fill(); } diff --git a/sd/source/ui/sidebar/CurrentMasterPagesSelector.cxx b/sd/source/ui/sidebar/CurrentMasterPagesSelector.cxx index 2e3bd5a4ede7..c1ac330b7314 100644 --- a/sd/source/ui/sidebar/CurrentMasterPagesSelector.cxx +++ b/sd/source/ui/sidebar/CurrentMasterPagesSelector.cxx @@ -18,7 +18,6 @@ */ #include "CurrentMasterPagesSelector.hxx" -#include "PreviewValueSet.hxx" #include <ViewShellBase.hxx> #include <DrawViewShell.hxx> #include <drawdoc.hxx> @@ -61,15 +60,16 @@ std::unique_ptr<PanelLayout> CurrentMasterPagesSelector::Create ( return xSelector; } -CurrentMasterPagesSelector::CurrentMasterPagesSelector ( - weld::Widget* pParent, - SdDrawDocument& rDocument, - ViewShellBase& rBase, +CurrentMasterPagesSelector::CurrentMasterPagesSelector( + weld::Widget* pParent, SdDrawDocument& rDocument, ViewShellBase& rBase, const std::shared_ptr<MasterPageContainer>& rpContainer, const css::uno::Reference<css::ui::XSidebar>& rxSidebar) - : MasterPagesSelector (pParent, rDocument, rBase, rpContainer, rxSidebar, u"modules/simpress/ui/masterpagepanel.ui"_ustr, u"usedvalueset"_ustr) + : MasterPagesSelector(pParent, rDocument, rBase, rpContainer, rxSidebar, + u"modules/simpress/ui/masterpagepanel.ui"_ustr, + u"masterpagecurrent_icons"_ustr) { - Link<sd::tools::EventMultiplexerEvent&,void> aLink (LINK(this,CurrentMasterPagesSelector,EventMultiplexerListener)); + Link<sd::tools::EventMultiplexerEvent&, void> aLink( + LINK(this, CurrentMasterPagesSelector, EventMultiplexerListener)); rBase.GetEventMultiplexer()->AddEventListener(aLink); } @@ -176,17 +176,6 @@ void CurrentMasterPagesSelector::UpdateSelection() } } } - - // Find the items for the master pages in the set. - sal_uInt16 nItemCount (mxPreviewValueSet->GetItemCount()); - for (nIndex=1; nIndex<=nItemCount && bLoop; nIndex++) - { - OUString sName (mxPreviewValueSet->GetItemText (nIndex)); - if (aNames.find(sName) != aNames.end()) - { - mxPreviewValueSet->SelectItem (nIndex); - } - } } void CurrentMasterPagesSelector::ExecuteCommand(const OUString &rIdent) diff --git a/sd/source/ui/sidebar/MasterPagesSelector.cxx b/sd/source/ui/sidebar/MasterPagesSelector.cxx index c1417dd538ce..2ee57bca11c3 100644 --- a/sd/source/ui/sidebar/MasterPagesSelector.cxx +++ b/sd/source/ui/sidebar/MasterPagesSelector.cxx @@ -32,7 +32,7 @@ #include <DrawController.hxx> #include <SlideSorterViewShell.hxx> -#include "PreviewValueSet.hxx" +#include <vcl/vclptr.hxx> #include <ViewShellBase.hxx> #include <o3tl/safeint.hxx> #include <vcl/image.hxx> @@ -40,6 +40,7 @@ #include <sfx2/viewfrm.hxx> #include <sfx2/sidebar/Theme.hxx> #include <memory> +#include <vcl/virdev.hxx> namespace sd::sidebar { @@ -48,35 +49,22 @@ namespace sd::sidebar { */ constexpr OUStringLiteral gsDefaultClickAction = u"applyselect"; -MasterPagesSelector::MasterPagesSelector ( - weld::Widget* pParent, - SdDrawDocument& rDocument, - ViewShellBase& rBase, - std::shared_ptr<MasterPageContainer> pContainer, - css::uno::Reference<css::ui::XSidebar> xSidebar, - const OUString& rUIFileName, - const OUString& rValueSetName) - : PanelLayout( pParent, u"MasterPagePanel"_ustr, rUIFileName ), - mpContainer(std::move(pContainer)), - mxPreviewValueSet(new PreviewValueSet), - mxPreviewValueSetWin(new weld::CustomWeld(*m_xBuilder, rValueSetName, *mxPreviewValueSet)), - mrDocument(rDocument), - mrBase(rBase), - mxSidebar(std::move(xSidebar)) -{ - mxPreviewValueSet->SetSelectHdl ( - LINK(this, MasterPagesSelector, ClickHandler)); - mxPreviewValueSet->SetContextMenuHandler ( - LINK(this, MasterPagesSelector, ContextMenuHandler)); - mxPreviewValueSet->SetStyle(mxPreviewValueSet->GetStyle() | WB_NO_DIRECTSELECT); - - if (mxPreviewValueSet->GetDrawingArea()->get_ref_device().GetDPIScaleFactor() > 1) - mpContainer->SetPreviewSize(MasterPageContainer::LARGE); - - mxPreviewValueSet->SetPreviewSize(mpContainer->GetPreviewSizePixel()); - mxPreviewValueSet->Show(); - - mxPreviewValueSet->SetColor(sfx2::sidebar::Theme::GetColor(sfx2::sidebar::Theme::Color_PanelBackground)); +MasterPagesSelector::MasterPagesSelector(weld::Widget* pParent, SdDrawDocument& rDocument, + ViewShellBase& rBase, + std::shared_ptr<MasterPageContainer> pContainer, + css::uno::Reference<css::ui::XSidebar> xSidebar, + const OUString& rUIFileName, const OUString& rIconViewId) + : PanelLayout(pParent, u"MasterPagePanel"_ustr, rUIFileName) + , mpContainer(std::move(pContainer)) + , mxPreviewIconView(m_xBuilder->weld_icon_view(rIconViewId)) + , mrDocument(rDocument) + , mrBase(rBase) + , mxSidebar(std::move(xSidebar)) + , maIconViewId(rIconViewId) +{ + mxPreviewIconView->connect_item_activated(LINK(this, MasterPagesSelector, MasterPageSelected)); + mxPreviewIconView->connect_mouse_press(LINK(this, MasterPagesSelector, MousePressHdl)); + mxPreviewIconView->connect_query_tooltip(LINK(this, MasterPagesSelector, QueryTooltipHdl)); Link<MasterPageContainerChangeEvent&,void> aChangeListener (LINK(this,MasterPagesSelector,ContainerChangeListener)); mpContainer->AddChangeListener(aChangeListener); @@ -90,21 +78,13 @@ MasterPagesSelector::~MasterPagesSelector() Link<MasterPageContainerChangeEvent&,void> aChangeListener (LINK(this,MasterPagesSelector,ContainerChangeListener)); mpContainer->RemoveChangeListener(aChangeListener); mpContainer.reset(); - mxPreviewValueSetWin.reset(); - mxPreviewValueSet.reset(); + mxPreviewIconView.reset(); } void MasterPagesSelector::LateInit() { } -sal_Int32 MasterPagesSelector::GetPreferredHeight (sal_Int32 nWidth) -{ - const ::osl::MutexGuard aGuard (maMutex); - - return mxPreviewValueSet->GetPreferredHeight (nWidth); -} - void MasterPagesSelector::UpdateLocks (const ItemList& rItemList) { ItemList aNewLockList; @@ -144,61 +124,50 @@ OUString MasterPagesSelector::GetContextMenuUIFile() const return u"modules/simpress/ui/mastermenu.ui"_ustr; } -IMPL_LINK_NOARG(MasterPagesSelector, ClickHandler, ValueSet*, void) +IMPL_LINK_NOARG(MasterPagesSelector, MasterPageSelected, weld::IconView&, bool) { - // We use the framework to assign the clicked-on master page because we - // so use the same mechanism as the context menu does (where we do not - // have the option to call the assignment method directly.) ExecuteCommand(gsDefaultClickAction); + return true; } -IMPL_LINK(MasterPagesSelector, ContextMenuHandler, const Point*, pPos, void) +IMPL_LINK(MasterPagesSelector, MousePressHdl, const MouseEvent&, rMEvet, bool) { - if (pPos) + if (!rMEvet.IsRight()) + return false; + + const Point& pPos = rMEvet.GetPosPixel(); + for (int i = 0; i < mxPreviewIconView->n_children(); i++) { - // Here we only prepare the display of the context menu: on right - // click the item under the mouse is selected. - mxPreviewValueSet->GrabFocus(); - mxPreviewValueSet->ReleaseMouse(); - - sal_uInt16 nIndex = mxPreviewValueSet->GetItemId(*pPos); - if (nIndex > 0) - mxPreviewValueSet->SelectItem(nIndex); + const ::tools::Rectangle aRect = mxPreviewIconView->get_rect(i); + if (aRect.Contains(pPos)) + { + mxPreviewIconView->select(i); + ShowContextMenu(pPos); + break; + } } - - // Now do the actual display of the context menu - ShowContextMenu(pPos); + return false; } -void MasterPagesSelector::ShowContextMenu(const Point* pPos) +IMPL_LINK(MasterPagesSelector, QueryTooltipHdl, const weld::TreeIter&, iter, OUString) { - // Use the currently selected item and show the popup menu in its - // center. - const sal_uInt16 nIndex = mxPreviewValueSet->GetSelectedItemId(); - if (nIndex <= 0) - return; + const OUString sId = mxPreviewIconView->get_id(iter); + if (!sId.isEmpty()) + return mpContainer->GetPageNameForToken(sId.toUInt32()); - // The position of the upper left corner of the context menu is - // taken either from the mouse position (when the command was sent - // as reaction to a right click) or in the center of the selected - // item (when the command was sent as reaction to Shift+F10.) - Point aPosition; - if (!pPos) - { - ::tools::Rectangle aBBox (mxPreviewValueSet->GetItemRect(nIndex)); - aPosition = aBBox.Center(); - } - else - aPosition = *pPos; + return OUString(); +} +void MasterPagesSelector::ShowContextMenu(const Point& pPos) +{ // Setup the menu. - weld::Widget* pParent = mxPreviewValueSet->GetDrawingArea(); - std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pParent, GetContextMenuUIFile())); + ::tools::Rectangle aRect(pPos, Size(1, 1)); + std::unique_ptr<weld::Builder> xBuilder( + Application::CreateBuilder(mxPreviewIconView.get(), GetContextMenuUIFile())); std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu(u"menu"_ustr)); ProcessPopupMenu(*xMenu); - ::tools::Rectangle aRect(aPosition, Size(1,1)); // Show the menu. - ExecuteCommand(xMenu->popup_at_rect(pParent, aRect)); + ExecuteCommand(xMenu->popup_at_rect(mxPreviewIconView.get(), aRect)); } void MasterPagesSelector::ProcessPopupMenu(weld::Menu& rMenu) @@ -254,13 +223,12 @@ void MasterPagesSelector::ExecuteCommand(const OUString &rIdent) SfxDispatcher* pDispatcher = rViewFrame.GetDispatcher(); if (pDispatcher != nullptr) { - sal_uInt16 nIndex = mxPreviewValueSet->GetSelectedItemId(); pDispatcher->Execute(SID_MASTERPAGE, SfxCallMode::SYNCHRON); - mxPreviewValueSet->SelectItem (nIndex); mrBase.GetDrawController()->setCurrentPage(xSelectedMaster); } } } + mxPreviewIconView->unselect_all(); } IMPL_LINK(MasterPagesSelector, ContainerChangeListener, MasterPageContainerChangeEvent&, rEvent, void) @@ -273,11 +241,13 @@ SdPage* MasterPagesSelector::GetSelectedMasterPage() const ::osl::MutexGuard aGuard (maMutex); SdPage* pMasterPage = nullptr; - sal_uInt16 nIndex = mxPreviewValueSet->GetSelectedItemId(); - UserData* pData = GetUserData(nIndex); - if (pData != nullptr) + OUString sSelectedId = mxPreviewIconView->get_selected_id(); + + if (!sSelectedId.isEmpty()) { - pMasterPage = mpContainer->GetPageObjectForToken(pData->second, true); + const MasterPageContainer::Token aToken + = static_cast<MasterPageContainer::Token>(sSelectedId.toInt32()); + pMasterPage = mpContainer->GetPageObjectForToken(aToken, true); } return pMasterPage; } @@ -354,7 +324,6 @@ void MasterPagesSelector::NotifyContainerChangeEvent (const MasterPageContainerC switch (rEvent.meEventType) { case MasterPageContainerChangeEvent::EventType::SIZE_CHANGED: - mxPreviewValueSet->SetPreviewSize(mpContainer->GetPreviewSizePixel()); UpdateAllPreviews(); break; @@ -363,10 +332,12 @@ void MasterPagesSelector::NotifyContainerChangeEvent (const MasterPageContainerC int nIndex (GetIndexForToken(rEvent.maChildToken)); if (nIndex >= 0) { - mxPreviewValueSet->SetItemImage ( - static_cast<sal_uInt16>(nIndex), - mpContainer->GetPreviewForToken(rEvent.maChildToken)); - mxPreviewValueSet->Invalidate(mxPreviewValueSet->GetItemRect(static_cast<sal_uInt16>(nIndex))); + Image aPreview(mpContainer->GetPreviewForToken(rEvent.maChildToken)); + if (aPreview.GetSizePixel().Width() > 0) + { + VclPtr<VirtualDevice> aDev = GetVirtualDevice(aPreview); + mxPreviewIconView->set_image(nIndex, aDev); + } } } break; @@ -390,58 +361,50 @@ void MasterPagesSelector::NotifyContainerChangeEvent (const MasterPageContainerC } } -MasterPagesSelector::UserData* MasterPagesSelector::GetUserData (int nIndex) const +std::unique_ptr<MasterPagesSelector::UserData> MasterPagesSelector::GetUserData(int nIndex) const { - const ::osl::MutexGuard aGuard (maMutex); + const ::osl::MutexGuard aGuard(maMutex); - if (nIndex>0 && o3tl::make_unsigned(nIndex)<=mxPreviewValueSet->GetItemCount()) - return static_cast<UserData*>(mxPreviewValueSet->GetItemData(static_cast<sal_uInt16>(nIndex))); + if (nIndex >= 0 && nIndex < mxPreviewIconView->n_children()) + { + const MasterPageContainer::Token aToken + = static_cast<MasterPageContainer::Token>(mxPreviewIconView->get_id(nIndex).toInt32()); + return std::make_unique<UserData>(std::make_pair(nIndex, aToken)); + } else return nullptr; } -void MasterPagesSelector::SetUserData (int nIndex, std::unique_ptr<UserData> pData) -{ - const ::osl::MutexGuard aGuard (maMutex); - - delete GetUserData(nIndex); - mxPreviewValueSet->SetItemData(static_cast<sal_uInt16>(nIndex), pData.release()); -} - void MasterPagesSelector::SetItem ( sal_uInt16 nIndex, MasterPageContainer::Token aToken) { const ::osl::MutexGuard aGuard (maMutex); - RemoveTokenToIndexEntry(nIndex,aToken); + RemoveTokenToIndexEntry(nIndex, aToken); - if (nIndex <= 0) - return; + mxPreviewIconView->freeze(); if (aToken != MasterPageContainer::NIL_TOKEN) { Image aPreview (mpContainer->GetPreviewForToken(aToken)); MasterPageContainer::PreviewState eState (mpContainer->GetPreviewState(aToken)); - if (aPreview.GetSizePixel().Width()>0) + if (aPreview.GetSizePixel().Width() > 0) { - if (mxPreviewValueSet->GetItemPos(nIndex) != VALUESET_ITEM_NOTFOUND) + VclPtr<VirtualDevice> aVDev = GetVirtualDevice(aPreview); + if (!mxPreviewIconView->get_id(nIndex).isEmpty()) { - mxPreviewValueSet->SetItemImage(nIndex,aPreview); - mxPreviewValueSet->SetItemText(nIndex, mpContainer->GetPageNameForToken(aToken)); + mxPreviewIconView->set_image(nIndex, aVDev); + mxPreviewIconView->set_id(nIndex, OUString::number(aToken)); } else { - mxPreviewValueSet->InsertItem ( - nIndex, - aPreview, - mpContainer->GetPageNameForToken(aToken), - nIndex); + OUString sId = OUString::number(aToken); + mxPreviewIconView->insert(nIndex, nullptr, &sId, aVDev, nullptr); } - SetUserData(nIndex, std::make_unique<UserData>(nIndex,aToken)); - AddTokenToIndexEntry(nIndex,aToken); + AddTokenToIndexEntry(nIndex, aToken); } if (eState == MasterPageContainer::PS_CREATABLE) @@ -449,9 +412,9 @@ void MasterPagesSelector::SetItem ( } else { - mxPreviewValueSet->RemoveItem(nIndex); + mxPreviewIconView->remove(nIndex); } - + mxPreviewIconView->thaw(); } void MasterPagesSelector::AddTokenToIndexEntry ( @@ -469,7 +432,7 @@ void MasterPagesSelector::RemoveTokenToIndexEntry ( { const ::osl::MutexGuard aGuard (maMutex); - UserData* pData = GetUserData(nIndex); + std::unique_ptr<UserData> pData = GetUserData(nIndex); if (pData != nullptr) { // Get the token that the index pointed to previously. @@ -478,7 +441,7 @@ void MasterPagesSelector::RemoveTokenToIndexEntry ( if (aNewToken != aOldToken && nIndex == GetIndexForToken(aOldToken)) { - maTokenToValueSetIndex[aOldToken] = 0; + maTokenToValueSetIndex[aOldToken] = -1; } } } @@ -487,9 +450,9 @@ void MasterPagesSelector::InvalidatePreview (const SdPage* pPage) { const ::osl::MutexGuard aGuard (maMutex); - for (size_t nIndex=1; nIndex<=mxPreviewValueSet->GetItemCount(); nIndex++) + for (int nIndex = 0; nIndex < mxPreviewIconView->n_children(); nIndex++) { - UserData* pData = GetUserData(nIndex); + std::unique_ptr<UserData> pData = GetUserData(nIndex); if (pData != nullptr) { MasterPageContainer::Token aToken (pData->second); @@ -503,43 +466,54 @@ void MasterPagesSelector::InvalidatePreview (const SdPage* pPage) } } +VclPtr<VirtualDevice> MasterPagesSelector::GetVirtualDevice(Image pImage) +{ + BitmapEx aPreviewBitmap = pImage.GetBitmapEx(); + VclPtr<VirtualDevice> pVDev = VclPtr<VirtualDevice>::Create(); + const Point aNull(0, 0); + if (pVDev->GetDPIScaleFactor() > 1) + aPreviewBitmap.Scale(pVDev->GetDPIScaleFactor(), pVDev->GetDPIScaleFactor()); + const Size aSize(aPreviewBitmap.GetSizePixel()); + pVDev->SetOutputSizePixel(aSize); + pVDev->DrawBitmapEx(aNull, aPreviewBitmap); + + return pVDev; +} + void MasterPagesSelector::UpdateAllPreviews() { const ::osl::MutexGuard aGuard (maMutex); - for (size_t nIndex=1; nIndex<=mxPreviewValueSet->GetItemCount(); nIndex++) + mxPreviewIconView->freeze(); + for (int aIndex = 0; aIndex < mxPreviewIconView->n_children(); aIndex++) { - UserData* pData = GetUserData(nIndex); - if (pData != nullptr) + const MasterPageContainer::Token aToken + = static_cast<MasterPageContainer::Token>(mxPreviewIconView->get_id(aIndex).toInt32()); + + Image aPreview(mpContainer->GetPreviewForToken(aToken)); + if (aPreview.GetSizePixel().Width() > 0) { - MasterPageContainer::Token aToken (pData->second); - mxPreviewValueSet->SetItemImage( - nIndex, - mpContainer->GetPreviewForToken(aToken)); - if (mpContainer->GetPreviewState(aToken) == MasterPageContainer::PS_CREATABLE) - mpContainer->RequestPreview(aToken); + VclPtr<VirtualDevice> pVDev = GetVirtualDevice(aPreview); + mxPreviewIconView->set_image(aIndex, pVDev); + } + else if (mpContainer->GetPreviewState(aToken) == MasterPageContainer::PS_CREATABLE) + { + mpContainer->RequestPreview(aToken); } } - mxPreviewValueSet->Rearrange(); + mxPreviewIconView->thaw(); } void MasterPagesSelector::ClearPageSet() { const ::osl::MutexGuard aGuard (maMutex); - - for (size_t nIndex=1; nIndex<=mxPreviewValueSet->GetItemCount(); nIndex++) - { - UserData* pData = GetUserData(nIndex); - delete pData; - } - mxPreviewValueSet->Clear(); + mxPreviewIconView->clear(); } void MasterPagesSelector::SetHelpId( const OUString& aId ) { const ::osl::MutexGuard aGuard (maMutex); - - mxPreviewValueSet->SetHelpId( aId ); + mxPreviewIconView->set_help_id(aId); } sal_Int32 MasterPagesSelector::GetIndexForToken (MasterPageContainer::Token aToken) const @@ -577,7 +551,7 @@ void MasterPagesSelector::UpdateItemList (::std::unique_ptr<ItemList> && pNewIte ItemList::const_iterator iCurrentItem (maCurrentItemList.begin()); ItemList::const_iterator iNewEnd (pNewItemList->end()); ItemList::const_iterator iCurrentEnd (maCurrentItemList.end()); - sal_uInt16 nIndex (1); + sal_uInt16 nIndex(0); // Update existing items. for ( ; iNewItem!=iNewEnd && iCurrentItem!=iCurrentEnd; ++iNewItem, ++iCurrentItem,++nIndex) @@ -602,15 +576,22 @@ void MasterPagesSelector::UpdateItemList (::std::unique_ptr<ItemList> && pNewIte maCurrentItemList.swap(*pNewItemList); - mxPreviewValueSet->Rearrange(); if (mxSidebar.is()) mxSidebar->requestLayout(); } -css::ui::LayoutSize MasterPagesSelector::GetHeightForWidth (const sal_Int32 nWidth) +css::ui::LayoutSize MasterPagesSelector::GetHeightForWidth(const sal_Int32 nWidth) { - const sal_Int32 nHeight (GetPreferredHeight(nWidth)); - return css::ui::LayoutSize(nHeight,nHeight,nHeight); + if (maIconViewId == "masterpageall_icons") + return css::ui::LayoutSize(-1, -1, -1); + + const sal_uInt32 nItemWidth = mxPreviewIconView->get_item_width(); + sal_Int32 nMinimumHeight = mxPreviewIconView->get_preferred_size().getHeight(); + const sal_Int32 itemsInRows = floor(nWidth / nItemWidth); + sal_Int32 totalItems = mxPreviewIconView->n_children(); + if (itemsInRows > 0) + nMinimumHeight = ((totalItems / itemsInRows) + 1) * nMinimumHeight; + return css::ui::LayoutSize(nMinimumHeight, nMinimumHeight, nMinimumHeight); } } // end of namespace sd::sidebar diff --git a/sd/source/ui/sidebar/MasterPagesSelector.hxx b/sd/source/ui/sidebar/MasterPagesSelector.hxx index f0a540bade1b..3eaf9851e317 100644 --- a/sd/source/ui/sidebar/MasterPagesSelector.hxx +++ b/sd/source/ui/sidebar/MasterPagesSelector.hxx @@ -22,7 +22,10 @@ #include <map> #include <memory> #include "MasterPageContainer.hxx" -#include "PreviewValueSet.hxx" +#include <vcl/image.hxx> +#include <vcl/vclptr.hxx> +#include <vcl/virdev.hxx> +#include <vcl/weld.hxx> #include <sfx2/sidebar/ILayoutableWindow.hxx> #include <sfx2/sidebar/PanelLayout.hxx> @@ -46,14 +49,10 @@ class MasterPagesSelector : public PanelLayout , public sfx2::sidebar::ILayoutableWindow { public: - MasterPagesSelector ( - weld::Widget* pParent, - SdDrawDocument& rDocument, - ViewShellBase& rBase, - std::shared_ptr<MasterPageContainer> pContainer, - css::uno::Reference<css::ui::XSidebar> xSidebar, - const OUString& rUIFileName, - const OUString& rValueSetName); + MasterPagesSelector(weld::Widget* pParent, SdDrawDocument& rDocument, ViewShellBase& rBase, + std::shared_ptr<MasterPageContainer> pContainer, + css::uno::Reference<css::ui::XSidebar> xSidebar, + const OUString& rUIFileName, const OUString& rIconViewId); virtual ~MasterPagesSelector() override; virtual void LateInit(); @@ -80,7 +79,7 @@ public: void UpdateAllPreviews(); - void ShowContextMenu(const Point* pPos); + void ShowContextMenu(const Point& pPos); // ILayoutableWindow virtual css::ui::LayoutSize GetHeightForWidth (const sal_Int32 nWidth) override; @@ -89,8 +88,7 @@ protected: mutable ::osl::Mutex maMutex; std::shared_ptr<MasterPageContainer> mpContainer; - std::unique_ptr<PreviewValueSet> mxPreviewValueSet; - std::unique_ptr<weld::CustomWeld> mxPreviewValueSetWin; + std::unique_ptr<weld::IconView> mxPreviewIconView; SdDrawDocument& mrDocument; ViewShellBase& mrBase; @@ -117,8 +115,7 @@ protected: virtual void NotifyContainerChangeEvent (const MasterPageContainerChangeEvent& rEvent); typedef ::std::pair<int, MasterPageContainer::Token> UserData; - UserData* GetUserData (int nIndex) const; - void SetUserData (int nIndex, std::unique_ptr<UserData> pData); + std::unique_ptr<MasterPagesSelector::UserData> GetUserData(int nIndex) const; sal_Int32 GetIndexForToken (MasterPageContainer::Token aToken) const; typedef ::std::vector<MasterPageContainer::Token> ItemList; @@ -155,14 +152,16 @@ protected: private: css::uno::Reference<css::ui::XSidebar> mxSidebar; + OUString maIconViewId; /** The offset between ValueSet index and MasterPageContainer::Token last seen. This value is used heuristically to speed up the lookup of an index for a token. */ - DECL_LINK(ClickHandler, ValueSet*, void); - DECL_LINK(ContextMenuHandler, const Point*, void); + DECL_LINK(MasterPageSelected, weld::IconView&, bool); + DECL_LINK(MousePressHdl, const MouseEvent&, bool); DECL_LINK(ContainerChangeListener, MasterPageContainerChangeEvent&, void); + DECL_LINK(QueryTooltipHdl, const weld::TreeIter&, OUString); void SetItem ( sal_uInt16 nIndex, @@ -173,6 +172,8 @@ private: void RemoveTokenToIndexEntry ( sal_uInt16 nIndex, MasterPageContainer::Token aToken); + + static VclPtr<VirtualDevice> GetVirtualDevice(Image pPreview); }; } // end of namespace sd::sidebar diff --git a/sd/source/ui/sidebar/PreviewValueSet.cxx b/sd/source/ui/sidebar/PreviewValueSet.cxx deleted file mode 100644 index f752d60eb00d..000000000000 --- a/sd/source/ui/sidebar/PreviewValueSet.cxx +++ /dev/null @@ -1,127 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "PreviewValueSet.hxx" -#include <vcl/commandevent.hxx> - -namespace sd::sidebar { - -const int gnBorderWidth(3); -const int gnBorderHeight(3); - -PreviewValueSet::PreviewValueSet() - : ValueSet(nullptr) - , maPreviewSize(10,10) -{ - SetStyle ( - GetStyle() - & ~(WB_ITEMBORDER)// | WB_MENUSTYLEVALUESET) - // | WB_FLATVALUESET); - ); -} - -void PreviewValueSet::SetDrawingArea(weld::DrawingArea* pDrawingArea) -{ - ValueSet::SetDrawingArea(pDrawingArea); - - SetColCount(2); - SetExtraSpacing (2); -} - -PreviewValueSet::~PreviewValueSet() -{ -} - -void PreviewValueSet::SetPreviewSize (const Size& rSize) -{ - maPreviewSize = rSize; -} - -void PreviewValueSet::SetContextMenuHandler(const Link<const Point*, void>& rLink) -{ - maContextMenuHandler = rLink; -} - -bool PreviewValueSet::Command(const CommandEvent& rEvent) -{ - if (rEvent.GetCommand() != CommandEventId::ContextMenu) - return ValueSet::Command(rEvent); - maContextMenuHandler.Call(rEvent.IsMouseEvent() ? &rEvent.GetMousePosPixel() : nullptr); - return true; -} - -void PreviewValueSet::Resize() -{ - ValueSet::Resize(); - - Size aWindowSize (GetOutputSizePixel()); - if (!aWindowSize.IsEmpty()) - { - Rearrange(); - } -} - -void PreviewValueSet::Rearrange() -{ - sal_uInt16 nNewColumnCount (CalculateColumnCount ( - GetOutputSizePixel().Width())); - sal_uInt16 nNewRowCount (CalculateRowCount (nNewColumnCount)); - - SetFormat(); - SetColCount(nNewColumnCount); - SetLineCount(nNewRowCount); -} - -sal_uInt16 PreviewValueSet::CalculateColumnCount (int nWidth) const -{ - int nColumnCount = 0; - if (nWidth > 0) - { - nColumnCount = nWidth / (maPreviewSize.Width() + 2*gnBorderWidth); - if (nColumnCount < 1) - nColumnCount = 1; - } - return static_cast<sal_uInt16>(nColumnCount); -} - -sal_uInt16 PreviewValueSet::CalculateRowCount (sal_uInt16 nColumnCount) const -{ - int nRowCount = 0; - int nItemCount = GetItemCount(); - if (nColumnCount > 0) - { - nRowCount = (nItemCount+nColumnCount-1) / nColumnCount; - if (nRowCount < 1) - nRowCount = 1; - } - - return static_cast<sal_uInt16>(nRowCount); -} - -sal_Int32 PreviewValueSet::GetPreferredHeight (sal_Int32 nWidth) -{ - int nRowCount (CalculateRowCount(CalculateColumnCount(nWidth))); - int nItemHeight (maPreviewSize.Height()); - - return nRowCount * (nItemHeight + 2*gnBorderHeight); -} - -} // end of namespace sd::sidebar - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/PreviewValueSet.hxx b/sd/source/ui/sidebar/PreviewValueSet.hxx deleted file mode 100644 index adab3c78ad4d..000000000000 --- a/sd/source/ui/sidebar/PreviewValueSet.hxx +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#pragma once - -#include <svtools/valueset.hxx> - -namespace sd::sidebar -{ -/** Adapt the svtools valueset to the needs of the master page controls. -*/ -class PreviewValueSet : public ValueSet -{ -public: - explicit PreviewValueSet(); - virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override; - virtual ~PreviewValueSet() override; - - void SetContextMenuHandler(const Link<const Point*, void>& rLink); - - virtual void Resize() override; - virtual bool Command(const CommandEvent& rEvent) override; - - void SetPreviewSize(const Size& rSize); - - sal_Int32 GetPreferredHeight(sal_Int32 nWidth); - - /** Set the number of rows and columns according to the current number - of items. Call this method when new items have been inserted. - */ - void Rearrange(); - -private: - Link<const Point*, void> maContextMenuHandler; - Size maPreviewSize; - - sal_uInt16 CalculateColumnCount(int nWidth) const; - sal_uInt16 CalculateRowCount(sal_uInt16 nColumnCount) const; -}; - -} // end of namespace sd::sidebar - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/RecentMasterPagesSelector.cxx b/sd/source/ui/sidebar/RecentMasterPagesSelector.cxx index ef8e7fca3353..0917a46712c4 100644 --- a/sd/source/ui/sidebar/RecentMasterPagesSelector.cxx +++ b/sd/source/ui/sidebar/RecentMasterPagesSelector.cxx @@ -51,13 +51,13 @@ std::unique_ptr<PanelLayout> RecentMasterPagesSelector::Create ( return xSelector; } -RecentMasterPagesSelector::RecentMasterPagesSelector ( - weld::Widget* pParent, - SdDrawDocument& rDocument, - ViewShellBase& rBase, +RecentMasterPagesSelector::RecentMasterPagesSelector( + weld::Widget* pParent, SdDrawDocument& rDocument, ViewShellBase& rBase, const std::shared_ptr<MasterPageContainer>& rpContainer, const css::uno::Reference<css::ui::XSidebar>& rxSidebar) - : MasterPagesSelector (pParent, rDocument, rBase, rpContainer, rxSidebar, u"modules/simpress/ui/masterpagepanelrecent.ui"_ustr, u"recentvalueset"_ustr) + : MasterPagesSelector(pParent, rDocument, rBase, rpContainer, rxSidebar, + u"modules/simpress/ui/masterpagepanelrecent.ui"_ustr, + u"masterpagerecent_icons"_ustr) { } @@ -115,24 +115,6 @@ void RecentMasterPagesSelector::Fill (ItemList& rItemList) } } -void RecentMasterPagesSelector::AssignMasterPageToPageList ( - SdPage* pMasterPage, - const std::shared_ptr<std::vector<SdPage*> >& rpPageList) -{ - sal_uInt16 nSelectedItemId = mxPreviewValueSet->GetSelectedItemId(); - - MasterPagesSelector::AssignMasterPageToPageList(pMasterPage, rpPageList); - - // Restore the selection. - if (mxPreviewValueSet->GetItemCount() > 0) - { - if (mxPreviewValueSet->GetItemCount() >= nSelectedItemId) - mxPreviewValueSet->SelectItem(nSelectedItemId); - else - mxPreviewValueSet->SelectItem(mxPreviewValueSet->GetItemCount()); - } -} - } // end of namespace sd::sidebar /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/sidebar/RecentMasterPagesSelector.hxx b/sd/source/ui/sidebar/RecentMasterPagesSelector.hxx index 6dbc3a2aae07..bf35ca0adf3b 100644 --- a/sd/source/ui/sidebar/RecentMasterPagesSelector.hxx +++ b/sd/source/ui/sidebar/RecentMasterPagesSelector.hxx @@ -49,20 +49,6 @@ private: using sd::sidebar::MasterPagesSelector::Fill; - /** Forward this call to the base class but save and restore the - currently selected item. - Assign the given master page to the list of pages. - @param pMasterPage - This master page will usually be a member of the list of all - available master pages as provided by the MasterPageContainer. - @param rPageList - The pages to which to assign the master page. These pages may - be slides or master pages themselves. - */ - virtual void AssignMasterPageToPageList ( - SdPage* pMasterPage, - const std::shared_ptr<std::vector<SdPage*> >& rpPageList) override; - virtual void LateInit() override; }; diff --git a/sd/uiconfig/simpress/ui/masterpagepanel.ui b/sd/uiconfig/simpress/ui/masterpagepanel.ui index 429032ed2148..666d30ffacb5 100644 --- a/sd/uiconfig/simpress/ui/masterpagepanel.ui +++ b/sd/uiconfig/simpress/ui/masterpagepanel.ui @@ -3,22 +3,51 @@ <interface domain="sd"> <requires lib="gtk+" version="3.20"/> <!-- n-columns=1 n-rows=1 --> - <object class="GtkGrid" id="MasterPagePanel"> + <object class="GtkTreeStore" id="liststore1"> + <columns> + <!-- column-name pixbuf --> + <column type="GdkPixbuf"/> + <!-- column-name id --> + <column type="gchararray"/> + </columns> + </object> + <object class="GtkBox" id="MasterPagePanel"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="hexpand">True</property> <property name="vexpand">True</property> + <property name="orientation">vertical</property> <child> - <object class="GtkDrawingArea" id="usedvalueset"> + <object class="GtkScrolledWindow" id="masterpagecurrent_icons_scrolled_window"> <property name="visible">True</property> <property name="can-focus">True</property> - <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property> <property name="hexpand">True</property> <property name="vexpand">True</property> + <property name="hscrollbar-policy">never</property> + <property name="shadow-type">in</property> + <child> + <object class="GtkIconView" id="masterpagecurrent_icons"> + <property name="visible">True</property> + <property name="item-padding">2</property> + <property name="can-focus">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="model">liststore1</property> + <property name="pixbuf-column">0</property> + <property name="item-width">55</property> + <property name="margin">6</property> + <property name="activate-on-single-click">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="masterpagecurrent_icons-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="masterpagecurrentpanel|extended_tip|masterpagecurrent_icons">Currently selected master slide.</property> + </object> + </child> + </object> + </child> </object> <packing> - <property name="left-attach">0</property> - <property name="top-attach">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> </packing> </child> </object> diff --git a/sd/uiconfig/simpress/ui/masterpagepanelall.ui b/sd/uiconfig/simpress/ui/masterpagepanelall.ui index 979d06990e9e..078c4b7bec09 100644 --- a/sd/uiconfig/simpress/ui/masterpagepanelall.ui +++ b/sd/uiconfig/simpress/ui/masterpagepanelall.ui @@ -3,22 +3,51 @@ <interface domain="sd"> <requires lib="gtk+" version="3.20"/> <!-- n-columns=1 n-rows=1 --> - <object class="GtkGrid" id="MasterPagePanel"> + <object class="GtkTreeStore" id="liststore1"> + <columns> + <!-- column-name pixbuf --> + <column type="GdkPixbuf"/> + <!-- column-name id --> + <column type="gchararray"/> + </columns> + </object> + <object class="GtkBox" id="MasterPagePanel"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="hexpand">True</property> <property name="vexpand">True</property> + <property name="orientation">vertical</property> <child> - <object class="GtkDrawingArea" id="allvalueset"> + <object class="GtkScrolledWindow" id="masterpageall_icons_scrolled_window"> <property name="visible">True</property> <property name="can-focus">True</property> - <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property> <property name="hexpand">True</property> <property name="vexpand">True</property> + <property name="hscrollbar-policy">never</property> + <property name="shadow-type">in</property> + <child> + <object class="GtkIconView" id="masterpageall_icons"> + <property name="item-padding">2</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="model">liststore1</property> + <property name="pixbuf-column">0</property> + <property name="activate-on-single-click">True</property> + <property name="item-width">55</property> + <property name="margin">6</property> + <child internal-child="accessible"> + <object class="AtkObject" id="masterpageall_icons-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="masterpageallpanel|extended_tip|masterpageall_icons">Select master slide from available.</property> + </object> + </child> + </object> + </child> </object> <packing> - <property name="left-attach">0</property> - <property name="top-attach">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> </packing> </child> </object> diff --git a/sd/uiconfig/simpress/ui/masterpagepanelrecent.ui b/sd/uiconfig/simpress/ui/masterpagepanelrecent.ui index 4ec8487cfc5c..9be8d5a3ec9e 100644 --- a/sd/uiconfig/simpress/ui/masterpagepanelrecent.ui +++ b/sd/uiconfig/simpress/ui/masterpagepanelrecent.ui @@ -3,22 +3,51 @@ <interface domain="sd"> <requires lib="gtk+" version="3.20"/> <!-- n-columns=1 n-rows=1 --> - <object class="GtkGrid" id="MasterPagePanel"> + <object class="GtkTreeStore" id="liststore1"> + <columns> + <!-- column-name pixbuf --> + <column type="GdkPixbuf"/> + <!-- column-name id --> + <column type="gchararray"/> + </columns> + </object> + <object class="GtkBox" id="MasterPagePanel"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="hexpand">True</property> <property name="vexpand">True</property> + <property name="orientation">vertical</property> <child> - <object class="GtkDrawingArea" id="recentvalueset"> + <object class="GtkScrolledWindow" id="masterpagerecent_icons_scrolled_window"> <property name="visible">True</property> <property name="can-focus">True</property> - <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property> <property name="hexpand">True</property> <property name="vexpand">True</property> + <property name="hscrollbar-policy">never</property> + <property name="shadow-type">in</property> + <child> + <object class="GtkIconView" id="masterpagerecent_icons"> + <property name="item-padding">2</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="model">liststore1</property> + <property name="pixbuf-column">0</property> + <property name="item-width">55</property> + <property name="margin">6</property> + <property name="activate-on-single-click">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="masterpagerecent_icons-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="masterpagerecentpanel|extended_tip|masterpagerecent_icons">Select recenty used master slide.</property> + </object> + </child> + </object> + </child> </object> <packing> - <property name="left-attach">0</property> - <property name="top-attach">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> </packing> </child> </object> diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist index cf05e4de8eb8..6eff59432b41 100644 --- a/solenv/clang-format/excludelist +++ b/solenv/clang-format/excludelist @@ -9874,7 +9874,6 @@ sd/source/ui/sidebar/NavigatorWrapper.hxx sd/source/ui/sidebar/PageMarginUtils.hxx sd/source/ui/sidebar/PanelFactory.cxx sd/source/ui/sidebar/PanelFactory.hxx -sd/source/ui/sidebar/PreviewValueSet.cxx sd/source/ui/sidebar/RecentMasterPagesSelector.cxx sd/source/ui/sidebar/RecentMasterPagesSelector.hxx sd/source/ui/sidebar/RecentlyUsedMasterPages.cxx diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index 3837576c486e..534e158b4196 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -1979,14 +1979,30 @@ public: virtual bool get_iter_first(weld::TreeIter& rIter) const override; + virtual bool iter_next_sibling(weld::TreeIter& rIter) const override; + virtual void scroll_to_item(const weld::TreeIter& rIter) override; virtual void selected_foreach(const std::function<bool(weld::TreeIter&)>& func) override; virtual OUString get_id(const weld::TreeIter& rIter) const override; + virtual OUString get_id(int pos) const override; + + virtual void remove(int pos) override; + + const OUString* getEntryData(int index) const; + + virtual void set_image(int pos, VirtualDevice* rImage) override; + + virtual void set_text(int pos, const OUString& rText) override; + + virtual void set_id(int pos, const OUString& rId) override; + virtual OUString get_text(const weld::TreeIter& rIter) const override; + virtual tools::Rectangle get_rect(int pos) const override; + virtual void clear() override; virtual ~SalInstanceIconView() override; diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index a20c1831626d..3b06cc0e05e6 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -5667,6 +5667,13 @@ bool SalInstanceIconView::get_iter_first(weld::TreeIter& rIter) const return rVclIter.iter != nullptr; } +bool SalInstanceIconView::iter_next_sibling(weld::TreeIter& rIter) const +{ + SalInstanceTreeIter& rVclIter = static_cast<SalInstanceTreeIter&>(rIter); + rVclIter.iter = rVclIter.iter->NextSibling(); + return rVclIter.iter != nullptr; +} + void SalInstanceIconView::scroll_to_item(const weld::TreeIter& rIter) { assert(m_xIconView->IsUpdateMode() @@ -5698,12 +5705,99 @@ OUString SalInstanceIconView::get_id(const weld::TreeIter& rIter) const return OUString(); } +OUString SalInstanceIconView::get_id(int pos) const +{ + const OUString* pRet = getEntryData(pos); + if (!pRet) + return OUString(); + return *pRet; +} + +void SalInstanceIconView::set_image(int pos, VirtualDevice* pIcon) +{ + SvTreeListEntry* aEntry = m_xIconView->GetEntry(nullptr, pos); + if (aEntry == nullptr) + return; + SvLBoxContextBmp* aItem + = static_cast<SvLBoxContextBmp*>(aEntry->GetFirstItem(SvLBoxItemType::ContextBmp)); + + Image aImage; + if (pIcon) + { + const Point aNull(0, 0); + const Size aSize = pIcon->GetOutputSize(); + aImage = Image(pIcon->GetBitmapEx(aNull, aSize)); + } + if (aItem == nullptr) + { + aEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aImage, aImage, false)); + } + else + { + aItem->SetBitmap1(aImage); + aItem->SetBitmap2(aImage); + } + + if (!m_xIconView->GetModel()->IsEnableInvalidate()) + m_xIconView->ModelHasEntryInvalidated(aEntry); +} + +void SalInstanceIconView::remove(int pos) +{ + disable_notify_events(); + SvTreeListEntry* pEntry = m_xIconView->GetEntry(nullptr, pos); + m_xIconView->RemoveEntry(pEntry); + enable_notify_events(); +} + +const OUString* SalInstanceIconView::getEntryData(int index) const +{ + SvTreeListEntry* pEntry = m_xIconView->GetEntry(nullptr, index); + return pEntry ? static_cast<const OUString*>(pEntry->GetUserData()) : nullptr; +} + OUString SalInstanceIconView::get_text(const weld::TreeIter& rIter) const { const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter); return SvTabListBox::GetEntryText(rVclIter.iter, 0); } +void SalInstanceIconView::set_text(int pos, const OUString& rText) +{ + SvTreeListEntry* aEntry = m_xIconView->GetEntry(nullptr, pos); + if (aEntry == nullptr) + return; + + SvLBoxString* aItem = static_cast<SvLBoxString*>(aEntry->GetFirstItem(SvLBoxItemType::String)); + if (aItem == nullptr) + { + aEntry->AddItem(std::make_unique<SvLBoxString>(rText)); + } + else + { + aItem->SetText(rText); + } + + if (!m_xIconView->GetModel()->IsEnableInvalidate()) + m_xIconView->ModelHasEntryInvalidated(aEntry); +} + +void SalInstanceIconView::set_id(int pos, const OUString& rId) +{ + SvTreeListEntry* pEntry = m_xIconView->GetEntry(nullptr, pos); + m_aUserData.emplace_back(std::make_unique<OUString>(rId)); + pEntry->SetUserData(m_aUserData.back().get()); +} + +tools::Rectangle SalInstanceIconView::get_rect(int pos) const +{ + SvTreeListEntry* aEntry = m_xIconView->GetEntry(nullptr, pos); + if (aEntry == nullptr) + return tools::Rectangle(); + + return m_xIconView->GetBoundingRect(aEntry); +} + void SalInstanceIconView::clear() { disable_notify_events(); diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index 834984642a1e..47841398e847 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -2262,6 +2262,17 @@ namespace { rOutRect = GdkRectangle{static_cast<int>(rInRect.Left()), static_cast<int>(rInRect.Top()), static_cast<int>(rInRect.GetWidth()), static_cast<int>(rInRect.GetHeight())}; + + if (GTK_IS_ICON_VIEW(pWidget)) + { + // GtkIconView is a little weird in its positioning with scrolling, so adjust here to match what + // it expects + gint nOffsetX(0), nOffsetY(0); + gtk_icon_view_convert_widget_to_bin_window_coords(GTK_ICON_VIEW(pWidget), 0, 0, &nOffsetX, &nOffsetY); + rOutRect.x -= nOffsetX; + rOutRect.y -= nOffsetY; + } + if (SwapForRTL(pWidget)) rOutRect.x = gtk_widget_get_allocated_width(pWidget) - rOutRect.width - 1 - rOutRect.x; } @@ -17123,6 +17134,87 @@ private: return sRet; } + OUString get(int pos, int col) const + { + GtkTreeModel* pModel = GTK_TREE_MODEL(m_pTreeStore); + OUString sRet; + GtkTreeIter iter; + if (gtk_tree_model_iter_nth_child(pModel, &iter, nullptr, pos)) + sRet = get(iter, col); + return sRet; + } + + tools::Rectangle get_rect(int pos) const override + { + GtkTreeModel* pModel = GTK_TREE_MODEL(m_pTreeStore); + GtkTreeIter rIter; + if (!gtk_tree_model_iter_nth_child(pModel, &rIter, nullptr, pos)) + return tools::Rectangle(); + + const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter); + GtkTreePath* path + = gtk_tree_model_get_path(pModel, const_cast<GtkTreeIter*>(&rGtkIter.iter)); + + GdkRectangle aRect; + gtk_icon_view_get_cell_rect(m_pIconView, path, nullptr, &aRect); + gtk_tree_path_free(path); + + // GtkIconView is a little weird in its positioning with scrolling + gtk_icon_view_convert_widget_to_bin_window_coords(m_pIconView, aRect.x, aRect.y, &aRect.x, + &aRect.y); + + return tools::Rectangle(aRect.x, aRect.y, aRect.x + aRect.width, aRect.y + aRect.height); + } + + void set_image(int pos, VirtualDevice* pIcon) override + { + GtkTreeModel* pModel = GTK_TREE_MODEL(m_pTreeStore); + GtkTreeIter iter; + if (gtk_tree_model_iter_nth_child(pModel, &iter, nullptr, pos)) + { + if (pIcon) + { + GdkPixbuf* pixbuf = getPixbuf(*pIcon); + gtk_tree_store_set(m_pTreeStore, &iter, m_nImageCol, pixbuf, -1); + if (pixbuf) + g_object_unref(pixbuf); + } + } + } + + virtual void set_text(int pos, const OUString& rText) override + { + GtkTreeModel* pModel = GTK_TREE_MODEL(m_pTreeStore); + GtkTreeIter iter; + if (gtk_tree_model_iter_nth_child(pModel, &iter, nullptr, pos)) + { + OString aStr(OUStringToOString(rText, RTL_TEXTENCODING_UTF8)); + gtk_tree_store_set(m_pTreeStore, &iter, m_nTextCol, aStr.getStr(), -1); + } + } + + virtual void set_id(int pos, const OUString& rId) override + { + GtkTreeModel* pModel = GTK_TREE_MODEL(m_pTreeStore); + GtkTreeIter iter; + + if (gtk_tree_model_iter_nth_child(pModel, &iter, nullptr, pos)) + { + OString aStr(OUStringToOString(rId, RTL_TEXTENCODING_UTF8)); + gtk_tree_store_set(m_pTreeStore, &iter, m_nIdCol, aStr.getStr(), -1); + } + } + + virtual void remove(int pos) override + { + disable_notify_events(); + GtkTreeModel* pModel = GTK_TREE_MODEL(m_pTreeStore); + GtkTreeIter iter; + if (gtk_tree_model_iter_nth_child(pModel, &iter, nullptr, pos)) + tree_store_remove(pModel, &iter); + enable_notify_events(); + } + bool get_selected_iterator(GtkTreeIter* pIter) const { assert(gtk_icon_view_get_model(m_pIconView) && "don't request selection when frozen"); @@ -17387,6 +17479,13 @@ public: return gtk_tree_model_get_iter_first(pModel, &rGtkIter.iter); } + virtual bool iter_next_sibling(weld::TreeIter& rIter) const override + { + GtkInstanceTreeIter& rGtkIter = static_cast<GtkInstanceTreeIter&>(rIter); + GtkTreeModel* pModel = GTK_TREE_MODEL(m_pTreeStore); + return gtk_tree_model_iter_next(pModel, &rGtkIter.iter); + } + virtual void scroll_to_item(const weld::TreeIter& rIter) override { assert(gtk_icon_view_get_model(m_pIconView) && "don't select when frozen, select after thaw. Note selection doesn't survive a freeze"); @@ -17431,6 +17530,8 @@ public: return get(rGtkIter.iter, m_nIdCol); } + virtual OUString get_id(int pos) const override { return get(pos, m_nIdCol); } + virtual OUString get_text(const weld::TreeIter& rIter) const override { const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);
