Line data Source code
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 :
21 : #include <UndoInsert.hxx>
22 :
23 : #include <hintids.hxx>
24 : #include <unotools/charclass.hxx>
25 : #include <sot/storage.hxx>
26 : #include <editeng/keepitem.hxx>
27 : #include <svx/svdobj.hxx>
28 :
29 : #include <docsh.hxx>
30 : #include <fmtcntnt.hxx>
31 : #include <fmtanchr.hxx>
32 : #include <frmfmt.hxx>
33 : #include <doc.hxx>
34 : #include <IDocumentUndoRedo.hxx>
35 : #include <swundo.hxx>
36 : #include <pam.hxx>
37 : #include <ndtxt.hxx>
38 : #include <UndoCore.hxx>
39 : #include <UndoDelete.hxx>
40 : #include <UndoAttribute.hxx>
41 : #include <rolbck.hxx>
42 : #include <ndgrf.hxx>
43 : #include <ndole.hxx>
44 : #include <grfatr.hxx>
45 : #include <cntfrm.hxx>
46 : #include <flyfrm.hxx>
47 : #include <fesh.hxx>
48 : #include <swtable.hxx>
49 : #include <redline.hxx>
50 : #include <docary.hxx>
51 : #include <acorrect.hxx>
52 : #include <dcontact.hxx>
53 :
54 : #include <comcore.hrc> // #111827#
55 : #include <undo.hrc>
56 :
57 : using namespace ::com::sun::star;
58 :
59 :
60 : //------------------------------------------------------------
61 :
62 : // INSERT
63 :
64 0 : String * SwUndoInsert::GetTxtFromDoc() const
65 : {
66 0 : String * pResult = NULL;
67 :
68 0 : SwNodeIndex aNd( pDoc->GetNodes(), nNode);
69 0 : SwCntntNode* pCNd = aNd.GetNode().GetCntntNode();
70 0 : SwPaM aPaM( *pCNd, nCntnt );
71 :
72 0 : aPaM.SetMark();
73 :
74 0 : if( pCNd->IsTxtNode() )
75 : {
76 : pResult = new String( ((SwTxtNode*)pCNd)->GetTxt().Copy(nCntnt-nLen,
77 0 : nLen ) );
78 :
79 : }
80 :
81 0 : return pResult;
82 : }
83 :
84 0 : void SwUndoInsert::Init(const SwNodeIndex & rNd)
85 : {
86 : // consider Redline
87 0 : pDoc = rNd.GetNode().GetDoc();
88 0 : if( pDoc->IsRedlineOn() )
89 : {
90 : pRedlData = new SwRedlineData( nsRedlineType_t::REDLINE_INSERT,
91 0 : pDoc->GetRedlineAuthor() );
92 0 : SetRedlineMode( pDoc->GetRedlineMode() );
93 : }
94 :
95 0 : pUndoTxt = GetTxtFromDoc();
96 :
97 0 : bCacheComment = false;
98 0 : }
99 :
100 : // #111827#
101 0 : SwUndoInsert::SwUndoInsert( const SwNodeIndex& rNd, xub_StrLen nCnt,
102 : xub_StrLen nL,
103 : const IDocumentContentOperations::InsertFlags nInsertFlags,
104 : sal_Bool bWDelim )
105 : : SwUndo(UNDO_TYPING), pTxt( 0 ), pRedlData( 0 ),
106 0 : nNode( rNd.GetIndex() ), nCntnt(nCnt), nLen(nL),
107 : bIsWordDelim( bWDelim ), bIsAppend( sal_False )
108 0 : , m_nInsertFlags(nInsertFlags)
109 : {
110 0 : Init(rNd);
111 0 : }
112 :
113 : // #111827#
114 0 : SwUndoInsert::SwUndoInsert( const SwNodeIndex& rNd )
115 : : SwUndo(UNDO_SPLITNODE), pTxt( 0 ),
116 0 : pRedlData( 0 ), nNode( rNd.GetIndex() ), nCntnt(0), nLen(1),
117 : bIsWordDelim( sal_False ), bIsAppend( sal_True )
118 0 : , m_nInsertFlags(IDocumentContentOperations::INS_EMPTYEXPAND)
119 : {
120 0 : Init(rNd);
121 0 : }
122 :
123 : // Check if the next Insert can be combined with the current one. If so
124 : // change the length and InsPos. As a result, SwDoc::Inser will not add a
125 : // new object into the Undo list.
126 :
127 0 : sal_Bool SwUndoInsert::CanGrouping( sal_Unicode cIns )
128 : {
129 0 : if( !bIsAppend && bIsWordDelim ==
130 0 : !GetAppCharClass().isLetterNumeric( rtl::OUString( cIns )) )
131 : {
132 0 : nLen++;
133 0 : nCntnt++;
134 :
135 0 : if (pUndoTxt)
136 0 : pUndoTxt->Insert(cIns);
137 :
138 0 : return sal_True;
139 : }
140 0 : return sal_False;
141 : }
142 :
143 0 : sal_Bool SwUndoInsert::CanGrouping( const SwPosition& rPos )
144 : {
145 0 : sal_Bool bRet = sal_False;
146 0 : if( nNode == rPos.nNode.GetIndex() &&
147 0 : nCntnt == rPos.nContent.GetIndex() )
148 : {
149 : // consider Redline
150 0 : SwDoc& rDoc = *rPos.nNode.GetNode().GetDoc();
151 0 : if( ( ~nsRedlineMode_t::REDLINE_SHOW_MASK & rDoc.GetRedlineMode() ) ==
152 0 : ( ~nsRedlineMode_t::REDLINE_SHOW_MASK & GetRedlineMode() ) )
153 : {
154 0 : bRet = sal_True;
155 :
156 : // than there is or was still an active Redline:
157 : // Check if there is another Redline at the InsPosition. If the
158 : // same exists only once, it can be combined.
159 0 : const SwRedlineTbl& rTbl = rDoc.GetRedlineTbl();
160 0 : if( !rTbl.empty() )
161 : {
162 0 : SwRedlineData aRData( nsRedlineType_t::REDLINE_INSERT, rDoc.GetRedlineAuthor() );
163 0 : const SwIndexReg* pIReg = rPos.nContent.GetIdxReg();
164 : SwIndex* pIdx;
165 0 : for( sal_uInt16 i = 0; i < rTbl.size(); ++i )
166 : {
167 0 : SwRedline* pRedl = rTbl[ i ];
168 0 : if( pIReg == (pIdx = &pRedl->End()->nContent)->GetIdxReg() &&
169 0 : nCntnt == pIdx->GetIndex() )
170 : {
171 0 : if( !pRedl->HasMark() || !pRedlData ||
172 0 : *pRedl != *pRedlData || *pRedl != aRData )
173 : {
174 0 : bRet = sal_False;
175 0 : break;
176 : }
177 : }
178 0 : }
179 : }
180 : }
181 : }
182 0 : return bRet;
183 : }
184 :
185 0 : SwUndoInsert::~SwUndoInsert()
186 : {
187 0 : if (m_pUndoNodeIndex) // delete the section from UndoNodes array
188 : {
189 : // Insert saves the content in IconSection
190 0 : SwNodes& rUNds = m_pUndoNodeIndex->GetNodes();
191 0 : rUNds.Delete(*m_pUndoNodeIndex,
192 0 : rUNds.GetEndOfExtras().GetIndex() - m_pUndoNodeIndex->GetIndex());
193 0 : m_pUndoNodeIndex.reset();
194 : }
195 0 : else if( pTxt ) // the inserted text
196 0 : delete pTxt;
197 0 : delete pRedlData;
198 0 : delete pUndoTxt;
199 0 : }
200 :
201 :
202 :
203 0 : void SwUndoInsert::UndoImpl(::sw::UndoRedoContext & rContext)
204 : {
205 0 : SwDoc *const pTmpDoc = & rContext.GetDoc();
206 0 : SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
207 :
208 0 : if( bIsAppend )
209 : {
210 0 : pPam->GetPoint()->nNode = nNode;
211 :
212 0 : if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
213 : {
214 0 : pPam->GetPoint()->nContent.Assign( pPam->GetCntntNode(), 0 );
215 0 : pPam->SetMark();
216 0 : pPam->Move( fnMoveBackward );
217 0 : pPam->Exchange();
218 0 : pTmpDoc->DeleteRedline( *pPam, true, USHRT_MAX );
219 : }
220 0 : pPam->DeleteMark();
221 0 : pTmpDoc->DelFullPara( *pPam );
222 0 : pPam->GetPoint()->nContent.Assign( pPam->GetCntntNode(), 0 );
223 : }
224 : else
225 : {
226 0 : sal_uLong nNd = nNode;
227 0 : xub_StrLen nCnt = nCntnt;
228 0 : if( nLen )
229 : {
230 0 : SwNodeIndex aNd( pTmpDoc->GetNodes(), nNode);
231 0 : SwCntntNode* pCNd = aNd.GetNode().GetCntntNode();
232 0 : SwPaM aPaM( *pCNd, nCntnt );
233 :
234 0 : aPaM.SetMark();
235 :
236 0 : SwTxtNode * const pTxtNode( pCNd->GetTxtNode() );
237 0 : if ( pTxtNode )
238 : {
239 0 : aPaM.GetPoint()->nContent -= nLen;
240 0 : if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
241 0 : pTmpDoc->DeleteRedline( aPaM, true, USHRT_MAX );
242 0 : RemoveIdxFromRange( aPaM, sal_False );
243 0 : pTxt = new String( pTxtNode->GetTxt().Copy(nCntnt-nLen, nLen) );
244 0 : pTxtNode->EraseText( aPaM.GetPoint()->nContent, nLen );
245 : }
246 : else // otherwise Graphics/OLE/Text/...
247 : {
248 0 : aPaM.Move(fnMoveBackward);
249 0 : if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
250 0 : pTmpDoc->DeleteRedline( aPaM, true, USHRT_MAX );
251 0 : RemoveIdxFromRange( aPaM, sal_False );
252 : }
253 :
254 0 : nNd = aPaM.GetPoint()->nNode.GetIndex();
255 0 : nCnt = aPaM.GetPoint()->nContent.GetIndex();
256 :
257 0 : if( !pTxt )
258 : {
259 : m_pUndoNodeIndex.reset(
260 0 : new SwNodeIndex(pDoc->GetNodes().GetEndOfContent()));
261 0 : MoveToUndoNds(aPaM, m_pUndoNodeIndex.get());
262 : }
263 0 : nNode = aPaM.GetPoint()->nNode.GetIndex();
264 0 : nCntnt = aPaM.GetPoint()->nContent.GetIndex();
265 : }
266 :
267 : // set cursor to Undo range
268 0 : pPam->DeleteMark();
269 :
270 0 : pPam->GetPoint()->nNode = nNd;
271 0 : pPam->GetPoint()->nContent.Assign(
272 0 : pPam->GetPoint()->nNode.GetNode().GetCntntNode(), nCnt );
273 : }
274 :
275 0 : DELETEZ(pUndoTxt);
276 0 : }
277 :
278 :
279 0 : void SwUndoInsert::RedoImpl(::sw::UndoRedoContext & rContext)
280 : {
281 0 : SwDoc *const pTmpDoc = & rContext.GetDoc();
282 0 : SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
283 0 : pPam->DeleteMark();
284 :
285 0 : if( bIsAppend )
286 : {
287 0 : pPam->GetPoint()->nNode = nNode - 1;
288 0 : pTmpDoc->AppendTxtNode( *pPam->GetPoint() );
289 :
290 0 : pPam->SetMark();
291 0 : pPam->Move( fnMoveBackward );
292 0 : pPam->Exchange();
293 :
294 0 : if( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
295 : {
296 0 : RedlineMode_t eOld = pTmpDoc->GetRedlineMode();
297 0 : pTmpDoc->SetRedlineMode_intern((RedlineMode_t)(eOld & ~nsRedlineMode_t::REDLINE_IGNORE));
298 0 : pTmpDoc->AppendRedline( new SwRedline( *pRedlData, *pPam ), true);
299 0 : pTmpDoc->SetRedlineMode_intern( eOld );
300 : }
301 0 : else if( !( nsRedlineMode_t::REDLINE_IGNORE & GetRedlineMode() ) &&
302 0 : !pTmpDoc->GetRedlineTbl().empty() )
303 0 : pTmpDoc->SplitRedline( *pPam );
304 :
305 0 : pPam->DeleteMark();
306 : }
307 : else
308 : {
309 0 : pPam->GetPoint()->nNode = nNode;
310 : SwCntntNode *const pCNd =
311 0 : pPam->GetPoint()->nNode.GetNode().GetCntntNode();
312 0 : pPam->GetPoint()->nContent.Assign( pCNd, nCntnt );
313 :
314 0 : if( nLen )
315 : {
316 0 : sal_Bool bMvBkwrd = MovePtBackward( *pPam );
317 :
318 0 : if( pTxt )
319 : {
320 0 : SwTxtNode *const pTxtNode = pCNd->GetTxtNode();
321 : OSL_ENSURE( pTxtNode, "where is my textnode ?" );
322 0 : pTxtNode->InsertText( *pTxt, pPam->GetMark()->nContent,
323 0 : m_nInsertFlags );
324 0 : DELETEZ( pTxt );
325 : }
326 : else
327 : {
328 : // re-insert content again (first detach m_pUndoNodeIndex!)
329 0 : sal_uLong const nMvNd = m_pUndoNodeIndex->GetIndex();
330 0 : m_pUndoNodeIndex.reset();
331 0 : MoveFromUndoNds(*pTmpDoc, nMvNd, *pPam->GetMark());
332 : }
333 0 : nNode = pPam->GetMark()->nNode.GetIndex();
334 0 : nCntnt = pPam->GetMark()->nContent.GetIndex();
335 :
336 0 : MovePtForward( *pPam, bMvBkwrd );
337 0 : pPam->Exchange();
338 0 : if( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
339 : {
340 0 : RedlineMode_t eOld = pTmpDoc->GetRedlineMode();
341 0 : pTmpDoc->SetRedlineMode_intern((RedlineMode_t)(eOld & ~nsRedlineMode_t::REDLINE_IGNORE));
342 : pTmpDoc->AppendRedline( new SwRedline( *pRedlData,
343 0 : *pPam ), true);
344 0 : pTmpDoc->SetRedlineMode_intern( eOld );
345 : }
346 0 : else if( !( nsRedlineMode_t::REDLINE_IGNORE & GetRedlineMode() ) &&
347 0 : !pTmpDoc->GetRedlineTbl().empty() )
348 0 : pTmpDoc->SplitRedline(*pPam);
349 : }
350 : }
351 :
352 0 : pUndoTxt = GetTxtFromDoc();
353 0 : }
354 :
355 :
356 0 : void SwUndoInsert::RepeatImpl(::sw::RepeatContext & rContext)
357 : {
358 0 : if( !nLen )
359 0 : return;
360 :
361 0 : SwDoc & rDoc = rContext.GetDoc();
362 0 : SwNodeIndex aNd( rDoc.GetNodes(), nNode );
363 0 : SwCntntNode* pCNd = aNd.GetNode().GetCntntNode();
364 :
365 0 : if( !bIsAppend && 1 == nLen ) // >1 than always Text, otherwise Graphics/OLE/Text/...
366 : {
367 0 : SwPaM aPaM( *pCNd, nCntnt );
368 0 : aPaM.SetMark();
369 0 : aPaM.Move(fnMoveBackward);
370 0 : pCNd = aPaM.GetCntntNode();
371 : }
372 :
373 : // What happens with the possible selected range ???
374 :
375 0 : switch( pCNd->GetNodeType() )
376 : {
377 : case ND_TEXTNODE:
378 0 : if( bIsAppend )
379 : {
380 0 : rDoc.AppendTxtNode( *rContext.GetRepeatPaM().GetPoint() );
381 : }
382 : else
383 : {
384 0 : String aTxt( ((SwTxtNode*)pCNd)->GetTxt() );
385 0 : ::sw::GroupUndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
386 0 : rDoc.InsertString( rContext.GetRepeatPaM(),
387 0 : aTxt.Copy( nCntnt - nLen, nLen ) );
388 : }
389 0 : break;
390 : case ND_GRFNODE:
391 : {
392 0 : SwGrfNode* pGrfNd = (SwGrfNode*)pCNd;
393 0 : String sFile, sFilter;
394 0 : if( pGrfNd->IsGrfLink() )
395 0 : pGrfNd->GetFileFilterNms( &sFile, &sFilter );
396 :
397 0 : rDoc.Insert( rContext.GetRepeatPaM(), sFile, sFilter,
398 0 : &pGrfNd->GetGrf(),
399 0 : 0/* Graphics collection*/, NULL, NULL );
400 : }
401 0 : break;
402 :
403 : case ND_OLENODE:
404 : {
405 : // StarView does not yet provide an option to copy a StarOBJ
406 0 : SvStorageRef aRef = new SvStorage( aEmptyStr );
407 0 : SwOLEObj& rSwOLE = (SwOLEObj&)((SwOLENode*)pCNd)->GetOLEObj();
408 :
409 : // temporary storage until object is inserted
410 : // TODO/MBA: seems that here a physical copy is done - not as in drawing layer! Testing!
411 : // TODO/LATER: Copying through the container would copy the replacement image as well
412 0 : comphelper::EmbeddedObjectContainer aCnt;
413 0 : ::rtl::OUString aName = aCnt.CreateUniqueObjectName();
414 0 : if ( aCnt.StoreEmbeddedObject( rSwOLE.GetOleRef(), aName, sal_True ) )
415 : {
416 0 : uno::Reference < embed::XEmbeddedObject > aNew = aCnt.GetEmbeddedObject( aName );
417 0 : rDoc.Insert( rContext.GetRepeatPaM(),
418 : svt::EmbeddedObjectRef( aNew,
419 : static_cast<SwOLENode*>(pCNd)->GetAspect() ),
420 0 : NULL, NULL, NULL );
421 : }
422 :
423 0 : break;
424 : }
425 0 : }
426 : }
427 :
428 : // #111827#
429 0 : SwRewriter SwUndoInsert::GetRewriter() const
430 : {
431 0 : SwRewriter aResult;
432 0 : String * pStr = NULL;
433 0 : bool bDone = false;
434 :
435 0 : if (pTxt)
436 0 : pStr = pTxt;
437 0 : else if (pUndoTxt)
438 0 : pStr = pUndoTxt;
439 :
440 0 : if (pStr)
441 : {
442 : String aString = ShortenString(DenoteSpecialCharacters(*pStr),
443 : nUndoStringLength,
444 0 : String(SW_RES(STR_LDOTS)));
445 :
446 0 : aResult.AddRule(UndoArg1, aString);
447 :
448 0 : bDone = true;
449 : }
450 :
451 0 : if ( ! bDone )
452 : {
453 0 : aResult.AddRule(UndoArg1, String("??", RTL_TEXTENCODING_ASCII_US));
454 : }
455 :
456 0 : return aResult;
457 : }
458 :
459 :
460 : // SwUndoReplace /////////////////////////////////////////////////////////
461 :
462 :
463 : class SwUndoReplace::Impl
464 : : private SwUndoSaveCntnt
465 : {
466 : ::rtl::OUString m_sOld;
467 : ::rtl::OUString m_sIns;
468 : sal_uLong m_nSttNd, m_nEndNd, m_nOffset;
469 : xub_StrLen m_nSttCnt, m_nEndCnt, m_nSetPos, m_nSelEnd;
470 : bool m_bSplitNext : 1;
471 : bool m_bRegExp : 1;
472 : // metadata references for paragraph and following para (if m_bSplitNext)
473 : ::boost::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoStart;
474 : ::boost::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoEnd;
475 :
476 : public:
477 : Impl(SwPaM const& rPam, ::rtl::OUString const& rIns, bool const bRegExp);
478 0 : virtual ~Impl()
479 0 : {
480 0 : }
481 :
482 : virtual void UndoImpl( ::sw::UndoRedoContext & );
483 : virtual void RedoImpl( ::sw::UndoRedoContext & );
484 :
485 : void SetEnd(SwPaM const& rPam);
486 :
487 0 : ::rtl::OUString const& GetOld() const { return m_sOld; }
488 0 : ::rtl::OUString const& GetIns() const { return m_sIns; }
489 : };
490 :
491 :
492 0 : SwUndoReplace::SwUndoReplace(SwPaM const& rPam,
493 : ::rtl::OUString const& rIns, bool const bRegExp)
494 : : SwUndo( UNDO_REPLACE )
495 0 : , m_pImpl(new Impl(rPam, rIns, bRegExp))
496 : {
497 0 : }
498 :
499 0 : SwUndoReplace::~SwUndoReplace()
500 : {
501 0 : }
502 :
503 0 : void SwUndoReplace::UndoImpl(::sw::UndoRedoContext & rContext)
504 : {
505 0 : m_pImpl->UndoImpl(rContext);
506 0 : }
507 :
508 0 : void SwUndoReplace::RedoImpl(::sw::UndoRedoContext & rContext)
509 : {
510 0 : m_pImpl->RedoImpl(rContext);
511 0 : }
512 :
513 : SwRewriter
514 0 : MakeUndoReplaceRewriter(sal_uLong const occurrences,
515 : ::rtl::OUString const& sOld, ::rtl::OUString const& sNew)
516 : {
517 0 : SwRewriter aResult;
518 :
519 0 : if (1 < occurrences)
520 : {
521 0 : aResult.AddRule(UndoArg1, String::CreateFromInt32(occurrences));
522 0 : aResult.AddRule(UndoArg2, String(SW_RES(STR_OCCURRENCES_OF)));
523 :
524 0 : String aTmpStr;
525 0 : aTmpStr += String(SW_RES(STR_START_QUOTE));
526 : aTmpStr += ShortenString(sOld, nUndoStringLength,
527 0 : SW_RES(STR_LDOTS));
528 0 : aTmpStr += String(SW_RES(STR_END_QUOTE));
529 0 : aResult.AddRule(UndoArg3, aTmpStr);
530 : }
531 0 : else if (1 == occurrences)
532 : {
533 : {
534 0 : String aTmpStr;
535 :
536 0 : aTmpStr += String(SW_RES(STR_START_QUOTE));
537 : // #i33488 #
538 : aTmpStr += ShortenString(sOld, nUndoStringLength,
539 0 : SW_RES(STR_LDOTS));
540 0 : aTmpStr += String(SW_RES(STR_END_QUOTE));
541 0 : aResult.AddRule(UndoArg1, aTmpStr);
542 : }
543 :
544 0 : aResult.AddRule(UndoArg2, String(SW_RES(STR_YIELDS)));
545 :
546 : {
547 0 : String aTmpStr;
548 :
549 0 : aTmpStr += String(SW_RES(STR_START_QUOTE));
550 : // #i33488 #
551 : aTmpStr += ShortenString(sNew, nUndoStringLength,
552 0 : SW_RES(STR_LDOTS));
553 0 : aTmpStr += String(SW_RES(STR_END_QUOTE));
554 0 : aResult.AddRule(UndoArg3, aTmpStr);
555 : }
556 : }
557 :
558 0 : return aResult;
559 : }
560 :
561 : // #111827#
562 0 : SwRewriter SwUndoReplace::GetRewriter() const
563 : {
564 0 : return MakeUndoReplaceRewriter(1, m_pImpl->GetOld(), m_pImpl->GetIns());
565 : }
566 :
567 0 : void SwUndoReplace::SetEnd(SwPaM const& rPam)
568 : {
569 0 : m_pImpl->SetEnd(rPam);
570 0 : }
571 :
572 0 : SwUndoReplace::Impl::Impl(
573 : SwPaM const& rPam, ::rtl::OUString const& rIns, bool const bRegExp)
574 : : m_sIns( rIns )
575 : , m_nOffset( 0 )
576 0 : , m_bRegExp(bRegExp)
577 : {
578 :
579 0 : const SwPosition * pStt( rPam.Start() );
580 0 : const SwPosition * pEnd( rPam.End() );
581 :
582 0 : m_nSttNd = m_nEndNd = pStt->nNode.GetIndex();
583 0 : m_nSttCnt = pStt->nContent.GetIndex();
584 0 : m_nSelEnd = m_nEndCnt = pEnd->nContent.GetIndex();
585 :
586 0 : m_bSplitNext = m_nSttNd != pEnd->nNode.GetIndex();
587 :
588 0 : SwTxtNode* pNd = pStt->nNode.GetNode().GetTxtNode();
589 : OSL_ENSURE( pNd, "Dude, where's my TextNode?" );
590 :
591 0 : pHistory = new SwHistory;
592 0 : DelCntntIndex( *rPam.GetMark(), *rPam.GetPoint() );
593 :
594 0 : m_nSetPos = pHistory->Count();
595 :
596 0 : sal_uLong nNewPos = pStt->nNode.GetIndex();
597 0 : m_nOffset = m_nSttNd - nNewPos;
598 :
599 0 : if ( pNd->GetpSwpHints() )
600 : {
601 : pHistory->CopyAttr( pNd->GetpSwpHints(), nNewPos, 0,
602 0 : pNd->GetTxt().Len(), true );
603 : }
604 :
605 0 : if ( m_bSplitNext )
606 : {
607 0 : if( pNd->HasSwAttrSet() )
608 0 : pHistory->CopyFmtAttr( *pNd->GetpSwAttrSet(), nNewPos );
609 0 : pHistory->Add( pNd->GetTxtColl(), nNewPos, ND_TEXTNODE );
610 :
611 0 : SwTxtNode* pNext = pEnd->nNode.GetNode().GetTxtNode();
612 0 : sal_uLong nTmp = pNext->GetIndex();
613 : pHistory->CopyAttr( pNext->GetpSwpHints(), nTmp, 0,
614 0 : pNext->GetTxt().Len(), true );
615 0 : if( pNext->HasSwAttrSet() )
616 0 : pHistory->CopyFmtAttr( *pNext->GetpSwAttrSet(), nTmp );
617 0 : pHistory->Add( pNext->GetTxtColl(),nTmp, ND_TEXTNODE );
618 : // METADATA: store
619 0 : m_pMetadataUndoStart = pNd ->CreateUndo();
620 0 : m_pMetadataUndoEnd = pNext->CreateUndo();
621 : }
622 :
623 0 : if( !pHistory->Count() )
624 0 : delete pHistory, pHistory = 0;
625 :
626 0 : xub_StrLen nECnt = m_bSplitNext ? pNd->GetTxt().Len()
627 0 : : pEnd->nContent.GetIndex();
628 0 : m_sOld = pNd->GetTxt().Copy( m_nSttCnt, nECnt - m_nSttCnt );
629 0 : }
630 :
631 0 : void SwUndoReplace::Impl::UndoImpl(::sw::UndoRedoContext & rContext)
632 : {
633 0 : SwDoc *const pDoc = & rContext.GetDoc();
634 0 : SwPaM & rPam(rContext.GetCursorSupplier().CreateNewShellCursor());
635 0 : rPam.DeleteMark();
636 :
637 0 : SwTxtNode* pNd = pDoc->GetNodes()[ m_nSttNd - m_nOffset ]->GetTxtNode();
638 : OSL_ENSURE( pNd, "Dude, where's my TextNode?" );
639 :
640 0 : SwAutoCorrExceptWord* pACEWord = pDoc->GetAutoCorrExceptWord();
641 0 : if( pACEWord )
642 : {
643 0 : if ((1 == m_sIns.getLength()) && (1 == m_sOld.getLength()))
644 : {
645 0 : SwPosition aPos( *pNd ); aPos.nContent.Assign( pNd, m_nSttCnt );
646 0 : pACEWord->CheckChar( aPos, m_sOld[ 0 ] );
647 : }
648 0 : pDoc->SetAutoCorrExceptWord( 0 );
649 : }
650 :
651 0 : SwIndex aIdx( pNd, m_nSttCnt );
652 0 : if( m_nSttNd == m_nEndNd )
653 : {
654 0 : pNd->EraseText( aIdx, sal_uInt16( m_sIns.getLength() ) );
655 : }
656 : else
657 : {
658 0 : rPam.GetPoint()->nNode = *pNd;
659 0 : rPam.GetPoint()->nContent.Assign( pNd, m_nSttCnt );
660 0 : rPam.SetMark();
661 0 : rPam.GetPoint()->nNode = m_nEndNd - m_nOffset;
662 0 : rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), m_nEndCnt );
663 : // move it out of the way so it is not registered at deleted node
664 0 : aIdx.Assign(0, 0);
665 :
666 0 : pDoc->DeleteAndJoin( rPam );
667 0 : rPam.DeleteMark();
668 0 : pNd = rPam.GetNode()->GetTxtNode();
669 : OSL_ENSURE( pNd, "Dude, where's my TextNode?" );
670 0 : aIdx.Assign( pNd, m_nSttCnt );
671 : }
672 :
673 0 : if( m_bSplitNext )
674 : {
675 0 : SwPosition aPos( *pNd, aIdx );
676 0 : pDoc->SplitNode( aPos, false );
677 0 : pNd->RestoreMetadata(m_pMetadataUndoEnd);
678 0 : pNd = pDoc->GetNodes()[ m_nSttNd - m_nOffset ]->GetTxtNode();
679 0 : aIdx.Assign( pNd, m_nSttCnt );
680 : // METADATA: restore
681 0 : pNd->RestoreMetadata(m_pMetadataUndoStart);
682 : }
683 :
684 0 : if (!m_sOld.isEmpty())
685 : {
686 0 : pNd->InsertText( m_sOld, aIdx );
687 : }
688 :
689 0 : if( pHistory )
690 : {
691 0 : if( pNd->GetpSwpHints() )
692 0 : pNd->ClearSwpHintsArr( true );
693 :
694 0 : pHistory->TmpRollback( pDoc, m_nSetPos, false );
695 0 : if ( m_nSetPos ) // there were footnotes/FlyFrames
696 : {
697 : // are there others than these?
698 0 : if( m_nSetPos < pHistory->Count() )
699 : {
700 : // than save those attributes as well
701 0 : SwHistory aHstr;
702 0 : aHstr.Move( 0, pHistory, m_nSetPos );
703 0 : pHistory->Rollback( pDoc );
704 0 : pHistory->Move( 0, &aHstr );
705 : }
706 : else
707 : {
708 0 : pHistory->Rollback( pDoc );
709 0 : DELETEZ( pHistory );
710 : }
711 : }
712 : }
713 :
714 0 : rPam.GetPoint()->nNode = m_nSttNd;
715 0 : rPam.GetPoint()->nContent = aIdx;
716 0 : }
717 :
718 0 : void SwUndoReplace::Impl::RedoImpl(::sw::UndoRedoContext & rContext)
719 : {
720 0 : SwDoc & rDoc = rContext.GetDoc();
721 0 : SwPaM & rPam(rContext.GetCursorSupplier().CreateNewShellCursor());
722 0 : rPam.DeleteMark();
723 0 : rPam.GetPoint()->nNode = m_nSttNd;
724 :
725 0 : SwTxtNode* pNd = rPam.GetPoint()->nNode.GetNode().GetTxtNode();
726 : OSL_ENSURE( pNd, "Dude, where's my TextNode?" );
727 0 : rPam.GetPoint()->nContent.Assign( pNd, m_nSttCnt );
728 0 : rPam.SetMark();
729 0 : if( m_bSplitNext )
730 : {
731 0 : rPam.GetPoint()->nNode = m_nSttNd + 1;
732 0 : pNd = rPam.GetPoint()->nNode.GetNode().GetTxtNode();
733 : }
734 0 : rPam.GetPoint()->nContent.Assign( pNd, m_nSelEnd );
735 :
736 0 : if( pHistory )
737 : {
738 0 : SwHistory* pSave = pHistory;
739 0 : SwHistory aHst;
740 0 : pHistory = &aHst;
741 0 : DelCntntIndex( *rPam.GetMark(), *rPam.GetPoint() );
742 0 : m_nSetPos = pHistory->Count();
743 :
744 0 : pHistory = pSave;
745 0 : pHistory->Move( 0, &aHst );
746 : }
747 : else
748 : {
749 0 : pHistory = new SwHistory;
750 0 : DelCntntIndex( *rPam.GetMark(), *rPam.GetPoint() );
751 0 : m_nSetPos = pHistory->Count();
752 0 : if( !m_nSetPos )
753 0 : delete pHistory, pHistory = 0;
754 : }
755 :
756 0 : rDoc.ReplaceRange( rPam, m_sIns, m_bRegExp );
757 0 : rPam.DeleteMark();
758 0 : }
759 :
760 0 : void SwUndoReplace::Impl::SetEnd(SwPaM const& rPam)
761 : {
762 0 : if( rPam.GetPoint()->nNode != rPam.GetMark()->nNode )
763 : {
764 : // multiple paragraphs were inserted
765 0 : const SwPosition* pEnd = rPam.End();
766 0 : m_nEndNd = m_nOffset + pEnd->nNode.GetIndex();
767 0 : m_nEndCnt = pEnd->nContent.GetIndex();
768 : }
769 0 : }
770 :
771 :
772 : // SwUndoReRead //////////////////////////////////////////////////////////
773 :
774 :
775 0 : SwUndoReRead::SwUndoReRead( const SwPaM& rPam, const SwGrfNode& rGrfNd )
776 0 : : SwUndo( UNDO_REREAD ), nPos( rPam.GetPoint()->nNode.GetIndex() )
777 : {
778 0 : SaveGraphicData( rGrfNd );
779 0 : }
780 :
781 :
782 0 : SwUndoReRead::~SwUndoReRead()
783 : {
784 0 : delete pGrf;
785 0 : delete pNm;
786 0 : delete pFltr;
787 0 : }
788 :
789 :
790 0 : void SwUndoReRead::SetAndSave(::sw::UndoRedoContext & rContext)
791 : {
792 0 : SwDoc & rDoc = rContext.GetDoc();
793 0 : SwGrfNode* pGrfNd = rDoc.GetNodes()[ nPos ]->GetGrfNode();
794 :
795 0 : if( !pGrfNd )
796 0 : return ;
797 :
798 : // cache the old values
799 0 : Graphic* pOldGrf = pGrf;
800 0 : String* pOldNm = pNm;
801 0 : String* pOldFltr = pFltr;
802 0 : sal_uInt16 nOldMirr = nMirr;
803 :
804 0 : SaveGraphicData( *pGrfNd );
805 0 : if( pOldNm )
806 : {
807 0 : pGrfNd->ReRead( *pOldNm, pFltr ? *pFltr : aEmptyStr, 0, 0, sal_True );
808 0 : delete pOldNm;
809 0 : delete pOldFltr;
810 : }
811 : else
812 : {
813 0 : pGrfNd->ReRead( aEmptyStr, aEmptyStr, pOldGrf, 0, sal_True );
814 0 : delete pOldGrf;
815 : }
816 :
817 0 : if( RES_MIRROR_GRAPH_DONT != nOldMirr )
818 0 : pGrfNd->SetAttr( SwMirrorGrf() );
819 :
820 0 : rContext.SetSelections(pGrfNd->GetFlyFmt(), 0);
821 : }
822 :
823 :
824 0 : void SwUndoReRead::UndoImpl(::sw::UndoRedoContext & rContext)
825 : {
826 0 : SetAndSave(rContext);
827 0 : }
828 :
829 :
830 0 : void SwUndoReRead::RedoImpl(::sw::UndoRedoContext & rContext)
831 : {
832 0 : SetAndSave(rContext);
833 0 : }
834 :
835 :
836 0 : void SwUndoReRead::SaveGraphicData( const SwGrfNode& rGrfNd )
837 : {
838 0 : if( rGrfNd.IsGrfLink() )
839 : {
840 0 : pNm = new String;
841 0 : pFltr = new String;
842 0 : rGrfNd.GetFileFilterNms( pNm, pFltr );
843 0 : pGrf = 0;
844 : }
845 : else
846 : {
847 0 : ((SwGrfNode&)rGrfNd).SwapIn( sal_True );
848 0 : pGrf = new Graphic( rGrfNd.GetGrf() );
849 0 : pNm = pFltr = 0;
850 : }
851 0 : nMirr = rGrfNd.GetSwAttrSet().GetMirrorGrf().GetValue();
852 0 : }
853 :
854 :
855 0 : SwUndoInsertLabel::SwUndoInsertLabel( const SwLabelType eTyp,
856 : const String &rTxt,
857 : const String& rSeparator,
858 : const String& rNumberSeparator,
859 : const sal_Bool bBef,
860 : const sal_uInt16 nInitId,
861 : const String& rCharacterStyle,
862 : const sal_Bool bCpyBorder )
863 : : SwUndo( UNDO_INSERTLABEL ),
864 : sText( rTxt ),
865 : sSeparator( rSeparator ),
866 : sNumberSeparator( rNumberSeparator ),//#i61007# order of captions
867 : sCharacterStyle( rCharacterStyle ),
868 : nFldId( nInitId ),
869 : eType( eTyp ),
870 : nLayerId( 0 ),
871 : bBefore( bBef ),
872 0 : bCpyBrd( bCpyBorder )
873 : {
874 0 : bUndoKeep = sal_False;
875 0 : OBJECT.pUndoFly = 0;
876 0 : OBJECT.pUndoAttr = 0;
877 0 : }
878 :
879 0 : SwUndoInsertLabel::~SwUndoInsertLabel()
880 : {
881 0 : if( LTYPE_OBJECT == eType || LTYPE_DRAW == eType )
882 : {
883 0 : delete OBJECT.pUndoFly;
884 0 : delete OBJECT.pUndoAttr;
885 : }
886 : else
887 0 : delete NODE.pUndoInsNd;
888 0 : }
889 :
890 0 : void SwUndoInsertLabel::UndoImpl(::sw::UndoRedoContext & rContext)
891 : {
892 0 : SwDoc & rDoc = rContext.GetDoc();
893 :
894 0 : if( LTYPE_OBJECT == eType || LTYPE_DRAW == eType )
895 : {
896 : OSL_ENSURE( OBJECT.pUndoAttr && OBJECT.pUndoFly, "Pointer not initialized" );
897 : SwFrmFmt* pFmt;
898 0 : SdrObject *pSdrObj = 0;
899 0 : if( OBJECT.pUndoAttr &&
900 0 : 0 != (pFmt = (SwFrmFmt*)OBJECT.pUndoAttr->GetFmt( rDoc )) &&
901 : ( LTYPE_DRAW != eType ||
902 : 0 != (pSdrObj = pFmt->FindSdrObject()) ) )
903 : {
904 0 : OBJECT.pUndoAttr->UndoImpl(rContext);
905 0 : OBJECT.pUndoFly->UndoImpl(rContext);
906 0 : if( LTYPE_DRAW == eType )
907 : {
908 0 : pSdrObj->SetLayer( nLayerId );
909 : }
910 0 : }
911 : }
912 0 : else if( NODE.nNode )
913 : {
914 0 : if ( eType == LTYPE_TABLE && bUndoKeep )
915 : {
916 0 : SwTableNode *pNd = rDoc.GetNodes()[
917 0 : rDoc.GetNodes()[NODE.nNode-1]->StartOfSectionIndex()]->GetTableNode();
918 0 : if ( pNd )
919 0 : pNd->GetTable().GetFrmFmt()->ResetFmtAttr( RES_KEEP );
920 : }
921 0 : SwPaM aPam( rDoc.GetNodes().GetEndOfContent() );
922 0 : aPam.GetPoint()->nNode = NODE.nNode;
923 0 : aPam.SetMark();
924 0 : aPam.GetPoint()->nNode = NODE.nNode + 1;
925 0 : NODE.pUndoInsNd = new SwUndoDelete( aPam, sal_True );
926 : }
927 0 : }
928 :
929 :
930 0 : void SwUndoInsertLabel::RedoImpl(::sw::UndoRedoContext & rContext)
931 : {
932 0 : SwDoc & rDoc = rContext.GetDoc();
933 :
934 0 : if( LTYPE_OBJECT == eType || LTYPE_DRAW == eType )
935 : {
936 : OSL_ENSURE( OBJECT.pUndoAttr && OBJECT.pUndoFly, "Pointer not initialized" );
937 : SwFrmFmt* pFmt;
938 0 : SdrObject *pSdrObj = 0;
939 0 : if( OBJECT.pUndoAttr &&
940 0 : 0 != (pFmt = (SwFrmFmt*)OBJECT.pUndoAttr->GetFmt( rDoc )) &&
941 : ( LTYPE_DRAW != eType ||
942 : 0 != (pSdrObj = pFmt->FindSdrObject()) ) )
943 : {
944 0 : OBJECT.pUndoFly->RedoImpl(rContext);
945 0 : OBJECT.pUndoAttr->RedoImpl(rContext);
946 0 : if( LTYPE_DRAW == eType )
947 : {
948 0 : pSdrObj->SetLayer( nLayerId );
949 0 : if( pSdrObj->GetLayer() == rDoc.GetHellId() )
950 0 : pSdrObj->SetLayer( rDoc.GetHeavenId() );
951 : // OD 02.07.2003 #108784#
952 0 : else if( pSdrObj->GetLayer() == rDoc.GetInvisibleHellId() )
953 0 : pSdrObj->SetLayer( rDoc.GetInvisibleHeavenId() );
954 : }
955 0 : }
956 : }
957 0 : else if( NODE.pUndoInsNd )
958 : {
959 0 : if ( eType == LTYPE_TABLE && bUndoKeep )
960 : {
961 0 : SwTableNode *pNd = rDoc.GetNodes()[
962 0 : rDoc.GetNodes()[NODE.nNode-1]->StartOfSectionIndex()]->GetTableNode();
963 0 : if ( pNd )
964 0 : pNd->GetTable().GetFrmFmt()->SetFmtAttr( SvxFmtKeepItem(sal_True, RES_KEEP) );
965 : }
966 0 : NODE.pUndoInsNd->UndoImpl(rContext);
967 0 : delete NODE.pUndoInsNd, NODE.pUndoInsNd = 0;
968 : }
969 0 : }
970 :
971 0 : void SwUndoInsertLabel::RepeatImpl(::sw::RepeatContext & rContext)
972 : {
973 0 : SwDoc & rDoc = rContext.GetDoc();
974 0 : const SwPosition& rPos = *rContext.GetRepeatPaM().GetPoint();
975 :
976 0 : sal_uLong nIdx = 0;
977 :
978 0 : SwCntntNode* pCNd = rPos.nNode.GetNode().GetCntntNode();
979 0 : if( pCNd )
980 0 : switch( eType )
981 : {
982 : case LTYPE_TABLE:
983 : {
984 0 : const SwTableNode* pTNd = pCNd->FindTableNode();
985 0 : if( pTNd )
986 0 : nIdx = pTNd->GetIndex();
987 : }
988 0 : break;
989 :
990 : case LTYPE_FLY:
991 : case LTYPE_OBJECT:
992 : {
993 : SwFlyFrm* pFly;
994 0 : SwCntntFrm *pCnt = pCNd->getLayoutFrm( rDoc.GetCurrentLayout() );
995 0 : if( pCnt && 0 != ( pFly = pCnt->FindFlyFrm() ) )
996 0 : nIdx = pFly->GetFmt()->GetCntnt().GetCntntIdx()->GetIndex();
997 : }
998 0 : break;
999 : case LTYPE_DRAW:
1000 0 : break;
1001 : }
1002 :
1003 0 : if( nIdx )
1004 : {
1005 : rDoc.InsertLabel( eType, sText, sSeparator, sNumberSeparator, bBefore,
1006 0 : nFldId, nIdx, sCharacterStyle, bCpyBrd );
1007 : }
1008 0 : }
1009 :
1010 : // #111827#
1011 0 : SwRewriter SwUndoInsertLabel::GetRewriter() const
1012 : {
1013 0 : SwRewriter aRewriter;
1014 :
1015 0 : String aTmpStr;
1016 :
1017 0 : aTmpStr += String(SW_RES(STR_START_QUOTE));
1018 : aTmpStr += ShortenString(sText, nUndoStringLength,
1019 0 : String(SW_RES(STR_LDOTS)));
1020 0 : aTmpStr += String(SW_RES(STR_END_QUOTE));
1021 :
1022 0 : aRewriter.AddRule(UndoArg1, aTmpStr);
1023 :
1024 0 : return aRewriter;
1025 : }
1026 :
1027 0 : void SwUndoInsertLabel::SetFlys( SwFrmFmt& rOldFly, SfxItemSet& rChgSet,
1028 : SwFrmFmt& rNewFly )
1029 : {
1030 0 : if( LTYPE_OBJECT == eType || LTYPE_DRAW == eType )
1031 : {
1032 0 : SwUndoFmtAttrHelper aTmp( rOldFly, false );
1033 0 : rOldFly.SetFmtAttr( rChgSet );
1034 0 : if ( aTmp.GetUndo() )
1035 : {
1036 0 : OBJECT.pUndoAttr = aTmp.ReleaseUndo();
1037 : }
1038 0 : OBJECT.pUndoFly = new SwUndoInsLayFmt( &rNewFly,0,0 );
1039 : }
1040 0 : }
1041 :
1042 0 : void SwUndoInsertLabel::SetDrawObj( sal_uInt8 nLId )
1043 : {
1044 0 : if( LTYPE_DRAW == eType )
1045 : {
1046 0 : nLayerId = nLId;
1047 : }
1048 0 : }
1049 :
1050 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|