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 #include <svx/svdview.hxx>
23 
24 #include <viewopt.hxx>
25 
26 #include <FrameControlsManager.hxx>
27 
29  const SwFrame* pFrame)
30  : InterimItemWindow(pEditWin, "modules/swriter/ui/outlinebutton.ui", "OutlineButton")
31  , m_xShowBtn(m_xBuilder->weld_button("show"))
32  , m_xHideBtn(m_xBuilder->weld_button("hide"))
33  , m_pEditWin(pEditWin)
34  , m_pFrame(pFrame)
35  , m_nDelayAppearing(0)
36  , m_bDestroyed(false)
37  , m_nOutlinePos(SwOutlineNodes::npos)
38 {
39  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
40  SetPaintTransparent(false);
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 
63  m_pEditWin.clear();
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)),
115  &m_nOutlinePos);
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 = GetFrame()->getFrameArea();
135  aFrameAreaRect.AddTop(GetFrame()->GetTopMargin());
136  SwRect aCharRect;
137  GetFrame()->GetCharRect(aCharRect, SwPosition(*pTextNode));
139  Point(aCharRect.Left(), aFrameAreaRect.Center().getY())));
140  if (GetFrame()->IsRightToLeft())
141  aPxPt.AdjustX(2);
142  else
143  aPxPt.AdjustX(-(GetSizePixel().getWidth() + 2));
144  aPxPt.AdjustY(-GetSizePixel().getHeight() / 2);
145  SetPosPixel(aPxPt);
146 }
147 
149 {
150  if (bShow)
151  {
152  m_nDelayAppearing = 0;
155  if (!m_bDestroyed)
157  }
158  else
159  Hide();
160 }
161 
162 bool SwOutlineContentVisibilityWin::Contains(const Point& rDocPt) const
163 {
165  if (aRect.IsInside(rDocPt))
166  return true;
167  return false;
168 }
169 
170 IMPL_LINK(SwOutlineContentVisibilityWin, MouseMoveHdl, const MouseEvent&, rMEvt, bool)
171 {
172  if (rMEvt.IsLeaveWindow())
173  {
174  if (GetSymbol() == ButtonSymbol::HIDE)
175  {
176  // MouseMove event may not be seen by the edit window for example when move is to
177  // a show button or when move is outside of the edit window.
178  // Only hide when mouse leave results in leaving the frame.
179  tools::Rectangle aFrameAreaPxRect
180  = GetEditWin()->LogicToPixel(GetFrame()->getFrameArea().SVRect());
181  auto nY = GetPosPixel().getY() + rMEvt.GetPosPixel().getY();
182  if (nY <= 0 || nY <= aFrameAreaPxRect.Top() || nY >= aFrameAreaPxRect.Bottom()
183  || nY >= GetEditWin()->GetSizePixel().Height())
184  {
185  GetEditWin()->SetSavedOutlineFrame(nullptr);
186  GetEditWin()->GetFrameControlsManager().RemoveControlsByType(
187  FrameControlType::Outline, GetFrame());
188  // warning: "this" is disposed now
189  }
190  }
191  }
192  else if (rMEvt.IsEnterWindow())
193  {
194  // Leave window event might not have resulted in removing hide button from saved frame
195  // and the edit win might not receive mouse event between leaving saved frame button and
196  // entering this button.
197  if (GetFrame() != GetEditWin()->GetSavedOutlineFrame())
198  {
199  SwFrameControlPtr pFrameControl = GetEditWin()->GetFrameControlsManager().GetControl(
200  FrameControlType::Outline, GetEditWin()->GetSavedOutlineFrame());
201  if (pFrameControl)
202  {
204  = dynamic_cast<SwOutlineContentVisibilityWin*>(pFrameControl->GetIFacePtr());
205  if (pControl && pControl->GetSymbol() == ButtonSymbol::HIDE)
206  {
207  GetEditWin()->GetFrameControlsManager().RemoveControlsByType(
208  FrameControlType::Outline, GetEditWin()->GetSavedOutlineFrame());
209  // The outline content visibility window frame control (hide button)
210  // for saved outline frame is now disposed.
211  }
212  }
213  GetEditWin()->SetSavedOutlineFrame(const_cast<SwFrame*>(GetFrame()));
214  }
215  if (!m_bDestroyed && m_aDelayTimer.IsActive())
216  m_aDelayTimer.Stop();
217  // bring button to top
218  SetZOrder(this, ZOrderFlags::First);
219  }
220  return false;
221 }
222 
223 // Toggle the outline content visibility on mouse press
224 IMPL_LINK(SwOutlineContentVisibilityWin, MousePressHdl, const MouseEvent&, rMEvt, bool)
225 {
226  Hide();
227  GetEditWin()->ToggleOutlineContentVisibility(m_nOutlinePos, rMEvt.IsRight());
228  return false;
229 }
230 
232 {
233  const int TICKS_BEFORE_WE_APPEAR = 3;
234  if (m_nDelayAppearing < TICKS_BEFORE_WE_APPEAR)
235  {
236  ++m_nDelayAppearing;
237  m_aDelayTimer.Start();
238  return;
239  }
240  if (GetEditWin()->GetSavedOutlineFrame() == GetFrame())
241  Show();
242  m_aDelayTimer.Stop();
243 }
244 
245 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual Point GetPosPixel() const
Base class of the Writer layout elements.
Definition: frame.hxx:315
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:158
void SetBackground()
bool bVisible
Marks a position in the document model.
Definition: pam.hxx:35
const SwNodes & GetNodes() const
Definition: viewsh.cxx:2092
std::unique_ptr< weld::Button > m_xHideBtn
virtual bool Contains(const Point &rDocPt) const override
Returns true if the point is inside the control.
void Left(const tools::Long nLeft)
Definition: swrect.hxx:194
const SwView & GetView() const
Definition: edtwin.hxx:244
const IDocumentOutlineNodes * getIDocumentOutlineNodesAccess() const
Definition: viewsh.cxx:2695
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
const Color & GetFaceColor() const
virtual SwEditWin * GetEditWin() override
virtual Size GetSizePixel() const
virtual void SetSizePixel(const Size &rNewSize)
tools::Long getY() const
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
void SetQuickHelpText(const OUString &rHelpText)
SwWrtShell & GetWrtShell() const
Definition: view.hxx:413
void AddTop(const tools::Long nAdd)
Definition: swrect.cxx:165
bool IsActive() const
Used by the UI to modify the document model.
Definition: wrtsh.hxx:93
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:165
virtual const SwFrame * GetFrame() override
int m_nDelayAppearing
Before we show the control, wait a few timer ticks to avoid appearing with every mouse over...
const SwRect & getFrameArea() const
Definition: frame.hxx:180
std::unique_ptr< weld::Button > m_xShowBtn
virtual void connect_mouse_move(const Link< const MouseEvent &, bool > &rLink)
virtual bool GetCharRect(SwRect &, const SwPosition &, SwCursorMoveState *=nullptr, bool bAllowFarAway=true) const
Definition: unusedf.cxx:72
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:457
void clear()
Point LogicToPixel(const Point &rLogicPt) const
Window class for the Writer edit area, this is the one handling mouse and keyboard events and doing t...
Definition: edtwin.hxx:58
virtual int getOutlineLevel(const tSortedOutlineNodeList::size_type nIdx) const =0
IMPL_LINK_NOARG(SwOutlineContentVisibilityWin, DelayAppearHandler, Timer *, void)
virtual void Start(bool bStartTimer=true) override
virtual tSortedOutlineNodeList::size_type getOutlineNodesCount() const =0
Size get_preferred_size() const
constexpr tools::Long Top() const
bool IsInside(const Point &rPOINT) const
const SwOutlineNodes & GetOutLineNds() const
Array of all OutlineNodes.
Definition: ndarr.hxx:231
void SetPaintTransparent(bool bTransparent)
virtual void ShowAll(bool bShow) override
void SetTimeout(sal_uInt64 nTimeoutMs)
Point Center() const
Definition: swrect.cxx:35
constexpr tools::Long Bottom() const
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
void Stop()
SwOutlineContentVisibilityWin(SwEditWin *pEditWin, const SwFrame *pFrame)
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:423
virtual void dispose() override
::OutputDevice const * GetOutDev() const
bool IsRightToLeft() const
Definition: frame.hxx:988
void SetInvokeHandler(const Link< Timer *, void > &rLink)
bool IsTreatSubOutlineLevelsAsContent() const
Definition: viewopt.cxx:105
bool Seek_Entry(SwNode *rP, size_type *pnPos) const
Definition: ndnum.cxx:32
std::shared_ptr< SwFrameControl > SwFrameControlPtr
std::vector< SwNode * >::size_type size_type
virtual void SetPosPixel(const Point &rNewPos)
void InitControlBase(weld::Widget *pWidget)
IMPL_LINK(SwOutlineContentVisibilityWin, MouseMoveHdl, const MouseEvent &, rMEvt, bool)
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo