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