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 <edimp.hxx>
29 #include <sectfrm.hxx>
30 #include <cntfrm.hxx>
31 #include <tabfrm.hxx>
32 #include <rootfrm.hxx>
33 
34 SwSection const*
36  SwSectionData & rNewData, SfxItemSet const*const pAttr)
37 {
38  const SwSection* pRet = nullptr;
39  if( !IsTableMode() )
40  {
43 
44  for(const SwPaM& rPaM : GetCursor()->GetRingContainer())
45  {
46  SwSection const*const pNew =
47  GetDoc()->InsertSwSection( rPaM, rNewData, nullptr, pAttr );
48  if( !pRet )
49  pRet = pNew;
50  }
51 
53  EndAllAction();
54  }
55  return pRet;
56 }
57 
59 {
60  if( IsTableMode() )
61  return false;
62  SwPaM* pCursor = GetCursor();
63  if( pCursor->GetNext() != pCursor )
64  return false;
65  if( pCursor->HasMark() )
66  return 0 != SwDoc::IsInsRegionAvailable( *pCursor );
67 
68  return true;
69 }
70 
72 {
73  if( IsTableMode() )
74  return nullptr;
75 
76  return SwDoc::GetCurrSection( *GetCursor()->GetPoint() );
77 }
78 
83 SwSection* SwEditShell::GetAnySection( bool bOutOfTab, const Point* pPt )
84 {
85  SwFrame *pFrame;
86  if ( pPt )
87  {
88  SwPosition aPos( *GetCursor()->GetPoint() );
89  Point aPt( *pPt );
90  GetLayout()->GetCursorOfst( &aPos, aPt );
91  SwContentNode *pNd = aPos.nNode.GetNode().GetContentNode();
92  std::pair<Point, bool> const tmp(*pPt, true);
93  pFrame = pNd->getLayoutFrame(GetLayout(), nullptr, &tmp);
94  }
95  else
96  pFrame = GetCurrFrame( false );
97 
98  if( bOutOfTab && pFrame )
99  pFrame = pFrame->FindTabFrame();
100  if( pFrame && pFrame->IsInSct() )
101  {
102  SwSectionFrame* pSect = pFrame->FindSctFrame();
103  OSL_ENSURE( pSect, "GetAnySection: Where's my Sect?" );
104  if( pSect->IsInFootnote() && pSect->GetUpper()->IsInSct() )
105  {
106  pSect = pSect->GetUpper()->FindSctFrame();
107  OSL_ENSURE( pSect, "GetAnySection: Where's my SectFrame?" );
108  }
109  return pSect->GetSection();
110  }
111  return nullptr;
112 }
113 
115 {
116  return GetDoc()->GetSections().size();
117 }
118 
120 {
121  const SwSectionFormats& rFormats = GetDoc()->GetSections();
122 
123  for( const SwSectionFormat* pFormat : rFormats )
124  {
125  SectionType eTmpType;
126  if( pFormat->IsInNodesArr() &&
127  ( (eTmpType = pFormat->GetSection()->GetType()) != TOX_CONTENT_SECTION
128  && TOX_HEADER_SECTION != eTmpType ) )
129  {
130  return true;
131  }
132  }
133  return false;
134 }
135 
136 size_t SwEditShell::GetSectionFormatPos( const SwSectionFormat& rFormat ) const
137 {
138  SwSectionFormat* pFormat = const_cast<SwSectionFormat*>(&rFormat);
139  return GetDoc()->GetSections().GetPos( pFormat );
140 }
141 
142 const SwSectionFormat& SwEditShell::GetSectionFormat(size_t nFormat) const
143 {
144  return *GetDoc()->GetSections()[ nFormat ];
145 }
146 
147 void SwEditShell::DelSectionFormat(size_t nFormat)
148 {
149  StartAllAction();
150  GetDoc()->DelSectionFormat( GetDoc()->GetSections()[ nFormat ] );
151  // Call the AttrChangeNotify on the UI page.
152  CallChgLnk();
153  EndAllAction();
154 }
155 
156 void SwEditShell::UpdateSection(size_t const nSect,
157  SwSectionData & rNewData, SfxItemSet const*const pAttr)
158 {
159  StartAllAction();
160  GetDoc()->UpdateSection( nSect, rNewData, pAttr );
161  // Call the AttrChangeNotify on the UI page.
162  CallChgLnk();
163  EndAllAction();
164 }
165 
166 OUString SwEditShell::GetUniqueSectionName( const OUString* pChkStr ) const
167 {
168  return GetDoc()->GetUniqueSectionName( pChkStr );
169 }
170 
172  SwSectionFormat* pSectFormat )
173 {
174  if( pSectFormat )
175  SetSectionAttr_( *pSectFormat, rSet );
176  else
177  {
178  // for all section in the selection
179 
180  for(SwPaM& rPaM : GetCursor()->GetRingContainer())
181  {
182  const SwPosition* pStt = rPaM.Start(),
183  * pEnd = rPaM.End();
184 
185  SwSectionNode* pSttSectNd = pStt->nNode.GetNode().FindSectionNode(),
186  * pEndSectNd = pEnd->nNode.GetNode().FindSectionNode();
187 
188  if( pSttSectNd || pEndSectNd )
189  {
190  if( pSttSectNd )
191  SetSectionAttr_( *pSttSectNd->GetSection().GetFormat(),
192  rSet );
193  if( pEndSectNd && pSttSectNd != pEndSectNd )
194  SetSectionAttr_( *pEndSectNd->GetSection().GetFormat(),
195  rSet );
196 
197  if( pSttSectNd && pEndSectNd )
198  {
199  SwNodeIndex aSIdx( pStt->nNode );
200  SwNodeIndex aEIdx( pEnd->nNode );
201  if( pSttSectNd->EndOfSectionIndex() <
202  pEndSectNd->GetIndex() )
203  {
204  aSIdx = pSttSectNd->EndOfSectionIndex() + 1;
205  aEIdx = *pEndSectNd;
206  }
207 
208  while( aSIdx < aEIdx )
209  {
210  if( nullptr != (pSttSectNd = aSIdx.GetNode().GetSectionNode())
211  || ( aSIdx.GetNode().IsEndNode() &&
212  nullptr != ( pSttSectNd = aSIdx.GetNode().
213  StartOfSectionNode()->GetSectionNode())) )
214  SetSectionAttr_( *pSttSectNd->GetSection().GetFormat(),
215  rSet );
216  ++aSIdx;
217  }
218  }
219  }
220 
221  }
222  }
223 }
224 
226  const SfxItemSet& rSet )
227 {
228  StartAllAction();
229  if(SfxItemState::SET == rSet.GetItemState(RES_CNTNT, false))
230  {
231  SfxItemSet aSet(rSet);
232  aSet.ClearItem(RES_CNTNT);
233  GetDoc()->SetAttr( aSet, rSectFormat );
234  }
235  else
236  GetDoc()->SetAttr( rSet, rSectFormat );
237 
238  // Call the AttrChangeNotify on the UI page.
239  CallChgLnk();
240  EndAllAction();
241 }
242 
248 {
249  sal_uInt16 nRet = 0;
250  for(SwPaM& rPaM : GetCursor()->GetRingContainer())
251  {
252 
253  const SwPosition* pStt = rPaM.Start(),
254  * pEnd = rPaM.End();
255  const SwContentNode* pCNd;
256  // check the selection, if Start at Node begin and End at Node end
257  if( pStt->nContent.GetIndex() ||
258  ( nullptr == ( pCNd = pEnd->nNode.GetNode().GetContentNode() )) ||
259  pCNd->Len() != pEnd->nContent.GetIndex() )
260  {
261  nRet = 0;
262  break;
263  }
264 
265 // !!!
266 // what about table at start or end ?
267 // There is no selection possible!
268 // What about only a table inside the section ?
269 // There is only a table selection possible!
270 
271  SwNodeIndex aSIdx( pStt->nNode, -1 ), aEIdx( pEnd->nNode, +1 );
272  if( !aSIdx.GetNode().IsSectionNode() ||
273  !aEIdx.GetNode().IsEndNode() ||
275  {
276  nRet = 0;
277  break;
278  }
279 
280  ++nRet;
281  if( &aSIdx.GetNode() != aEIdx.GetNode().StartOfSectionNode() )
282  ++nRet;
283 
284  }
285  return nRet;
286 }
287 
301 static const SwNode* lcl_SpecialInsertNode(const SwPosition* pCurrentPos)
302 {
303  const SwNode* pReturn = nullptr;
304 
305  // the current position
306  OSL_ENSURE( pCurrentPos != nullptr, "Strange, we have no position!" );
307  const SwNode& rCurrentNode = pCurrentPos->nNode.GetNode();
308 
309  // find innermost section or table. At the end of this scope,
310  // pInntermostNode contain the section/table before/after which we should
311  // insert our empty paragraph, or it will be NULL if none is found.
312  const SwNode* pInnermostNode = nullptr;
313  {
314  const SwNode* pTableNode = rCurrentNode.FindTableNode();
315  const SwNode* pSectionNode = rCurrentNode.FindSectionNode();
316 
317  // find the table/section which is close
318  if( pTableNode == nullptr )
319  pInnermostNode = pSectionNode;
320  else if ( pSectionNode == nullptr )
321  pInnermostNode = pTableNode;
322  else
323  {
324  // compare and choose the larger one
325  pInnermostNode =
326  ( pSectionNode->GetIndex() > pTableNode->GetIndex() )
327  ? pSectionNode : pTableNode;
328  }
329  }
330 
331  // The previous version had a check to skip empty read-only sections. Those
332  // shouldn't occur, so we only need to check whether our pInnermostNode is
333  // inside a protected area.
334 
335  // Now, pInnermostNode is NULL or the innermost section or table node.
336  if( (pInnermostNode != nullptr) && !pInnermostNode->IsProtect() )
337  {
338  OSL_ENSURE( pInnermostNode->IsTableNode() ||
339  pInnermostNode->IsSectionNode(), "wrong node found" );
340  OSL_ENSURE( ( pInnermostNode->GetIndex() <= rCurrentNode.GetIndex() )&&
341  ( pInnermostNode->EndOfSectionNode()->GetIndex() >=
342  rCurrentNode.GetIndex() ), "wrong node found" );
343 
344  // we now need to find the possible start/end positions
345 
346  // we found a start if
347  // - we're at or just before a start node
348  // - there are only start nodes between the current and pInnermostNode
349  SwNodeIndex aBegin( pCurrentPos->nNode );
350  if( rCurrentNode.IsContentNode() &&
351  (pCurrentPos->nContent.GetIndex() == 0))
352  --aBegin;
353  while( (aBegin != pInnermostNode->GetIndex()) &&
354  aBegin.GetNode().IsStartNode() )
355  --aBegin;
356  bool bStart = ( aBegin == pInnermostNode->GetIndex() );
357 
358  // we found an end if
359  // - we're at or just before an end node
360  // - there are only end nodes between the current node and
361  // pInnermostNode's end node
362  SwNodeIndex aEnd( pCurrentPos->nNode );
363  if( rCurrentNode.IsContentNode() &&
364  ( pCurrentPos->nContent.GetIndex() ==
365  rCurrentNode.GetContentNode()->Len() ) )
366  ++aEnd;
367  while( (aEnd != pInnermostNode->EndOfSectionNode()->GetIndex()) &&
368  aEnd.GetNode().IsEndNode() )
369  ++aEnd;
370  bool bEnd = ( aEnd == pInnermostNode->EndOfSectionNode()->GetIndex() );
371 
372  // evaluate result: if both start + end, end is preferred
373  if( bEnd )
374  pReturn = pInnermostNode->EndOfSectionNode();
375  else if ( bStart )
376  pReturn = pInnermostNode;
377  }
378 
379  OSL_ENSURE( ( pReturn == nullptr ) || pReturn->IsStartNode() ||
380  pReturn->IsEndNode(),
381  "SpecialInsertNode failed" );
382  return pReturn;
383 }
384 
389 {
390  return nullptr != lcl_SpecialInsertNode( GetCursor()->GetPoint() );
391 }
392 
397 {
398  // get current node
399  SwPosition* pCursorPos = GetCursor()->GetPoint();
400  const SwNode* pInsertNode = lcl_SpecialInsertNode( pCursorPos );
401  if( pInsertNode != nullptr )
402  {
403  StartAllAction();
404 
405  // adjust insert position to insert before start nodes and after end
406  // nodes
407  SwNodeIndex aInsertIndex( *pInsertNode,
408  pInsertNode->IsStartNode() ? -1 : 0 );
409  SwPosition aInsertPos( aInsertIndex );
410 
411  // insert a new text node, and set the cursor
413  *pCursorPos = aInsertPos;
414 
415  // call AttrChangeNotify for the UI
416  CallChgLnk();
417 
418  EndAllAction();
419  }
420 }
421 
422 /* 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:420
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:136
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:184
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:35
OUString GetUniqueSectionName(const OUString *pChkStr=nullptr) const
Definition: ndsect.cxx:1351
SwNode & GetNode() const
Definition: ndindex.hxx:119
SwSectionFormat * GetFormat()
Definition: section.hxx:336
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:143
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:314
#define RES_CNTNT
Definition: hintids.hxx:202
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:71
Array of Undo-history.
Definition: docary.hxx:299
void UpdateSection(size_t const nSect, SwSectionData &, SfxItemSet const *const =nullptr)
Definition: edsect.cxx:156
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:388
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:142
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:83
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:58
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:119
sal_uInt16 GetFullSelectedSectionCount() const
Search inside the cursor selection for full selected sections.
Definition: edsect.cxx:247
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:396
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:2492
size_t GetSectionFormatCount() const
Definition: edsect.cxx:114
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:2426
OUString GetUniqueSectionName(const OUString *pChkStr=nullptr) const
Definition: edsect.cxx:166
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:225
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:171
void StartAllAction()
For all views of this document.
Definition: edws.cxx:85
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2075
SwSectionFormats & GetSections()
Definition: doc.hxx:1328
void DelSectionFormat(size_t nFormat)
Definition: edsect.cxx:147
static const SwNode * lcl_SpecialInsertNode(const SwPosition *pCurrentPos)
Find the suitable node for a special insert (alt-enter).
Definition: edsect.cxx:301
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1075
Base class of the Writer document model elements.
Definition: node.hxx:79