From a1571c111fb4bd8ba466dc9026c22e58351625f1 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Sat, 27 Feb 2021 20:07:29 +0000 Subject: drop intermediate vcl container for ScFilterListBox floating toplevel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ib76fe7658f5f6817f048b1490be59bf24fc26e11 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111688 Tested-by: Jenkins Reviewed-by: Caolán McNamara Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125646 Tested-by: Jenkins CollaboraOffice Reviewed-by: Jan Holesovsky --- sc/source/ui/inc/FilterFloatingWindow.hxx | 37 -------- sc/source/ui/inc/FilterListBox.hxx | 24 +++-- sc/source/ui/inc/gridwin.hxx | 9 +- sc/source/ui/view/gridwin.cxx | 142 ++++++++++-------------------- sc/uiconfig/scalc/ui/filterlist.ui | 88 +++++++++--------- 5 files changed, 114 insertions(+), 186 deletions(-) delete mode 100644 sc/source/ui/inc/FilterFloatingWindow.hxx 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 - -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 1a4685ff5656..f29641165235 100644 --- a/sc/source/ui/inc/FilterListBox.hxx +++ b/sc/source/ui/inc/FilterListBox.hxx @@ -19,7 +19,9 @@ #pragma once -#include +#include + +#include class ScGridWindow; @@ -29,15 +31,18 @@ enum class ScFilterBoxMode Scenario }; -class ScFilterListBox final : public InterimItemWindow +class ScFilterListBox final : public std::enable_shared_from_this { private: + std::unique_ptr xBuilder; + std::unique_ptr xPopover; std::unique_ptr xTreeView; VclPtr pGridWin; SCCOL nCol; SCROW nRow; bool bInit; bool bCancelled; + bool bGridHadMouseCaptured; sal_uLong nSel; ScFilterBoxMode eMode; ImplSVEvent* nAsyncSelectHdl; @@ -47,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& rLink) + { + xPopover->connect_closed(rLink); + } + void popdown() { xPopover->popdown(); } + ~ScFilterListBox(); weld::TreeView& get_widget() { return *xTreeView; } @@ -59,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 a4eab900b548..b4c9c619d072 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -51,7 +51,6 @@ class ScOutputData; class SdrObject; class SdrEditView; class ScNoteMarker; -class FloatingWindow; class SdrHdlList; class ScTransferObj; struct SpellCallbackInfo; @@ -84,7 +83,6 @@ struct SpellCallbackInfo; namespace sdr::overlay { class OverlayObjectList; } class ScFilterListBox; -class ScFilterFloatingWindow; class SAL_DLLPUBLIC_RTTI ScGridWindow : public vcl::Window, public DropTargetHelper, public DragSourceHelper { @@ -155,8 +153,7 @@ class SAL_DLLPUBLIC_RTTI ScGridWindow : public vcl::Window, public DropTargetHel std::unique_ptr> mpNoteMarker; - VclPtr mpFilterBox; - VclPtr mpFilterFloat; + std::shared_ptr mpFilterBox; VclPtr mpAutoFilterPopup; VclPtr mpDPFieldPopup; std::unique_ptr mpFilterButton; @@ -216,7 +213,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 ); @@ -384,7 +381,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 b52bd12a6fc3..bb0c8bac9fe5 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -141,7 +142,6 @@ #include #include -#include using namespace css; using namespace css::uno; @@ -183,38 +183,32 @@ 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)); } ScFilterListBox::~ScFilterListBox() -{ - disposeOnce(); -} - -void ScFilterListBox::dispose() { if (nAsyncSelectHdl) { Application::RemoveUserEvent(nAsyncSelectHdl); nAsyncSelectHdl = nullptr; } - pGridWin.clear(); - xTreeView.reset(); - InterimItemWindow::dispose(); } void ScFilterListBox::EndInit() @@ -267,9 +261,9 @@ IMPL_LINK_NOARG(ScFilterListBox, AsyncSelectHdl, void*, void) nAsyncSelectHdl = nullptr; //tdf#133971 hold self-ref until we return - VclPtr 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; @@ -277,23 +271,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 @@ -380,7 +357,6 @@ ScGridWindow::ScGridWindow( vcl::Window* pParent, ScViewData& rData, ScSplitPos eWhich( eWhichPos ), mpNoteMarker(), mpFilterBox(), - mpFilterFloat(), mpAutoFilterPopup(), mpDPFieldPopup(), mpFilterButton(), @@ -462,8 +438,7 @@ void ScGridWindow::dispose() { ImpDestroyOverlayObjects(); - mpFilterBox.disposeAndClear(); - mpFilterFloat.disposeAndClear(); + mpFilterBox.reset(); mpNoteMarker.reset(); mpAutoFilterPopup.disposeAndClear(); mpDPFieldPopup.disposeAndClear(); @@ -483,8 +458,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); @@ -495,14 +469,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(); } @@ -944,7 +921,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(); @@ -984,12 +961,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 ) @@ -997,8 +973,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(); @@ -1020,7 +995,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) @@ -1032,15 +1007,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::Create(this)); - mpFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) ); - mpFilterBox.reset(VclPtr::Create(mpFilterFloat.get(), this, nCol, nRow, ScFilterBoxMode::Scenario)); + weld::Window* pParent = weld::GetPopupParent(*this, aCellRect); + mpFilterBox = std::make_shared(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; @@ -1060,7 +1032,7 @@ void ScGridWindow::DoScenarioMenu( const ScRange& rScenRange ) } rFilterBox.thaw(); - ShowFilterMenu(aCellRect, bLayoutRTL); + ShowFilterMenu(pParent, aCellRect, bLayoutRTL); rFilterBox.grab_focus(); @@ -1083,8 +1055,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(); @@ -1113,19 +1084,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::Create(this)); - if (bLOKActive) - { - mpFilterFloat->SetLOKNotifier(SfxViewShell::Current()); - } - mpFilterFloat->SetPopupModeEndHdl(LINK( this, ScGridWindow, PopupModeEndHdl)); - mpFilterBox.reset(VclPtr::Create(mpFilterFloat.get(), this, nCol, nRow, ScFilterBoxMode::DataSelect)); + weld::Window* pParent = weld::GetPopupParent(*this, aCellRect); + mpFilterBox = std::make_shared(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 @@ -1140,7 +1103,6 @@ void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow ) if (!bEmpty) { - mpFilterBox->Show(); // Show has to be before freeze !!! rFilterBox.freeze(); // Fill Listbox @@ -1157,7 +1119,7 @@ void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow ) rFilterBox.thaw(); - ShowFilterMenu(aCellRect, bLayoutRTL); + ShowFilterMenu(pParent, aCellRect, bLayoutRTL); } sal_Int32 nSelPos = -1; @@ -1197,8 +1159,7 @@ void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow ) if ( bEmpty ) { - mpFilterBox.disposeAndClear(); - mpFilterFloat.disposeAndClear(); + mpFilterBox.reset(); } else { @@ -1235,8 +1196,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 } @@ -2420,19 +2381,6 @@ void ScGridWindow::MouseMove( const MouseEvent& rMEvt ) return; } - if (nMouseStatus == SC_GM_FILTER && mpFilterBox) - { - Point aRelPos = mpFilterBox->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ); - if ( tools::Rectangle(Point(), mpFilterBox->GetOutputSizePixel()).IsInside(aRelPos) ) - { - nButtonDown = 0; - nMouseStatus = SC_GM_NONE; - ReleaseMouse(); - mpFilterBox->MouseButtonDown( MouseEvent( aRelPos, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT ) ); - return; - } - } - bool bFormulaMode = pScMod->IsFormulaMode(); // next click -> reference if (bEEMouse && mrViewData.HasEditView( eWhich )) 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 @@ - + - - - - - - - - - - True - False - True - True - vertical - 6 + + False + bottom - + True - True + False True True - never + vertical + 6 - + True - True + True + True True - liststore1 - False - False - 0 - True - False - True - - - + never - + + True + True + True + liststore1 + False + False + 0 + True + False + True + + + - - - 0 - + + + + + 0 + + + + + False + True + 0 + - - False - True - 0 - + + + + + + + + -- cgit