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