diff options
author | Caolán McNamara <caolanm@redhat.com> | 2020-08-19 14:59:33 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2020-08-26 17:14:31 +0200 |
commit | fd2ea8e03510c6a99ec8be6228b7422f6c5b182b (patch) | |
tree | 0d79547d16857ce9f0f885fe11adb23189654833 | |
parent | 57666b8ba70f27c7250ef32f4cb9e7660e258521 (diff) |
weld OApplicationSwapWindow
Change-Id: I71d24494b5fe7dd2949876944ab9aff41330ad50
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101027
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | dbaccess/UIConfig_dbaccess.mk | 1 | ||||
-rw-r--r-- | dbaccess/source/ui/app/AppIconControl.cxx | 174 | ||||
-rw-r--r-- | dbaccess/source/ui/app/AppIconControl.hxx | 42 | ||||
-rw-r--r-- | dbaccess/source/ui/app/AppSwapWindow.cxx | 89 | ||||
-rw-r--r-- | dbaccess/source/ui/app/AppSwapWindow.hxx | 20 | ||||
-rw-r--r-- | dbaccess/source/ui/app/AppView.cxx | 4 | ||||
-rw-r--r-- | dbaccess/source/ui/inc/TableWindowListBox.hxx | 2 | ||||
-rw-r--r-- | dbaccess/uiconfig/ui/appswapwindow.ui | 59 | ||||
-rw-r--r-- | include/sfx2/thumbnailview.hxx | 13 | ||||
-rw-r--r-- | sfx2/source/control/thumbnailview.cxx | 17 | ||||
-rw-r--r-- | sfx2/source/control/thumbnailviewitem.cxx | 37 |
11 files changed, 334 insertions, 124 deletions
diff --git a/dbaccess/UIConfig_dbaccess.mk b/dbaccess/UIConfig_dbaccess.mk index 40a06cd388a0..91dc44de9606 100644 --- a/dbaccess/UIConfig_dbaccess.mk +++ b/dbaccess/UIConfig_dbaccess.mk @@ -13,6 +13,7 @@ $(eval $(call gb_UIConfig_add_uifiles,dbaccess, \ dbaccess/uiconfig/ui/admindialog \ dbaccess/uiconfig/ui/advancedsettingsdialog \ dbaccess/uiconfig/ui/applycolpage \ + dbaccess/uiconfig/ui/appswapwindow \ dbaccess/uiconfig/ui/authentificationpage \ dbaccess/uiconfig/ui/autocharsetpage \ dbaccess/uiconfig/ui/choosedatasourcedialog \ diff --git a/dbaccess/source/ui/app/AppIconControl.cxx b/dbaccess/source/ui/app/AppIconControl.cxx index 514580014f79..84edc6a27f15 100644 --- a/dbaccess/source/ui/app/AppIconControl.cxx +++ b/dbaccess/source/ui/app/AppIconControl.cxx @@ -21,18 +21,53 @@ #include <core_resource.hxx> #include <strings.hrc> #include <bitmaps.hlst> -#include <vcl/image.hxx> +#include <vcl/bitmapex.hxx> +#include <vcl/event.hxx> +#include <vcl/i18nhelp.hxx> +#include <vcl/mnemonic.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> #include <callbacks.hxx> #include <AppElementType.hxx> -using namespace ::dbaui; -OApplicationIconControl::OApplicationIconControl(vcl::Window* _pParent) - : SvtIconChoiceCtrl(_pParent,WB_ICON | WB_NOCOLUMNHEADER | WB_HIGHLIGHTFRAME | /*!WB_NOSELECTION |*/ - WB_TABSTOP | WB_CLIPCHILDREN | WB_NOVSCROLL | WB_SMART_ARRANGE | WB_NOHSCROLL | WB_CENTER) - ,DropTargetHelper(this) - ,m_pActionListener(nullptr) +namespace dbaui { +class OApplicationIconControlDropTarget final : public DropTargetHelper +{ +private: + OApplicationIconControl& m_rControl; + +public: + OApplicationIconControlDropTarget(OApplicationIconControl& rControl) + : DropTargetHelper(rControl.GetDrawingArea()->get_drop_target()) + , m_rControl(rControl) + { + } + + virtual sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt) override + { + return m_rControl.AcceptDrop(rEvt); + } + + virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt) override + { + return m_rControl.ExecuteDrop(rEvt); + } +}; + +OApplicationIconControl::OApplicationIconControl(std::unique_ptr<weld::ScrolledWindow> xScroll) + : SfxThumbnailView(std::move(xScroll), nullptr) + , m_pActionListener(nullptr) + , m_nMaxWidth(0) + , m_nMaxHeight(0) +{ + mnVItemSpace = 6; // row spacing + DrawMnemonics(true); +} + +void OApplicationIconControl::Fill() +{ static const struct CategoryDescriptor { const char* pLabelResId; @@ -44,63 +79,128 @@ OApplicationIconControl::OApplicationIconControl(vcl::Window* _pParent) { RID_STR_FORMS_CONTAINER, E_FORM, BMP_FORMFOLDER_TREE_L }, { RID_STR_REPORTS_CONTAINER, E_REPORT, BMP_REPORTFOLDER_TREE_L } }; + for (const CategoryDescriptor& aCategorie : aCategories) { - SvxIconChoiceCtrlEntry* pEntry = InsertEntry( - DBA_RES(aCategorie.pLabelResId) , - Image(StockImage::Yes, OUString::createFromAscii(aCategorie.aImageResId))); - if ( pEntry ) - pEntry->SetUserData( new ElementType( aCategorie.eType ) ); + // E_TABLE is 0, but 0 means void so use id of enum + 1 + std::unique_ptr<ThumbnailViewItem> xItem(new ThumbnailViewItem(*this, aCategorie.eType + 1)); + xItem->mbBorder = false; + xItem->maPreview1 = BitmapEx(OUString::createFromAscii(aCategorie.aImageResId)); + const Size& rSize = xItem->maPreview1.GetSizePixel(); + m_nMaxWidth = std::max(m_nMaxWidth, rSize.Width()); + m_nMaxHeight = std::max(m_nMaxHeight, rSize.Height()); + xItem->maTitle = DBA_RES(aCategorie.pLabelResId); + m_nMaxWidth = std::max<long>(m_nMaxWidth, GetTextWidth(xItem->maTitle)); + AppendItem(std::move(xItem)); } - SetChoiceWithCursor(); - SetSelectionMode(SelectionMode::Single); + const int nMargin = 12; + const int nWidthRequest = m_nMaxWidth + 2 * nMargin; + set_size_request(nWidthRequest, -1); + // we expect a Resize at which point we'll set the item sizes based on our final size } -OApplicationIconControl::~OApplicationIconControl() +ElementType OApplicationIconControl::GetSelectedItem() const +{ + for (const auto& rItem : mItemList) + { + if (!rItem->mbSelected) + continue; + return static_cast<ElementType>(rItem->mnId - 1); + } + return E_NONE; +} + +void OApplicationIconControl::createIconAutoMnemonics(MnemonicGenerator& rMnemonics) { - disposeOnce(); + for (const auto& rItem : mItemList) + rMnemonics.RegisterMnemonic(rItem->maTitle); + + // exchange texts with generated mnemonics + for (auto& rItem : mItemList) + rItem->maTitle = rMnemonics.CreateMnemonic(rItem->maTitle); } -void OApplicationIconControl::dispose() +void OApplicationIconControl::Resize() { - sal_Int32 nCount = GetEntryCount(); - for ( sal_Int32 i = 0; i < nCount; ++i ) + // fill the full width of the allocated area and give two lines of space to + // center the title in + setItemDimensions(GetOutputSizePixel().Width(), m_nMaxHeight, GetTextHeight() * 2, 0); + SfxThumbnailView::Resize(); +} + +bool OApplicationIconControl::IsMnemonicChar(sal_Unicode cChar, ElementType& rType) const +{ + bool bRet = false; + + const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper(); + for (const auto& rItem : mItemList) { - SvxIconChoiceCtrlEntry* pEntry = GetEntry( i ); - if ( pEntry ) + if (rI18nHelper.MatchMnemonic(rItem->maTitle, cChar)) { - delete static_cast<ElementType*>(pEntry->GetUserData()); - pEntry->SetUserData(nullptr); + bRet = true; + rType = static_cast<ElementType>(rItem->mnId - 1); + break; } } - DropTargetHelper::dispose(); - SvtIconChoiceCtrl::dispose(); + + return bRet; } -sal_Int8 OApplicationIconControl::AcceptDrop( const AcceptDropEvent& _rEvt ) +bool OApplicationIconControl::DoKeyShortCut(const KeyEvent& rKEvt) { - sal_Int8 nDropOption = DND_ACTION_NONE; - if ( m_pActionListener ) + bool bMod2 = rKEvt.GetKeyCode().IsMod2(); + sal_Unicode cChar = rKEvt.GetCharCode(); + ElementType eType(E_NONE); + if (bMod2 && cChar && IsMnemonicChar(cChar, eType)) { + // shortcut is clicked + deselectItems(); + SelectItem(eType + 1); + return true; + } + + return false; +} + +bool OApplicationIconControl::KeyInput(const KeyEvent& rKEvt) +{ + return DoKeyShortCut(rKEvt) || SfxThumbnailView::KeyInput(rKEvt); +} + +void OApplicationIconControl::SetDrawingArea(weld::DrawingArea* pDrawingArea) +{ + SfxThumbnailView::SetDrawingArea(pDrawingArea); + m_xDropTarget.reset(new OApplicationIconControlDropTarget(*this)); +} - SvxIconChoiceCtrlEntry* pEntry = GetEntry(_rEvt.maPosPixel); - if ( pEntry ) +sal_Int8 OApplicationIconControl::AcceptDrop(const AcceptDropEvent& rEvt) +{ + sal_Int8 nDropOption = DND_ACTION_NONE; + if (m_pActionListener) + { + sal_uInt16 nEntry = GetItemId(rEvt.maPosPixel); + if (nEntry) { - SetCursor(pEntry); - nDropOption = m_pActionListener->queryDrop( _rEvt, GetDataFlavorExVector() ); + deselectItems(); + SelectItem(nEntry); + nDropOption = m_pActionListener->queryDrop(rEvt, m_xDropTarget->GetDataFlavorExVector()); } } - return nDropOption; } -sal_Int8 OApplicationIconControl::ExecuteDrop( const ExecuteDropEvent& _rEvt ) +sal_Int8 OApplicationIconControl::ExecuteDrop(const ExecuteDropEvent& rEvt) { - if ( m_pActionListener ) - return m_pActionListener->executeDrop( _rEvt ); - + if (m_pActionListener) + m_pActionListener->executeDrop(rEvt); return DND_ACTION_NONE; } +OApplicationIconControl::~OApplicationIconControl() +{ +} + +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/dbaccess/source/ui/app/AppIconControl.hxx b/dbaccess/source/ui/app/AppIconControl.hxx index 38408af60687..7b29018c377b 100644 --- a/dbaccess/source/ui/app/AppIconControl.hxx +++ b/dbaccess/source/ui/app/AppIconControl.hxx @@ -19,28 +19,48 @@ #ifndef INCLUDED_DBACCESS_SOURCE_UI_APP_APPICONCONTROL_HXX #define INCLUDED_DBACCESS_SOURCE_UI_APP_APPICONCONTROL_HXX -#include <vcl/ivctrl.hxx> +#include <sfx2/thumbnailview.hxx> +#include <sfx2/thumbnailviewitem.hxx> #include <vcl/transfer.hxx> +#include <vcl/customweld.hxx> +#include <vcl/weld.hxx> +#include <AppElementType.hxx> + +class MnemonicGenerator; namespace dbaui { class IControlActionListener; - class OApplicationIconControl :public SvtIconChoiceCtrl - ,public DropTargetHelper + class IconControl; + class OApplicationIconControlDropTarget; + + class OApplicationIconControl final : public SfxThumbnailView { - IControlActionListener* m_pActionListener; + std::unique_ptr<OApplicationIconControlDropTarget> m_xDropTarget; + IControlActionListener* m_pActionListener; + + long m_nMaxWidth; + long m_nMaxHeight; + + bool IsMnemonicChar(sal_Unicode cChar, ElementType& rType) const; public: - explicit OApplicationIconControl(vcl::Window* _pParent); + explicit OApplicationIconControl(std::unique_ptr<weld::ScrolledWindow> xScroll); + virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override; + virtual void Resize() override; + bool DoKeyShortCut(const KeyEvent& rKEvt); + virtual bool KeyInput(const KeyEvent& rKEvt) override; virtual ~OApplicationIconControl() override; - virtual void dispose() override; - void setControlActionListener( IControlActionListener* _pListener ) { m_pActionListener = _pListener; } + ElementType GetSelectedItem() const; + + void setControlActionListener( IControlActionListener* _pListener ) { m_pActionListener = _pListener; } + void Fill(); + + void createIconAutoMnemonics(MnemonicGenerator& rMnemonics); - protected: - // DropTargetHelper overridables - virtual sal_Int8 AcceptDrop( const AcceptDropEvent& _rEvt ) override; - virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& _rEvt ) override; + sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt); + sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt); }; } #endif // INCLUDED_DBACCESS_SOURCE_UI_APP_APPICONCONTROL_HXX diff --git a/dbaccess/source/ui/app/AppSwapWindow.cxx b/dbaccess/source/ui/app/AppSwapWindow.cxx index e291bdb8a6ac..9ab50e8a0b4c 100644 --- a/dbaccess/source/ui/app/AppSwapWindow.cxx +++ b/dbaccess/source/ui/app/AppSwapWindow.cxx @@ -31,18 +31,28 @@ using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::container; -OApplicationSwapWindow::OApplicationSwapWindow( vcl::Window* _pParent, OAppBorderWindow& _rBorderWindow ) - :Window(_pParent,WB_DIALOGCONTROL ) - ,m_aIconControl(VclPtr<OApplicationIconControl>::Create(this)) - ,m_eLastType(E_NONE) - ,m_rBorderWin( _rBorderWindow ) +OApplicationSwapWindow::OApplicationSwapWindow(vcl::Window* pParent, OAppBorderWindow& rBorderWindow) + : InterimItemWindow(pParent, "dbaccess/ui/appswapwindow.ui", "AppSwapWindow") + , m_xIconControl(new OApplicationIconControl(m_xBuilder->weld_scrolled_window("scroll"))) + , m_xIconControlWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xIconControl)) + , m_eLastType(E_NONE) + , m_rBorderWin(rBorderWindow) { + m_xContainer->set_stack_background(); + ImplInitSettings(); - m_aIconControl->SetClickHdl(LINK(this, OApplicationSwapWindow, OnContainerSelectHdl)); - m_aIconControl->setControlActionListener( &m_rBorderWin.getView()->getAppController() ); - m_aIconControl->SetHelpId(HID_APP_SWAP_ICONCONTROL); - m_aIconControl->Show(); + m_xIconControl->SetHelpId(HID_APP_SWAP_ICONCONTROL); + m_xIconControl->Fill(); + m_xIconControl->setItemStateHdl(LINK(this, OApplicationSwapWindow, OnContainerSelectHdl)); + m_xIconControl->setControlActionListener( &m_rBorderWin.getView()->getAppController() ); +} + +void OApplicationSwapWindow::GetFocus() +{ + if (m_xIconControl) + m_xIconControl->GrabFocus(); + InterimItemWindow::GetFocus(); } OApplicationSwapWindow::~OApplicationSwapWindow() @@ -52,21 +62,9 @@ OApplicationSwapWindow::~OApplicationSwapWindow() void OApplicationSwapWindow::dispose() { - m_aIconControl.disposeAndClear(); - vcl::Window::dispose(); -} - -void OApplicationSwapWindow::Resize() -{ - Size aFLSize = LogicToPixel(Size(8, 0), MapMode(MapUnit::MapAppFont)); - long nX = 0; - if ( m_aIconControl->GetEntryCount() != 0 ) - nX = m_aIconControl->GetBoundingBox( m_aIconControl->GetEntry(0) ).GetWidth() + aFLSize.Width(); - - Size aOutputSize = GetOutputSize(); - - m_aIconControl->SetPosSizePixel( Point(static_cast<long>((aOutputSize.Width() - nX)*0.5), 0) ,Size(nX,aOutputSize.Height())); - m_aIconControl->ArrangeIcons(); + m_xIconControlWin.reset(); + m_xIconControl.reset(); + InterimItemWindow::dispose(); } void OApplicationSwapWindow::ImplInitSettings() @@ -99,32 +97,27 @@ void OApplicationSwapWindow::DataChanged( const DataChangedEvent& rDCEvt ) void OApplicationSwapWindow::clearSelection() { - m_aIconControl->SetNoSelection(); - SvxIconChoiceCtrlEntry* pEntry = m_aIconControl->GetSelectedEntry(); - if ( pEntry ) - m_aIconControl->InvalidateEntry(pEntry); - m_aIconControl->GetClickHdl().Call(m_aIconControl.get()); + m_xIconControl->deselectItems(); + onContainerSelected(E_NONE); } -void OApplicationSwapWindow::createIconAutoMnemonics( MnemonicGenerator& _rMnemonics ) +void OApplicationSwapWindow::createIconAutoMnemonics(MnemonicGenerator& rMnemonics) { - m_aIconControl->CreateAutoMnemonics( _rMnemonics ); + m_xIconControl->createIconAutoMnemonics(rMnemonics); } bool OApplicationSwapWindow::interceptKeyInput( const KeyEvent& _rEvent ) { const vcl::KeyCode& rKeyCode = _rEvent.GetKeyCode(); if ( rKeyCode.GetModifier() == KEY_MOD2 ) - return m_aIconControl->DoKeyInput( _rEvent ); - + return m_xIconControl->DoKeyShortCut( _rEvent ); // not handled return false; } ElementType OApplicationSwapWindow::getElementType() const { - SvxIconChoiceCtrlEntry* pEntry = m_aIconControl->GetSelectedEntry(); - return pEntry ? *static_cast<ElementType*>(pEntry->GetUserData()) : E_NONE; + return m_xIconControl->GetSelectedItem(); } bool OApplicationSwapWindow::onContainerSelected( ElementType _eType ) @@ -143,13 +136,11 @@ bool OApplicationSwapWindow::onContainerSelected( ElementType _eType ) return false; } -IMPL_LINK(OApplicationSwapWindow, OnContainerSelectHdl, SvtIconChoiceCtrl*, _pControl, void) +IMPL_LINK(OApplicationSwapWindow, OnContainerSelectHdl, const ThumbnailViewItem*, pEntry, void) { - SvxIconChoiceCtrlEntry* pEntry = _pControl->GetSelectedEntry(); - ElementType eType = E_NONE; - if ( pEntry ) + if (pEntry->mbSelected) { - eType = *static_cast<ElementType*>(pEntry->GetUserData()); + ElementType eType = static_cast<ElementType>(pEntry->mnId - 1); onContainerSelected( eType ); // i87582 } } @@ -159,22 +150,10 @@ IMPL_LINK_NOARG(OApplicationSwapWindow, ChangeToLastSelected, void*, void) selectContainer(m_eLastType); } -void OApplicationSwapWindow::selectContainer(ElementType _eType) +void OApplicationSwapWindow::selectContainer(ElementType eType) { - sal_Int32 nCount = m_aIconControl->GetEntryCount(); - SvxIconChoiceCtrlEntry* pEntry = nullptr; - for (sal_Int32 i=0; i < nCount; ++i) - { - pEntry = m_aIconControl->GetEntry(i); - if ( pEntry && *static_cast<ElementType*>(pEntry->GetUserData()) == _eType ) - break; - pEntry = nullptr; - } - - if ( pEntry ) - m_aIconControl->SetCursor(pEntry); // this call also initiates a onContainerSelected call - else - onContainerSelected( _eType ); + m_xIconControl->deselectItems(); + m_xIconControl->SelectItem(eType + 1); // will trigger onContainerSelected } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/dbaccess/source/ui/app/AppSwapWindow.hxx b/dbaccess/source/ui/app/AppSwapWindow.hxx index 62f58c15248d..b63d563e496b 100644 --- a/dbaccess/source/ui/app/AppSwapWindow.hxx +++ b/dbaccess/source/ui/app/AppSwapWindow.hxx @@ -20,32 +20,36 @@ #define INCLUDED_DBACCESS_SOURCE_UI_APP_APPSWAPWINDOW_HXX #include <IClipBoardTest.hxx> +#include <vcl/InterimItemWindow.hxx> #include <vcl/vclptr.hxx> #include "AppIconControl.hxx" #include <AppElementType.hxx> +class MnemonicGenerator; + namespace dbaui { class OAppBorderWindow; - class OApplicationSwapWindow : public vcl::Window, - public IClipboardTest + class OApplicationSwapWindow : public InterimItemWindow + , public IClipboardTest { - VclPtr<OApplicationIconControl> m_aIconControl; + std::unique_ptr<OApplicationIconControl> m_xIconControl; + std::unique_ptr<weld::CustomWeld> m_xIconControlWin; ElementType m_eLastType; OAppBorderWindow& m_rBorderWin; void ImplInitSettings(); - DECL_LINK( OnContainerSelectHdl, SvtIconChoiceCtrl*, void ); + DECL_LINK( OnContainerSelectHdl, const ThumbnailViewItem*, void ); DECL_LINK( ChangeToLastSelected, void*, void ); protected: virtual void DataChanged(const DataChangedEvent& rDCEvt) override; public: - OApplicationSwapWindow( vcl::Window* _pParent, OAppBorderWindow& _rBorderWindow ); + OApplicationSwapWindow(vcl::Window* pParent, OAppBorderWindow& rBorderWindow); virtual ~OApplicationSwapWindow() override; // Window overrides virtual void dispose() override; - virtual void Resize() override; + virtual void GetFocus() override; bool isCutAllowed() override { return false; } bool isCopyAllowed() override { return false; } @@ -54,10 +58,6 @@ namespace dbaui void cut() override { } void paste() override { } - sal_Int32 GetEntryCount() const { return m_aIconControl->GetEntryCount(); } - SvxIconChoiceCtrlEntry* GetEntry( sal_uLong nPos ) const { return m_aIconControl->GetEntry(nPos); } - tools::Rectangle GetBoundingBox( SvxIconChoiceCtrlEntry* pEntry ) const { return m_aIconControl->GetBoundingBox(pEntry); } - /** automatically creates mnemonics for the icon/texts in our left hand side panel */ void createIconAutoMnemonics( MnemonicGenerator& _rMnemonics ); diff --git a/dbaccess/source/ui/app/AppView.cxx b/dbaccess/source/ui/app/AppView.cxx index b92917c4615b..c6770a1eafd9 100644 --- a/dbaccess/source/ui/app/AppView.cxx +++ b/dbaccess/source/ui/app/AppView.cxx @@ -100,8 +100,8 @@ void OAppBorderWindow::Resize() if ( m_pPanel ) { OApplicationSwapWindow* pSwap = getPanel(); - if ( pSwap && pSwap->GetEntryCount() != 0 ) - nX = pSwap->GetBoundingBox( pSwap->GetEntry(0) ).GetWidth() + aFLSize.Height(); + if (pSwap) + nX = pSwap->get_preferred_size().Width(); nX = std::max(m_pPanel->GetWidthPixel() ,nX); m_pPanel->SetPosSizePixel(Point(0,0),Size(nX,nOutputHeight)); } diff --git a/dbaccess/source/ui/inc/TableWindowListBox.hxx b/dbaccess/source/ui/inc/TableWindowListBox.hxx index 5ca01098266b..6d4ded28f97f 100644 --- a/dbaccess/source/ui/inc/TableWindowListBox.hxx +++ b/dbaccess/source/ui/inc/TableWindowListBox.hxx @@ -93,7 +93,7 @@ namespace dbaui int GetEntryFromText( const OUString& rEntryText ); }; - class TableWindowListBoxHelper : public DropTargetHelper + class TableWindowListBoxHelper final : public DropTargetHelper { private: OTableWindowListBox& m_rParent; diff --git a/dbaccess/uiconfig/ui/appswapwindow.ui b/dbaccess/uiconfig/ui/appswapwindow.ui new file mode 100644 index 000000000000..d2dfc1b397c3 --- /dev/null +++ b/dbaccess/uiconfig/ui/appswapwindow.ui @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.36.0 --> +<interface domain="dba"> + <requires lib="gtk+" version="3.18"/> + <object class="GtkBox" id="AppSwapWindow"> + <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="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="border_width">12</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkScrolledWindow" id="scroll"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="hscrollbar_policy">never</property> + <property name="vscrollbar_policy">never</property> + <child> + <object class="GtkViewport"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <child> + <object class="GtkDrawingArea" id="valueset"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + </object> +</interface> diff --git a/include/sfx2/thumbnailview.hxx b/include/sfx2/thumbnailview.hxx index f2e90f94ac59..45f4a6753286 100644 --- a/include/sfx2/thumbnailview.hxx +++ b/include/sfx2/thumbnailview.hxx @@ -176,6 +176,8 @@ public: virtual bool renameItem(ThumbnailViewItem* pItem, const OUString& sNewTitle); + virtual bool isDrawMnemonic() const = 0; + virtual ~ThumbnailViewBase(); }; @@ -205,6 +207,8 @@ public: sal_uInt16 getNextItemId () const; + virtual bool isDrawMnemonic() const override { return false; } + void setItemMaxTextLength (sal_uInt32 nLength); void setItemDimensions (long ItemWidth, long ThumbnailHeight, @@ -340,6 +344,8 @@ public: sal_uInt16 getNextItemId () const; + virtual bool isDrawMnemonic() const override { return mbDrawMnemonics; } + void setItemMaxTextLength (sal_uInt32 nLength); void setItemDimensions (long ItemWidth, long ThumbnailHeight, @@ -359,6 +365,8 @@ public: void ShowTooltips( bool bShowTooltips ); + void DrawMnemonics( bool bDrawMnemonics ); + void SetMultiSelectionEnabled( bool bIsMultiSelectionEnabled ); void filterItems (const std::function<bool (const ThumbnailViewItem*) > &func); @@ -437,14 +445,17 @@ protected: long mnItemPadding; long mnThumbnailHeight; // Maximum height of the thumbnail long mnDisplayHeight; // Height of the data display box (name, etc) + long mnVItemSpace; // Vertical spacing between rows, -1 to use excess unused height split up between items long mnVisLines; long mnLines; sal_uInt16 mnCols; sal_uInt16 mnFirstLine; - bool mbScroll : 1; + bool mbScroll : 1; // Whether we need to scroll + bool mbAllowVScrollBar : 1; // Whether to show a visible scrollbar bool mbHasVisibleItems : 1; bool mbShowTooltips : 1; + bool mbDrawMnemonics : 1; bool mbIsMultiSelectionEnabled: 1; Color maFillColor; ///< Background color of the thumbnail view widget. Color maTextColor; ///< Text color. diff --git a/sfx2/source/control/thumbnailview.cxx b/sfx2/source/control/thumbnailview.cxx index a607493119a4..f0f31700fb39 100644 --- a/sfx2/source/control/thumbnailview.cxx +++ b/sfx2/source/control/thumbnailview.cxx @@ -1221,6 +1221,8 @@ BitmapEx ThumbnailView::readThumbnail(const OUString &msURL) SfxThumbnailView::SfxThumbnailView(std::unique_ptr<weld::ScrolledWindow> xWindow, std::unique_ptr<weld::Menu> xMenu) : mnThumbnailHeight(0) , mnDisplayHeight(0) + , mnVItemSpace(-1) + , mbAllowVScrollBar(xWindow->get_vpolicy() != VclPolicyType::NEVER) , mpItemAttrs(new ThumbnailItemAttributes) , mxScrolledWindow(std::move(xWindow)) , mxContextMenu(std::move(xMenu)) @@ -1314,6 +1316,7 @@ void SfxThumbnailView::ImplInit() mbScroll = false; mbHasVisibleItems = false; mbShowTooltips = false; + mbDrawMnemonics = false; mbIsMultiSelectionEnabled = true; maFilterFunc = ViewFilterAll(); @@ -1418,7 +1421,7 @@ void SfxThumbnailView::CalculateItemPositions(bool bScrollBarUsed) nScrollRatio = 0; // calculate ScrollBar width - long nScrBarWidth = mxScrolledWindow->get_vscroll_width(); + long nScrBarWidth = mbAllowVScrollBar ? mxScrolledWindow->get_vscroll_width() : 0; // calculate maximum number of visible columns mnCols = static_cast<sal_uInt16>((aWinSize.Width()-nScrBarWidth) / mnItemWidth); @@ -1433,7 +1436,9 @@ void SfxThumbnailView::CalculateItemPositions(bool bScrollBarUsed) long nHSpace = aWinSize.Width()-nScrBarWidth - mnCols*mnItemWidth; long nVSpace = aWinSize.Height() - mnVisLines*mnItemHeight; long nHItemSpace = nHSpace / (mnCols+1); - long nVItemSpace = nVSpace / (mnVisLines+1); + long nVItemSpace = mnVItemSpace; + if (nVItemSpace == -1) // auto, split up extra space to use as vertical spacing + nVItemSpace = nVSpace / (mnVisLines+1); // calculate maximum number of rows // Floor( (M+N-1)/N )==Ceiling( M/N ) @@ -1545,7 +1550,8 @@ void SfxThumbnailView::CalculateItemPositions(bool bScrollBarUsed) if ( nPageSize < 1 ) nPageSize = 1; mxScrolledWindow->vadjustment_set_page_increment(nPageSize); - mxScrolledWindow->set_vpolicy(mbScroll ? VclPolicyType::ALWAYS : VclPolicyType::NEVER); + if (mbAllowVScrollBar) + mxScrolledWindow->set_vpolicy(mbScroll ? VclPolicyType::ALWAYS : VclPolicyType::NEVER); } size_t SfxThumbnailView::ImplGetItem( const Point& rPos ) const @@ -2237,6 +2243,11 @@ void SfxThumbnailView::ShowTooltips( bool bShowTooltips ) mbShowTooltips = bShowTooltips; } +void SfxThumbnailView::DrawMnemonics( bool bDrawMnemonics ) +{ + mbDrawMnemonics = bDrawMnemonics; +} + void SfxThumbnailView::SetMultiSelectionEnabled( bool bIsMultiSelectionEnabled ) { mbIsMultiSelectionEnabled = bIsMultiSelectionEnabled; diff --git a/sfx2/source/control/thumbnailviewitem.cxx b/sfx2/source/control/thumbnailviewitem.cxx index 474f415e73cb..b3a6e7d4af97 100644 --- a/sfx2/source/control/thumbnailviewitem.cxx +++ b/sfx2/source/control/thumbnailviewitem.cxx @@ -27,6 +27,7 @@ #include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx> #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> #include <drawinglayer/primitive2d/PolyPolygonSelectionPrimitive2D.hxx> +#include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx> #include <drawinglayer/primitive2d/textlayoutdevice.hxx> #include <drawinglayer/primitive2d/textprimitive2d.hxx> #include <drawinglayer/processor2d/baseprocessor2d.hxx> @@ -213,27 +214,30 @@ void ThumbnailViewItem::addTextPrimitives (const OUString& rText, const Thumbnai aPos.setY(aPos.getY() + aTextDev.getTextHeight()); - OUString aText (rText); + sal_Int32 nMnemonicPos = -1; + OUString aOrigText(mrParent.isDrawMnemonic() ? OutputDevice::GetNonMnemonicString(rText, nMnemonicPos) : rText); TextEngine aTextEngine; aTextEngine.SetFont(getVclFontFromFontAttribute(pAttrs->aFontAttr, pAttrs->aFontSize.getX(), pAttrs->aFontSize.getY(), 0, css::lang::Locale())); aTextEngine.SetMaxTextWidth(maDrawArea.getWidth()); - aTextEngine.SetText(rText); + aTextEngine.SetText(aOrigText); sal_Int32 nPrimitives = rSeq.size(); - rSeq.resize(nPrimitives + aTextEngine.GetLineCount(0)); + sal_Int32 nFinalPrimCount = nPrimitives + aTextEngine.GetLineCount(0); + rSeq.resize(nFinalPrimCount); // Create the text primitives sal_uInt16 nLineStart = 0; + OUString aText(aOrigText); for (sal_uInt16 i=0; i < aTextEngine.GetLineCount(0); ++i) { sal_Int32 nLineLength = aTextEngine.GetLineLen(0, i); double nLineWidth = aTextDev.getTextWidth (aText, nLineStart, nLineLength); bool bTooLong = (aPos.getY() + aTextEngine.GetCharHeight()) > maDrawArea.Bottom(); - if (bTooLong && (nLineLength + nLineStart) < rText.getLength()) + if (bTooLong && (nLineLength + nLineStart) < aOrigText.getLength()) { // Add the '...' to the last line to show, even though it may require to shorten the line double nDotsWidth = aTextDev.getTextWidth("...",0,3); @@ -271,6 +275,31 @@ void ThumbnailViewItem::addTextPrimitives (const OUString& rText, const Thumbnai pAttrs->aFontAttr, css::lang::Locale(), aTextColor)); + + if (nMnemonicPos != -1 && nMnemonicPos >= nLineStart && nMnemonicPos < nLineStart + nLineLength) + { + rSeq.resize(nFinalPrimCount + 1); + + auto aCaretPositions = aTextDev.getCaretPositions(aText, nLineStart, nLineLength); + + auto lc_x1 = aCaretPositions[2*(nMnemonicPos - nLineStart)]; + auto lc_x2 = aCaretPositions[2*(nMnemonicPos - nLineStart)+1]; + auto fMnemonicWidth = std::abs(lc_x1 - lc_x2); + auto fMnemonicHeight = aTextDev.getUnderlineHeight(); + + auto fPosX = nLineX + std::min(lc_x1, lc_x2); + auto fPosY = aPos.Y() + aTextDev.getUnderlineOffset(); + + B2DPolygon aLine; + aLine.append(B2DPoint(fPosX, fPosY)); + aLine.append(B2DPoint(fPosX + fMnemonicWidth, fPosY)); + + drawinglayer::attribute::LineAttribute aLineAttribute(Color(aTextColor).getBColor(), fMnemonicHeight); + + rSeq[nPrimitives++] = drawinglayer::primitive2d::Primitive2DReference( + new PolygonStrokePrimitive2D(aLine, aLineAttribute)); + } + nLineStart += nLineLength; aPos.setY(aPos.getY() + aTextEngine.GetCharHeight()); |