LibreOffice Module vcl (master)  1
textundo.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include "textundo.hxx"
21 #include "textund2.hxx"
22 #include <strings.hrc>
23 
24 #include <sal/log.hxx>
25 #include <vcl/texteng.hxx>
26 #include <vcl/textview.hxx>
27 #include <vcl/textdata.hxx>
28 #include "textdoc.hxx"
29 #include "textdat2.hxx"
30 #include <svdata.hxx>
31 
32 namespace
33 {
34 
35 // Shorten() -- inserts ellipsis (...) in the middle of a long text
36 void Shorten (OUString& rString)
37 {
38  unsigned nLen = rString.getLength();
39  if (nLen > 48)
40  {
41  // If possible, we don't break a word, hence first we look for a space.
42  // Space before the ellipsis:
43  int iFirst = rString.lastIndexOf(' ', 32);
44  if (iFirst == -1 || unsigned(iFirst) < 16)
45  iFirst = 24; // not possible
46  // Space after the ellipsis:
47  int iLast = rString.indexOf(' ', nLen - 16);
48  if (iLast == -1 || unsigned(iLast) > nLen - 4)
49  iLast = nLen - 8; // not possible
50  // finally:
51  rString =
52  rString.copy(0, iFirst + 1) +
53  "..." +
54  rString.copy(iLast);
55  }
56 }
57 
58 } // namespace
59 
61 {
62  mpTextEngine = p;
63 }
64 
66 {
67 }
68 
70 {
71  if ( GetUndoActionCount() == 0 )
72  return false;
73 
74  UndoRedoStart();
75 
76  mpTextEngine->SetIsInUndo( true );
77  bool bDone = SfxUndoManager::Undo();
78  mpTextEngine->SetIsInUndo( false );
79 
80  UndoRedoEnd();
81 
82  return bDone;
83 }
84 
86 {
87  if ( GetRedoActionCount() == 0 )
88  return false;
89 
90  UndoRedoStart();
91 
92  mpTextEngine->SetIsInUndo( true );
93  bool bDone = SfxUndoManager::Redo();
94  mpTextEngine->SetIsInUndo( false );
95 
96  UndoRedoEnd();
97 
98  return bDone;
99 }
100 
102 {
103  SAL_WARN_IF( !GetView(), "vcl", "Undo/Redo: Active View?" );
104 }
105 
107 {
108  if ( GetView() )
109  {
110  TextSelection aNewSel( GetView()->GetSelection() );
111  aNewSel.GetStart() = aNewSel.GetEnd();
112  GetView()->ImpSetSelection( aNewSel );
113  }
114 
116 }
117 
119 {
120  mpTextEngine = p;
121 }
122 
124 {
125 }
126 
127 OUString TextUndo::GetComment() const
128 {
129  return OUString();
130 }
131 
133 {
134  if ( GetView() )
135  GetView()->ImpSetSelection( rSel );
136 }
137 
138 TextUndoDelPara::TextUndoDelPara( TextEngine* pTextEngine, TextNode* pNode, sal_uInt32 nPara )
139  : TextUndo( pTextEngine )
140  , mbDelObject( true)
141  , mnPara( nPara )
142  , mpNode( pNode )
143 {
144 }
145 
147 {
148  if ( mbDelObject )
149  delete mpNode;
150 }
151 
153 {
154  GetTextEngine()->InsertContent( std::unique_ptr<TextNode>(mpNode), mnPara );
155  mbDelObject = false; // belongs again to the engine
156 
157  if ( GetView() )
158  {
159  TextSelection aSel( TextPaM( mnPara, 0 ), TextPaM( mnPara, mpNode->GetText().getLength() ) );
160  SetSelection( aSel );
161  }
162 }
163 
165 {
166  auto & rDocNodes = GetDoc()->GetNodes();
167  // pNode is not valid anymore in case an Undo joined paragraphs
168  mpNode = rDocNodes[ mnPara ].get();
169 
171 
172  // do not delete Node because of Undo!
173  auto it = ::std::find_if( rDocNodes.begin(), rDocNodes.end(),
174  [&] (std::unique_ptr<TextNode> const & p) { return p.get() == mpNode; } );
175  assert(it != rDocNodes.end());
176  it->release();
177  GetDoc()->GetNodes().erase( it );
178 
180 
181  mbDelObject = true; // belongs again to the Undo
182 
183  const sal_uInt32 nParas = static_cast<sal_uInt32>(GetDoc()->GetNodes().size());
184  const sal_uInt32 n = mnPara < nParas ? mnPara : nParas-1;
185  TextNode* pN = GetDoc()->GetNodes()[ n ].get();
186  TextPaM aPaM( n, pN->GetText().getLength() );
187  SetSelection( aPaM );
188 }
189 
191 {
192  return VclResId(STR_TEXTUNDO_DELPARA);
193 }
194 
195 TextUndoConnectParas::TextUndoConnectParas( TextEngine* pTextEngine, sal_uInt32 nPara, sal_Int32 nPos )
196  : TextUndo( pTextEngine )
197  , mnPara( nPara )
198  , mnSepPos( nPos )
199 {
200 }
201 
203 {
204 }
205 
207 {
209  SetSelection( aPaM );
210 }
211 
213 {
215  SetSelection( aPaM );
216 }
217 
219 {
220  return VclResId(STR_TEXTUNDO_CONNECTPARAS);
221 }
222 
223 TextUndoSplitPara::TextUndoSplitPara( TextEngine* pTextEngine, sal_uInt32 nPara, sal_Int32 nPos )
224  : TextUndo( pTextEngine )
225  , mnPara( nPara )
226  , mnSepPos ( nPos )
227 {
228 }
229 
231 {
232 }
233 
235 {
237  SetSelection( aPaM );
238 }
239 
241 {
243  SetSelection( aPaM );
244 }
245 
247 {
248  return VclResId(STR_TEXTUNDO_SPLITPARA);
249 }
250 
251 TextUndoInsertChars::TextUndoInsertChars( TextEngine* pTextEngine, const TextPaM& rTextPaM, const OUString& rStr )
252  : TextUndo( pTextEngine ),
253  maTextPaM( rTextPaM ), maText( rStr )
254 {
255 }
256 
258 {
260  aSel.GetEnd().GetIndex() += maText.getLength();
261  TextPaM aPaM = GetTextEngine()->ImpDeleteText( aSel );
262  SetSelection( aPaM );
263 }
264 
266 {
268  GetTextEngine()->ImpInsertText( aSel, maText );
269  TextPaM aNewPaM( maTextPaM );
270  aNewPaM.GetIndex() += maText.getLength();
271  SetSelection( TextSelection( aSel.GetStart(), aNewPaM ) );
272 }
273 
275 {
276  if ( nullptr == dynamic_cast< const TextUndoInsertChars*>( pNextAction ) )
277  return false;
278 
279  TextUndoInsertChars* pNext = static_cast<TextUndoInsertChars*>(pNextAction);
280 
281  if ( maTextPaM.GetPara() != pNext->maTextPaM.GetPara() )
282  return false;
283 
284  if ( ( maTextPaM.GetIndex() + maText.getLength() ) == pNext->maTextPaM.GetIndex() )
285  {
286  maText += pNext->maText;
287  return true;
288  }
289  return false;
290 }
291 
293 {
294  // multiple lines?
295  OUString sText(maText);
296  Shorten(sText);
297  return VclResId(STR_TEXTUNDO_INSERTCHARS).replaceAll("$1", sText);
298 }
299 
300 TextUndoRemoveChars::TextUndoRemoveChars( TextEngine* pTextEngine, const TextPaM& rTextPaM, const OUString& rStr )
301  : TextUndo( pTextEngine ),
302  maTextPaM( rTextPaM ), maText( rStr )
303 {
304 }
305 
307 {
309  GetTextEngine()->ImpInsertText( aSel, maText );
310  aSel.GetEnd().GetIndex() += maText.getLength();
311  SetSelection( aSel );
312 }
313 
315 {
317  aSel.GetEnd().GetIndex() += maText.getLength();
318  TextPaM aPaM = GetTextEngine()->ImpDeleteText( aSel );
319  SetSelection( aPaM );
320 }
321 
323 {
324  // multiple lines?
325  OUString sText(maText);
326  Shorten(sText);
327  return VclResId(STR_TEXTUNDO_REMOVECHARS).replaceAll("$1", sText);
328 }
329 
330 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
TextPaM SplitContent(sal_uInt32 nNode, sal_Int32 nSepPos)
Definition: texteng.cxx:1329
virtual ~TextUndoSplitPara() override
Definition: textundo.cxx:230
virtual void Redo() override
Definition: textundo.cxx:212
std::vector< std::unique_ptr< TextNode > > & GetNodes()
Definition: textdoc.hxx:107
virtual OUString GetComment() const override
Definition: textundo.cxx:292
TextPaM ImpInsertText(const TextSelection &rSel, sal_Unicode c, bool bOverwrite=false)
Definition: texteng.cxx:636
void GetSelection(struct ESelection &rSel, SvxTextForwarder const *pForwarder)
void SetSelection(const TextSelection &rSel)
Definition: textundo.cxx:132
void SetIsInUndo(bool bInUndo)
Definition: texteng.hxx:267
virtual void Redo() override
Definition: textundo.cxx:240
TextEngine * mpTextEngine
Definition: textundo.hxx:56
virtual ~TextUndoDelPara() override
Definition: textundo.cxx:146
const TextPaM & GetEnd() const
Definition: textdata.hxx:94
virtual void Undo() override
Definition: textundo.cxx:234
sal_Int32 const mnSepPos
Definition: textund2.hxx:62
virtual bool Undo()
sal_Int32 const mnSepPos
Definition: textund2.hxx:46
virtual ~TextUndoConnectParas() override
Definition: textundo.cxx:202
virtual bool Redo()
TextUndoManager(TextEngine *pTextEngine)
Definition: textundo.cxx:60
virtual void Undo() override
Definition: textundo.cxx:152
void InsertContent(std::unique_ptr< TextNode > pNode, sal_uInt32 nPara)
Definition: texteng.cxx:1319
sal_uInt32 const mnPara
Definition: textund2.hxx:29
virtual size_t GetRedoActionCount(bool const i_currentLevel=CurrentLevel) const
TextEngine * mpTextEngine
Definition: textundo.hxx:33
void Remove(sal_uInt32 nPos)
Definition: textdat2.hxx:224
sal_uInt32 const mnPara
Definition: textund2.hxx:45
virtual bool Redo() override
Definition: textundo.cxx:85
sal_uInt32 const mnPara
Definition: textund2.hxx:61
TEParaPortions * GetTEParaPortions() const
Definition: textundo.hxx:64
TextUndoSplitPara(TextEngine *pTextEngine, sal_uInt32 nPara, sal_Int32 nSepPos)
Definition: textundo.cxx:223
TextPaM const maTextPaM
Definition: textund2.hxx:94
virtual OUString GetComment() const override
Definition: textundo.cxx:190
virtual void Undo() override
Definition: textundo.cxx:257
virtual OUString GetComment() const override
Definition: textundo.cxx:218
TextView * GetView() const
Definition: textundo.hxx:60
const TextPaM & GetStart() const
Definition: textdata.hxx:91
virtual void Undo() override
Definition: textundo.cxx:206
virtual bool Undo() override
Definition: textundo.cxx:69
TextNode * mpNode
Definition: textund2.hxx:30
virtual size_t GetUndoActionCount(bool const i_currentLevel=CurrentLevel) const
void ImpParagraphRemoved(sal_uInt32 nPara)
Definition: texteng.cxx:2545
void UndoRedoEnd()
Definition: textundo.cxx:106
virtual OUString GetComment() const override
Definition: textundo.cxx:322
Text maText
#define SAL_WARN_IF(condition, area, stream)
TextUndoRemoveChars(TextEngine *pTextEngine, const TextPaM &rTextPaM, const OUString &rStr)
Definition: textundo.cxx:300
TextPaM ImpDeleteText(const TextSelection &rSel)
Definition: texteng.cxx:523
OUString const maText
Definition: textund2.hxx:95
sal_Int32 GetIndex() const
Definition: textdata.hxx:49
virtual ~TextUndo() override
Definition: textundo.cxx:123
virtual void Redo() override
Definition: textundo.cxx:314
TextUndoDelPara(TextEngine *pTextEngine, TextNode *pNode, sal_uInt32 nPara)
Definition: textundo.cxx:138
const OUString & GetText() const
Definition: textdoc.hxx:80
void FormatAndUpdate(TextView *pCurView=nullptr)
Definition: texteng.cxx:1412
OUString VclResId(const char *pId)
Definition: svdata.cxx:257
virtual OUString GetComment() const override
Definition: textundo.cxx:246
TextView * GetView() const
Definition: textundo.hxx:40
TextPaM ConnectContents(sal_uInt32 nLeftNode)
Definition: texteng.cxx:1341
void ImpSetSelection(const TextSelection &rSelection)
Definition: textview.cxx:378
virtual void Redo() override
Definition: textundo.cxx:164
void UndoRedoStart()
Definition: textundo.cxx:101
virtual void Undo() override
Definition: textundo.cxx:306
TextUndoInsertChars(TextEngine *pTextEngine, const TextPaM &rTextPaM, const OUString &rStr)
Definition: textundo.cxx:251
TextEngine * GetTextEngine() const
Definition: textundo.hxx:70
TextUndo(TextEngine *pTextEngine)
Definition: textundo.cxx:118
sal_uInt32 GetPara() const
Definition: textdata.hxx:46
virtual OUString GetComment() const override
Definition: textundo.cxx:127
virtual bool Merge(SfxUndoAction *pNextAction) override
Definition: textundo.cxx:274
virtual void Redo() override
Definition: textundo.cxx:265
virtual ~TextUndoManager() override
Definition: textundo.cxx:65
TextDoc * GetDoc() const
Definition: textundo.hxx:63
TextUndoConnectParas(TextEngine *pTextEngine, sal_uInt32 nPara, sal_Int32 nSepPos)
Definition: textundo.cxx:195