Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / uibase / docvw / OutlineContentVisibilityWin.cxx
blob9985485502746f290e2db18d8348a39329f6f3d1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include <edtwin.hxx>
11 #include <OutlineContentVisibilityWin.hxx>
12 #include <view.hxx>
13 #include <wrtsh.hxx>
15 #include <IDocumentOutlineNodes.hxx>
16 #include <txtfrm.hxx>
17 #include <ndtxt.hxx>
18 #include <vcl/InterimItemWindow.hxx>
19 #include <vcl/event.hxx>
20 #include <vcl/svapp.hxx>
21 #include <strings.hrc>
23 #include <viewopt.hxx>
25 #include <FrameControlsManager.hxx>
27 SwOutlineContentVisibilityWin::SwOutlineContentVisibilityWin(SwEditWin* pEditWin,
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)
39 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
40 SetPaintTransparent(false);
41 SetBackground(rStyleSettings.GetFaceColor());
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);
48 SetSizePixel(get_preferred_size());
49 SetSymbol(ButtonSymbol::NONE);
51 m_xShowBtn->connect_mouse_press(LINK(this, SwOutlineContentVisibilityWin, MousePressHdl));
52 m_xHideBtn->connect_mouse_press(LINK(this, SwOutlineContentVisibilityWin, MousePressHdl));
54 m_aDelayTimer.SetTimeout(25);
55 m_aDelayTimer.SetInvokeHandler(LINK(this, SwOutlineContentVisibilityWin, DelayAppearHandler));
58 void SwOutlineContentVisibilityWin::dispose()
60 m_bDestroyed = true;
61 m_aDelayTimer.Stop();
63 m_pEditWin.clear();
64 m_pFrame = nullptr;
66 m_xHideBtn.reset();
67 m_xShowBtn.reset();
69 InterimItemWindow::dispose();
72 ButtonSymbol SwOutlineContentVisibilityWin::GetSymbol() const
74 if (m_xShowBtn->get_visible())
75 return ButtonSymbol::SHOW;
76 if (m_xHideBtn->get_visible())
77 return ButtonSymbol::HIDE;
78 return ButtonSymbol::NONE;
81 void SwOutlineContentVisibilityWin::SetSymbol(ButtonSymbol eStyle)
83 if (GetSymbol() == eStyle)
84 return;
86 bool bShow = eStyle == ButtonSymbol::SHOW;
87 bool bHide = eStyle == ButtonSymbol::HIDE;
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>());
94 m_xShowBtn->set_visible(bShow);
95 m_xHideBtn->set_visible(bHide);
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));
107 void SwOutlineContentVisibilityWin::Set()
109 const SwTextFrame* pTextFrame = static_cast<const SwTextFrame*>(GetFrame());
110 const SwTextNode* pTextNode = pTextFrame->GetTextNodeFirst();
111 SwWrtShell& rSh = GetEditWin()->GetView().GetWrtShell();
112 const SwOutlineNodes& rOutlineNodes = rSh.GetNodes().GetOutLineNds();
114 (void)rOutlineNodes.Seek_Entry(static_cast<SwNode*>(const_cast<SwTextNode*>(pTextNode)),
115 &m_nOutlinePos);
117 // set symbol displayed on button
118 bool bVisible = true;
119 const_cast<SwTextNode*>(pTextNode)->GetAttrOutlineContentVisible(bVisible);
120 SetSymbol(bVisible ? ButtonSymbol::HIDE : ButtonSymbol::SHOW);
122 // set quick help
123 SwOutlineNodes::size_type nOutlineNodesCount
124 = rSh.getIDocumentOutlineNodesAccess()->getOutlineNodesCount();
125 int nLevel = rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(m_nOutlinePos);
126 OUString sQuickHelp(SwResId(STR_OUTLINE_CONTENT_TOGGLE_VISIBILITY));
127 if (!rSh.GetViewOptions()->IsTreatSubOutlineLevelsAsContent()
128 && m_nOutlinePos + 1 < nOutlineNodesCount
129 && rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(m_nOutlinePos + 1) > nLevel)
130 sQuickHelp += " (" + SwResId(STR_OUTLINE_CONTENT_TOGGLE_VISIBILITY_EXT) + ")";
131 SetQuickHelpText(sQuickHelp);
133 // Set the position of the window
134 SwRect aFrameAreaRect = pTextFrame->getFrameArea();
135 aFrameAreaRect.AddTop(pTextFrame->GetTopMargin());
136 SwSpecialPos aSpecialPos;
137 aSpecialPos.nExtendRange = pTextNode->HasVisibleNumberingOrBullet() ? SwSPExtendRange::BEFORE
138 : SwSPExtendRange::NONE;
139 SwCursorMoveState aMoveState;
140 aMoveState.m_pSpecialPos = &aSpecialPos;
141 SwRect aCharRect;
142 pTextFrame->GetCharRect(aCharRect, SwPosition(*(pTextFrame->GetTextNodeForParaProps())),
143 &aMoveState);
144 Point aPxPt(GetEditWin()->GetOutDev()->LogicToPixel(
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);
154 void SwOutlineContentVisibilityWin::ShowAll(bool bShow)
156 if (bShow)
158 m_nDelayAppearing = 0;
159 if (!m_bDestroyed && m_aDelayTimer.IsActive())
160 m_aDelayTimer.Stop();
161 if (!m_bDestroyed)
162 m_aDelayTimer.Start();
164 else
165 Hide();
168 bool SwOutlineContentVisibilityWin::Contains(const Point& rDocPt) const
170 ::tools::Rectangle aRect(GetPosPixel(), GetSizePixel());
171 if (aRect.Contains(rDocPt))
172 return true;
173 return false;
176 IMPL_LINK(SwOutlineContentVisibilityWin, MouseMoveHdl, const MouseEvent&, rMEvt, bool)
178 if (rMEvt.IsLeaveWindow())
180 if (GetSymbol() == ButtonSymbol::HIDE)
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())
191 GetEditWin()->SetSavedOutlineFrame(nullptr);
192 GetEditWin()->GetFrameControlsManager().RemoveControlsByType(
193 FrameControlType::Outline, GetFrame());
194 // warning: "this" is disposed now
198 else if (rMEvt.IsEnterWindow())
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())
205 SwFrameControlPtr pFrameControl = GetEditWin()->GetFrameControlsManager().GetControl(
206 FrameControlType::Outline, GetEditWin()->GetSavedOutlineFrame());
207 if (pFrameControl)
209 SwOutlineContentVisibilityWin* pControl
210 = dynamic_cast<SwOutlineContentVisibilityWin*>(pFrameControl->GetIFacePtr());
211 if (pControl && pControl->GetSymbol() == ButtonSymbol::HIDE)
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.
219 GetEditWin()->SetSavedOutlineFrame(
220 static_cast<SwTextFrame*>(const_cast<SwFrame*>(GetFrame())));
222 if (!m_bDestroyed && m_aDelayTimer.IsActive())
223 m_aDelayTimer.Stop();
224 // bring button to top
225 SetZOrder(this, ZOrderFlags::First);
227 return false;
230 // Toggle the outline content visibility on mouse press
231 IMPL_LINK(SwOutlineContentVisibilityWin, MousePressHdl, const MouseEvent&, rMEvt, bool)
233 Hide();
234 GetEditWin()->ToggleOutlineContentVisibility(m_nOutlinePos, rMEvt.IsRight());
235 return false;
238 IMPL_LINK_NOARG(SwOutlineContentVisibilityWin, DelayAppearHandler, Timer*, void)
240 const int TICKS_BEFORE_WE_APPEAR = 3;
241 if (m_nDelayAppearing < TICKS_BEFORE_WE_APPEAR)
243 ++m_nDelayAppearing;
244 m_aDelayTimer.Start();
245 return;
247 if (GetEditWin()->GetSavedOutlineFrame() == GetFrame())
248 Show();
249 m_aDelayTimer.Stop();
252 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */