[Libreoffice-commits] core.git: solenv/sanitizers sw/source sw/uiconfig sw/UIConfig_swriter.mk

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Thu Dec 3 08:46:15 UTC 2020


 solenv/sanitizers/ui/modules/swriter.suppr             |    2 
 sw/UIConfig_swriter.mk                                 |    1 
 sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx |  104 ++++++++++++++---
 sw/source/uibase/inc/FrameControl.hxx                  |    5 
 sw/source/uibase/inc/OutlineContentVisibilityWin.hxx   |   24 ++-
 sw/source/uibase/wrtsh/wrtsh1.cxx                      |    2 
 sw/uiconfig/swriter/ui/outlinebutton.ui                |   59 +++++++++
 7 files changed, 172 insertions(+), 25 deletions(-)

New commits:
commit 0865857e7448d995b6e72d9c749d69da3f752e5e
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Mon Nov 30 12:29:35 2020 +0000
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Thu Dec 3 09:45:36 2020 +0100

    weld SwOutlineContentVisibilityWin
    
    Change-Id: I4a1b22e57c7834066d2a8e0fb89175c1e25d13b4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106916
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/solenv/sanitizers/ui/modules/swriter.suppr b/solenv/sanitizers/ui/modules/swriter.suppr
index 30a915a0e8ec..5eec1594569b 100644
--- a/solenv/sanitizers/ui/modules/swriter.suppr
+++ b/solenv/sanitizers/ui/modules/swriter.suppr
@@ -119,6 +119,8 @@ sw/uiconfig/swriter/ui/notebookbar_groups.ui://GtkLabel[@id='formatgrouplabel']
 sw/uiconfig/swriter/ui/notebookbar_groups.ui://GtkLabel[@id='insertgrouplabel'] orphan-label
 sw/uiconfig/swriter/ui/notebookbar_groups.ui://GtkLabel[@id='tablegrouplabel'] orphan-label
 sw/uiconfig/swriter/ui/notebookbar_groups.ui://GtkLabel[@id='imagegrouplabel'] orphan-label
+sw/uiconfig/swriter/ui/outlinebutton.ui://GtkButton[@id='right'] button-no-label
+sw/uiconfig/swriter/ui/outlinebutton.ui://GtkButton[@id='down'] button-no-label
 sw/uiconfig/swriter/ui/pagemargincontrol.ui://GtkSpinButton[@id='hidden'] no-labelled-by
 sw/uiconfig/swriter/ui/pagesizecontrol.ui://GtkSpinButton[@id='metric'] no-labelled-by
 sw/uiconfig/swriter/ui/printmonitordialog.ui://GtkLabel[@id='docname'] orphan-label
diff --git a/sw/UIConfig_swriter.mk b/sw/UIConfig_swriter.mk
index 366c1ed19854..33074fc8f76e 100644
--- a/sw/UIConfig_swriter.mk
+++ b/sw/UIConfig_swriter.mk
@@ -200,6 +200,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/swriter,\
 	sw/uiconfig/swriter/ui/optredlinepage \
 	sw/uiconfig/swriter/ui/opttablepage \
 	sw/uiconfig/swriter/ui/opttestpage \
+	sw/uiconfig/swriter/ui/outlinebutton \
 	sw/uiconfig/swriter/ui/outlinenumbering \
 	sw/uiconfig/swriter/ui/outlinenumberingpage \
 	sw/uiconfig/swriter/ui/outlinepositionpage \
diff --git a/sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx b/sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx
index 2ebb863b45e0..b696709d6042 100644
--- a/sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx
+++ b/sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx
@@ -15,27 +15,43 @@
 #include <IDocumentOutlineNodes.hxx>
 #include <txtfrm.hxx>
 #include <ndtxt.hxx>
-#include <vcl/button.hxx>
+#include <vcl/InterimItemWindow.hxx>
 #include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
 #include <strings.hrc>
 #include <svx/svdview.hxx>
 
-#define BUTTON_WIDTH 18
-#define BUTTON_HEIGHT 20
-
 SwOutlineContentVisibilityWin::SwOutlineContentVisibilityWin(SwEditWin* pEditWin,
                                                              const SwFrame* pFrame)
