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