LibreOffice Module sw (master)  1
FrameControlsManager.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>
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>
22 #include <ndtxt.hxx>
24 #include <vcl/settings.hxx>
25 #include <vcl/svapp.hxx>
26 
27 using namespace std;
28 
30  m_pEditWin( pEditWin ),
31  m_aControls( )
32 {
33 }
34 
36 {
37 }
38 
40 {
41  m_aControls.clear();
43 }
44 
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 
58 {
59  for ( auto& rEntry : m_aControls )
60  {
61  SwFrameControlPtrMap& rMap = rEntry.second;
62  rMap.erase(pFrame);
63  }
64 }
65 
67 {
68  SwFrameControlPtrMap& rMap = m_aControls[eType];
69  rMap.erase(pFrame);
70 }
71 
73 {
74  for ( const auto& rCtrl : m_aControls[eType] )
75  rCtrl.second->ShowAll( false );
76 }
77 
79 {
80  for ( auto& rEntry : m_aControls )
81  for ( auto& rCtrl : rEntry.second )
82  rCtrl.second->SetReadonly( bReadonly );
83 }
84 
85 void SwFrameControlsManager::SetHeaderFooterControl( const SwPageFrame* pPageFrame, FrameControlType eType, Point aOffset )
86 {
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 
121 {
122  // Check if we already have the control
123  SwFrameControlPtr pControl;
124 
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 
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 
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 
183  const OUString& rUIXMLDescription, const OString& rID)
184  : InterimItemWindow(pEditWin, rUIXMLDescription, rID)
185  , m_pEditWin(pEditWin)
186  , m_pFrame(pFrame)
187 {
188 }
189 
191 {
192  // remove entries with outline node keys that are not in the outline nodes list
195  std::map<const SwTextNode*, const SwContentFrame*>::iterator it = m_aTextNodeContentFrameMap.begin();
196  while(it != m_aTextNodeContentFrameMap.end())
197  {
198  const SwNode* pNd = it->first;
199  IDocumentOutlineNodes::tSortedOutlineNodeList::iterator i = std::find(aOutlineNodes.begin(), aOutlineNodes.end(), pNd);
200  if (i == aOutlineNodes.end())
201  {
203  it = m_aTextNodeContentFrameMap.erase(it);
204  }
205  else
206  ++it;
207  }
209  {
210  bool bOutlineContentVisibleAttr = true;
211  pNd->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr);
212  if (!bOutlineContentVisibleAttr)
213  SetOutlineContentVisibilityButton(pNd->GetTextNode());
214  }
215 }
216 
218 {
219  const SwContentFrame* pContentFrame = pTextNd->getLayoutFrame(nullptr);
220 
221  // has node frame changed or been deleted?
222  std::map<const SwTextNode*, const SwContentFrame*>::iterator iter = m_aTextNodeContentFrameMap.find(pTextNd);
223  if (iter != m_aTextNodeContentFrameMap.end())
224  {
225  const SwContentFrame* pFrameWas = iter->second;
226  if (pContentFrame != pFrameWas)
227  {
228  // frame does not match frame in map for node
230  m_aTextNodeContentFrameMap.erase(iter);
231  }
232  }
233  if (pContentFrame && !pContentFrame->IsInDtor())
234  {
235  // frame is not being destroyed and isn't in map
236  m_aTextNodeContentFrameMap.insert(make_pair(pTextNd, pContentFrame));
237  }
238  else
239  {
240  if (pContentFrame)
241  {
242  // frame is being destroyed
244  }
245  return;
246  }
247 
248  // Check if we already have the control
249  SwFrameControlPtr pControl;
250 
252 
253  SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pContentFrame);
254  if (lb != rControls.end() && !(rControls.key_comp()(pContentFrame, lb->first)))
255  {
256  pControl = lb->second;
257  }
258  else
259  {
260  SwFrameControlPtr pNewControl =
261  std::make_shared<SwFrameControl>(VclPtr<SwOutlineContentVisibilityWin>::Create(
262  m_pEditWin, pContentFrame).get());
263  rControls.insert(lb, make_pair(pContentFrame, pNewControl));
264  pControl.swap(pNewControl);
265  }
266 
267  SwOutlineContentVisibilityWin* pWin = dynamic_cast<SwOutlineContentVisibilityWin *>(pControl->GetWindow());
268  assert(pWin != nullptr) ;
269  pWin->Set();
270 
271  if (pWin->GetSymbol() == SymbolType::ARROW_RIGHT)
272  {
273  // show expand button immediately
274  pWin->Show();
275  /*
276  The outline content might be visible here. This happens on document load,
277  undo outline moves, and show of outline content that itself has outline nodes
278  having outline content visibility attribute false, for example tables and text
279  frames containing outline nodes.
280  */
283  if (rOutlineNds.Seek_Entry(const_cast<SwTextNode*>(pTextNd), &nPos))
284  {
285  SwNodeIndex aIdx(*pTextNd, +1);
286  // there shouldn't be a layout frame
287  // if there is then force visibility false
289  {
290  if (!(aIdx.GetNode().IsEndNode() ||
291  (nPos + 1 < rOutlineNds.size() && &aIdx.GetNode() == rOutlineNds[nPos +1]))
292  && aIdx.GetNode().IsContentNode()
293  // this determines if the content is really visible
294  && aIdx.GetNode().GetContentNode()->getLayoutFrame(nullptr))
295  {
296  // force outline content visibility false
298  }
299  }
300  else if (!aIdx.GetNode().IsEndNode()
301  && aIdx.GetNode().IsContentNode()
302  // this determines if the content is really visible
303  && aIdx.GetNode().GetContentNode()->getLayoutFrame(nullptr))
304  {
305  // force outline content visibility false
307  }
308  }
309  }
310  else if (!pWin->IsVisible() && pWin->GetSymbol() == SymbolType::ARROW_DOWN)
311  pWin->ShowAll(true);
312 }
313 
315 {
316  if (m_pFrame->IsPageFrame())
317  return static_cast<const SwPageFrame*>( m_pFrame );
318 
319  if (m_pFrame->IsFlyFrame())
320  return static_cast<const SwFlyFrame*>(m_pFrame)->GetAnchorFrame()->FindPageFrame();
321 
322  return m_pFrame->FindPageFrame();
323 }
324 
326 {
327  m_pEditWin.clear();
328  m_pFrame = nullptr;
331 }
332 
334 {
335  // Get the font and configure it
337  if (vcl::Window* pDefaultDevice = dynamic_cast<vcl::Window*>(Application::GetDefaultDevice()))
338  pDefaultDevice->SetPointFont(*m_xVirDev, aFont);
339 }
340 
342 {
343  assert(static_cast<bool>(pWindow));
344  mxWindow.reset( pWindow );
345  mpIFace = dynamic_cast<ISwFrameControl *>( pWindow.get() );
346 }
347 
349 {
350  mpIFace = nullptr;
352 }
353 
355 {
356 }
357 
358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetOffset(Point aTopRightPixel)
Base class of the Writer layout elements.
Definition: frame.hxx:298
VclPtr< SwEditWin > m_pEditWin
const SwNodes & GetNodes() const
Definition: viewsh.cxx:2084
virtual void dispose() override
void SetReadonly(bool bSet)
Definition: viewopt.hxx:465
const SwView & GetView() const
Definition: edtwin.hxx:244
const IDocumentOutlineNodes * getIDocumentOutlineNodesAccess() const
Definition: viewsh.cxx:2694
void UpdatePosition(const std::optional< Point > &xEvtPt=std::optional< Point >())
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1212
SwFrameMenuButtonBase(SwEditWin *pEditWin, const SwFrame *pFrame, const OUString &rUIXMLDescription, const OString &rID)
void HideControls(FrameControlType eType)
SwNode & GetNode() const
Definition: ndindex.hxx:119
void RemoveControls(const SwFrame *pFrame)
SwWrtShell & GetWrtShell() const
Definition: view.hxx:400
static OutputDevice * GetDefaultDevice()
bool IsFlyFrame() const
Definition: frame.hxx:1191
bool IsReadonly() const
Definition: viewopt.hxx:464
tools::Long Left() const
void SetOutlineContentVisibilityButton(const SwTextNode *pTextNd)
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
virtual void getOutlineNodes(IDocumentOutlineNodes::tSortedOutlineNodeList &orOutlineNodeList) const =0
Class for the page break control window.
size_type size() const
void SetHeaderFooterControl(const SwPageFrame *pPageFrame, FrameControlType eType, Point aOffset)
Abstract interface to be implemented by writer FrameControls.
void SetPageBreakControl(const SwPageFrame *pPageFrame)
void SetReadonlyControls(bool bReadonly)
bool IsContentNode() const
Definition: node.hxx:632
bool IsInDtor() const
Definition: frame.hxx:873
void RemoveControlsByType(FrameControlType eType, const SwFrame *pFrame)
void clear()
int i
const vcl::Font & GetToolFont() const
Window class for the Writer edit area, this is the one handling mouse and keyboard events and doing t...
Definition: edtwin.hxx:58
SwPageFrame * FindPageFrame()
Definition: frame.hxx:663
SwContentNode * GetContentNode()
Definition: node.hxx:619
void SetOffset(Point aOffset, tools::Long nXLineStart, tools::Long nXLineEnd)
Marks a node in the document model.
Definition: ndindex.hxx:31
bool IsEndNode() const
Definition: node.hxx:636
const SwOutlineNodes & GetOutLineNds() const
Array of all OutlineNodes.
Definition: ndarr.hxx:231
VclPtr< vcl::Window > mxWindow
virtual void ShowAll(bool bShow) override
A page of the document layout.
Definition: pagefrm.hxx:41
void reset(vcl::Window *pBody)
Class for the header and footer separator control window.
const SwFrame * m_pFrame
FrameControlType
Definition: swtypes.hxx:238
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
std::map< const SwTextNode *, const SwContentFrame * > m_aTextNodeContentFrameMap
VclPtr< SwEditWin > m_pEditWin
const SwPageFrame * GetPageFrame() const
general base class for all free-flowing frames
Definition: flyfrm.hxx:60
Class for unfloat table button.
std::map< FrameControlType, SwFrameControlPtrMap > m_aControls
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:423
virtual void dispose() override
void ToggleOutlineContentVisibility(SwNode *pNd, const bool bForceNotVisible=false)
Definition: wrtsh1.cxx:2007
bool IsVisible() const
std::vector< const SwTextNode * > tSortedOutlineNodeList
static VclPtr< reference_type > Create(Arg &&...arg)
bool IsPageFrame() const
Definition: frame.hxx:1159
SwFrameControlPtr GetControl(FrameControlType eType, const SwFrame *pFrame)
bool IsHeader() const
bool IsTreatSubOutlineLevelsAsContent() const
Definition: viewopt.cxx:106
ISwFrameControl * mpIFace
VclPtr< VirtualDevice > m_xVirDev
reference_type * get() const
if(!pCandidateA->getEnd().equal(pCandidateB->getStart()))
void SetUnfloatTableButton(const SwFlyFrame *pFlyFrame, bool bShow, Point aTopRightPixel=Point())
bool Seek_Entry(SwNode *rP, size_type *pnPos) const
Definition: ndnum.cxx:32
std::map< const SwFrame *, SwFrameControlPtr > SwFrameControlPtrMap
std::shared_ptr< SwFrameControl > SwFrameControlPtr
std::vector< SwNode * >::size_type size_type
SwFrameControlsManager(SwEditWin *pEditWin)
tools::Long Right() const
SwFrameControl(const VclPtr< vcl::Window > &pWindow)
sal_uInt16 nPos
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Base class of the Writer document model elements.
Definition: node.hxx:80