xref: /aoo41x/main/svtools/source/edit/textundo.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_svtools.hxx"
30 
31 #include <svtools/texteng.hxx>
32 #include <svtools/textview.hxx>
33 #include <textundo.hxx>
34 #include <textund2.hxx>
35 #include <svtools/textdata.hxx>
36 #include <textdoc.hxx>
37 #include <textdat2.hxx>
38 
39 TYPEINIT1( TextUndo, SfxUndoAction );
40 TYPEINIT1( TextUndoDelPara, TextUndo );
41 TYPEINIT1( TextUndoConnectParas, TextUndo );
42 TYPEINIT1( TextUndoSplitPara, TextUndo );
43 TYPEINIT1( TextUndoInsertChars, TextUndo );
44 TYPEINIT1( TextUndoRemoveChars, TextUndo );
45 TYPEINIT1( TextUndoSetAttribs, TextUndo );
46 
47 
48 TextUndoManager::TextUndoManager( TextEngine* p )
49 {
50 	mpTextEngine = p;
51 }
52 
53 TextUndoManager::~TextUndoManager()
54 {
55 }
56 
57 sal_Bool __EXPORT TextUndoManager::Undo()
58 {
59 	if ( GetUndoActionCount() == 0 )
60 		return sal_False;
61 
62 	UndoRedoStart();
63 
64 	mpTextEngine->SetIsInUndo( sal_True );
65     sal_Bool bDone = SfxUndoManager::Undo();
66 	mpTextEngine->SetIsInUndo( sal_False );
67 
68 	UndoRedoEnd();
69 
70 	return bDone;
71 }
72 
73 sal_Bool __EXPORT TextUndoManager::Redo()
74 {
75 	if ( GetRedoActionCount() == 0 )
76 		return sal_False;
77 
78 
79 	UndoRedoStart();
80 
81 	mpTextEngine->SetIsInUndo( sal_True );
82     sal_Bool bDone = SfxUndoManager::Redo();
83 	mpTextEngine->SetIsInUndo( sal_False );
84 
85 	UndoRedoEnd();
86 
87 	return bDone;
88 }
89 
90 void TextUndoManager::UndoRedoStart()
91 {
92 	DBG_ASSERT( GetView(), "Undo/Redo: Active View?" );
93 
94 //	if ( GetView() )
95 //		GetView()->HideSelection();
96 }
97 
98 void TextUndoManager::UndoRedoEnd()
99 {
100 	if ( GetView() )
101 	{
102 		TextSelection aNewSel( GetView()->GetSelection() );
103 		aNewSel.GetStart() = aNewSel.GetEnd();
104 		GetView()->ImpSetSelection( aNewSel );
105 	}
106 
107 	mpTextEngine->UpdateSelections();
108 
109 	mpTextEngine->FormatAndUpdate( GetView() );
110 }
111 
112 
113 TextUndo::TextUndo( TextEngine* p )
114 {
115 	mpTextEngine = p;
116 }
117 
118 TextUndo::~TextUndo()
119 {
120 }
121 
122 XubString __EXPORT TextUndo::GetComment() const
123 {
124 //	return mpTextEngine->GetUndoComment( this );
125 	return String();
126 }
127 
128 void TextUndo::SetSelection( const TextSelection& rSel )
129 {
130 	if ( GetView() )
131 		GetView()->ImpSetSelection( rSel );
132 }
133 
134 
135 TextUndoDelPara::TextUndoDelPara( TextEngine* pTextEngine, TextNode* pNode, sal_uLong nPara )
136 					: TextUndo( pTextEngine )
137 {
138 	mpNode = pNode;
139 	mnPara = nPara;
140 	mbDelObject = sal_True;
141 }
142 
143 TextUndoDelPara::~TextUndoDelPara()
144 {
145 	if ( mbDelObject )
146 		delete mpNode;
147 }
148 
149 void __EXPORT TextUndoDelPara::Undo()
150 {
151 	GetTextEngine()->InsertContent( mpNode, mnPara );
152 	mbDelObject = sal_False;	// gehoert wieder der Engine
153 
154 	if ( GetView() )
155 	{
156 		TextSelection aSel( TextPaM( mnPara, 0 ), TextPaM( mnPara, mpNode->GetText().Len() ) );
157 		SetSelection( aSel );
158 	}
159 }
160 
161 void __EXPORT TextUndoDelPara::Redo()
162 {
163 	// pNode stimmt nicht mehr, falls zwischendurch Undos, in denen
164 	// Absaetze verschmolzen sind.
165 	mpNode = GetDoc()->GetNodes().GetObject( mnPara );
166 
167 	delete GetTEParaPortions()->GetObject( mnPara );
168 	GetTEParaPortions()->Remove( mnPara );
169 
170 	// Node nicht loeschen, haengt im Undo!
171 	GetDoc()->GetNodes().Remove( mnPara );
172 	GetTextEngine()->ImpParagraphRemoved( mnPara );
173 
174 	mbDelObject = sal_True;	// gehoert wieder dem Undo
175 
176 	sal_uLong nParas = GetDoc()->GetNodes().Count();
177 	sal_uLong n = mnPara < nParas ? mnPara : (nParas-1);
178 	TextNode* pN = GetDoc()->GetNodes().GetObject( n );
179 	TextPaM aPaM( n, pN->GetText().Len() );
180 	SetSelection( aPaM );
181 }
182 
183 // -----------------------------------------------------------------------
184 // TextUndoConnectParas
185 // ------------------------------------------------------------------------
186 TextUndoConnectParas::TextUndoConnectParas( TextEngine* pTextEngine, sal_uLong nPara, sal_uInt16 nPos )
187 					: 	TextUndo( pTextEngine )
188 {
189 	mnPara = nPara;
190 	mnSepPos = nPos;
191 }
192 
193 TextUndoConnectParas::~TextUndoConnectParas()
194 {
195 }
196 
197 void __EXPORT TextUndoConnectParas::Undo()
198 {
199 	TextPaM aPaM = GetTextEngine()->SplitContent( mnPara, mnSepPos );
200 	SetSelection( aPaM );
201 }
202 
203 void __EXPORT TextUndoConnectParas::Redo()
204 {
205 	TextPaM aPaM = GetTextEngine()->ConnectContents( mnPara );
206 	SetSelection( aPaM );
207 }
208 
209 
210 TextUndoSplitPara::TextUndoSplitPara( TextEngine* pTextEngine, sal_uLong nPara, sal_uInt16 nPos )
211 					: TextUndo( pTextEngine )
212 {
213 	mnPara = nPara;
214 	mnSepPos = nPos;
215 }
216 
217 TextUndoSplitPara::~TextUndoSplitPara()
218 {
219 }
220 
221 void __EXPORT TextUndoSplitPara::Undo()
222 {
223 	TextPaM aPaM = GetTextEngine()->ConnectContents( mnPara );
224 	SetSelection( aPaM );
225 }
226 
227 void __EXPORT TextUndoSplitPara::Redo()
228 {
229 	TextPaM aPaM = GetTextEngine()->SplitContent( mnPara, mnSepPos );
230 	SetSelection( aPaM );
231 }
232 
233 
234 TextUndoInsertChars::TextUndoInsertChars( TextEngine* pTextEngine, const TextPaM& rTextPaM, const XubString& rStr )
235 					: TextUndo( pTextEngine ),
236 						maTextPaM( rTextPaM ), maText( rStr )
237 {
238 }
239 
240 void __EXPORT TextUndoInsertChars::Undo()
241 {
242 	TextSelection aSel( maTextPaM, maTextPaM );
243 	aSel.GetEnd().GetIndex() = aSel.GetEnd().GetIndex() + maText.Len();
244 	TextPaM aPaM = GetTextEngine()->ImpDeleteText( aSel );
245 	SetSelection( aPaM );
246 }
247 
248 void __EXPORT TextUndoInsertChars::Redo()
249 {
250 	TextSelection aSel( maTextPaM, maTextPaM );
251 	GetTextEngine()->ImpInsertText( aSel, maText );
252 	TextPaM aNewPaM( maTextPaM );
253 	aNewPaM.GetIndex() = aNewPaM.GetIndex() + maText.Len();
254 	SetSelection( TextSelection( aSel.GetStart(), aNewPaM ) );
255 }
256 
257 sal_Bool __EXPORT TextUndoInsertChars::Merge( SfxUndoAction* pNextAction )
258 {
259 	if ( !pNextAction->ISA( TextUndoInsertChars ) )
260 		return sal_False;
261 
262 	TextUndoInsertChars* pNext = (TextUndoInsertChars*)pNextAction;
263 
264 	if ( maTextPaM.GetPara() != pNext->maTextPaM.GetPara() )
265 		return sal_False;
266 
267 	if ( ( maTextPaM.GetIndex() + maText.Len() ) == pNext->maTextPaM.GetIndex() )
268 	{
269 		maText += pNext->maText;
270 		return sal_True;
271 	}
272 	return sal_False;
273 }
274 
275 
276 TextUndoRemoveChars::TextUndoRemoveChars( TextEngine* pTextEngine, const TextPaM& rTextPaM, const XubString& rStr )
277 					: TextUndo( pTextEngine ),
278 						maTextPaM( rTextPaM ), maText( rStr )
279 {
280 }
281 
282 void __EXPORT TextUndoRemoveChars::Undo()
283 {
284 	TextSelection aSel( maTextPaM, maTextPaM );
285 	GetTextEngine()->ImpInsertText( aSel, maText );
286 	aSel.GetEnd().GetIndex() = aSel.GetEnd().GetIndex() + maText.Len();
287 	SetSelection( aSel );
288 }
289 
290 void __EXPORT TextUndoRemoveChars::Redo()
291 {
292 	TextSelection aSel( maTextPaM, maTextPaM );
293 	aSel.GetEnd().GetIndex() = aSel.GetEnd().GetIndex() + maText.Len();
294 	TextPaM aPaM = GetTextEngine()->ImpDeleteText( aSel );
295 	SetSelection( aPaM );
296 }
297 
298 
299 TextUndoSetAttribs::TextUndoSetAttribs( TextEngine* pTextEngine, const TextSelection& rSel )
300 	: TextUndo( pTextEngine ), maSelection( rSel )
301 {
302 	maSelection.Justify();
303 // 	aNewAttribs.Set( rNewItems );
304 //	mbSetIsRemove = sal_False;
305 //	mnRemoveWhich = 0;
306 //	mnSpecial = 0;
307 }
308 
309 TextUndoSetAttribs::~TextUndoSetAttribs()
310 {
311 	// ...............
312 }
313 
314 void __EXPORT TextUndoSetAttribs::Undo()
315 {
316 	for ( sal_uLong nPara = maSelection.GetStart().GetPara(); nPara <= maSelection.GetEnd().GetPara(); nPara++ )
317 	{
318 //		ContentAttribsInfo* pInf = aPrevAttribs[ (sal_uInt16)(nPara-aESel.nStartPara) ];
319 //		GetTextEngine()->RemoveCharAttribs( nPara );
320 //		TextNode* pNode = GetTextEngine()->GetTextDoc().GetObject( nPara );
321 //		for ( sal_uInt16 nAttr = 0; nAttr < pInf->GetPrevCharAttribs().Count(); nAttr++ )
322 //		{
323 //			GetTextEngine()->GetTextDoc().InsertAttrib( pNode, pX->GetStart(), pX->GetEnd(), *pX->GetItem() );
324 //		}
325 	}
326 	SetSelection( maSelection );
327 }
328 
329 void __EXPORT TextUndoSetAttribs::Redo()
330 {
331 //	if ( !bSetIsRemove )
332 //		GetTextEngine()->SetAttribs( aSel, aNewAttribs, nSpecial );
333 //	else
334 //		GetTextEngine()->RemoveCharAttribs( aSel, bRemoveParaAttribs, nRemoveWhich );
335 	SetSelection( maSelection );
336 }
337