LibreOffice Module sw (master)  1
edsect.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  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <editsh.hxx>
21 #include <doc.hxx>
22 #include <IDocumentUndoRedo.hxx>
24 #include <pam.hxx>
25 #include <docary.hxx>
26 #include <swundo.hxx>
27 #include <section.hxx>
28 #include <sectfrm.hxx>
29 #include <cntfrm.hxx>
30 #include <tabfrm.hxx>
31 #include <rootfrm.hxx>
32 
33 SwSection const*
35  SwSectionData & rNewData, SfxItemSet const*const pAttr)
36 {
37  const SwSection* pRet = nullptr;
38  if( !IsTableMode() )
39  {
42 
43  for(const SwPaM& rPaM : GetCursor()->GetRingContainer())
44  {
45  SwSection const*const pNew =
46  GetDoc()->InsertSwSection( rPaM, rNewData, nullptr, pAttr );
47  if( !pRet )
48  pRet = pNew;
49  }
50 
52  EndAllAction();
53  }
54  return pRet;
55 }
56 
58 {
59  if( IsTableMode() )
60  return false;
61  SwPaM* pCursor = GetCursor();
62  if( pCursor->GetNext() != pCursor )
63  return false;
64  if( pCursor->HasMark() )
65  return 0 != SwDoc::IsInsRegionAvailable( *pCursor );
66 
67  return true;
68 }
69 
71 {
72  if( IsTableMode() )
73  return nullptr;
74 
75  return SwDoc::GetCurrSection( *GetCursor()->GetPoint() );
76 }
77 
82 SwSection* SwEditShell::GetAnySection( bool bOutOfTab, const Point* pPt )
83 {
84  SwFrame *pFrame;
85  if ( pPt )
86  {
87  SwPosition aPos( *GetCursor()->GetPoint() );
88  Point aPt( *pPt );
89  GetLayout()->GetCursorOfst( &aPos, aPt );
90  SwContentNode *pNd = aPos.nNode.GetNode().GetContentNode();
91  std::pair<Point, bool> const tmp(*pPt, true);
92  pFrame = pNd->getLayoutFrame(GetLayout(), nullptr, &tmp);
93  }
94  else
95  pFrame = GetCurrFrame( false );
96 
97  if( bOutOfTab && pFrame )
98  pFrame = pFrame->FindTabFrame();
99  if( pFrame && pFrame->IsInSct() )
100  {
101  SwSectionFrame* pSect = pFrame->FindSctFrame();
102  OSL_ENSURE( pSect, "GetAnySection: Where's my Sect?" );
103  if( pSect->IsInFootnote() && pSect->GetUpper()->IsInSct() )
104  {
105  pSect = pSect->GetUpper()->FindSctFrame();
106  OSL_ENSURE( pSect, "GetAnySection: Where's my SectFrame?" );
107  }
108  return pSect->GetSection();
109  }
110  return nullptr;
111 }
112 
114 {
115  return GetDoc()->GetSections().size();
116 }
117 
119 {
120  const SwSectionFormats& rFormats = GetDoc()->GetSections();
121 
122  for( const SwSectionFormat* pFormat : rFormats )
123  {
124  SectionType eTmpType;
125  if( pFormat->IsInNodesArr() &&
126  ( (eTmpType = pFormat->GetSection()->GetType()) != SectionType::ToxContent
127  && SectionType::ToxHeader != eTmpType ) )
128  {
129  return true;
130  }
131  }
132  return false;
133 }
134 
135 size_t SwEditShell::GetSectionFormatPos( const SwSectionFormat& rFormat ) const
136 {
137  SwSectionFormat* pFormat = const_cast<SwSectionFormat*>(&rFormat);
138  return GetDoc()->GetSections().GetPos( pFormat );
139 }
140 
141 const SwSectionFormat& SwEditShell::GetSectionFormat(size_t nFormat) const
142 {
143  return *GetDoc()->GetSections()[ nFormat ];
144 }
145 
146 void SwEditShell::DelSectionFormat(size_t nFormat)
147 {
148  StartAllAction();
149  GetDoc()->DelSectionFormat( GetDoc()->GetSections()[ nFormat ] );
150  // Call the AttrChangeNotify on the UI page.
151  CallChgLnk();
152  EndAllAction();
153 }
154 
155 void SwEditShell::UpdateSection(size_t const nSect,
156  SwSectionData & rNewData, SfxItemSet const*const pAttr)
157 {
158  StartAllAction();
159  GetDoc()->UpdateSection( nSect, rNewData, pAttr );
160  // Call the AttrChangeNotify on the UI page.
161  CallChgLnk();
162  EndAllAction();
163 }
164 
165 OUString SwEditShell::GetUniqueSectionName( const OUString* pChkStr ) const
166 {
167  return GetDoc()->GetUniqueSectionName( pChkStr );
168 }
169 
171  SwSectionFormat* pSectFormat )
172 {
173  if( pSectFormat )
174  SetSectionAttr_( *pSectFormat, rSet );
175  else
176  {
177  // for all section in the selection
178 
179  for(SwPaM& rPaM : GetCursor()->GetRingContainer())
180  {
181  const SwPosition* pStt = rPaM.Start(),
182  * pEnd = rPaM.End();
183 
184  SwSectionNode* pSttSectNd = pStt->nNode.GetNode().FindSectionNode(),
185  * pEndSectNd = pEnd->nNode.GetNode().FindSectionNode();
186 
187  if( pSttSectNd || pEndSectNd )
188  {
189  if( pSttSectNd )
190  SetSectionAttr_( *pSttSectNd->GetSection().GetFormat(),
191  rSet );
192  if( pEndSectNd && pSttSectNd != pEndSectNd )
193  SetSectionAttr_( *pEndSectNd->GetSection().GetFormat(),
194  rSet );
195 
196  if( pSttSectNd && pEndSectNd )
197  {
198  SwNodeIndex aSIdx( pStt->nNode );
199  SwNodeIndex aEIdx( pEnd->nNode );
200  if( pSttSectNd->EndOfSectionIndex() <
201  pEndSectNd->GetIndex() )
202  {
203  aSIdx = pSttSectNd->EndOfSectionIndex() + 1;
204  aEIdx = *pEndSectNd;
205  }
206 
207  while( aSIdx < aEIdx )
208  {
209  if( nullptr != (pSttSectNd = aSIdx.GetNode().GetSectionNode())
210  || ( aSIdx.GetNode().IsEndNode() &&
211  nullptr != ( pSttSectNd = aSIdx.GetNode().
212  StartOfSectionNode()->GetSectionNode())) )
213  SetSectionAttr_( *pSttSectNd->GetSection().GetFormat(),
214  rSet );
215  ++aSIdx;
216  }
217  }
218  }
219 
220  }
221  }
222 }
223 
225  const SfxItemSet& rSet )
226 {
227  StartAllAction();
228  if(SfxItemState::SET == rSet.GetItemState(RES_CNTNT, false))
229  {
230  SfxItemSet aSet(rSet);
231  aSet.ClearItem(RES_CNTNT);
232  GetDoc()->SetAttr( aSet, rSectFormat );
233  }
234  else
235  GetDoc()->SetAttr( rSet, rSectFormat );
236 
237  // Call the AttrChangeNotify on the UI page.
238  CallChgLnk();
239  EndAllAction();
240 }
241 
247 {
248  sal_uInt16 nRet = 0;
249  for(SwPaM& rPaM : GetCursor()->GetRingContainer())
250  {
251 
252  const SwPosition* pStt = rPaM.Start(),
253  * pEnd = rPaM.End();
254  const SwContentNode* pCNd;
255  // check the selection, if Start at Node begin and End at Node end
256  if( pStt->nContent.GetIndex() ||
257  ( nullptr == ( pCNd = pEnd->nNode.GetNode().GetContentNode() )) ||
258  pCNd->Len() != pEnd->nContent.GetIndex() )
259  {
260  nRet = 0;
261  break;
262  }
263 
264 // !!!
265 // what about table at start or end ?
266 // There is no selection possible!
267 // What about only a table inside the section ?
268 // There is only a table selection possible!
269 
270  SwNodeIndex aSIdx( pStt->nNode, -1 ), aEIdx( pEnd->nNode, +1 );
271  if( !aSIdx.GetNode().IsSectionNode() ||
272  !aEIdx.GetNode().IsEndNode() ||
274  {
275  nRet = 0;
276  break;
277  }
278 
279  ++nRet;
280  if( &aSIdx.GetNode() != aEIdx.GetNode().StartOfSectionNode() )
281  ++nRet;
282 
283  }
284  return nRet;
285 }
286 
300 static const SwNode* lcl_SpecialInsertNode(const SwPosition* pCurrentPos)
301 {
302  const SwNode* pReturn = nullptr;
303 
304  // the current position
305  OSL_ENSURE( pCurrentPos != nullptr, "Strange, we have no position!" );
306  const SwNode& rCurrentNode = pCurrentPos->nNode.GetNode();
307 
308  // find innermost section or table. At the end of this scope,
309  // pInntermostNode contain the section/table before/after which we should
310  // insert our empty paragraph, or it will be NULL if none is found.
311  const SwNode* pInnermostNode = nullptr;
312  {
313  const SwNode* pTableNode = rCurrentNode.FindTableNode();
314  const SwNode* pSectionNode = rCurrentNode.FindSectionNode();
315 
316  // find the table/section which is close
317  if( pTableNode == nullptr )
318  pInnermostNode = pSectionNode;
319  else if ( pSectionNode == nullptr )
320  pInnermostNode = pTableNode;
321  else
322  {
323  // compare and choose the larger one
324  pInnermostNode =
325  ( pSectionNode->GetIndex() > pTableNode->GetIndex() )
326  ? pSectionNode : pTableNode;
327  }
328  }
329 
330  // The previous version had a check to skip empty read-only sections. Those
331  // shouldn't occur, so we only need to check whether our pInnermostNode is
332  // inside a protected area.
333 
334  // Now, pInnermostNode is NULL or the innermost section or table node.
335  if( (pInnermostNode != nullptr) && !pInnermostNode->IsProtect() )
336  {
337  OSL_ENSURE( pInnermostNode->IsTableNode() ||
338  pInnermostNode->IsSectionNode(), "wrong node found" );
339  OSL_ENSURE( ( pInnermostNode->GetIndex() <= rCurrentNode.GetIndex() )&&
340  ( pInnermostNode->EndOfSectionNode()->GetIndex() >=
341  rCurrentNode.GetIndex() ), "wrong node found" );
342 
343  // we now need to find the possible start/end positions
344 
345  // we found a start if
346  // - we're at or just before a start node
347  // - there are only start nodes between the current and pInnermostNode
348  SwNodeIndex aBegin( pCurrentPos->nNode );
349  if( rCurrentNode.IsContentNode() &&
350  (pCurrentPos->nContent.GetIndex() == 0))
351  --aBegin;
352  while( (aBegin != pInnermostNode->GetIndex()) &&
353  aBegin.GetNode().IsStartNode() )
354  --aBegin;
355  bool bStart = ( aBegin == pInnermostNode->GetIndex() );
356 
357  // we found an end if
358  // - we're at or just before an end node
359  // - there are only end nodes between the current node and
360  // pInnermostNode's end node
361  SwNodeIndex aEnd( pCurrentPos->nNode );
362  if( rCurrentNode.IsContentNode() &&
363  ( pCurrentPos->nContent.GetIndex() ==
364  rCurrentNode.GetContentNode()->Len() ) )
365  ++aEnd;
366  while( (aEnd != pInnermostNode->EndOfSectionNode()->GetIndex()) &&
367  aEnd.GetNode().IsEndNode() )
368  ++aEnd;
369  bool bEnd = ( aEnd == pInnermostNode->EndOfSectionNode()->GetIndex() );
370 
371  // evaluate result: if both start + end, end is preferred
372  if( bEnd )
373  pReturn = pInnermostNode->EndOfSectionNode();
374  else if ( bStart )
375  pReturn = pInnermostNode;
376  }
377 
378  OSL_ENSURE( ( pReturn == nullptr ) || pReturn->IsStartNode() ||
379  pReturn->IsEndNode(),
380  "SpecialInsertNode failed" );
381  return pReturn;
382 }
383 
388 {
389  return nullptr != lcl_SpecialInsertNode( GetCursor()->GetPoint() );
390 }
391 
396 {
397  // get current node
398  SwPosition* pCursorPos = GetCursor()->GetPoint();
399  const SwNode* pInsertNode = lcl_SpecialInsertNode( pCursorPos );
400  if( pInsertNode != nullptr )
401  {
402  StartAllAction();
403 
404  // adjust insert position to insert before start nodes and after end
405  // nodes
406  SwNodeIndex aInsertIndex( *pInsertNode,
407  pInsertNode->IsStartNode() ? -1 : 0 );
408  SwPosition aInsertPos( aInsertIndex );
409 
410  // insert a new text node, and set the cursor
412  *pCursorPos = aInsertPos;
413 
414  // call AttrChangeNotify for the UI
415  CallChgLnk();
416 
417  EndAllAction();
418  }
419 }
420 
421 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual bool GetCursorOfst(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const override
Primary passes the call to the first page.
Definition: trvlfrm.cxx:423
SwSectionNode * FindSectionNode()
Search section node, in which it is.
Definition: ndsect.cxx:955
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:682
Base class of the Writer layout elements.
Definition: frame.hxx:295
virtual sal_Int32 Len() const
Definition: node.cxx:1180
sal_uLong GetIndex() const
Definition: node.hxx:282
size_t GetSectionFormatPos(const SwSectionFormat &) const
Definition: edsect.cxx:135
Marks a position in the document model.
Definition: pam.hxx:35
bool IsSectionNode() const
Definition: node.hxx:644
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:188
bool IsInSct() const
Definition: frame.hxx:943
void DelSectionFormat(SwSectionFormat *pFormat, bool bDelNodes=false)
Definition: ndsect.cxx:512
SwNodeIndex nNode
Definition: pam.hxx:37
bool IsTableMode() const
Definition: crsrsh.hxx:647
bool IsInFootnote() const
Definition: frame.hxx:925
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1147
virtual SwUndoId EndUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Closes undo block.
SwSection const * InsertSection(SwSectionData &rNewData, SfxItemSet const *const =nullptr)
Definition: edsect.cxx:34
OUString GetUniqueSectionName(const OUString *pChkStr=nullptr) const
Definition: ndsect.cxx:1351
SwNode & GetNode() const
Definition: ndindex.hxx:119
SwSectionFormat * GetFormat()
Definition: section.hxx:337
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:143
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:314
#define RES_CNTNT
Definition: hintids.hxx:295
void EndAllAction()
Definition: edws.cxx:96
static SwSection * GetCurrSection(const SwPosition &rPos)
Definition: ndsect.cxx:497
size_t GetPos(const SwFormat *p) const
Definition: docary.hxx:165
const SwSection * GetCurrSection() const
Definition: edsect.cxx:70
Array of Undo-history.
Definition: docary.hxx:299
void UpdateSection(size_t const nSect, SwSectionData &, SfxItemSet const *const =nullptr)
Definition: edsect.cxx:155
const SwSection & GetSection() const
Definition: node.hxx:541
SwIndex nContent
Definition: pam.hxx:38
bool CanSpecialInsert() const
a node can be special-inserted (alt-Enter) whenever lcl_SpecialInsertNode finds a suitable position ...
Definition: edsect.cxx:387
void SetAttr(const SfxPoolItem &, SwFormat &)
Set attribute in given format.1y If Undo is enabled, the old values is added to the Undo history...
Definition: docfmt.cxx:448
bool IsStartNode() const
Definition: node.hxx:624
SwSection * InsertSwSection(SwPaM const &rRange, SwSectionData &, std::pair< SwTOXBase const *, sw::RedlineMode > const *pTOXBase, SfxItemSet const *const pAttr, bool const bUpdate=true)
Definition: ndsect.cxx:151
SwDoc * GetDoc() const
Definition: viewsh.hxx:284
const SwSectionFormat & GetSectionFormat(size_t nFormat) const
Definition: edsect.cxx:141
SwPaM * GetNext()
Definition: pam.hxx:264
SwSection * GetAnySection(bool bOutOfTab=false, const Point *pPt=nullptr)
Deliver the responsible area of the columns.
Definition: edsect.cxx:82
bool IsContentNode() const
Definition: node.hxx:628
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
virtual SwUndoId StartUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Opens undo block.
bool IsInsRegionAvailable() const
Definition: edsect.cxx:57
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
const SwPosition * GetPoint() const
Definition: pam.hxx:207
bool IsAnySectionInDoc() const
Definition: edsect.cxx:118
sal_uInt16 GetFullSelectedSectionCount() const
Search inside the cursor selection for full selected sections.
Definition: edsect.cxx:246
SwContentNode * GetContentNode()
Definition: node.hxx:615
SwSection * GetSection()
Definition: sectfrm.hxx:84
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
SwLayoutFrame * GetUpper()
Definition: frame.hxx:656
void DoSpecialInsert()
Special insert: Insert a new text node just before or after a section or table, if the cursor is posi...
Definition: edsect.cxx:395
size_t size() const
Definition: docary.hxx:91
Marks a node in the document model.
Definition: ndindex.hxx:31
bool IsEndNode() const
Definition: node.hxx:632
ring_container GetRingContainer()
SectionType
Definition: section.hxx:46
bool IsProtect() const
Is node in something that is protected (range, frame, table cells ...
Definition: node.cxx:418
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1091
void CallChgLnk()
Definition: crsrsh.cxx:2500
size_t GetSectionFormatCount() const
Definition: edsect.cxx:113
sal_uLong EndOfSectionIndex() const
Definition: node.hxx:677
void UpdateSection(size_t const nSect, SwSectionData &, SfxItemSet const *const =nullptr, bool const bPreventLinkUpdate=false)
Definition: ndsect.cxx:604
SwContentFrame * GetCurrFrame(const bool bCalcFrame=true) const
Get current frame in which the cursor is positioned.
Definition: crsrsh.cxx:2434
OUString GetUniqueSectionName(const OUString *pChkStr=nullptr) const
Definition: edsect.cxx:165
sal_Int32 GetIndex() const
Definition: index.hxx:95
static sal_uInt16 IsInsRegionAvailable(const SwPaM &rRange, const SwNode **ppSttNd=nullptr)
Definition: ndsect.cxx:384
SAL_DLLPRIVATE void SetSectionAttr_(SwSectionFormat &rSectFormat, const SfxItemSet &rSet)
Definition: edsect.cxx:224
virtual bool AppendTextNode(SwPosition &rPos)=0
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:349
bool IsTableNode() const
Definition: node.hxx:640
SwSectionNode * GetSectionNode()
Definition: node.hxx:607
void SetSectionAttr(const SfxItemSet &rSet, SwSectionFormat *pSectFormat=nullptr)
Set attributes.
Definition: edsect.cxx:170
void StartAllAction()
For all views of this document.
Definition: edws.cxx:85
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2062
SwSectionFormats & GetSections()
Definition: doc.hxx:1332
void DelSectionFormat(size_t nFormat)
Definition: edsect.cxx:146
static const SwNode * lcl_SpecialInsertNode(const SwPosition *pCurrentPos)
Find the suitable node for a special insert (alt-enter).
Definition: edsect.cxx:300
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1075
Base class of the Writer document model elements.
Definition: node.hxx:79