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 
25 using namespace std;
26 
28  m_pEditWin( pEditWin ),
29  m_aControls( )
30 {
31 }
32 
34 {
35 }
36 
38 {
39  m_aControls.clear();
41 }
42 
44 {
45  SwFrameControlPtrMap& rControls = m_aControls[eType];
46 
47  SwFrameControlPtrMap::iterator aIt = rControls.find(pFrame);
48 
49  if (aIt != rControls.end())
50  return aIt->second;
51 
52  return SwFrameControlPtr();
53 }
54 
56 {
57  for ( auto& rEntry : m_aControls )
58  {
59  SwFrameControlPtrMap& rMap = rEntry.second;
60  rMap.erase(pFrame);
61  }
62 }
63 
65 {
66  SwFrameControlPtrMap& rMap = m_aControls[eType];
67  rMap.erase(pFrame);
68 }
69 
71 {
72  for ( const auto& rCtrl : m_aControls[eType] )
73  rCtrl.second->ShowAll( false );
74 }
75 
77 {
78  for ( auto& rEntry : m_aControls )
79  for ( auto& rCtrl : rEntry.second )
80  rCtrl.second->SetReadonly( bReadonly );
81 }
82 
83 void SwFrameControlsManager::SetHeaderFooterControl( const SwPageFrame* pPageFrame, FrameControlType eType, Point aOffset )
84 {
86 
87  // Check if we already have the control
88  SwFrameControlPtr pControl;
89  const bool bHeader = ( eType == FrameControlType::Header );
90 
91  SwFrameControlPtrMap& rControls = m_aControls[eType];
92 
93  SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pPageFrame);
94  if (lb != rControls.end() && !(rControls.key_comp()(pPageFrame, lb->first)))
95  pControl = lb->second;
96  else
97  {
98  SwFrameControlPtr pNewControl =
99  std::make_shared<SwFrameControl>( VclPtr<SwHeaderFooterWin>::Create(
100  m_pEditWin, pPageFrame, bHeader ).get() );
101  const SwViewOption* pViewOpt = m_pEditWin->GetView().GetWrtShell().GetViewOptions();
102  pNewControl->SetReadonly( pViewOpt->IsReadonly() );
103  rControls.insert(lb, make_pair(pPageFrame, pNewControl));
104  pControl.swap( pNewControl );
105  }
106 
107  tools::Rectangle aPageRect = m_pEditWin->LogicToPixel( pPageFrame->getFrameArea().SVRect() );
108 
109  SwHeaderFooterWin* pWin = dynamic_cast<SwHeaderFooterWin *>(pControl->GetWindow());
110  assert( pWin != nullptr) ;
111  assert( pWin->IsHeader() == bHeader );
112  pWin->SetOffset( aOffset, aPageRect.Left(), aPageRect.Right() );
113 
114  if (!pWin->IsVisible())
115  pControl->ShowAll( true );
116 }
117 
119 {
120  // Check if we already have the control
121  SwFrameControlPtr pControl;
122 
124 
125  SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pPageFrame);
126  if (lb != rControls.end() && !(rControls.key_comp()(pPageFrame, lb->first)))
127  pControl = lb->second;
128  else
129  {
130  SwFrameControlPtr pNewControl = std::make_shared<SwFrameControl>(
131  VclPtr<SwPageBreakWin>::Create( m_pEditWin, pPageFrame ).get() );
132  const SwViewOption* pViewOpt = m_pEditWin->GetView().GetWrtShell().GetViewOptions();
133  pNewControl->SetReadonly( pViewOpt->IsReadonly() );
134 
135  rControls.insert(lb, make_pair(pPageFrame, pNewControl));
136 
137  pControl.swap( pNewControl );
138  }
139 
140  SwPageBreakWin* pWin = dynamic_cast<SwPageBreakWin *>(pControl->GetWindow());
141  assert (pWin != nullptr);
142  pWin->UpdatePosition();
143  if (!pWin->IsVisible())
144  pControl->ShowAll( true );
145 }
146 
147 void SwFrameControlsManager::SetUnfloatTableButton( const SwFlyFrame* pFlyFrame, bool bShow, Point aTopRightPixel )
148 {
149  if(pFlyFrame == nullptr)
150  return;
151 
152  // Check if we already have the control
153  SwFrameControlPtr pControl;
154 
156 
157  SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pFlyFrame);
158  if (lb != rControls.end() && !(rControls.key_comp()(pFlyFrame, lb->first)))
159  pControl = lb->second;
160  else if (!bShow) // Do not create the control when it's not shown
161  return;
162  else
163  {
164  SwFrameControlPtr pNewControl = std::make_shared<SwFrameControl>(
165  VclPtr<UnfloatTableButton>::Create( m_pEditWin, pFlyFrame ).get() );
166  const SwViewOption* pViewOpt = m_pEditWin->GetView().GetWrtShell().GetViewOptions();
167  pNewControl->SetReadonly( pViewOpt->IsReadonly() );
168 
169  rControls.insert(lb, make_pair(pFlyFrame, pNewControl));
170 
171  pControl.swap( pNewControl );
172  }
173 
174  UnfloatTableButton* pButton = dynamic_cast<UnfloatTableButton*>(pControl->GetWindow());
175  assert(pButton != nullptr);
176  pButton->SetOffset(aTopRightPixel);
177  pControl->ShowAll( bShow );
178 }
179 
181  MenuButton( pEditWin, WB_DIALOGCONTROL ),
182  m_pEditWin( pEditWin ),
183  m_pFrame( pFrame )
184 {
185 }
186 
188 {
189  // remove entries with outline node keys that are not in the outline nodes list
192  std::map<const SwTextNode*, const SwContentFrame*>::iterator it = m_aTextNodeContentFrameMap.begin();
193  while(it != m_aTextNodeContentFrameMap.end())
194  {
195  const SwNode* pNd = it->first;
196  IDocumentOutlineNodes::tSortedOutlineNodeList::iterator i = std::find(aOutlineNodes.begin(), aOutlineNodes.end(), pNd);
197  if (i == aOutlineNodes.end())
198  {
200  it = m_aTextNodeContentFrameMap.erase(it);
201  }
202  else
203  it++;
204  }
206  {
207  bool bOutlineContentVisibleAttr = true;
208  pNd->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr);
209  if (!bOutlineContentVisibleAttr)
210  SetOutlineContentVisibilityButton(pNd->GetTextNode());
211  }
212 }
213 
215 {
216  const SwContentFrame* pContentFrame = pTextNd->getLayoutFrame(nullptr);
217 
218  // has node frame changed or been deleted
219  std::map<const SwTextNode*, const SwContentFrame*>::iterator iter = m_aTextNodeContentFrameMap.find(pTextNd);
220  if (iter != m_aTextNodeContentFrameMap.end())
221  {
222  const SwContentFrame* pFrameWas = iter->second;
223  if (pContentFrame != pFrameWas)
224  {
225  // frame does not match frame in map for node
227  m_aTextNodeContentFrameMap.erase(iter);
228  }
229  }
230  if (pContentFrame && !pContentFrame->IsInDtor())
231  {
232  // frame is not being destroyed and isn't in map
233  m_aTextNodeContentFrameMap.insert(make_pair(pTextNd, pContentFrame));
234  }
235  else
236  {
237  if (pContentFrame)
238  {
239  // frame is being destroyed
241  }
242  return;
243  }
244 
245  // Check if we already have the control
246  SwFrameControlPtr pControl;
247 
249 
250  SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pContentFrame);
251  if (lb != rControls.end() && !(rControls.key_comp()(pContentFrame, lb->first)))
252  {
253  pControl = lb->second;
254  }
255  else
256  {
257  SwFrameControlPtr pNewControl =
258  std::make_shared<SwFrameControl>(VclPtr<SwOutlineContentVisibilityWin>::Create(
259  m_pEditWin, pContentFrame).get());
260  rControls.insert(lb, make_pair(pContentFrame, pNewControl));
261  pControl.swap(pNewControl);
262  }
263 
264  SwOutlineContentVisibilityWin* pWin = dynamic_cast<SwOutlineContentVisibilityWin *>(pControl->GetWindow());
265  assert(pWin != nullptr) ;
266  pWin->Set();
267 
268  if (pWin->GetSymbol() == SymbolType::ARROW_RIGHT)
269  {
270  // show expand button immediately
271  pWin->Show();
272  // outline content might not be folded, this happens on undo, outline moves, and folded outline content reveals
275  if (rOutlineNds.Seek_Entry(const_cast<SwTextNode*>(pTextNd), &nPos))
276  {
277  // don't toggle if next node is an outline node or end node
278  SwNodeIndex aIdx(*pTextNd, 1);
279  if (!(aIdx.GetNode().IsEndNode() || ((nPos + 1 < rOutlineNds.size()) && &aIdx.GetNode() == rOutlineNds[nPos +1]))
280  && aIdx.GetNode().IsContentNode() && aIdx.GetNode().GetContentNode()->getLayoutFrame(nullptr))
281  {
282  m_pEditWin->GetView().GetWrtShell().ToggleOutlineContentVisibility(nPos, true); // force fold
283  }
284  }
285  }
286  else if (!pWin->IsVisible() && pWin->GetSymbol() == SymbolType::ARROW_DOWN)
287  pWin->ShowAll(true);
288 }
289 
291 {
292  if (m_pFrame->IsPageFrame())
293  return static_cast<const SwPageFrame*>( m_pFrame );
294 
295  if (m_pFrame->IsFlyFrame())
296  return static_cast<const SwFlyFrame*>(m_pFrame)->GetAnchorFrame()->FindPageFrame();
297 
298  return m_pFrame->FindPageFrame();
299 }
300 
302 {
303  m_pEditWin.clear();
304  m_pFrame = nullptr;
306 }
307 
309 {
310  assert(static_cast<bool>(pWindow));
311  mxWindow.reset( pWindow );
312  mpIFace = dynamic_cast<ISwFrameControl *>( pWindow.get() );
313 }
314 
316 {
317  mpIFace = nullptr;
319 }
320 
322 {
323 }
324 
325 /* 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:2089
virtual void dispose() override
void SetReadonly(bool bSet)
Definition: viewopt.hxx:450
const SwView & GetView() const
Definition: edtwin.hxx:244
const IDocumentOutlineNodes * getIDocumentOutlineNodesAccess() const
Definition: viewsh.cxx:2689
void UpdatePosition(const std::optional< Point > &xEvtPt=std::optional< Point >())
virtual void dispose() override
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1208
void HideControls(FrameControlType eType)
SwNode & GetNode() const
Definition: ndindex.hxx:119
void RemoveControls(const SwFrame *pFrame)
SwWrtShell & GetWrtShell() const
Definition: view.hxx:399
bool IsFlyFrame() const
Definition: frame.hxx:1191
bool IsReadonly() const
Definition: viewopt.hxx:449
void ToggleOutlineContentVisibility(SwNode *pNd, bool bForceFold=false)
Definition: wrtsh1.cxx:2010
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:631
WinBits const WB_DIALOGCONTROL
bool IsInDtor() const
Definition: frame.hxx:873
void RemoveControlsByType(FrameControlType eType, const SwFrame *pFrame)
void clear()
int i
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:618
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:635
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:236
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.
SwFrameMenuButtonBase(SwEditWin *pEditWin, const SwFrame *pFrame)
std::map< FrameControlType, SwFrameControlPtrMap > m_aControls
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:423
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
ISwFrameControl * mpIFace
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)
SymbolType GetSymbol() const
sal_uInt16 nPos
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Base class of the Writer document model elements.
Definition: node.hxx:79