xref: /AOO41X/main/sc/source/ui/undo/undoblk.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8)
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