From e5ef9a396b5808fc561e92216071e18815344dd9 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Tue, 26 May 2020 17:07:38 +0100 Subject: weld SvxUndoRedoControl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: If78886a40243da01109364d8df02fb664fd1f011 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96554 Tested-by: Jenkins Reviewed-by: Caolán McNamara --- svx/source/tbxctrls/lboxctrl.cxx | 233 +++++++++++++++++++++++++++--------- svx/uiconfig/ui/floatingundoredo.ui | 56 ++++++--- 2 files changed, 220 insertions(+), 69 deletions(-) (limited to 'svx') diff --git a/svx/source/tbxctrls/lboxctrl.cxx b/svx/source/tbxctrls/lboxctrl.cxx index 1c9a902035ea..6f7eda4d98a3 100644 --- a/svx/source/tbxctrls/lboxctrl.cxx +++ b/svx/source/tbxctrls/lboxctrl.cxx @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include #include @@ -41,72 +41,168 @@ using namespace ::com::sun::star::beans; using namespace ::com::sun::star::util; using namespace ::com::sun::star::frame; -class SvxPopupWindowListBox final : public svtools::ToolbarPopup +class SvxPopupWindowListBox final : public WeldToolbarPopup { - VclPtr m_pListBox; rtl::Reference m_xControl; + std::unique_ptr m_xListBox; + std::unique_ptr m_xScratchIter; + int m_nSelectedRows; + int m_nVisRows; - DECL_LINK( SelectHdl, ListBox&, void ); + void UpdateRow(int nRow); -public: - SvxPopupWindowListBox(SvxUndoRedoControl* pControl, vcl::Window* pParent); - virtual ~SvxPopupWindowListBox() override; - virtual void dispose() override; + DECL_LINK(KeyInputHdl, const KeyEvent&, bool); + DECL_LINK(ActivateHdl, weld::TreeView&, bool); + DECL_LINK(MouseMoveHdl, const MouseEvent&, bool); + DECL_LINK(MousePressHdl, const MouseEvent&, bool); + DECL_LINK(MouseReleaseHdl, const MouseEvent&, bool); - ListBox & GetListBox() { return *m_pListBox; } +public: + SvxPopupWindowListBox(SvxUndoRedoControl* pControl, weld::Widget* pParent, + const std::vector& rUndoRedoList); - void SetInfo(sal_Int32 nCount); + virtual void GrabFocus() override + { + m_xListBox->grab_focus(); + } }; -SvxPopupWindowListBox::SvxPopupWindowListBox(SvxUndoRedoControl* pControl, vcl::Window* pParent) - : ToolbarPopup(pControl->getFrameInterface(), pParent, "FloatingUndoRedo", "svx/ui/floatingundoredo.ui") +SvxPopupWindowListBox::SvxPopupWindowListBox(SvxUndoRedoControl* pControl, weld::Widget* pParent, + const std::vector& rUndoRedoList) + : WeldToolbarPopup(pControl->getFrameInterface(), pParent, "svx/ui/floatingundoredo.ui", "FloatingUndoRedo") , m_xControl(pControl) + , m_xListBox(m_xBuilder->weld_tree_view("treeview")) + , m_xScratchIter(m_xListBox->make_iterator()) + , m_nVisRows(10) { - get(m_pListBox, "treeview"); - WinBits nBits(m_pListBox->GetStyle()); - nBits &= ~WB_SIMPLEMODE; - m_pListBox->SetStyle(nBits); - Size aSize(LogicToPixel(Size(100, 85), MapMode(MapUnit::MapAppFont))); - m_pListBox->set_width_request(aSize.Width()); - m_pListBox->set_height_request(aSize.Height()); - m_pListBox->EnableMultiSelection( true, true ); - SetBackground( GetSettings().GetStyleSettings().GetDialogColor() ); + m_xListBox->set_selection_mode(SelectionMode::Multiple); - m_pListBox->SetSelectHdl( LINK( this, SvxPopupWindowListBox, SelectHdl ) ); -} + for (const OUString& s : rUndoRedoList) + m_xListBox->append_text(s); + if (!rUndoRedoList.empty()) + { + m_xListBox->set_cursor(0); + m_xListBox->select(0); + m_nSelectedRows = 1; + } + else + m_nSelectedRows = 0; -SvxPopupWindowListBox::~SvxPopupWindowListBox() -{ - disposeOnce(); -} + m_xListBox->set_size_request(m_xListBox->get_approximate_digit_width() * 25, + m_xListBox->get_height_rows(m_nVisRows) + 2); -void SvxPopupWindowListBox::dispose() -{ - m_pListBox.clear(); - ToolbarPopup::dispose(); + m_xListBox->connect_row_activated(LINK(this, SvxPopupWindowListBox, ActivateHdl)); + m_xListBox->connect_mouse_move(LINK(this, SvxPopupWindowListBox, MouseMoveHdl)); + m_xListBox->connect_mouse_press(LINK(this, SvxPopupWindowListBox, MousePressHdl)); + m_xListBox->connect_mouse_release(LINK(this, SvxPopupWindowListBox, MouseReleaseHdl)); + m_xListBox->connect_key_press(LINK(this, SvxPopupWindowListBox, KeyInputHdl)); } -void SvxPopupWindowListBox::SetInfo( sal_Int32 nCount ) +void SvxUndoRedoControl::SetInfo( sal_Int32 nCount ) { const char* pId; if (nCount == 1) - pId = m_xControl->getCommandURL() == ".uno:Undo" ? RID_SVXSTR_NUM_UNDO_ACTION : RID_SVXSTR_NUM_REDO_ACTION; + pId = getCommandURL() == ".uno:Undo" ? RID_SVXSTR_NUM_UNDO_ACTION : RID_SVXSTR_NUM_REDO_ACTION; else - pId = m_xControl->getCommandURL() == ".uno:Undo" ? RID_SVXSTR_NUM_UNDO_ACTIONS : RID_SVXSTR_NUM_REDO_ACTIONS; + pId = getCommandURL() == ".uno:Undo" ? RID_SVXSTR_NUM_UNDO_ACTIONS : RID_SVXSTR_NUM_REDO_ACTIONS; OUString aActionStr = SvxResId(pId); OUString aText = aActionStr.replaceAll("$(ARG1)", OUString::number(nCount)); SetText(aText); } -IMPL_LINK(SvxPopupWindowListBox, SelectHdl, ListBox&, rListBox, void) +void SvxPopupWindowListBox::UpdateRow(int nRow) { - if (rListBox.IsTravelSelect()) - SetInfo(rListBox.GetSelectedEntryCount()); - else + int nOldSelectedRows = m_nSelectedRows; + while (m_nSelectedRows < nRow + 1) + { + m_xListBox->select(m_nSelectedRows++); + } + while (m_nSelectedRows - 1 > nRow) { - m_xControl->Do(GetListBox().GetSelectedEntryCount()); - EndPopupMode(); + m_xListBox->unselect(--m_nSelectedRows); } + if (nOldSelectedRows != m_nSelectedRows) + m_xControl->SetInfo(m_nSelectedRows); +} + +IMPL_LINK(SvxPopupWindowListBox, MouseMoveHdl, const MouseEvent&, rMEvt, bool) +{ + if (m_xListBox->get_dest_row_at_pos(rMEvt.GetPosPixel(), m_xScratchIter.get(), false)) + UpdateRow(m_xListBox->get_iter_index_in_parent(*m_xScratchIter)); + return false; +} + +IMPL_LINK(SvxPopupWindowListBox, MousePressHdl, const MouseEvent&, rMEvt, bool) +{ + if (m_xListBox->get_dest_row_at_pos(rMEvt.GetPosPixel(), m_xScratchIter.get(), false)) + { + UpdateRow(m_xListBox->get_iter_index_in_parent(*m_xScratchIter)); + ActivateHdl(*m_xListBox); + } + return true; +} + +IMPL_LINK(SvxPopupWindowListBox, MouseReleaseHdl, const MouseEvent&, rMEvt, bool) +{ + if (m_xListBox->get_dest_row_at_pos(rMEvt.GetPosPixel(), m_xScratchIter.get(), false)) + UpdateRow(m_xListBox->get_iter_index_in_parent(*m_xScratchIter)); + return true; +} + +IMPL_LINK(SvxPopupWindowListBox, KeyInputHdl, const KeyEvent&, rKEvt, bool) +{ + const vcl::KeyCode& rKCode = rKEvt.GetKeyCode(); + if (rKCode.GetModifier()) // only with no modifiers held + return true; + + sal_uInt16 nCode = rKCode.GetCode(); + + if (nCode == KEY_UP || nCode == KEY_PAGEUP || + nCode == KEY_DOWN || nCode == KEY_PAGEDOWN) + { + sal_Int32 nIndex = m_nSelectedRows - 1; + sal_Int32 nOrigIndex = nIndex; + sal_Int32 nCount = m_xListBox->n_children(); + + if (nCode == KEY_UP) + --nIndex; + else if (nCode == KEY_DOWN) + ++nIndex; + else if (nCode == KEY_PAGEUP) + nIndex -= m_nVisRows; + else if (nCode == KEY_PAGEDOWN) + nIndex += m_nVisRows; + + if (nIndex < 0) + nIndex = 0; + if (nIndex >= nCount) + nIndex = nCount - 1; + + if (nIndex != nOrigIndex) + { + m_xListBox->scroll_to_row(nIndex); + if (nIndex > nOrigIndex) + { + for (int i = nOrigIndex + 1; i <= nIndex; ++i) + UpdateRow(i); + } + else + { + for (int i = nOrigIndex - 1; i >= nIndex; --i) + UpdateRow(i); + } + } + return true; + } + + return false; +} + +IMPL_LINK_NOARG(SvxPopupWindowListBox, ActivateHdl, weld::TreeView&, bool) +{ + m_xControl->Do(m_nSelectedRows); + m_xControl->EndPopupMode(); + return true; } void SvxUndoRedoControl::Do(sal_Int16 nCount) @@ -142,10 +238,17 @@ void SvxUndoRedoControl::initialize( const css::uno::Sequence< css::uno::Any >& ToolBox* pToolBox = nullptr; sal_uInt16 nId = 0; - if (getToolboxId(nId, &pToolBox) && getModuleName() != "com.sun.star.script.BasicIDE") + if (!getToolboxId(nId, &pToolBox) && !m_pToolbar) + return; + + if (getModuleName() != "com.sun.star.script.BasicIDE") { - pToolBox->SetItemBits(nId, ToolBoxItemBits::DROPDOWN | pToolBox->GetItemBits(nId)); - aDefaultTooltip = pToolBox->GetQuickHelpText(nId); + if (pToolBox) + pToolBox->SetItemBits(nId, ToolBoxItemBits::DROPDOWN | pToolBox->GetItemBits(nId)); + if (m_pToolbar) + aDefaultTooltip = m_pToolbar->get_item_tooltip_text(m_aCommandURL.toUtf8()); + else + aDefaultTooltip = pToolBox->GetQuickHelpText(nId); } } @@ -153,6 +256,11 @@ SvxUndoRedoControl::~SvxUndoRedoControl() { } +void SvxUndoRedoControl::SetText(const OUString& rText) +{ + mxInterimPopover->SetText(rText); +} + // XStatusListener void SAL_CALL SvxUndoRedoControl::statusChanged(const css::frame::FeatureStateEvent& rEvent) { @@ -168,38 +276,55 @@ void SAL_CALL SvxUndoRedoControl::statusChanged(const css::frame::FeatureStateEv ToolBox* pToolBox = nullptr; sal_uInt16 nId = 0; - if (!getToolboxId(nId, &pToolBox)) + if (!getToolboxId(nId, &pToolBox) && !m_pToolbar) return; if (!rEvent.IsEnabled) { - pToolBox->SetQuickHelpText(nId, aDefaultTooltip); + if (m_pToolbar) + m_pToolbar->set_item_tooltip_text(m_aCommandURL.toUtf8(), aDefaultTooltip); + else + pToolBox->SetQuickHelpText(nId, aDefaultTooltip); return; } OUString aQuickHelpText; if (rEvent.State >>= aQuickHelpText) - pToolBox->SetQuickHelpText(nId, aQuickHelpText); + { + if (m_pToolbar) + m_pToolbar->set_item_tooltip_text(m_aCommandURL.toUtf8(), aQuickHelpText); + else + pToolBox->SetQuickHelpText(nId, aQuickHelpText); + } +} + +std::unique_ptr SvxUndoRedoControl::weldPopupWindow() +{ + if ( m_aCommandURL == ".uno:Undo" ) + updateStatus( ".uno:GetUndoStrings"); + else + updateStatus( ".uno:GetRedoStrings"); + + return std::make_unique(this, m_pToolbar, aUndoRedoList); } -VclPtr SvxUndoRedoControl::createVclPopupWindow(vcl::Window* pParent) +VclPtr SvxUndoRedoControl::createVclPopupWindow( vcl::Window* pParent ) { if ( m_aCommandURL == ".uno:Undo" ) updateStatus( ".uno:GetUndoStrings"); else updateStatus( ".uno:GetRedoStrings"); - auto xPopupWin = VclPtr::Create(this, pParent); + auto xPopupWin = std::make_unique(this, pParent->GetFrameWeld(), aUndoRedoList); - ListBox &rListBox = xPopupWin->GetListBox(); + mxInterimPopover = VclPtr::Create(getFrameInterface(), pParent, + std::move(xPopupWin)); - for(const OUString & s : aUndoRedoList) - rListBox.InsertEntry( s ); + SetInfo(1); // count of selected rows - rListBox.SelectEntryPos(0); - xPopupWin->SetInfo(rListBox.GetSelectedEntryCount()); + mxInterimPopover->Show(); - return xPopupWin; + return mxInterimPopover; } OUString SvxUndoRedoControl::getImplementationName() diff --git a/svx/uiconfig/ui/floatingundoredo.ui b/svx/uiconfig/ui/floatingundoredo.ui index d9a259835d35..079bb2c586ee 100644 --- a/svx/uiconfig/ui/floatingundoredo.ui +++ b/svx/uiconfig/ui/floatingundoredo.ui @@ -1,33 +1,59 @@ - + - + + + + + + + + + False - True - True - 6 - False - True - popup-menu - True - False + True + 4 - + True False True True vertical + 6 - + True True True True - False - - + never + + + True + True + True + liststore1 + False + False + False + 0 + False + + + + + + + + + 0 + + + + + -- cgit v1.2.3