[Libreoffice-commits] core.git: dbaccess/source include/svtools svtools/source svx/source

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Sun Jul 12 18:54:50 UTC 2020


 dbaccess/source/ui/dlg/indexfieldscontrol.cxx |    1 
 include/svtools/editbrowsebox.hxx             |   13 ++++--
 svtools/source/brwbox/ebbcontrols.cxx         |   43 +++++++++++++++----
 svtools/source/brwbox/editbrowsebox.cxx       |   56 ++++----------------------
 svx/source/fmcomp/gridcell.cxx                |    9 +---
 5 files changed, 56 insertions(+), 66 deletions(-)

New commits:
commit 0b05a04f978688aedce90e259a31873de82a2d2a
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Sun Jul 12 15:43:46 2020 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Sun Jul 12 20:54:15 2020 +0200

    clarify what WantMouseEvent is for
    
    and add tristate machine support that we also need
    
    WantMouseEvent is if the first click in a browse cell that activates it should
    be passed to the control that appears on click as if it was itself clicked on
    
    primarily for the the CheckBoxController to toggle it immediately.
    Rework to explicitly toggle the checkbox in that implementation rather than
    rely on passing fake mouse click/release/tracking events.
    
    seeing as the main dbaccess table design view doesn't auto-launch its listboxes
    on clicking in a cell, but the sub create index dialog does, drop the auto-launch
    in the index dialog to match the main table design rathern than add a feature
    to weld::ComboBox to auto-launch the popup for that one solitary case
    
    Change-Id: Ie3d3f2ecf55d3d5b0b02b85ca09a6ca64bb800e9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98603
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/dbaccess/source/ui/dlg/indexfieldscontrol.cxx b/dbaccess/source/ui/dlg/indexfieldscontrol.cxx
index e0613e02ac17..dd959a05dda8 100644
--- a/dbaccess/source/ui/dlg/indexfieldscontrol.cxx
+++ b/dbaccess/source/ui/dlg/indexfieldscontrol.cxx
@@ -53,7 +53,6 @@ constexpr auto BROWSER_STANDARD_FLAGS = BrowserMode::COLUMNSELECTION | BrowserMo
         void SetAdditionalModifyHdl(const Link<DbaMouseDownListBoxController&,void>& _rHdl);
 
     protected:
-        virtual bool WantMouseEvent() const override { return true; }
         virtual void callModifyHdl() override;
     };
 
diff --git a/include/svtools/editbrowsebox.hxx b/include/svtools/editbrowsebox.hxx
index 3b21aaea53c4..fde44b38d136 100644
--- a/include/svtools/editbrowsebox.hxx
+++ b/include/svtools/editbrowsebox.hxx
@@ -105,7 +105,7 @@ namespace svt
     protected:
         virtual bool MoveAllowed(const KeyEvent& rEvt) const;
         void SetModifyHdl(const Link<LinkParamNone*,void>& rLink) { maModifyHdl = rLink; }
-        virtual bool WantMouseEvent() const;
+        virtual void ActivatingMouseEvent(const BrowserMouseEvent& rEvt, bool bUp);
         virtual void callModifyHdl() { maModifyHdl.Call(nullptr); }
     };
 
@@ -581,10 +581,10 @@ namespace svt
     class SVT_DLLPUBLIC CheckBoxControl final : public ControlBase
     {
         std::unique_ptr<weld::CheckButton> m_xBox;
+        weld::TriStateEnabled m_aModeState;
         Link<weld::Button&,void> m_aClickLink;
         Link<LinkParamNone*,void> m_aModify1Hdl;
         Link<LinkParamNone*,void> m_aModify2Hdl;
-        bool m_bTriState;
 
     public:
         CheckBoxControl(BrowserDataWin* pParent);
@@ -612,8 +612,13 @@ namespace svt
 
         weld::CheckButton&   GetBox() {return *m_xBox;};
 
+        // for pseudo-click when initially clicking in a cell activates
+        // the cell and performs a state change on the button as if
+        // it was clicked on
+        void Clicked();
+
     private:
-        DECL_LINK(OnClick, weld::Button&, void);
+        DECL_LINK(OnToggle, weld::ToggleButton&, void);
 
         void CallModifyHdls()
         {
@@ -634,7 +639,7 @@ namespace svt
         virtual void SaveValue() override;
 
     private:
-        virtual bool WantMouseEvent() const override;
+        virtual void ActivatingMouseEvent(const BrowserMouseEvent& rEvt, bool bUp) override;
         DECL_LINK(ModifyHdl, LinkParamNone*, void);
     };
 
diff --git a/svtools/source/brwbox/ebbcontrols.cxx b/svtools/source/brwbox/ebbcontrols.cxx
index 911063b82d4e..cd65d3ed0264 100644
--- a/svtools/source/brwbox/ebbcontrols.cxx
+++ b/svtools/source/brwbox/ebbcontrols.cxx
@@ -168,28 +168,29 @@ namespace svt
     CheckBoxControl::CheckBoxControl(BrowserDataWin* pParent)
         : ControlBase(pParent, "svt/ui/checkboxcontrol.ui", "CheckBoxControl")
         , m_xBox(m_xBuilder->weld_check_button("checkbox"))
-        , m_bTriState(true)
     {
+        m_aModeState.bTriStateEnabled = true;
         InitControlBase(m_xBox.get());
         m_xBox->connect_key_press(LINK(this, ControlBase, KeyInputHdl));
-        m_xBox->connect_clicked(LINK(this, CheckBoxControl, OnClick));
+        m_xBox->connect_toggled(LINK(this, CheckBoxControl, OnToggle));
     }
 
     void CheckBoxControl::EnableTriState( bool bTriState )
     {
-        if (m_bTriState != bTriState)
+        if (m_aModeState.bTriStateEnabled != bTriState)
         {
-            m_bTriState = bTriState;
+            m_aModeState.bTriStateEnabled = bTriState;
 
-            if (!m_bTriState && GetState() == TRISTATE_INDET)
+            if (!m_aModeState.bTriStateEnabled && GetState() == TRISTATE_INDET)
                 SetState(TRISTATE_FALSE);
         }
     }
 
     void CheckBoxControl::SetState(TriState eState)
     {
-        if (!m_bTriState && (eState == TRISTATE_INDET))
+        if (!m_aModeState.bTriStateEnabled && (eState == TRISTATE_INDET))
             eState = TRISTATE_FALSE;
+        m_aModeState.eState = eState;
         m_xBox->set_state(eState);
     }
 
@@ -204,8 +205,18 @@ namespace svt
         ControlBase::dispose();
     }
 
-    IMPL_LINK_NOARG(CheckBoxControl, OnClick, weld::Button&, void)
+    void CheckBoxControl::Clicked()
     {
+        // if tristate is enabled, m_aModeState will take care of setting the
+        // next state in the sequence via TriStateEnabled::ButtonToggled
+        if (!m_aModeState.bTriStateEnabled)
+            m_xBox->set_active(!m_xBox->get_active());
+        OnToggle(*m_xBox);
+    }
+
+    IMPL_LINK_NOARG(CheckBoxControl, OnToggle, weld::ToggleButton&, void)
+    {
+        m_aModeState.ButtonToggled(*m_xBox);
         m_aClickLink.Call(*m_xBox);
         CallModifyHdls();
     }
@@ -217,9 +228,23 @@ namespace svt
         static_cast<CheckBoxControl &>(GetWindow()).SetModifyHdl( LINK(this, CheckBoxCellController, ModifyHdl) );
     }
 
-    bool CheckBoxCellController::WantMouseEvent() const
+    void CheckBoxCellController::ActivatingMouseEvent(const BrowserMouseEvent& rEvt, bool /*bUp*/)
     {
-        return true;
+        CheckBoxControl& rControl = static_cast<CheckBoxControl&>(GetWindow());
+        rControl.GrabFocus();
+
+        // we have to adjust the position of the event relative to the controller's window
+        Point aPos = rEvt.GetPosPixel() - rEvt.GetRect().TopLeft();
+
+        Size aControlSize = rControl.GetSizePixel();
+        Size aBoxSize = rControl.GetBox().get_preferred_size();
+        tools::Rectangle aHotRect(Point((aControlSize.Width() - aBoxSize.Width()) / 2,
+                                        (aControlSize.Height() - aBoxSize.Height()) / 2),
+                                  aBoxSize);
+
+        // we want the initial mouse event to act as if it was performed on the checkbox
+        if (aHotRect.IsInside(aPos))
+            rControl.Clicked();
     }
 
     weld::CheckButton& CheckBoxCellController::GetCheckBox() const
diff --git a/svtools/source/brwbox/editbrowsebox.cxx b/svtools/source/brwbox/editbrowsebox.cxx
index b9249ccd9ebc..a5c13f067400 100644
--- a/svtools/source/brwbox/editbrowsebox.cxx
+++ b/svtools/source/brwbox/editbrowsebox.cxx
@@ -481,50 +481,13 @@ namespace svt
         else if (IsEditing() && !ControlHasFocus())
             AsynchGetFocus();
 
