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