diff options
author | Caolán McNamara <caolanm@redhat.com> | 2021-02-27 20:07:29 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2021-03-01 10:11:16 +0100 |
commit | 451d05d11324ef3ff4d6a65eca2c6291818373d9 (patch) | |
tree | 043d49b84a2d06b540fcf833fc15fea54a6c8b4e | |
parent | a95dc94446b2a19db6223efe174e2cff09464664 (diff) |
drop intermediate vcl container for ScFilterListBox floating toplevel
Change-Id: Ib76fe7658f5f6817f048b1490be59bf24fc26e11
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111688
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | sc/source/ui/inc/FilterFloatingWindow.hxx | 37 | ||||
-rw-r--r-- | sc/source/ui/inc/FilterListBox.hxx | 22 | ||||
-rw-r--r-- | sc/source/ui/inc/gridwin.hxx | 9 | ||||
-rw-r--r-- | sc/source/ui/view/gridwin.cxx | 125 | ||||
-rw-r--r-- | sc/uiconfig/scalc/ui/filterlist.ui | 88 |
5 files changed, 112 insertions, 169 deletions
diff --git a/sc/source/ui/inc/FilterFloatingWindow.hxx b/sc/source/ui/inc/FilterFloatingWindow.hxx deleted file mode 100644 index 71c13c62c864..000000000000 --- a/sc/source/ui/inc/FilterFloatingWindow.hxx +++ /dev/null @@ -1,37 +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 <vcl/floatwin.hxx> - -class ScFilterFloatingWindow : public FloatingWindow -{ -private: - bool m_bGridHadMouseCaptured; - -public: - ScFilterFloatingWindow(vcl::Window* pParent); - virtual ~ScFilterFloatingWindow() override; - virtual void dispose() override; - - bool MouseWasCaptured() const { return m_bGridHadMouseCaptured; } -}; - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/inc/FilterListBox.hxx b/sc/source/ui/inc/FilterListBox.hxx index 0177bb4691a5..f29641165235 100644 --- a/sc/source/ui/inc/FilterListBox.hxx +++ b/sc/source/ui/inc/FilterListBox.hxx @@ -21,7 +21,7 @@ #include <types.hxx> -#include <vcl/InterimItemWindow.hxx> +#include <vcl/weld.hxx> class ScGridWindow; @@ -31,15 +31,18 @@ enum class ScFilterBoxMode Scenario }; -class ScFilterListBox final : public InterimItemWindow +class ScFilterListBox final : public std::enable_shared_from_this<ScFilterListBox> { private: + std::unique_ptr<weld::Builder> xBuilder; + std::unique_ptr<weld::Popover> xPopover; std::unique_ptr<weld::TreeView> xTreeView; VclPtr<ScGridWindow> pGridWin; SCCOL nCol; SCROW nRow; bool bInit; bool bCancelled; + bool bGridHadMouseCaptured; sal_uLong nSel; ScFilterBoxMode eMode; ImplSVEvent* nAsyncSelectHdl; @@ -49,10 +52,18 @@ private: DECL_LINK(AsyncSelectHdl, void*, void); public: - ScFilterListBox(vcl::Window* pParent, ScGridWindow* pGrid, SCCOL nNewCol, SCROW nNewRow, + ScFilterListBox(weld::Window* pParent, ScGridWindow* pGrid, SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode); - virtual ~ScFilterListBox() override; - virtual void dispose() override; + void popup_at_rect(weld::Widget* pParent, const tools::Rectangle& rRect) + { + xPopover->popup_at_rect(pParent, rRect); + } + void connect_closed(const Link<weld::Popover&, void>& rLink) + { + xPopover->connect_closed(rLink); + } + void popdown() { xPopover->popdown(); } + ~ScFilterListBox(); weld::TreeView& get_widget() { return *xTreeView; } @@ -61,6 +72,7 @@ public: ScFilterBoxMode GetMode() const { return eMode; } void EndInit(); bool IsInInit() const { return bInit; } + bool MouseWasCaptured() const { return bGridHadMouseCaptured; } void SetCancelled() { bCancelled = true; } }; diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index 2202b3647563..b4f08368d530 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -50,7 +50,6 @@ class ScOutputData; class SdrObject; class SdrEditView; class ScNoteMarker; -class FloatingWindow; class SdrHdlList; class ScTransferObj; struct SpellCallbackInfo; @@ -83,7 +82,6 @@ struct SpellCallbackInfo; namespace sdr::overlay { class OverlayObjectList; } class ScFilterListBox; -class ScFilterFloatingWindow; class SAL_DLLPUBLIC_RTTI ScGridWindow : public vcl::Window, public DropTargetHelper, public DragSourceHelper { @@ -154,8 +152,7 @@ class SAL_DLLPUBLIC_RTTI ScGridWindow : public vcl::Window, public DropTargetHel std::unique_ptr<ScNoteMarker, o3tl::default_delete<ScNoteMarker>> mpNoteMarker; - VclPtr<ScFilterListBox> mpFilterBox; - VclPtr<ScFilterFloatingWindow> mpFilterFloat; + std::shared_ptr<ScFilterListBox> mpFilterBox; VclPtr<ScCheckListMenuWindow> mpAutoFilterPopup; VclPtr<ScCheckListMenuWindow> mpDPFieldPopup; std::unique_ptr<ScDPFieldButton> mpFilterButton; @@ -215,7 +212,7 @@ class SAL_DLLPUBLIC_RTTI ScGridWindow : public vcl::Window, public DropTargetHel bool bAutoMarkVisible:1; bool bListValButton:1; - DECL_LINK( PopupModeEndHdl, FloatingWindow*, void ); + DECL_LINK( PopupModeEndHdl, weld::Popover&, void ); DECL_LINK( PopupSpellingHdl, SpellCallbackInfo&, void ); bool TestMouse( const MouseEvent& rMEvt, bool bAction ); @@ -383,7 +380,7 @@ public: void UpdateFormulas(SCCOL nX1 = -1, SCROW nY1 = -1, SCCOL nX2 = -1, SCROW nY2 = -1); - void ShowFilterMenu(const tools::Rectangle& rCellRect, bool bLayoutRTL); + void ShowFilterMenu(weld::Window* pParent, const tools::Rectangle& rCellRect, bool bLayoutRTL); void LaunchDataSelectMenu( SCCOL nCol, SCROW nRow ); void DoScenarioMenu( const ScRange& rScenRange ); diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 28d8ecfb1ba3..f3a543075b9d 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -43,6 +43,7 @@ #include <vcl/inputctx.hxx> #include <vcl/menu.hxx> #include <vcl/settings.hxx> +#include <vcl/weldutils.hxx> #include <sot/formats.hxx> #include <comphelper/classids.hxx> @@ -139,7 +140,6 @@ #include <boost/property_tree/json_parser.hpp> #include <FilterListBox.hxx> -#include <FilterFloatingWindow.hxx> using namespace css; using namespace css::uno; @@ -181,18 +181,20 @@ bool ScGridWindow::VisibleRange::set(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCRO } // ListBox in a FloatingWindow (pParent) -ScFilterListBox::ScFilterListBox( vcl::Window* pParent, ScGridWindow* pGrid, - SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode ) : - InterimItemWindow(pParent, "modules/scalc/ui/filterlist.ui", "FilterList"), - xTreeView(m_xBuilder->weld_tree_view("list")), - pGridWin( pGrid ), - nCol( nNewCol ), - nRow( nNewRow ), - bInit( true ), - bCancelled( false ), - nSel( 0 ), - eMode( eNewMode ), - nAsyncSelectHdl(nullptr) +ScFilterListBox::ScFilterListBox(weld::Window* pParent, ScGridWindow* pGrid, + SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode) + : xBuilder(Application::CreateBuilder(pParent, "modules/scalc/ui/filterlist.ui")) + , xPopover(xBuilder->weld_popover("FilterList")) + , xTreeView(xBuilder->weld_tree_view("list")) + , pGridWin(pGrid) + , nCol(nNewCol) + , nRow(nNewRow) + , bInit(true) + , bCancelled(false) + , bGridHadMouseCaptured(pGrid->IsMouseCaptured()) + , nSel(0) + , eMode(eNewMode) + , nAsyncSelectHdl(nullptr) { xTreeView->connect_row_activated(LINK(this, ScFilterListBox, SelectHdl)); xTreeView->connect_key_press(LINK(this, ScFilterListBox, KeyInputHdl)); @@ -200,19 +202,11 @@ ScFilterListBox::ScFilterListBox( vcl::Window* pParent, ScGridWindow* pGrid, ScFilterListBox::~ScFilterListBox() { - disposeOnce(); -} - -void ScFilterListBox::dispose() -{ if (nAsyncSelectHdl) { Application::RemoveUserEvent(nAsyncSelectHdl); nAsyncSelectHdl = nullptr; } - pGridWin.clear(); - xTreeView.reset(); - InterimItemWindow::dispose(); } void ScFilterListBox::EndInit() @@ -265,9 +259,9 @@ IMPL_LINK_NOARG(ScFilterListBox, AsyncSelectHdl, void*, void) nAsyncSelectHdl = nullptr; //tdf#133971 hold self-ref until we return - VclPtr<ScFilterListBox> xThis(this); + auto xThis(shared_from_this()); pGridWin->FilterSelect(nSel); - if (!pGridWin) + if (xThis.use_count() == 1) { // tdf#133855 we got disposed by FilterSelect return; @@ -275,23 +269,6 @@ IMPL_LINK_NOARG(ScFilterListBox, AsyncSelectHdl, void*, void) pGridWin->ClickExtern(); } -ScFilterFloatingWindow::ScFilterFloatingWindow(vcl::Window* pParent) - : FloatingWindow( pParent, WB_BORDER | WB_SYSTEMWINDOW ) // make it a system floater - , m_bGridHadMouseCaptured(pParent->IsMouseCaptured()) -{ -} - -ScFilterFloatingWindow::~ScFilterFloatingWindow() -{ - disposeOnce(); -} - -void ScFilterFloatingWindow::dispose() -{ - EndPopupMode(); - FloatingWindow::dispose(); -} - static bool lcl_IsEditableMatrix( ScDocument& rDoc, const ScRange& rRange ) { // If it is an editable range and if there is a Matrix cell at the bottom right with an @@ -378,7 +355,6 @@ ScGridWindow::ScGridWindow( vcl::Window* pParent, ScViewData& rData, ScSplitPos eWhich( eWhichPos ), mpNoteMarker(), mpFilterBox(), - mpFilterFloat(), mpAutoFilterPopup(), mpDPFieldPopup(), mpFilterButton(), @@ -459,8 +435,7 @@ void ScGridWindow::dispose() { ImpDestroyOverlayObjects(); - mpFilterBox.disposeAndClear(); - mpFilterFloat.disposeAndClear(); + mpFilterBox.reset(); mpNoteMarker.reset(); mpAutoFilterPopup.disposeAndClear(); mpDPFieldPopup.disposeAndClear(); @@ -480,8 +455,7 @@ void ScGridWindow::ClickExtern() // #i84277# when initializing the filter box, a Basic error can deactivate the view if (mpFilterBox && mpFilterBox->IsInInit()) break; - mpFilterBox.disposeAndClear(); - mpFilterFloat.disposeAndClear(); + mpFilterBox.reset(); } while (false); @@ -492,14 +466,17 @@ void ScGridWindow::ClickExtern() } } -IMPL_LINK_NOARG(ScGridWindow, PopupModeEndHdl, FloatingWindow*, void) +IMPL_LINK_NOARG(ScGridWindow, PopupModeEndHdl, weld::Popover&, void) { if (mpFilterBox) + { + bool bMouseWasCaptured = mpFilterBox->MouseWasCaptured(); mpFilterBox->SetCancelled(); // cancel select - // restore the mouse capture state of the GridWindow to - // what it was at initial popup time - if (mpFilterFloat->MouseWasCaptured()) - CaptureMouse(); + // restore the mouse capture state of the GridWindow to + // what it was at initial popup time + if (bMouseWasCaptured) + CaptureMouse(); + } GrabFocus(); } @@ -941,7 +918,7 @@ void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol, SCROW nRow ) DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, ScAddress(nCol, nRow, nTab), pDPObj); } -void ScGridWindow::ShowFilterMenu(const tools::Rectangle& rCellRect, bool bLayoutRTL) +void ScGridWindow::ShowFilterMenu(weld::Window* pParent, const tools::Rectangle& rCellRect, bool bLayoutRTL) { auto nSizeX = rCellRect.GetWidth(); @@ -981,12 +958,11 @@ void ScGridWindow::ShowFilterMenu(const tools::Rectangle& rCellRect, bool bLayou aCellRect.SetLeft( nNewX ); } - mpFilterBox->SetSizePixel(aSize); - mpFilterFloat->SetOutputSizePixel(aSize); + rFilterBox.set_size_request(aSize.Width(), aSize.Height()); if (IsMouseCaptured()) ReleaseMouse(); - mpFilterFloat->StartPopupMode(aCellRect, FloatWinPopupFlags::Down|FloatWinPopupFlags::GrabFocus|FloatWinPopupFlags::NoMouseUpClose); + mpFilterBox->popup_at_rect(pParent, aCellRect); } void ScGridWindow::DoScenarioMenu( const ScRange& rScenRange ) @@ -994,8 +970,7 @@ void ScGridWindow::DoScenarioMenu( const ScRange& rScenRange ) bool bMenuAtTop = true; ScDocument& rDoc = mrViewData.GetDocument(); - mpFilterBox.disposeAndClear(); - mpFilterFloat.disposeAndClear(); + mpFilterBox.reset(); SCCOL nCol = rScenRange.aEnd.Col(); // Cell is below the Buttons SCROW nRow = rScenRange.aStart.Row(); @@ -1017,7 +992,7 @@ void ScGridWindow::DoScenarioMenu( const ScRange& rScenRange ) Point aPos = mrViewData.GetScrPos( nCol, nRow, eWhich ); if ( bLayoutRTL ) aPos.AdjustX( -nSizeX ); - tools::Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) ); + tools::Rectangle aCellRect(aPos, Size(nSizeX, nSizeY)); aCellRect.AdjustTop( -nSizeY ); aCellRect.AdjustBottom( -(nSizeY - 1) ); if (!bMenuAtTop) @@ -1029,15 +1004,12 @@ void ScGridWindow::DoScenarioMenu( const ScRange& rScenRange ) // Place the ListBox directly below the black line of the cell grid // (It looks odd if the line gets hidden...) - mpFilterFloat.reset(VclPtr<ScFilterFloatingWindow>::Create(this)); - mpFilterFloat->SetPopupModeEndHdl(LINK(this, ScGridWindow, PopupModeEndHdl)); - mpFilterBox.reset(VclPtr<ScFilterListBox>::Create(mpFilterFloat.get(), this, nCol, nRow, ScFilterBoxMode::Scenario)); + weld::Window* pParent = weld::GetPopupParent(*this, aCellRect); + mpFilterBox = std::make_shared<ScFilterListBox>(pParent, this, nCol, nRow, ScFilterBoxMode::Scenario); + mpFilterBox->connect_closed(LINK(this, ScGridWindow, PopupModeEndHdl)); weld::TreeView& rFilterBox = mpFilterBox->get_widget(); rFilterBox.set_direction(bLayoutRTL); // Fix for bug fdo#44925 use sheet direction for widget RTL/LTR - mpFilterBox->Show(); // Show has to be before SetUpdateMode !!! - // SetOutputSizePixel/StartPopupMode first below, when the size is set - // Listbox fill rFilterBox.freeze(); OUString aCurrent; @@ -1057,7 +1029,7 @@ void ScGridWindow::DoScenarioMenu( const ScRange& rScenRange ) } rFilterBox.thaw(); - ShowFilterMenu(aCellRect, bLayoutRTL); + ShowFilterMenu(pParent, aCellRect, bLayoutRTL); rFilterBox.grab_focus(); @@ -1080,8 +1052,7 @@ void ScGridWindow::DoScenarioMenu( const ScRange& rScenRange ) void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow ) { - mpFilterBox.disposeAndClear(); - mpFilterFloat.disposeAndClear(); + mpFilterBox.reset(); ScDocument& rDoc = mrViewData.GetDocument(); SCTAB nTab = mrViewData.GetTabNo(); @@ -1110,15 +1081,11 @@ void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow ) if ( bLayoutRTL ) aPos.AdjustX( -nSizeX ); + tools::Rectangle aCellRect(aPos, Size(nSizeX, nSizeY)); - tools::Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) ); - - aPos.AdjustX( -1 ); - aPos.AdjustY( nSizeY - 1 ); - - mpFilterFloat.reset(VclPtr<ScFilterFloatingWindow>::Create(this)); - mpFilterFloat->SetPopupModeEndHdl(LINK(this, ScGridWindow, PopupModeEndHdl)); - mpFilterBox.reset(VclPtr<ScFilterListBox>::Create(mpFilterFloat.get(), this, nCol, nRow, ScFilterBoxMode::DataSelect)); + weld::Window* pParent = weld::GetPopupParent(*this, aCellRect); + mpFilterBox = std::make_shared<ScFilterListBox>(pParent, this, nCol, nRow, ScFilterBoxMode::DataSelect); + mpFilterBox->connect_closed(LINK(this, ScGridWindow, PopupModeEndHdl)); weld::TreeView& rFilterBox = mpFilterBox->get_widget(); rFilterBox.set_direction(bLayoutRTL); // Fix for bug fdo#44925 use sheet direction for widget RTL/LTR @@ -1133,7 +1100,6 @@ void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow ) if (!bEmpty) { - mpFilterBox->Show(); // Show has to be before freeze !!! rFilterBox.freeze(); // Fill Listbox @@ -1150,7 +1116,7 @@ void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow ) rFilterBox.thaw(); - ShowFilterMenu(aCellRect, bLayoutRTL); + ShowFilterMenu(pParent, aCellRect, bLayoutRTL); } sal_Int32 nSelPos = -1; @@ -1190,8 +1156,7 @@ void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow ) if ( bEmpty ) { - mpFilterBox.disposeAndClear(); - mpFilterFloat.disposeAndClear(); + mpFilterBox.reset(); } else { @@ -1228,8 +1193,8 @@ void ScGridWindow::FilterSelect( sal_uLong nSel ) break; } - if (mpFilterFloat) - mpFilterFloat->EndPopupMode(); + if (mpFilterBox) + mpFilterBox->popdown(); GrabFocus(); // Otherwise the focus would be wrong on OS/2 } diff --git a/sc/uiconfig/scalc/ui/filterlist.ui b/sc/uiconfig/scalc/ui/filterlist.ui index 4f5222391cdc..783f977d6d5f 100644 --- a/sc/uiconfig/scalc/ui/filterlist.ui +++ b/sc/uiconfig/scalc/ui/filterlist.ui @@ -1,62 +1,68 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.22.2 --> +<!-- Generated with glade 3.38.2 --> <interface domain="sc"> <requires lib="gtk+" version="3.20"/> - <object class="GtkTreeStore" id="liststore1"> - <columns> - <!-- column-name text --> - <column type="gchararray"/> - <!-- column-name id --> - <column type="gchararray"/> - </columns> - </object> - <object class="GtkBox" id="FilterList"> - <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> - <property name="spacing">6</property> + <object class="GtkPopover" id="FilterList"> + <property name="can-focus">False</property> + <property name="position">bottom</property> <child> - <object class="GtkScrolledWindow"> + <object class="GtkBox" id="container"> <property name="visible">True</property> - <property name="can_focus">True</property> + <property name="can-focus">False</property> <property name="hexpand">True</property> <property name="vexpand">True</property> - <property name="hscrollbar_policy">never</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> <child> - <object class="GtkTreeView" id="list"> + <object class="GtkScrolledWindow"> <property name="visible">True</property> - <property name="can_focus">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="headers_visible">False</property> - <property name="headers_clickable">False</property> - <property name="search_column">0</property> - <property name="hover_selection">True</property> - <property name="show_expanders">False</property> - <property name="activate_on_single_click">True</property> - <child internal-child="selection"> - <object class="GtkTreeSelection" id="treeview-selection1"/> - </child> + <property name="hscrollbar-policy">never</property> <child> - <object class="GtkTreeViewColumn" id="treeviewcolumn1"> + <object class="GtkTreeView" id="list"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="vexpand">True</property> + <property name="model">liststore1</property> + <property name="headers-visible">False</property> + <property name="headers-clickable">False</property> + <property name="search-column">0</property> + <property name="hover-selection">True</property> + <property name="show-expanders">False</property> + <property name="activate-on-single-click">True</property> + <child internal-child="selection"> + <object class="GtkTreeSelection"/> + </child> <child> - <object class="GtkCellRendererText" id="cellrenderertext1"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> + <object class="GtkTreeViewColumn" id="treeviewcolumn1"> + <child> + <object class="GtkCellRendererText" id="cellrenderertext1"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> </child> </object> </child> </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> </child> </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> </child> </object> + <object class="GtkTreeStore" id="liststore1"> + <columns> + <!-- column-name text --> + <column type="gchararray"/> + <!-- column-name id --> + <column type="gchararray"/> + </columns> + </object> </interface> |