xref: /trunk/main/sw/source/core/undo/unspnd.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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_sw.hxx"
30 
31 #include <UndoSplitMove.hxx>
32 
33 #include "doc.hxx"
34 #include "pam.hxx"
35 #include "swtable.hxx"
36 #include "ndtxt.hxx"
37 #include "swundo.hxx"           // fuer die UndoIds
38 #include <editeng/brkitem.hxx>
39 #include <fmtpdsc.hxx>
40 #include <frmfmt.hxx>
41 #include <UndoCore.hxx>
42 #include "rolbck.hxx"
43 #include "redline.hxx"
44 #include "docary.hxx"
45 #include <IShellCursorSupplier.hxx>
46 
47 
48 //------------------------------------------------------------------
49 
50 // SPLITNODE
51 
52 
53 SwUndoSplitNode::SwUndoSplitNode( SwDoc* pDoc, const SwPosition& rPos,
54                                     sal_Bool bChkTable )
55     : SwUndo( UNDO_SPLITNODE ), pHistory( 0 ), pRedlData( 0 ), nNode( rPos.nNode.GetIndex() ),
56         nCntnt( rPos.nContent.GetIndex() ),
57         bTblFlag( sal_False ), bChkTblStt( bChkTable )
58 {
59     SwTxtNode *const pTxtNd = rPos.nNode.GetNode().GetTxtNode();
60     OSL_ENSURE(pTxtNd, "SwUndoSplitNode: TextNode expected!");
61     if( pTxtNd->GetpSwpHints() )
62     {
63         pHistory = new SwHistory;
64         pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nNode, 0,
65                             pTxtNd->GetTxt().Len(), false );
66         if( !pHistory->Count() )
67             DELETEZ( pHistory );
68     }
69     // Redline beachten
70     if( pDoc->IsRedlineOn() )
71     {
72         pRedlData = new SwRedlineData( nsRedlineType_t::REDLINE_INSERT, pDoc->GetRedlineAuthor() );
73         SetRedlineMode( pDoc->GetRedlineMode() );
74     }
75 }
76 
77 SwUndoSplitNode::~SwUndoSplitNode()
78 {
79     delete pHistory;
80     delete pRedlData;
81 }
82 
83 void SwUndoSplitNode::UndoImpl(::sw::UndoRedoContext & rContext)
84 {
85     SwDoc *const pDoc = & rContext.GetDoc();
86     SwPaM & rPam( rContext.GetCursorSupplier().CreateNewShellCursor() );
87     rPam.DeleteMark();
88     if( bTblFlag )
89     {
90         // dann wurde direkt vor der akt. Tabelle ein TextNode eingefuegt.
91         SwNodeIndex& rIdx = rPam.GetPoint()->nNode;
92         rIdx = nNode;
93         SwTxtNode* pTNd;
94         SwNode* pCurrNd = pDoc->GetNodes()[ nNode + 1 ];
95         SwTableNode* pTblNd = pCurrNd->FindTableNode();
96         if( pCurrNd->IsCntntNode() && pTblNd &&
97             0 != ( pTNd = pDoc->GetNodes()[ pTblNd->GetIndex()-1 ]->GetTxtNode() ))
98         {
99             // verschiebe die BreakAttribute noch
100             SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt();
101             const SfxItemSet* pNdSet = pTNd->GetpSwAttrSet();
102             if( pNdSet )
103             {
104                 const SfxPoolItem *pItem;
105                 if( SFX_ITEM_SET == pNdSet->GetItemState( RES_PAGEDESC, sal_False,
106                     &pItem ) )
107                     pTableFmt->SetFmtAttr( *pItem );
108 
109                 if( SFX_ITEM_SET == pNdSet->GetItemState( RES_BREAK, sal_False,
110                      &pItem ) )
111                     pTableFmt->SetFmtAttr( *pItem );
112             }
113 
114             // dann loesche den wieder
115             SwNodeIndex aDelNd( *pTblNd, -1 );
116             rPam.GetPoint()->nContent.Assign( (SwCntntNode*)pCurrNd, 0 );
117             RemoveIdxRel( aDelNd.GetIndex(), *rPam.GetPoint() );
118             pDoc->GetNodes().Delete( aDelNd );
119         }
120     }
121     else
122     {
123         SwTxtNode * pTNd = pDoc->GetNodes()[ nNode ]->GetTxtNode();
124         if( pTNd )
125         {
126             rPam.GetPoint()->nNode = *pTNd;
127             rPam.GetPoint()->nContent.Assign( pTNd, pTNd->GetTxt().Len() );
128 
129             if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
130             {
131                 rPam.SetMark();
132                 rPam.GetMark()->nNode++;
133                 rPam.GetMark()->nContent.Assign( rPam.GetMark()->
134                                     nNode.GetNode().GetCntntNode(), 0 );
135                 pDoc->DeleteRedline( rPam, true, USHRT_MAX );
136                 rPam.DeleteMark();
137             }
138 
139             RemoveIdxRel( nNode+1, *rPam.GetPoint() );
140 
141             pTNd->JoinNext();
142             if( pHistory )
143             {
144                 rPam.GetPoint()->nContent = 0;
145                 rPam.SetMark();
146                 rPam.GetPoint()->nContent = pTNd->GetTxt().Len();
147 
148                 pDoc->RstTxtAttrs( rPam, sal_True );
149                 pHistory->TmpRollback( pDoc, 0, false );
150             }
151         }
152     }
153 
154     // setze noch den Cursor auf den Undo-Bereich
155     rPam.DeleteMark();
156     rPam.GetPoint()->nNode = nNode;
157     rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), nCntnt );
158 }
159 
160 void SwUndoSplitNode::RedoImpl(::sw::UndoRedoContext & rContext)
161 {
162     SwPaM & rPam( rContext.GetCursorSupplier().CreateNewShellCursor() );
163     rPam.GetPoint()->nNode = nNode;
164     SwTxtNode * pTNd = rPam.GetNode()->GetTxtNode();
165     OSL_ENSURE(pTNd, "SwUndoSplitNode::RedoImpl(): SwTxtNode expected");
166     if (pTNd)
167     {
168         rPam.GetPoint()->nContent.Assign( pTNd, nCntnt );
169 
170         SwDoc* pDoc = rPam.GetDoc();
171         pDoc->SplitNode( *rPam.GetPoint(), bChkTblStt );
172 
173         if( pHistory )
174             pHistory->SetTmpEnd( pHistory->Count() );
175 
176         if( ( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() )) ||
177             ( !( nsRedlineMode_t::REDLINE_IGNORE & GetRedlineMode() ) &&
178                 pDoc->GetRedlineTbl().Count() ))
179         {
180             rPam.SetMark();
181             if( rPam.Move( fnMoveBackward ))
182             {
183                 if( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
184                 {
185                     RedlineMode_t eOld = pDoc->GetRedlineMode();
186                     pDoc->SetRedlineMode_intern((RedlineMode_t)(eOld & ~nsRedlineMode_t::REDLINE_IGNORE));
187                     pDoc->AppendRedline( new SwRedline( *pRedlData, rPam ), true);
188                     pDoc->SetRedlineMode_intern( eOld );
189                 }
190                 else
191                     pDoc->SplitRedline( rPam );
192                 rPam.Exchange();
193             }
194             rPam.DeleteMark();
195         }
196     }
197 }
198 
199 void SwUndoSplitNode::RepeatImpl(::sw::RepeatContext & rContext)
200 {
201     rContext.GetDoc().SplitNode(
202         *rContext.GetRepeatPaM().GetPoint(), bChkTblStt );
203 }
204 
205