1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "textundo.hxx"
21 #include "textund2.hxx"
22 #include "textundo.hrc"
24 #include <vcl/texteng.hxx>
25 #include <vcl/textview.hxx>
26 #include <vcl/textdata.hxx>
27 #include <textdoc.hxx>
28 #include <textdat2.hxx>
29 #include <svdata.hxx> // ImplGetResMgr()
30 #include <tools/resid.hxx>
32 TYPEINIT1( TextUndo
, SfxUndoAction
);
33 TYPEINIT1( TextUndoDelPara
, TextUndo
);
34 TYPEINIT1( TextUndoConnectParas
, TextUndo
);
35 TYPEINIT1( TextUndoSplitPara
, TextUndo
);
36 TYPEINIT1( TextUndoInsertChars
, TextUndo
);
37 TYPEINIT1( TextUndoRemoveChars
, TextUndo
);
43 // Shorten() -- inserts ellipsis (...) in the middle of a long text
44 void Shorten (OUString
& rString
)
46 unsigned nLen
= rString
.getLength();
49 // If possible, we don't break a word, hence first we look for a space.
50 // Space before the ellipsis:
51 int iFirst
= rString
.lastIndexOf(' ', 32);
52 if (iFirst
== -1 || unsigned(iFirst
) < 16)
53 iFirst
= 24; // not possible
54 // Space after the ellipsis:
55 int iLast
= rString
.indexOf(' ', nLen
- 16);
56 if (iLast
== -1 || unsigned(iLast
) > nLen
- 4)
57 iLast
= nLen
- 8; // not possible
60 rString
.copy(0, iFirst
+ 1) +
69 TextUndoManager::TextUndoManager( TextEngine
* p
)
74 TextUndoManager::~TextUndoManager()
78 sal_Bool
TextUndoManager::Undo()
80 if ( GetUndoActionCount() == 0 )
85 mpTextEngine
->SetIsInUndo( sal_True
);
86 sal_Bool bDone
= SfxUndoManager::Undo();
87 mpTextEngine
->SetIsInUndo( sal_False
);
94 sal_Bool
TextUndoManager::Redo()
96 if ( GetRedoActionCount() == 0 )
102 mpTextEngine
->SetIsInUndo( sal_True
);
103 sal_Bool bDone
= SfxUndoManager::Redo();
104 mpTextEngine
->SetIsInUndo( sal_False
);
111 void TextUndoManager::UndoRedoStart()
113 DBG_ASSERT( GetView(), "Undo/Redo: Active View?" );
116 void TextUndoManager::UndoRedoEnd()
120 TextSelection
aNewSel( GetView()->GetSelection() );
121 aNewSel
.GetStart() = aNewSel
.GetEnd();
122 GetView()->ImpSetSelection( aNewSel
);
125 mpTextEngine
->UpdateSelections();
127 mpTextEngine
->FormatAndUpdate( GetView() );
130 TextUndo::TextUndo( TextEngine
* p
)
135 TextUndo::~TextUndo()
139 OUString
TextUndo::GetComment() const
144 void TextUndo::SetSelection( const TextSelection
& rSel
)
147 GetView()->ImpSetSelection( rSel
);
150 TextUndoDelPara::TextUndoDelPara( TextEngine
* pTextEngine
, TextNode
* pNode
, sal_uLong nPara
)
151 : TextUndo( pTextEngine
)
155 mbDelObject
= sal_True
;
158 TextUndoDelPara::~TextUndoDelPara()
164 void TextUndoDelPara::Undo()
166 GetTextEngine()->InsertContent( mpNode
, mnPara
);
167 mbDelObject
= sal_False
; // belongs again to the engine
171 TextSelection
aSel( TextPaM( mnPara
, 0 ), TextPaM( mnPara
, mpNode
->GetText().Len() ) );
172 SetSelection( aSel
);
176 void TextUndoDelPara::Redo()
178 // pNode is not valid anymore in case an Undo joined paragraphs
179 mpNode
= GetDoc()->GetNodes().GetObject( mnPara
);
181 delete GetTEParaPortions()->GetObject( mnPara
);
182 GetTEParaPortions()->Remove( mnPara
);
184 // do not delete Node because of Undo!
185 GetDoc()->GetNodes().Remove( mnPara
);
186 GetTextEngine()->ImpParagraphRemoved( mnPara
);
188 mbDelObject
= sal_True
; // belongs again to the Undo
190 sal_uLong nParas
= GetDoc()->GetNodes().Count();
191 sal_uLong n
= mnPara
< nParas
? mnPara
: (nParas
-1);
192 TextNode
* pN
= GetDoc()->GetNodes().GetObject( n
);
193 TextPaM
aPaM( n
, pN
->GetText().Len() );
194 SetSelection( aPaM
);
197 OUString
TextUndoDelPara::GetComment () const
199 return ResId(STR_TEXTUNDO_DELPARA
, *ImplGetResMgr());
202 TextUndoConnectParas::TextUndoConnectParas( TextEngine
* pTextEngine
, sal_uLong nPara
, sal_uInt16 nPos
)
203 : TextUndo( pTextEngine
)
209 TextUndoConnectParas::~TextUndoConnectParas()
213 void TextUndoConnectParas::Undo()
215 TextPaM aPaM
= GetTextEngine()->SplitContent( mnPara
, mnSepPos
);
216 SetSelection( aPaM
);
219 void TextUndoConnectParas::Redo()
221 TextPaM aPaM
= GetTextEngine()->ConnectContents( mnPara
);
222 SetSelection( aPaM
);
225 OUString
TextUndoConnectParas::GetComment () const
227 return ResId(STR_TEXTUNDO_CONNECTPARAS
, *ImplGetResMgr());
230 TextUndoSplitPara::TextUndoSplitPara( TextEngine
* pTextEngine
, sal_uLong nPara
, sal_uInt16 nPos
)
231 : TextUndo( pTextEngine
)
237 TextUndoSplitPara::~TextUndoSplitPara()
241 void TextUndoSplitPara::Undo()
243 TextPaM aPaM
= GetTextEngine()->ConnectContents( mnPara
);
244 SetSelection( aPaM
);
247 void TextUndoSplitPara::Redo()
249 TextPaM aPaM
= GetTextEngine()->SplitContent( mnPara
, mnSepPos
);
250 SetSelection( aPaM
);
253 OUString
TextUndoSplitPara::GetComment () const
255 return ResId(STR_TEXTUNDO_SPLITPARA
, *ImplGetResMgr());
258 TextUndoInsertChars::TextUndoInsertChars( TextEngine
* pTextEngine
, const TextPaM
& rTextPaM
, const XubString
& rStr
)
259 : TextUndo( pTextEngine
),
260 maTextPaM( rTextPaM
), maText( rStr
)
264 void TextUndoInsertChars::Undo()
266 TextSelection
aSel( maTextPaM
, maTextPaM
);
267 aSel
.GetEnd().GetIndex() = aSel
.GetEnd().GetIndex() + maText
.Len();
268 TextPaM aPaM
= GetTextEngine()->ImpDeleteText( aSel
);
269 SetSelection( aPaM
);
272 void TextUndoInsertChars::Redo()
274 TextSelection
aSel( maTextPaM
, maTextPaM
);
275 GetTextEngine()->ImpInsertText( aSel
, maText
);
276 TextPaM
aNewPaM( maTextPaM
);
277 aNewPaM
.GetIndex() = aNewPaM
.GetIndex() + maText
.Len();
278 SetSelection( TextSelection( aSel
.GetStart(), aNewPaM
) );
281 sal_Bool
TextUndoInsertChars::Merge( SfxUndoAction
* pNextAction
)
283 if ( !pNextAction
->ISA( TextUndoInsertChars
) )
286 TextUndoInsertChars
* pNext
= (TextUndoInsertChars
*)pNextAction
;
288 if ( maTextPaM
.GetPara() != pNext
->maTextPaM
.GetPara() )
291 if ( ( maTextPaM
.GetIndex() + maText
.Len() ) == pNext
->maTextPaM
.GetIndex() )
293 maText
+= pNext
->maText
;
299 OUString
TextUndoInsertChars::GetComment () const
302 OUString
sText(maText
);
304 return OUString(ResId(STR_TEXTUNDO_INSERTCHARS
, *ImplGetResMgr())).replaceAll("$1", sText
);
307 TextUndoRemoveChars::TextUndoRemoveChars( TextEngine
* pTextEngine
, const TextPaM
& rTextPaM
, const XubString
& rStr
)
308 : TextUndo( pTextEngine
),
309 maTextPaM( rTextPaM
), maText( rStr
)
313 void TextUndoRemoveChars::Undo()
315 TextSelection
aSel( maTextPaM
, maTextPaM
);
316 GetTextEngine()->ImpInsertText( aSel
, maText
);
317 aSel
.GetEnd().GetIndex() = aSel
.GetEnd().GetIndex() + maText
.Len();
318 SetSelection( aSel
);
321 void TextUndoRemoveChars::Redo()
323 TextSelection
aSel( maTextPaM
, maTextPaM
);
324 aSel
.GetEnd().GetIndex() = aSel
.GetEnd().GetIndex() + maText
.Len();
325 TextPaM aPaM
= GetTextEngine()->ImpDeleteText( aSel
);
326 SetSelection( aPaM
);
329 OUString
TextUndoRemoveChars::GetComment () const
332 OUString
sText(maText
);
334 return OUString(ResId(STR_TEXTUNDO_REMOVECHARS
, *ImplGetResMgr())).replaceAll("$1", sText
);
337 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */