LibreOffice Module sw (master)  1
SwUndoPageDesc.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 <doc.hxx>
21 #include <IDocumentUndoRedo.hxx>
22 #include <swundo.hxx>
23 #include <pagedesc.hxx>
24 #include <SwUndoPageDesc.hxx>
25 #include <SwRewriter.hxx>
26 #include <undobj.hxx>
27 #include <strings.hrc>
28 #include <fmtcntnt.hxx>
29 #include <fmthdft.hxx>
30 #include <osl/diagnose.h>
31 
33  const SwPageDesc & _aNew,
34  SwDoc * _pDoc)
35  : SwUndo( _aOld.GetName() != _aNew.GetName() ?
38  _pDoc ),
39  m_aOld(_aOld, _pDoc), m_aNew(_aNew, _pDoc), m_pDoc(_pDoc), m_bExchange( false )
40 {
41  OSL_ENSURE(nullptr != m_pDoc, "no document?");
42 
43  /*
44  The page description changes.
45  If there are no header/footer content changes like header on/off or change from shared content
46  to unshared etc., there is no reason to duplicate the content nodes (Crash i55547)
47  But this happens, this Undo Ctor will destroy the unnecessary duplicate and manipulate the
48  content pointer of the both page descriptions.
49  */
50  SwPageDesc &rOldDesc = m_aOld.m_PageDesc;
51  SwPageDesc &rNewDesc = m_aNew.m_PageDesc;
52  const SwFormatHeader& rOldHead = rOldDesc.GetMaster().GetHeader();
53  const SwFormatHeader& rNewHead = rNewDesc.GetMaster().GetHeader();
54  const SwFormatFooter& rOldFoot = rOldDesc.GetMaster().GetFooter();
55  const SwFormatFooter& rNewFoot = rNewDesc.GetMaster().GetFooter();
56  /* bExchange must not be set, if the old page descriptor will stay active.
57  Two known situations:
58  #i67735#: renaming a page descriptor
59  #i67334#: changing the follow style
60  If header/footer will be activated or deactivated, this undo will not work.
61  */
62  m_bExchange = ( m_aOld.GetName() == m_aNew.GetName() ) &&
63  ( _aOld.GetFollow() == _aNew.GetFollow() ) &&
64  ( rOldHead.IsActive() == rNewHead.IsActive() ) &&
65  ( rOldFoot.IsActive() == rNewFoot.IsActive() );
66  if( rOldHead.IsActive() && ( rOldDesc.IsHeaderShared() != rNewDesc.IsHeaderShared() ) )
67  m_bExchange = false;
68  if( rOldFoot.IsActive() && ( rOldDesc.IsFooterShared() != rNewDesc.IsFooterShared() ) )
69  m_bExchange = false;
70  if( ( rOldHead.IsActive() || rOldFoot.IsActive() ) && ( rOldDesc.IsFirstShared() != rNewDesc.IsFirstShared() ) )
71  m_bExchange = false;
72  if( !m_bExchange )
73  return;
74 
75  if( rNewHead.IsActive() )
76  {
77  SwFrameFormat* pFormat = new SwFrameFormat( *rNewHead.GetHeaderFormat() );
78  // The Ctor of this object will remove the duplicate!
79  SwFormatHeader aFormatHeader(pFormat);
80  (void)aFormatHeader;
81  if (!rNewDesc.IsHeaderShared())
82  {
83  pFormat = new SwFrameFormat( *rNewDesc.GetLeft().GetHeader().GetHeaderFormat() );
84  // The Ctor of this object will remove the duplicate!
85  SwFormatHeader aLeftHeader(pFormat);
86  (void)aLeftHeader;
87  }
88  if (!rNewDesc.IsFirstShared())
89  {
90  pFormat = new SwFrameFormat( *rNewDesc.GetFirstMaster().GetHeader().GetHeaderFormat() );
91  // The Ctor of this object will remove the duplicate!
92  SwFormatHeader aFirstHeader(pFormat);
93  (void)aFirstHeader;
94  }
95  }
96  // Same procedure for footers...
97  if( rNewFoot.IsActive() )
98  {
99  SwFrameFormat* pFormat = new SwFrameFormat( *rNewFoot.GetFooterFormat() );
100  // The Ctor of this object will remove the duplicate!
101  SwFormatFooter aFormatFooter(pFormat);
102  (void)aFormatFooter;
103  if (!rNewDesc.IsFooterShared())
104  {
105  pFormat = new SwFrameFormat( *rNewDesc.GetLeft().GetFooter().GetFooterFormat() );
106  // The Ctor of this object will remove the duplicate!
107  SwFormatFooter aLeftFooter(pFormat);
108  (void)aLeftFooter;
109  }
110  if (!rNewDesc.IsFirstShared())
111  {
112  pFormat = new SwFrameFormat( *rNewDesc.GetFirstMaster().GetFooter().GetFooterFormat() );
113  // The Ctor of this object will remove the duplicate!
114  SwFormatFooter aFirstFooter(pFormat);
115  (void)aFirstFooter;
116  }
117  }
118 
119  // After this exchange method the old page description will point to zero,
120  // the new one will point to the node position of the original content nodes.
122 }
123 
125 {
126 }
127 
129 {
130  OSL_ENSURE( m_bExchange, "You shouldn't do that." );
131  const SwFormatHeader& rDestHead = rDest.GetMaster().GetHeader();
132  const SwFormatHeader& rSourceHead = rSource.GetMaster().GetHeader();
133  if( rDestHead.IsActive() )
134  {
135  // Let the destination page description point to the source node position,
136  // from now on this descriptor is responsible for the content nodes!
137  const SwFormatHeader* pItem = rDest.GetMaster().GetAttrSet().GetItemIfSet( RES_HEADER, false );
138  std::unique_ptr<SwFormatHeader> pNewItem(pItem->Clone());
139  SwFrameFormat* pNewFormat = pNewItem->GetHeaderFormat();
140  pNewFormat->SetFormatAttr( rSourceHead.GetHeaderFormat()->GetContent() );
141 
142  // Let the source page description point to zero node position,
143  // it loses the responsible and can be destroyed without removing the content nodes.
144  pItem = rSource.GetMaster().GetAttrSet().GetItemIfSet( RES_HEADER, false );
145  pNewItem.reset(pItem->Clone());
146  pNewFormat = pNewItem->GetHeaderFormat();
147  pNewFormat->SetFormatAttr( SwFormatContent() );
148 
149  if( !rDest.IsHeaderShared() )
150  {
151  // Same procedure for unshared header...
152  const SwFormatHeader& rSourceLeftHead = rSource.GetLeft().GetHeader();
153  pItem = rDest.GetLeft().GetAttrSet().GetItemIfSet( RES_HEADER, false );
154  pNewItem.reset(pItem->Clone());
155  pNewFormat = pNewItem->GetHeaderFormat();
156  pNewFormat->SetFormatAttr( rSourceLeftHead.GetHeaderFormat()->GetContent() );
157  pItem = rSource.GetLeft().GetAttrSet().GetItemIfSet( RES_HEADER, false );
158  pNewItem.reset(pItem->Clone());
159  pNewFormat = pNewItem->GetHeaderFormat();
160  pNewFormat->SetFormatAttr( SwFormatContent() );
161  }
162  if (!rDest.IsFirstShared())
163  {
164  // Same procedure for unshared header...
165  const SwFormatHeader& rSourceFirstMasterHead = rSource.GetFirstMaster().GetHeader();
166  pItem = rDest.GetFirstMaster().GetAttrSet().GetItemIfSet( RES_HEADER, false );
167  pNewItem.reset(pItem->Clone());
168  pNewFormat = pNewItem->GetHeaderFormat();
169  pNewFormat->SetFormatAttr( rSourceFirstMasterHead.GetHeaderFormat()->GetContent() );
170  pItem = rSource.GetFirstMaster().GetAttrSet().GetItemIfSet( RES_HEADER, false );
171  pNewItem.reset(pItem->Clone());
172  pNewFormat = pNewItem->GetHeaderFormat();
173  pNewFormat->SetFormatAttr( SwFormatContent() );
174  }
175  }
176  // Same procedure for footers...
177  const SwFormatFooter& rDestFoot = rDest.GetMaster().GetFooter();
178  const SwFormatFooter& rSourceFoot = rSource.GetMaster().GetFooter();
179  if( !rDestFoot.IsActive() )
180  return;
181 
182  const SwFormatFooter* pItem;
183  pItem = rDest.GetMaster().GetAttrSet().GetItemIfSet( RES_FOOTER, false );
184  std::unique_ptr<SwFormatFooter> pNewItem(pItem->Clone());
185  SwFrameFormat *pNewFormat = pNewItem->GetFooterFormat();
186  pNewFormat->SetFormatAttr( rSourceFoot.GetFooterFormat()->GetContent() );
187 
188  pItem = rSource.GetMaster().GetAttrSet().GetItemIfSet( RES_FOOTER, false );
189  pNewItem.reset(pItem->Clone());
190  pNewFormat = pNewItem->GetFooterFormat();
191  pNewFormat->SetFormatAttr( SwFormatContent() );
192 
193  if( !rDest.IsFooterShared() )
194  {
195  const SwFormatFooter& rSourceLeftFoot = rSource.GetLeft().GetFooter();
196  pItem = rDest.GetLeft().GetAttrSet().GetItemIfSet( RES_FOOTER, false );
197  pNewItem.reset(pItem->Clone());
198  pNewFormat = pNewItem->GetFooterFormat();
199  pNewFormat->SetFormatAttr( rSourceLeftFoot.GetFooterFormat()->GetContent() );
200  pItem = rSource.GetLeft().GetAttrSet().GetItemIfSet( RES_FOOTER, false );
201  pNewItem.reset(pItem->Clone());
202  pNewFormat = pNewItem->GetFooterFormat();
203  pNewFormat->SetFormatAttr( SwFormatContent() );
204  }
205  if (rDest.IsFirstShared())
206  return;
207 
208  const SwFormatFooter& rSourceFirstMasterFoot = rSource.GetFirstMaster().GetFooter();
209  pItem = rDest.GetFirstMaster().GetAttrSet().GetItemIfSet( RES_FOOTER, false );
210  pNewItem.reset(pItem->Clone());
211  pNewFormat = pNewItem->GetFooterFormat();
212  pNewFormat->SetFormatAttr( rSourceFirstMasterFoot.GetFooterFormat()->GetContent() );
213  pItem = rSource.GetFirstMaster().GetAttrSet().GetItemIfSet( RES_FOOTER, false );
214  pNewItem.reset(pItem->Clone());
215  pNewFormat = pNewItem->GetFooterFormat();
216  pNewFormat->SetFormatAttr( SwFormatContent() );
217 }
218 
220 {
221  // Move (header/footer)content node responsibility from new page descriptor to old one again.
222  if( m_bExchange )
225 }
226 
228 {
229  // Move (header/footer)content node responsibility from old page descriptor to new one again.
230  if( m_bExchange )
233 }
234 
236 {
237  SwRewriter aResult;
238 
239  aResult.AddRule(UndoArg1, m_aOld.GetName());
240  aResult.AddRule(UndoArg2, SwResId(STR_YIELDS));
241  aResult.AddRule(UndoArg3, m_aNew.GetName());
242 
243  return aResult;
244 }
245 
247  SwDoc * _pDoc)
248  : SwUndo(SwUndoId::CREATE_PAGEDESC, _pDoc), m_pDesc(pNew), m_aNew(*pNew, _pDoc),
249  m_pDoc(_pDoc)
250 {
251  OSL_ENSURE(nullptr != m_pDoc, "no document?");
252 }
253 
255 {
256 }
257 
259 {
260  if (m_pDesc)
261  {
262  m_aNew = *m_pDesc;
263  m_pDesc = nullptr;
264  }
265 
266  m_pDoc->DelPageDesc(m_aNew.GetName(), true);
267 }
268 
270 {
271  SwPageDesc aPageDesc = m_aNew;
272  m_pDoc->MakePageDesc(m_aNew.GetName(), &aPageDesc, false, true);
273 }
274 
276 {
277  DoImpl();
278 }
279 
281 {
282  ::sw::UndoGuard const undoGuard(m_pDoc->GetIDocumentUndoRedo());
283  DoImpl();
284 }
285 
287 {
288  SwRewriter aResult;
289 
290  if (m_pDesc)
291  aResult.AddRule(UndoArg1, m_pDesc->GetName());
292  else
293  aResult.AddRule(UndoArg1, m_aNew.GetName());
294 
295  return aResult;
296 }
297 
299  SwDoc * _pDoc)
300  : SwUndo(SwUndoId::DELETE_PAGEDESC, _pDoc), m_aOld(_aOld, _pDoc), m_pDoc(_pDoc)
301 {
302  OSL_ENSURE(nullptr != m_pDoc, "no document?");
303 }
304 
306 {
307 }
308 
310 {
311  SwPageDesc aPageDesc = m_aOld;
312  m_pDoc->MakePageDesc(m_aOld.GetName(), &aPageDesc, false, true);
313 }
314 
316 {
317  m_pDoc->DelPageDesc(m_aOld.GetName(), true);
318 }
319 
321 {
322  DoImpl();
323 }
324 
326 {
327  ::sw::UndoGuard const undoGuard(m_pDoc->GetIDocumentUndoRedo());
328  DoImpl();
329 }
330 
332 {
333  SwRewriter aResult;
334 
335  aResult.AddRule(UndoArg1, m_aOld.GetName());
336 
337  return aResult;
338 }
339 
340 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwUndoPageDesc(const SwPageDesc &aOld, const SwPageDesc &aNew, SwDoc *pDoc)
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
virtual SwFormatFooter * Clone(SfxItemPool *pPool=nullptr) const override
Definition: atrfrm.cxx:573
virtual ~SwUndoPageDesc() override
SwFrameFormat & GetLeft()
Definition: pagedesc.hxx:239
const SwFormatHeader & GetHeader(bool=true) const
Definition: fmthdft.hxx:97
SwUndoId
Definition: swundo.hxx:29
constexpr TypedWhichId< SwFormatHeader > RES_HEADER(96)
void DelPageDesc(const OUString &rName, bool bBroadcast=false)
Definition: docdesc.cxx:964
virtual void RepeatImpl(::sw::RepeatContext &) override
virtual void RepeatImpl(::sw::RepeatContext &) override
SwFrameFormat & GetFirstMaster()
Definition: pagedesc.hxx:240
Definition: doc.hxx:187
Content, content of frame (header, footer, fly).
Definition: fmtcntnt.hxx:31
virtual SwFormatHeader * Clone(SfxItemPool *pPool=nullptr) const override
Definition: atrfrm.cxx:523
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:144
virtual void RedoImpl(::sw::UndoRedoContext &) override
virtual void RedoImpl(::sw::UndoRedoContext &) override
virtual void RedoImpl(::sw::UndoRedoContext &) override
const OUString & GetName() const
Definition: pagedesc.hxx:196
bool IsActive() const
Definition: fmthdft.hxx:89
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:164
const SwPageDesc * m_pDesc
virtual ~SwUndoPageDescCreate() override
Footer, for pageformats Client of FrameFormat describing the footer.
Definition: fmthdft.hxx:64
virtual void UndoImpl(::sw::UndoRedoContext &) override
virtual OUString GetName() const override
SwPageDescExt m_aNew
SwPageDesc m_PageDesc
Definition: pagedesc.hxx:379
bool IsHeaderShared() const
Definition: pagedesc.hxx:319
virtual SwRewriter GetRewriter() const override
Returns the rewriter for this object.
Style of a layout element.
Definition: frmfmt.hxx:59
virtual void UndoImpl(::sw::UndoRedoContext &) override
const SwFrameFormat * GetFooterFormat() const
Definition: fmthdft.hxx:85
SwUndoPageDescDelete(const SwPageDesc &aOld, SwDoc *pDoc)
SwPageDesc * MakePageDesc(const OUString &rName, const SwPageDesc *pCpy=nullptr, bool bRegardLanguage=true, bool bBroadcast=false)
Definition: docdesc.cxx:759
void AddRule(SwUndoArg eWhat, const OUString &rWith)
Definition: SwRewriter.cxx:25
const SwFormatFooter & GetFooter(bool=true) const
Definition: fmthdft.hxx:99
void ChgPageDesc(const OUString &rName, const SwPageDesc &)
Definition: docdesc.cxx:972
bool IsFooterShared() const
Definition: pagedesc.hxx:323
SwUndoPageDescCreate(const SwPageDesc *pNew, SwDoc *pDoc)
void ExchangeContentNodes(SwPageDesc &rSource, SwPageDesc &rDest)
SwPageDescExt m_aOld
const SwPageDesc * GetFollow() const
Definition: pagedesc.hxx:267
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:448
SwFrameFormat & GetMaster()
Definition: pagedesc.hxx:238
OUString const & GetName() const
Definition: pagedesc.cxx:697
Header, for PageFormats Client of FrameFormat describing the header.
Definition: fmthdft.hxx:33
virtual SwRewriter GetRewriter() const override
Returns the rewriter for this object.
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
virtual void UndoImpl(::sw::UndoRedoContext &) override
constexpr TypedWhichId< SwFormatFooter > RES_FOOTER(97)
bool IsFirstShared() const
Definition: pagedesc.cxx:396
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
bool IsActive() const
Definition: fmthdft.hxx:58
virtual ~SwUndoPageDescDelete() override
virtual SwRewriter GetRewriter() const override
Returns the rewriter for this object.
const SwFrameFormat * GetHeaderFormat() const
Definition: fmthdft.hxx:54
bool m_bDetectedRangeSegmentation false
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo