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