xref: /aoo41x/main/sc/source/ui/undo/undoblk3.cxx (revision b3f79822)
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 // INCLUDE -------------------------------------------------------------------
28 
29 #include "scitems.hxx"
30 #include <editeng/boxitem.hxx>
31 #include <svl/srchitem.hxx>
32 #include <sfx2/linkmgr.hxx>
33 #include <sfx2/bindings.hxx>
34 #include <vcl/virdev.hxx>
35 #include <sfx2/app.hxx>
36 
37 #include "undoblk.hxx"
38 #include "sc.hrc"
39 #include "globstr.hrc"
40 #include "global.hxx"
41 #include "rangenam.hxx"
42 #include "arealink.hxx"
43 #include "patattr.hxx"
44 #include "target.hxx"
45 #include "document.hxx"
46 #include "docpool.hxx"
47 #include "table.hxx"
48 #include "docsh.hxx"
49 #include "tabvwsh.hxx"
50 #include "undoolk.hxx"
51 #include "undoutil.hxx"
52 #include "chgtrack.hxx"
53 #include "dociter.hxx"
54 #include "cell.hxx"
55 #include "paramisc.hxx"
56 #include "postit.hxx"
57 #include "docuno.hxx"
58 
59 // STATIC DATA ---------------------------------------------------------------
60 
61 TYPEINIT1(ScUndoDeleteContents, 	SfxUndoAction);
62 TYPEINIT1(ScUndoFillTable,		 	SfxUndoAction);
63 TYPEINIT1(ScUndoSelectionAttr,		SfxUndoAction);
64 TYPEINIT1(ScUndoAutoFill,			SfxUndoAction);
65 TYPEINIT1(ScUndoMerge,				SfxUndoAction);
66 TYPEINIT1(ScUndoAutoFormat, 		SfxUndoAction);
67 TYPEINIT1(ScUndoReplace,			SfxUndoAction);
68 TYPEINIT1(ScUndoTabOp,				SfxUndoAction);
69 TYPEINIT1(ScUndoConversion,         SfxUndoAction);
70 TYPEINIT1(ScUndoRefConversion,      SfxUndoAction);
71 TYPEINIT1(ScUndoRefreshLink,		SfxUndoAction);
72 TYPEINIT1(ScUndoInsertAreaLink,		SfxUndoAction);
73 TYPEINIT1(ScUndoRemoveAreaLink,		SfxUndoAction);
74 TYPEINIT1(ScUndoUpdateAreaLink,		SfxUndoAction);
75 
76 
77 // To Do:
78 /*A*/	// SetOptimalHeight auf Dokument, wenn keine View
79 
80 
81 //============================================================================
82 //	class ScUndoDeleteContents
83 //
84 //	Inhalte loeschen
85 
86 //----------------------------------------------------------------------------
87 
88 ScUndoDeleteContents::ScUndoDeleteContents(
89 				ScDocShell* pNewDocShell,
90 				const ScMarkData& rMark, const ScRange& rRange,
91 				ScDocument* pNewUndoDoc, sal_Bool bNewMulti,
92 				sal_uInt16 nNewFlags, sal_Bool bObjects )
93 		//
94 	:	ScSimpleUndo( pNewDocShell ),
95 		//
96 		aRange		( rRange ),
97 		aMarkData	( rMark ),
98 		pUndoDoc	( pNewUndoDoc ),
99 		pDrawUndo	( NULL ),
100 		nFlags		( nNewFlags ),
101 		bMulti		( bNewMulti )	// ueberliquid
102 {
103 	if (bObjects)
104 		pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
105 
106 	if ( !(aMarkData.IsMarked() || aMarkData.IsMultiMarked()) )		// keine Zelle markiert:
107 		aMarkData.SetMarkArea( aRange );							// Zelle unter Cursor markieren
108 
109 	SetChangeTrack();
110 }
111 
112 
113 //----------------------------------------------------------------------------
114 
115 __EXPORT ScUndoDeleteContents::~ScUndoDeleteContents()
116 {
117 	delete pUndoDoc;
118 	DeleteSdrUndoAction( pDrawUndo );
119 }
120 
121 
122 //----------------------------------------------------------------------------
123 
124 String __EXPORT ScUndoDeleteContents::GetComment() const
125 {
126 	return ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS );	 // "Loeschen"
127 }
128 
129 
130 void ScUndoDeleteContents::SetChangeTrack()
131 {
132 	ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
133 	if ( pChangeTrack && (nFlags & IDF_CONTENTS) )
134 		pChangeTrack->AppendContentRange( aRange, pUndoDoc,
135 			nStartChangeAction, nEndChangeAction );
136 	else
137 		nStartChangeAction = nEndChangeAction = 0;
138 }
139 
140 
141 //----------------------------------------------------------------------------
142 
143 void ScUndoDeleteContents::DoChange( const sal_Bool bUndo )
144 {
145 	ScDocument* pDoc = pDocShell->GetDocument();
146 
147 	SetViewMarkData( aMarkData );
148 
149 	sal_uInt16 nExtFlags = 0;
150 
151 	if (bUndo)	// nur Undo
152 	{
153 		sal_uInt16 nUndoFlags = IDF_NONE;		//	entweder alle oder keine Inhalte kopieren
154 		if (nFlags & IDF_CONTENTS)			//	(es sind nur die richtigen ins UndoDoc kopiert worden)
155 			nUndoFlags |= IDF_CONTENTS;
156 		if (nFlags & IDF_ATTRIB)
157 			nUndoFlags |= IDF_ATTRIB;
158 		if (nFlags & IDF_EDITATTR)			// Edit-Engine-Attribute
159 			nUndoFlags |= IDF_STRING;		// -> Zellen werden geaendert
160         // do not create clones of note captions, they will be restored via drawing undo
161         nUndoFlags |= IDF_NOCAPTIONS;
162 
163 		ScRange aCopyRange = aRange;
164 		SCTAB nTabCount = pDoc->GetTableCount();
165 		aCopyRange.aStart.SetTab(0);
166 		aCopyRange.aEnd.SetTab(nTabCount-1);
167 
168 		pUndoDoc->CopyToDocument( aCopyRange, nUndoFlags, bMulti, pDoc, &aMarkData );
169 
170         DoSdrUndoAction( pDrawUndo, pDoc );
171 
172 		ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
173 		if ( pChangeTrack )
174 			pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
175 
176 		pDocShell->UpdatePaintExt( nExtFlags, aRange );				// content after the change
177 	}
178 	else		// nur Redo
179 	{
180 		pDocShell->UpdatePaintExt( nExtFlags, aRange );				// content before the change
181 
182 		aMarkData.MarkToMulti();
183         RedoSdrUndoAction( pDrawUndo );
184         // do not delete objects and note captions, they have been removed via drawing undo
185         sal_uInt16 nRedoFlags = (nFlags & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
186         pDoc->DeleteSelection( nRedoFlags, aMarkData );
187 		aMarkData.MarkToSimple();
188 
189 		SetChangeTrack();
190 	}
191 
192 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
193 	if ( !( (pViewShell) && pViewShell->AdjustRowHeight(
194 								aRange.aStart.Row(), aRange.aEnd.Row() ) ) )
195 /*A*/	pDocShell->PostPaint( aRange, PAINT_GRID | PAINT_EXTRAS, nExtFlags );
196 
197 	pDocShell->PostDataChanged();
198 	if (pViewShell)
199 		pViewShell->CellContentChanged();
200 
201 	ShowTable( aRange );
202 }
203 
204 
205 //----------------------------------------------------------------------------
206 
207 void __EXPORT ScUndoDeleteContents::Undo()
208 {
209 	BeginUndo();
210 	DoChange( sal_True );
211 	EndUndo();
212 
213     // #i97876# Spreadsheet data changes are not notified
214     ScModelObj* pModelObj = ScModelObj::getImplementation( pDocShell->GetModel() );
215     if ( pModelObj && pModelObj->HasChangesListeners() )
216     {
217         ScRangeList aChangeRanges;
218         aChangeRanges.Append( aRange );
219         pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
220     }
221 }
222 
223 
224 //----------------------------------------------------------------------------
225 
226 void __EXPORT ScUndoDeleteContents::Redo()
227 {
228 	BeginRedo();
229 	DoChange( sal_False );
230 	EndRedo();
231 
232     // #i97876# Spreadsheet data changes are not notified
233     ScModelObj* pModelObj = ScModelObj::getImplementation( pDocShell->GetModel() );
234     if ( pModelObj && pModelObj->HasChangesListeners() )
235     {
236         ScRangeList aChangeRanges;
237         aChangeRanges.Append( aRange );
238         pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
239     }
240 }
241 
242 
243 //----------------------------------------------------------------------------
244 
245 void __EXPORT ScUndoDeleteContents::Repeat(SfxRepeatTarget& rTarget)
246 {
247 	if (rTarget.ISA(ScTabViewTarget))
248 		((ScTabViewTarget&)rTarget).GetViewShell()->DeleteContents( nFlags, sal_True );
249 }
250 
251 
252 //----------------------------------------------------------------------------
253 
254 sal_Bool __EXPORT ScUndoDeleteContents::CanRepeat(SfxRepeatTarget& rTarget) const
255 {
256 	return (rTarget.ISA(ScTabViewTarget));
257 }
258 
259 
260 //============================================================================
261 //	class ScUndoFillTable
262 //
263 //	Tabellen ausfuellen
264 //	(Bearbeiten|Ausfuellen|...)
265 
266 //----------------------------------------------------------------------------
267 
268 ScUndoFillTable::ScUndoFillTable( ScDocShell* pNewDocShell,
269 				const ScMarkData& rMark,
270 				SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
271 				SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
272 				ScDocument* pNewUndoDoc, sal_Bool bNewMulti, SCTAB nSrc,
273 				sal_uInt16 nFlg, sal_uInt16 nFunc, sal_Bool bSkip, sal_Bool bLink )
274 		//
275 	:	ScSimpleUndo( pNewDocShell ),
276 		//
277 		aRange		( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
278 		aMarkData	( rMark ),
279 		pUndoDoc	( pNewUndoDoc ),
280 		nFlags		( nFlg ),
281 		nFunction	( nFunc ),
282 		nSrcTab		( nSrc ),
283 		bMulti		( bNewMulti ),
284 		bSkipEmpty	( bSkip ),
285 		bAsLink		( bLink )
286 {
287 	SetChangeTrack();
288 }
289 
290 
291 //----------------------------------------------------------------------------
292 
293 __EXPORT ScUndoFillTable::~ScUndoFillTable()
294 {
295 	delete pUndoDoc;
296 }
297 
298 
299 //----------------------------------------------------------------------------
300 
301 String __EXPORT ScUndoFillTable::GetComment() const
302 {
303 	return ScGlobal::GetRscString( STR_FILL_TAB );
304 }
305 
306 
307 void ScUndoFillTable::SetChangeTrack()
308 {
309 	ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
310 	if ( pChangeTrack )
311 	{
312 		SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();
313 		ScRange aWorkRange(aRange);
314 		nStartChangeAction = 0;
315 		sal_uLong nTmpAction;
316 		for ( SCTAB i = 0; i < nTabCount; i++ )
317 		{
318 			if (i != nSrcTab && aMarkData.GetTableSelect(i))
319 			{
320 				aWorkRange.aStart.SetTab(i);
321 				aWorkRange.aEnd.SetTab(i);
322 				pChangeTrack->AppendContentRange( aWorkRange, pUndoDoc,
323 					nTmpAction, nEndChangeAction );
324 				if ( !nStartChangeAction )
325 					nStartChangeAction = nTmpAction;
326 			}
327 		}
328 	}
329 	else
330 		nStartChangeAction = nEndChangeAction = 0;
331 }
332 
333 
334 //----------------------------------------------------------------------------
335 
336 void ScUndoFillTable::DoChange( const sal_Bool bUndo )
337 {
338 	ScDocument* pDoc = pDocShell->GetDocument();
339 
340 	SetViewMarkData( aMarkData );
341 
342 	if (bUndo)	// nur Undo
343 	{
344 		SCTAB nTabCount = pDoc->GetTableCount();
345 		ScRange aWorkRange(aRange);
346 		for ( SCTAB i = 0; i < nTabCount; i++ )
347 			if (i != nSrcTab && aMarkData.GetTableSelect(i))
348 			{
349 				aWorkRange.aStart.SetTab(i);
350 				aWorkRange.aEnd.SetTab(i);
351 				if (bMulti)
352 					pDoc->DeleteSelectionTab( i, IDF_ALL, aMarkData );
353 				else
354 					pDoc->DeleteAreaTab( aWorkRange, IDF_ALL );
355 				pUndoDoc->CopyToDocument( aWorkRange, IDF_ALL, bMulti, pDoc, &aMarkData );
356 			}
357 
358 		ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
359 		if ( pChangeTrack )
360 			pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
361 	}
362 	else		// nur Redo
363 	{
364 		aMarkData.MarkToMulti();
365 		pDoc->FillTabMarked( nSrcTab, aMarkData, nFlags, nFunction, bSkipEmpty, bAsLink );
366 		aMarkData.MarkToSimple();
367 		SetChangeTrack();
368 	}
369 
370 	pDocShell->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_GRID|PAINT_EXTRAS);
371 	pDocShell->PostDataChanged();
372 
373 	//	CellContentChanged kommt mit der Markierung
374 
375 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
376 	if (pViewShell)
377 	{
378 		SCTAB nTab = pViewShell->GetViewData()->GetTabNo();
379 		if ( !aMarkData.GetTableSelect(nTab) )
380 			pViewShell->SetTabNo( nSrcTab );
381 
382 		pViewShell->DoneBlockMode();	// gibt sonst Probleme, weil Markierung auf falscher Tabelle
383 	}
384 }
385 
386 
387 //----------------------------------------------------------------------------
388 
389 void __EXPORT ScUndoFillTable::Undo()
390 {
391 	BeginUndo();
392 	DoChange( sal_True );
393 	EndUndo();
394 }
395 
396 
397 //----------------------------------------------------------------------------
398 
399 void __EXPORT ScUndoFillTable::Redo()
400 {
401 	BeginRedo();
402 	DoChange( sal_False );
403 	EndRedo();
404 }
405 
406 
407 //----------------------------------------------------------------------------
408 
409 void __EXPORT ScUndoFillTable::Repeat(SfxRepeatTarget& rTarget)
410 {
411 	if (rTarget.ISA(ScTabViewTarget))
412 		((ScTabViewTarget&)rTarget).GetViewShell()->FillTab( nFlags, nFunction, bSkipEmpty, bAsLink );
413 }
414 
415 
416 //----------------------------------------------------------------------------
417 
418 sal_Bool __EXPORT ScUndoFillTable::CanRepeat(SfxRepeatTarget& rTarget) const
419 {
420 	return (rTarget.ISA(ScTabViewTarget));
421 }
422 
423 
424 //============================================================================
425 //	class ScUndoSelectionAttr
426 //
427 //	Zellformat aendern
428 
429 //----------------------------------------------------------------------------
430 
431 ScUndoSelectionAttr::ScUndoSelectionAttr( ScDocShell* pNewDocShell,
432 				const ScMarkData& rMark,
433 				SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
434 				SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
435 				ScDocument* pNewUndoDoc, sal_Bool bNewMulti,
436 				const ScPatternAttr* pNewApply,
437 				const SvxBoxItem* pNewOuter, const SvxBoxInfoItem* pNewInner )
438 		//
439 	:	ScSimpleUndo( pNewDocShell ),
440 		//
441 		aMarkData	( rMark ),
442 		aRange		( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
443 		pUndoDoc	( pNewUndoDoc ),
444 		bMulti		( bNewMulti )
445 {
446 	ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
447 	pApplyPattern = (ScPatternAttr*) &pPool->Put( *pNewApply );
448 	pLineOuter = pNewOuter ? (SvxBoxItem*) &pPool->Put( *pNewOuter ) : NULL;
449 	pLineInner = pNewInner ? (SvxBoxInfoItem*) &pPool->Put( *pNewInner ) : NULL;
450 }
451 
452 
453 //----------------------------------------------------------------------------
454 
455 __EXPORT ScUndoSelectionAttr::~ScUndoSelectionAttr()
456 {
457 	ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
458 	pPool->Remove(*pApplyPattern);
459 	if (pLineOuter)
460 		pPool->Remove(*pLineOuter);
461 	if (pLineInner)
462 		pPool->Remove(*pLineInner);
463 
464 	delete pUndoDoc;
465 }
466 
467 
468 //----------------------------------------------------------------------------
469 
470 String __EXPORT ScUndoSelectionAttr::GetComment() const
471 {
472 	//"Attribute" "/Linien"
473 	return ScGlobal::GetRscString( pLineOuter ? STR_UNDO_SELATTRLINES : STR_UNDO_SELATTR );
474 }
475 
476 
477 //----------------------------------------------------------------------------
478 
479 void ScUndoSelectionAttr::DoChange( const sal_Bool bUndo )
480 {
481 	ScDocument* pDoc = pDocShell->GetDocument();
482 
483 	SetViewMarkData( aMarkData );
484 
485 	ScRange aEffRange( aRange );
486 	if ( pDoc->HasAttrib( aEffRange, HASATTR_MERGED ) )			// zusammengefasste Zellen?
487 		pDoc->ExtendMerge( aEffRange );
488 
489 	sal_uInt16 nExtFlags = 0;
490 	pDocShell->UpdatePaintExt( nExtFlags, aEffRange );
491 
492 	if (bUndo)	// nur bei Undo
493 	{
494 		ScRange aCopyRange = aRange;
495 		SCTAB nTabCount = pDoc->GetTableCount();
496 		aCopyRange.aStart.SetTab(0);
497 		aCopyRange.aEnd.SetTab(nTabCount-1);
498 		pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, bMulti, pDoc, &aMarkData );
499 	}
500 	else		// nur bei Redo
501 	{
502 		aMarkData.MarkToMulti();
503 		pDoc->ApplySelectionPattern( *pApplyPattern, aMarkData );
504 		aMarkData.MarkToSimple();
505 
506 		if (pLineOuter)
507 			pDoc->ApplySelectionFrame( aMarkData, pLineOuter, pLineInner );
508 	}
509 
510 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
511 	if ( !( (pViewShell) && pViewShell->AdjustBlockHeight() ) )
512 /*A*/	pDocShell->PostPaint( aEffRange, PAINT_GRID | PAINT_EXTRAS, nExtFlags );
513 
514 	ShowTable( aRange );
515 }
516 
517 
518 //----------------------------------------------------------------------------
519 
520 void __EXPORT ScUndoSelectionAttr::Undo()
521 {
522 	BeginUndo();
523 	DoChange( sal_True );
524 	EndUndo();
525 }
526 
527 
528 //----------------------------------------------------------------------------
529 
530 void __EXPORT ScUndoSelectionAttr::Redo()
531 {
532 	BeginRedo();
533 	DoChange( sal_False );
534 	EndRedo();
535 }
536 
537 
538 //----------------------------------------------------------------------------
539 
540 void __EXPORT ScUndoSelectionAttr::Repeat(SfxRepeatTarget& rTarget)
541 {
542 	if (rTarget.ISA(ScTabViewTarget))
543 	{
544 		ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
545 		if (pLineOuter)
546 			rViewShell.ApplyPatternLines( *pApplyPattern, pLineOuter, pLineInner, sal_True );
547 		else
548 			rViewShell.ApplySelectionPattern( *pApplyPattern, sal_True );
549 	}
550 }
551 
552 
553 //----------------------------------------------------------------------------
554 
555 sal_Bool __EXPORT ScUndoSelectionAttr::CanRepeat(SfxRepeatTarget& rTarget) const
556 {
557 	return (rTarget.ISA(ScTabViewTarget));
558 }
559 
560 
561 //============================================================================
562 //	class ScUndoAutoFill
563 //
564 //	Auto-Fill (nur einfache Bloecke)
565 
566 //----------------------------------------------------------------------------
567 
568 ScUndoAutoFill::ScUndoAutoFill( ScDocShell* pNewDocShell,
569 				const ScRange& rRange, const ScRange& rSourceArea,
570 				ScDocument* pNewUndoDoc, const ScMarkData& rMark,
571 				FillDir eNewFillDir, FillCmd eNewFillCmd, FillDateCmd eNewFillDateCmd,
572 				double fNewStartValue, double fNewStepValue, double fNewMaxValue,
573 				sal_uInt16 nMaxShIndex )
574 		//
575 	:	ScBlockUndo( pNewDocShell, rRange, SC_UNDO_AUTOHEIGHT ),
576 		//
577 		aSource			( rSourceArea ),
578 		aMarkData		( rMark ),
579 		pUndoDoc		( pNewUndoDoc ),
580 		eFillDir		( eNewFillDir ),
581 		eFillCmd		( eNewFillCmd ),
582 		eFillDateCmd	( eNewFillDateCmd ),
583 		fStartValue		( fNewStartValue ),
584 		fStepValue		( fNewStepValue ),
585 		fMaxValue		( fNewMaxValue ),
586 		nMaxSharedIndex	( nMaxShIndex)
587 {
588 	SetChangeTrack();
589 }
590 
591 
592 //----------------------------------------------------------------------------
593 
594 __EXPORT ScUndoAutoFill::~ScUndoAutoFill()
595 {
596 	pDocShell->GetDocument()->EraseNonUsedSharedNames(nMaxSharedIndex);
597 	delete pUndoDoc;
598 }
599 
600 
601 //----------------------------------------------------------------------------
602 
603 String __EXPORT ScUndoAutoFill::GetComment() const
604 {
605 	return ScGlobal::GetRscString( STR_UNDO_AUTOFILL ); //"Ausfuellen"
606 }
607 
608 
609 void ScUndoAutoFill::SetChangeTrack()
610 {
611 	ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
612 	if ( pChangeTrack )
613 		pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
614 			nStartChangeAction, nEndChangeAction );
615 	else
616 		nStartChangeAction = nEndChangeAction = 0;
617 }
618 
619 
620 //----------------------------------------------------------------------------
621 
622 void __EXPORT ScUndoAutoFill::Undo()
623 {
624 	BeginUndo();
625 
626 	ScDocument* pDoc = pDocShell->GetDocument();
627 
628 	SCTAB nTabCount = pDoc->GetTableCount();
629 	for (SCTAB nTab=0; nTab<nTabCount; nTab++)
630 	{
631 		if (aMarkData.GetTableSelect(nTab))
632 		{
633 			ScRange aWorkRange = aBlockRange;
634 			aWorkRange.aStart.SetTab(nTab);
635 			aWorkRange.aEnd.SetTab(nTab);
636 
637 			sal_uInt16 nExtFlags = 0;
638 			pDocShell->UpdatePaintExt( nExtFlags, aWorkRange );
639             pDoc->DeleteAreaTab( aWorkRange, IDF_AUTOFILL );
640             pUndoDoc->CopyToDocument( aWorkRange, IDF_AUTOFILL, sal_False, pDoc );
641 
642 			pDoc->ExtendMerge( aWorkRange, sal_True );
643 			pDocShell->PostPaint( aWorkRange, PAINT_GRID, nExtFlags );
644 		}
645 	}
646 	pDocShell->PostDataChanged();
647 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
648 	if (pViewShell)
649 		pViewShell->CellContentChanged();
650 
651 // Shared-Names loeschen
652 // Falls Undo ins Dokument gespeichert
653 // => automatisches Loeschen am Ende
654 // umarbeiten!!
655 
656 	String aName = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("___SC_"));
657 	aName += String::CreateFromInt32(nMaxSharedIndex);
658 	aName += '_';
659 	ScRangeName* pRangeName = pDoc->GetRangeName();
660 	sal_Bool bHasFound = sal_False;
661 	for (sal_uInt16 i = 0; i < pRangeName->GetCount(); i++)
662 	{
663 		ScRangeData* pRangeData = (*pRangeName)[i];
664 		if (pRangeData)
665 		{
666 			String aRName;
667 			pRangeData->GetName(aRName);
668 			if (aRName.Search(aName) != STRING_NOTFOUND)
669 			{
670 				pRangeName->AtFree(i);
671 				bHasFound = sal_True;
672 			}
673 		}
674 	}
675 	if (bHasFound)
676 		pRangeName->SetSharedMaxIndex(pRangeName->GetSharedMaxIndex()-1);
677 
678 	ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
679 	if ( pChangeTrack )
680 		pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
681 
682 	EndUndo();
683 }
684 
685 
686 //----------------------------------------------------------------------------
687 
688 void __EXPORT ScUndoAutoFill::Redo()
689 {
690 	BeginRedo();
691 
692 //!	Tabellen selektieren
693 
694     SCCOLROW nCount = 0;
695 	switch (eFillDir)
696 	{
697 		case FILL_TO_BOTTOM:
698 			nCount = aBlockRange.aEnd.Row() - aSource.aEnd.Row();
699 			break;
700 		case FILL_TO_RIGHT:
701 			nCount = aBlockRange.aEnd.Col() - aSource.aEnd.Col();
702 			break;
703 		case FILL_TO_TOP:
704 			nCount = aSource.aStart.Row() - aBlockRange.aStart.Row();
705 			break;
706 		case FILL_TO_LEFT:
707 			nCount = aSource.aStart.Col() - aBlockRange.aStart.Col();
708 			break;
709 	}
710 
711 	ScDocument* pDoc = pDocShell->GetDocument();
712 	if ( fStartValue != MAXDOUBLE )
713 	{
714 		SCCOL nValX = (eFillDir == FILL_TO_LEFT) ? aSource.aEnd.Col() : aSource.aStart.Col();
715 		SCROW nValY = (eFillDir == FILL_TO_TOP ) ? aSource.aEnd.Row() : aSource.aStart.Row();
716 		SCTAB nTab = aSource.aStart.Tab();
717 		pDoc->SetValue( nValX, nValY, nTab, fStartValue );
718 	}
719 	pDoc->Fill( aSource.aStart.Col(), aSource.aStart.Row(),
720 				aSource.aEnd.Col(),   aSource.aEnd.Row(),
721 				aMarkData, nCount,
722 				eFillDir, eFillCmd, eFillDateCmd,
723 				fStepValue, fMaxValue );
724 
725 	SetChangeTrack();
726 
727 	pDocShell->PostPaint( aBlockRange, PAINT_GRID );
728 	pDocShell->PostDataChanged();
729 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
730 	if (pViewShell)
731 		pViewShell->CellContentChanged();
732 
733 	EndRedo();
734 }
735 
736 
737 //----------------------------------------------------------------------------
738 
739 void __EXPORT ScUndoAutoFill::Repeat(SfxRepeatTarget& rTarget)
740 {
741 	if (rTarget.ISA(ScTabViewTarget))
742 	{
743 		ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
744 		if (eFillCmd==FILL_SIMPLE)
745 			rViewShell.FillSimple( eFillDir, sal_True );
746 		else
747 			rViewShell.FillSeries( eFillDir, eFillCmd, eFillDateCmd,
748 								   fStartValue, fStepValue, fMaxValue, sal_True );
749 	}
750 }
751 
752 
753 //----------------------------------------------------------------------------
754 
755 sal_Bool __EXPORT ScUndoAutoFill::CanRepeat(SfxRepeatTarget& rTarget) const
756 {
757 	return (rTarget.ISA(ScTabViewTarget));
758 }
759 
760 
761 //============================================================================
762 //	class ScUndoMerge
763 //
764 //	Zellen zusammenfassen / Zusammenfassung aufheben
765 
766 //----------------------------------------------------------------------------
767 
768 ScUndoMerge::ScUndoMerge( ScDocShell* pNewDocShell,
769 							SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
770 							SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
771                             bool bMergeContents, ScDocument* pUndoDoc, SdrUndoAction* pDrawUndo )
772 		//
773 	:	ScSimpleUndo( pNewDocShell ),
774 		//
775 		maRange( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
776         mbMergeContents( bMergeContents ),
777         mpUndoDoc( pUndoDoc ),
778         mpDrawUndo( pDrawUndo )
779 {
780 }
781 
782 
783 //----------------------------------------------------------------------------
784 
785 ScUndoMerge::~ScUndoMerge()
786 {
787 	delete mpUndoDoc;
788     DeleteSdrUndoAction( mpDrawUndo );
789 }
790 
791 
792 //----------------------------------------------------------------------------
793 
794 String ScUndoMerge::GetComment() const
795 {
796 	return ScGlobal::GetRscString( STR_UNDO_MERGE );
797 }
798 
799 
800 //----------------------------------------------------------------------------
801 
802 void ScUndoMerge::DoChange( bool bUndo ) const
803 {
804 	ScDocument* pDoc = pDocShell->GetDocument();
805 
806 	ScUndoUtil::MarkSimpleBlock( pDocShell, maRange );
807 
808 	if (bUndo)
809         // remove merge (contents are copied back below from undo document)
810 		pDoc->RemoveMerge( maRange.aStart.Col(), maRange.aStart.Row(), maRange.aStart.Tab() );
811 	else
812         // repeat merge, but do not remove note captions (will be done by drawing redo below)
813 /*!*/	pDoc->DoMerge( maRange.aStart.Tab(),
814 					   maRange.aStart.Col(), maRange.aStart.Row(),
815                        maRange.aEnd.Col(),   maRange.aEnd.Row(), false );
816 
817     // undo -> copy back deleted contents
818 	if (bUndo && mpUndoDoc)
819     {
820         pDoc->DeleteAreaTab( maRange, IDF_CONTENTS|IDF_NOCAPTIONS );
821         mpUndoDoc->CopyToDocument( maRange, IDF_ALL|IDF_NOCAPTIONS, sal_False, pDoc );
822     }
823 
824     // redo -> merge contents again
825     else if (!bUndo && mbMergeContents)
826     {
827 /*!*/   pDoc->DoMergeContents( maRange.aStart.Tab(),
828 							   maRange.aStart.Col(), maRange.aStart.Row(),
829 							   maRange.aEnd.Col(),   maRange.aEnd.Row()   );
830     }
831 
832     if (bUndo)
833         DoSdrUndoAction( mpDrawUndo, pDoc );
834     else
835         RedoSdrUndoAction( mpDrawUndo );
836 
837 	sal_Bool bDidPaint = sal_False;
838 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
839 	if ( pViewShell )
840 	{
841 		pViewShell->SetTabNo( maRange.aStart.Tab() );
842 		bDidPaint = pViewShell->AdjustRowHeight( maRange.aStart.Row(), maRange.aEnd.Row() );
843 	}
844 
845 	if (!bDidPaint)
846 		ScUndoUtil::PaintMore( pDocShell, maRange );
847 
848 	ShowTable( maRange );
849 }
850 
851 
852 //----------------------------------------------------------------------------
853 
854 void ScUndoMerge::Undo()
855 {
856 	BeginUndo();
857 	DoChange( true );
858 	EndUndo();
859 }
860 
861 
862 //----------------------------------------------------------------------------
863 
864 void ScUndoMerge::Redo()
865 {
866 	BeginRedo();
867 	DoChange( false );
868 	EndRedo();
869 }
870 
871 
872 //----------------------------------------------------------------------------
873 
874 void ScUndoMerge::Repeat(SfxRepeatTarget& rTarget)
875 {
876 	if (rTarget.ISA(ScTabViewTarget))
877 	{
878 		ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
879 		sal_Bool bCont = sal_False;
880 		rViewShell.MergeCells( sal_False, bCont, sal_True );
881 	}
882 }
883 
884 
885 //----------------------------------------------------------------------------
886 
887 sal_Bool ScUndoMerge::CanRepeat(SfxRepeatTarget& rTarget) const
888 {
889 	return (rTarget.ISA(ScTabViewTarget));
890 }
891 
892 
893 //============================================================================
894 //	class ScUndoAutoFormat
895 //
896 //		Auto-Format (nur einfache Bloecke)
897 
898 //----------------------------------------------------------------------------
899 
900 ScUndoAutoFormat::ScUndoAutoFormat( ScDocShell* pNewDocShell,
901 						const ScRange& rRange, ScDocument* pNewUndoDoc,
902 						const ScMarkData& rMark, sal_Bool bNewSize, sal_uInt16 nNewFormatNo )
903 		//
904 	:	ScBlockUndo( pNewDocShell, rRange, bNewSize ? SC_UNDO_MANUALHEIGHT : SC_UNDO_AUTOHEIGHT ),
905 		//
906 		pUndoDoc	( pNewUndoDoc ),
907 		aMarkData	( rMark ),
908 		bSize		( bNewSize ),
909 		nFormatNo	( nNewFormatNo )
910 {
911 }
912 
913 
914 //----------------------------------------------------------------------------
915 
916 __EXPORT ScUndoAutoFormat::~ScUndoAutoFormat()
917 {
918 	delete pUndoDoc;
919 }
920 
921 
922 //----------------------------------------------------------------------------
923 
924 String __EXPORT ScUndoAutoFormat::GetComment() const
925 {
926 	return ScGlobal::GetRscString( STR_UNDO_AUTOFORMAT );	//"Auto-Format"
927 }
928 
929 
930 //----------------------------------------------------------------------------
931 
932 void __EXPORT ScUndoAutoFormat::Undo()
933 {
934 	BeginUndo();
935 
936 	ScDocument* pDoc = pDocShell->GetDocument();
937 
938 	// Attribute
939 //	pDoc->DeleteAreaTab( aBlockRange, IDF_ATTRIB );
940 //	pUndoDoc->CopyToDocument( aBlockRange, IDF_ATTRIB, sal_False, pDoc );
941 
942 	SCTAB nTabCount = pDoc->GetTableCount();
943 	pDoc->DeleteArea( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
944 					  aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(),
945 					  aMarkData, IDF_ATTRIB );
946 	ScRange aCopyRange = aBlockRange;
947 	aCopyRange.aStart.SetTab(0);
948 	aCopyRange.aEnd.SetTab(nTabCount-1);
949 	pUndoDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, sal_False, pDoc, &aMarkData );
950 
951 	// Zellhoehen und -breiten (IDF_NONE)
952 	if (bSize)
953 	{
954 		SCCOL nStartX = aBlockRange.aStart.Col();
955 		SCROW nStartY = aBlockRange.aStart.Row();
956 		SCTAB nStartZ = aBlockRange.aStart.Tab();
957 		SCCOL nEndX = aBlockRange.aEnd.Col();
958 		SCROW nEndY = aBlockRange.aEnd.Row();
959 		SCTAB nEndZ = aBlockRange.aEnd.Tab();
960 
961 		pUndoDoc->CopyToDocument( nStartX, 0, 0, nEndX, MAXROW, nTabCount-1,
962 									IDF_NONE, sal_False, pDoc, &aMarkData );
963 		pUndoDoc->CopyToDocument( 0, nStartY, 0, MAXCOL, nEndY, nTabCount-1,
964 									IDF_NONE, sal_False, pDoc, &aMarkData );
965 		pDocShell->PostPaint( 0, 0, nStartZ, MAXCOL, MAXROW, nEndZ,
966 							  PAINT_GRID | PAINT_LEFT | PAINT_TOP, SC_PF_LINES );
967 	}
968 	else
969 		pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES );
970 
971 	EndUndo();
972 }
973 
974 
975 //----------------------------------------------------------------------------
976 
977 void __EXPORT ScUndoAutoFormat::Redo()
978 {
979 	BeginRedo();
980 
981 	ScDocument* pDoc = pDocShell->GetDocument();
982 
983 	SCCOL nStartX = aBlockRange.aStart.Col();
984 	SCROW nStartY = aBlockRange.aStart.Row();
985 	SCTAB nStartZ = aBlockRange.aStart.Tab();
986 	SCCOL nEndX = aBlockRange.aEnd.Col();
987 	SCROW nEndY = aBlockRange.aEnd.Row();
988 	SCTAB nEndZ = aBlockRange.aEnd.Tab();
989 
990 	pDoc->AutoFormat( nStartX, nStartY, nEndX, nEndY, nFormatNo, aMarkData );
991 
992 	if (bSize)
993 	{
994 		VirtualDevice aVirtDev;
995 		Fraction aZoomX(1,1);
996 		Fraction aZoomY = aZoomX;
997 		double nPPTX,nPPTY;
998 		ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
999 		if (pViewShell)
1000 		{
1001 			ScViewData* pData = pViewShell->GetViewData();
1002 			nPPTX = pData->GetPPTX();
1003 			nPPTY = pData->GetPPTY();
1004 			aZoomX = pData->GetZoomX();
1005 			aZoomY = pData->GetZoomY();
1006 		}
1007 		else
1008 		{
1009 			//	Zoom auf 100 lassen
1010 			nPPTX = ScGlobal::nScreenPPTX;
1011 			nPPTY = ScGlobal::nScreenPPTY;
1012 		}
1013 
1014 		sal_Bool bFormula = sal_False;	//! merken
1015 
1016 		for (SCTAB nTab=nStartZ; nTab<=nEndZ; nTab++)
1017 		{
1018 			ScMarkData aDestMark;
1019 			aDestMark.SelectOneTable( nTab );
1020 			aDestMark.SetMarkArea( ScRange( nStartX, nStartY, nTab, nEndX, nEndY, nTab ) );
1021 			aDestMark.MarkToMulti();
1022 
1023 			// wie SC_SIZE_VISOPT
1024             SCROW nLastRow = -1;
1025 			for (SCROW nRow=nStartY; nRow<=nEndY; nRow++)
1026 			{
1027 				sal_uInt8 nOld = pDoc->GetRowFlags(nRow,nTab);
1028                 bool bHidden = pDoc->RowHidden(nRow, nTab, nLastRow);
1029 				if ( !bHidden && ( nOld & CR_MANUALSIZE ) )
1030 					pDoc->SetRowFlags( nRow, nTab, nOld & ~CR_MANUALSIZE );
1031 			}
1032 			pDoc->SetOptimalHeight( nStartY, nEndY, nTab, 0, &aVirtDev,
1033 										nPPTX, nPPTY, aZoomX, aZoomY, sal_False );
1034 
1035             SCCOL nLastCol = -1;
1036 			for (SCCOL nCol=nStartX; nCol<=nEndX; nCol++)
1037                 if (!pDoc->ColHidden(nCol, nTab, nLastCol))
1038 				{
1039 					sal_uInt16 nThisSize = STD_EXTRA_WIDTH + pDoc->GetOptimalColWidth( nCol, nTab,
1040 												&aVirtDev, nPPTX, nPPTY, aZoomX, aZoomY, bFormula,
1041 												&aDestMark );
1042 					pDoc->SetColWidth( nCol, nTab, nThisSize );
1043 					pDoc->ShowCol( nCol, nTab, sal_True );
1044 				}
1045 		}
1046 
1047 		pDocShell->PostPaint( 0,      0,      nStartZ,
1048 							  MAXCOL, MAXROW, nEndZ,
1049 							  PAINT_GRID | PAINT_LEFT | PAINT_TOP, SC_PF_LINES);
1050 	}
1051 	else
1052 		pDocShell->PostPaint( aBlockRange, PAINT_GRID, SC_PF_LINES );
1053 
1054 	EndRedo();
1055 }
1056 
1057 
1058 //----------------------------------------------------------------------------
1059 
1060 void __EXPORT ScUndoAutoFormat::Repeat(SfxRepeatTarget& rTarget)
1061 {
1062 	if (rTarget.ISA(ScTabViewTarget))
1063 		((ScTabViewTarget&)rTarget).GetViewShell()->AutoFormat( nFormatNo, sal_True );
1064 }
1065 
1066 
1067 //----------------------------------------------------------------------------
1068 
1069 sal_Bool __EXPORT ScUndoAutoFormat::CanRepeat(SfxRepeatTarget& rTarget) const
1070 {
1071 	return (rTarget.ISA(ScTabViewTarget));
1072 }
1073 
1074 
1075 //============================================================================
1076 //	class ScUndoReplace
1077 //
1078 //		Ersetzen
1079 
1080 //----------------------------------------------------------------------------
1081 
1082 ScUndoReplace::ScUndoReplace( ScDocShell* pNewDocShell, const ScMarkData& rMark,
1083 									SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
1084 									const String& rNewUndoStr, ScDocument* pNewUndoDoc,
1085 									const SvxSearchItem* pItem )
1086 		//
1087 	:	ScSimpleUndo( pNewDocShell ),
1088 		//
1089 		aCursorPos	( nCurX, nCurY, nCurZ ),
1090 		aMarkData	( rMark ),
1091 		aUndoStr	( rNewUndoStr ),
1092 		pUndoDoc	( pNewUndoDoc )
1093 {
1094 	pSearchItem = new SvxSearchItem( *pItem );
1095 	SetChangeTrack();
1096 }
1097 
1098 
1099 //----------------------------------------------------------------------------
1100 
1101 __EXPORT ScUndoReplace::~ScUndoReplace()
1102 {
1103 	delete pUndoDoc;
1104 	delete pSearchItem;
1105 }
1106 
1107 
1108 //----------------------------------------------------------------------------
1109 
1110 void ScUndoReplace::SetChangeTrack()
1111 {
1112 	ScDocument* pDoc = pDocShell->GetDocument();
1113 	ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1114 	if ( pChangeTrack )
1115 	{
1116 		if ( pUndoDoc )
1117 		{	//! im UndoDoc stehen nur die geaenderten Zellen,
1118 			// deswegen per Iterator moeglich
1119 			pChangeTrack->AppendContentsIfInRefDoc( pUndoDoc,
1120 				nStartChangeAction,	nEndChangeAction );
1121 		}
1122 		else
1123 		{
1124 			nStartChangeAction = pChangeTrack->GetActionMax() + 1;
1125 			ScChangeActionContent* pContent = new ScChangeActionContent(
1126 				ScRange( aCursorPos) );
1127 			pContent->SetOldValue( aUndoStr, pDoc );
1128 			pContent->SetNewValue( pDoc->GetCell( aCursorPos ), pDoc );
1129 			pChangeTrack->Append( pContent );
1130 			nEndChangeAction = pChangeTrack->GetActionMax();
1131 		}
1132 	}
1133 	else
1134 		nStartChangeAction = nEndChangeAction = 0;
1135 }
1136 
1137 //----------------------------------------------------------------------------
1138 
1139 String __EXPORT ScUndoReplace::GetComment() const
1140 {
1141 	return ScGlobal::GetRscString( STR_UNDO_REPLACE );	// "Ersetzen"
1142 }
1143 
1144 
1145 //----------------------------------------------------------------------------
1146 
1147 void __EXPORT ScUndoReplace::Undo()
1148 {
1149 	BeginUndo();
1150 
1151 	ScDocument* pDoc = pDocShell->GetDocument();
1152 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1153 
1154 	ShowTable( aCursorPos.Tab() );
1155 
1156 	if (pUndoDoc)		// nur bei ReplaceAll !!
1157 	{
1158 		DBG_ASSERT(pSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE_ALL,
1159 				   "ScUndoReplace:: Falscher Modus");
1160 
1161 	    SetViewMarkData( aMarkData );
1162 
1163 //!	markierte Tabellen
1164 //!	Bereich merken ?
1165 
1166 		//	Undo-Dokument hat keine Zeilen-/Spalten-Infos, also mit bColRowFlags = FALSE
1167 		//	kopieren, um Outline-Gruppen nicht kaputtzumachen.
1168 
1169 		sal_uInt16 nUndoFlags = (pSearchItem->GetPattern()) ? IDF_ATTRIB : IDF_CONTENTS;
1170 		pUndoDoc->CopyToDocument( 0,      0,      0,
1171 								  MAXCOL, MAXROW, MAXTAB,
1172 								  nUndoFlags, sal_False, pDoc, NULL, sal_False );	// ohne Row-Flags
1173 		pDocShell->PostPaintGridAll();
1174 	}
1175 	else if (pSearchItem->GetPattern() &&
1176 			 pSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE)
1177 	{
1178 		String aTempStr = pSearchItem->GetSearchString();		// vertauschen
1179 		pSearchItem->SetSearchString(pSearchItem->GetReplaceString());
1180 		pSearchItem->SetReplaceString(aTempStr);
1181 		pDoc->ReplaceStyle( *pSearchItem,
1182 							aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(),
1183 							aMarkData, sal_True);
1184 		pSearchItem->SetReplaceString(pSearchItem->GetSearchString());
1185 		pSearchItem->SetSearchString(aTempStr);
1186 		if (pViewShell)
1187 			pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
1188 									   SC_FOLLOW_JUMP, sal_False, sal_False );
1189 		pDocShell->PostPaintGridAll();
1190 	}
1191 	else if (pSearchItem->GetCellType() == SVX_SEARCHIN_NOTE)
1192 	{
1193         ScPostIt* pNote = pDoc->GetNote( aCursorPos );
1194         DBG_ASSERT( pNote, "ScUndoReplace::Undo - cell does not contain a note" );
1195         if (pNote)
1196             pNote->SetText( aCursorPos, aUndoStr );
1197 		if (pViewShell)
1198 			pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
1199 									   SC_FOLLOW_JUMP, sal_False, sal_False );
1200 	}
1201 	else
1202 	{
1203 		// #78889# aUndoStr may contain line breaks
1204 		if ( aUndoStr.Search('\n') != STRING_NOTFOUND )
1205 			pDoc->PutCell( aCursorPos, new ScEditCell( aUndoStr, pDoc ) );
1206 		else
1207 			pDoc->SetString( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), aUndoStr );
1208 		if (pViewShell)
1209 			pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
1210 									   SC_FOLLOW_JUMP, sal_False, sal_False );
1211 		pDocShell->PostPaintGridAll();
1212 	}
1213 
1214 	ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1215 	if ( pChangeTrack )
1216 		pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1217 
1218 	EndUndo();
1219 }
1220 
1221 
1222 //----------------------------------------------------------------------------
1223 
1224 void __EXPORT ScUndoReplace::Redo()
1225 {
1226 	BeginRedo();
1227 
1228 	ScDocument* pDoc = pDocShell->GetDocument();
1229 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1230 
1231 	if (pViewShell)
1232 		pViewShell->MoveCursorAbs( aCursorPos.Col(), aCursorPos.Row(),
1233 								   SC_FOLLOW_JUMP, sal_False, sal_False );
1234 	if (pUndoDoc)
1235 	{
1236 		if (pViewShell)
1237 		{
1238             SetViewMarkData( aMarkData );
1239 
1240 			pViewShell->SearchAndReplace( pSearchItem, sal_False, sal_True );
1241 		}
1242 	}
1243 	else if (pSearchItem->GetPattern() &&
1244 			 pSearchItem->GetCommand() == SVX_SEARCHCMD_REPLACE)
1245 	{
1246 		pDoc->ReplaceStyle( *pSearchItem,
1247 							aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(),
1248 							aMarkData, sal_True);
1249 		pDocShell->PostPaintGridAll();
1250 	}
1251 	else
1252 		if (pViewShell)
1253 			pViewShell->SearchAndReplace( pSearchItem, sal_False, sal_True );
1254 
1255 	SetChangeTrack();
1256 
1257 	EndRedo();
1258 }
1259 
1260 
1261 //----------------------------------------------------------------------------
1262 
1263 void __EXPORT ScUndoReplace::Repeat(SfxRepeatTarget& rTarget)
1264 {
1265 	if (rTarget.ISA(ScTabViewTarget))
1266 		((ScTabViewTarget&)rTarget).GetViewShell()->SearchAndReplace( pSearchItem, sal_True, sal_False );
1267 }
1268 
1269 
1270 //----------------------------------------------------------------------------
1271 
1272 sal_Bool __EXPORT ScUndoReplace::CanRepeat(SfxRepeatTarget& rTarget) const
1273 {
1274 	return (rTarget.ISA(ScTabViewTarget));
1275 }
1276 
1277 
1278 //============================================================================
1279 //	class ScUndoTabOp
1280 //
1281 //	Mehrfachoperation (nur einfache Bloecke)
1282 
1283 //----------------------------------------------------------------------------
1284 
1285 ScUndoTabOp::ScUndoTabOp( ScDocShell* pNewDocShell,
1286 				SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
1287 				SCCOL nEndX, SCROW nEndY, SCTAB nEndZ, ScDocument* pNewUndoDoc,
1288 				const ScRefAddress& rFormulaCell,
1289 				const ScRefAddress& rFormulaEnd,
1290 				const ScRefAddress& rRowCell,
1291 				const ScRefAddress& rColCell,
1292 				sal_uInt8 nMd )
1293 		//
1294 	:	ScSimpleUndo( pNewDocShell ),
1295 		//
1296 		aRange			( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
1297 		pUndoDoc		( pNewUndoDoc ),
1298 		theFormulaCell	( rFormulaCell ),
1299 		theFormulaEnd	( rFormulaEnd ),
1300 		theRowCell		( rRowCell ),
1301 		theColCell		( rColCell ),
1302 		nMode			( nMd )
1303 {
1304 }
1305 
1306 
1307 //----------------------------------------------------------------------------
1308 
1309 __EXPORT ScUndoTabOp::~ScUndoTabOp()
1310 {
1311 	delete pUndoDoc;
1312 }
1313 
1314 
1315 //----------------------------------------------------------------------------
1316 
1317 String __EXPORT ScUndoTabOp::GetComment() const
1318 {
1319 	return ScGlobal::GetRscString( STR_UNDO_TABOP );	// "Mehrfachoperation"
1320 }
1321 
1322 
1323 //----------------------------------------------------------------------------
1324 
1325 void __EXPORT ScUndoTabOp::Undo()
1326 {
1327 	BeginUndo();
1328 
1329 	ScUndoUtil::MarkSimpleBlock( pDocShell, aRange );
1330 
1331 	sal_uInt16 nExtFlags = 0;
1332 	pDocShell->UpdatePaintExt( nExtFlags, aRange );
1333 
1334 	ScDocument* pDoc = pDocShell->GetDocument();
1335     pDoc->DeleteAreaTab( aRange,IDF_ALL & ~IDF_NOTE );
1336     pUndoDoc->CopyToDocument( aRange, IDF_ALL & ~IDF_NOTE, sal_False, pDoc );
1337 	pDocShell->PostPaint( aRange, PAINT_GRID, nExtFlags );
1338 	pDocShell->PostDataChanged();
1339 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1340 	if (pViewShell)
1341 		pViewShell->CellContentChanged();
1342 
1343 	EndUndo();
1344 }
1345 
1346 
1347 //----------------------------------------------------------------------------
1348 
1349 void __EXPORT ScUndoTabOp::Redo()
1350 {
1351 	BeginRedo();
1352 
1353 	ScUndoUtil::MarkSimpleBlock( pDocShell, aRange );
1354 
1355 	ScTabOpParam aParam( theFormulaCell, theFormulaEnd,
1356 						 theRowCell,     theColCell,
1357 						 nMode );
1358 
1359 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1360 	if (pViewShell)
1361 		pViewShell->TabOp( aParam, sal_False);
1362 
1363 	EndRedo();
1364 }
1365 
1366 
1367 //----------------------------------------------------------------------------
1368 
1369 void __EXPORT ScUndoTabOp::Repeat(SfxRepeatTarget& /* rTarget */)
1370 {
1371 }
1372 
1373 
1374 //----------------------------------------------------------------------------
1375 
1376 sal_Bool __EXPORT ScUndoTabOp::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1377 {
1378 	return sal_False;
1379 }
1380 
1381 
1382 //============================================================================
1383 //  class ScUndoConversion
1384 //
1385 //	Spelling
1386 
1387 //----------------------------------------------------------------------------
1388 
1389 ScUndoConversion::ScUndoConversion(
1390         ScDocShell* pNewDocShell, const ScMarkData& rMark,
1391         SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, ScDocument* pNewUndoDoc,
1392         SCCOL nNewX, SCROW nNewY, SCTAB nNewZ, ScDocument* pNewRedoDoc,
1393         const ScConversionParam& rConvParam ) :
1394     ScSimpleUndo( pNewDocShell ),
1395     aMarkData( rMark ),
1396     aCursorPos( nCurX, nCurY, nCurZ ),
1397     pUndoDoc( pNewUndoDoc ),
1398     aNewCursorPos( nNewX, nNewY, nNewZ ),
1399     pRedoDoc( pNewRedoDoc ),
1400     maConvParam( rConvParam )
1401 {
1402 	SetChangeTrack();
1403 }
1404 
1405 
1406 //----------------------------------------------------------------------------
1407 
1408 __EXPORT ScUndoConversion::~ScUndoConversion()
1409 {
1410 	delete pUndoDoc;
1411 	delete pRedoDoc;
1412 }
1413 
1414 
1415 //----------------------------------------------------------------------------
1416 
1417 void ScUndoConversion::SetChangeTrack()
1418 {
1419 	ScDocument* pDoc = pDocShell->GetDocument();
1420 	ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
1421 	if ( pChangeTrack )
1422 	{
1423 		if ( pUndoDoc )
1424 			pChangeTrack->AppendContentsIfInRefDoc( pUndoDoc,
1425 				nStartChangeAction, nEndChangeAction );
1426 		else
1427 		{
1428             DBG_ERROR( "ScUndoConversion::SetChangeTrack: kein UndoDoc" );
1429 			nStartChangeAction = nEndChangeAction = 0;
1430 		}
1431 	}
1432 	else
1433 		nStartChangeAction = nEndChangeAction = 0;
1434 }
1435 
1436 //----------------------------------------------------------------------------
1437 
1438 String ScUndoConversion::GetComment() const
1439 {
1440     String aText;
1441     switch( maConvParam.GetType() )
1442     {
1443         case SC_CONVERSION_SPELLCHECK:      aText = ScGlobal::GetRscString( STR_UNDO_SPELLING );    break;
1444         case SC_CONVERSION_HANGULHANJA:     aText = ScGlobal::GetRscString( STR_UNDO_HANGULHANJA ); break;
1445         case SC_CONVERSION_CHINESE_TRANSL:  aText = ScGlobal::GetRscString( STR_UNDO_CHINESE_TRANSLATION ); break;
1446         default: DBG_ERRORFILE( "ScUndoConversion::GetComment - unknown conversion type" );
1447     }
1448     return aText;
1449 }
1450 
1451 
1452 //----------------------------------------------------------------------------
1453 
1454 void ScUndoConversion::DoChange( ScDocument* pRefDoc, const ScAddress& rCursorPos )
1455 {
1456 	if (pRefDoc)
1457 	{
1458 		ScDocument* pDoc = pDocShell->GetDocument();
1459 		ShowTable( rCursorPos.Tab() );
1460 
1461 	    SetViewMarkData( aMarkData );
1462 
1463 		SCTAB nTabCount = pDoc->GetTableCount();
1464 		//	Undo/Redo-doc has only selected tables
1465 
1466 		sal_Bool bMulti = aMarkData.IsMultiMarked();
1467 		pRefDoc->CopyToDocument( 0,      0,      0,
1468 								 MAXCOL, MAXROW, nTabCount-1,
1469 								 IDF_CONTENTS, bMulti, pDoc, &aMarkData );
1470 		pDocShell->PostPaintGridAll();
1471 	}
1472 	else
1473 	{
1474 		DBG_ERROR("Kein Un-/RedoDoc bei Un-/RedoSpelling");
1475 	}
1476 }
1477 
1478 
1479 //----------------------------------------------------------------------------
1480 
1481 void ScUndoConversion::Undo()
1482 {
1483 	BeginUndo();
1484 	DoChange( pUndoDoc, aCursorPos );
1485 	ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
1486 	if ( pChangeTrack )
1487 		pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1488 	EndUndo();
1489 }
1490 
1491 
1492 //----------------------------------------------------------------------------
1493 
1494 void ScUndoConversion::Redo()
1495 {
1496 	BeginRedo();
1497 	DoChange( pRedoDoc, aNewCursorPos );
1498 	SetChangeTrack();
1499 	EndRedo();
1500 }
1501 
1502 
1503 //----------------------------------------------------------------------------
1504 
1505 void ScUndoConversion::Repeat( SfxRepeatTarget& rTarget )
1506 {
1507     if( rTarget.ISA( ScTabViewTarget ) )
1508         ((ScTabViewTarget&)rTarget).GetViewShell()->DoSheetConversion( maConvParam, sal_True );
1509 }
1510 
1511 
1512 //----------------------------------------------------------------------------
1513 
1514 sal_Bool ScUndoConversion::CanRepeat(SfxRepeatTarget& rTarget) const
1515 {
1516     return rTarget.ISA( ScTabViewTarget );
1517 }
1518 
1519 
1520 //============================================================================
1521 //  class ScUndoRefConversion
1522 //
1523 //	cell reference conversion
1524 
1525 //----------------------------------------------------------------------------
1526 
1527 ScUndoRefConversion::ScUndoRefConversion( ScDocShell* pNewDocShell,
1528                                          const ScRange& aMarkRange, const ScMarkData& rMark,
1529                                          ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc, sal_Bool bNewMulti, sal_uInt16 nNewFlag) :
1530 ScSimpleUndo( pNewDocShell ),
1531 aMarkData   ( rMark ),
1532 pUndoDoc	( pNewUndoDoc ),
1533 pRedoDoc	( pNewRedoDoc ),
1534 aRange  	( aMarkRange ),
1535 bMulti      ( bNewMulti ),
1536 nFlags      ( nNewFlag )
1537 {
1538     SetChangeTrack();
1539 }
1540 
1541 __EXPORT ScUndoRefConversion::~ScUndoRefConversion()
1542 {
1543     delete pUndoDoc;
1544     delete pRedoDoc;
1545 }
1546 
1547 String __EXPORT ScUndoRefConversion::GetComment() const
1548 {
1549     return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Eingabe"
1550 }
1551 
1552 void ScUndoRefConversion::SetChangeTrack()
1553 {
1554     ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
1555     if ( pChangeTrack && (nFlags & IDF_FORMULA) )
1556         pChangeTrack->AppendContentsIfInRefDoc( pUndoDoc,
1557             nStartChangeAction, nEndChangeAction );
1558     else
1559         nStartChangeAction = nEndChangeAction = 0;
1560 }
1561 
1562 void ScUndoRefConversion::DoChange( ScDocument* pRefDoc)
1563 {
1564     ScDocument* pDoc = pDocShell->GetDocument();
1565 
1566     ShowTable(aRange);
1567 
1568     SetViewMarkData( aMarkData );
1569 
1570     ScRange aCopyRange = aRange;
1571     SCTAB nTabCount = pDoc->GetTableCount();
1572     aCopyRange.aStart.SetTab(0);
1573     aCopyRange.aEnd.SetTab(nTabCount-1);
1574     pRefDoc->CopyToDocument( aCopyRange, nFlags, bMulti, pDoc, &aMarkData );
1575     pDocShell->PostPaint( aRange, PAINT_GRID);
1576     pDocShell->PostDataChanged();
1577     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1578     if (pViewShell)
1579         pViewShell->CellContentChanged();
1580 }
1581 void __EXPORT ScUndoRefConversion::Undo()
1582 {
1583     BeginUndo();
1584     if (pUndoDoc)
1585         DoChange(pUndoDoc);
1586     ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
1587     if ( pChangeTrack )
1588         pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
1589     EndUndo();
1590 }
1591 
1592 void __EXPORT ScUndoRefConversion::Redo()
1593 {
1594     BeginRedo();
1595     if (pRedoDoc)
1596         DoChange(pRedoDoc);
1597     SetChangeTrack();
1598     EndRedo();
1599 }
1600 
1601 void __EXPORT ScUndoRefConversion::Repeat(SfxRepeatTarget& rTarget)
1602 {
1603     if (rTarget.ISA(ScTabViewTarget))
1604         ((ScTabViewTarget&)rTarget).GetViewShell()->DoRefConversion();
1605 }
1606 
1607 sal_Bool __EXPORT ScUndoRefConversion::CanRepeat(SfxRepeatTarget& rTarget) const
1608 {
1609     return (rTarget.ISA(ScTabViewTarget));
1610 }
1611 //============================================================================
1612 //	class ScUndoRefreshLink
1613 //
1614 //	Link aktualisieren / aendern
1615 
1616 //----------------------------------------------------------------------------
1617 
1618 ScUndoRefreshLink::ScUndoRefreshLink( ScDocShell* pNewDocShell,
1619 									ScDocument* pNewUndoDoc )
1620 		//
1621 	:	ScSimpleUndo( pNewDocShell ),
1622 		//
1623 		pUndoDoc( pNewUndoDoc ),
1624 		pRedoDoc( NULL )
1625 {
1626 }
1627 
1628 
1629 //----------------------------------------------------------------------------
1630 
1631 __EXPORT ScUndoRefreshLink::~ScUndoRefreshLink()
1632 {
1633 	delete pUndoDoc;
1634 	delete pRedoDoc;
1635 }
1636 
1637 
1638 //----------------------------------------------------------------------------
1639 
1640 String __EXPORT ScUndoRefreshLink::GetComment() const
1641 {
1642 	return ScGlobal::GetRscString( STR_UNDO_UPDATELINK );
1643 }
1644 
1645 
1646 //----------------------------------------------------------------------------
1647 
1648 void __EXPORT ScUndoRefreshLink::Undo()
1649 {
1650 	BeginUndo();
1651 
1652 	sal_Bool bMakeRedo = !pRedoDoc;
1653 	if (bMakeRedo)
1654 		pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
1655 
1656 	sal_Bool bFirst = sal_True;
1657 	ScDocument* pDoc = pDocShell->GetDocument();
1658 	SCTAB nCount = pDoc->GetTableCount();
1659 	for (SCTAB nTab=0; nTab<nCount; nTab++)
1660 		if (pUndoDoc->HasTable(nTab))
1661 		{
1662 			ScRange aRange(0,0,nTab,MAXCOL,MAXROW,nTab);
1663 			if (bMakeRedo)
1664 			{
1665 				if (bFirst)
1666 					pRedoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
1667 				else
1668 					pRedoDoc->AddUndoTab( nTab, nTab, sal_True, sal_True );
1669 				bFirst = sal_False;
1670 				pDoc->CopyToDocument(aRange, IDF_ALL, sal_False, pRedoDoc);
1671 //				pRedoDoc->TransferDrawPage( pDoc, nTab, nTab );
1672 				pRedoDoc->SetLink( nTab,
1673 								   pDoc->GetLinkMode(nTab),
1674 								   pDoc->GetLinkDoc(nTab),
1675 								   pDoc->GetLinkFlt(nTab),
1676 								   pDoc->GetLinkOpt(nTab),
1677 								   pDoc->GetLinkTab(nTab),
1678 								   pDoc->GetLinkRefreshDelay(nTab) );
1679 			}
1680 
1681 			pDoc->DeleteAreaTab( aRange,IDF_ALL );
1682 			pUndoDoc->CopyToDocument( aRange, IDF_ALL, sal_False, pDoc );
1683 //			pDoc->TransferDrawPage( pUndoDoc, nTab, nTab );
1684 			pDoc->SetLink( nTab, pUndoDoc->GetLinkMode(nTab), pUndoDoc->GetLinkDoc(nTab),
1685 								 pUndoDoc->GetLinkFlt(nTab),  pUndoDoc->GetLinkOpt(nTab),
1686 								 pUndoDoc->GetLinkTab(nTab),
1687 								 pUndoDoc->GetLinkRefreshDelay(nTab) );
1688 		}
1689 
1690 	pDocShell->PostPaintGridAll();
1691 
1692 	EndUndo();
1693 }
1694 
1695 
1696 //----------------------------------------------------------------------------
1697 
1698 void __EXPORT ScUndoRefreshLink::Redo()
1699 {
1700 	DBG_ASSERT(pRedoDoc, "Kein RedoDoc bei ScUndoRefreshLink::Redo");
1701 
1702 	BeginUndo();
1703 
1704 	ScDocument* pDoc = pDocShell->GetDocument();
1705 	SCTAB nCount = pDoc->GetTableCount();
1706 	for (SCTAB nTab=0; nTab<nCount; nTab++)
1707 		if (pRedoDoc->HasTable(nTab))
1708 		{
1709 			ScRange aRange(0,0,nTab,MAXCOL,MAXROW,nTab);
1710 
1711 			pDoc->DeleteAreaTab( aRange, IDF_ALL );
1712 			pRedoDoc->CopyToDocument( aRange, IDF_ALL, sal_False, pDoc );
1713 //			pDoc->TransferDrawPage( pRedoDoc, nTab, nTab );
1714 			pDoc->SetLink( nTab,
1715 						   pRedoDoc->GetLinkMode(nTab),
1716 						   pRedoDoc->GetLinkDoc(nTab),
1717 						   pRedoDoc->GetLinkFlt(nTab),
1718 						   pRedoDoc->GetLinkOpt(nTab),
1719 						   pRedoDoc->GetLinkTab(nTab),
1720 						   pRedoDoc->GetLinkRefreshDelay(nTab) );
1721 		}
1722 
1723 	pDocShell->PostPaintGridAll();
1724 
1725 	EndUndo();
1726 }
1727 
1728 
1729 //----------------------------------------------------------------------------
1730 
1731 void __EXPORT ScUndoRefreshLink::Repeat(SfxRepeatTarget& /* rTarget */)
1732 {
1733 	//	gippsnich
1734 }
1735 
1736 
1737 //----------------------------------------------------------------------------
1738 
1739 sal_Bool __EXPORT ScUndoRefreshLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1740 {
1741 	return sal_False;
1742 }
1743 
1744 
1745 //----------------------------------------------------------------------------
1746 
1747 ScAreaLink* lcl_FindAreaLink( sfx2::LinkManager* pLinkManager, const String& rDoc,
1748 							const String& rFlt, const String& rOpt,
1749 							const String& rSrc, const ScRange& rDest )
1750 {
1751     const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
1752 	sal_uInt16 nCount = pLinkManager->GetLinks().Count();
1753 	for (sal_uInt16 i=0; i<nCount; i++)
1754 	{
1755         ::sfx2::SvBaseLink* pBase = *rLinks[i];
1756 		if (pBase->ISA(ScAreaLink))
1757 			if ( ((ScAreaLink*)pBase)->IsEqual( rDoc, rFlt, rOpt, rSrc, rDest ) )
1758 				return (ScAreaLink*)pBase;
1759 	}
1760 
1761 	DBG_ERROR("ScAreaLink nicht gefunden");
1762 	return NULL;
1763 }
1764 
1765 
1766 //============================================================================
1767 //	class ScUndoInsertAreaLink
1768 //
1769 //	Bereichs-Verknuepfung einfuegen
1770 
1771 //----------------------------------------------------------------------------
1772 
1773 ScUndoInsertAreaLink::ScUndoInsertAreaLink( ScDocShell* pShell,
1774 							const String& rDoc,
1775 							const String& rFlt, const String& rOpt,
1776 							const String& rArea, const ScRange& rDestRange,
1777 							sal_uLong nRefresh )
1778 		//
1779 	:	ScSimpleUndo	( pShell ),
1780 		//
1781 		aDocName		( rDoc ),
1782 		aFltName		( rFlt ),
1783 		aOptions		( rOpt ),
1784 		aAreaName		( rArea ),
1785 		aRange			( rDestRange ),
1786 		nRefreshDelay	( nRefresh )
1787 {
1788 }
1789 
1790 
1791 //----------------------------------------------------------------------------
1792 
1793 __EXPORT ScUndoInsertAreaLink::~ScUndoInsertAreaLink()
1794 {
1795 }
1796 
1797 
1798 //----------------------------------------------------------------------------
1799 
1800 String __EXPORT ScUndoInsertAreaLink::GetComment() const
1801 {
1802 	return ScGlobal::GetRscString( STR_UNDO_INSERTAREALINK );
1803 }
1804 
1805 
1806 //----------------------------------------------------------------------------
1807 
1808 void __EXPORT ScUndoInsertAreaLink::Undo()
1809 {
1810 	ScDocument* pDoc = pDocShell->GetDocument();
1811 	sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1812 
1813 	ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aDocName, aFltName, aOptions,
1814 											aAreaName, aRange );
1815 	if (pLink)
1816 		pLinkManager->Remove( pLink );
1817 
1818 	SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );		// Navigator
1819 }
1820 
1821 
1822 //----------------------------------------------------------------------------
1823 
1824 void __EXPORT ScUndoInsertAreaLink::Redo()
1825 {
1826 	ScDocument* pDoc = pDocShell->GetDocument();
1827 	sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1828 
1829 	ScAreaLink* pLink = new ScAreaLink( pDocShell, aDocName, aFltName, aOptions,
1830 											aAreaName, aRange.aStart, nRefreshDelay );
1831 	pLink->SetInCreate( sal_True );
1832 	pLink->SetDestArea( aRange );
1833 	pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aDocName, &aFltName, &aAreaName );
1834 	pLink->Update();
1835 	pLink->SetInCreate( sal_False );
1836 
1837 	SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );		// Navigator
1838 }
1839 
1840 
1841 //----------------------------------------------------------------------------
1842 
1843 void __EXPORT ScUndoInsertAreaLink::Repeat(SfxRepeatTarget& /* rTarget */)
1844 {
1845 	//!	....
1846 }
1847 
1848 
1849 //----------------------------------------------------------------------------
1850 
1851 sal_Bool __EXPORT ScUndoInsertAreaLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1852 {
1853 	return sal_False;
1854 }
1855 
1856 
1857 //============================================================================
1858 //	class ScUndoRemoveAreaLink
1859 //
1860 //	Bereichs-Verknuepfung loeschen
1861 
1862 //----------------------------------------------------------------------------
1863 
1864 ScUndoRemoveAreaLink::ScUndoRemoveAreaLink( ScDocShell* pShell,
1865 							const String& rDoc, const String& rFlt, const String& rOpt,
1866 							const String& rArea, const ScRange& rDestRange,
1867 							sal_uLong nRefresh )
1868 		//
1869 	:	ScSimpleUndo	( pShell ),
1870 		//
1871 		aDocName		( rDoc ),
1872 		aFltName		( rFlt ),
1873 		aOptions		( rOpt ),
1874 		aAreaName		( rArea ),
1875 		aRange			( rDestRange ),
1876 		nRefreshDelay	( nRefresh )
1877 {
1878 }
1879 
1880 
1881 //----------------------------------------------------------------------------
1882 
1883 __EXPORT ScUndoRemoveAreaLink::~ScUndoRemoveAreaLink()
1884 {
1885 }
1886 
1887 
1888 //----------------------------------------------------------------------------
1889 
1890 String __EXPORT ScUndoRemoveAreaLink::GetComment() const
1891 {
1892 	return ScGlobal::GetRscString( STR_UNDO_REMOVELINK );	//! eigener Text ??
1893 }
1894 
1895 
1896 //----------------------------------------------------------------------------
1897 
1898 void __EXPORT ScUndoRemoveAreaLink::Undo()
1899 {
1900 	ScDocument* pDoc = pDocShell->GetDocument();
1901 	sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1902 
1903 	ScAreaLink* pLink = new ScAreaLink( pDocShell, aDocName, aFltName, aOptions,
1904 										aAreaName, aRange.aStart, nRefreshDelay );
1905 	pLink->SetInCreate( sal_True );
1906 	pLink->SetDestArea( aRange );
1907 	pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aDocName, &aFltName, &aAreaName );
1908 	pLink->Update();
1909 	pLink->SetInCreate( sal_False );
1910 
1911 	SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );		// Navigator
1912 }
1913 
1914 
1915 //----------------------------------------------------------------------------
1916 
1917 void __EXPORT ScUndoRemoveAreaLink::Redo()
1918 {
1919 	ScDocument* pDoc = pDocShell->GetDocument();
1920 	sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1921 
1922 	ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aDocName, aFltName, aOptions,
1923 											aAreaName, aRange );
1924 	if (pLink)
1925 		pLinkManager->Remove( pLink );
1926 
1927 	SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );		// Navigator
1928 }
1929 
1930 
1931 //----------------------------------------------------------------------------
1932 
1933 void __EXPORT ScUndoRemoveAreaLink::Repeat(SfxRepeatTarget& /* rTarget */)
1934 {
1935 	//	gippsnich
1936 }
1937 
1938 
1939 //----------------------------------------------------------------------------
1940 
1941 sal_Bool __EXPORT ScUndoRemoveAreaLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1942 {
1943 	return sal_False;
1944 }
1945 
1946 
1947 //============================================================================
1948 //	class ScUndoUpdateAreaLink
1949 //
1950 //	Bereichs-Verknuepfung aktualisieren
1951 
1952 //----------------------------------------------------------------------------
1953 
1954 ScUndoUpdateAreaLink::ScUndoUpdateAreaLink( ScDocShell* pShell,
1955 							const String& rOldD, const String& rOldF, const String& rOldO,
1956 							const String& rOldA, const ScRange& rOldR, sal_uLong nOldRD,
1957 							const String& rNewD, const String& rNewF, const String& rNewO,
1958 							const String& rNewA, const ScRange& rNewR, sal_uLong nNewRD,
1959 							ScDocument* pUndo, ScDocument* pRedo, sal_Bool bDoInsert )
1960 		//
1961 	:	ScSimpleUndo( pShell ),
1962 		//
1963 		aOldDoc		( rOldD ),
1964 		aOldFlt		( rOldF ),
1965 		aOldOpt		( rOldO ),
1966 		aOldArea	( rOldA ),
1967 		aOldRange	( rOldR ),
1968 		aNewDoc		( rNewD ),
1969 		aNewFlt		( rNewF ),
1970 		aNewOpt		( rNewO ),
1971 		aNewArea	( rNewA ),
1972 		aNewRange	( rNewR ),
1973 		pUndoDoc	( pUndo ),
1974 		pRedoDoc	( pRedo ),
1975 		nOldRefresh	( nOldRD ),
1976 		nNewRefresh	( nNewRD ),
1977 		bWithInsert	( bDoInsert )
1978 {
1979 	DBG_ASSERT( aOldRange.aStart == aNewRange.aStart, "AreaLink verschoben ?" );
1980 }
1981 
1982 
1983 //----------------------------------------------------------------------------
1984 
1985 __EXPORT ScUndoUpdateAreaLink::~ScUndoUpdateAreaLink()
1986 {
1987 	delete pUndoDoc;
1988 	delete pRedoDoc;
1989 }
1990 
1991 
1992 //----------------------------------------------------------------------------
1993 
1994 String __EXPORT ScUndoUpdateAreaLink::GetComment() const
1995 {
1996 	return ScGlobal::GetRscString( STR_UNDO_UPDATELINK );	//! eigener Text ??
1997 }
1998 
1999 
2000 //----------------------------------------------------------------------------
2001 
2002 void ScUndoUpdateAreaLink::DoChange( const sal_Bool bUndo ) const
2003 {
2004 	ScDocument* pDoc = pDocShell->GetDocument();
2005 
2006 	SCCOL nEndX = Max( aOldRange.aEnd.Col(), aNewRange.aEnd.Col() );
2007 	SCROW nEndY = Max( aOldRange.aEnd.Row(), aNewRange.aEnd.Row() );
2008 	SCTAB nEndZ = Max( aOldRange.aEnd.Tab(), aNewRange.aEnd.Tab() );	//?
2009 
2010 	if ( bUndo )
2011 	{
2012 		if ( bWithInsert )
2013 		{
2014 			pDoc->FitBlock( aNewRange, aOldRange );
2015             pDoc->DeleteAreaTab( aOldRange, IDF_ALL & ~IDF_NOTE );
2016             pUndoDoc->UndoToDocument( aOldRange, IDF_ALL & ~IDF_NOTE, sal_False, pDoc );
2017 		}
2018 		else
2019 		{
2020 			ScRange aCopyRange( aOldRange.aStart, ScAddress(nEndX,nEndY,nEndZ) );
2021             pDoc->DeleteAreaTab( aCopyRange, IDF_ALL & ~IDF_NOTE );
2022             pUndoDoc->CopyToDocument( aCopyRange, IDF_ALL & ~IDF_NOTE, sal_False, pDoc );
2023 		}
2024 	}
2025 	else
2026 	{
2027 		if ( bWithInsert )
2028 		{
2029 			pDoc->FitBlock( aOldRange, aNewRange );
2030             pDoc->DeleteAreaTab( aNewRange, IDF_ALL & ~IDF_NOTE );
2031             pRedoDoc->CopyToDocument( aNewRange, IDF_ALL & ~IDF_NOTE, sal_False, pDoc );
2032 		}
2033 		else
2034 		{
2035 			ScRange aCopyRange( aOldRange.aStart, ScAddress(nEndX,nEndY,nEndZ) );
2036             pDoc->DeleteAreaTab( aCopyRange, IDF_ALL & ~IDF_NOTE );
2037             pRedoDoc->CopyToDocument( aCopyRange, IDF_ALL & ~IDF_NOTE, sal_False, pDoc );
2038 		}
2039 	}
2040 
2041 	ScRange aWorkRange( aNewRange.aStart, ScAddress( nEndX, nEndY, nEndZ ) );
2042 	pDoc->ExtendMerge( aWorkRange, sal_True );
2043 
2044 	//	Paint
2045 
2046 	if ( aNewRange.aEnd.Col() != aOldRange.aEnd.Col() )
2047 		aWorkRange.aEnd.SetCol(MAXCOL);
2048 	if ( aNewRange.aEnd.Row() != aOldRange.aEnd.Row() )
2049 		aWorkRange.aEnd.SetRow(MAXROW);
2050 
2051 	if ( !pDocShell->AdjustRowHeight( aWorkRange.aStart.Row(), aWorkRange.aEnd.Row(), aWorkRange.aStart.Tab() ) )
2052 		pDocShell->PostPaint( aWorkRange, PAINT_GRID );
2053 
2054 	pDocShell->PostDataChanged();
2055 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
2056 	if (pViewShell)
2057 		pViewShell->CellContentChanged();
2058 }
2059 
2060 
2061 //----------------------------------------------------------------------------
2062 
2063 void __EXPORT ScUndoUpdateAreaLink::Undo()
2064 {
2065 	ScDocument* pDoc = pDocShell->GetDocument();
2066 	sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
2067 	ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aNewDoc, aNewFlt, aNewOpt,
2068 											aNewArea, aNewRange );
2069 	if (pLink)
2070 	{
2071 		pLink->SetSource( aOldDoc, aOldFlt, aOldOpt, aOldArea );		// alte Werte im Link
2072 		pLink->SetDestArea( aOldRange );
2073 		pLink->SetRefreshDelay( nOldRefresh );
2074 	}
2075 
2076 	DoChange(sal_True);
2077 }
2078 
2079 
2080 //----------------------------------------------------------------------------
2081 
2082 void __EXPORT ScUndoUpdateAreaLink::Redo()
2083 {
2084 	ScDocument* pDoc = pDocShell->GetDocument();
2085 	sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
2086 	ScAreaLink* pLink = lcl_FindAreaLink( pLinkManager, aOldDoc, aOldFlt, aOldOpt,
2087 											aOldArea, aOldRange );
2088 	if (pLink)
2089 	{
2090 		pLink->SetSource( aNewDoc, aNewFlt, aNewOpt, aNewArea );		// neue Werte im Link
2091 		pLink->SetDestArea( aNewRange );
2092 		pLink->SetRefreshDelay( nNewRefresh );
2093 	}
2094 
2095 	DoChange(sal_False);
2096 }
2097 
2098 
2099 //----------------------------------------------------------------------------
2100 
2101 void __EXPORT ScUndoUpdateAreaLink::Repeat(SfxRepeatTarget& /* rTarget */)
2102 {
2103 	//	gippsnich
2104 }
2105 
2106 
2107 //----------------------------------------------------------------------------
2108 
2109 sal_Bool __EXPORT ScUndoUpdateAreaLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
2110 {
2111 	return sal_False;
2112 }
2113 
2114 
2115 
2116 
2117