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 #include <vcl/weldutils.hxx>
27 
28 using namespace std;
29 
31  m_pEditWin( pEditWin ),
32  m_aControls( )
33 {
34 }
35 
37 {
38 }
39 
41 {
42  m_aControls.clear();
44 }
45 
47 {
48  SwFrameControlPtrMap& rControls = m_aControls[eType];
49 
50  SwFrameControlPtrMap::iterator aIt = rControls.find(pFrame);
51 
52  if (aIt != rControls.end())
53  return aIt->second;
54 
55  return SwFrameControlPtr();
56 }
57 
59 {
60  for ( auto& rEntry : m_aControls )
61  {
62  SwFrameControlPtrMap& rMap = rEntry.second;
63  rMap.erase(pFrame);
64  }
65 }
66 
68 {
69  SwFrameControlPtrMap& rMap = m_aControls[eType];
70  rMap.erase(pFrame);
71 }
72 
74 {
75  for ( const auto& rCtrl : m_aControls[eType] )
76  rCtrl.second->ShowAll( false );
77 }
78 
80 {
81  for ( auto& rEntry : m_aControls )
82  for ( auto& rCtrl : rEntry.second )
83  rCtrl.second->SetReadonly( bReadonly );
84 }
85 
86 void SwFrameControlsManager::SetHeaderFooterControl( const SwPageFrame* pPageFrame, FrameControlType eType, Point aOffset )
87 {
89 
90  // Check if we already have the control
91  SwFrameControlPtr pControl;
92  const bool bHeader = ( eType == FrameControlType::Header );
93 
94  SwFrameControlPtrMap& rControls = m_aControls[eType];
95 
96  SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pPageFrame);
97  if (lb != rControls.end() && !(rControls.key_comp()(pPageFrame, lb->first)))
98  pControl = lb->second;
99  else
100  {
101  SwFrameControlPtr pNewControl =
102  std::make_shared<SwFrameControl>( VclPtr<SwHeaderFooterWin>::Create(
103  m_pEditWin, pPageFrame, bHeader ).get() );
104  const SwViewOption* pViewOpt = m_pEditWin->GetView().GetWrtShell().GetViewOptions();
105  pNewControl->SetReadonly( pViewOpt->IsReadonly() );
106  rControls.insert(lb, make_pair(pPageFrame, pNewControl));
107  pControl.swap( pNewControl );
108  }
109 
110  tools::Rectangle aPageRect = m_pEditWin->LogicToPixel( pPageFrame->getFrameArea().SVRect() );
111 
112  SwHeaderFooterWin* pWin = dynamic_cast<SwHeaderFooterWin *>(pControl->GetWindow());
113  assert( pWin != nullptr) ;
114  assert( pWin->IsHeader() == bHeader );
115  pWin->SetOffset( aOffset, aPageRect.Left(), aPageRect.Right() );
116 
117  if (!pWin->IsVisible())
118  pControl->ShowAll( true );
119 }
120 
122 {
123  // Check if we already have the control
124  SwFrameControlPtr pControl;
125 
127 
128  SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pPageFrame);
129  if (lb != rControls.end() && !(rControls.key_comp()(pPageFrame, lb->first)))
130  pControl = lb->second;
131  else
132  {
133  SwFrameControlPtr pNewControl = std::make_shared<SwFrameControl>(
134  VclPtr<SwPageBreakWin>::Create( m_pEditWin, pPageFrame ).get() );
135  const SwViewOption* pViewOpt = m_pEditWin->GetView().GetWrtShell().GetViewOptions();
136  pNewControl->SetReadonly( pViewOpt->IsReadonly() );
137 
138  rControls.insert(lb, make_pair(pPageFrame, pNewControl));
139 
140  pControl.swap( pNewControl );
141  }
142 
143  SwPageBreakWin* pWin = dynamic_cast<SwPageBreakWin *>(pControl->GetWindow());
144  assert (pWin != nullptr);
145  pWin->UpdatePosition();
146  if (!pWin->IsVisible())
147  pControl->ShowAll( true );
148 }
149 
150 void SwFrameControlsManager::SetUnfloatTableButton( const SwFlyFrame* pFlyFrame, bool bShow, Point aTopRightPixel )
151 {
152  if(pFlyFrame == nullptr)
153  return;
154 
155  // Check if we already have the control
156  SwFrameControlPtr pControl;
157 
159 
160  SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pFlyFrame);
161  if (lb != rControls.end() && !(rControls.key_comp()(pFlyFrame, lb->first)))
162  pControl = lb->second;
163  else if (!bShow) // Do not create the control when it's not shown
164  return;
165  else
166  {
167  SwFrameControlPtr pNewControl = std::make_shared<SwFrameControl>(
168  VclPtr<UnfloatTableButton>::Create( m_pEditWin, pFlyFrame ).get() );
169  const SwViewOption* pViewOpt = m_pEditWin->GetView().GetWrtShell().GetViewOptions();
170  pNewControl->SetReadonly( pViewOpt->IsReadonly() );
171 
172  rControls.insert(lb, make_pair(pFlyFrame, pNewControl));
173 
174  pControl.swap( pNewControl );
175  }
176 
177  UnfloatTableButton* pButton = dynamic_cast<UnfloatTableButton*>(pControl->GetWindow());
178  assert(pButton != nullptr);
179  pButton->SetOffset(aTopRightPixel);
180  pControl->ShowAll( bShow );
181 }
182 
184  const OUString& rUIXMLDescription, const OString& rID)
185  : InterimItemWindow(pEditWin, rUIXMLDescription, rID)
186  , m_pEditWin(pEditWin)
187  , m_pFrame(pFrame)
188 {
189 }
190 
192 {
193  // remove entries with outline node keys that are not in the outline nodes list
196  std::map<const SwTextNode*, const SwContentFrame*>::iterator it = m_aTextNodeContentFrameMap.begin();
197  while(it != m_aTextNodeContentFrameMap.end())
198  {
199  const SwNode* pNd = it->first;
200  IDocumentOutlineNodes::tSortedOutlineNodeList::iterator i = std::find(aOutlineNodes.begin(), aOutlineNodes.end(), pNd);
201  if (i == aOutlineNodes.end())
202  {
204  it = m_aTextNodeContentFrameMap.erase(it);
205  }
206  else
207  ++it;
208  }
210  {
211  bool bOutlineContentVisibleAttr = true;
212  pNd->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr);
213  if (!bOutlineContentVisibleAttr)
214  SetOutlineContentVisibilityButton(pNd->GetTextNode());
215  }
216 }
217 
219 {
220  const SwContentFrame* pContentFrame = pTextNd->getLayoutFrame(nullptr);
221 
222  // has node frame changed or been deleted?
223  std::map<const SwTextNode*, const SwContentFrame*>::iterator iter = m_aTextNodeContentFrameMap.find(pTextNd);
224  if (iter != m_aTextNodeContentFrameMap.end())
225  {
226  const SwContentFrame* pFrameWas = iter->second;
227  if (pContentFrame != pFrameWas)
228  {
229  // frame does not match frame in map for node
231  m_aTextNodeContentFrameMap.erase(iter);
232  }
233  }
234  if (pContentFrame && !pContentFrame->IsInDtor())
235  {
236  // frame is not being destroyed and isn't in map
237  m_aTextNodeContentFrameMap.insert(make_pair(pTextNd, pContentFrame));
238  }
239  else
240  {
241  if (pContentFrame)
242  {
243  // frame is being destroyed
245  }
246  return;
247  }
248 
249  // Check if we already have the control
250  SwFrameControlPtr pControl;
251 
253 
254  SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pContentFrame);
255  if (lb != rControls.end() && !(rControls.key_comp()(pContentFrame, lb->first)))
256  {
257  pControl = lb->second;
258  }
259  else
260  {
261  SwFrameControlPtr pNewControl =
262  std::make_shared<SwFrameControl>(VclPtr<SwOutlineContentVisibilityWin>::Create(
263  m_pEditWin, pContentFrame).get());
264  rControls.insert(lb, make_pair(pContentFrame, pNewControl));
265  pControl.swap(pNewControl);
266  }
267 
268  SwOutlineContentVisibilityWin* pWin = dynamic_cast<SwOutlineContentVisibilityWin *>(pControl->GetWindow());
269  assert(pWin != nullptr) ;
270  pWin->Set();
271 
272  if (pWin->GetSymbol() == ButtonSymbol::SHOW)
273  {
274  // show expand button immediately
275  pWin->Show();
276  /*
277  The outline content might be visible here. This happens on document load,
278  undo outline moves, and show of outline content that itself has outline nodes
279  having outline content visibility attribute false, for example tables and text
280  frames containing outline nodes.
281  */
284  if (rOutlineNds.Seek_Entry(const_cast<SwTextNode*>(pTextNd), &nPos))
285  {
286  SwNodeIndex aIdx(*pTextNd, +1);
287  // there shouldn't be a layout frame
288  // if there is then force visibility false
290  {
291  if (!(aIdx.GetNode().IsEndNode() ||
292  (nPos + 1 < rOutlineNds.size() && &aIdx.GetNode() == rOutlineNds[nPos +1]))
293  && aIdx.GetNode().IsContentNode()
294  // this determines if the content is really visible
295  && aIdx.GetNode().GetContentNode()->getLayoutFrame(nullptr))
296  {
297  // force outline content visibility false
299  }
300  }
301  else if (!aIdx.GetNode().IsEndNode()
302  && aIdx.GetNode().IsContentNode()
303  // this determines if the content is really visible
304  && aIdx.GetNode().GetContentNode()->getLayoutFrame(nullptr))
305  {
306  // force outline content visibility false
308  }
309  }
310  }
311  else if (!pWin->IsVisible() && pWin->GetSymbol() == ButtonSymbol::HIDE)
312  pWin->ShowAll(true);
313 }
314 
316 {
317  if (m_pFrame->IsPageFrame())
318  return static_cast<const SwPageFrame*>( m_pFrame );
319 
320  if (m_pFrame->IsFlyFrame())
321  return static_cast<const SwFlyFrame*>(m_pFrame)->GetAnchorFrame()->FindPageFrame();
322 
323  return m_pFrame->FindPageFrame();
324 }
325 
327 {
328  m_pEditWin.clear();
329  m_pFrame = nullptr;
332 }
333 
335 {
336  // Get the font and configure it
338  weld::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:313
VclPtr< SwEditWin > m_pEditWin
const SwNodes & GetNodes() const
Definition: viewsh.cxx:2085
virtual void dispose() override
void SetReadonly(bool bSet)
Definition: viewopt.hxx:464
const SwView & GetView() const
Definition: edtwin.hxx:244
const IDocumentOutlineNodes * getIDocumentOutlineNodesAccess() const
Definition: viewsh.cxx:2688
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:413
bool IsFlyFrame() const
Definition: frame.hxx:1206
bool IsReadonly() const
Definition: viewopt.hxx:463
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:888
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:678
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:57
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:79
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:78
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:2011
bool IsVisible() const
if(aStr!=aBuf) UpdateName_Impl(m_xFollowLb.get()
std::vector< const SwTextNode * > tSortedOutlineNodeList
static VclPtr< reference_type > Create(Arg &&...arg)
void SetPointFont(OutputDevice &rDevice, const vcl::Font &rFont)
bool IsPageFrame() const
Definition: frame.hxx:1174
SwFrameControlPtr GetControl(FrameControlType eType, const SwFrame *pFrame)
bool IsHeader() const
bool IsTreatSubOutlineLevelsAsContent() const
Definition: viewopt.cxx:105
ISwFrameControl * mpIFace
VclPtr< VirtualDevice > m_xVirDev
reference_type * get() const
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