update credits
[LibreOffice.git] / vcl / source / edit / textundo.cxx
blob51b3826da802069c3799870002afe02d6d576dac
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 );
40 namespace
43 // Shorten() -- inserts ellipsis (...) in the middle of a long text
44 void Shorten (OUString& rString)
46 unsigned nLen = rString.getLength();
47 if (nLen > 48)
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
58 // finally:
59 rString =
60 rString.copy(0, iFirst + 1) +
61 "..." +
62 rString.copy(iLast);
66 } // namespace
69 TextUndoManager::TextUndoManager( TextEngine* p )
71 mpTextEngine = p;
74 TextUndoManager::~TextUndoManager()
78 sal_Bool TextUndoManager::Undo()
80 if ( GetUndoActionCount() == 0 )
81 return sal_False;
83 UndoRedoStart();
85 mpTextEngine->SetIsInUndo( sal_True );
86 sal_Bool bDone = SfxUndoManager::Undo();
87 mpTextEngine->SetIsInUndo( sal_False );
89 UndoRedoEnd();
91 return bDone;
94 sal_Bool TextUndoManager::Redo()
96 if ( GetRedoActionCount() == 0 )
97 return sal_False;
100 UndoRedoStart();
102 mpTextEngine->SetIsInUndo( sal_True );
103 sal_Bool bDone = SfxUndoManager::Redo();
104 mpTextEngine->SetIsInUndo( sal_False );
106 UndoRedoEnd();
108 return bDone;
111 void TextUndoManager::UndoRedoStart()
113 DBG_ASSERT( GetView(), "Undo/Redo: Active View?" );
116 void TextUndoManager::UndoRedoEnd()
118 if ( GetView() )
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 )
132 mpTextEngine = p;
135 TextUndo::~TextUndo()
139 OUString TextUndo::GetComment() const
141 return OUString();
144 void TextUndo::SetSelection( const TextSelection& rSel )
146 if ( GetView() )
147 GetView()->ImpSetSelection( rSel );
150 TextUndoDelPara::TextUndoDelPara( TextEngine* pTextEngine, TextNode* pNode, sal_uLong nPara )
151 : TextUndo( pTextEngine )
153 mpNode = pNode;
154 mnPara = nPara;
155 mbDelObject = sal_True;
158 TextUndoDelPara::~TextUndoDelPara()
160 if ( mbDelObject )
161 delete mpNode;
164 void TextUndoDelPara::Undo()
166 GetTextEngine()->InsertContent( mpNode, mnPara );
167 mbDelObject = sal_False; // belongs again to the engine
169 if ( GetView() )
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 )
205 mnPara = nPara;
206 mnSepPos = nPos;
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 )
233 mnPara = nPara;
234 mnSepPos = nPos;
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 ) )
284 return sal_False;
286 TextUndoInsertChars* pNext = (TextUndoInsertChars*)pNextAction;
288 if ( maTextPaM.GetPara() != pNext->maTextPaM.GetPara() )
289 return sal_False;
291 if ( ( maTextPaM.GetIndex() + maText.Len() ) == pNext->maTextPaM.GetIndex() )
293 maText += pNext->maText;
294 return sal_True;
296 return sal_False;
299 OUString TextUndoInsertChars::GetComment () const
301 // multiple lines?
302 OUString sText(maText);
303 Shorten(sText);
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
331 // multiple lines?
332 OUString sText(maText);
333 Shorten(sText);
334 return OUString(ResId(STR_TEXTUNDO_REMOVECHARS, *ImplGetResMgr())).replaceAll("$1", sText);
337 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */