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  aOld(_aOld, _pDoc), aNew(_aNew, _pDoc), pDoc(_pDoc), bExchange( false )
40 {
41  OSL_ENSURE(nullptr != 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 = aOld.m_PageDesc;
51  SwPageDesc &rNewDesc = 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  bExchange = ( aOld.GetName() == 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  bExchange = false;
68  if( rOldFoot.IsActive() && ( rOldDesc.IsFooterShared() != rNewDesc.IsFooterShared() ) )
69  bExchange = false;
70  if( ( rOldHead.IsActive() || rOldFoot.IsActive() ) && ( rOldDesc.IsFirstShared() != rNewDesc.IsFirstShared() ) )
71  bExchange = false;
72  if( bExchange )
73  {
74  if( rNewHead.IsActive() )
75  {
76  SwFrameFormat* pFormat = new SwFrameFormat( *rNewHead.GetHeaderFormat() );
77  // The Ctor of this object will remove the duplicate!
78  SwFormatHeader aFormatHeader(pFormat);
79  (void)aFormatHeader;
80  if (!rNewDesc.IsHeaderShared())
81  {
82  pFormat = new SwFrameFormat( *rNewDesc.GetLeft().GetHeader().GetHeaderFormat() );
83  // The Ctor of this object will remove the duplicate!
84  SwFormatHeader aLeftHeader(pFormat);
85  (void)aLeftHeader;
86  }
87  if (!rNewDesc.IsFirstShared())
88  {
89  pFormat = new SwFrameFormat( *rNewDesc.GetFirstMaster().GetHeader().GetHeaderFormat() );
90  // The Ctor of this object will remove the duplicate!
91  SwFormatHeader aFirstHeader(pFormat);
92  (void)aFirstHeader;
93  }
94  }
95  // Same procedure for footers...
96  if( rNewFoot.IsActive() )
97  {
98  SwFrameFormat* pFormat = new SwFrameFormat( *rNewFoot.GetFooterFormat() );
99  // The Ctor of this object will remove the duplicate!
100  SwFormatFooter aFormatFooter(pFormat);
101  (void)aFormatFooter;
102  if (!rNewDesc.IsFooterShared())
103  {
104  pFormat = new SwFrameFormat( *rNewDesc.GetLeft().GetFooter().GetFooterFormat() );
105  // The Ctor of this object will remove the duplicate!
106  SwFormatFooter aLeftFooter(pFormat);
107  (void)aLeftFooter;
108  }
109  if (!rNewDesc.IsFirstShared())
110  {
111  pFormat = new SwFrameFormat( *rNewDesc.GetFirstMaster().GetFooter().GetFooterFormat() );
112  // The Ctor of this object will remove the duplicate!
113  SwFormatFooter aFirstFooter(pFormat);
114  (void)aFirstFooter;
115  }
116  }
117 
118  // After this exchange method the old page description will point to zero,
119  // the new one will point to the node position of the original content nodes.
121  }
122 }
123 
125 {
126 }
127 
129 {
130  OSL_ENSURE( 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 SfxPoolItem* pItem;
138  rDest.GetMaster().GetAttrSet().GetItemState( RES_HEADER, false, &pItem );
139  std::unique_ptr<SfxPoolItem> pNewItem(pItem->Clone());
140  SwFrameFormat* pNewFormat = static_cast<SwFormatHeader*>(pNewItem.get())->GetHeaderFormat();
141  pNewFormat->SetFormatAttr( rSourceHead.GetHeaderFormat()->GetContent() );
142 
143  // Let the source page description point to zero node position,
144  // it loses the responsible and can be destroyed without removing the content nodes.
145  rSource.GetMaster().GetAttrSet().GetItemState( RES_HEADER, false, &pItem );
146  pNewItem.reset(pItem->Clone());
147  pNewFormat = static_cast<SwFormatHeader*>(pNewItem.get())->GetHeaderFormat();
148  pNewFormat->SetFormatAttr( SwFormatContent() );
149 
150  if( !rDest.IsHeaderShared() )
151  {
152  // Same procedure for unshared header...
153  const SwFormatHeader& rSourceLeftHead = rSource.GetLeft().GetHeader();
154  rDest.GetLeft().GetAttrSet().GetItemState( RES_HEADER, false, &pItem );
155  pNewItem.reset(pItem->Clone());
156  pNewFormat = static_cast<SwFormatHeader*>(pNewItem.get())->GetHeaderFormat();
157  pNewFormat->SetFormatAttr( rSourceLeftHead.GetHeaderFormat()->GetContent() );
158  rSource.GetLeft().GetAttrSet().GetItemState( RES_HEADER, false, &pItem );
159  pNewItem.reset(pItem->Clone());
160  pNewFormat = static_cast<SwFormatHeader*>(pNewItem.get())->GetHeaderFormat();
161  pNewFormat->SetFormatAttr( SwFormatContent() );
162  }
163  if (!rDest.IsFirstShared())
164  {
165  // Same procedure for unshared header...
166  const SwFormatHeader& rSourceFirstMasterHead = rSource.GetFirstMaster().GetHeader();
167  rDest.GetFirstMaster().GetAttrSet().GetItemState( RES_HEADER, false, &pItem );
168  pNewItem.reset(pItem->Clone());
169  pNewFormat = static_cast<SwFormatHeader*>(pNewItem.get())->GetHeaderFormat();
170  pNewFormat->SetFormatAttr( rSourceFirstMasterHead.GetHeaderFormat()->GetContent() );
171  rSource.GetFirstMaster().GetAttrSet().GetItemState( RES_HEADER, false, &pItem );
172  pNewItem.reset(pItem->Clone());
173  pNewFormat = static_cast<SwFormatHeader*>(pNewItem.get())->GetHeaderFormat();
174  pNewFormat->SetFormatAttr( SwFormatContent() );
175  }
176  }
177  // Same procedure for footers...
178  const SwFormatFooter& rDestFoot = rDest.GetMaster().GetFooter();
179  const SwFormatFooter& rSourceFoot = rSource.GetMaster().GetFooter();
180  if( !rDestFoot.IsActive() )
181  return;
182 
183  const SfxPoolItem* pItem;
184  rDest.GetMaster().GetAttrSet().GetItemState( RES_FOOTER, false, &pItem );
185  std::unique_ptr<SfxPoolItem> pNewItem(pItem->Clone());
186  SwFrameFormat *pNewFormat = static_cast<SwFormatFooter*>(pNewItem.get())->GetFooterFormat();
187  pNewFormat->SetFormatAttr( rSourceFoot.GetFooterFormat()->GetContent() );
188 
189  rSource.GetMaster().GetAttrSet().GetItemState( RES_FOOTER, false, &pItem );
190  pNewItem.reset(pItem->Clone());
191  pNewFormat = static_cast<SwFormatFooter*>(pNewItem.get())->GetFooterFormat();
192  pNewFormat->SetFormatAttr( SwFormatContent() );
193 
194  if( !rDest.IsFooterShared() )
195  {
196  const SwFormatFooter& rSourceLeftFoot = rSource.GetLeft().GetFooter();
197  rDest.GetLeft().GetAttrSet().GetItemState( RES_FOOTER, false, &pItem );
198  pNewItem.reset(pItem->Clone());
199  pNewFormat = static_cast<SwFormatFooter*>(pNewItem.get())->GetFooterFormat();
200  pNewFormat->SetFormatAttr( rSourceLeftFoot.GetFooterFormat()->GetContent() );
201  rSource.GetLeft().GetAttrSet().GetItemState( RES_FOOTER, false, &pItem );
202  pNewItem.reset(pItem->Clone());
203  pNewFormat = static_cast<SwFormatFooter*>(pNewItem.get())->GetFooterFormat();
204  pNewFormat->SetFormatAttr( SwFormatContent() );
205  }
206  if (rDest.IsFirstShared())
207  return;
208 
209  const SwFormatFooter& rSourceFirstMasterFoot = rSource.GetFirstMaster().GetFooter();
210  rDest.GetFirstMaster().GetAttrSet().GetItemState( RES_FOOTER, false, &pItem );
211  pNewItem.reset(pItem->Clone());
212  pNewFormat = static_cast<SwFormatFooter*>(pNewItem.get())->GetFooterFormat();
213  pNewFormat->SetFormatAttr( rSourceFirstMasterFoot.GetFooterFormat()->GetContent() );
214  rSource.GetFirstMaster().GetAttrSet().GetItemState( RES_FOOTER, false, &pItem );
215  pNewItem.reset(pItem->Clone());
216  pNewFormat = static_cast<SwFormatFooter*>(pNewItem.get())->GetFooterFormat();
217  pNewFormat->SetFormatAttr( SwFormatContent() );
218 }
219 
221 {
222  // Move (header/footer)content node responsibility from new page descriptor to old one again.
223  if( bExchange )
226 }
227 
229 {
230  // Move (header/footer)content node responsibility from old page descriptor to new one again.
231  if( bExchange )
234 }
235 
237 {
238  SwRewriter aResult;
239 
240  aResult.AddRule(UndoArg1, aOld.GetName());
241  aResult.AddRule(UndoArg2, SwResId(STR_YIELDS));
242  aResult.AddRule(UndoArg3, aNew.GetName());
243 
244  return aResult;
245 }
246 
248  SwDoc * _pDoc)
249  : SwUndo(SwUndoId::CREATE_PAGEDESC, _pDoc), pDesc(pNew), aNew(*pNew, _pDoc),
250  pDoc(_pDoc)
251 {
252  OSL_ENSURE(nullptr != pDoc, "no document?");
253 }
254 
256 {
257 }
258 
260 {
261  if (pDesc)
262  {
263  aNew = *pDesc;
264  pDesc = nullptr;
265  }
266 
267  pDoc->DelPageDesc(aNew.GetName(), true);
268 }
269 
271 {
272  SwPageDesc aPageDesc = aNew;
273  pDoc->MakePageDesc(aNew.GetName(), &aPageDesc, false, true);
274 }
275 
277 {
278  DoImpl();
279 }
280 
282 {
283  ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
284  DoImpl();
285 }
286 
288 {
289  SwRewriter aResult;
290 
291  if (pDesc)
292  aResult.AddRule(UndoArg1, pDesc->GetName());
293  else
294  aResult.AddRule(UndoArg1, aNew.GetName());
295 
296  return aResult;
297 }
298 
300  SwDoc * _pDoc)
301  : SwUndo(SwUndoId::DELETE_PAGEDESC, _pDoc), aOld(_aOld, _pDoc), pDoc(_pDoc)
302 {
303  OSL_ENSURE(nullptr != pDoc, "no document?");
304 }
305 
307 {
308 }
309 
311 {
312  SwPageDesc aPageDesc = aOld;
313  pDoc->MakePageDesc(aOld.GetName(), &aPageDesc, false, true);
314 }
315 
317 {
318  pDoc->DelPageDesc(aOld.GetName(), true);
319 }
320 
322 {
323  DoImpl();
324 }
325 
327 {
328  ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
329  DoImpl();
330 }
331 
333 {
334  SwRewriter aResult;
335 
336  aResult.AddRule(UndoArg1, aOld.GetName());
337 
338  return aResult;
339 }
340 
341 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwUndoPageDesc(const SwPageDesc &aOld, const SwPageDesc &aNew, SwDoc *pDoc)
#define RES_HEADER
Definition: hintids.hxx:203
virtual ~SwUndoPageDesc() override
SwFrameFormat & GetLeft()
Definition: pagedesc.hxx:218
const SwFormatHeader & GetHeader(bool=true) const
Definition: fmthdft.hxx:97
SwUndoId
Definition: swundo.hxx:29
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const =0
void DelPageDesc(const OUString &rName, bool bBroadcast=false)
Definition: docdesc.cxx:845
virtual void RepeatImpl(::sw::RepeatContext &) override
virtual void RepeatImpl(::sw::RepeatContext &) override
SwFrameFormat & GetFirstMaster()
Definition: pagedesc.hxx:219
Definition: doc.hxx:185
sal_uInt16 sal_Char sal_Char * pDesc
SwPageDescExt aOld
Content, content of frame (header, footer, fly).
Definition: fmtcntnt.hxx:31
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:143
virtual void RedoImpl(::sw::UndoRedoContext &) override
virtual void RedoImpl(::sw::UndoRedoContext &) override
virtual void RedoImpl(::sw::UndoRedoContext &) override
bool IsActive() const
Definition: fmthdft.hxx:89
const SwPageDesc * pDesc
virtual ~SwUndoPageDescCreate() override
Footer, for pageformats Client of FrameFormat describing the footer.
Definition: fmthdft.hxx:64
virtual void UndoImpl(::sw::UndoRedoContext &) override
SwPageDesc m_PageDesc
Definition: pagedesc.hxx:358
SwPageDescExt aNew
bool IsHeaderShared() const
Definition: pagedesc.hxx:298
virtual SwRewriter GetRewriter() const override
Returns the rewriter for this object.
Style of a layout element.
Definition: frmfmt.hxx:57
virtual void UndoImpl(::sw::UndoRedoContext &) override
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
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:639
void AddRule(SwUndoArg eWhat, const OUString &rWith)
Definition: SwRewriter.cxx:29
const SwFormatFooter & GetFooter(bool=true) const
Definition: fmthdft.hxx:99
void ChgPageDesc(const OUString &rName, const SwPageDesc &)
Definition: docdesc.cxx:853
bool IsFooterShared() const
Definition: pagedesc.hxx:302
SwUndoPageDescCreate(const SwPageDesc *pNew, SwDoc *pDoc)
OUString SwResId(const char *pId)
Definition: swmodule.cxx:190
void ExchangeContentNodes(SwPageDesc &rSource, SwPageDesc &rDest)
const SwPageDesc * GetFollow() const
Definition: pagedesc.hxx:246
#define RES_FOOTER
Definition: hintids.hxx:204
SwFrameFormat & GetMaster()
Definition: pagedesc.hxx:217
OUString const & GetName() const
Definition: pagedesc.cxx:528
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
SwPageDescExt const aOld
virtual void UndoImpl(::sw::UndoRedoContext &) override
bool IsFirstShared() const
Definition: pagedesc.cxx:377
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:116
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
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo