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