xref: /trunk/main/svx/source/table/tableundo.cxx (revision a893be29343ee97512d484e6e8fefa91df2b44cb)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 #include "svx/sdr/properties/textproperties.hxx"
28 #include "editeng/outlobj.hxx"
29 
30 #include "cell.hxx"
31 #include "tableundo.hxx"
32 #include "svx/svdotable.hxx"
33 #include "tablerow.hxx"
34 #include "tablecolumn.hxx"
35 
36 
37 // -----------------------------------------------------------------------------
38 
39 using ::rtl::OUString;
40 using namespace ::com::sun::star::uno;
41 using namespace ::com::sun::star::table;
42 
43 // -----------------------------------------------------------------------------
44 
45 namespace sdr { namespace table {
46 
47 CellUndo::CellUndo( const SdrObjectWeakRef& xObjRef, const CellRef& xCell )
48 : SdrUndoAction( *xCell->GetModel() )
49 , mxObjRef( xObjRef )
50 , mxCell( xCell )
51 , mbUndo( true )
52 {
53     if( mxCell.is() && mxObjRef.is() )
54     {
55         getDataFromCell( maUndoData );
56         mxObjRef->AddObjectUser( *this );
57     }
58 }
59 
60 CellUndo::~CellUndo()
61 {
62     if( mxObjRef.is() )
63         mxObjRef->RemoveObjectUser( *this );
64     dispose();
65 }
66 
67 void CellUndo::dispose()
68 {
69     mxCell.clear();
70     delete maUndoData.mpProperties;
71     maUndoData.mpProperties = 0;
72     delete maRedoData.mpProperties;
73     maRedoData.mpProperties = 0;
74     delete maUndoData.mpOutlinerParaObject;
75     maUndoData.mpOutlinerParaObject = 0;
76     delete maRedoData.mpOutlinerParaObject;
77     maRedoData.mpOutlinerParaObject = 0;
78 }
79 
80 void CellUndo::ObjectInDestruction(const SdrObject& )
81 {
82     dispose();
83 }
84 
85 void CellUndo::Undo()
86 {
87     if( mxCell.is() && mbUndo )
88     {
89         if( maRedoData.mpProperties == 0 )
90             getDataFromCell( maRedoData );
91 
92         setDataToCell( maUndoData );
93         mbUndo = false;
94     }
95 }
96 
97 void CellUndo::Redo()
98 {
99     if( mxCell.is() && !mbUndo )
100     {
101         setDataToCell( maRedoData );
102         mbUndo = true;
103     }
104 }
105 
106 sal_Bool CellUndo::Merge( SfxUndoAction *pNextAction )
107 {
108     CellUndo* pNext = dynamic_cast< CellUndo* >( pNextAction );
109     if( pNext && pNext->mxCell.get() == mxCell.get() )
110     {
111         return sal_True;
112     }
113     else
114     {
115         return sal_False;
116     }
117 }
118 
119 void CellUndo::setDataToCell( const Data& rData )
120 {
121     delete mxCell->mpProperties;
122     if( rData.mpProperties )
123         mxCell->mpProperties = Cell::CloneProperties( rData.mpProperties, *mxObjRef.get(), *mxCell.get() );
124     else
125         mxCell->mpProperties = 0;
126 
127     if( rData.mpOutlinerParaObject )
128         mxCell->SetOutlinerParaObject( new OutlinerParaObject(*rData.mpOutlinerParaObject) );
129     else
130         mxCell->RemoveOutlinerParaObject();
131 
132     mxCell->msFormula = rData.msFormula;
133     mxCell->mfValue = rData.mfValue;
134     mxCell->mnError = rData.mnError;
135     mxCell->mbMerged = rData.mbMerged;
136     mxCell->mnRowSpan = rData.mnRowSpan;
137     mxCell->mnColSpan = rData.mnColSpan;
138 
139     if(mxObjRef.is())
140     {
141         // #120201# ActionChanged is not enough, we need to trigger TableLayouter::UpdateBorderLayout()
142         // and this is done best using ReformatText() for table objects
143         mxObjRef->ActionChanged();
144         mxObjRef->NbcReformatText();
145     }
146 }
147 
148 void CellUndo::getDataFromCell( Data& rData )
149 {
150     if( mxObjRef.is() && mxCell.is() )
151     {
152         if( mxCell->mpProperties )
153             rData.mpProperties = mxCell->CloneProperties( *mxObjRef.get(), *mxCell.get());
154 
155         if( mxCell->GetOutlinerParaObject() )
156             rData.mpOutlinerParaObject = new OutlinerParaObject(*mxCell->GetOutlinerParaObject());
157         else
158             rData.mpOutlinerParaObject =  0;
159 
160         rData.mnCellContentType = mxCell->mnCellContentType;
161 
162         rData.msFormula = mxCell->msFormula;
163         rData.mfValue = mxCell->mfValue;
164         rData.mnError = mxCell->mnError;
165         rData.mbMerged = mxCell->mbMerged;
166         rData.mnRowSpan = mxCell->mnRowSpan;
167         rData.mnColSpan = mxCell->mnColSpan;
168     }
169 }
170 
171 // -----------------------------------------------------------------------------
172 // class InsertRowUndo : public SdrUndoAction
173 // -----------------------------------------------------------------------------
174 
175 static void Dispose( RowVector& rRows )
176 {
177     RowVector::iterator aIter( rRows.begin() );
178     while( aIter != rRows.end() )
179         (*aIter++)->dispose();
180 }
181 
182 // -----------------------------------------------------------------------------
183 
184 InsertRowUndo::InsertRowUndo( const TableModelRef& xTable, sal_Int32 nIndex, RowVector& aNewRows )
185 : SdrUndoAction( *xTable->getSdrTableObj()->GetModel() )
186 , mxTable( xTable )
187 , mnIndex( nIndex )
188 , mbUndo( true )
189 {
190     maRows.swap( aNewRows );
191 }
192 
193 // -----------------------------------------------------------------------------
194 
195 InsertRowUndo::~InsertRowUndo()
196 {
197     if( !mbUndo )
198         Dispose( maRows );
199 }
200 
201 // -----------------------------------------------------------------------------
202 
203 void InsertRowUndo::Undo()
204 {
205     if( mxTable.is() )
206     {
207         mxTable->UndoInsertRows( mnIndex, sal::static_int_cast< sal_Int32 >( maRows.size() ) );
208         mbUndo = false;
209     }
210 }
211 
212 // -----------------------------------------------------------------------------
213 
214 void InsertRowUndo::Redo()
215 {
216     if( mxTable.is() )
217     {
218         mxTable->UndoRemoveRows( mnIndex, maRows );
219         mbUndo = true;
220     }
221 }
222 
223 // -----------------------------------------------------------------------------
224 // class RemoveRowUndo : public SdrUndoAction
225 // -----------------------------------------------------------------------------
226 
227 RemoveRowUndo::RemoveRowUndo( const TableModelRef& xTable, sal_Int32 nIndex, RowVector& aRemovedRows )
228 : SdrUndoAction( *xTable->getSdrTableObj()->GetModel() )
229 , mxTable( xTable )
230 , mnIndex( nIndex )
231 , mbUndo( true )
232 {
233     maRows.swap( aRemovedRows );
234 }
235 
236 // -----------------------------------------------------------------------------
237 
238 RemoveRowUndo::~RemoveRowUndo()
239 {
240     if( mbUndo )
241         Dispose( maRows );
242 }
243 
244 // -----------------------------------------------------------------------------
245 
246 void RemoveRowUndo::Undo()
247 {
248     if( mxTable.is() )
249     {
250         mxTable->UndoRemoveRows( mnIndex, maRows );
251         mbUndo = false;
252     }
253 }
254 
255 // -----------------------------------------------------------------------------
256 
257 void RemoveRowUndo::Redo()
258 {
259     if( mxTable.is() )
260     {
261         mxTable->UndoInsertRows( mnIndex, sal::static_int_cast< sal_Int32 >( maRows.size() ) );
262         mbUndo = true;
263     }
264 }
265 
266 // -----------------------------------------------------------------------------
267 // class InsertColUndo : public SdrUndoAction
268 // -----------------------------------------------------------------------------
269 
270 static void Dispose( ColumnVector& rCols )
271 {
272     ColumnVector::iterator aIter( rCols.begin() );
273     while( aIter != rCols.end() )
274         (*aIter++)->dispose();
275 }
276 
277 // -----------------------------------------------------------------------------
278 
279 static void Dispose( CellVector& rCells )
280 {
281     CellVector::iterator aIter( rCells.begin() );
282     while( aIter != rCells.end() )
283         (*aIter++)->dispose();
284 }
285 
286 // -----------------------------------------------------------------------------
287 
288 InsertColUndo::InsertColUndo( const TableModelRef& xTable, sal_Int32 nIndex, ColumnVector& aNewCols, CellVector& aCells  )
289 : SdrUndoAction( *xTable->getSdrTableObj()->GetModel() )
290 , mxTable( xTable )
291 , mnIndex( nIndex )
292 , mbUndo( true )
293 {
294     maColumns.swap( aNewCols );
295     maCells.swap( aCells );
296 }
297 
298 // -----------------------------------------------------------------------------
299 
300 InsertColUndo::~InsertColUndo()
301 {
302     if( !mbUndo )
303     {
304         Dispose( maColumns );
305         Dispose( maCells );
306     }
307 }
308 
309 // -----------------------------------------------------------------------------
310 
311 void InsertColUndo::Undo()
312 {
313     if( mxTable.is() )
314     {
315         mxTable->UndoInsertColumns( mnIndex, sal::static_int_cast< sal_Int32 >( maColumns.size() ) );
316         mbUndo = false;
317     }
318 }
319 
320 // -----------------------------------------------------------------------------
321 
322 void InsertColUndo::Redo()
323 {
324     if( mxTable.is() )
325     {
326         mxTable->UndoRemoveColumns( mnIndex, maColumns, maCells );
327         mbUndo = true;
328     }
329 }
330 
331 // -----------------------------------------------------------------------------
332 // class RemoveColUndo : public SdrUndoAction
333 // -----------------------------------------------------------------------------
334 
335 RemoveColUndo::RemoveColUndo( const TableModelRef& xTable, sal_Int32 nIndex, ColumnVector& aNewCols, CellVector& aCells )
336 : SdrUndoAction( *xTable->getSdrTableObj()->GetModel() )
337 , mxTable( xTable )
338 , mnIndex( nIndex )
339 , mbUndo( true )
340 {
341     maColumns.swap( aNewCols );
342     maCells.swap( aCells );
343 }
344 
345 // -----------------------------------------------------------------------------
346 
347 RemoveColUndo::~RemoveColUndo()
348 {
349     if( mbUndo )
350     {
351         Dispose( maColumns );
352         Dispose( maCells );
353     }
354 }
355 
356 // -----------------------------------------------------------------------------
357 
358 void RemoveColUndo::Undo()
359 {
360     if( mxTable.is() )
361     {
362         mxTable->UndoRemoveColumns( mnIndex, maColumns, maCells );
363         mbUndo = false;
364     }
365 }
366 
367 // -----------------------------------------------------------------------------
368 
369 void RemoveColUndo::Redo()
370 {
371     if( mxTable.is() )
372     {
373         mxTable->UndoInsertColumns( mnIndex, sal::static_int_cast< sal_Int32 >( maColumns.size() ) );
374         mbUndo = true;
375     }
376 }
377 
378 // -----------------------------------------------------------------------------
379 // class TableColumnUndo : public SdrUndoAction
380 // -----------------------------------------------------------------------------
381 
382 TableColumnUndo::TableColumnUndo( const TableColumnRef& xCol )
383 : SdrUndoAction( *xCol->mxTableModel->getSdrTableObj()->GetModel() )
384 , mxCol( xCol )
385 , mbHasRedoData( false )
386 {
387     getData( maUndoData );
388 }
389 
390 // -----------------------------------------------------------------------------
391 
392 TableColumnUndo::~TableColumnUndo()
393 {
394 }
395 
396 // -----------------------------------------------------------------------------
397 
398 void TableColumnUndo::Undo()
399 {
400     if( !mbHasRedoData )
401     {
402         getData( maRedoData );
403         mbHasRedoData = true;
404     }
405     setData( maUndoData );
406 }
407 
408 // -----------------------------------------------------------------------------
409 
410 void TableColumnUndo::Redo()
411 {
412     setData( maRedoData );
413 }
414 
415 // -----------------------------------------------------------------------------
416 
417 sal_Bool TableColumnUndo::Merge( SfxUndoAction *pNextAction )
418 {
419     TableColumnUndo* pNext = dynamic_cast< TableColumnUndo* >( pNextAction );
420     return pNext && pNext->mxCol == mxCol;
421 }
422 
423 // -----------------------------------------------------------------------------
424 
425 void TableColumnUndo::setData( const Data& rData )
426 {
427     mxCol->mnColumn = rData.mnColumn;
428     mxCol->mnWidth = rData.mnWidth;
429     mxCol->mbOptimalWidth = rData.mbOptimalWidth;
430     mxCol->mbIsVisible = rData.mbIsVisible;
431     mxCol->mbIsStartOfNewPage = rData.mbIsStartOfNewPage;
432     mxCol->maName = rData.maName;
433 }
434 
435 // -----------------------------------------------------------------------------
436 
437 void TableColumnUndo::getData( Data& rData )
438 {
439     rData.mnColumn = mxCol->mnColumn;
440     rData.mnWidth = mxCol->mnWidth;
441     rData.mbOptimalWidth = mxCol->mbOptimalWidth;
442     rData.mbIsVisible = mxCol->mbIsVisible;
443     rData.mbIsStartOfNewPage = mxCol->mbIsStartOfNewPage;
444     rData.maName = mxCol->maName;
445 }
446 
447 // -----------------------------------------------------------------------------
448 // class TableRowUndo : public SdrUndoAction
449 // -----------------------------------------------------------------------------
450 
451 TableRowUndo::TableRowUndo( const TableRowRef& xRow )
452 : SdrUndoAction( *xRow->mxTableModel->getSdrTableObj()->GetModel() )
453 , mxRow( xRow )
454 , mbHasRedoData( false )
455 {
456     getData( maUndoData );
457 }
458 
459 // -----------------------------------------------------------------------------
460 
461 TableRowUndo::~TableRowUndo()
462 {
463 }
464 
465 // -----------------------------------------------------------------------------
466 
467 void TableRowUndo::Undo()
468 {
469     if( !mbHasRedoData )
470     {
471         getData( maRedoData );
472         mbHasRedoData = true;
473     }
474     setData( maUndoData );
475 }
476 
477 // -----------------------------------------------------------------------------
478 
479 void TableRowUndo::Redo()
480 {
481     setData( maRedoData );
482 }
483 
484 // -----------------------------------------------------------------------------
485 
486 sal_Bool TableRowUndo::Merge( SfxUndoAction *pNextAction )
487 {
488     TableRowUndo* pNext = dynamic_cast< TableRowUndo* >( pNextAction );
489     return pNext && pNext->mxRow == mxRow;
490 }
491 
492 // -----------------------------------------------------------------------------
493 
494 void TableRowUndo::setData( const Data& rData )
495 {
496     mxRow->mnRow = rData.mnRow;
497     mxRow->mnHeight = rData.mnHeight;
498     mxRow->mbOptimalHeight = rData.mbOptimalHeight;
499     mxRow->mbIsVisible = rData.mbIsVisible;
500     mxRow->mbIsStartOfNewPage = rData.mbIsStartOfNewPage;
501     mxRow->maName = rData.maName;
502  }
503 
504 // -----------------------------------------------------------------------------
505 
506 void TableRowUndo::getData( Data& rData )
507 {
508     rData.mnRow = mxRow->mnRow;
509     rData.mnHeight = mxRow->mnHeight;
510     rData.mbOptimalHeight = mxRow->mbOptimalHeight;
511     rData.mbIsVisible = mxRow->mbIsVisible;
512     rData.mbIsStartOfNewPage = mxRow->mbIsStartOfNewPage;
513     rData.maName = mxRow->maName;
514 }
515 
516 // -----------------------------------------------------------------------------
517 
518 TableStyleUndo::TableStyleUndo( const SdrTableObj& rTableObj )
519 : SdrUndoAction( *rTableObj.GetModel() )
520 , mxObjRef( const_cast< sdr::table::SdrTableObj*>( &rTableObj ) )
521 {
522     getData( maUndoData );
523 }
524 
525 void TableStyleUndo::Undo()
526 {
527     if( !mbHasRedoData )
528     {
529         getData( maRedoData );
530         mbHasRedoData = true;
531     }
532     setData( maUndoData );
533 }
534 
535 void TableStyleUndo::Redo()
536 {
537     setData( maRedoData );
538 }
539 
540 void TableStyleUndo::setData( const Data& rData )
541 {
542     SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxObjRef.get() );
543     if( pTableObj )
544     {
545         pTableObj->setTableStyle( rData.mxTableStyle );
546         pTableObj->setTableStyleSettings( rData.maSettings );
547     }
548 }
549 
550 void TableStyleUndo::getData( Data& rData )
551 {
552     SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxObjRef.get() );
553     if( pTableObj )
554     {
555         rData.maSettings = pTableObj->getTableStyleSettings();
556         rData.mxTableStyle = pTableObj->getTableStyle();
557     }
558 }
559 
560 } }
561