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
CellUndo(const SdrObjectWeakRef & xObjRef,const CellRef & xCell)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
~CellUndo()60 CellUndo::~CellUndo()
61 {
62 if( mxObjRef.is() )
63 mxObjRef->RemoveObjectUser( *this );
64 dispose();
65 }
66
dispose()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
ObjectInDestruction(const SdrObject &)80 void CellUndo::ObjectInDestruction(const SdrObject& )
81 {
82 dispose();
83 }
84
Undo()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
Redo()97 void CellUndo::Redo()
98 {
99 if( mxCell.is() && !mbUndo )
100 {
101 setDataToCell( maRedoData );
102 mbUndo = true;
103 }
104 }
105
Merge(SfxUndoAction * pNextAction)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
setDataToCell(const Data & rData)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
getDataFromCell(Data & rData)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
Dispose(RowVector & rRows)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
InsertRowUndo(const TableModelRef & xTable,sal_Int32 nIndex,RowVector & aNewRows)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
~InsertRowUndo()195 InsertRowUndo::~InsertRowUndo()
196 {
197 if( !mbUndo )
198 Dispose( maRows );
199 }
200
201 // -----------------------------------------------------------------------------
202
Undo()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
Redo()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
RemoveRowUndo(const TableModelRef & xTable,sal_Int32 nIndex,RowVector & aRemovedRows)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
~RemoveRowUndo()238 RemoveRowUndo::~RemoveRowUndo()
239 {
240 if( mbUndo )
241 Dispose( maRows );
242 }
243
244 // -----------------------------------------------------------------------------
245
Undo()246 void RemoveRowUndo::Undo()
247 {
248 if( mxTable.is() )
249 {
250 mxTable->UndoRemoveRows( mnIndex, maRows );
251 mbUndo = false;
252 }
253 }
254
255 // -----------------------------------------------------------------------------
256
Redo()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
Dispose(ColumnVector & rCols)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
Dispose(CellVector & rCells)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
InsertColUndo(const TableModelRef & xTable,sal_Int32 nIndex,ColumnVector & aNewCols,CellVector & aCells)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
~InsertColUndo()300 InsertColUndo::~InsertColUndo()
301 {
302 if( !mbUndo )
303 {
304 Dispose( maColumns );
305 Dispose( maCells );
306 }
307 }
308
309 // -----------------------------------------------------------------------------
310
Undo()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
Redo()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
RemoveColUndo(const TableModelRef & xTable,sal_Int32 nIndex,ColumnVector & aNewCols,CellVector & aCells)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
~RemoveColUndo()347 RemoveColUndo::~RemoveColUndo()
348 {
349 if( mbUndo )
350 {
351 Dispose( maColumns );
352 Dispose( maCells );
353 }
354 }
355
356 // -----------------------------------------------------------------------------
357
Undo()358 void RemoveColUndo::Undo()
359 {
360 if( mxTable.is() )
361 {
362 mxTable->UndoRemoveColumns( mnIndex, maColumns, maCells );
363 mbUndo = false;
364 }
365 }
366
367 // -----------------------------------------------------------------------------
368
Redo()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
TableColumnUndo(const TableColumnRef & xCol)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
~TableColumnUndo()392 TableColumnUndo::~TableColumnUndo()
393 {
394 }
395
396 // -----------------------------------------------------------------------------
397
Undo()398 void TableColumnUndo::Undo()
399 {
400 if( !mbHasRedoData )
401 {
402 getData( maRedoData );
403 mbHasRedoData = true;
404 }
405 setData( maUndoData );
406 }
407
408 // -----------------------------------------------------------------------------
409
Redo()410 void TableColumnUndo::Redo()
411 {
412 setData( maRedoData );
413 }
414
415 // -----------------------------------------------------------------------------
416
Merge(SfxUndoAction * pNextAction)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
setData(const Data & rData)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
getData(Data & rData)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
TableRowUndo(const TableRowRef & xRow)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
~TableRowUndo()461 TableRowUndo::~TableRowUndo()
462 {
463 }
464
465 // -----------------------------------------------------------------------------
466
Undo()467 void TableRowUndo::Undo()
468 {
469 if( !mbHasRedoData )
470 {
471 getData( maRedoData );
472 mbHasRedoData = true;
473 }
474 setData( maUndoData );
475 }
476
477 // -----------------------------------------------------------------------------
478
Redo()479 void TableRowUndo::Redo()
480 {
481 setData( maRedoData );
482 }
483
484 // -----------------------------------------------------------------------------
485
Merge(SfxUndoAction * pNextAction)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
setData(const Data & rData)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
getData(Data & rData)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
TableStyleUndo(const SdrTableObj & rTableObj)518 TableStyleUndo::TableStyleUndo( const SdrTableObj& rTableObj )
519 : SdrUndoAction( *rTableObj.GetModel() )
520 , mxObjRef( const_cast< sdr::table::SdrTableObj*>( &rTableObj ) )
521 {
522 getData( maUndoData );
523 }
524
Undo()525 void TableStyleUndo::Undo()
526 {
527 if( !mbHasRedoData )
528 {
529 getData( maRedoData );
530 mbHasRedoData = true;
531 }
532 setData( maUndoData );
533 }
534
Redo()535 void TableStyleUndo::Redo()
536 {
537 setData( maRedoData );
538 }
539
setData(const Data & rData)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
getData(Data & rData)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