LibreOffice Module sw (master) 1
OutlineContentVisibilityWin.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10#include <edtwin.hxx>
12#include <view.hxx>
13#include <wrtsh.hxx>
14
16#include <txtfrm.hxx>
17#include <ndtxt.hxx>
19#include <vcl/event.hxx>
20#include <vcl/svapp.hxx>
21#include <strings.hrc>
22
23#include <viewopt.hxx>
24
26
28 const SwFrame* pFrame)
29 : InterimItemWindow(pEditWin, "modules/swriter/ui/outlinebutton.ui", "OutlineButton")
30 , m_xShowBtn(m_xBuilder->weld_button("show"))
31 , m_xHideBtn(m_xBuilder->weld_button("hide"))
32 , m_pEditWin(pEditWin)
33 , m_pFrame(pFrame)
34 , m_nDelayAppearing(0)
35 , m_aDelayTimer("SwOutlineContentVisibilityWin m_aDelayTimer")
36 , m_bDestroyed(false)
37 , m_nOutlinePos(SwOutlineNodes::npos)
38{
41 SetBackground(rStyleSettings.GetFaceColor());
42
43 Size aBtnsSize(m_xShowBtn->get_preferred_size());
44 auto nDim = std::max(aBtnsSize.Width(), aBtnsSize.Height());
45 m_xShowBtn->set_size_request(nDim, nDim);
46 m_xHideBtn->set_size_request(nDim, nDim);
47
50
51 m_xShowBtn->connect_mouse_press(LINK(this, SwOutlineContentVisibilityWin, MousePressHdl));
52 m_xHideBtn->connect_mouse_press(LINK(this, SwOutlineContentVisibilityWin, MousePressHdl));
53
56}
57
59{
60 m_bDestroyed = true;
62
64 m_pFrame = nullptr;
65
66 m_xHideBtn.reset();
67 m_xShowBtn.reset();
68
70}
71
73{
74 if (m_xShowBtn->get_visible())
75 return ButtonSymbol::SHOW;
76 if (m_xHideBtn->get_visible())
77 return ButtonSymbol::HIDE;
78 return ButtonSymbol::NONE;
79}
80
82{
83 if (GetSymbol() == eStyle)
84 return;
85
86 bool bShow = eStyle == ButtonSymbol::SHOW;
87 bool bHide = eStyle == ButtonSymbol::HIDE;
88
89 // disable mouse move for the hidden button so we don't get mouse
90 // leave events we don't care about when we swap buttons
91 m_xShowBtn->connect_mouse_move(Link<const MouseEvent&, bool>());
92 m_xHideBtn->connect_mouse_move(Link<const MouseEvent&, bool>());
93
94 m_xShowBtn->set_visible(bShow);
95 m_xHideBtn->set_visible(bHide);
96
97 weld::Button* pButton = nullptr;
98 if (bShow)
99 pButton = m_xShowBtn.get();
100 else if (bHide)
101 pButton = m_xHideBtn.get();
102 InitControlBase(pButton);
103 if (pButton)
104 pButton->connect_mouse_move(LINK(this, SwOutlineContentVisibilityWin, MouseMoveHdl));
105}
106
108{
109 const SwTextFrame* pTextFrame = static_cast<const SwTextFrame*>(GetFrame());
110 const SwTextNode* pTextNode = pTextFrame->GetTextNodeFirst();
112 const SwOutlineNodes& rOutlineNodes = rSh.GetNodes().GetOutLineNds();
113
114 (void)rOutlineNodes.Seek_Entry(static_cast<SwNode*>(const_cast<SwTextNode*>(pTextNode)),
116
117 // set symbol displayed on button
118 bool bVisible = true;
119 const_cast<SwTextNode*>(pTextNode)->GetAttrOutlineContentVisible(bVisible);
121
122 // set quick help
123 SwOutlineNodes::size_type nOutlineNodesCount
126 OUString sQuickHelp(SwResId(STR_OUTLINE_CONTENT_TOGGLE_VISIBILITY));
128 && m_nOutlinePos + 1 < nOutlineNodesCount
130 sQuickHelp += " (" + SwResId(STR_OUTLINE_CONTENT_TOGGLE_VISIBILITY_EXT) + ")";
131 SetQuickHelpText(sQuickHelp);
132
133 // Set the position of the window
134 SwRect aFrameAreaRect = pTextFrame->getFrameArea();
135 aFrameAreaRect.AddTop(pTextFrame->GetTopMargin());
136 SwSpecialPos aSpecialPos;
139 SwCursorMoveState aMoveState;
140 aMoveState.m_pSpecialPos = &aSpecialPos;
141 SwRect aCharRect;
142 pTextFrame->GetCharRect(aCharRect, SwPosition(*(pTextFrame->GetTextNodeForParaProps())),
143 &aMoveState);
145 Point(aCharRect.Left(), aFrameAreaRect.Center().getY())));
146 if (pTextFrame->IsRightToLeft())
147 aPxPt.AdjustX(2);
148 else
149 aPxPt.AdjustX(-(GetSizePixel().getWidth() + 2));
150 aPxPt.AdjustY(-GetSizePixel().getHeight() / 2);
151 SetPosPixel(aPxPt);
152}
153
155{
156 if (bShow)
157 {
161 if (!m_bDestroyed)
163 }
164 else
165 Hide();
166}
167
169{
171 if (aRect.Contains(rDocPt))
172 return true;
173 return false;
174}
175
176IMPL_LINK(SwOutlineContentVisibilityWin, MouseMoveHdl, const MouseEvent&, rMEvt, bool)
177{
178 if (rMEvt.IsLeaveWindow())
179 {
180 if (GetSymbol() == ButtonSymbol::HIDE)
181 {
182 // MouseMove event may not be seen by the edit window for example when move is to
183 // a show button or when move is outside of the edit window.
184 // Only hide when mouse leave results in leaving the frame.
185 tools::Rectangle aFrameAreaPxRect
186 = GetEditWin()->LogicToPixel(GetFrame()->getFrameArea().SVRect());
187 auto nY = GetPosPixel().getY() + rMEvt.GetPosPixel().getY();
188 if (nY <= 0 || nY <= aFrameAreaPxRect.Top() || nY >= aFrameAreaPxRect.Bottom()
189 || nY >= GetEditWin()->GetSizePixel().Height())
190 {
191 GetEditWin()->SetSavedOutlineFrame(nullptr);
192 GetEditWin()->GetFrameControlsManager().RemoveControlsByType(
193 FrameControlType::Outline, GetFrame());
194 // warning: "this" is disposed now
195 }
196 }
197 }
198 else if (rMEvt.IsEnterWindow())
199 {
200 // Leave window event might not have resulted in removing hide button from saved frame
201 // and the edit win might not receive mouse event between leaving saved frame button and
202 // entering this button.
203 if (GetFrame() != GetEditWin()->GetSavedOutlineFrame())
204 {
205 SwFrameControlPtr pFrameControl = GetEditWin()->GetFrameControlsManager().GetControl(
206 FrameControlType::Outline, GetEditWin()->GetSavedOutlineFrame());
207 if (pFrameControl)
208 {
210 = dynamic_cast<SwOutlineContentVisibilityWin*>(pFrameControl->GetIFacePtr());
211 if (pControl && pControl->GetSymbol() == ButtonSymbol::HIDE)
212 {
213 GetEditWin()->GetFrameControlsManager().RemoveControlsByType(
214 FrameControlType::Outline, GetEditWin()->GetSavedOutlineFrame());
215 // The outline content visibility window frame control (hide button)
216 // for saved outline frame is now disposed.
217 }
218 }
219 GetEditWin()->SetSavedOutlineFrame(
220 static_cast<SwTextFrame*>(const_cast<SwFrame*>(GetFrame())));
221 }
222 if (!m_bDestroyed && m_aDelayTimer.IsActive())
223 m_aDelayTimer.Stop();
224 // bring button to top
225 SetZOrder(this, ZOrderFlags::First);
226 }
227 return false;
228}
229
230// Toggle the outline content visibility on mouse press
231IMPL_LINK(SwOutlineContentVisibilityWin, MousePressHdl, const MouseEvent&, rMEvt, bool)
232{
233 Hide();
234 GetEditWin()->ToggleOutlineContentVisibility(m_nOutlinePos, rMEvt.IsRight());
235 return false;
236}
237
239{
240 const int TICKS_BEFORE_WE_APPEAR = 3;
241 if (m_nDelayAppearing < TICKS_BEFORE_WE_APPEAR)
242 {
243 ++m_nDelayAppearing;
244 m_aDelayTimer.Start();
245 return;
246 }
247 if (GetEditWin()->GetSavedOutlineFrame() == GetFrame())
248 Show();
249 m_aDelayTimer.Stop();
250}
251
252/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::shared_ptr< SwFrameControl > SwFrameControlPtr
IMPL_LINK_NOARG(SwOutlineContentVisibilityWin, DelayAppearHandler, Timer *, void)
IMPL_LINK(SwOutlineContentVisibilityWin, MouseMoveHdl, const MouseEvent &, rMEvt, bool)
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
virtual tSortedOutlineNodeList::size_type getOutlineNodesCount() const =0
virtual int getOutlineLevel(const tSortedOutlineNodeList::size_type nIdx) const =0
virtual void dispose() override
void InitControlBase(weld::Widget *pWidget)
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long getY() const
constexpr tools::Long Height() const
constexpr tools::Long Width() const
const Color & GetFaceColor() const
Window class for the Writer edit area, this is the one handling mouse and keyboard events and doing t...
Definition: edtwin.hxx:61
const SwView & GetView() const
Definition: edtwin.hxx:246
const SwRect & getFrameArea() const
Definition: frame.hxx:179
Base class of the Writer layout elements.
Definition: frame.hxx:315
bool IsRightToLeft() const
Definition: frame.hxx:993
tools::Long GetTopMargin() const
Definition: ssfrm.cxx:44
Base class of the Writer document model elements.
Definition: node.hxx:98
const SwOutlineNodes & GetOutLineNds() const
Array of all OutlineNodes.
Definition: ndarr.hxx:236
virtual bool Contains(const Point &rDocPt) const override
virtual SwEditWin * GetEditWin() override
std::unique_ptr< weld::Button > m_xHideBtn
SwOutlineContentVisibilityWin(SwEditWin *pEditWin, const SwFrame *pFrame)
virtual void ShowAll(bool bShow) override
virtual const SwFrame * GetFrame() override
std::unique_ptr< weld::Button > m_xShowBtn
int m_nDelayAppearing
Before we show the control, wait a few timer ticks to avoid appearing with every mouse over.
bool Seek_Entry(SwNode *rP, size_type *pnPos) const
Definition: ndnum.cxx:32
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
Point Center() const
Definition: swrect.hxx:338
void AddTop(const tools::Long nAdd)
Definition: swrect.cxx:128
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:168
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:472
virtual bool GetCharRect(SwRect &rRect, const SwPosition &rPos, SwCursorMoveState *pCMS=nullptr, bool bAllowFarAway=true) const override
Returns the view rectangle for the rPos model position.
Definition: frmcrsr.cxx:178
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1390
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:112
bool HasVisibleNumberingOrBullet() const
Returns if the paragraph has a visible numbering or bullet.
Definition: ndtxt.cxx:4284
bool IsTreatSubOutlineLevelsAsContent() const
Definition: viewopt.cxx:182
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:452
const SwNodes & GetNodes() const
Definition: viewsh.cxx:2181
const IDocumentOutlineNodes * getIDocumentOutlineNodesAccess() const
Definition: viewsh.cxx:2844
SwWrtShell & GetWrtShell() const
Definition: view.hxx:423
Used by the UI to modify the document model.
Definition: wrtsh.hxx:97
bool IsActive() const
void Stop()
void SetTimeout(sal_uInt64 nTimeoutMs)
void SetInvokeHandler(const Link< Timer *, void > &rLink)
virtual void Start(bool bStartTimer=true) override
void clear()
bool Contains(const Point &rPOINT) const
tools::Long getY() const
constexpr tools::Long Top() const
constexpr tools::Long Bottom() const
Point LogicToPixel(const Point &rLogicPt) const
virtual void SetSizePixel(const Size &rNewSize)
Size get_preferred_size() const
virtual Point GetPosPixel() const
::OutputDevice const * GetOutDev() const
virtual Size GetSizePixel() const
void SetPaintTransparent(bool bTransparent)
virtual void SetPosPixel(const Point &rNewPos)
void SetQuickHelpText(const OUString &rHelpText)
void SetBackground()
virtual void connect_mouse_move(const Link< const MouseEvent &, bool > &rLink)
SwSpecialPos * m_pSpecialPos
for positions inside fields
Definition: crstate.hxx:136
Marks a position in the document model.
Definition: pam.hxx:38
SwSPExtendRange nExtendRange
Definition: crstate.hxx:112
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:168
bool bVisible