Line data Source code
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 "scitems.hxx"
21 : #include <vcl/virdev.hxx>
22 : #include <vcl/waitobj.hxx>
23 : #include <editeng/boxitem.hxx>
24 : #include <editeng/justifyitem.hxx>
25 : #include <sfx2/app.hxx>
26 :
27 : #include "undoblk.hxx"
28 : #include "undoutil.hxx"
29 : #include "document.hxx"
30 : #include "patattr.hxx"
31 : #include "docsh.hxx"
32 : #include "tabvwsh.hxx"
33 : #include "rangenam.hxx"
34 : #include "rangeutl.hxx"
35 : #include "dbdata.hxx"
36 : #include "stlpool.hxx"
37 : #include "stlsheet.hxx"
38 : #include "globstr.hrc"
39 : #include "global.hxx"
40 : #include "target.hxx"
41 : #include "docpool.hxx"
42 : #include "docfunc.hxx"
43 : #include "attrib.hxx"
44 : #include "chgtrack.hxx"
45 : #include "transobj.hxx"
46 : #include "refundo.hxx"
47 : #include "undoolk.hxx"
48 : #include "clipparam.hxx"
49 : #include <brdcst.hxx>
50 : #include "sc.hrc"
51 : #include <rowheightcontext.hxx>
52 : #include <refhint.hxx>
53 : #include <refupdatecontext.hxx>
54 : #include <validat.hxx>
55 : #include <gridwin.hxx>
56 : #include <svl/listener.hxx>
57 :
58 : #include <set>
59 : #include <boost/scoped_ptr.hpp>
60 :
61 : // STATIC DATA -----------------------------------------------------------
62 :
63 0 : TYPEINIT1(ScUndoInsertCells, SfxUndoAction);
64 0 : TYPEINIT1(ScUndoDeleteCells, SfxUndoAction);
65 0 : TYPEINIT1(ScUndoDeleteMulti, SfxUndoAction);
66 0 : TYPEINIT1(ScUndoCut, ScBlockUndo);
67 0 : TYPEINIT1(ScUndoPaste, SfxUndoAction);
68 0 : TYPEINIT1(ScUndoDragDrop, SfxUndoAction);
69 0 : TYPEINIT1(ScUndoListNames, SfxUndoAction);
70 0 : TYPEINIT1(ScUndoConditionalFormat, SfxUndoAction);
71 0 : TYPEINIT1(ScUndoUseScenario, SfxUndoAction);
72 0 : TYPEINIT1(ScUndoSelectionStyle, SfxUndoAction);
73 0 : TYPEINIT1(ScUndoEnterMatrix, ScBlockUndo);
74 0 : TYPEINIT1(ScUndoIndent, ScBlockUndo);
75 0 : TYPEINIT1(ScUndoTransliterate, ScBlockUndo);
76 0 : TYPEINIT1(ScUndoClearItems, ScBlockUndo);
77 0 : TYPEINIT1(ScUndoRemoveBreaks, SfxUndoAction);
78 0 : TYPEINIT1(ScUndoRemoveMerge, ScBlockUndo);
79 0 : TYPEINIT1(ScUndoBorder, ScBlockUndo);
80 :
81 : // TODO:
82 : /*A*/ // SetOptimalHeight on Document, if no View
83 : /*B*/ // linked sheets
84 : /*C*/ // ScArea
85 : //? // check later
86 :
87 10 : ScUndoInsertCells::ScUndoInsertCells( ScDocShell* pNewDocShell,
88 : const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios,
89 : InsCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData,
90 : bool bNewPartOfPaste ) :
91 : ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
92 : aEffRange( rRange ),
93 : nCount( nNewCount ),
94 : pTabs( pNewTabs ),
95 : pScenarios( pNewScenarios ),
96 : eCmd( eNewCmd ),
97 : bPartOfPaste( bNewPartOfPaste ),
98 10 : pPasteUndo( NULL )
99 : {
100 10 : if (eCmd == INS_INSROWS_BEFORE || eCmd == INS_INSROWS_AFTER) // whole row?
101 : {
102 5 : aEffRange.aStart.SetCol(0);
103 5 : aEffRange.aEnd.SetCol(MAXCOL);
104 : }
105 :
106 10 : if (eCmd == INS_INSCOLS_BEFORE || eCmd == INS_INSCOLS_AFTER) // whole column?
107 : {
108 4 : aEffRange.aStart.SetRow(0);
109 4 : aEffRange.aEnd.SetRow(MAXROW);
110 : }
111 :
112 10 : SetChangeTrack();
113 10 : }
114 :
115 30 : ScUndoInsertCells::~ScUndoInsertCells()
116 : {
117 10 : delete pPasteUndo;
118 10 : delete []pTabs;
119 10 : delete []pScenarios;
120 20 : }
121 :
122 15 : OUString ScUndoInsertCells::GetComment() const
123 : {
124 15 : return ScGlobal::GetRscString( pPasteUndo ? STR_UNDO_PASTE : STR_UNDO_INSERTCELLS );
125 : }
126 :
127 0 : bool ScUndoInsertCells::Merge( SfxUndoAction* pNextAction )
128 : {
129 : // If a paste undo action has already been added, append (detective) action there.
130 0 : if ( pPasteUndo )
131 0 : return pPasteUndo->Merge( pNextAction );
132 :
133 0 : if ( bPartOfPaste && pNextAction->ISA( ScUndoWrapper ) )
134 : {
135 0 : ScUndoWrapper* pWrapper = static_cast<ScUndoWrapper*>(pNextAction);
136 0 : SfxUndoAction* pWrappedAction = pWrapper->GetWrappedUndo();
137 0 : if ( pWrappedAction && pWrappedAction->ISA( ScUndoPaste ) )
138 : {
139 : // Store paste action if this is part of paste with inserting cells.
140 : // A list action isn't used because Repeat wouldn't work (insert wrong cells).
141 :
142 0 : pPasteUndo = pWrappedAction;
143 0 : pWrapper->ForgetWrappedUndo(); // pWrapper is deleted by UndoManager
144 0 : return true;
145 : }
146 : }
147 :
148 : // Call base class for detective handling
149 0 : return ScMoveUndo::Merge( pNextAction );
150 : }
151 :
152 12 : void ScUndoInsertCells::SetChangeTrack()
153 : {
154 12 : ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
155 12 : if ( pChangeTrack )
156 : {
157 0 : pChangeTrack->AppendInsert( aEffRange );
158 0 : nEndChangeAction = pChangeTrack->GetActionMax();
159 : }
160 : else
161 12 : nEndChangeAction = 0;
162 12 : }
163 :
164 5 : void ScUndoInsertCells::DoChange( const bool bUndo )
165 : {
166 5 : ScDocument& rDoc = pDocShell->GetDocument();
167 : SCTAB i;
168 :
169 5 : if ( bUndo )
170 : {
171 3 : ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
172 3 : if ( pChangeTrack )
173 0 : pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
174 : }
175 : else
176 2 : SetChangeTrack();
177 :
178 : // refresh of merged cells has to be after inserting/deleting
179 :
180 5 : switch (eCmd)
181 : {
182 : case INS_INSROWS_BEFORE:
183 : case INS_INSROWS_AFTER:
184 : case INS_CELLSDOWN:
185 8 : for( i=0; i<nCount; i++ )
186 : {
187 4 : if (bUndo)
188 10 : rDoc.DeleteRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
189 12 : aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
190 : else
191 10 : rDoc.InsertRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
192 12 : aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
193 : }
194 4 : break;
195 : case INS_INSCOLS_BEFORE:
196 : case INS_INSCOLS_AFTER:
197 : case INS_CELLSRIGHT:
198 2 : for( i=0; i<nCount; i++ )
199 : {
200 1 : if (bUndo)
201 3 : rDoc.DeleteCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
202 4 : aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
203 : else
204 0 : rDoc.InsertCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
205 0 : aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
206 : }
207 1 : break;
208 : default:
209 : {
210 : // added to avoid warnings
211 : }
212 : }
213 :
214 5 : ScRange aWorkRange( aEffRange );
215 5 : if ( eCmd == INS_CELLSRIGHT ) // only "shift right" requires refresh of the moved area
216 0 : aWorkRange.aEnd.SetCol(MAXCOL);
217 10 : for( i=0; i<nCount; i++ )
218 : {
219 15 : if ( rDoc.HasAttrib( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
220 15 : aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i], HASATTR_MERGED ) )
221 : {
222 0 : SCCOL nEndCol = aWorkRange.aEnd.Col();
223 0 : SCROW nEndRow = aWorkRange.aEnd.Row();
224 0 : rDoc.ExtendMerge( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), nEndCol, nEndRow, pTabs[i], true );
225 : }
226 : }
227 :
228 : // Undo for displaced attributes?
229 :
230 5 : sal_uInt16 nPaint = PAINT_GRID;
231 5 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
232 5 : switch (eCmd)
233 : {
234 : case INS_INSROWS_BEFORE:
235 : case INS_INSROWS_AFTER:
236 4 : nPaint |= PAINT_LEFT;
237 4 : aWorkRange.aEnd.SetRow(MAXROW);
238 4 : break;
239 : case INS_CELLSDOWN:
240 0 : for( i=0; i<nCount; i++ )
241 : {
242 0 : aWorkRange.aEnd.SetRow(MAXROW);
243 0 : if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ))
244 : {
245 0 : aWorkRange.aStart.SetCol(0);
246 0 : aWorkRange.aEnd.SetCol(MAXCOL);
247 0 : nPaint |= PAINT_LEFT;
248 : }
249 : }
250 0 : break;
251 : case INS_INSCOLS_BEFORE:
252 : case INS_INSCOLS_AFTER:
253 1 : nPaint |= PAINT_TOP; // top bar
254 : case INS_CELLSRIGHT:
255 2 : for( i=0; i<nCount; i++ )
256 : {
257 1 : aWorkRange.aEnd.SetCol(MAXCOL); // to the far right
258 1 : if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i]) )
259 : { // AdjustDraw does not paint PAINT_TOP,
260 0 : aWorkRange.aStart.SetCol(0); // thus solved like this
261 0 : aWorkRange.aEnd.SetRow(MAXROW);
262 0 : nPaint |= PAINT_LEFT;
263 : }
264 : }
265 1 : break;
266 : default:
267 : {
268 : // added to avoid warnings
269 : }
270 : }
271 :
272 10 : for( i=0; i<nCount; i++ )
273 : {
274 10 : pDocShell->PostPaint( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
275 15 : aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i]+pScenarios[i], nPaint );
276 : }
277 5 : pDocShell->PostDataChanged();
278 5 : if (pViewShell)
279 0 : pViewShell->CellContentChanged();
280 5 : }
281 :
282 3 : void ScUndoInsertCells::Undo()
283 : {
284 3 : if ( pPasteUndo )
285 0 : pPasteUndo->Undo(); // undo paste first
286 :
287 3 : WaitObject aWait( ScDocShell::GetActiveDialogParent() ); // important due to TrackFormulas in UpdateReference
288 3 : BeginUndo();
289 3 : DoChange( true );
290 3 : EndUndo();
291 :
292 3 : ScDocument& rDoc = pDocShell->GetDocument();
293 6 : for (SCTAB i = 0; i < nCount; ++i)
294 6 : rDoc.SetDrawPageSize(pTabs[i]);
295 3 : }
296 :
297 2 : void ScUndoInsertCells::Redo()
298 : {
299 2 : WaitObject aWait( ScDocShell::GetActiveDialogParent() ); // important due to TrackFormulas in UpdateReference
300 2 : BeginRedo();
301 2 : DoChange( false );
302 2 : EndRedo();
303 :
304 2 : if ( pPasteUndo )
305 0 : pPasteUndo->Redo(); // redo paste last
306 :
307 2 : ScDocument& rDoc = pDocShell->GetDocument();
308 4 : for (SCTAB i = 0; i < nCount; ++i)
309 4 : rDoc.SetDrawPageSize(pTabs[i]);
310 2 : }
311 :
312 0 : void ScUndoInsertCells::Repeat(SfxRepeatTarget& rTarget)
313 : {
314 0 : if (rTarget.ISA(ScTabViewTarget))
315 : {
316 0 : if ( pPasteUndo )
317 : {
318 : // Repeat for paste with inserting cells is handled completely
319 : // by the Paste undo action
320 :
321 0 : pPasteUndo->Repeat( rTarget );
322 : }
323 : else
324 0 : static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->InsertCells( eCmd, true );
325 : }
326 0 : }
327 :
328 0 : bool ScUndoInsertCells::CanRepeat(SfxRepeatTarget& rTarget) const
329 : {
330 0 : return rTarget.ISA(ScTabViewTarget);
331 : }
332 :
333 30 : ScUndoDeleteCells::ScUndoDeleteCells( ScDocShell* pNewDocShell,
334 : const ScRange& rRange, SCTAB nNewCount, SCTAB* pNewTabs, SCTAB* pNewScenarios,
335 : DelCellCmd eNewCmd, ScDocument* pUndoDocument, ScRefUndoData* pRefData ) :
336 : ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
337 : aEffRange( rRange ),
338 : nCount( nNewCount ),
339 : pTabs( pNewTabs ),
340 : pScenarios( pNewScenarios ),
341 30 : eCmd( eNewCmd )
342 : {
343 30 : if (eCmd == DEL_DELROWS) // whole row?
344 : {
345 3 : aEffRange.aStart.SetCol(0);
346 3 : aEffRange.aEnd.SetCol(MAXCOL);
347 : }
348 :
349 30 : if (eCmd == DEL_DELCOLS) // whole column?
350 : {
351 3 : aEffRange.aStart.SetRow(0);
352 3 : aEffRange.aEnd.SetRow(MAXROW);
353 : }
354 :
355 30 : SetChangeTrack();
356 30 : }
357 :
358 90 : ScUndoDeleteCells::~ScUndoDeleteCells()
359 : {
360 30 : delete []pTabs;
361 30 : delete []pScenarios;
362 60 : }
363 :
364 53 : OUString ScUndoDeleteCells::GetComment() const
365 : {
366 53 : return ScGlobal::GetRscString( STR_UNDO_DELETECELLS ); // "Delete"
367 : }
368 :
369 32 : void ScUndoDeleteCells::SetChangeTrack()
370 : {
371 32 : ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
372 32 : if ( pChangeTrack )
373 : pChangeTrack->AppendDeleteRange( aEffRange, pRefUndoDoc,
374 0 : nStartChangeAction, nEndChangeAction );
375 : else
376 32 : nStartChangeAction = nEndChangeAction = 0;
377 32 : }
378 :
379 23 : void ScUndoDeleteCells::DoChange( const bool bUndo )
380 : {
381 23 : ScDocument& rDoc = pDocShell->GetDocument();
382 : SCTAB i;
383 :
384 23 : if ( bUndo )
385 : {
386 21 : ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
387 21 : if ( pChangeTrack )
388 0 : pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
389 : }
390 : else
391 2 : SetChangeTrack();
392 :
393 23 : switch (eCmd)
394 : {
395 : case DEL_DELROWS:
396 : case DEL_CELLSUP:
397 26 : for( i=0; i<nCount; i++ )
398 : {
399 13 : if (bUndo)
400 60 : rDoc.InsertRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
401 72 : aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
402 : else
403 5 : rDoc.DeleteRow( aEffRange.aStart.Col(), pTabs[i], aEffRange.aEnd.Col(), pTabs[i]+pScenarios[i],
404 6 : aEffRange.aStart.Row(), static_cast<SCSIZE>(aEffRange.aEnd.Row()-aEffRange.aStart.Row()+1));
405 : }
406 13 : break;
407 : case DEL_DELCOLS:
408 : case DEL_CELLSLEFT:
409 20 : for( i=0; i<nCount; i++ )
410 : {
411 10 : if (bUndo)
412 27 : rDoc.InsertCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
413 36 : aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
414 : else
415 3 : rDoc.DeleteCol( aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
416 4 : aEffRange.aStart.Col(), static_cast<SCSIZE>(aEffRange.aEnd.Col()-aEffRange.aStart.Col()+1));
417 : }
418 10 : break;
419 : default:
420 : {
421 : // added to avoid warnings
422 : }
423 : }
424 :
425 : // if Undo, restore references
426 44 : for( i=0; i<nCount && bUndo; i++ )
427 : {
428 105 : pRefUndoDoc->CopyToDocument( aEffRange.aStart.Col(), aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Col(), aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
429 126 : IDF_ALL | IDF_NOCAPTIONS, false, &rDoc );
430 : }
431 :
432 23 : ScRange aWorkRange( aEffRange );
433 23 : if ( eCmd == DEL_CELLSLEFT ) // only "shift left" requires refresh of the moved area
434 10 : aWorkRange.aEnd.SetCol(MAXCOL);
435 :
436 46 : for( i=0; i<nCount; i++ )
437 : {
438 69 : if ( rDoc.HasAttrib( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
439 69 : aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i], HASATTR_MERGED | HASATTR_OVERLAPPED ) )
440 : {
441 : // #i51445# old merge flag attributes must be deleted also for single cells,
442 : // not only for whole columns/rows
443 :
444 0 : if ( !bUndo )
445 : {
446 0 : if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
447 0 : aWorkRange.aEnd.SetCol(MAXCOL);
448 0 : if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
449 0 : aWorkRange.aEnd.SetRow(MAXROW);
450 0 : ScMarkData aMarkData;
451 0 : aMarkData.SelectOneTable( aWorkRange.aStart.Tab() );
452 0 : ScPatternAttr aPattern( rDoc.GetPool() );
453 0 : aPattern.GetItemSet().Put( ScMergeFlagAttr() );
454 0 : rDoc.ApplyPatternArea( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(),
455 0 : aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(),
456 0 : aMarkData, aPattern );
457 : }
458 :
459 0 : SCCOL nEndCol = aWorkRange.aEnd.Col();
460 0 : SCROW nEndRow = aWorkRange.aEnd.Row();
461 0 : rDoc.ExtendMerge( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), nEndCol, nEndRow, pTabs[i], true );
462 : }
463 : }
464 :
465 : // Zeichnen
466 23 : sal_uInt16 nPaint = PAINT_GRID;
467 23 : switch (eCmd)
468 : {
469 : case DEL_DELROWS:
470 1 : nPaint |= PAINT_LEFT;
471 1 : aWorkRange.aEnd.SetRow(MAXROW);
472 1 : break;
473 : case DEL_CELLSUP:
474 24 : for( i=0; i<nCount; i++ )
475 : {
476 12 : aWorkRange.aEnd.SetRow(MAXROW);
477 12 : if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ))
478 : {
479 0 : aWorkRange.aStart.SetCol(0);
480 0 : aWorkRange.aEnd.SetCol(MAXCOL);
481 0 : nPaint |= PAINT_LEFT;
482 : }
483 : }
484 12 : break;
485 : case DEL_DELCOLS:
486 0 : nPaint |= PAINT_TOP; // top bar
487 : case DEL_CELLSLEFT:
488 20 : for( i=0; i<nCount; i++ )
489 : {
490 10 : aWorkRange.aEnd.SetCol(MAXCOL); // to the far right
491 10 : if ( pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), pTabs[i] ) )
492 : {
493 0 : aWorkRange.aStart.SetCol(0);
494 0 : aWorkRange.aEnd.SetRow(MAXROW);
495 0 : nPaint |= PAINT_LEFT;
496 : }
497 : }
498 10 : break;
499 : default:
500 : {
501 : // added to avoid warnings
502 : }
503 : }
504 :
505 46 : for( i=0; i<nCount; i++ )
506 : {
507 46 : pDocShell->PostPaint( aWorkRange.aStart.Col(), aWorkRange.aStart.Row(), pTabs[i],
508 69 : aWorkRange.aEnd.Col(), aWorkRange.aEnd.Row(), pTabs[i]+pScenarios[i], nPaint, SC_PF_LINES );
509 : }
510 : // Selection not until EndUndo
511 :
512 23 : pDocShell->PostDataChanged();
513 : // CellContentChanged comes with the selection
514 23 : }
515 :
516 21 : void ScUndoDeleteCells::Undo()
517 : {
518 21 : WaitObject aWait( ScDocShell::GetActiveDialogParent() ); // important because of TrackFormulas in UpdateReference
519 21 : BeginUndo();
520 21 : DoChange( true );
521 21 : EndUndo();
522 21 : SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
523 :
524 : // Selection not until EndUndo
525 21 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
526 21 : if (pViewShell)
527 : {
528 0 : for( SCTAB i=0; i<nCount; i++ )
529 : {
530 0 : pViewShell->MarkRange( ScRange(aEffRange.aStart.Col(), aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Col(), aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i]) );
531 : }
532 : }
533 :
534 21 : ScDocument& rDoc = pDocShell->GetDocument();
535 42 : for (SCTAB i = 0; i < nCount; ++i)
536 42 : rDoc.SetDrawPageSize(pTabs[i]);
537 21 : }
538 :
539 2 : void ScUndoDeleteCells::Redo()
540 : {
541 2 : WaitObject aWait( ScDocShell::GetActiveDialogParent() ); // important because of TrackFormulas in UpdateReference
542 2 : BeginRedo();
543 2 : DoChange( false);
544 2 : EndRedo();
545 2 : SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
546 :
547 2 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
548 2 : if (pViewShell)
549 0 : pViewShell->DoneBlockMode(); // current way
550 :
551 2 : ScDocument& rDoc = pDocShell->GetDocument();
552 4 : for (SCTAB i = 0; i < nCount; ++i)
553 4 : rDoc.SetDrawPageSize(pTabs[i]);
554 2 : }
555 :
556 0 : void ScUndoDeleteCells::Repeat(SfxRepeatTarget& rTarget)
557 : {
558 0 : if (rTarget.ISA(ScTabViewTarget))
559 0 : static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->DeleteCells( eCmd, true );
560 0 : }
561 :
562 0 : bool ScUndoDeleteCells::CanRepeat(SfxRepeatTarget& rTarget) const
563 : {
564 0 : return rTarget.ISA(ScTabViewTarget);
565 : }
566 :
567 : // delete cells in multiselection
568 0 : ScUndoDeleteMulti::ScUndoDeleteMulti(
569 : ScDocShell* pNewDocShell,
570 : bool bNewRows, bool bNeedsRefresh, SCTAB nNewTab,
571 : const std::vector<sc::ColRowSpan>& rSpans,
572 : ScDocument* pUndoDocument, ScRefUndoData* pRefData ) :
573 : ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFLAST ),
574 : mbRows(bNewRows),
575 : mbRefresh(bNeedsRefresh),
576 : nTab( nNewTab ),
577 0 : maSpans(rSpans)
578 : {
579 0 : SetChangeTrack();
580 0 : }
581 :
582 0 : ScUndoDeleteMulti::~ScUndoDeleteMulti()
583 : {
584 0 : }
585 :
586 0 : OUString ScUndoDeleteMulti::GetComment() const
587 : {
588 0 : return ScGlobal::GetRscString( STR_UNDO_DELETECELLS ); // like DeleteCells
589 : }
590 :
591 0 : void ScUndoDeleteMulti::DoChange() const
592 : {
593 : SCCOL nStartCol;
594 : SCROW nStartRow;
595 : sal_uInt16 nPaint;
596 0 : if (mbRows)
597 : {
598 0 : nStartCol = 0;
599 0 : nStartRow = static_cast<SCROW>(maSpans[0].mnStart);
600 0 : nPaint = PAINT_GRID | PAINT_LEFT;
601 : }
602 : else
603 : {
604 0 : nStartCol = static_cast<SCCOL>(maSpans[0].mnStart);
605 0 : nStartRow = 0;
606 0 : nPaint = PAINT_GRID | PAINT_TOP;
607 : }
608 :
609 0 : if (mbRefresh)
610 : {
611 0 : ScDocument& rDoc = pDocShell->GetDocument();
612 0 : SCCOL nEndCol = MAXCOL;
613 0 : SCROW nEndRow = MAXROW;
614 0 : rDoc.RemoveFlagsTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER );
615 0 : rDoc.ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab, true );
616 : }
617 :
618 0 : pDocShell->PostPaint( nStartCol, nStartRow, nTab, MAXCOL, MAXROW, nTab, nPaint );
619 0 : pDocShell->PostDataChanged();
620 0 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
621 0 : if (pViewShell)
622 0 : pViewShell->CellContentChanged();
623 :
624 0 : ShowTable( nTab );
625 0 : }
626 :
627 0 : void ScUndoDeleteMulti::SetChangeTrack()
628 : {
629 0 : ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
630 0 : if ( pChangeTrack )
631 : {
632 0 : nStartChangeAction = pChangeTrack->GetActionMax() + 1;
633 0 : ScRange aRange( 0, 0, nTab, 0, 0, nTab );
634 0 : if (mbRows)
635 0 : aRange.aEnd.SetCol( MAXCOL );
636 : else
637 0 : aRange.aEnd.SetRow( MAXROW );
638 : // delete in reverse
639 0 : std::vector<sc::ColRowSpan>::const_reverse_iterator ri = maSpans.rbegin(), riEnd = maSpans.rend();
640 0 : for (; ri != riEnd; ++ri)
641 : {
642 0 : SCCOLROW nEnd = ri->mnEnd;
643 0 : SCCOLROW nStart = ri->mnStart;
644 0 : if (mbRows)
645 : {
646 0 : aRange.aStart.SetRow( nStart );
647 0 : aRange.aEnd.SetRow( nEnd );
648 : }
649 : else
650 : {
651 0 : aRange.aStart.SetCol( static_cast<SCCOL>(nStart) );
652 0 : aRange.aEnd.SetCol( static_cast<SCCOL>(nEnd) );
653 : }
654 : sal_uLong nDummyStart;
655 : pChangeTrack->AppendDeleteRange( aRange, pRefUndoDoc,
656 0 : nDummyStart, nEndChangeAction );
657 : }
658 : }
659 : else
660 0 : nStartChangeAction = nEndChangeAction = 0;
661 0 : }
662 :
663 0 : void ScUndoDeleteMulti::Undo()
664 : {
665 0 : WaitObject aWait( ScDocShell::GetActiveDialogParent() ); // important because of TrackFormulas in UpdateReference
666 0 : BeginUndo();
667 :
668 0 : ScDocument& rDoc = pDocShell->GetDocument();
669 :
670 : // reverse delete -> forward insert
671 0 : std::vector<sc::ColRowSpan>::const_iterator it = maSpans.begin(), itEnd = maSpans.end();
672 0 : for (; it != itEnd; ++it)
673 : {
674 0 : SCCOLROW nStart = it->mnStart;
675 0 : SCCOLROW nEnd = it->mnEnd;
676 0 : if (mbRows)
677 0 : rDoc.InsertRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) );
678 : else
679 0 : rDoc.InsertCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) );
680 : }
681 :
682 0 : it = maSpans.begin();
683 0 : for (; it != itEnd; ++it)
684 : {
685 0 : SCCOLROW nStart = it->mnStart;
686 0 : SCCOLROW nEnd = it->mnEnd;
687 0 : if (mbRows)
688 0 : pRefUndoDoc->CopyToDocument( 0,nStart,nTab, MAXCOL,nEnd,nTab, IDF_ALL,false, &rDoc );
689 : else
690 : pRefUndoDoc->CopyToDocument( static_cast<SCCOL>(nStart),0,nTab,
691 0 : static_cast<SCCOL>(nEnd),MAXROW,nTab, IDF_ALL,false, &rDoc );
692 : }
693 :
694 0 : ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
695 0 : if ( pChangeTrack )
696 0 : pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
697 :
698 0 : DoChange();
699 :
700 : //! redrawing the selection is not possible at the moment
701 : //! since no data for selection exist
702 :
703 0 : EndUndo();
704 0 : SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
705 0 : }
706 :
707 0 : void ScUndoDeleteMulti::Redo()
708 : {
709 0 : WaitObject aWait( ScDocShell::GetActiveDialogParent() ); // important because of TrackFormulas in UpdateReference
710 0 : BeginRedo();
711 :
712 0 : ScDocument& rDoc = pDocShell->GetDocument();
713 :
714 : // reverse delete
715 0 : std::vector<sc::ColRowSpan>::const_reverse_iterator ri = maSpans.rbegin(), riEnd = maSpans.rend();
716 0 : for (; ri != riEnd; ++ri)
717 : {
718 0 : SCCOLROW nEnd = ri->mnEnd;
719 0 : SCCOLROW nStart = ri->mnStart;
720 0 : if (mbRows)
721 0 : rDoc.DeleteRow( 0,nTab, MAXCOL,nTab, nStart,static_cast<SCSIZE>(nEnd-nStart+1) );
722 : else
723 0 : rDoc.DeleteCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) );
724 : }
725 :
726 0 : SetChangeTrack();
727 :
728 0 : DoChange();
729 :
730 0 : EndRedo();
731 0 : SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
732 0 : }
733 :
734 0 : void ScUndoDeleteMulti::Repeat(SfxRepeatTarget& rTarget)
735 : {
736 : // if single selection
737 0 : if (rTarget.ISA(ScTabViewTarget))
738 0 : static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->DeleteCells( DEL_DELROWS, true );
739 0 : }
740 :
741 0 : bool ScUndoDeleteMulti::CanRepeat(SfxRepeatTarget& rTarget) const
742 : {
743 0 : return rTarget.ISA(ScTabViewTarget);
744 : }
745 :
746 1 : ScUndoCut::ScUndoCut( ScDocShell* pNewDocShell,
747 : ScRange aRange, ScAddress aOldEnd, const ScMarkData& rMark,
748 : ScDocument* pNewUndoDoc ) :
749 : ScBlockUndo( pNewDocShell, ScRange(aRange.aStart, aOldEnd), SC_UNDO_AUTOHEIGHT ),
750 : aMarkData( rMark ),
751 : pUndoDoc( pNewUndoDoc ),
752 1 : aExtendedRange( aRange )
753 : {
754 1 : SetChangeTrack();
755 1 : }
756 :
757 2 : ScUndoCut::~ScUndoCut()
758 : {
759 1 : delete pUndoDoc;
760 1 : }
761 :
762 0 : OUString ScUndoCut::GetComment() const
763 : {
764 0 : return ScGlobal::GetRscString( STR_UNDO_CUT ); // "cut"
765 : }
766 :
767 2 : void ScUndoCut::SetChangeTrack()
768 : {
769 2 : ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
770 2 : if ( pChangeTrack )
771 : pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
772 0 : nStartChangeAction, nEndChangeAction, SC_CACM_CUT );
773 : else
774 2 : nStartChangeAction = nEndChangeAction = 0;
775 2 : }
776 :
777 3 : void ScUndoCut::DoChange( const bool bUndo )
778 : {
779 3 : ScDocument& rDoc = pDocShell->GetDocument();
780 3 : sal_uInt16 nExtFlags = 0;
781 :
782 : // do not undo/redo objects and note captions, they are handled via drawing undo
783 3 : InsertDeleteFlags nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
784 :
785 3 : if (bUndo) // only for Undo
786 : {
787 : // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
788 2 : SCTAB nTabCount = rDoc.GetTableCount();
789 2 : ScRange aCopyRange = aExtendedRange;
790 2 : aCopyRange.aStart.SetTab(0);
791 2 : aCopyRange.aEnd.SetTab(nTabCount-1);
792 2 : pUndoDoc->CopyToDocument( aCopyRange, nUndoFlags, false, &rDoc );
793 2 : ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
794 2 : if ( pChangeTrack )
795 0 : pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
796 :
797 2 : BroadcastChanges(aCopyRange);
798 : }
799 : else // only for Redo
800 : {
801 1 : pDocShell->UpdatePaintExt( nExtFlags, aExtendedRange );
802 1 : rDoc.DeleteArea( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
803 2 : aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(), aMarkData, nUndoFlags );
804 1 : SetChangeTrack();
805 : }
806 :
807 3 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
808 3 : if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
809 3 : /*A*/ pDocShell->PostPaint( aExtendedRange, PAINT_GRID, nExtFlags );
810 :
811 3 : if ( !bUndo ) // draw redo after updating row heights
812 1 : RedoSdrUndoAction( pDrawUndo ); //! include in ScBlockUndo?
813 :
814 3 : pDocShell->PostDataChanged();
815 3 : if (pViewShell)
816 0 : pViewShell->CellContentChanged();
817 3 : }
818 :
819 2 : void ScUndoCut::Undo()
820 : {
821 2 : BeginUndo();
822 2 : DoChange( true );
823 2 : EndUndo();
824 2 : }
825 :
826 1 : void ScUndoCut::Redo()
827 : {
828 1 : BeginRedo();
829 1 : ScDocument& rDoc = pDocShell->GetDocument();
830 1 : EnableDrawAdjust( &rDoc, false ); //! include in ScBlockUndo?
831 1 : DoChange( false );
832 1 : EnableDrawAdjust( &rDoc, true ); //! include in ScBlockUndo?
833 1 : EndRedo();
834 1 : }
835 :
836 0 : void ScUndoCut::Repeat(SfxRepeatTarget& rTarget)
837 : {
838 0 : if (rTarget.ISA(ScTabViewTarget))
839 0 : static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->CutToClip( NULL, true );
840 0 : }
841 :
842 0 : bool ScUndoCut::CanRepeat(SfxRepeatTarget& rTarget) const
843 : {
844 0 : return rTarget.ISA(ScTabViewTarget);
845 : }
846 :
847 32 : ScUndoPaste::ScUndoPaste( ScDocShell* pNewDocShell, const ScRangeList& rRanges,
848 : const ScMarkData& rMark,
849 : ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc,
850 : InsertDeleteFlags nNewFlags,
851 : ScRefUndoData* pRefData,
852 : bool bRedoIsFilled, const ScUndoPasteOptions* pOptions ) :
853 : ScMultiBlockUndo( pNewDocShell, rRanges, SC_UNDO_SIMPLE ),
854 : aMarkData( rMark ),
855 : pUndoDoc( pNewUndoDoc ),
856 : pRedoDoc( pNewRedoDoc ),
857 : nFlags( nNewFlags ),
858 : pRefUndoData( pRefData ),
859 : pRefRedoData( NULL ),
860 32 : bRedoFilled( bRedoIsFilled )
861 : {
862 32 : if ( pRefUndoData )
863 3 : pRefUndoData->DeleteUnchanged( &pDocShell->GetDocument() );
864 :
865 32 : if ( pOptions )
866 17 : aPasteOptions = *pOptions; // used only for Repeat
867 :
868 32 : SetChangeTrack();
869 32 : }
870 :
871 94 : ScUndoPaste::~ScUndoPaste()
872 : {
873 32 : delete pUndoDoc;
874 32 : delete pRedoDoc;
875 32 : delete pRefUndoData;
876 32 : delete pRefRedoData;
877 62 : }
878 :
879 38 : OUString ScUndoPaste::GetComment() const
880 : {
881 38 : return ScGlobal::GetRscString( STR_UNDO_PASTE ); // "paste"
882 : }
883 :
884 35 : void ScUndoPaste::SetChangeTrack()
885 : {
886 35 : ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
887 35 : if ( pChangeTrack && (nFlags & IDF_CONTENTS) )
888 : {
889 0 : for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
890 : {
891 0 : pChangeTrack->AppendContentRange(*maBlockRanges[i], pUndoDoc,
892 0 : nStartChangeAction, nEndChangeAction, SC_CACM_PASTE );
893 : }
894 : }
895 : else
896 35 : nStartChangeAction = nEndChangeAction = 0;
897 35 : }
898 :
899 8 : void ScUndoPaste::DoChange(bool bUndo)
900 : {
901 8 : ScDocument& rDoc = pDocShell->GetDocument();
902 :
903 : // RefUndoData for redo is created before first undo
904 : // (with DeleteUnchanged after the DoUndo call)
905 8 : bool bCreateRedoData = ( bUndo && pRefUndoData && !pRefRedoData );
906 8 : if ( bCreateRedoData )
907 3 : pRefRedoData = new ScRefUndoData( &rDoc );
908 :
909 8 : ScRefUndoData* pWorkRefData = bUndo ? pRefUndoData : pRefRedoData;
910 :
911 : // Always back-up either all or none of the content for Undo
912 8 : InsertDeleteFlags nUndoFlags = IDF_NONE;
913 8 : if (nFlags & IDF_CONTENTS)
914 8 : nUndoFlags |= IDF_CONTENTS;
915 8 : if (nFlags & IDF_ATTRIB)
916 7 : nUndoFlags |= IDF_ATTRIB;
917 :
918 : // do not undo/redo objects and note captions, they are handled via drawing undo
919 8 : (nUndoFlags &= ~IDF_OBJECTS) |= IDF_NOCAPTIONS;
920 :
921 8 : bool bPaintAll = false;
922 :
923 8 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
924 :
925 8 : SCTAB nTabCount = rDoc.GetTableCount();
926 8 : if ( bUndo && !bRedoFilled )
927 : {
928 3 : if (!pRedoDoc)
929 : {
930 3 : bool bColInfo = true;
931 3 : bool bRowInfo = true;
932 3 : for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
933 : {
934 3 : const ScRange& r = *maBlockRanges[i];
935 3 : bColInfo &= (r.aStart.Row() == 0 && r.aEnd.Row() == MAXROW);
936 3 : bRowInfo &= (r.aStart.Col() == 0 && r.aEnd.Col() == MAXCOL);
937 3 : if (!bColInfo && !bRowInfo)
938 3 : break;
939 : }
940 :
941 3 : pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
942 3 : pRedoDoc->InitUndoSelected( &rDoc, aMarkData, bColInfo, bRowInfo );
943 : }
944 : // read "redo" data from the document in the first undo
945 : // all sheets - CopyToDocument skips those that don't exist in pRedoDoc
946 6 : for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
947 : {
948 3 : ScRange aCopyRange = *maBlockRanges[i];
949 3 : aCopyRange.aStart.SetTab(0);
950 3 : aCopyRange.aEnd.SetTab(nTabCount-1);
951 3 : rDoc.CopyToDocument( aCopyRange, nUndoFlags, false, pRedoDoc );
952 3 : bRedoFilled = true;
953 : }
954 : }
955 :
956 8 : sal_uInt16 nExtFlags = 0;
957 8 : pDocShell->UpdatePaintExt(nExtFlags, maBlockRanges.Combine());
958 :
959 8 : rDoc.ForgetNoteCaptions(maBlockRanges);
960 8 : aMarkData.MarkToMulti();
961 8 : rDoc.DeleteSelection(nUndoFlags, aMarkData, false); // no broadcasting here
962 16 : for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
963 8 : rDoc.BroadcastCells(*maBlockRanges[i], SC_HINT_DATACHANGED);
964 :
965 8 : aMarkData.MarkToSimple();
966 :
967 8 : SCTAB nFirstSelected = aMarkData.GetFirstSelected();
968 :
969 8 : if ( !bUndo && pRedoDoc ) // Redo: UndoToDocument before handling RefData
970 : {
971 6 : for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
972 : {
973 3 : ScRange aRange = *maBlockRanges[i];
974 3 : aRange.aStart.SetTab(nFirstSelected);
975 3 : aRange.aEnd.SetTab(nFirstSelected);
976 3 : pRedoDoc->UndoToDocument(aRange, nUndoFlags, false, &rDoc);
977 3 : ScMarkData::iterator itr = aMarkData.begin(), itrEnd = aMarkData.end();
978 6 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
979 : {
980 3 : if (*itr == nFirstSelected)
981 3 : continue;
982 :
983 0 : aRange.aStart.SetTab(*itr);
984 0 : aRange.aEnd.SetTab(*itr);
985 0 : pRedoDoc->CopyToDocument( aRange, nUndoFlags, false, &rDoc );
986 : }
987 : }
988 : }
989 :
990 8 : if (pWorkRefData)
991 : {
992 5 : pWorkRefData->DoUndo( &rDoc, true ); // true = bSetChartRangeLists for SetChartListenerCollection
993 10 : if (!maBlockRanges.empty() &&
994 5 : rDoc.RefreshAutoFilter(0, 0, MAXCOL, MAXROW, maBlockRanges[0]->aStart.Tab()))
995 0 : bPaintAll = true;
996 : }
997 :
998 8 : if ( bCreateRedoData && pRefRedoData )
999 3 : pRefRedoData->DeleteUnchanged( &rDoc );
1000 :
1001 8 : if (bUndo) // Undo: UndoToDocument after handling RefData
1002 : {
1003 10 : for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)
1004 : {
1005 5 : ScRange aRange = *maBlockRanges[i];
1006 5 : ScMarkData::iterator itr = aMarkData.begin(), itrEnd = aMarkData.end();
1007 10 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
1008 : {
1009 5 : aRange.aStart.SetTab(*itr);
1010 5 : aRange.aEnd.SetTab(*itr);
1011 5 : pUndoDoc->UndoToDocument(aRange, nUndoFlags, false, &rDoc);
1012 : }
1013 : }
1014 : }
1015 :
1016 8 : if ( bUndo )
1017 : {
1018 5 : ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
1019 5 : if ( pChangeTrack )
1020 0 : pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1021 : }
1022 : else
1023 3 : SetChangeTrack();
1024 :
1025 8 : ScRangeList aDrawRanges(maBlockRanges);
1026 8 : sal_uInt16 nPaint = PAINT_GRID;
1027 16 : for (size_t i = 0, n = aDrawRanges.size(); i < n; ++i)
1028 : {
1029 8 : ScRange& rDrawRange = *aDrawRanges[i];
1030 8 : rDoc.ExtendMerge(rDrawRange, true); // only needed for single sheet (text/rtf etc.)
1031 8 : if (bPaintAll)
1032 : {
1033 0 : rDrawRange.aStart.SetCol(0);
1034 0 : rDrawRange.aStart.SetRow(0);
1035 0 : rDrawRange.aEnd.SetCol(MAXCOL);
1036 0 : rDrawRange.aEnd.SetRow(MAXROW);
1037 0 : nPaint |= PAINT_TOP | PAINT_LEFT;
1038 0 : if (pViewShell)
1039 0 : pViewShell->AdjustBlockHeight(false);
1040 : }
1041 : else
1042 : {
1043 8 : if (maBlockRanges[i]->aStart.Row() == 0 && maBlockRanges[i]->aEnd.Row() == MAXROW) // whole column
1044 : {
1045 0 : nPaint |= PAINT_TOP;
1046 0 : rDrawRange.aEnd.SetCol(MAXCOL);
1047 : }
1048 8 : if (maBlockRanges[i]->aStart.Col() == 0 && maBlockRanges[i]->aEnd.Col() == MAXCOL) // whole row
1049 : {
1050 0 : nPaint |= PAINT_LEFT;
1051 0 : rDrawRange.aEnd.SetRow(MAXROW);
1052 : }
1053 8 : if (pViewShell && pViewShell->AdjustBlockHeight(false))
1054 : {
1055 0 : rDrawRange.aStart.SetCol(0);
1056 0 : rDrawRange.aStart.SetRow(0);
1057 0 : rDrawRange.aEnd.SetCol(MAXCOL);
1058 0 : rDrawRange.aEnd.SetRow(MAXROW);
1059 0 : nPaint |= PAINT_LEFT;
1060 : }
1061 8 : pDocShell->UpdatePaintExt(nExtFlags, rDrawRange);
1062 : }
1063 : }
1064 :
1065 8 : if ( !bUndo ) // draw redo after updating row heights
1066 3 : RedoSdrUndoAction(mpDrawUndo);
1067 :
1068 8 : pDocShell->PostPaint(aDrawRanges, nPaint, nExtFlags);
1069 :
1070 8 : pDocShell->PostDataChanged();
1071 8 : if (pViewShell)
1072 0 : pViewShell->CellContentChanged();
1073 8 : }
1074 :
1075 5 : void ScUndoPaste::Undo()
1076 : {
1077 5 : BeginUndo();
1078 5 : DoChange(true);
1079 5 : if (!maBlockRanges.empty())
1080 5 : ShowTable(*maBlockRanges.front());
1081 5 : EndUndo();
1082 5 : SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1083 5 : }
1084 :
1085 3 : void ScUndoPaste::Redo()
1086 : {
1087 3 : BeginRedo();
1088 3 : ScDocument& rDoc = pDocShell->GetDocument();
1089 3 : EnableDrawAdjust( &rDoc, false ); //! include in ScBlockUndo?
1090 3 : DoChange( false );
1091 3 : EnableDrawAdjust( &rDoc, true ); //! include in ScBlockUndo?
1092 3 : EndRedo();
1093 3 : SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1094 3 : }
1095 :
1096 0 : void ScUndoPaste::Repeat(SfxRepeatTarget& rTarget)
1097 : {
1098 0 : if (rTarget.ISA(ScTabViewTarget))
1099 : {
1100 0 : ScTabViewShell* pViewSh = static_cast<ScTabViewTarget&>(rTarget).GetViewShell();
1101 0 : ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pViewSh->GetActiveWin() );
1102 0 : if (pOwnClip)
1103 : {
1104 : // keep a reference in case the clipboard is changed during PasteFromClip
1105 0 : com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable> aOwnClipRef( pOwnClip );
1106 : pViewSh->PasteFromClip( nFlags, pOwnClip->GetDocument(),
1107 : aPasteOptions.nFunction, aPasteOptions.bSkipEmpty, aPasteOptions.bTranspose,
1108 : aPasteOptions.bAsLink, aPasteOptions.eMoveMode, IDF_NONE,
1109 0 : true ); // allow warning dialog
1110 : }
1111 : }
1112 0 : }
1113 :
1114 24 : bool ScUndoPaste::CanRepeat(SfxRepeatTarget& rTarget) const
1115 : {
1116 24 : return rTarget.ISA(ScTabViewTarget);
1117 : }
1118 :
1119 12 : ScUndoDragDrop::ScUndoDragDrop( ScDocShell* pNewDocShell,
1120 : const ScRange& rRange, ScAddress aNewDestPos, bool bNewCut,
1121 : ScDocument* pUndoDocument, ScRefUndoData* pRefData, bool bScenario ) :
1122 : ScMoveUndo( pNewDocShell, pUndoDocument, pRefData, SC_UNDO_REFFIRST ),
1123 : mnPaintExtFlags( 0 ),
1124 : aSrcRange( rRange ),
1125 : bCut( bNewCut ),
1126 12 : bKeepScenarioFlags( bScenario )
1127 : {
1128 12 : ScAddress aDestEnd(aNewDestPos);
1129 12 : aDestEnd.IncRow(aSrcRange.aEnd.Row() - aSrcRange.aStart.Row());
1130 12 : aDestEnd.IncCol(aSrcRange.aEnd.Col() - aSrcRange.aStart.Col());
1131 12 : aDestEnd.IncTab(aSrcRange.aEnd.Tab() - aSrcRange.aStart.Tab());
1132 :
1133 12 : bool bIncludeFiltered = bCut;
1134 12 : if ( !bIncludeFiltered )
1135 : {
1136 : // find number of non-filtered rows
1137 3 : SCROW nPastedCount = pDocShell->GetDocument().CountNonFilteredRows(
1138 6 : aSrcRange.aStart.Row(), aSrcRange.aEnd.Row(), aSrcRange.aStart.Tab());
1139 :
1140 3 : if ( nPastedCount == 0 )
1141 0 : nPastedCount = 1;
1142 3 : aDestEnd.SetRow( aNewDestPos.Row() + nPastedCount - 1 );
1143 : }
1144 :
1145 12 : aDestRange.aStart = aNewDestPos;
1146 12 : aDestRange.aEnd = aDestEnd;
1147 :
1148 12 : SetChangeTrack();
1149 12 : }
1150 :
1151 24 : ScUndoDragDrop::~ScUndoDragDrop()
1152 : {
1153 24 : }
1154 :
1155 21 : OUString ScUndoDragDrop::GetComment() const
1156 : { // "Move" : "Copy"
1157 : return bCut ?
1158 : ScGlobal::GetRscString( STR_UNDO_MOVE ) :
1159 21 : ScGlobal::GetRscString( STR_UNDO_COPY );
1160 : }
1161 :
1162 14 : void ScUndoDragDrop::SetChangeTrack()
1163 : {
1164 14 : ScChangeTrack* pChangeTrack = pDocShell->GetDocument().GetChangeTrack();
1165 14 : if ( pChangeTrack )
1166 : {
1167 0 : if ( bCut )
1168 : {
1169 0 : nStartChangeAction = pChangeTrack->GetActionMax() + 1;
1170 0 : pChangeTrack->AppendMove( aSrcRange, aDestRange, pRefUndoDoc );
1171 0 : nEndChangeAction = pChangeTrack->GetActionMax();
1172 : }
1173 : else
1174 : pChangeTrack->AppendContentRange( aDestRange, pRefUndoDoc,
1175 0 : nStartChangeAction, nEndChangeAction );
1176 : }
1177 : else
1178 14 : nStartChangeAction = nEndChangeAction = 0;
1179 14 : }
1180 :
1181 17 : void ScUndoDragDrop::PaintArea( ScRange aRange, sal_uInt16 nExtFlags ) const
1182 : {
1183 17 : sal_uInt16 nPaint = PAINT_GRID;
1184 17 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1185 17 : ScDocument& rDoc = pDocShell->GetDocument();
1186 :
1187 17 : if (pViewShell)
1188 : {
1189 0 : ScopedVclPtrInstance< VirtualDevice > pVirtDev;
1190 0 : ScViewData& rViewData = pViewShell->GetViewData();
1191 : sc::RowHeightContext aCxt(
1192 0 : rViewData.GetPPTX(), rViewData.GetPPTY(), rViewData.GetZoomX(), rViewData.GetZoomY(),
1193 0 : pVirtDev);
1194 :
1195 0 : if (rDoc.SetOptimalHeight(aCxt, aRange.aStart.Row(), aRange.aEnd.Row(), aRange.aStart.Tab()))
1196 : {
1197 0 : aRange.aStart.SetCol(0);
1198 0 : aRange.aEnd.SetCol(MAXCOL);
1199 0 : aRange.aEnd.SetRow(MAXROW);
1200 0 : nPaint |= PAINT_LEFT;
1201 0 : }
1202 : }
1203 :
1204 17 : if ( bKeepScenarioFlags )
1205 : {
1206 : // Copy scenario -> also paint scenario boarder
1207 0 : aRange.aStart.SetCol(0);
1208 0 : aRange.aStart.SetRow(0);
1209 0 : aRange.aEnd.SetCol(MAXCOL);
1210 0 : aRange.aEnd.SetRow(MAXROW);
1211 : }
1212 :
1213 : // column/row info (width/height) included if whole columns/rows were copied
1214 17 : if ( aSrcRange.aStart.Col() == 0 && aSrcRange.aEnd.Col() == MAXCOL )
1215 : {
1216 0 : nPaint |= PAINT_LEFT;
1217 0 : aRange.aEnd.SetRow(MAXROW);
1218 : }
1219 17 : if ( aSrcRange.aStart.Row() == 0 && aSrcRange.aEnd.Row() == MAXROW )
1220 : {
1221 0 : nPaint |= PAINT_TOP;
1222 0 : aRange.aEnd.SetCol(MAXCOL);
1223 : }
1224 :
1225 17 : pDocShell->PostPaint( aRange, nPaint, nExtFlags );
1226 17 : }
1227 :
1228 13 : void ScUndoDragDrop::DoUndo( ScRange aRange )
1229 : {
1230 13 : ScDocument& rDoc = pDocShell->GetDocument();
1231 :
1232 13 : ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
1233 13 : if ( pChangeTrack )
1234 0 : pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1235 :
1236 : // Database range before data, so that the Autofilter button match up in ExtendMerge
1237 :
1238 13 : ScRange aPaintRange = aRange;
1239 13 : rDoc.ExtendMerge( aPaintRange ); // before deleting
1240 :
1241 13 : pDocShell->UpdatePaintExt(mnPaintExtFlags, aPaintRange);
1242 :
1243 : // do not undo objects and note captions, they are handled via drawing undo
1244 13 : InsertDeleteFlags nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
1245 :
1246 13 : rDoc.DeleteAreaTab( aRange, nUndoFlags );
1247 13 : pRefUndoDoc->CopyToDocument( aRange, nUndoFlags, false, &rDoc );
1248 13 : if ( rDoc.HasAttrib( aRange, HASATTR_MERGED ) )
1249 0 : rDoc.ExtendMerge( aRange, true );
1250 :
1251 13 : aPaintRange.aEnd.SetCol( std::max( aPaintRange.aEnd.Col(), aRange.aEnd.Col() ) );
1252 13 : aPaintRange.aEnd.SetRow( std::max( aPaintRange.aEnd.Row(), aRange.aEnd.Row() ) );
1253 :
1254 13 : pDocShell->UpdatePaintExt(mnPaintExtFlags, aPaintRange);
1255 13 : maPaintRanges.Join(aPaintRange);
1256 13 : }
1257 :
1258 : namespace {
1259 :
1260 18 : class DataChangeNotifier : std::unary_function<SvtListener*, void>
1261 : {
1262 : ScHint maHint;
1263 : public:
1264 6 : DataChangeNotifier() : maHint(SC_HINT_DATACHANGED, ScAddress()) {}
1265 :
1266 1 : void operator() ( SvtListener* p )
1267 : {
1268 1 : p->Notify(maHint);
1269 1 : }
1270 : };
1271 :
1272 : }
1273 :
1274 7 : void ScUndoDragDrop::Undo()
1275 : {
1276 7 : mnPaintExtFlags = 0;
1277 7 : maPaintRanges.RemoveAll();
1278 :
1279 7 : BeginUndo();
1280 :
1281 7 : if (bCut)
1282 : {
1283 : // During undo, we move cells from aDestRange to aSrcRange.
1284 :
1285 6 : ScDocument& rDoc = pDocShell->GetDocument();
1286 :
1287 6 : SCCOL nColDelta = aSrcRange.aStart.Col() - aDestRange.aStart.Col();
1288 6 : SCROW nRowDelta = aSrcRange.aStart.Row() - aDestRange.aStart.Row();
1289 6 : SCTAB nTabDelta = aSrcRange.aStart.Tab() - aDestRange.aStart.Tab();
1290 :
1291 6 : sc::RefUpdateContext aCxt(rDoc);
1292 6 : aCxt.meMode = URM_MOVE;
1293 6 : aCxt.maRange = aSrcRange;
1294 6 : aCxt.mnColDelta = nColDelta;
1295 6 : aCxt.mnRowDelta = nRowDelta;
1296 6 : aCxt.mnTabDelta = nTabDelta;
1297 :
1298 : // Global range names.
1299 6 : ScRangeName* pName = rDoc.GetRangeName();
1300 6 : if (pName)
1301 6 : pName->UpdateReference(aCxt);
1302 :
1303 6 : SCTAB nTabCount = rDoc.GetTableCount();
1304 13 : for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
1305 : {
1306 : // Sheet-local range names.
1307 7 : pName = rDoc.GetRangeName(nTab);
1308 7 : if (pName)
1309 7 : pName->UpdateReference(aCxt, nTab);
1310 : }
1311 :
1312 : // Notify all listeners of the destination range, and have them update their references.
1313 12 : sc::RefMovedHint aHint(aDestRange, ScAddress(nColDelta, nRowDelta, nTabDelta), aCxt);
1314 6 : rDoc.BroadcastRefMoved(aHint);
1315 :
1316 6 : ScValidationDataList* pValidList = rDoc.GetValidationList();
1317 6 : if (pValidList)
1318 : {
1319 : // Update the references of validation entries.
1320 0 : pValidList->UpdateReference(aCxt);
1321 : }
1322 :
1323 6 : DoUndo(aDestRange);
1324 6 : DoUndo(aSrcRange);
1325 :
1326 : // Notify all area listeners whose listened areas are partially moved, to
1327 : // recalculate.
1328 12 : std::vector<SvtListener*> aListeners;
1329 6 : rDoc.CollectAllAreaListeners(aListeners, aSrcRange, sc::AreaPartialOverlap);
1330 :
1331 : // Remove any duplicate listener entries. We must ensure that we notify
1332 : // each unique listener only once.
1333 6 : std::sort(aListeners.begin(), aListeners.end());
1334 6 : aListeners.erase(std::unique(aListeners.begin(), aListeners.end()), aListeners.end());
1335 :
1336 12 : std::for_each(aListeners.begin(), aListeners.end(), DataChangeNotifier());
1337 : }
1338 : else
1339 1 : DoUndo(aDestRange);
1340 :
1341 20 : for (size_t i = 0; i < maPaintRanges.size(); ++i)
1342 : {
1343 13 : const ScRange* p = maPaintRanges[i];
1344 13 : PaintArea(*p, mnPaintExtFlags);
1345 : }
1346 :
1347 7 : EndUndo();
1348 7 : SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1349 7 : }
1350 :
1351 2 : void ScUndoDragDrop::Redo()
1352 : {
1353 2 : BeginRedo();
1354 :
1355 2 : ScDocument& rDoc = pDocShell->GetDocument();
1356 2 : boost::scoped_ptr<ScDocument> pClipDoc(new ScDocument( SCDOCMODE_CLIP ));
1357 :
1358 2 : EnableDrawAdjust( &rDoc, false ); //! include in ScBlockUndo?
1359 :
1360 : // do not undo/redo objects and note captions, they are handled via drawing undo
1361 2 : InsertDeleteFlags nRedoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
1362 :
1363 : /* TODO: Redoing note captions is quite tricky due to the fact that a
1364 : helper clip document is used. While (re-)pasting the contents to the
1365 : destination area, the original pointers to the captions created while
1366 : dropping have to be restored. A simple CopyFromClip() would create new
1367 : caption objects that are not tracked by drawing undo, and the captions
1368 : restored by drawing redo would live without cell note objects pointing
1369 : to them. So, first, CopyToClip() and CopyFromClip() are called without
1370 : cloning the caption objects. This leads to cell notes pointing to the
1371 : wrong captions from source area that will be removed by drawing redo
1372 : later. Second, the pointers to the new captions have to be restored.
1373 : Sadly, currently these pointers are not stored anywhere but in the list
1374 : of drawing undo actions. */
1375 :
1376 : SCTAB nTab;
1377 4 : ScMarkData aSourceMark;
1378 4 : for (nTab=aSrcRange.aStart.Tab(); nTab<=aSrcRange.aEnd.Tab(); nTab++)
1379 2 : aSourceMark.SelectTable( nTab, true );
1380 :
1381 : // do not clone objects and note captions into clipdoc (see above)
1382 : // but at least copy notes
1383 4 : ScClipParam aClipParam(aSrcRange, bCut);
1384 2 : rDoc.CopyToClip(aClipParam, pClipDoc.get(), &aSourceMark, false, bKeepScenarioFlags, false, true);
1385 :
1386 2 : if (bCut)
1387 : {
1388 2 : ScRange aSrcPaintRange = aSrcRange;
1389 2 : rDoc.ExtendMerge( aSrcPaintRange ); // before deleting
1390 2 : sal_uInt16 nExtFlags = 0;
1391 2 : pDocShell->UpdatePaintExt( nExtFlags, aSrcPaintRange );
1392 2 : rDoc.DeleteAreaTab( aSrcRange, nRedoFlags );
1393 2 : PaintArea( aSrcPaintRange, nExtFlags );
1394 : }
1395 :
1396 4 : ScMarkData aDestMark;
1397 4 : for (nTab=aDestRange.aStart.Tab(); nTab<=aDestRange.aEnd.Tab(); nTab++)
1398 2 : aDestMark.SelectTable( nTab, true );
1399 :
1400 2 : bool bIncludeFiltered = bCut;
1401 : // TODO: restore old note captions instead of cloning new captions...
1402 2 : rDoc.CopyFromClip( aDestRange, aDestMark, IDF_ALL & ~IDF_OBJECTS, NULL, pClipDoc.get(), true, false, bIncludeFiltered );
1403 :
1404 2 : if (bCut)
1405 4 : for (nTab=aSrcRange.aStart.Tab(); nTab<=aSrcRange.aEnd.Tab(); nTab++)
1406 2 : rDoc.RefreshAutoFilter( aSrcRange.aStart.Col(), aSrcRange.aStart.Row(),
1407 4 : aSrcRange.aEnd.Col(), aSrcRange.aEnd.Row(), nTab );
1408 :
1409 : // skipped rows and merged cells don't mix
1410 2 : if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
1411 0 : pDocShell->GetDocFunc().UnmergeCells( aDestRange, false );
1412 :
1413 4 : for (nTab=aDestRange.aStart.Tab(); nTab<=aDestRange.aEnd.Tab(); nTab++)
1414 : {
1415 2 : SCCOL nEndCol = aDestRange.aEnd.Col();
1416 2 : SCROW nEndRow = aDestRange.aEnd.Row();
1417 2 : rDoc.ExtendMerge( aDestRange.aStart.Col(), aDestRange.aStart.Row(),
1418 4 : nEndCol, nEndRow, nTab, true );
1419 2 : PaintArea( ScRange( aDestRange.aStart.Col(), aDestRange.aStart.Row(), nTab,
1420 4 : nEndCol, nEndRow, nTab ), 0 );
1421 : }
1422 :
1423 2 : SetChangeTrack();
1424 :
1425 2 : pClipDoc.reset();
1426 2 : ShowTable( aDestRange.aStart.Tab() );
1427 :
1428 2 : RedoSdrUndoAction( pDrawUndo ); //! include in ScBlockUndo?
1429 2 : EnableDrawAdjust( &rDoc, true ); //! include in ScBlockUndo?
1430 :
1431 2 : EndRedo();
1432 4 : SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1433 2 : }
1434 :
1435 0 : void ScUndoDragDrop::Repeat(SfxRepeatTarget& /* rTarget */)
1436 : {
1437 0 : }
1438 :
1439 0 : bool ScUndoDragDrop::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1440 : {
1441 0 : return false; // not possible
1442 : }
1443 :
1444 : // Insert list containing range names
1445 : // (Insert|Name|Insert =>[List])
1446 5 : ScUndoListNames::ScUndoListNames( ScDocShell* pNewDocShell, const ScRange& rRange,
1447 : ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc ) :
1448 : ScBlockUndo( pNewDocShell, rRange, SC_UNDO_AUTOHEIGHT ),
1449 : pUndoDoc( pNewUndoDoc ),
1450 5 : pRedoDoc( pNewRedoDoc )
1451 : {
1452 5 : }
1453 :
1454 15 : ScUndoListNames::~ScUndoListNames()
1455 : {
1456 5 : delete pUndoDoc;
1457 5 : delete pRedoDoc;
1458 10 : }
1459 :
1460 9 : OUString ScUndoListNames::GetComment() const
1461 : {
1462 9 : return ScGlobal::GetRscString( STR_UNDO_LISTNAMES );
1463 : }
1464 :
1465 0 : void ScUndoListNames::DoChange( ScDocument* pSrcDoc ) const
1466 : {
1467 0 : ScDocument& rDoc = pDocShell->GetDocument();
1468 :
1469 0 : rDoc.DeleteAreaTab( aBlockRange, IDF_ALL );
1470 0 : pSrcDoc->CopyToDocument( aBlockRange, IDF_ALL, false, &rDoc );
1471 0 : pDocShell->PostPaint( aBlockRange, PAINT_GRID );
1472 0 : pDocShell->PostDataChanged();
1473 0 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1474 0 : if (pViewShell)
1475 0 : pViewShell->CellContentChanged();
1476 0 : }
1477 :
1478 0 : void ScUndoListNames::Undo()
1479 : {
1480 0 : BeginUndo();
1481 0 : DoChange(pUndoDoc);
1482 0 : EndUndo();
1483 0 : }
1484 :
1485 0 : void ScUndoListNames::Redo()
1486 : {
1487 0 : BeginRedo();
1488 0 : DoChange(pRedoDoc);
1489 0 : EndRedo();
1490 0 : }
1491 :
1492 0 : void ScUndoListNames::Repeat(SfxRepeatTarget& rTarget)
1493 : {
1494 0 : if (rTarget.ISA(ScTabViewTarget))
1495 0 : static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->InsertNameList();
1496 0 : }
1497 :
1498 2 : bool ScUndoListNames::CanRepeat(SfxRepeatTarget& rTarget) const
1499 : {
1500 2 : return rTarget.ISA(ScTabViewTarget);
1501 : }
1502 :
1503 3 : ScUndoConditionalFormat::ScUndoConditionalFormat(ScDocShell* pNewDocShell,
1504 : ScDocument* pUndoDoc, ScDocument* pRedoDoc, const ScRange& rRange):
1505 : ScSimpleUndo( pNewDocShell ),
1506 : mpUndoDoc(pUndoDoc),
1507 : mpRedoDoc(pRedoDoc),
1508 3 : maRange(rRange)
1509 : {
1510 3 : }
1511 :
1512 6 : ScUndoConditionalFormat::~ScUndoConditionalFormat()
1513 : {
1514 6 : }
1515 :
1516 7 : OUString ScUndoConditionalFormat::GetComment() const
1517 : {
1518 7 : return ScGlobal::GetRscString( STR_UNDO_CONDFORMAT );
1519 : }
1520 :
1521 0 : void ScUndoConditionalFormat::Undo()
1522 : {
1523 0 : DoChange(mpUndoDoc.get());
1524 0 : }
1525 :
1526 0 : void ScUndoConditionalFormat::Redo()
1527 : {
1528 0 : DoChange(mpRedoDoc.get());
1529 0 : }
1530 :
1531 0 : void ScUndoConditionalFormat::DoChange(ScDocument* pSrcDoc)
1532 : {
1533 0 : ScDocument& rDoc = pDocShell->GetDocument();
1534 :
1535 0 : rDoc.DeleteAreaTab( maRange, IDF_ALL );
1536 0 : pSrcDoc->CopyToDocument( maRange, IDF_ALL, false, &rDoc );
1537 0 : pDocShell->PostPaint( maRange, PAINT_GRID );
1538 0 : pDocShell->PostDataChanged();
1539 0 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1540 0 : if (pViewShell)
1541 0 : pViewShell->CellContentChanged();
1542 0 : }
1543 :
1544 0 : void ScUndoConditionalFormat::Repeat(SfxRepeatTarget& )
1545 : {
1546 0 : }
1547 :
1548 4 : bool ScUndoConditionalFormat::CanRepeat(SfxRepeatTarget& ) const
1549 : {
1550 4 : return false;
1551 : }
1552 :
1553 0 : ScUndoUseScenario::ScUndoUseScenario( ScDocShell* pNewDocShell,
1554 : const ScMarkData& rMark,
1555 : /*C*/ const ScArea& rDestArea,
1556 : ScDocument* pNewUndoDoc,
1557 : const OUString& rNewName ) :
1558 : ScSimpleUndo( pNewDocShell ),
1559 : pUndoDoc( pNewUndoDoc ),
1560 : aMarkData( rMark ),
1561 0 : aName( rNewName )
1562 : {
1563 0 : aRange.aStart.SetCol(rDestArea.nColStart);
1564 0 : aRange.aStart.SetRow(rDestArea.nRowStart);
1565 0 : aRange.aStart.SetTab(rDestArea.nTab);
1566 0 : aRange.aEnd.SetCol(rDestArea.nColEnd);
1567 0 : aRange.aEnd.SetRow(rDestArea.nRowEnd);
1568 0 : aRange.aEnd.SetTab(rDestArea.nTab);
1569 0 : }
1570 :
1571 0 : ScUndoUseScenario::~ScUndoUseScenario()
1572 : {
1573 0 : delete pUndoDoc;
1574 0 : }
1575 :
1576 0 : OUString ScUndoUseScenario::GetComment() const
1577 : {
1578 0 : return ScGlobal::GetRscString( STR_UNDO_USESCENARIO );
1579 : }
1580 :
1581 0 : void ScUndoUseScenario::Undo()
1582 : {
1583 0 : BeginUndo();
1584 :
1585 0 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1586 0 : if (pViewShell)
1587 : {
1588 0 : pViewShell->DoneBlockMode();
1589 0 : pViewShell->InitOwnBlockMode();
1590 : }
1591 :
1592 0 : ScDocument& rDoc = pDocShell->GetDocument();
1593 0 : rDoc.DeleteSelection( IDF_ALL, aMarkData );
1594 0 : pUndoDoc->CopyToDocument( aRange, IDF_ALL, true, &rDoc, &aMarkData );
1595 :
1596 : // scenario table
1597 0 : bool bFrame = false;
1598 0 : SCTAB nTab = aRange.aStart.Tab();
1599 0 : SCTAB nEndTab = nTab;
1600 0 : while ( pUndoDoc->HasTable(nEndTab+1) && pUndoDoc->IsScenario(nEndTab+1) )
1601 0 : ++nEndTab;
1602 0 : for (SCTAB i = nTab+1; i<=nEndTab; i++)
1603 : {
1604 : // Flags always
1605 0 : OUString aComment;
1606 0 : Color aColor;
1607 : sal_uInt16 nScenFlags;
1608 0 : pUndoDoc->GetScenarioData( i, aComment, aColor, nScenFlags );
1609 0 : rDoc.SetScenarioData( i, aComment, aColor, nScenFlags );
1610 0 : bool bActive = pUndoDoc->IsActiveScenario( i );
1611 0 : rDoc.SetActiveScenario( i, bActive );
1612 : // For copy-back scenario also consider content
1613 0 : if ( nScenFlags & SC_SCENARIO_TWOWAY )
1614 : {
1615 0 : rDoc.DeleteAreaTab( 0,0, MAXCOL,MAXROW, i, IDF_ALL );
1616 0 : pUndoDoc->CopyToDocument( 0,0,i, MAXCOL,MAXROW,i, IDF_ALL,false, &rDoc );
1617 : }
1618 0 : if ( nScenFlags & SC_SCENARIO_SHOWFRAME )
1619 0 : bFrame = true;
1620 0 : }
1621 :
1622 : // if visible borders, then paint all
1623 0 : if (bFrame)
1624 0 : pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_EXTRAS );
1625 : else
1626 0 : pDocShell->PostPaint( aRange, PAINT_GRID | PAINT_EXTRAS );
1627 0 : pDocShell->PostDataChanged();
1628 0 : if (pViewShell)
1629 0 : pViewShell->CellContentChanged();
1630 :
1631 0 : ShowTable( aRange.aStart.Tab() );
1632 :
1633 0 : EndUndo();
1634 0 : }
1635 :
1636 0 : void ScUndoUseScenario::Redo()
1637 : {
1638 0 : SCTAB nTab = aRange.aStart.Tab();
1639 0 : BeginRedo();
1640 :
1641 0 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1642 0 : if (pViewShell)
1643 : {
1644 0 : pViewShell->SetTabNo( nTab );
1645 0 : pViewShell->DoneBlockMode();
1646 0 : pViewShell->InitOwnBlockMode();
1647 : }
1648 :
1649 0 : pDocShell->UseScenario( nTab, aName, false );
1650 :
1651 0 : EndRedo();
1652 0 : }
1653 :
1654 0 : void ScUndoUseScenario::Repeat(SfxRepeatTarget& rTarget)
1655 : {
1656 0 : if (rTarget.ISA(ScTabViewTarget))
1657 : {
1658 0 : OUString aTemp = aName;
1659 0 : static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->UseScenario(aTemp);
1660 : }
1661 0 : }
1662 :
1663 0 : bool ScUndoUseScenario::CanRepeat(SfxRepeatTarget& rTarget) const
1664 : {
1665 0 : if (rTarget.ISA(ScTabViewTarget))
1666 : {
1667 0 : ScViewData& rViewData = static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->GetViewData();
1668 0 : return !rViewData.GetDocument()->IsScenario( rViewData.GetTabNo() );
1669 : }
1670 0 : return false;
1671 : }
1672 :
1673 0 : ScUndoSelectionStyle::ScUndoSelectionStyle( ScDocShell* pNewDocShell,
1674 : const ScMarkData& rMark,
1675 : const ScRange& rRange,
1676 : const OUString& rName,
1677 : ScDocument* pNewUndoDoc ) :
1678 : ScSimpleUndo( pNewDocShell ),
1679 : aMarkData( rMark ),
1680 : pUndoDoc( pNewUndoDoc ),
1681 : aStyleName( rName ),
1682 0 : aRange( rRange )
1683 : {
1684 0 : aMarkData.MarkToMulti();
1685 0 : }
1686 :
1687 0 : ScUndoSelectionStyle::~ScUndoSelectionStyle()
1688 : {
1689 0 : delete pUndoDoc;
1690 0 : }
1691 :
1692 0 : OUString ScUndoSelectionStyle::GetComment() const
1693 : {
1694 0 : return ScGlobal::GetRscString( STR_UNDO_APPLYCELLSTYLE );
1695 : }
1696 :
1697 0 : void ScUndoSelectionStyle::DoChange( const bool bUndo )
1698 : {
1699 0 : ScDocument& rDoc = pDocShell->GetDocument();
1700 :
1701 0 : SetViewMarkData( aMarkData );
1702 :
1703 0 : ScRange aWorkRange( aRange );
1704 0 : if ( rDoc.HasAttrib( aWorkRange, HASATTR_MERGED ) ) // Merged cells?
1705 0 : rDoc.ExtendMerge( aWorkRange, true );
1706 :
1707 0 : sal_uInt16 nExtFlags = 0;
1708 0 : pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
1709 :
1710 0 : if (bUndo) // if Undo then push back all old data again
1711 : {
1712 0 : SCTAB nTabCount = rDoc.GetTableCount();
1713 0 : ScRange aCopyRange = aWorkRange;
1714 0 : aCopyRange.aStart.SetTab(0);
1715 0 : aCopyRange.aEnd.SetTab(nTabCount-1);
1716 0 : pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, true, &rDoc, &aMarkData );
1717 : }
1718 : else // if Redo, then reapply style
1719 : {
1720 0 : ScStyleSheetPool* pStlPool = rDoc.GetStyleSheetPool();
1721 : ScStyleSheet* pStyleSheet =
1722 0 : static_cast<ScStyleSheet*>( pStlPool->Find( aStyleName, SFX_STYLE_FAMILY_PARA ) );
1723 0 : if (!pStyleSheet)
1724 : {
1725 : OSL_FAIL("StyleSheet not found");
1726 0 : return;
1727 : }
1728 0 : rDoc.ApplySelectionStyle( *pStyleSheet, aMarkData );
1729 : }
1730 :
1731 0 : pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
1732 :
1733 0 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1734 0 : if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
1735 0 : /*A*/ pDocShell->PostPaint( aWorkRange, PAINT_GRID | PAINT_EXTRAS, nExtFlags );
1736 :
1737 0 : ShowTable( aWorkRange.aStart.Tab() );
1738 : }
1739 :
1740 0 : void ScUndoSelectionStyle::Undo()
1741 : {
1742 0 : BeginUndo();
1743 0 : DoChange( true );
1744 0 : EndUndo();
1745 0 : }
1746 :
1747 0 : void ScUndoSelectionStyle::Redo()
1748 : {
1749 0 : BeginRedo();
1750 0 : DoChange( false );
1751 0 : EndRedo();
1752 0 : }
1753 :
1754 0 : void ScUndoSelectionStyle::Repeat(SfxRepeatTarget& rTarget)
1755 : {
1756 0 : if (rTarget.ISA(ScTabViewTarget))
1757 : {
1758 0 : ScDocument& rDoc = pDocShell->GetDocument();
1759 0 : ScStyleSheetPool* pStlPool = rDoc.GetStyleSheetPool();
1760 : ScStyleSheet* pStyleSheet = static_cast<ScStyleSheet*>( pStlPool->
1761 0 : Find( aStyleName, SFX_STYLE_FAMILY_PARA ));
1762 0 : if (!pStyleSheet)
1763 : {
1764 : OSL_FAIL("StyleSheet not found");
1765 0 : return;
1766 : }
1767 :
1768 0 : ScTabViewShell& rViewShell = *static_cast<ScTabViewTarget&>(rTarget).GetViewShell();
1769 0 : rViewShell.SetStyleSheetToMarked( pStyleSheet, true );
1770 : }
1771 : }
1772 :
1773 0 : bool ScUndoSelectionStyle::CanRepeat(SfxRepeatTarget& rTarget) const
1774 : {
1775 0 : return rTarget.ISA(ScTabViewTarget);
1776 : }
1777 :
1778 0 : sal_uInt16 ScUndoSelectionStyle::GetId() const
1779 : {
1780 0 : return STR_UNDO_APPLYCELLSTYLE;
1781 : }
1782 :
1783 2 : ScUndoEnterMatrix::ScUndoEnterMatrix( ScDocShell* pNewDocShell, const ScRange& rArea,
1784 : ScDocument* pNewUndoDoc, const OUString& rForm ) :
1785 : ScBlockUndo( pNewDocShell, rArea, SC_UNDO_SIMPLE ),
1786 : pUndoDoc( pNewUndoDoc ),
1787 2 : aFormula( rForm )
1788 : {
1789 2 : SetChangeTrack();
1790 2 : }
1791 :
1792 6 : ScUndoEnterMatrix::~ScUndoEnterMatrix()
1793 : {
1794 2 : delete pUndoDoc;
1795 4 : }
1796 :
1797 2 : OUString ScUndoEnterMatrix::GetComment() const
1798 : {
1799 2 : return ScGlobal::GetRscString( STR_UNDO_ENTERMATRIX );
1800 : }
1801 :
1802 2 : void ScUndoEnterMatrix::SetChangeTrack()
1803 : {
1804 2 : ScDocument& rDoc = pDocShell->GetDocument();
1805 2 : ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
1806 2 : if ( pChangeTrack )
1807 : pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
1808 0 : nStartChangeAction, nEndChangeAction );
1809 : else
1810 2 : nStartChangeAction = nEndChangeAction = 0;
1811 2 : }
1812 :
1813 0 : void ScUndoEnterMatrix::Undo()
1814 : {
1815 0 : BeginUndo();
1816 :
1817 0 : ScDocument& rDoc = pDocShell->GetDocument();
1818 :
1819 0 : rDoc.DeleteAreaTab( aBlockRange, IDF_ALL & ~IDF_NOTE );
1820 0 : pUndoDoc->CopyToDocument( aBlockRange, IDF_ALL & ~IDF_NOTE, false, &rDoc );
1821 0 : pDocShell->PostPaint( aBlockRange, PAINT_GRID );
1822 0 : pDocShell->PostDataChanged();
1823 0 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1824 0 : if (pViewShell)
1825 0 : pViewShell->CellContentChanged();
1826 :
1827 0 : ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
1828 0 : if ( pChangeTrack )
1829 0 : pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1830 :
1831 0 : EndUndo();
1832 0 : }
1833 :
1834 0 : void ScUndoEnterMatrix::Redo()
1835 : {
1836 0 : BeginRedo();
1837 :
1838 0 : ScDocument& rDoc = pDocShell->GetDocument();
1839 :
1840 0 : ScMarkData aDestMark;
1841 0 : aDestMark.SelectOneTable( aBlockRange.aStart.Tab() );
1842 0 : aDestMark.SetMarkArea( aBlockRange );
1843 :
1844 0 : rDoc.InsertMatrixFormula( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
1845 0 : aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(),
1846 0 : aDestMark, aFormula );
1847 :
1848 0 : SetChangeTrack();
1849 :
1850 0 : EndRedo();
1851 0 : }
1852 :
1853 0 : void ScUndoEnterMatrix::Repeat(SfxRepeatTarget& rTarget)
1854 : {
1855 0 : if (rTarget.ISA(ScTabViewTarget))
1856 : {
1857 0 : OUString aTemp = aFormula;
1858 0 : ScDocument& rDoc = pDocShell->GetDocument();
1859 0 : static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->EnterMatrix(aTemp, rDoc.GetGrammar());
1860 : }
1861 0 : }
1862 :
1863 0 : bool ScUndoEnterMatrix::CanRepeat(SfxRepeatTarget& rTarget) const
1864 : {
1865 0 : return rTarget.ISA(ScTabViewTarget);
1866 : }
1867 :
1868 7 : static ScRange lcl_GetMultiMarkRange( const ScMarkData& rMark )
1869 : {
1870 : OSL_ENSURE( rMark.IsMultiMarked(), "wrong mark type" );
1871 :
1872 7 : ScRange aRange;
1873 7 : rMark.GetMultiMarkArea( aRange );
1874 7 : return aRange;
1875 : }
1876 :
1877 6 : ScUndoIndent::ScUndoIndent( ScDocShell* pNewDocShell, const ScMarkData& rMark,
1878 : ScDocument* pNewUndoDoc, bool bIncrement ) :
1879 : ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
1880 : aMarkData( rMark ),
1881 : pUndoDoc( pNewUndoDoc ),
1882 6 : bIsIncrement( bIncrement )
1883 : {
1884 6 : }
1885 :
1886 18 : ScUndoIndent::~ScUndoIndent()
1887 : {
1888 6 : delete pUndoDoc;
1889 12 : }
1890 :
1891 6 : OUString ScUndoIndent::GetComment() const
1892 : {
1893 6 : sal_uInt16 nId = bIsIncrement ? STR_UNDO_INC_INDENT : STR_UNDO_DEC_INDENT;
1894 6 : return ScGlobal::GetRscString( nId );
1895 : }
1896 :
1897 0 : void ScUndoIndent::Undo()
1898 : {
1899 0 : BeginUndo();
1900 :
1901 0 : ScDocument& rDoc = pDocShell->GetDocument();
1902 0 : SCTAB nTabCount = rDoc.GetTableCount();
1903 0 : ScRange aCopyRange = aBlockRange;
1904 0 : aCopyRange.aStart.SetTab(0);
1905 0 : aCopyRange.aEnd.SetTab(nTabCount-1);
1906 0 : pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, true, &rDoc, &aMarkData );
1907 0 : pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1908 :
1909 0 : EndUndo();
1910 0 : }
1911 :
1912 0 : void ScUndoIndent::Redo()
1913 : {
1914 0 : BeginRedo();
1915 :
1916 0 : ScDocument& rDoc = pDocShell->GetDocument();
1917 0 : rDoc.ChangeSelectionIndent( bIsIncrement, aMarkData );
1918 0 : pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1919 :
1920 0 : EndRedo();
1921 0 : }
1922 :
1923 0 : void ScUndoIndent::Repeat(SfxRepeatTarget& rTarget)
1924 : {
1925 0 : if (rTarget.ISA(ScTabViewTarget))
1926 0 : static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->ChangeIndent( bIsIncrement );
1927 0 : }
1928 :
1929 0 : bool ScUndoIndent::CanRepeat(SfxRepeatTarget& rTarget) const
1930 : {
1931 0 : return rTarget.ISA(ScTabViewTarget);
1932 : }
1933 :
1934 1 : ScUndoTransliterate::ScUndoTransliterate( ScDocShell* pNewDocShell, const ScMarkData& rMark,
1935 : ScDocument* pNewUndoDoc, sal_Int32 nType ) :
1936 : ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
1937 : aMarkData( rMark ),
1938 : pUndoDoc( pNewUndoDoc ),
1939 1 : nTransliterationType( nType )
1940 : {
1941 1 : }
1942 :
1943 3 : ScUndoTransliterate::~ScUndoTransliterate()
1944 : {
1945 1 : delete pUndoDoc;
1946 2 : }
1947 :
1948 3 : OUString ScUndoTransliterate::GetComment() const
1949 : {
1950 3 : return ScGlobal::GetRscString( STR_UNDO_TRANSLITERATE );
1951 : }
1952 :
1953 1 : void ScUndoTransliterate::Undo()
1954 : {
1955 1 : BeginUndo();
1956 :
1957 1 : ScDocument& rDoc = pDocShell->GetDocument();
1958 1 : SCTAB nTabCount = rDoc.GetTableCount();
1959 1 : ScRange aCopyRange = aBlockRange;
1960 1 : aCopyRange.aStart.SetTab(0);
1961 1 : aCopyRange.aEnd.SetTab(nTabCount-1);
1962 1 : pUndoDoc->CopyToDocument( aCopyRange, IDF_CONTENTS, true, &rDoc, &aMarkData );
1963 1 : pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1964 :
1965 1 : EndUndo();
1966 1 : }
1967 :
1968 1 : void ScUndoTransliterate::Redo()
1969 : {
1970 1 : BeginRedo();
1971 :
1972 1 : ScDocument& rDoc = pDocShell->GetDocument();
1973 1 : rDoc.TransliterateText( aMarkData, nTransliterationType );
1974 1 : pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1975 :
1976 1 : EndRedo();
1977 1 : }
1978 :
1979 0 : void ScUndoTransliterate::Repeat(SfxRepeatTarget& rTarget)
1980 : {
1981 0 : if (rTarget.ISA(ScTabViewTarget))
1982 0 : static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->TransliterateText( nTransliterationType );
1983 0 : }
1984 :
1985 0 : bool ScUndoTransliterate::CanRepeat(SfxRepeatTarget& rTarget) const
1986 : {
1987 0 : return rTarget.ISA(ScTabViewTarget);
1988 : }
1989 :
1990 0 : ScUndoClearItems::ScUndoClearItems( ScDocShell* pNewDocShell, const ScMarkData& rMark,
1991 : ScDocument* pNewUndoDoc, const sal_uInt16* pW ) :
1992 : ScBlockUndo( pNewDocShell, lcl_GetMultiMarkRange(rMark), SC_UNDO_AUTOHEIGHT ),
1993 : aMarkData( rMark ),
1994 : pUndoDoc( pNewUndoDoc ),
1995 0 : pWhich( NULL )
1996 : {
1997 : OSL_ENSURE( pW, "ScUndoClearItems: Which-Pointer ist 0" );
1998 :
1999 0 : sal_uInt16 nCount = 0;
2000 0 : while ( pW[nCount] )
2001 0 : ++nCount;
2002 0 : pWhich = new sal_uInt16[nCount+1];
2003 0 : for (sal_uInt16 i=0; i<=nCount; i++)
2004 0 : pWhich[i] = pW[i];
2005 0 : }
2006 :
2007 0 : ScUndoClearItems::~ScUndoClearItems()
2008 : {
2009 0 : delete pUndoDoc;
2010 0 : delete pWhich;
2011 0 : }
2012 :
2013 0 : OUString ScUndoClearItems::GetComment() const
2014 : {
2015 0 : return ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS );
2016 : }
2017 :
2018 0 : void ScUndoClearItems::Undo()
2019 : {
2020 0 : BeginUndo();
2021 :
2022 0 : ScDocument& rDoc = pDocShell->GetDocument();
2023 0 : pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, true, &rDoc, &aMarkData );
2024 0 : pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
2025 :
2026 0 : EndUndo();
2027 0 : }
2028 :
2029 0 : void ScUndoClearItems::Redo()
2030 : {
2031 0 : BeginRedo();
2032 :
2033 0 : ScDocument& rDoc = pDocShell->GetDocument();
2034 0 : rDoc.ClearSelectionItems( pWhich, aMarkData );
2035 0 : pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
2036 :
2037 0 : EndRedo();
2038 0 : }
2039 :
2040 0 : void ScUndoClearItems::Repeat(SfxRepeatTarget& rTarget)
2041 : {
2042 0 : if (rTarget.ISA(ScTabViewTarget))
2043 : {
2044 0 : ScViewData& rViewData = static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->GetViewData();
2045 0 : rViewData.GetDocFunc().ClearItems( rViewData.GetMarkData(), pWhich, false );
2046 : }
2047 0 : }
2048 :
2049 0 : bool ScUndoClearItems::CanRepeat(SfxRepeatTarget& rTarget) const
2050 : {
2051 0 : return rTarget.ISA(ScTabViewTarget);
2052 : }
2053 :
2054 : // remove all line breaks of a table
2055 0 : ScUndoRemoveBreaks::ScUndoRemoveBreaks( ScDocShell* pNewDocShell,
2056 : SCTAB nNewTab, ScDocument* pNewUndoDoc ) :
2057 : ScSimpleUndo( pNewDocShell ),
2058 : nTab( nNewTab ),
2059 0 : pUndoDoc( pNewUndoDoc )
2060 : {
2061 0 : }
2062 :
2063 0 : ScUndoRemoveBreaks::~ScUndoRemoveBreaks()
2064 : {
2065 0 : delete pUndoDoc;
2066 0 : }
2067 :
2068 0 : OUString ScUndoRemoveBreaks::GetComment() const
2069 : {
2070 0 : return ScGlobal::GetRscString( STR_UNDO_REMOVEBREAKS );
2071 : }
2072 :
2073 0 : void ScUndoRemoveBreaks::Undo()
2074 : {
2075 0 : BeginUndo();
2076 :
2077 0 : ScDocument& rDoc = pDocShell->GetDocument();
2078 0 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2079 :
2080 0 : pUndoDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, false, &rDoc );
2081 0 : if (pViewShell)
2082 0 : pViewShell->UpdatePageBreakData( true );
2083 0 : pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
2084 :
2085 0 : EndUndo();
2086 0 : }
2087 :
2088 0 : void ScUndoRemoveBreaks::Redo()
2089 : {
2090 0 : BeginRedo();
2091 :
2092 0 : ScDocument& rDoc = pDocShell->GetDocument();
2093 0 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2094 :
2095 0 : rDoc.RemoveManualBreaks(nTab);
2096 0 : rDoc.UpdatePageBreaks(nTab);
2097 0 : if (pViewShell)
2098 0 : pViewShell->UpdatePageBreakData( true );
2099 0 : pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
2100 :
2101 0 : EndRedo();
2102 0 : }
2103 :
2104 0 : void ScUndoRemoveBreaks::Repeat(SfxRepeatTarget& rTarget)
2105 : {
2106 0 : if (rTarget.ISA(ScTabViewTarget))
2107 : {
2108 0 : ScTabViewShell& rViewShell = *static_cast<ScTabViewTarget&>(rTarget).GetViewShell();
2109 0 : rViewShell.RemoveManualBreaks();
2110 : }
2111 0 : }
2112 :
2113 0 : bool ScUndoRemoveBreaks::CanRepeat(SfxRepeatTarget& rTarget) const
2114 : {
2115 0 : return rTarget.ISA(ScTabViewTarget);
2116 : }
2117 :
2118 6 : ScUndoRemoveMerge::ScUndoRemoveMerge( ScDocShell* pNewDocShell,
2119 : const ScCellMergeOption& rOption, ScDocument* pNewUndoDoc ) :
2120 : ScBlockUndo( pNewDocShell, rOption.getFirstSingleRange(), SC_UNDO_SIMPLE ),
2121 : maOption(rOption),
2122 6 : pUndoDoc( pNewUndoDoc )
2123 : {
2124 6 : }
2125 :
2126 18 : ScUndoRemoveMerge::~ScUndoRemoveMerge()
2127 : {
2128 6 : delete pUndoDoc;
2129 12 : }
2130 :
2131 6 : OUString ScUndoRemoveMerge::GetComment() const
2132 : {
2133 6 : return ScGlobal::GetRscString( STR_UNDO_REMERGE ); // "remove merge"
2134 : }
2135 :
2136 0 : void ScUndoRemoveMerge::Undo()
2137 : {
2138 : using ::std::set;
2139 :
2140 0 : SetCurTab();
2141 0 : BeginUndo();
2142 :
2143 0 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2144 :
2145 0 : ScDocument& rDoc = pDocShell->GetDocument();
2146 0 : for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
2147 : itr != itrEnd; ++itr)
2148 : {
2149 : OSL_ENSURE(pUndoDoc, "NULL pUndoDoc!");
2150 0 : if (!pUndoDoc)
2151 0 : continue;
2152 : // There is no need to extend merge area because it's already been extended.
2153 0 : ScRange aRange = maOption.getSingleRange(*itr);
2154 0 : rDoc.DeleteAreaTab(aRange, IDF_ATTRIB);
2155 0 : pUndoDoc->CopyToDocument(aRange, IDF_ATTRIB, false, &rDoc);
2156 :
2157 0 : bool bDidPaint = false;
2158 0 : if ( pViewShell )
2159 : {
2160 0 : pViewShell->SetTabNo(*itr);
2161 0 : bDidPaint = pViewShell->AdjustRowHeight(maOption.mnStartRow, maOption.mnEndRow);
2162 : }
2163 0 : if (!bDidPaint)
2164 0 : ScUndoUtil::PaintMore(pDocShell, aRange);
2165 : }
2166 :
2167 0 : EndUndo();
2168 0 : }
2169 :
2170 0 : void ScUndoRemoveMerge::Redo()
2171 : {
2172 : using ::std::set;
2173 :
2174 0 : SetCurTab();
2175 0 : BeginRedo();
2176 :
2177 0 : ScDocument& rDoc = pDocShell->GetDocument();
2178 0 : ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2179 :
2180 0 : for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
2181 : itr != itrEnd; ++itr)
2182 : {
2183 0 : SCTAB nTab = *itr;
2184 : // There is no need to extend merge area because it's already been extended.
2185 0 : ScRange aRange = maOption.getSingleRange(nTab);
2186 :
2187 0 : const SfxPoolItem& rDefAttr = rDoc.GetPool()->GetDefaultItem( ATTR_MERGE );
2188 0 : ScPatternAttr aPattern( rDoc.GetPool() );
2189 0 : aPattern.GetItemSet().Put( rDefAttr );
2190 : rDoc.ApplyPatternAreaTab( maOption.mnStartCol, maOption.mnStartRow,
2191 : maOption.mnEndCol, maOption.mnEndRow, nTab,
2192 0 : aPattern );
2193 :
2194 : rDoc.RemoveFlagsTab( maOption.mnStartCol, maOption.mnStartRow,
2195 : maOption.mnEndCol, maOption.mnEndRow, nTab,
2196 0 : SC_MF_HOR | SC_MF_VER );
2197 :
2198 0 : rDoc.ExtendMerge(aRange, true);
2199 :
2200 : // Paint
2201 :
2202 0 : bool bDidPaint = false;
2203 0 : if ( pViewShell )
2204 : {
2205 0 : pViewShell->SetTabNo(nTab);
2206 0 : bDidPaint = pViewShell->AdjustRowHeight(maOption.mnStartRow, maOption.mnEndRow);
2207 : }
2208 0 : if (!bDidPaint)
2209 0 : ScUndoUtil::PaintMore(pDocShell, aRange);
2210 0 : }
2211 :
2212 0 : EndRedo();
2213 0 : }
2214 :
2215 0 : void ScUndoRemoveMerge::Repeat(SfxRepeatTarget& rTarget)
2216 : {
2217 0 : if (rTarget.ISA(ScTabViewTarget))
2218 0 : static_cast<ScTabViewTarget&>(rTarget).GetViewShell()->RemoveMerge();
2219 0 : }
2220 :
2221 0 : bool ScUndoRemoveMerge::CanRepeat(SfxRepeatTarget& rTarget) const
2222 : {
2223 0 : return rTarget.ISA(ScTabViewTarget);
2224 : }
2225 :
2226 0 : void ScUndoRemoveMerge::SetCurTab()
2227 : {
2228 0 : SCTAB nCurTab = ScDocShell::GetCurTab();
2229 0 : aBlockRange.aStart.SetTab(nCurTab);
2230 0 : aBlockRange.aEnd.SetTab(nCurTab);
2231 0 : }
2232 :
2233 : /** set only border, for ScRangeList (StarOne) */
2234 4 : static ScRange lcl_TotalRange( const ScRangeList& rRanges )
2235 : {
2236 4 : ScRange aTotal;
2237 4 : if ( !rRanges.empty() )
2238 : {
2239 4 : aTotal = *rRanges[ 0 ];
2240 4 : for ( size_t i = 1, nCount = rRanges.size(); i < nCount; ++i )
2241 : {
2242 0 : ScRange aRange = *rRanges[ i ];
2243 0 : if (aRange.aStart.Col() < aTotal.aStart.Col()) aTotal.aStart.SetCol(aRange.aStart.Col());
2244 0 : if (aRange.aStart.Row() < aTotal.aStart.Row()) aTotal.aStart.SetRow(aRange.aStart.Row());
2245 0 : if (aRange.aStart.Tab() < aTotal.aStart.Tab()) aTotal.aStart.SetTab(aRange.aStart.Tab());
2246 0 : if (aRange.aEnd.Col() > aTotal.aEnd.Col() ) aTotal.aEnd.SetCol( aRange.aEnd.Col() );
2247 0 : if (aRange.aEnd.Row() > aTotal.aEnd.Row() ) aTotal.aEnd.SetRow( aRange.aEnd.Row() );
2248 0 : if (aRange.aEnd.Tab() > aTotal.aEnd.Tab() ) aTotal.aEnd.SetTab(aRange.aEnd.Tab() );
2249 : }
2250 : }
2251 4 : return aTotal;
2252 : }
2253 :
2254 4 : ScUndoBorder::ScUndoBorder( ScDocShell* pNewDocShell,
2255 : const ScRangeList& rRangeList, ScDocument* pNewUndoDoc,
2256 : const SvxBoxItem& rNewOuter, const SvxBoxInfoItem& rNewInner ) :
2257 : ScBlockUndo( pNewDocShell, lcl_TotalRange(rRangeList), SC_UNDO_SIMPLE ),
2258 4 : pUndoDoc( pNewUndoDoc )
2259 : {
2260 4 : pRanges = new ScRangeList(rRangeList);
2261 4 : pOuter = new SvxBoxItem(rNewOuter);
2262 4 : pInner = new SvxBoxInfoItem(rNewInner);
2263 4 : }
2264 :
2265 12 : ScUndoBorder::~ScUndoBorder()
2266 : {
2267 4 : delete pUndoDoc;
2268 4 : delete pRanges;
2269 4 : delete pOuter;
2270 4 : delete pInner;
2271 8 : }
2272 :
2273 4 : OUString ScUndoBorder::GetComment() const
2274 : {
2275 4 : return ScGlobal::GetRscString( STR_UNDO_SELATTRLINES ); //! eigener String?
2276 : }
2277 :
2278 0 : void ScUndoBorder::Undo()
2279 : {
2280 0 : BeginUndo();
2281 :
2282 0 : ScDocument& rDoc = pDocShell->GetDocument();
2283 0 : ScMarkData aMarkData;
2284 0 : aMarkData.MarkFromRangeList( *pRanges, false );
2285 0 : pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, true, &rDoc, &aMarkData );
2286 0 : pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
2287 :
2288 0 : EndUndo();
2289 0 : }
2290 :
2291 0 : void ScUndoBorder::Redo()
2292 : {
2293 0 : BeginRedo();
2294 :
2295 0 : ScDocument& rDoc = pDocShell->GetDocument(); // call function at docfunc
2296 0 : size_t nCount = pRanges->size();
2297 0 : for (size_t i = 0; i < nCount; ++i )
2298 : {
2299 0 : ScRange aRange = *(*pRanges)[i];
2300 0 : SCTAB nTab = aRange.aStart.Tab();
2301 :
2302 0 : ScMarkData aMark;
2303 0 : aMark.SetMarkArea( aRange );
2304 0 : aMark.SelectTable( nTab, true );
2305 :
2306 0 : rDoc.ApplySelectionFrame( aMark, pOuter, pInner );
2307 0 : }
2308 0 : for (size_t i = 0; i < nCount; ++i)
2309 0 : pDocShell->PostPaint( *(*pRanges)[i], PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
2310 :
2311 0 : EndRedo();
2312 0 : }
2313 :
2314 0 : void ScUndoBorder::Repeat(SfxRepeatTarget& /* rTarget */)
2315 : {
2316 : //TODO later (when the function has moved from cellsuno to docfunc)
2317 0 : }
2318 :
2319 0 : bool ScUndoBorder::CanRepeat(SfxRepeatTarget& /* rTarget */) const
2320 : {
2321 0 : return false; // See above
2322 156 : }
2323 :
2324 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|