-    : PushButton(pEditWin, 0)
+    : InterimItemWindow(pEditWin, "modules/swriter/ui/outlinebutton.ui", "OutlineButton")
+    , m_xRightBtn(m_xBuilder->weld_button("right"))
+    , m_xDownBtn(m_xBuilder->weld_button("down"))
     , m_pEditWin(pEditWin)
     , m_pFrame(pFrame)
     , m_nDelayAppearing(0)
     , m_bDestroyed(false)
     , m_nOutlinePos(SwOutlineNodes::npos)
 {
-    SetSizePixel(Size(BUTTON_WIDTH, BUTTON_HEIGHT));
+    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+    SetPaintTransparent(false);
+    SetBackground(rStyleSettings.GetFaceColor());
+
+    Size aBtnsSize(m_xRightBtn->get_preferred_size());
+    auto nDim = std::max(aBtnsSize.Width(), aBtnsSize.Height());
+    m_xRightBtn->set_size_request(nDim, nDim);
+    m_xDownBtn->set_size_request(nDim, nDim);
+
+    SetSizePixel(get_preferred_size());
+    SetSymbol(SymbolType::DONTKNOW);
+
+    m_xRightBtn->connect_mouse_press(LINK(this, SwOutlineContentVisibilityWin, MousePressHdl));
+    m_xDownBtn->connect_mouse_press(LINK(this, SwOutlineContentVisibilityWin, MousePressHdl));
+
+    m_xRightBtn->connect_key_press(LINK(this, SwOutlineContentVisibilityWin, KeyInputHdl));
+    m_xDownBtn->connect_key_press(LINK(this, SwOutlineContentVisibilityWin, KeyInputHdl));
 
     m_aDelayTimer.SetTimeout(50);
-    m_aDelayTimer.SetInvokeHandler(LINK(this, SwOutlineContentVisibilityWin, DelayHandler));
+    m_aDelayTimer.SetInvokeHandler(LINK(this, SwOutlineContentVisibilityWin, DelayAppearHandler));
 }
 
 void SwOutlineContentVisibilityWin::dispose()
@@ -46,7 +62,51 @@ void SwOutlineContentVisibilityWin::dispose()
     m_pEditWin.clear();
     m_pFrame = nullptr;
 
-    PushButton::dispose();
+    m_xDownBtn.reset();
+    m_xRightBtn.reset();
+
+    InterimItemWindow::dispose();
+}
+
+SymbolType SwOutlineContentVisibilityWin::GetSymbol() const
+{
+    if (m_xRightBtn->get_visible())
+        return SymbolType::ARROW_RIGHT;
+    if (m_xDownBtn->get_visible())
+        return SymbolType::ARROW_DOWN;
+    return SymbolType::DONTKNOW;
+}
+
+void SwOutlineContentVisibilityWin::SetSymbol(SymbolType eStyle)
+{
+    if (GetSymbol() == eStyle)
+        return;
+
+    bool bRight = eStyle == SymbolType::ARROW_RIGHT;
+    bool bDown = eStyle == SymbolType::ARROW_DOWN;
+
+    bool bControlHasFocus = ControlHasFocus();
+
+    // disable mouse move for the hidden button so we don't get mouse
+    // leave events we don't care about when we swap buttons
+    m_xRightBtn->connect_mouse_move(Link<const MouseEvent&, bool>());
+    m_xDownBtn->connect_mouse_move(Link<const MouseEvent&, bool>());
+
+    m_xRightBtn->set_visible(bRight);
+    m_xDownBtn->set_visible(bDown);
+
+    weld::Button* pButton = nullptr;
+    if (bRight)
+        pButton = m_xRightBtn.get();
+    else if (bDown)
+        pButton = m_xDownBtn.get();
+    InitControlBase(pButton);
+    if (pButton)
+    {
+        pButton->connect_mouse_move(LINK(this, SwOutlineContentVisibilityWin, MouseMoveHdl));
+        if (bControlHasFocus)
+            pButton->grab_focus();
+    }
 }
 
 void SwOutlineContentVisibilityWin::Set()
@@ -176,27 +236,38 @@ void SwOutlineContentVisibilityWin::ToggleOutlineContentVisibility(const bool bS
     }
     else
         rSh.ToggleOutlineContentVisibility(m_nOutlinePos);
-    SetSymbol(rSh.IsOutlineContentFolded(m_nOutlinePos) ? SymbolType::ARROW_RIGHT
-                                                        : SymbolType::ARROW_DOWN);
+
+    if (!m_bDestroyed)
+    {
+        SetSymbol(rSh.IsOutlineContentFolded(m_nOutlinePos) ? SymbolType::ARROW_RIGHT
+                                                            : SymbolType::ARROW_DOWN);
+    }
+
     rSh.LockView(false);
 }
 
-void SwOutlineContentVisibilityWin::KeyInput(const KeyEvent& rKEvt)
+IMPL_LINK(SwOutlineContentVisibilityWin, KeyInputHdl, const KeyEvent&, rKEvt, bool)
 {
+    bool bConsumed = false;
+
     vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
     if (!aKeyCode.GetModifier()
         && (aKeyCode.GetCode() == KEY_RETURN || aKeyCode.GetCode() == KEY_SPACE))
     {
         ToggleOutlineContentVisibility(aKeyCode.GetCode() == KEY_RETURN);
+        bConsumed = true;
     }
     else if (aKeyCode.GetCode() == KEY_ESCAPE)
     {
         Hide();
         GrabFocusToDocument();
+        bConsumed = true;
     }
+
+    return bConsumed;
 }
 
-void SwOutlineContentVisibilityWin::MouseMove(const MouseEvent& rMEvt)
+IMPL_LINK(SwOutlineContentVisibilityWin, MouseMoveHdl, const MouseEvent&, rMEvt, bool)
 {
     if (rMEvt.IsLeaveWindow())
     {
@@ -212,17 +283,20 @@ void SwOutlineContentVisibilityWin::MouseMove(const MouseEvent& rMEvt)
             m_aDelayTimer.Stop();
         // bring button to top and grab focus
         SetZOrder(this, ZOrderFlags::First);
-        GrabFocus();
+        if (!ControlHasFocus())
+            GrabFocus();
     }
     GetEditWin()->SetSavedOutlineFrame(const_cast<SwFrame*>(GetFrame()));
+    return false;
 }
 
-void SwOutlineContentVisibilityWin::MouseButtonDown(const MouseEvent& rMEvt)
+IMPL_LINK(SwOutlineContentVisibilityWin, MousePressHdl, const MouseEvent&, rMEvt, bool)
 {
     ToggleOutlineContentVisibility(rMEvt.IsRight());
+    return false;
 }
 
-IMPL_LINK_NOARG(SwOutlineContentVisibilityWin, DelayHandler, Timer*, void)
+IMPL_LINK_NOARG(SwOutlineContentVisibilityWin, DelayAppearHandler, Timer*, void)
 {
     const int TICKS_BEFORE_WE_APPEAR = 5;
     if (m_nDelayAppearing < TICKS_BEFORE_WE_APPEAR)
diff --git a/sw/source/uibase/inc/FrameControl.hxx b/sw/source/uibase/inc/FrameControl.hxx
index bf2ff623920a..e3c98ca57e8a 100644
--- a/sw/source/uibase/inc/FrameControl.hxx
+++ b/sw/source/uibase/inc/FrameControl.hxx
@@ -29,6 +29,9 @@ public:
     /// Returns true if the point is inside the control.
     virtual bool Contains( const Point &rDocPt ) const = 0;
 
+    /// Returns true if the control has focus
+    virtual bool IsFocused() const = 0;
+
     virtual const SwFrame* GetFrame() = 0;
     virtual SwEditWin*   GetEditWin() = 0;
 };
@@ -46,6 +49,7 @@ public:
     void SetReadonly( bool bReadonly ) { mpIFace->SetReadonly( bReadonly ); }
     void ShowAll( bool bShow )         { mpIFace->ShowAll( bShow ); }
     bool Contains( const Point &rDocPt ) const { return mpIFace->Contains( rDocPt ); }
+    bool HasFocus() const { return mpIFace->IsFocused(); }
 };
 
 /** Class sharing some MenuButton code
@@ -64,6 +68,7 @@ public:
 
     virtual const SwFrame* GetFrame()   override { return m_pFrame; }
     virtual SwEditWin*   GetEditWin() override { return m_pEditWin; }
+    virtual bool IsFocused() const override { return HasFocus(); }
     const SwPageFrame*     GetPageFrame() const;
 };
 
diff --git a/sw/source/uibase/inc/OutlineContentVisibilityWin.hxx b/sw/source/uibase/inc/OutlineContentVisibilityWin.hxx
index 13f29fd0f2eb..3816484391a2 100644
--- a/sw/source/uibase/inc/OutlineContentVisibilityWin.hxx
+++ b/sw/source/uibase/inc/OutlineContentVisibilityWin.hxx
@@ -6,15 +6,18 @@
  * 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/.
  */
-#ifndef INCLUDED_SW_SOURCE_UIBASE_INC_OUTLINECONTENTVISIBILITYWIN_HXX
-#define INCLUDED_SW_SOURCE_UIBASE_INC_OUTLINECONTENTVISIBILITYWIN_HXX
+#pragma once
 
+#include <vcl/InterimItemWindow.hxx>
 #include "edtwin.hxx"
 #include "FrameControl.hxx"
 
-class SwOutlineContentVisibilityWin : public PushButton, public ISwFrameControl
+class SwOutlineContentVisibilityWin : public InterimItemWindow, public ISwFrameControl
 {
 private:
+    std::unique_ptr<weld::Button> m_xRightBtn;
+    std::unique_ptr<weld::Button> m_xDownBtn;
+
     VclPtr<SwEditWin> m_pEditWin;
     const SwFrame* m_pFrame;
     int m_nDelayAppearing; ///< Before we show the control, wait a few timer ticks to avoid appearing with every mouse over.
@@ -29,21 +32,24 @@ public:
     virtual ~SwOutlineContentVisibilityWin() override { disposeOnce(); }
     virtual void dispose() override;
 
-    virtual void KeyInput(const KeyEvent& rKEvt) override;
-    virtual void MouseButtonDown(const MouseEvent& rMEvt) override;
-    virtual void MouseMove(const MouseEvent& rMEvt) override;
     virtual void ShowAll(bool bShow) override;
     virtual bool Contains(const Point& rDocPt) const override;
     virtual void SetReadonly(bool /*bReadonly*/) override {}
+    virtual bool IsFocused() const override { return ControlHasFocus(); }
     virtual const SwFrame* GetFrame() override { return m_pFrame; }
     virtual SwEditWin* GetEditWin() override { return m_pEditWin; }
 
     void Set();
 
+    void SetSymbol(SymbolType eTyle);
+    SymbolType GetSymbol() const;
+
 private:
-    DECL_LINK(DelayHandler, Timer*, void);
+    DECL_LINK(DelayAppearHandler, Timer*, void);
+    DECL_LINK(IdleDisappearHandler, Timer*, void);
+    DECL_LINK(MousePressHdl, const MouseEvent&, bool);
+    DECL_LINK(MouseMoveHdl, const MouseEvent&, bool);
+    DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
 };
 
-#endif
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx
index 3fb11b740ca4..04d028f692d0 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -2064,7 +2064,7 @@ void SwWrtShell::ToggleOutlineContentVisibility(size_t nPos, bool bForceFold)
             if (pFrame && !pFrame->IsInDtor())
             {
                 SwFrameControlPtr pOutlineFrameControl = GetView().GetEditWin().GetFrameControlsManager().GetControl(FrameControlType::Outline, pFrame);
-                if (pOutlineFrameControl && pOutlineFrameControl->GetWindow() && !pOutlineFrameControl->GetWindow()->HasFocus())
+                if (pOutlineFrameControl && pOutlineFrameControl->GetWindow() && !pOutlineFrameControl->HasFocus())
                     GetView().GetEditWin().GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, pFrame);
             }
 
diff --git a/sw/uiconfig/swriter/ui/outlinebutton.ui b/sw/uiconfig/swriter/ui/outlinebutton.ui
new file mode 100644
index 000000000000..efd2f60fb4aa
--- /dev/null
+++ b/sw/uiconfig/swriter/ui/outlinebutton.ui
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.1 -->
+<interface domain="svt">
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkImage" id="image3">
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <property name="stock">gtk-go-forward</property>
+    <property name="icon_size">1</property>
+  </object>
+  <object class="GtkImage" id="image5">
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <property name="stock">gtk-go-down</property>
+    <property name="icon_size">1</property>
+  </object>
+  <object class="GtkBox" id="OutlineButton">
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <property name="hexpand">True</property>
+    <property name="vexpand">True</property>
+    <child>
+      <object class="GtkButton" id="right">
+        <property name="can-focus">True</property>
+        <property name="focus-on-click">False</property>
+        <property name="receives-default">True</property>
+        <property name="no-show-all">True</property>
+        <property name="image">image3</property>
+        <property name="always-show-image">True</property>
+        <style>
+          <class name="small-button"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkButton" id="down">
+        <property name="visible">True</property>
+        <property name="can-focus">True</property>
+        <property name="focus-on-click">False</property>
+        <property name="receives-default">True</property>
+        <property name="image">image5</property>
+        <property name="always-show-image">True</property>
+        <style>
+          <class name="small-button"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">3</property>
+      </packing>
+    </child>
+  </object>
+</interface>


More information about the Libreoffice-commits mailing list