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>
11 #include <cntfrm.hxx>
12 #include <FrameControlsManager.hxx>
13 #include <HeaderFooterWin.hxx>
14 #include <PageBreakWin.hxx>
15 #include <UnfloatTableButton.hxx>
16 #include <pagefrm.hxx>
17 #include <flyfrm.hxx>
18 #include <viewopt.hxx>
19 #include <view.hxx>
20 #include <wrtsh.hxx>
21 #include <OutlineContentVisibilityWin.hxx>
22 #include <ndtxt.hxx>
23 #include <IDocumentOutlineNodes.hxx>
24 #include <vcl/settings.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/weldutils.hxx>
27 
28 using namespace std;
29 
SwFrameControlsManager(SwEditWin * pEditWin)30 SwFrameControlsManager::SwFrameControlsManager( SwEditWin* pEditWin ) :
31     m_pEditWin( pEditWin ),
32     m_aControls( )
33 {
34 }
35 
~SwFrameControlsManager()36 SwFrameControlsManager::~SwFrameControlsManager()
37 {
38 }
39 
dispose()40 void SwFrameControlsManager::dispose()
41 {
42     m_aControls.clear();
43 }
44 
GetControl(FrameControlType eType,const SwFrame * pFrame)45 SwFrameControlPtr SwFrameControlsManager::GetControl( FrameControlType eType, const SwFrame* pFrame )
46 {
47     SwFrameControlPtrMap& rControls = m_aControls[eType];
48 
49     SwFrameControlPtrMap::iterator aIt = rControls.find(pFrame);
50 
51     if (aIt != rControls.end())
52         return aIt->second;
53 
54     return SwFrameControlPtr();
55 }
56 
RemoveControls(const SwFrame * pFrame)57 void SwFrameControlsManager::RemoveControls( const SwFrame* pFrame )
58 {
59     for ( auto& rEntry : m_aControls )
60     {
61         SwFrameControlPtrMap& rMap = rEntry.second;
62         rMap.erase(pFrame);
63     }
64 }
65 
RemoveControlsByType(FrameControlType eType,const SwFrame * pFrame)66 void SwFrameControlsManager::RemoveControlsByType( FrameControlType eType, const SwFrame* pFrame )
67 {
68     SwFrameControlPtrMap& rMap = m_aControls[eType];
69     rMap.erase(pFrame);
70 }
71 
HideControls(FrameControlType eType)72 void SwFrameControlsManager::HideControls( FrameControlType eType )
73 {
74     for ( const auto& rCtrl : m_aControls[eType] )
75         rCtrl.second->ShowAll( false );
76 }
77 
SetReadonlyControls(bool bReadonly)78 void SwFrameControlsManager::SetReadonlyControls( bool bReadonly )
79 {
80     for ( auto& rEntry : m_aControls )
81         for ( auto& rCtrl : rEntry.second )
82             rCtrl.second->SetReadonly( bReadonly );
83 }
84 
SetHeaderFooterControl(const SwPageFrame * pPageFrame,FrameControlType eType,Point aOffset)85 void SwFrameControlsManager::SetHeaderFooterControl( const SwPageFrame* pPageFrame, FrameControlType eType, Point aOffset )
86 {
87     assert( eType == FrameControlType::Header || eType == FrameControlType::Footer );
88 
89     // Check if we already have the control
90     SwFrameControlPtr pControl;
91     const bool bHeader = ( eType == FrameControlType::Header );
92 
93     SwFrameControlPtrMap& rControls = m_aControls[eType];
94 
95     SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pPageFrame);
96     if (lb != rControls.end() && !(rControls.key_comp()(pPageFrame, lb->first)))
97         pControl = lb->second;
98     else
99     {
100         SwFrameControlPtr pNewControl =
101                 std::make_shared<SwFrameControl>( VclPtr<SwHeaderFooterWin>::Create(
102                                         m_pEditWin, pPageFrame, bHeader ).get() );
103         const SwViewOption* pViewOpt = m_pEditWin->GetView().GetWrtShell().GetViewOptions();
104         pNewControl->SetReadonly( pViewOpt->IsReadonly() );
105         rControls.insert(lb, make_pair(pPageFrame, pNewControl));
106         pControl.swap( pNewControl );
107     }
108 
109     tools::Rectangle aPageRect = m_pEditWin->LogicToPixel( pPageFrame->getFrameArea().SVRect() );
110 
111     SwHeaderFooterWin* pWin = dynamic_cast<SwHeaderFooterWin *>(pControl->GetWindow());
112     assert( pWin != nullptr) ;
113     assert( pWin->IsHeader() == bHeader );
114     pWin->SetOffset( aOffset, aPageRect.Left(), aPageRect.Right() );
115 
116     if (!pWin->IsVisible())
117         pControl->ShowAll( true );
118 }
119 
SetPageBreakControl(const SwPageFrame * pPageFrame)120 void SwFrameControlsManager::SetPageBreakControl( const SwPageFrame* pPageFrame )
121 {
122     // Check if we already have the control
123     SwFrameControlPtr pControl;
124 
125     SwFrameControlPtrMap& rControls = m_aControls[FrameControlType::PageBreak];
126 
127     SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pPageFrame);
128     if (lb != rControls.end() && !(rControls.key_comp()(pPageFrame, lb->first)))
129         pControl = lb->second;
130     else
131     {
132         SwFrameControlPtr pNewControl = std::make_shared<SwFrameControl>(
133                 VclPtr<SwPageBreakWin>::Create( m_pEditWin, pPageFrame ).get() );
134         const SwViewOption* pViewOpt = m_pEditWin->GetView().GetWrtShell().GetViewOptions();
135         pNewControl->SetReadonly( pViewOpt->IsReadonly() );
136 
137         rControls.insert(lb, make_pair(pPageFrame, pNewControl));
138 
139         pControl.swap( pNewControl );
140     }
141 
142     SwPageBreakWin* pWin = dynamic_cast<SwPageBreakWin *>(pControl->GetWindow());
143     assert (pWin != nullptr);
144     pWin->UpdatePosition();
145     if (!pWin->IsVisible())
146         pControl->ShowAll( true );
147 }
148 
SetUnfloatTableButton(const SwFlyFrame * pFlyFrame,bool bShow,Point aTopRightPixel)149 void SwFrameControlsManager::SetUnfloatTableButton( const SwFlyFrame* pFlyFrame, bool bShow, Point aTopRightPixel )
150 {
151     if(pFlyFrame == nullptr)
152         return;
153 
154     // Check if we already have the control
155     SwFrameControlPtr pControl;
156 
157     SwFrameControlPtrMap& rControls = m_aControls[FrameControlType::FloatingTable];
158 
159     SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pFlyFrame);
160     if (lb != rControls.end() && !(rControls.key_comp()(pFlyFrame, lb->first)))
161         pControl = lb->second;
162     else if (!bShow) // Do not create the control when it's not shown
163         return;
164     else
165     {
166         SwFrameControlPtr pNewControl = std::make_shared<SwFrameControl>(
167                 VclPtr<UnfloatTableButton>::Create( m_pEditWin, pFlyFrame ).get() );
168         const SwViewOption* pViewOpt = m_pEditWin->GetView().GetWrtShell().GetViewOptions();
169         pNewControl->SetReadonly( pViewOpt->IsReadonly() );
170 
171         rControls.insert(lb, make_pair(pFlyFrame, pNewControl));
172 
173         pControl.swap( pNewControl );
174     }
175 
176     UnfloatTableButton* pButton = dynamic_cast<UnfloatTableButton*>(pControl->GetWindow());
177     assert(pButton != nullptr);
178     pButton->SetOffset(aTopRightPixel);
179     pControl->ShowAll( bShow );
180 }
181 
SwFrameMenuButtonBase(SwEditWin * pEditWin,const SwFrame * pFrame,const OUString & rUIXMLDescription,const OString & rID)182 SwFrameMenuButtonBase::SwFrameMenuButtonBase(SwEditWin* pEditWin, const SwFrame* pFrame,
183                                              const OUString& rUIXMLDescription, const OString& rID)
184     : InterimItemWindow(pEditWin, rUIXMLDescription, rID)
185     , m_pEditWin(pEditWin)
186     , m_pFrame(pFrame)
187 {
188 }
189 
SetOutlineContentVisibilityButton(const SwContentFrame * pContentFrame)190 void SwFrameControlsManager::SetOutlineContentVisibilityButton(const SwContentFrame* pContentFrame)
191 {
192     // Check if we already have the control
193     SwFrameControlPtr pControl;
194 
195     SwFrameControlPtrMap& rControls = m_aControls[FrameControlType::Outline];
196 
197     SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pContentFrame);
198     if (lb != rControls.end() && !(rControls.key_comp()(pContentFrame, lb->first)))
199     {
200         pControl = lb->second;
201     }
202     else
203     {
204         SwFrameControlPtr pNewControl =
205                 std::make_shared<SwFrameControl>(VclPtr<SwOutlineContentVisibilityWin>::Create(
206                                         m_pEditWin, pContentFrame).get());
207         rControls.insert(lb, make_pair(pContentFrame, pNewControl));
208         pControl.swap(pNewControl);
209     }
210 
211     SwOutlineContentVisibilityWin* pWin = dynamic_cast<SwOutlineContentVisibilityWin *>(pControl->GetWindow());
212     assert(pWin != nullptr);
213     pWin->Set();
214 
215     if (pWin->GetSymbol() == ButtonSymbol::SHOW)
216         pWin->Show(); // show the SHOW button immediately
217     else if (!pWin->IsVisible() && pWin->GetSymbol() == ButtonSymbol::HIDE)
218         pWin->ShowAll(true);
219 }
220 
GetPageFrame() const221 const SwPageFrame* SwFrameMenuButtonBase::GetPageFrame() const
222 {
223     if (m_pFrame->IsPageFrame())
224         return static_cast<const SwPageFrame*>( m_pFrame );
225 
226     if (m_pFrame->IsFlyFrame())
227         return static_cast<const SwFlyFrame*>(m_pFrame)->GetAnchorFrame()->FindPageFrame();
228 
229     return m_pFrame->FindPageFrame();
230 }
231 
dispose()232 void SwFrameMenuButtonBase::dispose()
233 {
234     m_pEditWin.clear();
235     m_pFrame = nullptr;
236     m_xVirDev.disposeAndClear();
237     InterimItemWindow::dispose();
238 }
239 
SetVirDevFont()240 void SwFrameMenuButtonBase::SetVirDevFont()
241 {
242     // Get the font and configure it
243     vcl::Font aFont = Application::GetSettings().GetStyleSettings().GetToolFont();
244     weld::SetPointFont(*m_xVirDev, aFont);
245 }
246 
SwFrameControl(const VclPtr<vcl::Window> & pWindow)247 SwFrameControl::SwFrameControl( const VclPtr<vcl::Window> &pWindow )
248 {
249     assert(static_cast<bool>(pWindow));
250     mxWindow.reset( pWindow );
251     mpIFace = dynamic_cast<ISwFrameControl *>( pWindow.get() );
252 }
253 
~SwFrameControl()254 SwFrameControl::~SwFrameControl()
255 {
256     mpIFace = nullptr;
257     mxWindow.disposeAndClear();
258 }
259 
~ISwFrameControl()260 ISwFrameControl::~ISwFrameControl()
261 {
262 }
263 
264 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
265