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