-        if (!(IsEditing() && aController->GetWindow().IsEnabled() && aController->WantMouseEvent()))
+        if (!IsEditing() || !aController->GetWindow().IsEnabled())
             return;
 
-// forwards the event to the control
-
-        // If the field has been moved previously, we have to adjust the position
-
-        aController->GetWindow().GrabFocus();
-
-        // the position of the event relative to the controller's window
-        Point aPos = _rEvt.GetPosPixel() - _rEvt.GetRect().TopLeft();
-        // the (child) window which should really get the event
-        vcl::Window* pRealHandler = aController->GetWindow().FindWindow(aPos);
-        if (pRealHandler)
-            // the coords relative to this real handler
-            aPos -= pRealHandler->GetPosPixel();
-        else
-            pRealHandler = &aController->GetWindow();
-
-        // the faked event
-        MouseEvent aEvent(aPos, _rEvt.GetClicks(), _rEvt.GetMode(),
-                          _rEvt.GetButtons(),
-                          _rEvt.GetModifier());
-
-        pRealHandler->MouseButtonDown(aEvent);
-        if (_bUp)
-            pRealHandler->MouseButtonUp(aEvent);
-
-        vcl::Window *pWin = &aController->GetWindow();
-        if (!pWin->IsTracking())
-        {
-            for (pWin = pWin->GetWindow(GetWindowType::FirstChild);
-                 pWin && !pWin->IsTracking();
-                 pWin = pWin->GetWindow(GetWindowType::Next))
-            {
-            }
-            if (!pWin)
-                pWin = pRealHandler;
-        }
-        if (pWin && pWin->IsTracking())
-            pWin->EndTracking();
+        // forwards the event to the control
+        aController->ActivatingMouseEvent(_rEvt, _bUp);
     }
 
-
     void EditBrowseBox::Dispatch( sal_uInt16 _nId )
     {
         if ( _nId == BROWSER_ENHANCESELECTION )
@@ -1222,11 +1185,10 @@ namespace svt
 
         pCheckBoxPaint->GetBox().set_sensitive(_bEnabled);
 
-        auto nWidth = pCheckBoxPaint->GetBox().get_preferred_size().Width();
-        auto nHeight = pCheckBoxPaint->GetBox().get_preferred_size().Height();
-        tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - nWidth) / 2),
-                                     rRect.Top() + ((rRect.GetHeight() - nHeight) / 2)),
-                               Size(nWidth, nHeight));
+        Size aBoxSize = pCheckBoxPaint->GetBox().get_preferred_size();
+        tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - aBoxSize.Width()) / 2),
+                                     rRect.Top() + ((rRect.GetHeight() - aBoxSize.Height()) / 2)),
+                               aBoxSize);
         pCheckBoxPaint->SetPosSizePixel(aRect.TopLeft(), aRect.GetSize());
 
         pCheckBoxPaint->Draw(&GetDataWindow(), aRect.TopLeft(), DrawFlags::NONE);
@@ -1305,9 +1267,9 @@ namespace svt
         // nothing to do in this base class
     }
 
-    bool CellController::WantMouseEvent() const
+    void CellController::ActivatingMouseEvent(const BrowserMouseEvent& /*rEvt*/, bool /*bUp*/)
     {
-        return false;
+        // nothing to do in this base class
     }
 
     bool CellController::MoveAllowed(const KeyEvent&) const
diff --git a/svx/source/fmcomp/gridcell.cxx b/svx/source/fmcomp/gridcell.cxx
index 67137720d18b..a813e7710a99 100644
--- a/svx/source/fmcomp/gridcell.cxx
+++ b/svx/source/fmcomp/gridcell.cxx
@@ -1696,11 +1696,10 @@ void DbCheckBox::PaintFieldToCell(OutputDevice& rDev, const tools::Rectangle& rR
     CheckBoxControl* pControl = static_cast<CheckBoxControl*>(m_pPainter.get());
     lcl_setCheckBoxState( _rxField, pControl );
 
-    auto nWidth = pControl->GetBox().get_preferred_size().Width();
-    auto nHeight = pControl->GetBox().get_preferred_size().Height();
-    tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - nWidth) / 2),
-                                 rRect.Top() + ((rRect.GetHeight() - nHeight) / 2)),
-                           Size(nWidth, nHeight));
+    Size aBoxSize = pControl->GetBox().get_preferred_size();
+    tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - aBoxSize.Width()) / 2),
+                                 rRect.Top() + ((rRect.GetHeight() - aBoxSize.Height()) / 2)),
+                           aBoxSize);
 
     DbCellControl::PaintFieldToCell(rDev, aRect, _rxField, xFormatter);
 }


More information about the Libreoffice-commits mailing list