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