xref: /aoo41x/main/sc/source/ui/undo/undocell.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 #include "scitems.hxx"
32 #include <editeng/eeitem.hxx>
33 
34 #include <editeng/editobj.hxx>
35 #include <svl/zforlist.hxx>
36 #include <sfx2/app.hxx>
37 
38 #include "undocell.hxx"
39 #include "document.hxx"
40 #include "docpool.hxx"
41 #include "patattr.hxx"
42 #include "docsh.hxx"
43 #include "tabvwsh.hxx"
44 #include "globstr.hrc"
45 #include "global.hxx"
46 #include "cell.hxx"
47 #include "target.hxx"
48 #include "undoolk.hxx"
49 #include "detdata.hxx"
50 #include "stlpool.hxx"
51 #include "printfun.hxx"
52 #include "rangenam.hxx"
53 #include "chgtrack.hxx"
54 #include "sc.hrc"
55 #include "docuno.hxx"
56 
57 // STATIC DATA -----------------------------------------------------------
58 
59 TYPEINIT1(ScUndoCursorAttr, ScSimpleUndo);
60 TYPEINIT1(ScUndoEnterData, ScSimpleUndo);
61 TYPEINIT1(ScUndoEnterValue, ScSimpleUndo);
62 TYPEINIT1(ScUndoPutCell, ScSimpleUndo);
63 TYPEINIT1(ScUndoPageBreak, ScSimpleUndo);
64 TYPEINIT1(ScUndoPrintZoom, ScSimpleUndo);
65 TYPEINIT1(ScUndoThesaurus, ScSimpleUndo);
66 TYPEINIT1(ScUndoReplaceNote, ScSimpleUndo);
67 TYPEINIT1(ScUndoShowHideNote, ScSimpleUndo);
68 TYPEINIT1(ScUndoDetective, ScSimpleUndo);
69 TYPEINIT1(ScUndoRangeNames, ScSimpleUndo);
70 
71 
72 // -----------------------------------------------------------------------
73 //
74 //		Attribute auf Cursor anwenden
75 //
76 
77 ScUndoCursorAttr::ScUndoCursorAttr( ScDocShell* pNewDocShell,
78 			SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
79 			const ScPatternAttr* pOldPat, const ScPatternAttr* pNewPat,
80 			const ScPatternAttr* pApplyPat, sal_Bool bAutomatic ) :
81 	ScSimpleUndo( pNewDocShell ),
82 	nCol( nNewCol ),
83 	nRow( nNewRow ),
84 	nTab( nNewTab ),
85 	bIsAutomatic( bAutomatic )
86 {
87 	ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
88 	pNewPattern = (ScPatternAttr*) &pPool->Put( *pNewPat );
89 	pOldPattern = (ScPatternAttr*) &pPool->Put( *pOldPat );
90 	pApplyPattern = (ScPatternAttr*) &pPool->Put( *pApplyPat );
91 }
92 
93 __EXPORT ScUndoCursorAttr::~ScUndoCursorAttr()
94 {
95 	ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
96 	pPool->Remove(*pNewPattern);
97 	pPool->Remove(*pOldPattern);
98 	pPool->Remove(*pApplyPattern);
99 }
100 
101 String __EXPORT ScUndoCursorAttr::GetComment() const
102 {
103 	//!	eigener Text fuer automatische Attributierung
104 
105 	sal_uInt16 nId = STR_UNDO_CURSORATTR;		 // "Attribute"
106 	return ScGlobal::GetRscString( nId );
107 }
108 
109 void ScUndoCursorAttr::DoChange( const ScPatternAttr* pWhichPattern ) const
110 {
111 	pDocShell->GetDocument()->SetPattern( nCol, nRow, nTab, *pWhichPattern, sal_True );
112 
113 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
114 	if (pViewShell)
115 	{
116 		pViewShell->SetTabNo( nTab );
117 		pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, sal_False, sal_False );
118 		pViewShell->AdjustBlockHeight();
119 	}
120 
121 	const SfxItemSet& rApplySet = pApplyPattern->GetItemSet();
122 	sal_Bool bPaintExt = ( rApplySet.GetItemState( ATTR_SHADOW, sal_True ) != SFX_ITEM_DEFAULT ||
123 					   rApplySet.GetItemState( ATTR_CONDITIONAL, sal_True ) != SFX_ITEM_DEFAULT );
124 	sal_Bool bPaintRows = ( rApplySet.GetItemState( ATTR_HOR_JUSTIFY, sal_True ) != SFX_ITEM_DEFAULT );
125 
126 	sal_uInt16 nFlags = SC_PF_TESTMERGE;
127 	if (bPaintExt)
128 		nFlags |= SC_PF_LINES;
129 	if (bPaintRows)
130 		nFlags |= SC_PF_WHOLEROWS;
131 	pDocShell->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID, nFlags );
132 }
133 
134 void __EXPORT ScUndoCursorAttr::Undo()
135 {
136 	BeginUndo();
137 	DoChange(pOldPattern);
138 
139 	if ( bIsAutomatic )
140 	{
141 		//	wenn automatische Formatierung rueckgaengig gemacht wird,
142 		//	soll auch nicht weiter automatisch formatiert werden:
143 
144 		ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
145 		if (pViewShell)
146 			pViewShell->ForgetFormatArea();
147 	}
148 
149 	EndUndo();
150 }
151 
152 void __EXPORT ScUndoCursorAttr::Redo()
153 {
154 	BeginRedo();
155 	DoChange(pNewPattern);
156 	EndRedo();
157 }
158 
159 void __EXPORT ScUndoCursorAttr::Repeat(SfxRepeatTarget& rTarget)
160 {
161 	if (rTarget.ISA(ScTabViewTarget))
162 		((ScTabViewTarget&)rTarget).GetViewShell()->ApplySelectionPattern( *pApplyPattern );
163 }
164 
165 sal_Bool __EXPORT ScUndoCursorAttr::CanRepeat(SfxRepeatTarget& rTarget) const
166 {
167 	return (rTarget.ISA(ScTabViewTarget));
168 }
169 
170 
171 // -----------------------------------------------------------------------
172 //
173 //		Daten eingeben
174 //
175 
176 ScUndoEnterData::ScUndoEnterData( ScDocShell* pNewDocShell,
177 			SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
178 			SCTAB nNewCount, SCTAB* pNewTabs, ScBaseCell** ppOldData,
179 			sal_Bool* pHasForm, sal_uLong* pOldForm,
180 			const String& rNewStr, EditTextObject* pObj ) :
181 	ScSimpleUndo( pNewDocShell ),
182 	aNewString( rNewStr ),
183 	pTabs( pNewTabs ),
184 	ppOldCells( ppOldData ),
185 	pHasFormat( pHasForm ),
186 	pOldFormats( pOldForm ),
187 	pNewEditData( pObj ),
188 	nCol( nNewCol ),
189 	nRow( nNewRow ),
190 	nTab( nNewTab ),
191 	nCount( nNewCount )
192 {
193 	SetChangeTrack();
194 }
195 
196 __EXPORT ScUndoEnterData::~ScUndoEnterData()
197 {
198 	for (sal_uInt16 i=0; i<nCount; i++)
199 		if (ppOldCells[i])
200 			ppOldCells[i]->Delete();
201 	delete[] ppOldCells;
202 
203 	delete[] pHasFormat;
204 	delete[] pOldFormats;
205 	delete[] pTabs;
206 
207 	delete pNewEditData;
208 }
209 
210 String __EXPORT ScUndoEnterData::GetComment() const
211 {
212 	return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Eingabe"
213 }
214 
215 void ScUndoEnterData::DoChange() const
216 {
217 	//	Zeilenhoehe anpassen
218 	//!	nur wenn noetig (alte oder neue EditZelle, oder Attribute) ??
219 	for (sal_uInt16 i=0; i<nCount; i++)
220 		pDocShell->AdjustRowHeight( nRow, nRow, pTabs[i] );
221 
222 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
223 	if (pViewShell)
224 	{
225 		pViewShell->SetTabNo( nTab );
226 		pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, sal_False, sal_False );
227 	}
228 
229 	pDocShell->PostDataChanged();
230 }
231 
232 void ScUndoEnterData::SetChangeTrack()
233 {
234 	ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
235 	if ( pChangeTrack )
236 	{
237 		nEndChangeAction = pChangeTrack->GetActionMax() + 1;
238 		ScAddress aPos( nCol, nRow, nTab );
239 		for (sal_uInt16 i=0; i<nCount; i++)
240 		{
241 			aPos.SetTab( pTabs[i] );
242 			sal_uLong nFormat = 0;
243 			if ( pHasFormat && pOldFormats )
244 			{
245 				if ( pHasFormat[i] )
246 					nFormat = pOldFormats[i];
247 			}
248 			pChangeTrack->AppendContent( aPos, ppOldCells[i], nFormat );
249 		}
250 		if ( nEndChangeAction > pChangeTrack->GetActionMax() )
251 			nEndChangeAction = 0;		// nichts appended
252 	}
253 	else
254 		nEndChangeAction = 0;
255 }
256 
257 void __EXPORT ScUndoEnterData::Undo()
258 {
259 	BeginUndo();
260 
261 	ScDocument* pDoc = pDocShell->GetDocument();
262 	for (sal_uInt16 i=0; i<nCount; i++)
263 	{
264         ScBaseCell* pNewCell = ppOldCells[i] ? ppOldCells[i]->CloneWithoutNote( *pDoc, SC_CLONECELL_STARTLISTENING ) : 0;
265 		pDoc->PutCell( nCol, nRow, pTabs[i], pNewCell );
266 
267 		if (pHasFormat && pOldFormats)
268 		{
269 			if ( pHasFormat[i] )
270 				pDoc->ApplyAttr( nCol, nRow, pTabs[i],
271 									SfxUInt32Item( ATTR_VALUE_FORMAT, pOldFormats[i] ) );
272 			else
273 			{
274 				ScPatternAttr aPattern( *pDoc->GetPattern( nCol, nRow, pTabs[i] ) );
275 				aPattern.GetItemSet().ClearItem( ATTR_VALUE_FORMAT );
276 				pDoc->SetPattern( nCol, nRow, pTabs[i], aPattern, sal_True );
277 			}
278 		}
279 		pDocShell->PostPaintCell( nCol, nRow, pTabs[i] );
280 	}
281 
282 	ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
283     if ( pChangeTrack && nEndChangeAction >= sal::static_int_cast<sal_uLong>(nCount) )
284 		pChangeTrack->Undo( nEndChangeAction - nCount + 1, nEndChangeAction );
285 
286 	DoChange();
287 	EndUndo();
288 
289     // #i97876# Spreadsheet data changes are not notified
290     ScModelObj* pModelObj = ScModelObj::getImplementation( pDocShell->GetModel() );
291     if ( pModelObj && pModelObj->HasChangesListeners() )
292     {
293         ScRangeList aChangeRanges;
294         for ( sal_uInt16 i = 0; i < nCount; ++i )
295         {
296             aChangeRanges.Append( ScRange( nCol, nRow, pTabs[i] ) );
297         }
298         pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
299     }
300 }
301 
302 void __EXPORT ScUndoEnterData::Redo()
303 {
304 	BeginRedo();
305 
306 	ScDocument* pDoc = pDocShell->GetDocument();
307 	for (sal_uInt16 i=0; i<nCount; i++)
308 	{
309 		if (pNewEditData)
310 			pDoc->PutCell( nCol, nRow, pTabs[i], new ScEditCell( pNewEditData,
311 				pDoc, NULL ) );
312 		else
313 			pDoc->SetString( nCol, nRow, pTabs[i], aNewString );
314 		pDocShell->PostPaintCell( nCol, nRow, pTabs[i] );
315 	}
316 
317 	SetChangeTrack();
318 
319 	DoChange();
320 	EndRedo();
321 
322     // #i97876# Spreadsheet data changes are not notified
323     ScModelObj* pModelObj = ScModelObj::getImplementation( pDocShell->GetModel() );
324     if ( pModelObj && pModelObj->HasChangesListeners() )
325     {
326         ScRangeList aChangeRanges;
327         for ( sal_uInt16 i = 0; i < nCount; ++i )
328         {
329             aChangeRanges.Append( ScRange( nCol, nRow, pTabs[i] ) );
330         }
331         pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
332     }
333 }
334 
335 void __EXPORT ScUndoEnterData::Repeat(SfxRepeatTarget& rTarget)
336 {
337 	if (rTarget.ISA(ScTabViewTarget))
338 	{
339 		String aTemp = aNewString;
340 		((ScTabViewTarget&)rTarget).GetViewShell()->EnterDataAtCursor( aTemp );
341 	}
342 }
343 
344 sal_Bool __EXPORT ScUndoEnterData::CanRepeat(SfxRepeatTarget& rTarget) const
345 {
346 	return (rTarget.ISA(ScTabViewTarget));
347 }
348 
349 
350 // -----------------------------------------------------------------------
351 //
352 //		Wert aendern
353 //
354 
355 ScUndoEnterValue::ScUndoEnterValue( ScDocShell* pNewDocShell, const ScAddress& rNewPos,
356 									ScBaseCell* pUndoCell, double nVal, sal_Bool bHeight ) :
357 	ScSimpleUndo( pNewDocShell ),
358 	aPos		( rNewPos ),
359 	pOldCell	( pUndoCell ),
360 	nValue		( nVal ),
361 	bNeedHeight	( bHeight )
362 {
363 	SetChangeTrack();
364 }
365 
366 __EXPORT ScUndoEnterValue::~ScUndoEnterValue()
367 {
368 	if (pOldCell)
369 		pOldCell->Delete();
370 }
371 
372 String __EXPORT ScUndoEnterValue::GetComment() const
373 {
374 	return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Eingabe"
375 }
376 
377 void ScUndoEnterValue::SetChangeTrack()
378 {
379 	ScDocument* pDoc = pDocShell->GetDocument();
380 	ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
381 	if ( pChangeTrack )
382 	{
383 		nEndChangeAction = pChangeTrack->GetActionMax() + 1;
384 		pChangeTrack->AppendContent( aPos, pOldCell );
385 		if ( nEndChangeAction > pChangeTrack->GetActionMax() )
386 			nEndChangeAction = 0;		// nichts appended
387 	}
388 	else
389 		nEndChangeAction = 0;
390 }
391 
392 void __EXPORT ScUndoEnterValue::Undo()
393 {
394 	BeginUndo();
395 
396 	ScDocument* pDoc = pDocShell->GetDocument();
397     ScBaseCell* pNewCell = pOldCell ? pOldCell->CloneWithoutNote( *pDoc, SC_CLONECELL_STARTLISTENING ) : 0;
398 
399 	pDoc->PutCell( aPos, pNewCell );
400 
401 	pDocShell->PostPaintCell( aPos );
402 
403 	ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
404 	if ( pChangeTrack )
405 		pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
406 
407 	EndUndo();
408 }
409 
410 void __EXPORT ScUndoEnterValue::Redo()
411 {
412 	BeginRedo();
413 
414 	ScDocument* pDoc = pDocShell->GetDocument();
415 	pDoc->SetValue( aPos.Col(), aPos.Row(), aPos.Tab(), nValue );
416 	pDocShell->PostPaintCell( aPos );
417 
418 	SetChangeTrack();
419 
420 	EndRedo();
421 }
422 
423 void __EXPORT ScUndoEnterValue::Repeat(SfxRepeatTarget& /* rTarget */)
424 {
425 	//	gippsnich
426 }
427 
428 sal_Bool __EXPORT ScUndoEnterValue::CanRepeat(SfxRepeatTarget& /* rTarget */) const
429 {
430 	return sal_False;
431 }
432 
433 
434 // -----------------------------------------------------------------------
435 //
436 //		Beliebige Zelle eingeben
437 //
438 
439 ScUndoPutCell::ScUndoPutCell( ScDocShell* pNewDocShell, const ScAddress& rNewPos,
440 							ScBaseCell* pUndoCell, ScBaseCell* pRedoCell, sal_Bool bHeight ) :
441 	ScSimpleUndo( pNewDocShell ),
442 	aPos		( rNewPos ),
443 	pOldCell	( pUndoCell ),
444 	pEnteredCell( pRedoCell ),
445 	bNeedHeight	( bHeight )
446 {
447 	SetChangeTrack();
448 }
449 
450 __EXPORT ScUndoPutCell::~ScUndoPutCell()
451 {
452 	if (pOldCell)
453 		pOldCell->Delete();
454 	if (pEnteredCell)
455 		pEnteredCell->Delete();
456 }
457 
458 String __EXPORT ScUndoPutCell::GetComment() const
459 {
460 	return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Eingabe"
461 }
462 
463 void ScUndoPutCell::SetChangeTrack()
464 {
465 	ScDocument* pDoc = pDocShell->GetDocument();
466 	ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
467 	if ( pChangeTrack )
468 	{
469 		nEndChangeAction = pChangeTrack->GetActionMax() + 1;
470 		pChangeTrack->AppendContent( aPos, pOldCell );
471 		if ( nEndChangeAction > pChangeTrack->GetActionMax() )
472 			nEndChangeAction = 0;		// nichts appended
473 	}
474 	else
475 		nEndChangeAction = 0;
476 }
477 
478 void __EXPORT ScUndoPutCell::Undo()
479 {
480 	BeginUndo();
481 
482 	ScDocument* pDoc = pDocShell->GetDocument();
483     ScBaseCell* pNewCell = pOldCell ? pOldCell->CloneWithoutNote( *pDoc, aPos, SC_CLONECELL_STARTLISTENING ) : 0;
484 
485 	pDoc->PutCell( aPos.Col(), aPos.Row(), aPos.Tab(), pNewCell );
486 
487 	pDocShell->PostPaintCell( aPos );
488 
489 	ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
490 	if ( pChangeTrack )
491 		pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
492 
493 	EndUndo();
494 }
495 
496 void __EXPORT ScUndoPutCell::Redo()
497 {
498 	BeginRedo();
499 
500 	ScDocument* pDoc = pDocShell->GetDocument();
501     ScBaseCell* pNewCell = pEnteredCell ? pEnteredCell->CloneWithoutNote( *pDoc, aPos, SC_CLONECELL_STARTLISTENING ) : 0;
502 
503 	pDoc->PutCell( aPos.Col(), aPos.Row(), aPos.Tab(), pNewCell );
504 
505 	pDocShell->PostPaintCell( aPos );
506 
507 	SetChangeTrack();
508 
509 	EndRedo();
510 }
511 
512 void __EXPORT ScUndoPutCell::Repeat(SfxRepeatTarget& /* rTarget */)
513 {
514 	//	gippsnich
515 }
516 
517 sal_Bool __EXPORT ScUndoPutCell::CanRepeat(SfxRepeatTarget& /* rTarget */) const
518 {
519 	return sal_False;
520 }
521 
522 
523 // -----------------------------------------------------------------------
524 //
525 //		Seitenumbrueche
526 //
527 
528 ScUndoPageBreak::ScUndoPageBreak( ScDocShell* pNewDocShell,
529 			SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
530 			sal_Bool bNewColumn, sal_Bool bNewInsert ) :
531 	ScSimpleUndo( pNewDocShell ),
532 	nCol( nNewCol ),
533 	nRow( nNewRow ),
534 	nTab( nNewTab ),
535 	bColumn( bNewColumn ),
536 	bInsert( bNewInsert )
537 {
538 }
539 
540 __EXPORT ScUndoPageBreak::~ScUndoPageBreak()
541 {
542 }
543 
544 String __EXPORT ScUndoPageBreak::GetComment() const
545 {
546 	//"Spaltenumbruch" | "Zeilenumbruch"  "einfuegen" | "loeschen"
547 	return String ( bColumn ?
548 		( bInsert ?
549 			ScGlobal::GetRscString( STR_UNDO_INSCOLBREAK ) :
550 			ScGlobal::GetRscString( STR_UNDO_DELCOLBREAK )
551 		) :
552 		( bInsert ?
553 			ScGlobal::GetRscString( STR_UNDO_INSROWBREAK ) :
554 			ScGlobal::GetRscString( STR_UNDO_DELROWBREAK )
555 		) );
556 }
557 
558 void ScUndoPageBreak::DoChange( sal_Bool bInsertP ) const
559 {
560 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
561 
562 	if (pViewShell)
563 	{
564 		pViewShell->SetTabNo( nTab );
565 		pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, sal_False, sal_False );
566 
567         if (bInsertP)
568 			pViewShell->InsertPageBreak(bColumn, sal_False);
569 		else
570 			pViewShell->DeletePageBreak(bColumn, sal_False);
571 
572         pDocShell->GetDocument()->InvalidatePageBreaks(nTab);
573 	}
574 }
575 
576 void __EXPORT ScUndoPageBreak::Undo()
577 {
578 	BeginUndo();
579 	DoChange(!bInsert);
580 	EndUndo();
581 }
582 
583 void __EXPORT ScUndoPageBreak::Redo()
584 {
585 	BeginRedo();
586 	DoChange(bInsert);
587 	EndRedo();
588 }
589 
590 void __EXPORT ScUndoPageBreak::Repeat(SfxRepeatTarget& rTarget)
591 {
592 	if (rTarget.ISA(ScTabViewTarget))
593 	{
594 		ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
595 
596 		if (bInsert)
597 			rViewShell.InsertPageBreak(bColumn, sal_True);
598 		else
599 			rViewShell.DeletePageBreak(bColumn, sal_True);
600 	}
601 }
602 
603 sal_Bool __EXPORT ScUndoPageBreak::CanRepeat(SfxRepeatTarget& rTarget) const
604 {
605 	return (rTarget.ISA(ScTabViewTarget));
606 }
607 
608 // -----------------------------------------------------------------------
609 //
610 //		Druck-Skalierung
611 //
612 
613 ScUndoPrintZoom::ScUndoPrintZoom( ScDocShell* pNewDocShell,
614 			SCTAB nT, sal_uInt16 nOS, sal_uInt16 nOP, sal_uInt16 nNS, sal_uInt16 nNP ) :
615 	ScSimpleUndo( pNewDocShell ),
616 	nTab( nT ),
617 	nOldScale( nOS ),
618 	nOldPages( nOP ),
619 	nNewScale( nNS ),
620 	nNewPages( nNP )
621 {
622 }
623 
624 __EXPORT ScUndoPrintZoom::~ScUndoPrintZoom()
625 {
626 }
627 
628 String __EXPORT ScUndoPrintZoom::GetComment() const
629 {
630 	return ScGlobal::GetRscString( STR_UNDO_PRINTSCALE );
631 }
632 
633 void ScUndoPrintZoom::DoChange( sal_Bool bUndo )
634 {
635 	sal_uInt16 nScale = bUndo ? nOldScale : nNewScale;
636 	sal_uInt16 nPages = bUndo ? nOldPages : nNewPages;
637 
638 	ScDocument* pDoc = pDocShell->GetDocument();
639 	String aStyleName = pDoc->GetPageStyle( nTab );
640 	ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
641 	SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
642 	DBG_ASSERT( pStyleSheet, "PageStyle not found" );
643 	if ( pStyleSheet )
644 	{
645 		SfxItemSet& rSet = pStyleSheet->GetItemSet();
646 		rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, nScale ) );
647 		rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALETOPAGES, nPages ) );
648 
649 		ScPrintFunc aPrintFunc( pDocShell, pDocShell->GetPrinter(), nTab );
650 		aPrintFunc.UpdatePages();
651 	}
652 }
653 
654 void __EXPORT ScUndoPrintZoom::Undo()
655 {
656 	BeginUndo();
657 	DoChange(sal_True);
658 	EndUndo();
659 }
660 
661 void __EXPORT ScUndoPrintZoom::Redo()
662 {
663 	BeginRedo();
664 	DoChange(sal_False);
665 	EndRedo();
666 }
667 
668 void __EXPORT ScUndoPrintZoom::Repeat(SfxRepeatTarget& rTarget)
669 {
670 	if (rTarget.ISA(ScTabViewTarget))
671 	{
672 		ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
673 		ScViewData* pViewData = rViewShell.GetViewData();
674 		pViewData->GetDocShell()->SetPrintZoom( pViewData->GetTabNo(), nNewScale, nNewPages );
675 	}
676 }
677 
678 sal_Bool __EXPORT ScUndoPrintZoom::CanRepeat(SfxRepeatTarget& rTarget) const
679 {
680 	return (rTarget.ISA(ScTabViewTarget));
681 }
682 
683 
684 // -----------------------------------------------------------------------
685 //
686 //		Thesaurus
687 //
688 
689 ScUndoThesaurus::ScUndoThesaurus( ScDocShell* pNewDocShell,
690 								  SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
691 								  const String& rNewUndoStr, const EditTextObject* pUndoTObj,
692 								  const String& rNewRedoStr, const EditTextObject* pRedoTObj) :
693 	ScSimpleUndo( pNewDocShell ),
694 	nCol( nNewCol ),
695 	nRow( nNewRow ),
696 	nTab( nNewTab ),
697 	aUndoStr( rNewUndoStr ),
698 	aRedoStr( rNewRedoStr )
699 {
700 	pUndoTObject = (pUndoTObj) ? pUndoTObj->Clone() : NULL;
701 	pRedoTObject = (pRedoTObj) ? pRedoTObj->Clone() : NULL;
702 
703 	ScBaseCell* pOldCell;
704 	if ( pUndoTObject )
705 		pOldCell = new ScEditCell( pUndoTObject, pDocShell->GetDocument(), NULL );
706 	else
707 		pOldCell = new ScStringCell( aUndoStr );
708 	SetChangeTrack( pOldCell );
709 	pOldCell->Delete();
710 }
711 
712 __EXPORT ScUndoThesaurus::~ScUndoThesaurus()
713 {
714 	delete pUndoTObject;
715 	delete pRedoTObject;
716 }
717 
718 String __EXPORT ScUndoThesaurus::GetComment() const
719 {
720 	return ScGlobal::GetRscString( STR_UNDO_THESAURUS );	// "Thesaurus"
721 }
722 
723 void ScUndoThesaurus::SetChangeTrack( ScBaseCell* pOldCell )
724 {
725 	ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
726 	if ( pChangeTrack )
727 	{
728 		nEndChangeAction = pChangeTrack->GetActionMax() + 1;
729 		pChangeTrack->AppendContent( ScAddress( nCol, nRow, nTab ), pOldCell );
730 		if ( nEndChangeAction > pChangeTrack->GetActionMax() )
731 			nEndChangeAction = 0;		// nichts appended
732 	}
733 	else
734 		nEndChangeAction = 0;
735 }
736 
737 void __EXPORT ScUndoThesaurus::DoChange( sal_Bool bUndo, const String& rStr,
738 			const EditTextObject* pTObj )
739 {
740 	ScDocument* pDoc = pDocShell->GetDocument();
741 
742 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
743 	if (pViewShell)
744 	{
745 		pViewShell->SetTabNo( nTab );
746 		pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, sal_False, sal_False );
747 	}
748 
749 	if (pTObj)
750 	{
751 		ScBaseCell* pCell;
752 		pDoc->GetCell( nCol, nRow, nTab, pCell );
753 		if (pCell)
754 		{
755 			if (pCell->GetCellType() == CELLTYPE_EDIT )
756 			{
757 				ScEditCell* pNewCell = new ScEditCell( pTObj, pDoc, NULL );
758 				pDoc->PutCell( nCol, nRow, nTab, pNewCell );
759 				if ( !bUndo )
760 					SetChangeTrack( pCell );
761 			}
762 			else
763 			{
764 				DBG_ERROR("Nicht CELLTYPE_EDIT bei Un/RedoThesaurus");
765 			}
766 		}
767 	}
768 	else
769 	{
770         ScBaseCell* pCell = NULL;
771 		if ( !bUndo )
772 			pDoc->GetCell( nCol, nRow, nTab, pCell );
773 		pDoc->SetString( nCol, nRow, nTab, rStr );
774 		if ( !bUndo )
775 			SetChangeTrack( pCell );
776 	}
777 
778 	pDocShell->PostPaintCell( nCol, nRow, nTab );
779 }
780 
781 void __EXPORT ScUndoThesaurus::Undo()
782 {
783 	BeginUndo();
784 	DoChange( sal_True, aUndoStr, pUndoTObject );
785 	ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
786 	if ( pChangeTrack )
787 		pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
788 	EndUndo();
789 }
790 
791 void __EXPORT ScUndoThesaurus::Redo()
792 {
793 	BeginRedo();
794 	DoChange( sal_False, aRedoStr, pRedoTObject );
795 	EndRedo();
796 }
797 
798 void __EXPORT ScUndoThesaurus::Repeat(SfxRepeatTarget& rTarget)
799 {
800 	if (rTarget.ISA(ScTabViewTarget))
801 		((ScTabViewTarget&)rTarget).GetViewShell()->DoThesaurus( sal_True );
802 }
803 
804 sal_Bool __EXPORT ScUndoThesaurus::CanRepeat(SfxRepeatTarget& rTarget) const
805 {
806 	return (rTarget.ISA(ScTabViewTarget));
807 }
808 
809 
810 // ============================================================================
811 
812 ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell& rDocShell, const ScAddress& rPos,
813         const ScNoteData& rNoteData, bool bInsert, SdrUndoAction* pDrawUndo ) :
814     ScSimpleUndo( &rDocShell ),
815     maPos( rPos ),
816     mpDrawUndo( pDrawUndo )
817 {
818     DBG_ASSERT( rNoteData.mpCaption, "ScUndoReplaceNote::ScUndoReplaceNote - missing note caption" );
819     (bInsert ? maNewData : maOldData) = rNoteData;
820 }
821 
822 ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell& rDocShell, const ScAddress& rPos,
823         const ScNoteData& rOldData, const ScNoteData& rNewData, SdrUndoAction* pDrawUndo ) :
824     ScSimpleUndo( &rDocShell ),
825     maPos( rPos ),
826     maOldData( rOldData ),
827     maNewData( rNewData ),
828     mpDrawUndo( pDrawUndo )
829 {
830     DBG_ASSERT( maOldData.mpCaption || maNewData.mpCaption, "ScUndoReplaceNote::ScUndoReplaceNote - missing note captions" );
831     DBG_ASSERT( !maOldData.mxInitData.get() && !maNewData.mxInitData.get(), "ScUndoReplaceNote::ScUndoReplaceNote - unexpected unitialized note" );
832 }
833 
834 ScUndoReplaceNote::~ScUndoReplaceNote()
835 {
836     DeleteSdrUndoAction( mpDrawUndo );
837 }
838 
839 void ScUndoReplaceNote::Undo()
840 {
841 	BeginUndo();
842     DoSdrUndoAction( mpDrawUndo, pDocShell->GetDocument() );
843     /*  Undo insert -> remove new note.
844         Undo remove -> insert old note.
845         Undo replace -> remove new note, insert old note. */
846     DoRemoveNote( maNewData );
847     DoInsertNote( maOldData );
848     pDocShell->PostPaintCell( maPos );
849 	EndUndo();
850 }
851 
852 void ScUndoReplaceNote::Redo()
853 {
854 	BeginRedo();
855     RedoSdrUndoAction( mpDrawUndo );
856     /*  Redo insert -> insert new note.
857         Redo remove -> remove old note.
858         Redo replace -> remove old note, insert new note. */
859     DoRemoveNote( maOldData );
860     DoInsertNote( maNewData );
861     pDocShell->PostPaintCell( maPos );
862 	EndRedo();
863 }
864 
865 void ScUndoReplaceNote::Repeat( SfxRepeatTarget& /*rTarget*/ )
866 {
867 }
868 
869 sal_Bool ScUndoReplaceNote::CanRepeat( SfxRepeatTarget& /*rTarget*/ ) const
870 {
871 	return sal_False;
872 }
873 
874 String ScUndoReplaceNote::GetComment() const
875 {
876     return ScGlobal::GetRscString( maNewData.mpCaption ?
877         (maOldData.mpCaption ? STR_UNDO_EDITNOTE : STR_UNDO_INSERTNOTE) : STR_UNDO_DELETENOTE );
878 }
879 
880 void ScUndoReplaceNote::DoInsertNote( const ScNoteData& rNoteData )
881 {
882     if( rNoteData.mpCaption )
883     {
884         ScDocument& rDoc = *pDocShell->GetDocument();
885         DBG_ASSERT( !rDoc.GetNote( maPos ), "ScUndoReplaceNote::DoInsertNote - unexpected cell note" );
886         ScPostIt* pNote = new ScPostIt( rDoc, maPos, rNoteData, false );
887         rDoc.TakeNote( maPos, pNote );
888     }
889 }
890 
891 void ScUndoReplaceNote::DoRemoveNote( const ScNoteData& rNoteData )
892 {
893     if( rNoteData.mpCaption )
894     {
895         ScDocument& rDoc = *pDocShell->GetDocument();
896         DBG_ASSERT( rDoc.GetNote( maPos ), "ScUndoReplaceNote::DoRemoveNote - missing cell note" );
897         if( ScPostIt* pNote = rDoc.ReleaseNote( maPos ) )
898         {
899             /*  Forget pointer to caption object to suppress removing the
900                 caption object from the drawing layer while deleting pNote
901                 (removing the caption is done by a drawing undo action). */
902             pNote->ForgetCaption();
903             delete pNote;
904         }
905     }
906 }
907 
908 // ============================================================================
909 
910 ScUndoShowHideNote::ScUndoShowHideNote( ScDocShell& rDocShell, const ScAddress& rPos, bool bShow ) :
911 	ScSimpleUndo( &rDocShell ),
912 	maPos( rPos ),
913 	mbShown( bShow )
914 {
915 }
916 
917 ScUndoShowHideNote::~ScUndoShowHideNote()
918 {
919 }
920 
921 void ScUndoShowHideNote::Undo()
922 {
923 	BeginUndo();
924 	if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( maPos ) )
925         pNote->ShowCaption( maPos, !mbShown );
926 	EndUndo();
927 }
928 
929 void ScUndoShowHideNote::Redo()
930 {
931 	BeginRedo();
932 	if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( maPos ) )
933         pNote->ShowCaption( maPos, mbShown );
934 	EndRedo();
935 }
936 
937 void ScUndoShowHideNote::Repeat( SfxRepeatTarget& /*rTarget*/ )
938 {
939 }
940 
941 sal_Bool ScUndoShowHideNote::CanRepeat( SfxRepeatTarget& /*rTarget*/ ) const
942 {
943 	return sal_False;
944 }
945 
946 String ScUndoShowHideNote::GetComment() const
947 {
948     return ScGlobal::GetRscString( mbShown ? STR_UNDO_SHOWNOTE : STR_UNDO_HIDENOTE );
949 }
950 
951 // ============================================================================
952 
953 // -----------------------------------------------------------------------
954 //
955 //		Detektiv
956 //
957 
958 ScUndoDetective::ScUndoDetective( ScDocShell* pNewDocShell,
959 									SdrUndoAction* pDraw, const ScDetOpData* pOperation,
960 									ScDetOpList* pUndoList ) :
961 	ScSimpleUndo( pNewDocShell ),
962 	pOldList	( pUndoList ),
963 	nAction		( 0 ),
964 	pDrawUndo	( pDraw )
965 {
966 	bIsDelete = ( pOperation == NULL );
967 	if (!bIsDelete)
968 	{
969 		nAction = (sal_uInt16) pOperation->GetOperation();
970 		aPos = pOperation->GetPos();
971 	}
972 }
973 
974 __EXPORT ScUndoDetective::~ScUndoDetective()
975 {
976 	DeleteSdrUndoAction( pDrawUndo );
977 	delete pOldList;
978 }
979 
980 String __EXPORT ScUndoDetective::GetComment() const
981 {
982 	sal_uInt16 nId = STR_UNDO_DETDELALL;
983 	if ( !bIsDelete )
984 		switch ( (ScDetOpType) nAction )
985 		{
986 			case SCDETOP_ADDSUCC:	nId = STR_UNDO_DETADDSUCC;	break;
987 			case SCDETOP_DELSUCC:	nId = STR_UNDO_DETDELSUCC;	break;
988 			case SCDETOP_ADDPRED:	nId = STR_UNDO_DETADDPRED;	break;
989 			case SCDETOP_DELPRED:	nId = STR_UNDO_DETDELPRED;	break;
990 			case SCDETOP_ADDERROR:	nId = STR_UNDO_DETADDERROR;	break;
991 		}
992 
993 	return ScGlobal::GetRscString( nId );
994 }
995 
996 
997 void __EXPORT ScUndoDetective::Undo()
998 {
999 	BeginUndo();
1000 
1001 	ScDocument* pDoc = pDocShell->GetDocument();
1002     DoSdrUndoAction(pDrawUndo, pDoc);
1003 
1004 	if (bIsDelete)
1005 	{
1006 		if ( pOldList )
1007 			pDoc->SetDetOpList( new ScDetOpList(*pOldList) );
1008 	}
1009 	else
1010 	{
1011 		//	Eintrag aus der Liste loeschen
1012 
1013 		ScDetOpList* pList = pDoc->GetDetOpList();
1014 		if (pList && pList->Count())
1015 		{
1016 			sal_uInt16 nPos = pList->Count() - 1;
1017 			ScDetOpData* pData = (*pList)[nPos];
1018 			if ( pData->GetOperation() == (ScDetOpType) nAction && pData->GetPos() == aPos )
1019 				pList->DeleteAndDestroy( nPos, 1 );
1020 			else
1021 			{
1022 				DBG_ERROR("Detektiv-Eintrag in der Liste nicht gefunden");
1023 			}
1024 		}
1025 	}
1026 
1027 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1028 	if (pViewShell)
1029 		pViewShell->RecalcPPT();	//! use broadcast instead?
1030 
1031 	EndUndo();
1032 }
1033 
1034 void __EXPORT ScUndoDetective::Redo()
1035 {
1036 	BeginRedo();
1037 
1038     RedoSdrUndoAction(pDrawUndo);
1039 
1040 	ScDocument* pDoc = pDocShell->GetDocument();
1041 
1042 	if (bIsDelete)
1043 		pDoc->ClearDetectiveOperations();
1044 	else
1045 		pDoc->AddDetectiveOperation( ScDetOpData( aPos, (ScDetOpType) nAction ) );
1046 
1047 	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
1048 	if (pViewShell)
1049 		pViewShell->RecalcPPT();	//! use broadcast instead?
1050 
1051 	EndRedo();
1052 }
1053 
1054 void __EXPORT ScUndoDetective::Repeat(SfxRepeatTarget& /* rTarget */)
1055 {
1056 	//	hammanich
1057 }
1058 
1059 sal_Bool __EXPORT ScUndoDetective::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1060 {
1061 	return sal_False;
1062 }
1063 
1064 // -----------------------------------------------------------------------
1065 //
1066 //		Benannte Bereiche
1067 //
1068 
1069 ScUndoRangeNames::ScUndoRangeNames( ScDocShell* pNewDocShell,
1070 									ScRangeName* pOld, ScRangeName* pNew ) :
1071 	ScSimpleUndo( pNewDocShell ),
1072 	pOldRanges	( pOld ),
1073 	pNewRanges	( pNew )
1074 {
1075 }
1076 
1077 __EXPORT ScUndoRangeNames::~ScUndoRangeNames()
1078 {
1079 	delete pOldRanges;
1080 	delete pNewRanges;
1081 }
1082 
1083 String __EXPORT ScUndoRangeNames::GetComment() const
1084 {
1085 	return ScGlobal::GetRscString( STR_UNDO_RANGENAMES );
1086 }
1087 
1088 void ScUndoRangeNames::DoChange( sal_Bool bUndo )
1089 {
1090 	ScDocument* pDoc = pDocShell->GetDocument();
1091 	pDoc->CompileNameFormula( sal_True );	// CreateFormulaString
1092 
1093 	if ( bUndo )
1094 		pDoc->SetRangeName( new ScRangeName( *pOldRanges ) );
1095 	else
1096 		pDoc->SetRangeName( new ScRangeName( *pNewRanges ) );
1097 
1098 	pDoc->CompileNameFormula( sal_False );	// CompileFormulaString
1099 
1100 	SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
1101 }
1102 
1103 void __EXPORT ScUndoRangeNames::Undo()
1104 {
1105 	BeginUndo();
1106 	DoChange( sal_True );
1107 	EndUndo();
1108 }
1109 
1110 void __EXPORT ScUndoRangeNames::Redo()
1111 {
1112 	BeginRedo();
1113 	DoChange( sal_False );
1114 	EndRedo();
1115 }
1116 
1117 void __EXPORT ScUndoRangeNames::Repeat(SfxRepeatTarget& /* rTarget */)
1118 {
1119 	//	hammanich
1120 }
1121 
1122 sal_Bool __EXPORT ScUndoRangeNames::CanRepeat(SfxRepeatTarget& /* rTarget */) const
1123 {
1124 	return sal_False;
1125 }
1126 
1127 
1128 
1129 
1130