1*b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*b3f79822SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*b3f79822SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*b3f79822SAndrew Rist * distributed with this work for additional information
6*b3f79822SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*b3f79822SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*b3f79822SAndrew Rist * "License"); you may not use this file except in compliance
9*b3f79822SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11*b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13*b3f79822SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*b3f79822SAndrew Rist * software distributed under the License is distributed on an
15*b3f79822SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b3f79822SAndrew Rist * KIND, either express or implied. See the License for the
17*b3f79822SAndrew Rist * specific language governing permissions and limitations
18*b3f79822SAndrew Rist * under the License.
19cdf0e10cSrcweir *
20*b3f79822SAndrew Rist *************************************************************/
21*b3f79822SAndrew Rist
22*b3f79822SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir
28cdf0e10cSrcweir #include <tools/debug.hxx>
29cdf0e10cSrcweir #include <tools/shl.hxx> // SHL_CALC
30cdf0e10cSrcweir #include <tools/stack.hxx>
31cdf0e10cSrcweir #include <tools/rtti.hxx>
32cdf0e10cSrcweir #include <svl/zforlist.hxx>
33cdf0e10cSrcweir #include <svl/itemset.hxx>
34cdf0e10cSrcweir #include <svl/isethint.hxx>
35cdf0e10cSrcweir #include <svl/itempool.hxx>
36cdf0e10cSrcweir #include <sfx2/app.hxx>
37cdf0e10cSrcweir #include <unotools/useroptions.hxx>
38cdf0e10cSrcweir #include <sfx2/sfxsids.hrc>
39cdf0e10cSrcweir
40cdf0e10cSrcweir #include "cell.hxx"
41cdf0e10cSrcweir #include "document.hxx"
42cdf0e10cSrcweir #include "dociter.hxx"
43cdf0e10cSrcweir #include "global.hxx"
44cdf0e10cSrcweir #include "rechead.hxx"
45cdf0e10cSrcweir #include "scerrors.hxx"
46cdf0e10cSrcweir #include "scmod.hxx" // SC_MOD
47cdf0e10cSrcweir #include "inputopt.hxx" // GetExpandRefs
48cdf0e10cSrcweir #include "patattr.hxx"
49cdf0e10cSrcweir #include "hints.hxx"
50cdf0e10cSrcweir
51cdf0e10cSrcweir #include "globstr.hrc"
52cdf0e10cSrcweir
53cdf0e10cSrcweir #include <stack>
54cdf0e10cSrcweir
55cdf0e10cSrcweir #define SC_CHGTRACK_CXX
56cdf0e10cSrcweir #include "chgtrack.hxx"
57cdf0e10cSrcweir
58cdf0e10cSrcweir DECLARE_STACK( ScChangeActionStack, ScChangeAction* )
59cdf0e10cSrcweir
60cdf0e10cSrcweir const sal_uInt16 nMemPoolChangeActionCellListEntry = (0x2000 - 64) / sizeof(ScChangeActionCellListEntry);
61cdf0e10cSrcweir IMPL_FIXEDMEMPOOL_NEWDEL( ScChangeActionCellListEntry, nMemPoolChangeActionCellListEntry, nMemPoolChangeActionCellListEntry )
62cdf0e10cSrcweir
63cdf0e10cSrcweir const sal_uInt16 nMemPoolChangeActionLinkEntry = (0x8000 - 64) / sizeof(ScChangeActionLinkEntry);
IMPL_FIXEDMEMPOOL_NEWDEL(ScChangeActionLinkEntry,nMemPoolChangeActionLinkEntry,nMemPoolChangeActionLinkEntry)64cdf0e10cSrcweir IMPL_FIXEDMEMPOOL_NEWDEL( ScChangeActionLinkEntry, nMemPoolChangeActionLinkEntry, nMemPoolChangeActionLinkEntry )
65cdf0e10cSrcweir
66cdf0e10cSrcweir // loaded MSB > eigenes => inkompatibel
67cdf0e10cSrcweir #define SC_CHGTRACK_FILEFORMAT_FIRST 0x0001
68cdf0e10cSrcweir #define SC_CHGTRACK_FILEFORMAT 0x0001
69cdf0e10cSrcweir
70cdf0e10cSrcweir // --- ScChangeActionLinkEntry ---------------------------------------------
71cdf0e10cSrcweir
72cdf0e10cSrcweir #if DEBUG_CHANGETRACK
73cdf0e10cSrcweir String ScChangeActionLinkEntry::ToString() const
74cdf0e10cSrcweir {
75cdf0e10cSrcweir String aReturn;
76cdf0e10cSrcweir if ( pAction )
77cdf0e10cSrcweir {
78cdf0e10cSrcweir aReturn = String::CreateFromInt64( static_cast< sal_Int64 >( pAction->GetActionNumber() ) );
79cdf0e10cSrcweir }
80cdf0e10cSrcweir else if ( pLink && pLink->pAction )
81cdf0e10cSrcweir {
82cdf0e10cSrcweir aReturn = String::CreateFromAscii( "*" );
83cdf0e10cSrcweir aReturn += String::CreateFromInt64( static_cast< sal_Int64 >( pLink->pAction->GetActionNumber() ) );
84cdf0e10cSrcweir }
85cdf0e10cSrcweir else
86cdf0e10cSrcweir {
87cdf0e10cSrcweir aReturn = String::CreateFromAscii( "-" );
88cdf0e10cSrcweir }
89cdf0e10cSrcweir
90cdf0e10cSrcweir return aReturn;
91cdf0e10cSrcweir }
92cdf0e10cSrcweir #endif // DEBUG_CHANGETRACK
93cdf0e10cSrcweir
94cdf0e10cSrcweir // --- ScChangeAction ------------------------------------------------------
95cdf0e10cSrcweir
ScChangeAction(ScChangeActionType eTypeP,const ScRange & rRange)96cdf0e10cSrcweir ScChangeAction::ScChangeAction( ScChangeActionType eTypeP, const ScRange& rRange )
97cdf0e10cSrcweir :
98cdf0e10cSrcweir aBigRange( rRange ),
99cdf0e10cSrcweir pNext( NULL ),
100cdf0e10cSrcweir pPrev( NULL ),
101cdf0e10cSrcweir pLinkAny( NULL ),
102cdf0e10cSrcweir pLinkDeletedIn( NULL ),
103cdf0e10cSrcweir pLinkDeleted( NULL ),
104cdf0e10cSrcweir pLinkDependent( NULL ),
105cdf0e10cSrcweir nAction( 0 ),
106cdf0e10cSrcweir nRejectAction( 0 ),
107cdf0e10cSrcweir eType( eTypeP ),
108cdf0e10cSrcweir eState( SC_CAS_VIRGIN )
109cdf0e10cSrcweir {
110cdf0e10cSrcweir aDateTime.ConvertToUTC();
111cdf0e10cSrcweir }
112cdf0e10cSrcweir
ScChangeAction(ScChangeActionType eTypeP,const ScBigRange & rRange,const sal_uLong nTempAction,const sal_uLong nTempRejectAction,const ScChangeActionState eTempState,const DateTime & aTempDateTime,const String & aTempUser,const String & aTempComment)113cdf0e10cSrcweir ScChangeAction::ScChangeAction( ScChangeActionType eTypeP, const ScBigRange& rRange,
114cdf0e10cSrcweir const sal_uLong nTempAction, const sal_uLong nTempRejectAction,
115cdf0e10cSrcweir const ScChangeActionState eTempState, const DateTime& aTempDateTime,
116cdf0e10cSrcweir const String& aTempUser, const String& aTempComment)
117cdf0e10cSrcweir :
118cdf0e10cSrcweir aBigRange( rRange ),
119cdf0e10cSrcweir aDateTime( aTempDateTime ),
120cdf0e10cSrcweir aUser( aTempUser ),
121cdf0e10cSrcweir aComment( aTempComment ),
122cdf0e10cSrcweir pNext( NULL ),
123cdf0e10cSrcweir pPrev( NULL ),
124cdf0e10cSrcweir pLinkAny( NULL ),
125cdf0e10cSrcweir pLinkDeletedIn( NULL ),
126cdf0e10cSrcweir pLinkDeleted( NULL ),
127cdf0e10cSrcweir pLinkDependent( NULL ),
128cdf0e10cSrcweir nAction( nTempAction ),
129cdf0e10cSrcweir nRejectAction( nTempRejectAction ),
130cdf0e10cSrcweir eType( eTypeP ),
131cdf0e10cSrcweir eState( eTempState )
132cdf0e10cSrcweir {
133cdf0e10cSrcweir }
134cdf0e10cSrcweir
ScChangeAction(ScChangeActionType eTypeP,const ScBigRange & rRange,const sal_uLong nTempAction)135cdf0e10cSrcweir ScChangeAction::ScChangeAction( ScChangeActionType eTypeP, const ScBigRange& rRange,
136cdf0e10cSrcweir const sal_uLong nTempAction)
137cdf0e10cSrcweir :
138cdf0e10cSrcweir aBigRange( rRange ),
139cdf0e10cSrcweir pNext( NULL ),
140cdf0e10cSrcweir pPrev( NULL ),
141cdf0e10cSrcweir pLinkAny( NULL ),
142cdf0e10cSrcweir pLinkDeletedIn( NULL ),
143cdf0e10cSrcweir pLinkDeleted( NULL ),
144cdf0e10cSrcweir pLinkDependent( NULL ),
145cdf0e10cSrcweir nAction( nTempAction ),
146cdf0e10cSrcweir nRejectAction( 0 ),
147cdf0e10cSrcweir eType( eTypeP ),
148cdf0e10cSrcweir eState( SC_CAS_VIRGIN )
149cdf0e10cSrcweir {
150cdf0e10cSrcweir aDateTime.ConvertToUTC();
151cdf0e10cSrcweir }
152cdf0e10cSrcweir
153cdf0e10cSrcweir
~ScChangeAction()154cdf0e10cSrcweir ScChangeAction::~ScChangeAction()
155cdf0e10cSrcweir {
156cdf0e10cSrcweir RemoveAllLinks();
157cdf0e10cSrcweir }
158cdf0e10cSrcweir
159cdf0e10cSrcweir
IsVisible() const160cdf0e10cSrcweir sal_Bool ScChangeAction::IsVisible() const
161cdf0e10cSrcweir {
162cdf0e10cSrcweir //! sequence order of execution is significant
163cdf0e10cSrcweir if ( IsRejected() || GetType() == SC_CAT_DELETE_TABS || IsDeletedIn() )
164cdf0e10cSrcweir return sal_False;
165cdf0e10cSrcweir if ( GetType() == SC_CAT_CONTENT )
166cdf0e10cSrcweir return ((ScChangeActionContent*)this)->IsTopContent();
167cdf0e10cSrcweir return sal_True;
168cdf0e10cSrcweir }
169cdf0e10cSrcweir
170cdf0e10cSrcweir
IsTouchable() const171cdf0e10cSrcweir sal_Bool ScChangeAction::IsTouchable() const
172cdf0e10cSrcweir {
173cdf0e10cSrcweir //! sequence order of execution is significant
174cdf0e10cSrcweir if ( IsRejected() || GetType() == SC_CAT_REJECT || IsDeletedIn() )
175cdf0e10cSrcweir return sal_False;
176cdf0e10cSrcweir // content may reject and be touchable if on top
177cdf0e10cSrcweir if ( GetType() == SC_CAT_CONTENT )
178cdf0e10cSrcweir return ((ScChangeActionContent*)this)->IsTopContent();
179cdf0e10cSrcweir if ( IsRejecting() )
180cdf0e10cSrcweir return sal_False;
181cdf0e10cSrcweir return sal_True;
182cdf0e10cSrcweir }
183cdf0e10cSrcweir
184cdf0e10cSrcweir
IsClickable() const185cdf0e10cSrcweir sal_Bool ScChangeAction::IsClickable() const
186cdf0e10cSrcweir {
187cdf0e10cSrcweir //! sequence order of execution is significant
188cdf0e10cSrcweir if ( !IsVirgin() )
189cdf0e10cSrcweir return sal_False;
190cdf0e10cSrcweir if ( IsDeletedIn() )
191cdf0e10cSrcweir return sal_False;
192cdf0e10cSrcweir if ( GetType() == SC_CAT_CONTENT )
193cdf0e10cSrcweir {
194cdf0e10cSrcweir ScChangeActionContentCellType eCCT =
195cdf0e10cSrcweir ScChangeActionContent::GetContentCellType(
196cdf0e10cSrcweir ((ScChangeActionContent*)this)->GetNewCell() );
197cdf0e10cSrcweir if ( eCCT == SC_CACCT_MATREF )
198cdf0e10cSrcweir return sal_False;
199cdf0e10cSrcweir if ( eCCT == SC_CACCT_MATORG )
200cdf0e10cSrcweir { // no Accept-Select if one of the references is in a deleted col/row
201cdf0e10cSrcweir const ScChangeActionLinkEntry* pL =
202cdf0e10cSrcweir ((ScChangeActionContent*)this)->GetFirstDependentEntry();
203cdf0e10cSrcweir while ( pL )
204cdf0e10cSrcweir {
205cdf0e10cSrcweir ScChangeAction* p = (ScChangeAction*) pL->GetAction();
206cdf0e10cSrcweir if ( p && p->IsDeletedIn() )
207cdf0e10cSrcweir return sal_False;
208cdf0e10cSrcweir pL = pL->GetNext();
209cdf0e10cSrcweir }
210cdf0e10cSrcweir }
211cdf0e10cSrcweir return sal_True; // for Select() a content doesn't have to be touchable
212cdf0e10cSrcweir }
213cdf0e10cSrcweir return IsTouchable(); // Accept()/Reject() only on touchables
214cdf0e10cSrcweir }
215cdf0e10cSrcweir
216cdf0e10cSrcweir
IsRejectable() const217cdf0e10cSrcweir sal_Bool ScChangeAction::IsRejectable() const
218cdf0e10cSrcweir {
219cdf0e10cSrcweir //! sequence order of execution is significant
220cdf0e10cSrcweir if ( !IsClickable() )
221cdf0e10cSrcweir return sal_False;
222cdf0e10cSrcweir if ( GetType() == SC_CAT_CONTENT )
223cdf0e10cSrcweir {
224cdf0e10cSrcweir if ( ((ScChangeActionContent*)this)->IsOldMatrixReference() )
225cdf0e10cSrcweir return sal_False;
226cdf0e10cSrcweir ScChangeActionContent* pNextContent =
227cdf0e10cSrcweir ((ScChangeActionContent*)this)->GetNextContent();
228cdf0e10cSrcweir if ( pNextContent == NULL )
229cdf0e10cSrcweir return sal_True; // *this is TopContent
230cdf0e10cSrcweir return pNextContent->IsRejected(); // *this is next rejectable
231cdf0e10cSrcweir }
232cdf0e10cSrcweir return IsTouchable();
233cdf0e10cSrcweir }
234cdf0e10cSrcweir
235cdf0e10cSrcweir
IsInternalRejectable() const236cdf0e10cSrcweir sal_Bool ScChangeAction::IsInternalRejectable() const
237cdf0e10cSrcweir {
238cdf0e10cSrcweir //! sequence order of execution is significant
239cdf0e10cSrcweir if ( !IsVirgin() )
240cdf0e10cSrcweir return sal_False;
241cdf0e10cSrcweir if ( IsDeletedIn() )
242cdf0e10cSrcweir return sal_False;
243cdf0e10cSrcweir if ( GetType() == SC_CAT_CONTENT )
244cdf0e10cSrcweir {
245cdf0e10cSrcweir ScChangeActionContent* pNextContent =
246cdf0e10cSrcweir ((ScChangeActionContent*)this)->GetNextContent();
247cdf0e10cSrcweir if ( pNextContent == NULL )
248cdf0e10cSrcweir return sal_True; // *this is TopContent
249cdf0e10cSrcweir return pNextContent->IsRejected(); // *this is next rejectable
250cdf0e10cSrcweir }
251cdf0e10cSrcweir return IsTouchable();
252cdf0e10cSrcweir }
253cdf0e10cSrcweir
254cdf0e10cSrcweir
IsDialogRoot() const255cdf0e10cSrcweir sal_Bool ScChangeAction::IsDialogRoot() const
256cdf0e10cSrcweir {
257cdf0e10cSrcweir return IsInternalRejectable(); // only rejectables in root
258cdf0e10cSrcweir }
259cdf0e10cSrcweir
260cdf0e10cSrcweir
IsDialogParent() const261cdf0e10cSrcweir sal_Bool ScChangeAction::IsDialogParent() const
262cdf0e10cSrcweir {
263cdf0e10cSrcweir //! sequence order of execution is significant
264cdf0e10cSrcweir if ( GetType() == SC_CAT_CONTENT )
265cdf0e10cSrcweir {
266cdf0e10cSrcweir if ( !IsDialogRoot() )
267cdf0e10cSrcweir return sal_False;
268cdf0e10cSrcweir if ( ((ScChangeActionContent*)this)->IsMatrixOrigin() && HasDependent() )
269cdf0e10cSrcweir return sal_True;
270cdf0e10cSrcweir ScChangeActionContent* pPrevContent =
271cdf0e10cSrcweir ((ScChangeActionContent*)this)->GetPrevContent();
272cdf0e10cSrcweir return pPrevContent && pPrevContent->IsVirgin();
273cdf0e10cSrcweir }
274cdf0e10cSrcweir if ( HasDependent() )
275cdf0e10cSrcweir return IsDeleteType() ? sal_True : !IsDeletedIn();
276cdf0e10cSrcweir if ( HasDeleted() )
277cdf0e10cSrcweir {
278cdf0e10cSrcweir if ( IsDeleteType() )
279cdf0e10cSrcweir {
280cdf0e10cSrcweir if ( IsDialogRoot() )
281cdf0e10cSrcweir return sal_True;
282cdf0e10cSrcweir ScChangeActionLinkEntry* pL = pLinkDeleted;
283cdf0e10cSrcweir while ( pL )
284cdf0e10cSrcweir {
285cdf0e10cSrcweir ScChangeAction* p = pL->GetAction();
286cdf0e10cSrcweir if ( p && p->GetType() != eType )
287cdf0e10cSrcweir return sal_True;
288cdf0e10cSrcweir pL = pL->GetNext();
289cdf0e10cSrcweir }
290cdf0e10cSrcweir }
291cdf0e10cSrcweir else
292cdf0e10cSrcweir return sal_True;
293cdf0e10cSrcweir }
294cdf0e10cSrcweir return sal_False;
295cdf0e10cSrcweir }
296cdf0e10cSrcweir
297cdf0e10cSrcweir
IsMasterDelete() const298cdf0e10cSrcweir sal_Bool ScChangeAction::IsMasterDelete() const
299cdf0e10cSrcweir {
300cdf0e10cSrcweir if ( !IsDeleteType() )
301cdf0e10cSrcweir return sal_False;
302cdf0e10cSrcweir ScChangeActionDel* pDel = (ScChangeActionDel*) this;
303cdf0e10cSrcweir return pDel->IsMultiDelete() && (pDel->IsTopDelete() || pDel->IsRejectable());
304cdf0e10cSrcweir }
305cdf0e10cSrcweir
306cdf0e10cSrcweir
RemoveAllLinks()307cdf0e10cSrcweir void ScChangeAction::RemoveAllLinks()
308cdf0e10cSrcweir {
309cdf0e10cSrcweir RemoveAllAnyLinks();
310cdf0e10cSrcweir RemoveAllDeletedIn();
311cdf0e10cSrcweir RemoveAllDeleted();
312cdf0e10cSrcweir RemoveAllDependent();
313cdf0e10cSrcweir }
314cdf0e10cSrcweir
315cdf0e10cSrcweir
RemoveAllAnyLinks()316cdf0e10cSrcweir void ScChangeAction::RemoveAllAnyLinks()
317cdf0e10cSrcweir {
318cdf0e10cSrcweir while ( pLinkAny )
319cdf0e10cSrcweir delete pLinkAny; // rueckt sich selbst hoch
320cdf0e10cSrcweir }
321cdf0e10cSrcweir
322cdf0e10cSrcweir
RemoveDeletedIn(const ScChangeAction * p)323cdf0e10cSrcweir sal_Bool ScChangeAction::RemoveDeletedIn( const ScChangeAction* p )
324cdf0e10cSrcweir {
325cdf0e10cSrcweir sal_Bool bRemoved = sal_False;
326cdf0e10cSrcweir ScChangeActionLinkEntry* pL = GetDeletedIn();
327cdf0e10cSrcweir while ( pL )
328cdf0e10cSrcweir {
329cdf0e10cSrcweir ScChangeActionLinkEntry* pNextLink = pL->GetNext();
330cdf0e10cSrcweir if ( pL->GetAction() == p )
331cdf0e10cSrcweir {
332cdf0e10cSrcweir delete pL;
333cdf0e10cSrcweir bRemoved = sal_True;
334cdf0e10cSrcweir }
335cdf0e10cSrcweir pL = pNextLink;
336cdf0e10cSrcweir }
337cdf0e10cSrcweir return bRemoved;
338cdf0e10cSrcweir }
339cdf0e10cSrcweir
340cdf0e10cSrcweir
IsDeletedIn(const ScChangeAction * p) const341cdf0e10cSrcweir sal_Bool ScChangeAction::IsDeletedIn( const ScChangeAction* p ) const
342cdf0e10cSrcweir {
343cdf0e10cSrcweir ScChangeActionLinkEntry* pL = GetDeletedIn();
344cdf0e10cSrcweir while ( pL )
345cdf0e10cSrcweir {
346cdf0e10cSrcweir if ( pL->GetAction() == p )
347cdf0e10cSrcweir return sal_True;
348cdf0e10cSrcweir pL = pL->GetNext();
349cdf0e10cSrcweir }
350cdf0e10cSrcweir return sal_False;
351cdf0e10cSrcweir }
352cdf0e10cSrcweir
353cdf0e10cSrcweir
RemoveAllDeletedIn()354cdf0e10cSrcweir void ScChangeAction::RemoveAllDeletedIn()
355cdf0e10cSrcweir {
356cdf0e10cSrcweir //! nicht vom evtl. TopContent sondern wirklich dieser
357cdf0e10cSrcweir while ( pLinkDeletedIn )
358cdf0e10cSrcweir delete pLinkDeletedIn; // rueckt sich selbst hoch
359cdf0e10cSrcweir }
360cdf0e10cSrcweir
361cdf0e10cSrcweir
IsDeletedInDelType(ScChangeActionType eDelType) const362cdf0e10cSrcweir sal_Bool ScChangeAction::IsDeletedInDelType( ScChangeActionType eDelType ) const
363cdf0e10cSrcweir {
364cdf0e10cSrcweir ScChangeAction* p;
365cdf0e10cSrcweir ScChangeActionLinkEntry* pL = GetDeletedIn();
366cdf0e10cSrcweir if ( pL )
367cdf0e10cSrcweir {
368cdf0e10cSrcweir // InsertType fuer MergePrepare/MergeOwn
369cdf0e10cSrcweir ScChangeActionType eInsType;
370cdf0e10cSrcweir switch ( eDelType )
371cdf0e10cSrcweir {
372cdf0e10cSrcweir case SC_CAT_DELETE_COLS :
373cdf0e10cSrcweir eInsType = SC_CAT_INSERT_COLS;
374cdf0e10cSrcweir break;
375cdf0e10cSrcweir case SC_CAT_DELETE_ROWS :
376cdf0e10cSrcweir eInsType = SC_CAT_INSERT_ROWS;
377cdf0e10cSrcweir break;
378cdf0e10cSrcweir case SC_CAT_DELETE_TABS :
379cdf0e10cSrcweir eInsType = SC_CAT_INSERT_TABS;
380cdf0e10cSrcweir break;
381cdf0e10cSrcweir default:
382cdf0e10cSrcweir eInsType = SC_CAT_NONE;
383cdf0e10cSrcweir }
384cdf0e10cSrcweir while ( pL )
385cdf0e10cSrcweir {
386cdf0e10cSrcweir if ( (p = pL->GetAction()) != NULL &&
387cdf0e10cSrcweir (p->GetType() == eDelType || p->GetType() == eInsType) )
388cdf0e10cSrcweir return sal_True;
389cdf0e10cSrcweir pL = pL->GetNext();
390cdf0e10cSrcweir }
391cdf0e10cSrcweir }
392cdf0e10cSrcweir return sal_False;
393cdf0e10cSrcweir }
394cdf0e10cSrcweir
395cdf0e10cSrcweir
SetDeletedIn(ScChangeAction * p)396cdf0e10cSrcweir void ScChangeAction::SetDeletedIn( ScChangeAction* p )
397cdf0e10cSrcweir {
398cdf0e10cSrcweir ScChangeActionLinkEntry* pLink1 = AddDeletedIn( p );
399cdf0e10cSrcweir ScChangeActionLinkEntry* pLink2;
400cdf0e10cSrcweir if ( GetType() == SC_CAT_CONTENT )
401cdf0e10cSrcweir pLink2 = p->AddDeleted( ((ScChangeActionContent*)this)->GetTopContent() );
402cdf0e10cSrcweir else
403cdf0e10cSrcweir pLink2 = p->AddDeleted( this );
404cdf0e10cSrcweir pLink1->SetLink( pLink2 );
405cdf0e10cSrcweir }
406cdf0e10cSrcweir
407cdf0e10cSrcweir
RemoveAllDeleted()408cdf0e10cSrcweir void ScChangeAction::RemoveAllDeleted()
409cdf0e10cSrcweir {
410cdf0e10cSrcweir while ( pLinkDeleted )
411cdf0e10cSrcweir delete pLinkDeleted; // rueckt sich selbst hoch
412cdf0e10cSrcweir }
413cdf0e10cSrcweir
414cdf0e10cSrcweir
RemoveAllDependent()415cdf0e10cSrcweir void ScChangeAction::RemoveAllDependent()
416cdf0e10cSrcweir {
417cdf0e10cSrcweir while ( pLinkDependent )
418cdf0e10cSrcweir delete pLinkDependent; // rueckt sich selbst hoch
419cdf0e10cSrcweir }
420cdf0e10cSrcweir
421cdf0e10cSrcweir
GetDateTime() const422cdf0e10cSrcweir DateTime ScChangeAction::GetDateTime() const
423cdf0e10cSrcweir {
424cdf0e10cSrcweir DateTime aDT( aDateTime );
425cdf0e10cSrcweir aDT.ConvertToLocalTime();
426cdf0e10cSrcweir return aDT;
427cdf0e10cSrcweir }
428cdf0e10cSrcweir
429cdf0e10cSrcweir
UpdateReference(const ScChangeTrack *,UpdateRefMode eMode,const ScBigRange & rRange,sal_Int32 nDx,sal_Int32 nDy,sal_Int32 nDz)430cdf0e10cSrcweir void ScChangeAction::UpdateReference( const ScChangeTrack* /* pTrack */,
431cdf0e10cSrcweir UpdateRefMode eMode, const ScBigRange& rRange,
432cdf0e10cSrcweir sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz )
433cdf0e10cSrcweir {
434cdf0e10cSrcweir ScRefUpdate::Update( eMode, rRange, nDx, nDy, nDz, GetBigRange() );
435cdf0e10cSrcweir }
436cdf0e10cSrcweir
437cdf0e10cSrcweir
GetDescription(String & rStr,ScDocument *,sal_Bool,bool bWarning) const438cdf0e10cSrcweir void ScChangeAction::GetDescription( String& rStr, ScDocument* /* pDoc */,
439cdf0e10cSrcweir sal_Bool /* bSplitRange */, bool bWarning ) const
440cdf0e10cSrcweir {
441cdf0e10cSrcweir if ( IsRejecting() && bWarning )
442cdf0e10cSrcweir {
443cdf0e10cSrcweir // #112261# Add comment if rejection may have resulted in references
444cdf0e10cSrcweir // not properly restored in formulas. See specification at
445cdf0e10cSrcweir // http://specs.openoffice.org/calc/ease-of-use/redlining_comment.sxw
446cdf0e10cSrcweir if (GetType() == SC_CAT_MOVE)
447cdf0e10cSrcweir {
448cdf0e10cSrcweir rStr += ScGlobal::GetRscString(
449cdf0e10cSrcweir STR_CHANGED_MOVE_REJECTION_WARNING);
450cdf0e10cSrcweir rStr += ' ';
451cdf0e10cSrcweir }
452cdf0e10cSrcweir else if (IsInsertType())
453cdf0e10cSrcweir {
454cdf0e10cSrcweir rStr += ScGlobal::GetRscString(
455cdf0e10cSrcweir STR_CHANGED_DELETE_REJECTION_WARNING);
456cdf0e10cSrcweir rStr += ' ';
457cdf0e10cSrcweir }
458cdf0e10cSrcweir else
459cdf0e10cSrcweir {
460cdf0e10cSrcweir const ScChangeTrack* pCT = GetChangeTrack();
461cdf0e10cSrcweir if (pCT)
462cdf0e10cSrcweir {
463cdf0e10cSrcweir ScChangeAction* pReject = pCT->GetActionOrGenerated(
464cdf0e10cSrcweir GetRejectAction());
465cdf0e10cSrcweir if (pReject)
466cdf0e10cSrcweir {
467cdf0e10cSrcweir if (pReject->GetType() == SC_CAT_MOVE)
468cdf0e10cSrcweir {
469cdf0e10cSrcweir rStr += ScGlobal::GetRscString(
470cdf0e10cSrcweir STR_CHANGED_MOVE_REJECTION_WARNING);
471cdf0e10cSrcweir rStr += ' ';
472cdf0e10cSrcweir }
473cdf0e10cSrcweir else if (pReject->IsDeleteType())
474cdf0e10cSrcweir {
475cdf0e10cSrcweir rStr += ScGlobal::GetRscString(
476cdf0e10cSrcweir STR_CHANGED_DELETE_REJECTION_WARNING);
477cdf0e10cSrcweir rStr += ' ';
478cdf0e10cSrcweir }
479cdf0e10cSrcweir else if (pReject->HasDependent())
480cdf0e10cSrcweir {
481cdf0e10cSrcweir ScChangeActionTable aTable;
482cdf0e10cSrcweir pCT->GetDependents( pReject, aTable, sal_False, sal_True );
483cdf0e10cSrcweir for ( const ScChangeAction* p = aTable.First(); p;
484cdf0e10cSrcweir p = aTable.Next() )
485cdf0e10cSrcweir {
486cdf0e10cSrcweir if (p->GetType() == SC_CAT_MOVE)
487cdf0e10cSrcweir {
488cdf0e10cSrcweir rStr += ScGlobal::GetRscString(
489cdf0e10cSrcweir STR_CHANGED_MOVE_REJECTION_WARNING);
490cdf0e10cSrcweir rStr += ' ';
491cdf0e10cSrcweir break; // for
492cdf0e10cSrcweir }
493cdf0e10cSrcweir else if (pReject->IsDeleteType())
494cdf0e10cSrcweir {
495cdf0e10cSrcweir rStr += ScGlobal::GetRscString(
496cdf0e10cSrcweir STR_CHANGED_DELETE_REJECTION_WARNING);
497cdf0e10cSrcweir rStr += ' ';
498cdf0e10cSrcweir break; // for
499cdf0e10cSrcweir }
500cdf0e10cSrcweir }
501cdf0e10cSrcweir }
502cdf0e10cSrcweir }
503cdf0e10cSrcweir }
504cdf0e10cSrcweir }
505cdf0e10cSrcweir }
506cdf0e10cSrcweir }
507cdf0e10cSrcweir
508cdf0e10cSrcweir
GetRefString(const ScBigRange & rRange,ScDocument * pDoc,sal_Bool bFlag3D) const509cdf0e10cSrcweir String ScChangeAction::GetRefString( const ScBigRange& rRange,
510cdf0e10cSrcweir ScDocument* pDoc, sal_Bool bFlag3D ) const
511cdf0e10cSrcweir {
512cdf0e10cSrcweir String aStr;
513cdf0e10cSrcweir sal_uInt16 nFlags = ( rRange.IsValid( pDoc ) ? SCA_VALID : 0 );
514cdf0e10cSrcweir if ( !nFlags )
515cdf0e10cSrcweir aStr = ScGlobal::GetRscString( STR_NOREF_STR );
516cdf0e10cSrcweir else
517cdf0e10cSrcweir {
518cdf0e10cSrcweir ScRange aTmpRange( rRange.MakeRange() );
519cdf0e10cSrcweir switch ( GetType() )
520cdf0e10cSrcweir {
521cdf0e10cSrcweir case SC_CAT_INSERT_COLS :
522cdf0e10cSrcweir case SC_CAT_DELETE_COLS :
523cdf0e10cSrcweir if ( bFlag3D )
524cdf0e10cSrcweir {
525cdf0e10cSrcweir pDoc->GetName( aTmpRange.aStart.Tab(), aStr );
526cdf0e10cSrcweir aStr += '.';
527cdf0e10cSrcweir }
528cdf0e10cSrcweir aStr += ::ScColToAlpha( aTmpRange.aStart.Col() );
529cdf0e10cSrcweir aStr += ':';
530cdf0e10cSrcweir aStr += ::ScColToAlpha( aTmpRange.aEnd.Col() );
531cdf0e10cSrcweir break;
532cdf0e10cSrcweir case SC_CAT_INSERT_ROWS :
533cdf0e10cSrcweir case SC_CAT_DELETE_ROWS :
534cdf0e10cSrcweir if ( bFlag3D )
535cdf0e10cSrcweir {
536cdf0e10cSrcweir pDoc->GetName( aTmpRange.aStart.Tab(), aStr );
537cdf0e10cSrcweir aStr += '.';
538cdf0e10cSrcweir }
539cdf0e10cSrcweir aStr += String::CreateFromInt32( aTmpRange.aStart.Row() + 1 );
540cdf0e10cSrcweir aStr += ':';
541cdf0e10cSrcweir aStr += String::CreateFromInt32( aTmpRange.aEnd.Row() + 1 );
542cdf0e10cSrcweir break;
543cdf0e10cSrcweir default:
544cdf0e10cSrcweir if ( bFlag3D || GetType() == SC_CAT_INSERT_TABS )
545cdf0e10cSrcweir nFlags |= SCA_TAB_3D;
546cdf0e10cSrcweir aTmpRange.Format( aStr, nFlags, pDoc, pDoc->GetAddressConvention() );
547cdf0e10cSrcweir }
548cdf0e10cSrcweir if ( (bFlag3D && IsDeleteType()) || IsDeletedIn() )
549cdf0e10cSrcweir {
550cdf0e10cSrcweir aStr.Insert( '(', 0 );
551cdf0e10cSrcweir aStr += ')';
552cdf0e10cSrcweir }
553cdf0e10cSrcweir }
554cdf0e10cSrcweir return aStr;
555cdf0e10cSrcweir }
556cdf0e10cSrcweir
557cdf0e10cSrcweir
GetRefString(String & rStr,ScDocument * pDoc,sal_Bool bFlag3D) const558cdf0e10cSrcweir void ScChangeAction::GetRefString( String& rStr, ScDocument* pDoc,
559cdf0e10cSrcweir sal_Bool bFlag3D ) const
560cdf0e10cSrcweir {
561cdf0e10cSrcweir rStr = GetRefString( GetBigRange(), pDoc, bFlag3D );
562cdf0e10cSrcweir }
563cdf0e10cSrcweir
564cdf0e10cSrcweir
Accept()565cdf0e10cSrcweir void ScChangeAction::Accept()
566cdf0e10cSrcweir {
567cdf0e10cSrcweir if ( IsVirgin() )
568cdf0e10cSrcweir {
569cdf0e10cSrcweir SetState( SC_CAS_ACCEPTED );
570cdf0e10cSrcweir DeleteCellEntries();
571cdf0e10cSrcweir }
572cdf0e10cSrcweir }
573cdf0e10cSrcweir
574cdf0e10cSrcweir
SetRejected()575cdf0e10cSrcweir void ScChangeAction::SetRejected()
576cdf0e10cSrcweir {
577cdf0e10cSrcweir if ( IsVirgin() )
578cdf0e10cSrcweir {
579cdf0e10cSrcweir SetState( SC_CAS_REJECTED );
580cdf0e10cSrcweir RemoveAllLinks();
581cdf0e10cSrcweir DeleteCellEntries();
582cdf0e10cSrcweir }
583cdf0e10cSrcweir }
584cdf0e10cSrcweir
585cdf0e10cSrcweir
RejectRestoreContents(ScChangeTrack * pTrack,SCsCOL nDx,SCsROW nDy)586cdf0e10cSrcweir void ScChangeAction::RejectRestoreContents( ScChangeTrack* pTrack,
587cdf0e10cSrcweir SCsCOL nDx, SCsROW nDy )
588cdf0e10cSrcweir {
589cdf0e10cSrcweir // Liste der Contents aufbauen
590cdf0e10cSrcweir ScChangeActionCellListEntry* pListContents = NULL;
591cdf0e10cSrcweir for ( ScChangeActionLinkEntry* pL = pLinkDeleted; pL; pL = pL->GetNext() )
592cdf0e10cSrcweir {
593cdf0e10cSrcweir ScChangeAction* p = pL->GetAction();
594cdf0e10cSrcweir if ( p && p->GetType() == SC_CAT_CONTENT )
595cdf0e10cSrcweir {
596cdf0e10cSrcweir ScChangeActionCellListEntry* pE = new ScChangeActionCellListEntry(
597cdf0e10cSrcweir (ScChangeActionContent*) p, pListContents );
598cdf0e10cSrcweir pListContents = pE;
599cdf0e10cSrcweir }
600cdf0e10cSrcweir }
601cdf0e10cSrcweir SetState( SC_CAS_REJECTED ); // vor UpdateReference fuer Move
602cdf0e10cSrcweir pTrack->UpdateReference( this, sal_True ); // LinkDeleted freigeben
603cdf0e10cSrcweir DBG_ASSERT( !pLinkDeleted, "ScChangeAction::RejectRestoreContents: pLinkDeleted != NULL" );
604cdf0e10cSrcweir // Liste der Contents abarbeiten und loeschen
605cdf0e10cSrcweir ScDocument* pDoc = pTrack->GetDocument();
606cdf0e10cSrcweir ScChangeActionCellListEntry* pE = pListContents;
607cdf0e10cSrcweir while ( pE )
608cdf0e10cSrcweir {
609cdf0e10cSrcweir if ( !pE->pContent->IsDeletedIn() &&
610cdf0e10cSrcweir pE->pContent->GetBigRange().aStart.IsValid( pDoc ) )
611cdf0e10cSrcweir pE->pContent->PutNewValueToDoc( pDoc, nDx, nDy );
612cdf0e10cSrcweir ScChangeActionCellListEntry* pNextEntry;
613cdf0e10cSrcweir pNextEntry = pE->pNext;
614cdf0e10cSrcweir delete pE;
615cdf0e10cSrcweir pE = pNextEntry;
616cdf0e10cSrcweir }
617cdf0e10cSrcweir DeleteCellEntries(); // weg mit den generierten
618cdf0e10cSrcweir }
619cdf0e10cSrcweir
620cdf0e10cSrcweir
SetDeletedInThis(sal_uLong nActionNumber,const ScChangeTrack * pTrack)621cdf0e10cSrcweir void ScChangeAction::SetDeletedInThis( sal_uLong nActionNumber,
622cdf0e10cSrcweir const ScChangeTrack* pTrack )
623cdf0e10cSrcweir {
624cdf0e10cSrcweir if ( nActionNumber )
625cdf0e10cSrcweir {
626cdf0e10cSrcweir ScChangeAction* pAct = pTrack->GetActionOrGenerated( nActionNumber );
627cdf0e10cSrcweir DBG_ASSERT( pAct, "ScChangeAction::SetDeletedInThis: missing Action" );
628cdf0e10cSrcweir if ( pAct )
629cdf0e10cSrcweir pAct->SetDeletedIn( this );
630cdf0e10cSrcweir }
631cdf0e10cSrcweir }
632cdf0e10cSrcweir
633cdf0e10cSrcweir
AddDependent(sal_uLong nActionNumber,const ScChangeTrack * pTrack)634cdf0e10cSrcweir void ScChangeAction::AddDependent( sal_uLong nActionNumber,
635cdf0e10cSrcweir const ScChangeTrack* pTrack )
636cdf0e10cSrcweir {
637cdf0e10cSrcweir if ( nActionNumber )
638cdf0e10cSrcweir {
639cdf0e10cSrcweir ScChangeAction* pAct = pTrack->GetActionOrGenerated( nActionNumber );
640cdf0e10cSrcweir DBG_ASSERT( pAct, "ScChangeAction::AddDependent: missing Action" );
641cdf0e10cSrcweir if ( pAct )
642cdf0e10cSrcweir {
643cdf0e10cSrcweir ScChangeActionLinkEntry* pLink = AddDependent( pAct );
644cdf0e10cSrcweir pAct->AddLink( this, pLink );
645cdf0e10cSrcweir }
646cdf0e10cSrcweir }
647cdf0e10cSrcweir }
648cdf0e10cSrcweir
649cdf0e10cSrcweir
650cdf0e10cSrcweir #if DEBUG_CHANGETRACK
ToString(ScDocument * pDoc) const651cdf0e10cSrcweir String ScChangeAction::ToString( ScDocument* pDoc ) const
652cdf0e10cSrcweir {
653cdf0e10cSrcweir String aReturn;
654cdf0e10cSrcweir
655cdf0e10cSrcweir String aNumber = String::CreateFromInt64( static_cast< sal_Int64 >( GetActionNumber() ) );
656cdf0e10cSrcweir
657cdf0e10cSrcweir String aActionState;
658cdf0e10cSrcweir ScChangeActionState eActionState = GetState();
659cdf0e10cSrcweir switch ( eActionState )
660cdf0e10cSrcweir {
661cdf0e10cSrcweir case SC_CAS_VIRGIN:
662cdf0e10cSrcweir {
663cdf0e10cSrcweir aActionState = String::CreateFromAscii( " " );
664cdf0e10cSrcweir }
665cdf0e10cSrcweir break;
666cdf0e10cSrcweir case SC_CAS_ACCEPTED:
667cdf0e10cSrcweir {
668cdf0e10cSrcweir aActionState = String::CreateFromAscii( "+" );
669cdf0e10cSrcweir }
670cdf0e10cSrcweir break;
671cdf0e10cSrcweir case SC_CAS_REJECTED:
672cdf0e10cSrcweir {
673cdf0e10cSrcweir aActionState = String::CreateFromAscii( "-" );
674cdf0e10cSrcweir }
675cdf0e10cSrcweir break;
676cdf0e10cSrcweir }
677cdf0e10cSrcweir
678cdf0e10cSrcweir String aRejectAction;
679cdf0e10cSrcweir if ( IsRejecting() )
680cdf0e10cSrcweir {
681cdf0e10cSrcweir aRejectAction += 'r';
682cdf0e10cSrcweir aRejectAction += String::CreateFromInt64( static_cast< sal_Int64 >( GetRejectAction() ) );
683cdf0e10cSrcweir }
684cdf0e10cSrcweir
685cdf0e10cSrcweir String aReference;
686cdf0e10cSrcweir GetRefString( aReference, pDoc, sal_True );
687cdf0e10cSrcweir
688cdf0e10cSrcweir String aAuthor = GetUser();
689cdf0e10cSrcweir
690cdf0e10cSrcweir DateTime aDT = GetDateTime();
691cdf0e10cSrcweir String aDate = ScGlobal::pLocaleData->getDate( aDT );
692cdf0e10cSrcweir aDate += ' ';
693cdf0e10cSrcweir aDate += ScGlobal::pLocaleData->getTime( aDT, sal_False, sal_False );
694cdf0e10cSrcweir
695cdf0e10cSrcweir String aDescription;
696cdf0e10cSrcweir GetDescription( aDescription, pDoc );
697cdf0e10cSrcweir
698cdf0e10cSrcweir String aLinkAny;
699cdf0e10cSrcweir const ScChangeActionLinkEntry* pLinkA = pLinkAny;
700cdf0e10cSrcweir while ( pLinkA )
701cdf0e10cSrcweir {
702cdf0e10cSrcweir if ( !aLinkAny.Len() )
703cdf0e10cSrcweir {
704cdf0e10cSrcweir aLinkAny = String::CreateFromAscii( "(Any:" );
705cdf0e10cSrcweir }
706cdf0e10cSrcweir aLinkAny += String::CreateFromAscii( " ->" );
707cdf0e10cSrcweir aLinkAny += pLinkA->ToString();
708cdf0e10cSrcweir pLinkA = pLinkA->GetNext();
709cdf0e10cSrcweir }
710cdf0e10cSrcweir if ( aLinkAny.Len() )
711cdf0e10cSrcweir {
712cdf0e10cSrcweir aLinkAny += ')';
713cdf0e10cSrcweir }
714cdf0e10cSrcweir
715cdf0e10cSrcweir String aLinkDeletedIn;
716cdf0e10cSrcweir const ScChangeActionLinkEntry* pLinkDI = pLinkDeletedIn;
717cdf0e10cSrcweir while ( pLinkDI )
718cdf0e10cSrcweir {
719cdf0e10cSrcweir if ( !aLinkDeletedIn.Len() )
720cdf0e10cSrcweir {
721cdf0e10cSrcweir aLinkDeletedIn = String::CreateFromAscii( "(DeletedIn:" );
722cdf0e10cSrcweir }
723cdf0e10cSrcweir aLinkDeletedIn += String::CreateFromAscii( " ->" );
724cdf0e10cSrcweir aLinkDeletedIn += pLinkDI->ToString();
725cdf0e10cSrcweir pLinkDI = pLinkDI->GetNext();
726cdf0e10cSrcweir }
727cdf0e10cSrcweir if ( aLinkDeletedIn.Len() )
728cdf0e10cSrcweir {
729cdf0e10cSrcweir aLinkDeletedIn += ')';
730cdf0e10cSrcweir }
731cdf0e10cSrcweir
732cdf0e10cSrcweir String aLinkDeleted;
733cdf0e10cSrcweir const ScChangeActionLinkEntry* pLinkD = pLinkDeleted;
734cdf0e10cSrcweir while ( pLinkD )
735cdf0e10cSrcweir {
736cdf0e10cSrcweir if ( !aLinkDeleted.Len() )
737cdf0e10cSrcweir {
738cdf0e10cSrcweir aLinkDeleted = String::CreateFromAscii( "(Deleted:" );
739cdf0e10cSrcweir }
740cdf0e10cSrcweir aLinkDeleted += String::CreateFromAscii( " ->" );
741cdf0e10cSrcweir aLinkDeleted += pLinkD->ToString();
742cdf0e10cSrcweir pLinkD = pLinkD->GetNext();
743cdf0e10cSrcweir }
744cdf0e10cSrcweir if ( aLinkDeleted.Len() )
745cdf0e10cSrcweir {
746cdf0e10cSrcweir aLinkDeleted += ')';
747cdf0e10cSrcweir }
748cdf0e10cSrcweir
749cdf0e10cSrcweir String aLinkDependent;
750cdf0e10cSrcweir const ScChangeActionLinkEntry* pLinkDp = pLinkDependent;
751cdf0e10cSrcweir while ( pLinkDp )
752cdf0e10cSrcweir {
753cdf0e10cSrcweir if ( !aLinkDependent.Len() )
754cdf0e10cSrcweir {
755cdf0e10cSrcweir aLinkDependent = String::CreateFromAscii( "(Dependent:" );
756cdf0e10cSrcweir }
757cdf0e10cSrcweir aLinkDependent += String::CreateFromAscii( " ->" );
758cdf0e10cSrcweir aLinkDependent += pLinkDp->ToString();
759cdf0e10cSrcweir pLinkDp = pLinkDp->GetNext();
760cdf0e10cSrcweir }
761cdf0e10cSrcweir if ( aLinkDependent.Len() )
762cdf0e10cSrcweir {
763cdf0e10cSrcweir aLinkDependent += ')';
764cdf0e10cSrcweir }
765cdf0e10cSrcweir
766cdf0e10cSrcweir aReturn += aNumber;
767cdf0e10cSrcweir aReturn += aActionState;
768cdf0e10cSrcweir aReturn += aRejectAction;
769cdf0e10cSrcweir aReturn += String::CreateFromAscii( ": " );
770cdf0e10cSrcweir aReturn += aReference;
771cdf0e10cSrcweir aReturn += ' ';
772cdf0e10cSrcweir aReturn += aAuthor;
773cdf0e10cSrcweir aReturn += ' ';
774cdf0e10cSrcweir aReturn += aDate;
775cdf0e10cSrcweir aReturn += ' ';
776cdf0e10cSrcweir aReturn += aDescription;
777cdf0e10cSrcweir aReturn += ' ';
778cdf0e10cSrcweir aReturn += aLinkAny;
779cdf0e10cSrcweir aReturn += ' ';
780cdf0e10cSrcweir aReturn += aLinkDeletedIn;
781cdf0e10cSrcweir aReturn += ' ';
782cdf0e10cSrcweir aReturn += aLinkDeleted;
783cdf0e10cSrcweir aReturn += ' ';
784cdf0e10cSrcweir aReturn += aLinkDependent;
785cdf0e10cSrcweir
786cdf0e10cSrcweir return aReturn;
787cdf0e10cSrcweir }
788cdf0e10cSrcweir #endif // DEBUG_CHANGETRACK
789cdf0e10cSrcweir
790cdf0e10cSrcweir
791cdf0e10cSrcweir // --- ScChangeActionIns ---------------------------------------------------
792cdf0e10cSrcweir
ScChangeActionIns(const ScRange & rRange)793cdf0e10cSrcweir ScChangeActionIns::ScChangeActionIns( const ScRange& rRange )
794cdf0e10cSrcweir : ScChangeAction( SC_CAT_NONE, rRange )
795cdf0e10cSrcweir {
796cdf0e10cSrcweir if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL )
797cdf0e10cSrcweir {
798cdf0e10cSrcweir aBigRange.aStart.SetCol( nInt32Min );
799cdf0e10cSrcweir aBigRange.aEnd.SetCol( nInt32Max );
800cdf0e10cSrcweir if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW )
801cdf0e10cSrcweir {
802cdf0e10cSrcweir SetType( SC_CAT_INSERT_TABS );
803cdf0e10cSrcweir aBigRange.aStart.SetRow( nInt32Min );
804cdf0e10cSrcweir aBigRange.aEnd.SetRow( nInt32Max );
805cdf0e10cSrcweir }
806cdf0e10cSrcweir else
807cdf0e10cSrcweir SetType( SC_CAT_INSERT_ROWS );
808cdf0e10cSrcweir }
809cdf0e10cSrcweir else if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW )
810cdf0e10cSrcweir {
811cdf0e10cSrcweir SetType( SC_CAT_INSERT_COLS );
812cdf0e10cSrcweir aBigRange.aStart.SetRow( nInt32Min );
813cdf0e10cSrcweir aBigRange.aEnd.SetRow( nInt32Max );
814cdf0e10cSrcweir }
815cdf0e10cSrcweir else
816cdf0e10cSrcweir {
817cdf0e10cSrcweir DBG_ERROR( "ScChangeActionIns: Block not supported!" );
818cdf0e10cSrcweir }
819cdf0e10cSrcweir }
820cdf0e10cSrcweir
821cdf0e10cSrcweir
ScChangeActionIns(const sal_uLong nActionNumber,const ScChangeActionState eStateP,const sal_uLong nRejectingNumber,const ScBigRange & aBigRangeP,const String & aUserP,const DateTime & aDateTimeP,const String & sComment,const ScChangeActionType eTypeP)822cdf0e10cSrcweir ScChangeActionIns::ScChangeActionIns(const sal_uLong nActionNumber, const ScChangeActionState eStateP, const sal_uLong nRejectingNumber,
823cdf0e10cSrcweir const ScBigRange& aBigRangeP, const String& aUserP, const DateTime& aDateTimeP, const String& sComment,
824cdf0e10cSrcweir const ScChangeActionType eTypeP)
825cdf0e10cSrcweir :
826cdf0e10cSrcweir ScChangeAction(eTypeP, aBigRangeP, nActionNumber, nRejectingNumber, eStateP, aDateTimeP, aUserP, sComment)
827cdf0e10cSrcweir {
828cdf0e10cSrcweir }
829cdf0e10cSrcweir
~ScChangeActionIns()830cdf0e10cSrcweir ScChangeActionIns::~ScChangeActionIns()
831cdf0e10cSrcweir {
832cdf0e10cSrcweir }
833cdf0e10cSrcweir
834cdf0e10cSrcweir
GetDescription(String & rStr,ScDocument * pDoc,sal_Bool bSplitRange,bool bWarning) const835cdf0e10cSrcweir void ScChangeActionIns::GetDescription( String& rStr, ScDocument* pDoc,
836cdf0e10cSrcweir sal_Bool bSplitRange, bool bWarning ) const
837cdf0e10cSrcweir {
838cdf0e10cSrcweir ScChangeAction::GetDescription( rStr, pDoc, bSplitRange, bWarning );
839cdf0e10cSrcweir
840cdf0e10cSrcweir sal_uInt16 nWhatId;
841cdf0e10cSrcweir switch ( GetType() )
842cdf0e10cSrcweir {
843cdf0e10cSrcweir case SC_CAT_INSERT_COLS :
844cdf0e10cSrcweir nWhatId = STR_COLUMN;
845cdf0e10cSrcweir break;
846cdf0e10cSrcweir case SC_CAT_INSERT_ROWS :
847cdf0e10cSrcweir nWhatId = STR_ROW;
848cdf0e10cSrcweir break;
849cdf0e10cSrcweir default:
850cdf0e10cSrcweir nWhatId = STR_AREA;
851cdf0e10cSrcweir }
852cdf0e10cSrcweir
853cdf0e10cSrcweir String aRsc( ScGlobal::GetRscString( STR_CHANGED_INSERT ) );
854cdf0e10cSrcweir xub_StrLen nPos = aRsc.SearchAscii( "#1" );
855cdf0e10cSrcweir rStr += aRsc.Copy( 0, nPos );
856cdf0e10cSrcweir rStr += ScGlobal::GetRscString( nWhatId );
857cdf0e10cSrcweir rStr += ' ';
858cdf0e10cSrcweir rStr += GetRefString( GetBigRange(), pDoc );
859cdf0e10cSrcweir rStr += aRsc.Copy( nPos+2 );
860cdf0e10cSrcweir }
861cdf0e10cSrcweir
862cdf0e10cSrcweir
Reject(ScDocument * pDoc)863cdf0e10cSrcweir sal_Bool ScChangeActionIns::Reject( ScDocument* pDoc )
864cdf0e10cSrcweir {
865cdf0e10cSrcweir if ( !aBigRange.IsValid( pDoc ) )
866cdf0e10cSrcweir return sal_False;
867cdf0e10cSrcweir
868cdf0e10cSrcweir ScRange aRange( aBigRange.MakeRange() );
869cdf0e10cSrcweir if ( !pDoc->IsBlockEditable( aRange.aStart.Tab(), aRange.aStart.Col(),
870cdf0e10cSrcweir aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row() ) )
871cdf0e10cSrcweir return sal_False;
872cdf0e10cSrcweir
873cdf0e10cSrcweir switch ( GetType() )
874cdf0e10cSrcweir {
875cdf0e10cSrcweir case SC_CAT_INSERT_COLS :
876cdf0e10cSrcweir pDoc->DeleteCol( aRange );
877cdf0e10cSrcweir break;
878cdf0e10cSrcweir case SC_CAT_INSERT_ROWS :
879cdf0e10cSrcweir pDoc->DeleteRow( aRange );
880cdf0e10cSrcweir break;
881cdf0e10cSrcweir case SC_CAT_INSERT_TABS :
882cdf0e10cSrcweir pDoc->DeleteTab( aRange.aStart.Tab() );
883cdf0e10cSrcweir break;
884cdf0e10cSrcweir default:
885cdf0e10cSrcweir {
886cdf0e10cSrcweir // added to avoid warnings
887cdf0e10cSrcweir }
888cdf0e10cSrcweir }
889cdf0e10cSrcweir SetState( SC_CAS_REJECTED );
890cdf0e10cSrcweir RemoveAllLinks();
891cdf0e10cSrcweir return sal_True;
892cdf0e10cSrcweir }
893cdf0e10cSrcweir
894cdf0e10cSrcweir
895cdf0e10cSrcweir // --- ScChangeActionDel ---------------------------------------------------
896cdf0e10cSrcweir
ScChangeActionDel(const ScRange & rRange,SCsCOL nDxP,SCsROW nDyP,ScChangeTrack * pTrackP)897cdf0e10cSrcweir ScChangeActionDel::ScChangeActionDel( const ScRange& rRange,
898cdf0e10cSrcweir SCsCOL nDxP, SCsROW nDyP, ScChangeTrack* pTrackP )
899cdf0e10cSrcweir :
900cdf0e10cSrcweir ScChangeAction( SC_CAT_NONE, rRange ),
901cdf0e10cSrcweir pTrack( pTrackP ),
902cdf0e10cSrcweir pFirstCell( NULL ),
903cdf0e10cSrcweir pCutOff( NULL ),
904cdf0e10cSrcweir nCutOff( 0 ),
905cdf0e10cSrcweir pLinkMove( NULL ),
906cdf0e10cSrcweir nDx( nDxP ),
907cdf0e10cSrcweir nDy( nDyP )
908cdf0e10cSrcweir {
909cdf0e10cSrcweir if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL )
910cdf0e10cSrcweir {
911cdf0e10cSrcweir aBigRange.aStart.SetCol( nInt32Min );
912cdf0e10cSrcweir aBigRange.aEnd.SetCol( nInt32Max );
913cdf0e10cSrcweir if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW )
914cdf0e10cSrcweir {
915cdf0e10cSrcweir SetType( SC_CAT_DELETE_TABS );
916cdf0e10cSrcweir aBigRange.aStart.SetRow( nInt32Min );
917cdf0e10cSrcweir aBigRange.aEnd.SetRow( nInt32Max );
918cdf0e10cSrcweir }
919cdf0e10cSrcweir else
920cdf0e10cSrcweir SetType( SC_CAT_DELETE_ROWS );
921cdf0e10cSrcweir }
922cdf0e10cSrcweir else if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW )
923cdf0e10cSrcweir {
924cdf0e10cSrcweir SetType( SC_CAT_DELETE_COLS );
925cdf0e10cSrcweir aBigRange.aStart.SetRow( nInt32Min );
926cdf0e10cSrcweir aBigRange.aEnd.SetRow( nInt32Max );
927cdf0e10cSrcweir }
928cdf0e10cSrcweir else
929cdf0e10cSrcweir {
930cdf0e10cSrcweir DBG_ERROR( "ScChangeActionDel: Block not supported!" );
931cdf0e10cSrcweir }
932cdf0e10cSrcweir }
933cdf0e10cSrcweir
934cdf0e10cSrcweir
ScChangeActionDel(const sal_uLong nActionNumber,const ScChangeActionState eStateP,const sal_uLong nRejectingNumber,const ScBigRange & aBigRangeP,const String & aUserP,const DateTime & aDateTimeP,const String & sComment,const ScChangeActionType eTypeP,const SCsCOLROW nD,ScChangeTrack * pTrackP)935cdf0e10cSrcweir ScChangeActionDel::ScChangeActionDel(const sal_uLong nActionNumber, const ScChangeActionState eStateP, const sal_uLong nRejectingNumber,
936cdf0e10cSrcweir const ScBigRange& aBigRangeP, const String& aUserP, const DateTime& aDateTimeP, const String &sComment,
937cdf0e10cSrcweir const ScChangeActionType eTypeP, const SCsCOLROW nD, ScChangeTrack* pTrackP) // wich of nDx and nDy is set is depend on the type
938cdf0e10cSrcweir :
939cdf0e10cSrcweir ScChangeAction(eTypeP, aBigRangeP, nActionNumber, nRejectingNumber, eStateP, aDateTimeP, aUserP, sComment),
940cdf0e10cSrcweir pTrack( pTrackP ),
941cdf0e10cSrcweir pFirstCell( NULL ),
942cdf0e10cSrcweir pCutOff( NULL ),
943cdf0e10cSrcweir nCutOff( 0 ),
944cdf0e10cSrcweir pLinkMove( NULL ),
945cdf0e10cSrcweir nDx( 0 ),
946cdf0e10cSrcweir nDy( 0 )
947cdf0e10cSrcweir {
948cdf0e10cSrcweir if (eType == SC_CAT_DELETE_COLS)
949cdf0e10cSrcweir nDx = static_cast<SCsCOL>(nD);
950cdf0e10cSrcweir else if (eType == SC_CAT_DELETE_ROWS)
951cdf0e10cSrcweir nDy = static_cast<SCsROW>(nD);
952cdf0e10cSrcweir }
953cdf0e10cSrcweir
~ScChangeActionDel()954cdf0e10cSrcweir ScChangeActionDel::~ScChangeActionDel()
955cdf0e10cSrcweir {
956cdf0e10cSrcweir DeleteCellEntries();
957cdf0e10cSrcweir while ( pLinkMove )
958cdf0e10cSrcweir delete pLinkMove;
959cdf0e10cSrcweir }
960cdf0e10cSrcweir
AddContent(ScChangeActionContent * pContent)961cdf0e10cSrcweir void ScChangeActionDel::AddContent( ScChangeActionContent* pContent )
962cdf0e10cSrcweir {
963cdf0e10cSrcweir ScChangeActionCellListEntry* pE = new ScChangeActionCellListEntry(
964cdf0e10cSrcweir pContent, pFirstCell );
965cdf0e10cSrcweir pFirstCell = pE;
966cdf0e10cSrcweir }
967cdf0e10cSrcweir
968cdf0e10cSrcweir
DeleteCellEntries()969cdf0e10cSrcweir void ScChangeActionDel::DeleteCellEntries()
970cdf0e10cSrcweir {
971cdf0e10cSrcweir pTrack->DeleteCellEntries( pFirstCell, this );
972cdf0e10cSrcweir }
973cdf0e10cSrcweir
974cdf0e10cSrcweir
IsBaseDelete() const975cdf0e10cSrcweir sal_Bool ScChangeActionDel::IsBaseDelete() const
976cdf0e10cSrcweir {
977cdf0e10cSrcweir return !GetDx() && !GetDy();
978cdf0e10cSrcweir }
979cdf0e10cSrcweir
980cdf0e10cSrcweir
IsTopDelete() const981cdf0e10cSrcweir sal_Bool ScChangeActionDel::IsTopDelete() const
982cdf0e10cSrcweir {
983cdf0e10cSrcweir const ScChangeAction* p = GetNext();
984cdf0e10cSrcweir if ( !p || p->GetType() != GetType() )
985cdf0e10cSrcweir return sal_True;
986cdf0e10cSrcweir return ((ScChangeActionDel*)p)->IsBaseDelete();
987cdf0e10cSrcweir }
988cdf0e10cSrcweir
989cdf0e10cSrcweir
IsMultiDelete() const990cdf0e10cSrcweir sal_Bool ScChangeActionDel::IsMultiDelete() const
991cdf0e10cSrcweir {
992cdf0e10cSrcweir if ( GetDx() || GetDy() )
993cdf0e10cSrcweir return sal_True;
994cdf0e10cSrcweir const ScChangeAction* p = GetNext();
995cdf0e10cSrcweir if ( !p || p->GetType() != GetType() )
996cdf0e10cSrcweir return sal_False;
997cdf0e10cSrcweir const ScChangeActionDel* pDel = (const ScChangeActionDel*) p;
998cdf0e10cSrcweir if ( (pDel->GetDx() > GetDx() || pDel->GetDy() > GetDy()) &&
999cdf0e10cSrcweir pDel->GetBigRange() == aBigRange )
1000cdf0e10cSrcweir return sal_True;
1001cdf0e10cSrcweir return sal_False;
1002cdf0e10cSrcweir }
1003cdf0e10cSrcweir
1004cdf0e10cSrcweir
IsTabDeleteCol() const1005cdf0e10cSrcweir sal_Bool ScChangeActionDel::IsTabDeleteCol() const
1006cdf0e10cSrcweir {
1007cdf0e10cSrcweir if ( GetType() != SC_CAT_DELETE_COLS )
1008cdf0e10cSrcweir return sal_False;
1009cdf0e10cSrcweir const ScChangeAction* p = this;
1010cdf0e10cSrcweir while ( p && p->GetType() == SC_CAT_DELETE_COLS &&
1011cdf0e10cSrcweir !((const ScChangeActionDel*)p)->IsTopDelete() )
1012cdf0e10cSrcweir p = p->GetNext();
1013cdf0e10cSrcweir return p && p->GetType() == SC_CAT_DELETE_TABS;
1014cdf0e10cSrcweir }
1015cdf0e10cSrcweir
1016cdf0e10cSrcweir
UpdateReference(const ScChangeTrack *,UpdateRefMode eMode,const ScBigRange & rRange,sal_Int32 nDxP,sal_Int32 nDyP,sal_Int32 nDz)1017cdf0e10cSrcweir void ScChangeActionDel::UpdateReference( const ScChangeTrack* /* pTrack */,
1018cdf0e10cSrcweir UpdateRefMode eMode, const ScBigRange& rRange,
1019cdf0e10cSrcweir sal_Int32 nDxP, sal_Int32 nDyP, sal_Int32 nDz )
1020cdf0e10cSrcweir {
1021cdf0e10cSrcweir ScRefUpdate::Update( eMode, rRange, nDxP, nDyP, nDz, GetBigRange() );
1022cdf0e10cSrcweir if ( !IsDeletedIn() )
1023cdf0e10cSrcweir return ;
1024cdf0e10cSrcweir // evtl. in "druntergerutschten" anpassen
1025cdf0e10cSrcweir for ( ScChangeActionLinkEntry* pL = pLinkDeleted; pL; pL = pL->GetNext() )
1026cdf0e10cSrcweir {
1027cdf0e10cSrcweir ScChangeAction* p = pL->GetAction();
1028cdf0e10cSrcweir if ( p && p->GetType() == SC_CAT_CONTENT &&
1029cdf0e10cSrcweir !GetBigRange().In( p->GetBigRange() ) )
1030cdf0e10cSrcweir {
1031cdf0e10cSrcweir switch ( GetType() )
1032cdf0e10cSrcweir {
1033cdf0e10cSrcweir case SC_CAT_DELETE_COLS :
1034cdf0e10cSrcweir p->GetBigRange().aStart.SetCol( GetBigRange().aStart.Col() );
1035cdf0e10cSrcweir p->GetBigRange().aEnd.SetCol( GetBigRange().aStart.Col() );
1036cdf0e10cSrcweir break;
1037cdf0e10cSrcweir case SC_CAT_DELETE_ROWS :
1038cdf0e10cSrcweir p->GetBigRange().aStart.SetRow( GetBigRange().aStart.Row() );
1039cdf0e10cSrcweir p->GetBigRange().aEnd.SetRow( GetBigRange().aStart.Row() );
1040cdf0e10cSrcweir break;
1041cdf0e10cSrcweir case SC_CAT_DELETE_TABS :
1042cdf0e10cSrcweir p->GetBigRange().aStart.SetTab( GetBigRange().aStart.Tab() );
1043cdf0e10cSrcweir p->GetBigRange().aEnd.SetTab( GetBigRange().aStart.Tab() );
1044cdf0e10cSrcweir break;
1045cdf0e10cSrcweir default:
1046cdf0e10cSrcweir {
1047cdf0e10cSrcweir // added to avoid warnings
1048cdf0e10cSrcweir }
1049cdf0e10cSrcweir }
1050cdf0e10cSrcweir }
1051cdf0e10cSrcweir }
1052cdf0e10cSrcweir }
1053cdf0e10cSrcweir
1054cdf0e10cSrcweir
GetOverAllRange() const1055cdf0e10cSrcweir ScBigRange ScChangeActionDel::GetOverAllRange() const
1056cdf0e10cSrcweir {
1057cdf0e10cSrcweir ScBigRange aTmpRange( GetBigRange() );
1058cdf0e10cSrcweir aTmpRange.aEnd.SetCol( aTmpRange.aEnd.Col() + GetDx() );
1059cdf0e10cSrcweir aTmpRange.aEnd.SetRow( aTmpRange.aEnd.Row() + GetDy() );
1060cdf0e10cSrcweir return aTmpRange;
1061cdf0e10cSrcweir }
1062cdf0e10cSrcweir
1063cdf0e10cSrcweir
GetDescription(String & rStr,ScDocument * pDoc,sal_Bool bSplitRange,bool bWarning) const1064cdf0e10cSrcweir void ScChangeActionDel::GetDescription( String& rStr, ScDocument* pDoc,
1065cdf0e10cSrcweir sal_Bool bSplitRange, bool bWarning ) const
1066cdf0e10cSrcweir {
1067cdf0e10cSrcweir ScChangeAction::GetDescription( rStr, pDoc, bSplitRange, bWarning );
1068cdf0e10cSrcweir
1069cdf0e10cSrcweir sal_uInt16 nWhatId;
1070cdf0e10cSrcweir switch ( GetType() )
1071cdf0e10cSrcweir {
1072cdf0e10cSrcweir case SC_CAT_DELETE_COLS :
1073cdf0e10cSrcweir nWhatId = STR_COLUMN;
1074cdf0e10cSrcweir break;
1075cdf0e10cSrcweir case SC_CAT_DELETE_ROWS :
1076cdf0e10cSrcweir nWhatId = STR_ROW;
1077cdf0e10cSrcweir break;
1078cdf0e10cSrcweir default:
1079cdf0e10cSrcweir nWhatId = STR_AREA;
1080cdf0e10cSrcweir }
1081cdf0e10cSrcweir
1082cdf0e10cSrcweir ScBigRange aTmpRange( GetBigRange() );
1083cdf0e10cSrcweir if ( !IsRejected() )
1084cdf0e10cSrcweir {
1085cdf0e10cSrcweir if ( bSplitRange )
1086cdf0e10cSrcweir {
1087cdf0e10cSrcweir aTmpRange.aStart.SetCol( aTmpRange.aStart.Col() + GetDx() );
1088cdf0e10cSrcweir aTmpRange.aStart.SetRow( aTmpRange.aStart.Row() + GetDy() );
1089cdf0e10cSrcweir }
1090cdf0e10cSrcweir aTmpRange.aEnd.SetCol( aTmpRange.aEnd.Col() + GetDx() );
1091cdf0e10cSrcweir aTmpRange.aEnd.SetRow( aTmpRange.aEnd.Row() + GetDy() );
1092cdf0e10cSrcweir }
1093cdf0e10cSrcweir
1094cdf0e10cSrcweir String aRsc( ScGlobal::GetRscString( STR_CHANGED_DELETE ) );
1095cdf0e10cSrcweir xub_StrLen nPos = aRsc.SearchAscii( "#1" );
1096cdf0e10cSrcweir rStr += aRsc.Copy( 0, nPos );
1097cdf0e10cSrcweir rStr += ScGlobal::GetRscString( nWhatId );
1098cdf0e10cSrcweir rStr += ' ';
1099cdf0e10cSrcweir rStr += GetRefString( aTmpRange, pDoc );
1100cdf0e10cSrcweir rStr += aRsc.Copy( nPos+2 );
1101cdf0e10cSrcweir }
1102cdf0e10cSrcweir
1103cdf0e10cSrcweir
Reject(ScDocument * pDoc)1104cdf0e10cSrcweir sal_Bool ScChangeActionDel::Reject( ScDocument* pDoc )
1105cdf0e10cSrcweir {
1106cdf0e10cSrcweir if ( !aBigRange.IsValid( pDoc ) && GetType() != SC_CAT_DELETE_TABS )
1107cdf0e10cSrcweir return sal_False;
1108cdf0e10cSrcweir
1109cdf0e10cSrcweir sal_Bool bOk = sal_True;
1110cdf0e10cSrcweir
1111cdf0e10cSrcweir if ( IsTopDelete() )
1112cdf0e10cSrcweir { // den kompletten Bereich in einem Rutsch restaurieren
1113cdf0e10cSrcweir ScBigRange aTmpRange( GetOverAllRange() );
1114cdf0e10cSrcweir if ( !aTmpRange.IsValid( pDoc ) )
1115cdf0e10cSrcweir {
1116cdf0e10cSrcweir if ( GetType() == SC_CAT_DELETE_TABS )
1117cdf0e10cSrcweir { // wird Tab angehaengt?
1118cdf0e10cSrcweir if ( aTmpRange.aStart.Tab() > pDoc->GetMaxTableNumber() )
1119cdf0e10cSrcweir bOk = sal_False;
1120cdf0e10cSrcweir }
1121cdf0e10cSrcweir else
1122cdf0e10cSrcweir bOk = sal_False;
1123cdf0e10cSrcweir }
1124cdf0e10cSrcweir if ( bOk )
1125cdf0e10cSrcweir {
1126cdf0e10cSrcweir ScRange aRange( aTmpRange.MakeRange() );
1127cdf0e10cSrcweir // InDelete... fuer Formel UpdateReference in Document
1128cdf0e10cSrcweir pTrack->SetInDeleteRange( aRange );
1129cdf0e10cSrcweir pTrack->SetInDeleteTop( sal_True );
1130cdf0e10cSrcweir pTrack->SetInDeleteUndo( sal_True );
1131cdf0e10cSrcweir pTrack->SetInDelete( sal_True );
1132cdf0e10cSrcweir switch ( GetType() )
1133cdf0e10cSrcweir {
1134cdf0e10cSrcweir case SC_CAT_DELETE_COLS :
1135cdf0e10cSrcweir if ( !(aRange.aStart.Col() == 0 && aRange.aEnd.Col() == MAXCOL) )
1136cdf0e10cSrcweir { // nur wenn nicht TabDelete
1137cdf0e10cSrcweir if ( ( bOk = pDoc->CanInsertCol( aRange ) ) != sal_False )
1138cdf0e10cSrcweir bOk = pDoc->InsertCol( aRange );
1139cdf0e10cSrcweir }
1140cdf0e10cSrcweir break;
1141cdf0e10cSrcweir case SC_CAT_DELETE_ROWS :
1142cdf0e10cSrcweir if ( ( bOk = pDoc->CanInsertRow( aRange ) ) != sal_False )
1143cdf0e10cSrcweir bOk = pDoc->InsertRow( aRange );
1144cdf0e10cSrcweir break;
1145cdf0e10cSrcweir case SC_CAT_DELETE_TABS :
1146cdf0e10cSrcweir {
1147cdf0e10cSrcweir //2do: Tabellennamen merken?
1148cdf0e10cSrcweir String aName;
1149cdf0e10cSrcweir pDoc->CreateValidTabName( aName );
1150cdf0e10cSrcweir if ( ( bOk = pDoc->ValidNewTabName( aName ) ) != sal_False )
1151cdf0e10cSrcweir bOk = pDoc->InsertTab( aRange.aStart.Tab(), aName );
1152cdf0e10cSrcweir }
1153cdf0e10cSrcweir break;
1154cdf0e10cSrcweir default:
1155cdf0e10cSrcweir {
1156cdf0e10cSrcweir // added to avoid warnings
1157cdf0e10cSrcweir }
1158cdf0e10cSrcweir }
1159cdf0e10cSrcweir pTrack->SetInDelete( sal_False );
1160cdf0e10cSrcweir pTrack->SetInDeleteUndo( sal_False );
1161cdf0e10cSrcweir }
1162cdf0e10cSrcweir if ( !bOk )
1163cdf0e10cSrcweir {
1164cdf0e10cSrcweir pTrack->SetInDeleteTop( sal_False );
1165cdf0e10cSrcweir return sal_False;
1166cdf0e10cSrcweir }
1167cdf0e10cSrcweir // InDeleteTop fuer UpdateReference-Undo behalten
1168cdf0e10cSrcweir }
1169cdf0e10cSrcweir
1170cdf0e10cSrcweir // setzt rejected und ruft UpdateReference-Undo und DeleteCellEntries
1171cdf0e10cSrcweir RejectRestoreContents( pTrack, GetDx(), GetDy() );
1172cdf0e10cSrcweir
1173cdf0e10cSrcweir pTrack->SetInDeleteTop( sal_False );
1174cdf0e10cSrcweir RemoveAllLinks();
1175cdf0e10cSrcweir return sal_True;
1176cdf0e10cSrcweir }
1177cdf0e10cSrcweir
1178cdf0e10cSrcweir
UndoCutOffMoves()1179cdf0e10cSrcweir void ScChangeActionDel::UndoCutOffMoves()
1180cdf0e10cSrcweir { // abgeschnittene Moves wiederherstellen, Entries/Links deleten
1181cdf0e10cSrcweir while ( pLinkMove )
1182cdf0e10cSrcweir {
1183cdf0e10cSrcweir ScChangeActionMove* pMove = pLinkMove->GetMove();
1184cdf0e10cSrcweir short nFrom = pLinkMove->GetCutOffFrom();
1185cdf0e10cSrcweir short nTo = pLinkMove->GetCutOffTo();
1186cdf0e10cSrcweir switch ( GetType() )
1187cdf0e10cSrcweir {
1188cdf0e10cSrcweir case SC_CAT_DELETE_COLS :
1189cdf0e10cSrcweir if ( nFrom > 0 )
1190cdf0e10cSrcweir pMove->GetFromRange().aStart.IncCol( -nFrom );
1191cdf0e10cSrcweir else if ( nFrom < 0 )
1192cdf0e10cSrcweir pMove->GetFromRange().aEnd.IncCol( -nFrom );
1193cdf0e10cSrcweir if ( nTo > 0 )
1194cdf0e10cSrcweir pMove->GetBigRange().aStart.IncCol( -nTo );
1195cdf0e10cSrcweir else if ( nTo < 0 )
1196cdf0e10cSrcweir pMove->GetBigRange().aEnd.IncCol( -nTo );
1197cdf0e10cSrcweir break;
1198cdf0e10cSrcweir case SC_CAT_DELETE_ROWS :
1199cdf0e10cSrcweir if ( nFrom > 0 )
1200cdf0e10cSrcweir pMove->GetFromRange().aStart.IncRow( -nFrom );
1201cdf0e10cSrcweir else if ( nFrom < 0 )
1202cdf0e10cSrcweir pMove->GetFromRange().aEnd.IncRow( -nFrom );
1203cdf0e10cSrcweir if ( nTo > 0 )
1204cdf0e10cSrcweir pMove->GetBigRange().aStart.IncRow( -nTo );
1205cdf0e10cSrcweir else if ( nTo < 0 )
1206cdf0e10cSrcweir pMove->GetBigRange().aEnd.IncRow( -nTo );
1207cdf0e10cSrcweir break;
1208cdf0e10cSrcweir case SC_CAT_DELETE_TABS :
1209cdf0e10cSrcweir if ( nFrom > 0 )
1210cdf0e10cSrcweir pMove->GetFromRange().aStart.IncTab( -nFrom );
1211cdf0e10cSrcweir else if ( nFrom < 0 )
1212cdf0e10cSrcweir pMove->GetFromRange().aEnd.IncTab( -nFrom );
1213cdf0e10cSrcweir if ( nTo > 0 )
1214cdf0e10cSrcweir pMove->GetBigRange().aStart.IncTab( -nTo );
1215cdf0e10cSrcweir else if ( nTo < 0 )
1216cdf0e10cSrcweir pMove->GetBigRange().aEnd.IncTab( -nTo );
1217cdf0e10cSrcweir break;
1218cdf0e10cSrcweir default:
1219cdf0e10cSrcweir {
1220cdf0e10cSrcweir // added to avoid warnings
1221cdf0e10cSrcweir }
1222cdf0e10cSrcweir }
1223cdf0e10cSrcweir delete pLinkMove; // rueckt sich selbst hoch
1224cdf0e10cSrcweir }
1225cdf0e10cSrcweir }
1226cdf0e10cSrcweir
UndoCutOffInsert()1227cdf0e10cSrcweir void ScChangeActionDel::UndoCutOffInsert()
1228cdf0e10cSrcweir { // abgeschnittenes Insert wiederherstellen
1229cdf0e10cSrcweir if ( pCutOff )
1230cdf0e10cSrcweir {
1231cdf0e10cSrcweir switch ( pCutOff->GetType() )
1232cdf0e10cSrcweir {
1233cdf0e10cSrcweir case SC_CAT_INSERT_COLS :
1234cdf0e10cSrcweir if ( nCutOff < 0 )
1235cdf0e10cSrcweir pCutOff->GetBigRange().aEnd.IncCol( -nCutOff );
1236cdf0e10cSrcweir else
1237cdf0e10cSrcweir pCutOff->GetBigRange().aStart.IncCol( -nCutOff );
1238cdf0e10cSrcweir break;
1239cdf0e10cSrcweir case SC_CAT_INSERT_ROWS :
1240cdf0e10cSrcweir if ( nCutOff < 0 )
1241cdf0e10cSrcweir pCutOff->GetBigRange().aEnd.IncRow( -nCutOff );
1242cdf0e10cSrcweir else
1243cdf0e10cSrcweir pCutOff->GetBigRange().aStart.IncRow( -nCutOff );
1244cdf0e10cSrcweir break;
1245cdf0e10cSrcweir case SC_CAT_INSERT_TABS :
1246cdf0e10cSrcweir if ( nCutOff < 0 )
1247cdf0e10cSrcweir pCutOff->GetBigRange().aEnd.IncTab( -nCutOff );
1248cdf0e10cSrcweir else
1249cdf0e10cSrcweir pCutOff->GetBigRange().aStart.IncTab( -nCutOff );
1250cdf0e10cSrcweir break;
1251cdf0e10cSrcweir default:
1252cdf0e10cSrcweir {
1253cdf0e10cSrcweir // added to avoid warnings
1254cdf0e10cSrcweir }
1255cdf0e10cSrcweir }
1256cdf0e10cSrcweir SetCutOffInsert( NULL, 0 );
1257cdf0e10cSrcweir }
1258cdf0e10cSrcweir }
1259cdf0e10cSrcweir
1260cdf0e10cSrcweir
1261cdf0e10cSrcweir // --- ScChangeActionMove --------------------------------------------------
1262cdf0e10cSrcweir
ScChangeActionMove(const sal_uLong nActionNumber,const ScChangeActionState eStateP,const sal_uLong nRejectingNumber,const ScBigRange & aToBigRange,const String & aUserP,const DateTime & aDateTimeP,const String & sComment,const ScBigRange & aFromBigRange,ScChangeTrack * pTrackP)1263cdf0e10cSrcweir ScChangeActionMove::ScChangeActionMove(const sal_uLong nActionNumber, const ScChangeActionState eStateP, const sal_uLong nRejectingNumber,
1264cdf0e10cSrcweir const ScBigRange& aToBigRange, const String& aUserP, const DateTime& aDateTimeP, const String &sComment,
1265cdf0e10cSrcweir const ScBigRange& aFromBigRange, ScChangeTrack* pTrackP) // wich of nDx and nDy is set is depend on the type
1266cdf0e10cSrcweir :
1267cdf0e10cSrcweir ScChangeAction(SC_CAT_MOVE, aToBigRange, nActionNumber, nRejectingNumber, eStateP, aDateTimeP, aUserP, sComment),
1268cdf0e10cSrcweir aFromRange(aFromBigRange),
1269cdf0e10cSrcweir pTrack( pTrackP ),
1270cdf0e10cSrcweir pFirstCell( NULL ),
1271cdf0e10cSrcweir nStartLastCut(0),
1272cdf0e10cSrcweir nEndLastCut(0)
1273cdf0e10cSrcweir {
1274cdf0e10cSrcweir }
1275cdf0e10cSrcweir
~ScChangeActionMove()1276cdf0e10cSrcweir ScChangeActionMove::~ScChangeActionMove()
1277cdf0e10cSrcweir {
1278cdf0e10cSrcweir DeleteCellEntries();
1279cdf0e10cSrcweir }
1280cdf0e10cSrcweir
1281cdf0e10cSrcweir
AddContent(ScChangeActionContent * pContent)1282cdf0e10cSrcweir void ScChangeActionMove::AddContent( ScChangeActionContent* pContent )
1283cdf0e10cSrcweir {
1284cdf0e10cSrcweir ScChangeActionCellListEntry* pE = new ScChangeActionCellListEntry(
1285cdf0e10cSrcweir pContent, pFirstCell );
1286cdf0e10cSrcweir pFirstCell = pE;
1287cdf0e10cSrcweir }
1288cdf0e10cSrcweir
1289cdf0e10cSrcweir
DeleteCellEntries()1290cdf0e10cSrcweir void ScChangeActionMove::DeleteCellEntries()
1291cdf0e10cSrcweir {
1292cdf0e10cSrcweir pTrack->DeleteCellEntries( pFirstCell, this );
1293cdf0e10cSrcweir }
1294cdf0e10cSrcweir
1295cdf0e10cSrcweir
UpdateReference(const ScChangeTrack *,UpdateRefMode eMode,const ScBigRange & rRange,sal_Int32 nDx,sal_Int32 nDy,sal_Int32 nDz)1296cdf0e10cSrcweir void ScChangeActionMove::UpdateReference( const ScChangeTrack* /* pTrack */,
1297cdf0e10cSrcweir UpdateRefMode eMode, const ScBigRange& rRange,
1298cdf0e10cSrcweir sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz )
1299cdf0e10cSrcweir {
1300cdf0e10cSrcweir ScRefUpdate::Update( eMode, rRange, nDx, nDy, nDz, aFromRange );
1301cdf0e10cSrcweir ScRefUpdate::Update( eMode, rRange, nDx, nDy, nDz, GetBigRange() );
1302cdf0e10cSrcweir }
1303cdf0e10cSrcweir
1304cdf0e10cSrcweir
GetDelta(sal_Int32 & nDx,sal_Int32 & nDy,sal_Int32 & nDz) const1305cdf0e10cSrcweir void ScChangeActionMove::GetDelta( sal_Int32& nDx, sal_Int32& nDy, sal_Int32& nDz ) const
1306cdf0e10cSrcweir {
1307cdf0e10cSrcweir const ScBigAddress& rToPos = GetBigRange().aStart;
1308cdf0e10cSrcweir const ScBigAddress& rFromPos = GetFromRange().aStart;
1309cdf0e10cSrcweir nDx = rToPos.Col() - rFromPos.Col();
1310cdf0e10cSrcweir nDy = rToPos.Row() - rFromPos.Row();
1311cdf0e10cSrcweir nDz = rToPos.Tab() - rFromPos.Tab();
1312cdf0e10cSrcweir }
1313cdf0e10cSrcweir
1314cdf0e10cSrcweir
GetDescription(String & rStr,ScDocument * pDoc,sal_Bool bSplitRange,bool bWarning) const1315cdf0e10cSrcweir void ScChangeActionMove::GetDescription( String& rStr, ScDocument* pDoc,
1316cdf0e10cSrcweir sal_Bool bSplitRange, bool bWarning ) const
1317cdf0e10cSrcweir {
1318cdf0e10cSrcweir ScChangeAction::GetDescription( rStr, pDoc, bSplitRange, bWarning );
1319cdf0e10cSrcweir
1320cdf0e10cSrcweir sal_Bool bFlag3D = ( GetFromRange().aStart.Tab() != GetBigRange().aStart.Tab() );
1321cdf0e10cSrcweir
1322cdf0e10cSrcweir String aRsc( ScGlobal::GetRscString( STR_CHANGED_MOVE ) );
1323cdf0e10cSrcweir
1324cdf0e10cSrcweir xub_StrLen nPos = 0;
1325cdf0e10cSrcweir String aTmpStr = ScChangeAction::GetRefString( GetFromRange(), pDoc, bFlag3D );
1326cdf0e10cSrcweir nPos = aRsc.SearchAscii( "#1", nPos );
1327cdf0e10cSrcweir aRsc.Erase( nPos, 2 );
1328cdf0e10cSrcweir aRsc.Insert( aTmpStr, nPos );
1329cdf0e10cSrcweir nPos = sal::static_int_cast<xub_StrLen>( nPos + aTmpStr.Len() );
1330cdf0e10cSrcweir
1331cdf0e10cSrcweir aTmpStr = ScChangeAction::GetRefString( GetBigRange(), pDoc, bFlag3D );
1332cdf0e10cSrcweir nPos = aRsc.SearchAscii( "#2", nPos );
1333cdf0e10cSrcweir aRsc.Erase( nPos, 2 );
1334cdf0e10cSrcweir aRsc.Insert( aTmpStr, nPos );
1335cdf0e10cSrcweir nPos = sal::static_int_cast<xub_StrLen>( nPos + aTmpStr.Len() );
1336cdf0e10cSrcweir
1337cdf0e10cSrcweir rStr += aRsc;
1338cdf0e10cSrcweir }
1339cdf0e10cSrcweir
1340cdf0e10cSrcweir
GetRefString(String & rStr,ScDocument * pDoc,sal_Bool bFlag3D) const1341cdf0e10cSrcweir void ScChangeActionMove::GetRefString( String& rStr, ScDocument* pDoc,
1342cdf0e10cSrcweir sal_Bool bFlag3D ) const
1343cdf0e10cSrcweir {
1344cdf0e10cSrcweir if ( !bFlag3D )
1345cdf0e10cSrcweir bFlag3D = ( GetFromRange().aStart.Tab() != GetBigRange().aStart.Tab() );
1346cdf0e10cSrcweir rStr = ScChangeAction::GetRefString( GetFromRange(), pDoc, bFlag3D );
1347cdf0e10cSrcweir rStr += ',';
1348cdf0e10cSrcweir rStr += ' ';
1349cdf0e10cSrcweir rStr += ScChangeAction::GetRefString( GetBigRange(), pDoc, bFlag3D );
1350cdf0e10cSrcweir }
1351cdf0e10cSrcweir
1352cdf0e10cSrcweir
Reject(ScDocument * pDoc)1353cdf0e10cSrcweir sal_Bool ScChangeActionMove::Reject( ScDocument* pDoc )
1354cdf0e10cSrcweir {
1355cdf0e10cSrcweir if ( !(aBigRange.IsValid( pDoc ) && aFromRange.IsValid( pDoc )) )
1356cdf0e10cSrcweir return sal_False;
1357cdf0e10cSrcweir
1358cdf0e10cSrcweir ScRange aToRange( aBigRange.MakeRange() );
1359cdf0e10cSrcweir ScRange aFrmRange( aFromRange.MakeRange() );
1360cdf0e10cSrcweir
1361cdf0e10cSrcweir sal_Bool bOk = pDoc->IsBlockEditable( aToRange.aStart.Tab(),
1362cdf0e10cSrcweir aToRange.aStart.Col(), aToRange.aStart.Row(),
1363cdf0e10cSrcweir aToRange.aEnd.Col(), aToRange.aEnd.Row() );
1364cdf0e10cSrcweir if ( bOk )
1365cdf0e10cSrcweir bOk = pDoc->IsBlockEditable( aFrmRange.aStart.Tab(),
1366cdf0e10cSrcweir aFrmRange.aStart.Col(), aFrmRange.aStart.Row(),
1367cdf0e10cSrcweir aFrmRange.aEnd.Col(), aFrmRange.aEnd.Row() );
1368cdf0e10cSrcweir if ( !bOk )
1369cdf0e10cSrcweir return sal_False;
1370cdf0e10cSrcweir
1371cdf0e10cSrcweir pTrack->LookUpContents( aToRange, pDoc, 0, 0, 0 ); // zu movende Contents
1372cdf0e10cSrcweir
1373cdf0e10cSrcweir pDoc->DeleteAreaTab( aToRange, IDF_ALL );
1374cdf0e10cSrcweir pDoc->DeleteAreaTab( aFrmRange, IDF_ALL );
1375cdf0e10cSrcweir // Formeln im Dokument anpassen
1376cdf0e10cSrcweir pDoc->UpdateReference( URM_MOVE,
1377cdf0e10cSrcweir aFrmRange.aStart.Col(), aFrmRange.aStart.Row(), aFrmRange.aStart.Tab(),
1378cdf0e10cSrcweir aFrmRange.aEnd.Col(), aFrmRange.aEnd.Row(), aFrmRange.aEnd.Tab(),
1379cdf0e10cSrcweir (SCsCOL) aFrmRange.aStart.Col() - aToRange.aStart.Col(),
1380cdf0e10cSrcweir (SCsROW) aFrmRange.aStart.Row() - aToRange.aStart.Row(),
1381cdf0e10cSrcweir (SCsTAB) aFrmRange.aStart.Tab() - aToRange.aStart.Tab(), NULL );
1382cdf0e10cSrcweir
1383cdf0e10cSrcweir // LinkDependent freigeben, nachfolgendes UpdateReference-Undo setzt
1384cdf0e10cSrcweir // ToRange->FromRange Dependents
1385cdf0e10cSrcweir RemoveAllDependent();
1386cdf0e10cSrcweir
1387cdf0e10cSrcweir // setzt rejected und ruft UpdateReference-Undo und DeleteCellEntries
1388cdf0e10cSrcweir RejectRestoreContents( pTrack, 0, 0 );
1389cdf0e10cSrcweir
1390cdf0e10cSrcweir while ( pLinkDependent )
1391cdf0e10cSrcweir {
1392cdf0e10cSrcweir ScChangeAction* p = pLinkDependent->GetAction();
1393cdf0e10cSrcweir if ( p && p->GetType() == SC_CAT_CONTENT )
1394cdf0e10cSrcweir {
1395cdf0e10cSrcweir ScChangeActionContent* pContent = (ScChangeActionContent*) p;
1396cdf0e10cSrcweir if ( !pContent->IsDeletedIn() &&
1397cdf0e10cSrcweir pContent->GetBigRange().aStart.IsValid( pDoc ) )
1398cdf0e10cSrcweir pContent->PutNewValueToDoc( pDoc, 0, 0 );
1399cdf0e10cSrcweir // in LookUpContents generierte loeschen
1400cdf0e10cSrcweir if ( pTrack->IsGenerated( pContent->GetActionNumber() ) &&
1401cdf0e10cSrcweir !pContent->IsDeletedIn() )
1402cdf0e10cSrcweir {
1403cdf0e10cSrcweir pLinkDependent->UnLink(); //! sonst wird der mitgeloescht
1404cdf0e10cSrcweir pTrack->DeleteGeneratedDelContent( pContent );
1405cdf0e10cSrcweir }
1406cdf0e10cSrcweir }
1407cdf0e10cSrcweir delete pLinkDependent;
1408cdf0e10cSrcweir }
1409cdf0e10cSrcweir
1410cdf0e10cSrcweir RemoveAllLinks();
1411cdf0e10cSrcweir return sal_True;
1412cdf0e10cSrcweir }
1413cdf0e10cSrcweir
1414cdf0e10cSrcweir
1415cdf0e10cSrcweir // --- ScChangeActionContent -----------------------------------------------
1416cdf0e10cSrcweir
1417cdf0e10cSrcweir const sal_uInt16 nMemPoolChangeActionContent = (0x8000 - 64) / sizeof(ScChangeActionContent);
IMPL_FIXEDMEMPOOL_NEWDEL(ScChangeActionContent,nMemPoolChangeActionContent,nMemPoolChangeActionContent)1418cdf0e10cSrcweir IMPL_FIXEDMEMPOOL_NEWDEL( ScChangeActionContent, nMemPoolChangeActionContent, nMemPoolChangeActionContent )
1419cdf0e10cSrcweir
1420cdf0e10cSrcweir ScChangeActionContent::ScChangeActionContent( const sal_uLong nActionNumber,
1421cdf0e10cSrcweir const ScChangeActionState eStateP, const sal_uLong nRejectingNumber,
1422cdf0e10cSrcweir const ScBigRange& aBigRangeP, const String& aUserP,
1423cdf0e10cSrcweir const DateTime& aDateTimeP, const String& sComment,
1424cdf0e10cSrcweir ScBaseCell* pTempOldCell, ScDocument* pDoc, const String& sOldValue )
1425cdf0e10cSrcweir :
1426cdf0e10cSrcweir ScChangeAction(SC_CAT_CONTENT, aBigRangeP, nActionNumber, nRejectingNumber, eStateP, aDateTimeP, aUserP, sComment),
1427cdf0e10cSrcweir aOldValue(sOldValue),
1428cdf0e10cSrcweir pOldCell(pTempOldCell),
1429cdf0e10cSrcweir pNewCell(NULL),
1430cdf0e10cSrcweir pNextContent(NULL),
1431cdf0e10cSrcweir pPrevContent(NULL),
1432cdf0e10cSrcweir pNextInSlot(NULL),
1433cdf0e10cSrcweir ppPrevInSlot(NULL)
1434cdf0e10cSrcweir
1435cdf0e10cSrcweir {
1436cdf0e10cSrcweir if (pOldCell)
1437cdf0e10cSrcweir ScChangeActionContent::SetCell( aOldValue, pOldCell, 0, pDoc );
1438cdf0e10cSrcweir if ( sOldValue.Len() ) // #i40704# don't overwrite SetCell result with empty string
1439cdf0e10cSrcweir aOldValue = sOldValue; // set again, because SetCell removes it
1440cdf0e10cSrcweir }
1441cdf0e10cSrcweir
ScChangeActionContent(const sal_uLong nActionNumber,ScBaseCell * pTempNewCell,const ScBigRange & aBigRangeP,ScDocument * pDoc,const String & sNewValue)1442cdf0e10cSrcweir ScChangeActionContent::ScChangeActionContent( const sal_uLong nActionNumber,
1443cdf0e10cSrcweir ScBaseCell* pTempNewCell, const ScBigRange& aBigRangeP,
1444cdf0e10cSrcweir ScDocument* pDoc, const String& sNewValue )
1445cdf0e10cSrcweir :
1446cdf0e10cSrcweir ScChangeAction(SC_CAT_CONTENT, aBigRangeP, nActionNumber),
1447cdf0e10cSrcweir aNewValue(sNewValue),
1448cdf0e10cSrcweir pOldCell(NULL),
1449cdf0e10cSrcweir pNewCell(pTempNewCell),
1450cdf0e10cSrcweir pNextContent(NULL),
1451cdf0e10cSrcweir pPrevContent(NULL),
1452cdf0e10cSrcweir pNextInSlot(NULL),
1453cdf0e10cSrcweir ppPrevInSlot(NULL)
1454cdf0e10cSrcweir {
1455cdf0e10cSrcweir if (pNewCell)
1456cdf0e10cSrcweir ScChangeActionContent::SetCell( aNewValue, pNewCell, 0, pDoc );
1457cdf0e10cSrcweir if ( sNewValue.Len() ) // #i40704# don't overwrite SetCell result with empty string
1458cdf0e10cSrcweir aNewValue = sNewValue; // set again, because SetCell removes it
1459cdf0e10cSrcweir }
1460cdf0e10cSrcweir
~ScChangeActionContent()1461cdf0e10cSrcweir ScChangeActionContent::~ScChangeActionContent()
1462cdf0e10cSrcweir {
1463cdf0e10cSrcweir ClearTrack();
1464cdf0e10cSrcweir }
1465cdf0e10cSrcweir
1466cdf0e10cSrcweir
ClearTrack()1467cdf0e10cSrcweir void ScChangeActionContent::ClearTrack()
1468cdf0e10cSrcweir {
1469cdf0e10cSrcweir RemoveFromSlot();
1470cdf0e10cSrcweir if ( pPrevContent )
1471cdf0e10cSrcweir pPrevContent->pNextContent = pNextContent;
1472cdf0e10cSrcweir if ( pNextContent )
1473cdf0e10cSrcweir pNextContent->pPrevContent = pPrevContent;
1474cdf0e10cSrcweir }
1475cdf0e10cSrcweir
1476cdf0e10cSrcweir
GetTopContent() const1477cdf0e10cSrcweir ScChangeActionContent* ScChangeActionContent::GetTopContent() const
1478cdf0e10cSrcweir {
1479cdf0e10cSrcweir if ( pNextContent )
1480cdf0e10cSrcweir {
1481cdf0e10cSrcweir ScChangeActionContent* pContent = pNextContent;
1482cdf0e10cSrcweir while ( pContent->pNextContent && pContent != pContent->pNextContent )
1483cdf0e10cSrcweir pContent = pContent->pNextContent;
1484cdf0e10cSrcweir return pContent;
1485cdf0e10cSrcweir }
1486cdf0e10cSrcweir return (ScChangeActionContent*) this;
1487cdf0e10cSrcweir }
1488cdf0e10cSrcweir
1489cdf0e10cSrcweir
GetDeletedIn() const1490cdf0e10cSrcweir ScChangeActionLinkEntry* ScChangeActionContent::GetDeletedIn() const
1491cdf0e10cSrcweir {
1492cdf0e10cSrcweir if ( pNextContent )
1493cdf0e10cSrcweir return GetTopContent()->pLinkDeletedIn;
1494cdf0e10cSrcweir return pLinkDeletedIn;
1495cdf0e10cSrcweir }
1496cdf0e10cSrcweir
1497cdf0e10cSrcweir
GetDeletedInAddress()1498cdf0e10cSrcweir ScChangeActionLinkEntry** ScChangeActionContent::GetDeletedInAddress()
1499cdf0e10cSrcweir {
1500cdf0e10cSrcweir if ( pNextContent )
1501cdf0e10cSrcweir return GetTopContent()->GetDeletedInAddress();
1502cdf0e10cSrcweir return &pLinkDeletedIn;
1503cdf0e10cSrcweir }
1504cdf0e10cSrcweir
1505cdf0e10cSrcweir
SetOldValue(const ScBaseCell * pCell,const ScDocument * pFromDoc,ScDocument * pToDoc,sal_uLong nFormat)1506cdf0e10cSrcweir void ScChangeActionContent::SetOldValue( const ScBaseCell* pCell,
1507cdf0e10cSrcweir const ScDocument* pFromDoc, ScDocument* pToDoc, sal_uLong nFormat )
1508cdf0e10cSrcweir {
1509cdf0e10cSrcweir ScChangeActionContent::SetValue( aOldValue, pOldCell,
1510cdf0e10cSrcweir nFormat, pCell, pFromDoc, pToDoc );
1511cdf0e10cSrcweir }
1512cdf0e10cSrcweir
1513cdf0e10cSrcweir
SetOldValue(const ScBaseCell * pCell,const ScDocument * pFromDoc,ScDocument * pToDoc)1514cdf0e10cSrcweir void ScChangeActionContent::SetOldValue( const ScBaseCell* pCell,
1515cdf0e10cSrcweir const ScDocument* pFromDoc, ScDocument* pToDoc )
1516cdf0e10cSrcweir {
1517cdf0e10cSrcweir ScChangeActionContent::SetValue( aOldValue, pOldCell,
1518cdf0e10cSrcweir aBigRange.aStart.MakeAddress(), pCell, pFromDoc, pToDoc );
1519cdf0e10cSrcweir }
1520cdf0e10cSrcweir
1521cdf0e10cSrcweir
SetNewValue(const ScBaseCell * pCell,ScDocument * pDoc)1522cdf0e10cSrcweir void ScChangeActionContent::SetNewValue( const ScBaseCell* pCell,
1523cdf0e10cSrcweir ScDocument* pDoc )
1524cdf0e10cSrcweir {
1525cdf0e10cSrcweir ScChangeActionContent::SetValue( aNewValue, pNewCell,
1526cdf0e10cSrcweir aBigRange.aStart.MakeAddress(), pCell, pDoc, pDoc );
1527cdf0e10cSrcweir }
1528cdf0e10cSrcweir
1529cdf0e10cSrcweir
SetOldNewCells(ScBaseCell * pOldCellP,sal_uLong nOldFormat,ScBaseCell * pNewCellP,sal_uLong nNewFormat,ScDocument * pDoc)1530cdf0e10cSrcweir void ScChangeActionContent::SetOldNewCells( ScBaseCell* pOldCellP,
1531cdf0e10cSrcweir sal_uLong nOldFormat, ScBaseCell* pNewCellP,
1532cdf0e10cSrcweir sal_uLong nNewFormat, ScDocument* pDoc )
1533cdf0e10cSrcweir {
1534cdf0e10cSrcweir pOldCell = pOldCellP;
1535cdf0e10cSrcweir pNewCell = pNewCellP;
1536cdf0e10cSrcweir ScChangeActionContent::SetCell( aOldValue, pOldCell, nOldFormat, pDoc );
1537cdf0e10cSrcweir ScChangeActionContent::SetCell( aNewValue, pNewCell, nNewFormat, pDoc );
1538cdf0e10cSrcweir }
1539cdf0e10cSrcweir
SetNewCell(ScBaseCell * pCell,ScDocument * pDoc,const String & rFormatted)1540cdf0e10cSrcweir void ScChangeActionContent::SetNewCell( ScBaseCell* pCell, ScDocument* pDoc, const String& rFormatted )
1541cdf0e10cSrcweir {
1542cdf0e10cSrcweir DBG_ASSERT( !pNewCell, "ScChangeActionContent::SetNewCell: overwriting existing cell" );
1543cdf0e10cSrcweir pNewCell = pCell;
1544cdf0e10cSrcweir ScChangeActionContent::SetCell( aNewValue, pNewCell, 0, pDoc );
1545cdf0e10cSrcweir
1546cdf0e10cSrcweir // #i40704# allow to set formatted text here - don't call SetNewValue with String from XML filter
1547cdf0e10cSrcweir if ( rFormatted.Len() )
1548cdf0e10cSrcweir aNewValue = rFormatted;
1549cdf0e10cSrcweir }
1550cdf0e10cSrcweir
SetValueString(String & rValue,ScBaseCell * & pCell,const String & rStr,ScDocument * pDoc)1551cdf0e10cSrcweir void ScChangeActionContent::SetValueString( String& rValue, ScBaseCell*& pCell,
1552cdf0e10cSrcweir const String& rStr, ScDocument* pDoc )
1553cdf0e10cSrcweir {
1554cdf0e10cSrcweir if ( pCell )
1555cdf0e10cSrcweir {
1556cdf0e10cSrcweir pCell->Delete();
1557cdf0e10cSrcweir pCell = NULL;
1558cdf0e10cSrcweir }
1559cdf0e10cSrcweir if ( rStr.Len() > 1 && rStr.GetChar(0) == '=' )
1560cdf0e10cSrcweir {
1561cdf0e10cSrcweir rValue.Erase();
1562cdf0e10cSrcweir pCell = new ScFormulaCell(
1563cdf0e10cSrcweir pDoc, aBigRange.aStart.MakeAddress(), rStr, formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::CONV_OOO );
1564cdf0e10cSrcweir ((ScFormulaCell*)pCell)->SetInChangeTrack( sal_True );
1565cdf0e10cSrcweir }
1566cdf0e10cSrcweir else
1567cdf0e10cSrcweir rValue = rStr;
1568cdf0e10cSrcweir }
1569cdf0e10cSrcweir
1570cdf0e10cSrcweir
SetOldValue(const String & rOld,ScDocument * pDoc)1571cdf0e10cSrcweir void ScChangeActionContent::SetOldValue( const String& rOld, ScDocument* pDoc )
1572cdf0e10cSrcweir {
1573cdf0e10cSrcweir SetValueString( aOldValue, pOldCell, rOld, pDoc );
1574cdf0e10cSrcweir }
1575cdf0e10cSrcweir
1576cdf0e10cSrcweir
SetNewValue(const String & rNew,ScDocument * pDoc)1577cdf0e10cSrcweir void ScChangeActionContent::SetNewValue( const String& rNew, ScDocument* pDoc )
1578cdf0e10cSrcweir {
1579cdf0e10cSrcweir SetValueString( aNewValue, pNewCell, rNew, pDoc );
1580cdf0e10cSrcweir }
1581cdf0e10cSrcweir
1582cdf0e10cSrcweir
GetOldString(String & rStr) const1583cdf0e10cSrcweir void ScChangeActionContent::GetOldString( String& rStr ) const
1584cdf0e10cSrcweir {
1585cdf0e10cSrcweir GetValueString( rStr, aOldValue, pOldCell );
1586cdf0e10cSrcweir }
1587cdf0e10cSrcweir
1588cdf0e10cSrcweir
GetNewString(String & rStr) const1589cdf0e10cSrcweir void ScChangeActionContent::GetNewString( String& rStr ) const
1590cdf0e10cSrcweir {
1591cdf0e10cSrcweir GetValueString( rStr, aNewValue, pNewCell );
1592cdf0e10cSrcweir }
1593cdf0e10cSrcweir
1594cdf0e10cSrcweir
GetDescription(String & rStr,ScDocument * pDoc,sal_Bool bSplitRange,bool bWarning) const1595cdf0e10cSrcweir void ScChangeActionContent::GetDescription( String& rStr, ScDocument* pDoc,
1596cdf0e10cSrcweir sal_Bool bSplitRange, bool bWarning ) const
1597cdf0e10cSrcweir {
1598cdf0e10cSrcweir ScChangeAction::GetDescription( rStr, pDoc, bSplitRange, bWarning );
1599cdf0e10cSrcweir
1600cdf0e10cSrcweir String aRsc( ScGlobal::GetRscString( STR_CHANGED_CELL ) );
1601cdf0e10cSrcweir
1602cdf0e10cSrcweir String aTmpStr;
1603cdf0e10cSrcweir GetRefString( aTmpStr, pDoc );
1604cdf0e10cSrcweir
1605cdf0e10cSrcweir xub_StrLen nPos = 0;
1606cdf0e10cSrcweir nPos = aRsc.SearchAscii( "#1", nPos );
1607cdf0e10cSrcweir aRsc.Erase( nPos, 2 );
1608cdf0e10cSrcweir aRsc.Insert( aTmpStr, nPos );
1609cdf0e10cSrcweir nPos = sal::static_int_cast<xub_StrLen>( nPos + aTmpStr.Len() );
1610cdf0e10cSrcweir
1611cdf0e10cSrcweir GetOldString( aTmpStr );
1612cdf0e10cSrcweir if ( !aTmpStr.Len() )
1613cdf0e10cSrcweir aTmpStr = ScGlobal::GetRscString( STR_CHANGED_BLANK );
1614cdf0e10cSrcweir nPos = aRsc.SearchAscii( "#2", nPos );
1615cdf0e10cSrcweir aRsc.Erase( nPos, 2 );
1616cdf0e10cSrcweir aRsc.Insert( aTmpStr, nPos );
1617cdf0e10cSrcweir nPos = sal::static_int_cast<xub_StrLen>( nPos + aTmpStr.Len() );
1618cdf0e10cSrcweir
1619cdf0e10cSrcweir GetNewString( aTmpStr );
1620cdf0e10cSrcweir if ( !aTmpStr.Len() )
1621cdf0e10cSrcweir aTmpStr = ScGlobal::GetRscString( STR_CHANGED_BLANK );
1622cdf0e10cSrcweir nPos = aRsc.SearchAscii( "#3", nPos );
1623cdf0e10cSrcweir aRsc.Erase( nPos, 2 );
1624cdf0e10cSrcweir aRsc.Insert( aTmpStr, nPos );
1625cdf0e10cSrcweir
1626cdf0e10cSrcweir rStr += aRsc;
1627cdf0e10cSrcweir }
1628cdf0e10cSrcweir
1629cdf0e10cSrcweir
GetRefString(String & rStr,ScDocument * pDoc,sal_Bool bFlag3D) const1630cdf0e10cSrcweir void ScChangeActionContent::GetRefString( String& rStr, ScDocument* pDoc,
1631cdf0e10cSrcweir sal_Bool bFlag3D ) const
1632cdf0e10cSrcweir {
1633cdf0e10cSrcweir sal_uInt16 nFlags = ( GetBigRange().IsValid( pDoc ) ? SCA_VALID : 0 );
1634cdf0e10cSrcweir if ( nFlags )
1635cdf0e10cSrcweir {
1636cdf0e10cSrcweir const ScBaseCell* pCell = GetNewCell();
1637cdf0e10cSrcweir if ( ScChangeActionContent::GetContentCellType( pCell ) == SC_CACCT_MATORG )
1638cdf0e10cSrcweir {
1639cdf0e10cSrcweir ScBigRange aLocalBigRange( GetBigRange() );
1640cdf0e10cSrcweir SCCOL nC;
1641cdf0e10cSrcweir SCROW nR;
1642cdf0e10cSrcweir ((const ScFormulaCell*)pCell)->GetMatColsRows( nC, nR );
1643cdf0e10cSrcweir aLocalBigRange.aEnd.IncCol( nC-1 );
1644cdf0e10cSrcweir aLocalBigRange.aEnd.IncRow( nR-1 );
1645cdf0e10cSrcweir rStr = ScChangeAction::GetRefString( aLocalBigRange, pDoc, bFlag3D );
1646cdf0e10cSrcweir
1647cdf0e10cSrcweir return ;
1648cdf0e10cSrcweir }
1649cdf0e10cSrcweir
1650cdf0e10cSrcweir ScAddress aTmpAddress( GetBigRange().aStart.MakeAddress() );
1651cdf0e10cSrcweir if ( bFlag3D )
1652cdf0e10cSrcweir nFlags |= SCA_TAB_3D;
1653cdf0e10cSrcweir aTmpAddress.Format( rStr, nFlags, pDoc, pDoc->GetAddressConvention() );
1654cdf0e10cSrcweir if ( IsDeletedIn() )
1655cdf0e10cSrcweir {
1656cdf0e10cSrcweir rStr.Insert( '(', 0 );
1657cdf0e10cSrcweir rStr += ')';
1658cdf0e10cSrcweir }
1659cdf0e10cSrcweir }
1660cdf0e10cSrcweir else
1661cdf0e10cSrcweir rStr = ScGlobal::GetRscString( STR_NOREF_STR );
1662cdf0e10cSrcweir }
1663cdf0e10cSrcweir
1664cdf0e10cSrcweir
Reject(ScDocument * pDoc)1665cdf0e10cSrcweir sal_Bool ScChangeActionContent::Reject( ScDocument* pDoc )
1666cdf0e10cSrcweir {
1667cdf0e10cSrcweir if ( !aBigRange.IsValid( pDoc ) )
1668cdf0e10cSrcweir return sal_False;
1669cdf0e10cSrcweir
1670cdf0e10cSrcweir PutOldValueToDoc( pDoc, 0, 0 );
1671cdf0e10cSrcweir
1672cdf0e10cSrcweir SetState( SC_CAS_REJECTED );
1673cdf0e10cSrcweir RemoveAllLinks();
1674cdf0e10cSrcweir
1675cdf0e10cSrcweir return sal_True;
1676cdf0e10cSrcweir }
1677cdf0e10cSrcweir
1678cdf0e10cSrcweir
Select(ScDocument * pDoc,ScChangeTrack * pTrack,sal_Bool bOldest,Stack * pRejectActions)1679cdf0e10cSrcweir sal_Bool ScChangeActionContent::Select( ScDocument* pDoc, ScChangeTrack* pTrack,
1680cdf0e10cSrcweir sal_Bool bOldest, Stack* pRejectActions )
1681cdf0e10cSrcweir {
1682cdf0e10cSrcweir if ( !aBigRange.IsValid( pDoc ) )
1683cdf0e10cSrcweir return sal_False;
1684cdf0e10cSrcweir
1685cdf0e10cSrcweir ScChangeActionContent* pContent = this;
1686cdf0e10cSrcweir // accept previous contents
1687cdf0e10cSrcweir while ( ( pContent = pContent->pPrevContent ) != NULL )
1688cdf0e10cSrcweir {
1689cdf0e10cSrcweir if ( pContent->IsVirgin() )
1690cdf0e10cSrcweir pContent->SetState( SC_CAS_ACCEPTED );
1691cdf0e10cSrcweir }
1692cdf0e10cSrcweir ScChangeActionContent* pEnd = pContent = this;
1693cdf0e10cSrcweir // reject subsequent contents
1694cdf0e10cSrcweir while ( ( pContent = pContent->pNextContent ) != NULL )
1695cdf0e10cSrcweir {
1696cdf0e10cSrcweir // MatrixOrigin may have dependents, no dependency recursion needed
1697cdf0e10cSrcweir const ScChangeActionLinkEntry* pL = pContent->GetFirstDependentEntry();
1698cdf0e10cSrcweir while ( pL )
1699cdf0e10cSrcweir {
1700cdf0e10cSrcweir ScChangeAction* p = (ScChangeAction*) pL->GetAction();
1701cdf0e10cSrcweir if ( p )
1702cdf0e10cSrcweir p->SetRejected();
1703cdf0e10cSrcweir pL = pL->GetNext();
1704cdf0e10cSrcweir }
1705cdf0e10cSrcweir pContent->SetRejected();
1706cdf0e10cSrcweir pEnd = pContent;
1707cdf0e10cSrcweir }
1708cdf0e10cSrcweir
1709cdf0e10cSrcweir if ( bOldest || pEnd != this )
1710cdf0e10cSrcweir { // wenn nicht aeltester: ist es ueberhaupt ein anderer als der letzte?
1711cdf0e10cSrcweir ScRange aRange( aBigRange.aStart.MakeAddress() );
1712cdf0e10cSrcweir const ScAddress& rPos = aRange.aStart;
1713cdf0e10cSrcweir
1714cdf0e10cSrcweir ScChangeActionContent* pNew = new ScChangeActionContent( aRange );
1715cdf0e10cSrcweir pNew->SetOldValue( pDoc->GetCell( rPos ), pDoc, pDoc );
1716cdf0e10cSrcweir
1717cdf0e10cSrcweir if ( bOldest )
1718cdf0e10cSrcweir PutOldValueToDoc( pDoc, 0, 0 );
1719cdf0e10cSrcweir else
1720cdf0e10cSrcweir PutNewValueToDoc( pDoc, 0, 0 );
1721cdf0e10cSrcweir
1722cdf0e10cSrcweir pNew->SetRejectAction( bOldest ? GetActionNumber() : pEnd->GetActionNumber() );
1723cdf0e10cSrcweir pNew->SetState( SC_CAS_ACCEPTED );
1724cdf0e10cSrcweir if ( pRejectActions )
1725cdf0e10cSrcweir pRejectActions->Push( pNew );
1726cdf0e10cSrcweir else
1727cdf0e10cSrcweir {
1728cdf0e10cSrcweir pNew->SetNewValue( pDoc->GetCell( rPos ), pDoc );
1729cdf0e10cSrcweir pTrack->Append( pNew );
1730cdf0e10cSrcweir }
1731cdf0e10cSrcweir }
1732cdf0e10cSrcweir
1733cdf0e10cSrcweir if ( bOldest )
1734cdf0e10cSrcweir SetRejected();
1735cdf0e10cSrcweir else
1736cdf0e10cSrcweir SetState( SC_CAS_ACCEPTED );
1737cdf0e10cSrcweir
1738cdf0e10cSrcweir return sal_True;
1739cdf0e10cSrcweir }
1740cdf0e10cSrcweir
1741cdf0e10cSrcweir
1742cdf0e10cSrcweir // static
GetStringOfCell(String & rStr,const ScBaseCell * pCell,const ScDocument * pDoc,const ScAddress & rPos)1743cdf0e10cSrcweir void ScChangeActionContent::GetStringOfCell( String& rStr,
1744cdf0e10cSrcweir const ScBaseCell* pCell, const ScDocument* pDoc, const ScAddress& rPos )
1745cdf0e10cSrcweir {
1746cdf0e10cSrcweir if ( pCell )
1747cdf0e10cSrcweir {
1748cdf0e10cSrcweir if ( ScChangeActionContent::NeedsNumberFormat( pCell ) )
1749cdf0e10cSrcweir GetStringOfCell( rStr, pCell, pDoc, pDoc->GetNumberFormat( rPos ) );
1750cdf0e10cSrcweir else
1751cdf0e10cSrcweir GetStringOfCell( rStr, pCell, pDoc, 0 );
1752cdf0e10cSrcweir }
1753cdf0e10cSrcweir else
1754cdf0e10cSrcweir rStr.Erase();
1755cdf0e10cSrcweir }
1756cdf0e10cSrcweir
1757cdf0e10cSrcweir
1758cdf0e10cSrcweir // static
GetStringOfCell(String & rStr,const ScBaseCell * pCell,const ScDocument * pDoc,sal_uLong nFormat)1759cdf0e10cSrcweir void ScChangeActionContent::GetStringOfCell( String& rStr,
1760cdf0e10cSrcweir const ScBaseCell* pCell, const ScDocument* pDoc, sal_uLong nFormat )
1761cdf0e10cSrcweir {
1762cdf0e10cSrcweir if ( ScChangeActionContent::GetContentCellType( pCell ) )
1763cdf0e10cSrcweir {
1764cdf0e10cSrcweir switch ( pCell->GetCellType() )
1765cdf0e10cSrcweir {
1766cdf0e10cSrcweir case CELLTYPE_VALUE :
1767cdf0e10cSrcweir {
1768cdf0e10cSrcweir double nValue = ((ScValueCell*)pCell)->GetValue();
1769cdf0e10cSrcweir pDoc->GetFormatTable()->GetInputLineString( nValue, nFormat,
1770cdf0e10cSrcweir rStr );
1771cdf0e10cSrcweir }
1772cdf0e10cSrcweir break;
1773cdf0e10cSrcweir case CELLTYPE_STRING :
1774cdf0e10cSrcweir ((ScStringCell*)pCell)->GetString( rStr );
1775cdf0e10cSrcweir break;
1776cdf0e10cSrcweir case CELLTYPE_EDIT :
1777cdf0e10cSrcweir ((ScEditCell*)pCell)->GetString( rStr );
1778cdf0e10cSrcweir break;
1779cdf0e10cSrcweir case CELLTYPE_FORMULA :
1780cdf0e10cSrcweir ((ScFormulaCell*)pCell)->GetFormula( rStr );
1781cdf0e10cSrcweir break;
1782cdf0e10cSrcweir default:
1783cdf0e10cSrcweir rStr.Erase();
1784cdf0e10cSrcweir }
1785cdf0e10cSrcweir }
1786cdf0e10cSrcweir else
1787cdf0e10cSrcweir rStr.Erase();
1788cdf0e10cSrcweir }
1789cdf0e10cSrcweir
1790cdf0e10cSrcweir
1791cdf0e10cSrcweir // static
GetContentCellType(const ScBaseCell * pCell)1792cdf0e10cSrcweir ScChangeActionContentCellType ScChangeActionContent::GetContentCellType( const ScBaseCell* pCell )
1793cdf0e10cSrcweir {
1794cdf0e10cSrcweir if ( pCell )
1795cdf0e10cSrcweir {
1796cdf0e10cSrcweir switch ( pCell->GetCellType() )
1797cdf0e10cSrcweir {
1798cdf0e10cSrcweir case CELLTYPE_VALUE :
1799cdf0e10cSrcweir case CELLTYPE_STRING :
1800cdf0e10cSrcweir case CELLTYPE_EDIT :
1801cdf0e10cSrcweir return SC_CACCT_NORMAL;
1802cdf0e10cSrcweir //break;
1803cdf0e10cSrcweir case CELLTYPE_FORMULA :
1804cdf0e10cSrcweir switch ( ((const ScFormulaCell*)pCell)->GetMatrixFlag() )
1805cdf0e10cSrcweir {
1806cdf0e10cSrcweir case MM_NONE :
1807cdf0e10cSrcweir return SC_CACCT_NORMAL;
1808cdf0e10cSrcweir //break;
1809cdf0e10cSrcweir case MM_FORMULA :
1810cdf0e10cSrcweir case MM_FAKE :
1811cdf0e10cSrcweir return SC_CACCT_MATORG;
1812cdf0e10cSrcweir //break;
1813cdf0e10cSrcweir case MM_REFERENCE :
1814cdf0e10cSrcweir return SC_CACCT_MATREF;
1815cdf0e10cSrcweir //break;
1816cdf0e10cSrcweir }
1817cdf0e10cSrcweir return SC_CACCT_NORMAL;
1818cdf0e10cSrcweir //break;
1819cdf0e10cSrcweir default:
1820cdf0e10cSrcweir return SC_CACCT_NONE;
1821cdf0e10cSrcweir }
1822cdf0e10cSrcweir }
1823cdf0e10cSrcweir return SC_CACCT_NONE;
1824cdf0e10cSrcweir }
1825cdf0e10cSrcweir
1826cdf0e10cSrcweir
1827cdf0e10cSrcweir // static
NeedsNumberFormat(const ScBaseCell * pCell)1828cdf0e10cSrcweir sal_Bool ScChangeActionContent::NeedsNumberFormat( const ScBaseCell* pCell )
1829cdf0e10cSrcweir {
1830cdf0e10cSrcweir return pCell && pCell->GetCellType() == CELLTYPE_VALUE;
1831cdf0e10cSrcweir }
1832cdf0e10cSrcweir
1833cdf0e10cSrcweir
1834cdf0e10cSrcweir // static
SetValue(String & rStr,ScBaseCell * & pCell,const ScAddress & rPos,const ScBaseCell * pOrgCell,const ScDocument * pFromDoc,ScDocument * pToDoc)1835cdf0e10cSrcweir void ScChangeActionContent::SetValue( String& rStr, ScBaseCell*& pCell,
1836cdf0e10cSrcweir const ScAddress& rPos, const ScBaseCell* pOrgCell,
1837cdf0e10cSrcweir const ScDocument* pFromDoc, ScDocument* pToDoc )
1838cdf0e10cSrcweir {
1839cdf0e10cSrcweir sal_uLong nFormat = NeedsNumberFormat( pOrgCell ) ? pFromDoc->GetNumberFormat( rPos ) : 0;
1840cdf0e10cSrcweir SetValue( rStr, pCell, nFormat, pOrgCell, pFromDoc, pToDoc );
1841cdf0e10cSrcweir }
1842cdf0e10cSrcweir
1843cdf0e10cSrcweir
1844cdf0e10cSrcweir // static
SetValue(String & rStr,ScBaseCell * & pCell,sal_uLong nFormat,const ScBaseCell * pOrgCell,const ScDocument * pFromDoc,ScDocument * pToDoc)1845cdf0e10cSrcweir void ScChangeActionContent::SetValue( String& rStr, ScBaseCell*& pCell,
1846cdf0e10cSrcweir sal_uLong nFormat, const ScBaseCell* pOrgCell,
1847cdf0e10cSrcweir const ScDocument* pFromDoc, ScDocument* pToDoc )
1848cdf0e10cSrcweir {
1849cdf0e10cSrcweir rStr.Erase();
1850cdf0e10cSrcweir if ( pCell )
1851cdf0e10cSrcweir pCell->Delete();
1852cdf0e10cSrcweir if ( ScChangeActionContent::GetContentCellType( pOrgCell ) )
1853cdf0e10cSrcweir {
1854cdf0e10cSrcweir pCell = pOrgCell->CloneWithoutNote( *pToDoc );
1855cdf0e10cSrcweir switch ( pOrgCell->GetCellType() )
1856cdf0e10cSrcweir {
1857cdf0e10cSrcweir case CELLTYPE_VALUE :
1858cdf0e10cSrcweir { // z.B. Datum auch als solches merken
1859cdf0e10cSrcweir double nValue = ((ScValueCell*)pOrgCell)->GetValue();
1860cdf0e10cSrcweir pFromDoc->GetFormatTable()->GetInputLineString( nValue,
1861cdf0e10cSrcweir nFormat, rStr );
1862cdf0e10cSrcweir }
1863cdf0e10cSrcweir break;
1864cdf0e10cSrcweir case CELLTYPE_FORMULA :
1865cdf0e10cSrcweir ((ScFormulaCell*)pCell)->SetInChangeTrack( sal_True );
1866cdf0e10cSrcweir break;
1867cdf0e10cSrcweir default:
1868cdf0e10cSrcweir {
1869cdf0e10cSrcweir // added to avoid warnings
1870cdf0e10cSrcweir }
1871cdf0e10cSrcweir }
1872cdf0e10cSrcweir }
1873cdf0e10cSrcweir else
1874cdf0e10cSrcweir pCell = NULL;
1875cdf0e10cSrcweir }
1876cdf0e10cSrcweir
1877cdf0e10cSrcweir
1878cdf0e10cSrcweir // static
SetCell(String & rStr,ScBaseCell * pCell,sal_uLong nFormat,const ScDocument * pDoc)1879cdf0e10cSrcweir void ScChangeActionContent::SetCell( String& rStr, ScBaseCell* pCell,
1880cdf0e10cSrcweir sal_uLong nFormat, const ScDocument* pDoc )
1881cdf0e10cSrcweir {
1882cdf0e10cSrcweir rStr.Erase();
1883cdf0e10cSrcweir if ( pCell )
1884cdf0e10cSrcweir {
1885cdf0e10cSrcweir switch ( pCell->GetCellType() )
1886cdf0e10cSrcweir {
1887cdf0e10cSrcweir case CELLTYPE_VALUE :
1888cdf0e10cSrcweir { // e.g. remember date as date string
1889cdf0e10cSrcweir double nValue = ((ScValueCell*)pCell)->GetValue();
1890cdf0e10cSrcweir pDoc->GetFormatTable()->GetInputLineString( nValue,
1891cdf0e10cSrcweir nFormat, rStr );
1892cdf0e10cSrcweir }
1893cdf0e10cSrcweir break;
1894cdf0e10cSrcweir case CELLTYPE_FORMULA :
1895cdf0e10cSrcweir ((ScFormulaCell*)pCell)->SetInChangeTrack( sal_True );
1896cdf0e10cSrcweir break;
1897cdf0e10cSrcweir default:
1898cdf0e10cSrcweir {
1899cdf0e10cSrcweir // added to avoid warnings
1900cdf0e10cSrcweir }
1901cdf0e10cSrcweir }
1902cdf0e10cSrcweir }
1903cdf0e10cSrcweir }
1904cdf0e10cSrcweir
1905cdf0e10cSrcweir
GetValueString(String & rStr,const String & rValue,const ScBaseCell * pCell) const1906cdf0e10cSrcweir void ScChangeActionContent::GetValueString( String& rStr,
1907cdf0e10cSrcweir const String& rValue, const ScBaseCell* pCell ) const
1908cdf0e10cSrcweir {
1909cdf0e10cSrcweir if ( !rValue.Len() )
1910cdf0e10cSrcweir {
1911cdf0e10cSrcweir if ( pCell )
1912cdf0e10cSrcweir {
1913cdf0e10cSrcweir switch ( pCell->GetCellType() )
1914cdf0e10cSrcweir {
1915cdf0e10cSrcweir case CELLTYPE_STRING :
1916cdf0e10cSrcweir ((ScStringCell*)pCell)->GetString( rStr );
1917cdf0e10cSrcweir break;
1918cdf0e10cSrcweir case CELLTYPE_EDIT :
1919cdf0e10cSrcweir ((ScEditCell*)pCell)->GetString( rStr );
1920cdf0e10cSrcweir break;
1921cdf0e10cSrcweir case CELLTYPE_VALUE : // ist immer in rValue
1922cdf0e10cSrcweir rStr = rValue;
1923cdf0e10cSrcweir break;
1924cdf0e10cSrcweir case CELLTYPE_FORMULA :
1925cdf0e10cSrcweir GetFormulaString( rStr, (ScFormulaCell*) pCell );
1926cdf0e10cSrcweir break;
1927cdf0e10cSrcweir default:
1928cdf0e10cSrcweir {
1929cdf0e10cSrcweir // added to avoid warnings
1930cdf0e10cSrcweir }
1931cdf0e10cSrcweir }
1932cdf0e10cSrcweir }
1933cdf0e10cSrcweir else
1934cdf0e10cSrcweir rStr.Erase();
1935cdf0e10cSrcweir }
1936cdf0e10cSrcweir else
1937cdf0e10cSrcweir rStr = rValue;
1938cdf0e10cSrcweir }
1939cdf0e10cSrcweir
1940cdf0e10cSrcweir
GetFormulaString(String & rStr,const ScFormulaCell * pCell) const1941cdf0e10cSrcweir void ScChangeActionContent::GetFormulaString( String& rStr,
1942cdf0e10cSrcweir const ScFormulaCell* pCell ) const
1943cdf0e10cSrcweir {
1944cdf0e10cSrcweir ScAddress aPos( aBigRange.aStart.MakeAddress() );
1945cdf0e10cSrcweir if ( aPos == pCell->aPos || IsDeletedIn() )
1946cdf0e10cSrcweir pCell->GetFormula( rStr );
1947cdf0e10cSrcweir else
1948cdf0e10cSrcweir {
1949cdf0e10cSrcweir DBG_ERROR( "ScChangeActionContent::GetFormulaString: aPos != pCell->aPos" );
1950cdf0e10cSrcweir ScFormulaCell* pNew = new ScFormulaCell( *pCell, *pCell->GetDocument(), aPos );
1951cdf0e10cSrcweir pNew->GetFormula( rStr );
1952cdf0e10cSrcweir delete pNew;
1953cdf0e10cSrcweir }
1954cdf0e10cSrcweir }
1955cdf0e10cSrcweir
1956cdf0e10cSrcweir
PutOldValueToDoc(ScDocument * pDoc,SCsCOL nDx,SCsROW nDy) const1957cdf0e10cSrcweir void ScChangeActionContent::PutOldValueToDoc( ScDocument* pDoc,
1958cdf0e10cSrcweir SCsCOL nDx, SCsROW nDy ) const
1959cdf0e10cSrcweir {
1960cdf0e10cSrcweir PutValueToDoc( pOldCell, aOldValue, pDoc, nDx, nDy );
1961cdf0e10cSrcweir }
1962cdf0e10cSrcweir
1963cdf0e10cSrcweir
PutNewValueToDoc(ScDocument * pDoc,SCsCOL nDx,SCsROW nDy) const1964cdf0e10cSrcweir void ScChangeActionContent::PutNewValueToDoc( ScDocument* pDoc,
1965cdf0e10cSrcweir SCsCOL nDx, SCsROW nDy ) const
1966cdf0e10cSrcweir {
1967cdf0e10cSrcweir PutValueToDoc( pNewCell, aNewValue, pDoc, nDx, nDy );
1968cdf0e10cSrcweir }
1969cdf0e10cSrcweir
1970cdf0e10cSrcweir
PutValueToDoc(ScBaseCell * pCell,const String & rValue,ScDocument * pDoc,SCsCOL nDx,SCsROW nDy) const1971cdf0e10cSrcweir void ScChangeActionContent::PutValueToDoc( ScBaseCell* pCell,
1972cdf0e10cSrcweir const String& rValue, ScDocument* pDoc, SCsCOL nDx, SCsROW nDy ) const
1973cdf0e10cSrcweir {
1974cdf0e10cSrcweir ScAddress aPos( aBigRange.aStart.MakeAddress() );
1975cdf0e10cSrcweir if ( nDx )
1976cdf0e10cSrcweir aPos.IncCol( nDx );
1977cdf0e10cSrcweir if ( nDy )
1978cdf0e10cSrcweir aPos.IncRow( nDy );
1979cdf0e10cSrcweir if ( !rValue.Len() )
1980cdf0e10cSrcweir {
1981cdf0e10cSrcweir if ( pCell )
1982cdf0e10cSrcweir {
1983cdf0e10cSrcweir switch ( pCell->GetCellType() )
1984cdf0e10cSrcweir {
1985cdf0e10cSrcweir case CELLTYPE_VALUE : // ist immer in rValue
1986cdf0e10cSrcweir pDoc->SetString( aPos.Col(), aPos.Row(), aPos.Tab(), rValue );
1987cdf0e10cSrcweir break;
1988cdf0e10cSrcweir default:
1989cdf0e10cSrcweir switch ( ScChangeActionContent::GetContentCellType( pCell ) )
1990cdf0e10cSrcweir {
1991cdf0e10cSrcweir case SC_CACCT_MATORG :
1992cdf0e10cSrcweir {
1993cdf0e10cSrcweir SCCOL nC;
1994cdf0e10cSrcweir SCROW nR;
1995cdf0e10cSrcweir ((const ScFormulaCell*)pCell)->GetMatColsRows( nC, nR );
1996cdf0e10cSrcweir DBG_ASSERT( nC>0 && nR>0, "ScChangeActionContent::PutValueToDoc: MatColsRows?" );
1997cdf0e10cSrcweir ScRange aRange( aPos );
1998cdf0e10cSrcweir if ( nC > 1 )
1999cdf0e10cSrcweir aRange.aEnd.IncCol( nC-1 );
2000cdf0e10cSrcweir if ( nR > 1 )
2001cdf0e10cSrcweir aRange.aEnd.IncRow( nR-1 );
2002cdf0e10cSrcweir ScMarkData aDestMark;
2003cdf0e10cSrcweir aDestMark.SelectOneTable( aPos.Tab() );
2004cdf0e10cSrcweir aDestMark.SetMarkArea( aRange );
2005cdf0e10cSrcweir pDoc->InsertMatrixFormula( aPos.Col(), aPos.Row(),
2006cdf0e10cSrcweir aRange.aEnd.Col(), aRange.aEnd.Row(),
2007cdf0e10cSrcweir aDestMark, EMPTY_STRING,
2008cdf0e10cSrcweir ((const ScFormulaCell*)pCell)->GetCode() );
2009cdf0e10cSrcweir }
2010cdf0e10cSrcweir break;
2011cdf0e10cSrcweir case SC_CACCT_MATREF :
2012cdf0e10cSrcweir // nothing
2013cdf0e10cSrcweir break;
2014cdf0e10cSrcweir default:
2015cdf0e10cSrcweir pDoc->PutCell( aPos, pCell->CloneWithoutNote( *pDoc ) );
2016cdf0e10cSrcweir }
2017cdf0e10cSrcweir }
2018cdf0e10cSrcweir }
2019cdf0e10cSrcweir else
2020cdf0e10cSrcweir pDoc->PutCell( aPos, NULL );
2021cdf0e10cSrcweir }
2022cdf0e10cSrcweir else
2023cdf0e10cSrcweir pDoc->SetString( aPos.Col(), aPos.Row(), aPos.Tab(), rValue );
2024cdf0e10cSrcweir }
2025cdf0e10cSrcweir
2026cdf0e10cSrcweir
lcl_InvalidateReference(ScToken & rTok,const ScBigAddress & rPos)2027cdf0e10cSrcweir void lcl_InvalidateReference( ScToken& rTok, const ScBigAddress& rPos )
2028cdf0e10cSrcweir {
2029cdf0e10cSrcweir ScSingleRefData& rRef1 = rTok.GetSingleRef();
2030cdf0e10cSrcweir if ( rPos.Col() < 0 || MAXCOL < rPos.Col() )
2031cdf0e10cSrcweir {
2032cdf0e10cSrcweir rRef1.nCol = SCCOL_MAX;
2033cdf0e10cSrcweir rRef1.nRelCol = SCCOL_MAX;
2034cdf0e10cSrcweir rRef1.SetColDeleted( sal_True );
2035cdf0e10cSrcweir }
2036cdf0e10cSrcweir if ( rPos.Row() < 0 || MAXROW < rPos.Row() )
2037cdf0e10cSrcweir {
2038cdf0e10cSrcweir rRef1.nRow = SCROW_MAX;
2039cdf0e10cSrcweir rRef1.nRelRow = SCROW_MAX;
2040cdf0e10cSrcweir rRef1.SetRowDeleted( sal_True );
2041cdf0e10cSrcweir }
2042cdf0e10cSrcweir if ( rPos.Tab() < 0 || MAXTAB < rPos.Tab() )
2043cdf0e10cSrcweir {
2044cdf0e10cSrcweir rRef1.nTab = SCTAB_MAX;
2045cdf0e10cSrcweir rRef1.nRelTab = SCTAB_MAX;
2046cdf0e10cSrcweir rRef1.SetTabDeleted( sal_True );
2047cdf0e10cSrcweir }
2048cdf0e10cSrcweir if ( rTok.GetType() == formula::svDoubleRef )
2049cdf0e10cSrcweir {
2050cdf0e10cSrcweir ScSingleRefData& rRef2 = rTok.GetDoubleRef().Ref2;
2051cdf0e10cSrcweir if ( rPos.Col() < 0 || MAXCOL < rPos.Col() )
2052cdf0e10cSrcweir {
2053cdf0e10cSrcweir rRef2.nCol = SCCOL_MAX;
2054cdf0e10cSrcweir rRef2.nRelCol = SCCOL_MAX;
2055cdf0e10cSrcweir rRef2.SetColDeleted( sal_True );
2056cdf0e10cSrcweir }
2057cdf0e10cSrcweir if ( rPos.Row() < 0 || MAXROW < rPos.Row() )
2058cdf0e10cSrcweir {
2059cdf0e10cSrcweir rRef2.nRow = SCROW_MAX;
2060cdf0e10cSrcweir rRef2.nRelRow = SCROW_MAX;
2061cdf0e10cSrcweir rRef2.SetRowDeleted( sal_True );
2062cdf0e10cSrcweir }
2063cdf0e10cSrcweir if ( rPos.Tab() < 0 || MAXTAB < rPos.Tab() )
2064cdf0e10cSrcweir {
2065cdf0e10cSrcweir rRef2.nTab = SCTAB_MAX;
2066cdf0e10cSrcweir rRef2.nRelTab = SCTAB_MAX;
2067cdf0e10cSrcweir rRef2.SetTabDeleted( sal_True );
2068cdf0e10cSrcweir }
2069cdf0e10cSrcweir }
2070cdf0e10cSrcweir }
2071cdf0e10cSrcweir
2072cdf0e10cSrcweir
UpdateReference(const ScChangeTrack * pTrack,UpdateRefMode eMode,const ScBigRange & rRange,sal_Int32 nDx,sal_Int32 nDy,sal_Int32 nDz)2073cdf0e10cSrcweir void ScChangeActionContent::UpdateReference( const ScChangeTrack* pTrack,
2074cdf0e10cSrcweir UpdateRefMode eMode, const ScBigRange& rRange,
2075cdf0e10cSrcweir sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz )
2076cdf0e10cSrcweir {
2077cdf0e10cSrcweir SCSIZE nOldSlot = ScChangeTrack::ComputeContentSlot( aBigRange.aStart.Row() );
2078cdf0e10cSrcweir ScRefUpdate::Update( eMode, rRange, nDx, nDy, nDz, aBigRange );
2079cdf0e10cSrcweir SCSIZE nNewSlot = ScChangeTrack::ComputeContentSlot( aBigRange.aStart.Row() );
2080cdf0e10cSrcweir if ( nNewSlot != nOldSlot )
2081cdf0e10cSrcweir {
2082cdf0e10cSrcweir RemoveFromSlot();
2083cdf0e10cSrcweir InsertInSlot( &(pTrack->GetContentSlots()[nNewSlot]) );
2084cdf0e10cSrcweir }
2085cdf0e10cSrcweir
2086cdf0e10cSrcweir if ( pTrack->IsInDelete() && !pTrack->IsInDeleteTop() )
2087cdf0e10cSrcweir return ; // Formeln nur kompletten Bereich updaten
2088cdf0e10cSrcweir
2089cdf0e10cSrcweir sal_Bool bOldFormula = ( pOldCell && pOldCell->GetCellType() == CELLTYPE_FORMULA );
2090cdf0e10cSrcweir sal_Bool bNewFormula = ( pNewCell && pNewCell->GetCellType() == CELLTYPE_FORMULA );
2091cdf0e10cSrcweir if ( bOldFormula || bNewFormula )
2092cdf0e10cSrcweir { // via ScFormulaCell UpdateReference anpassen (dort)
2093cdf0e10cSrcweir if ( pTrack->IsInDelete() )
2094cdf0e10cSrcweir {
2095cdf0e10cSrcweir const ScRange& rDelRange = pTrack->GetInDeleteRange();
2096cdf0e10cSrcweir if ( nDx > 0 )
2097cdf0e10cSrcweir nDx = rDelRange.aEnd.Col() - rDelRange.aStart.Col() + 1;
2098cdf0e10cSrcweir else if ( nDx < 0 )
2099cdf0e10cSrcweir nDx = -(rDelRange.aEnd.Col() - rDelRange.aStart.Col() + 1);
2100cdf0e10cSrcweir if ( nDy > 0 )
2101cdf0e10cSrcweir nDy = rDelRange.aEnd.Row() - rDelRange.aStart.Row() + 1;
2102cdf0e10cSrcweir else if ( nDy < 0 )
2103cdf0e10cSrcweir nDy = -(rDelRange.aEnd.Row() - rDelRange.aStart.Row() + 1);
2104cdf0e10cSrcweir if ( nDz > 0 )
2105cdf0e10cSrcweir nDz = rDelRange.aEnd.Tab() - rDelRange.aStart.Tab() + 1;
2106cdf0e10cSrcweir else if ( nDz < 0 )
2107cdf0e10cSrcweir nDz = -(rDelRange.aEnd.Tab() - rDelRange.aStart.Tab() + 1);
2108cdf0e10cSrcweir }
2109cdf0e10cSrcweir ScBigRange aTmpRange( rRange );
2110cdf0e10cSrcweir switch ( eMode )
2111cdf0e10cSrcweir {
2112cdf0e10cSrcweir case URM_INSDEL :
2113cdf0e10cSrcweir if ( nDx < 0 || nDy < 0 || nDz < 0 )
2114cdf0e10cSrcweir { // Delete startet dort hinter geloeschtem Bereich,
2115cdf0e10cSrcweir // Position wird dort angepasst.
2116cdf0e10cSrcweir if ( nDx )
2117cdf0e10cSrcweir aTmpRange.aStart.IncCol( -nDx );
2118cdf0e10cSrcweir if ( nDy )
2119cdf0e10cSrcweir aTmpRange.aStart.IncRow( -nDy );
2120cdf0e10cSrcweir if ( nDz )
2121cdf0e10cSrcweir aTmpRange.aStart.IncTab( -nDz );
2122cdf0e10cSrcweir }
2123cdf0e10cSrcweir break;
2124cdf0e10cSrcweir case URM_MOVE :
2125cdf0e10cSrcweir // Move ist hier Quelle, dort Ziel,
2126cdf0e10cSrcweir // Position muss vorher angepasst sein.
2127cdf0e10cSrcweir if ( bOldFormula )
2128cdf0e10cSrcweir ((ScFormulaCell*)pOldCell)->aPos = aBigRange.aStart.MakeAddress();
2129cdf0e10cSrcweir if ( bNewFormula )
2130cdf0e10cSrcweir ((ScFormulaCell*)pNewCell)->aPos = aBigRange.aStart.MakeAddress();
2131cdf0e10cSrcweir if ( nDx )
2132cdf0e10cSrcweir {
2133cdf0e10cSrcweir aTmpRange.aStart.IncCol( nDx );
2134cdf0e10cSrcweir aTmpRange.aEnd.IncCol( nDx );
2135cdf0e10cSrcweir }
2136cdf0e10cSrcweir if ( nDy )
2137cdf0e10cSrcweir {
2138cdf0e10cSrcweir aTmpRange.aStart.IncRow( nDy );
2139cdf0e10cSrcweir aTmpRange.aEnd.IncRow( nDy );
2140cdf0e10cSrcweir }
2141cdf0e10cSrcweir if ( nDz )
2142cdf0e10cSrcweir {
2143cdf0e10cSrcweir aTmpRange.aStart.IncTab( nDz );
2144cdf0e10cSrcweir aTmpRange.aEnd.IncTab( nDz );
2145cdf0e10cSrcweir }
2146cdf0e10cSrcweir break;
2147cdf0e10cSrcweir default:
2148cdf0e10cSrcweir {
2149cdf0e10cSrcweir // added to avoid warnings
2150cdf0e10cSrcweir }
2151cdf0e10cSrcweir }
2152cdf0e10cSrcweir ScRange aRange( aTmpRange.MakeRange() );
2153cdf0e10cSrcweir if ( bOldFormula )
2154cdf0e10cSrcweir ((ScFormulaCell*)pOldCell)->UpdateReference( eMode, aRange,
2155cdf0e10cSrcweir (SCsCOL) nDx, (SCsROW) nDy, (SCsTAB) nDz, NULL );
2156cdf0e10cSrcweir if ( bNewFormula )
2157cdf0e10cSrcweir ((ScFormulaCell*)pNewCell)->UpdateReference( eMode, aRange,
2158cdf0e10cSrcweir (SCsCOL) nDx, (SCsROW) nDy, (SCsTAB) nDz, NULL );
2159cdf0e10cSrcweir if ( !aBigRange.aStart.IsValid( pTrack->GetDocument() ) )
2160cdf0e10cSrcweir { //! HACK!
2161cdf0e10cSrcweir //! UpdateReference kann nicht mit Positionen ausserhalb des
2162cdf0e10cSrcweir //! Dokuments umgehen, deswegen alles auf #REF! setzen
2163cdf0e10cSrcweir //2do: make it possible! das bedeutet grossen Umbau von ScAddress etc.!
2164cdf0e10cSrcweir const ScBigAddress& rPos = aBigRange.aStart;
2165cdf0e10cSrcweir if ( bOldFormula )
2166cdf0e10cSrcweir {
2167cdf0e10cSrcweir ScToken* t;
2168cdf0e10cSrcweir ScTokenArray* pArr = ((ScFormulaCell*)pOldCell)->GetCode();
2169cdf0e10cSrcweir pArr->Reset();
2170cdf0e10cSrcweir while ( ( t = static_cast<ScToken*>(pArr->GetNextReference()) ) != NULL )
2171cdf0e10cSrcweir lcl_InvalidateReference( *t, rPos );
2172cdf0e10cSrcweir pArr->Reset();
2173cdf0e10cSrcweir while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
2174cdf0e10cSrcweir lcl_InvalidateReference( *t, rPos );
2175cdf0e10cSrcweir }
2176cdf0e10cSrcweir if ( bNewFormula )
2177cdf0e10cSrcweir {
2178cdf0e10cSrcweir ScToken* t;
2179cdf0e10cSrcweir ScTokenArray* pArr = ((ScFormulaCell*)pNewCell)->GetCode();
2180cdf0e10cSrcweir pArr->Reset();
2181cdf0e10cSrcweir while ( ( t = static_cast<ScToken*>(pArr->GetNextReference()) ) != NULL )
2182cdf0e10cSrcweir lcl_InvalidateReference( *t, rPos );
2183cdf0e10cSrcweir pArr->Reset();
2184cdf0e10cSrcweir while ( ( t = static_cast<ScToken*>(pArr->GetNextReferenceRPN()) ) != NULL )
2185cdf0e10cSrcweir lcl_InvalidateReference( *t, rPos );
2186cdf0e10cSrcweir }
2187cdf0e10cSrcweir }
2188cdf0e10cSrcweir }
2189cdf0e10cSrcweir }
2190cdf0e10cSrcweir
2191cdf0e10cSrcweir
2192cdf0e10cSrcweir // --- ScChangeActionReject ------------------------------------------------
2193cdf0e10cSrcweir
ScChangeActionReject(const sal_uLong nActionNumber,const ScChangeActionState eStateP,const sal_uLong nRejectingNumber,const ScBigRange & aBigRangeP,const String & aUserP,const DateTime & aDateTimeP,const String & sComment)2194cdf0e10cSrcweir ScChangeActionReject::ScChangeActionReject(const sal_uLong nActionNumber, const ScChangeActionState eStateP, const sal_uLong nRejectingNumber,
2195cdf0e10cSrcweir const ScBigRange& aBigRangeP, const String& aUserP, const DateTime& aDateTimeP, const String& sComment)
2196cdf0e10cSrcweir :
2197cdf0e10cSrcweir ScChangeAction(SC_CAT_CONTENT, aBigRangeP, nActionNumber, nRejectingNumber, eStateP, aDateTimeP, aUserP, sComment)
2198cdf0e10cSrcweir {
2199cdf0e10cSrcweir }
2200cdf0e10cSrcweir
2201cdf0e10cSrcweir
2202cdf0e10cSrcweir // --- ScChangeTrack -------------------------------------------------------
2203cdf0e10cSrcweir
2204cdf0e10cSrcweir IMPL_FIXEDMEMPOOL_NEWDEL( ScChangeTrackMsgInfo, 16, 16 )
2205cdf0e10cSrcweir
2206cdf0e10cSrcweir const SCROW ScChangeTrack::nContentRowsPerSlot = InitContentRowsPerSlot();
2207cdf0e10cSrcweir const SCSIZE ScChangeTrack::nContentSlots =
2208cdf0e10cSrcweir (MAXROWCOUNT) / InitContentRowsPerSlot() + 2;
2209cdf0e10cSrcweir
2210cdf0e10cSrcweir // static
InitContentRowsPerSlot()2211cdf0e10cSrcweir SCROW ScChangeTrack::InitContentRowsPerSlot()
2212cdf0e10cSrcweir {
2213cdf0e10cSrcweir const SCSIZE nMaxSlots = 0xffe0 / sizeof( ScChangeActionContent* ) - 2;
2214cdf0e10cSrcweir SCROW nRowsPerSlot = (MAXROWCOUNT) / nMaxSlots;
2215cdf0e10cSrcweir if ( nRowsPerSlot * nMaxSlots < sal::static_int_cast<SCSIZE>(MAXROWCOUNT) )
2216cdf0e10cSrcweir ++nRowsPerSlot;
2217cdf0e10cSrcweir return nRowsPerSlot;
2218cdf0e10cSrcweir }
2219cdf0e10cSrcweir
2220cdf0e10cSrcweir
ScChangeTrack(ScDocument * pDocP)2221cdf0e10cSrcweir ScChangeTrack::ScChangeTrack( ScDocument* pDocP ) :
2222cdf0e10cSrcweir pDoc( pDocP )
2223cdf0e10cSrcweir {
2224cdf0e10cSrcweir Init();
2225cdf0e10cSrcweir SC_MOD()->GetUserOptions().AddListener(this);
2226cdf0e10cSrcweir
2227cdf0e10cSrcweir ppContentSlots = new ScChangeActionContent* [ nContentSlots ];
2228cdf0e10cSrcweir memset( ppContentSlots, 0, nContentSlots * sizeof( ScChangeActionContent* ) );
2229cdf0e10cSrcweir }
2230cdf0e10cSrcweir
ScChangeTrack(ScDocument * pDocP,const ScStrCollection & aTempUserCollection)2231cdf0e10cSrcweir ScChangeTrack::ScChangeTrack( ScDocument* pDocP, const ScStrCollection& aTempUserCollection) :
2232cdf0e10cSrcweir aUserCollection(aTempUserCollection),
2233cdf0e10cSrcweir pDoc( pDocP )
2234cdf0e10cSrcweir {
2235cdf0e10cSrcweir Init();
2236cdf0e10cSrcweir SC_MOD()->GetUserOptions().AddListener(this);
2237cdf0e10cSrcweir ppContentSlots = new ScChangeActionContent* [ nContentSlots ];
2238cdf0e10cSrcweir memset( ppContentSlots, 0, nContentSlots * sizeof( ScChangeActionContent* ) );
2239cdf0e10cSrcweir }
2240cdf0e10cSrcweir
~ScChangeTrack()2241cdf0e10cSrcweir ScChangeTrack::~ScChangeTrack()
2242cdf0e10cSrcweir {
2243cdf0e10cSrcweir SC_MOD()->GetUserOptions().RemoveListener(this);
2244cdf0e10cSrcweir DtorClear();
2245cdf0e10cSrcweir delete [] ppContentSlots;
2246cdf0e10cSrcweir }
2247cdf0e10cSrcweir
2248cdf0e10cSrcweir
Init()2249cdf0e10cSrcweir void ScChangeTrack::Init()
2250cdf0e10cSrcweir {
2251cdf0e10cSrcweir pFirst = NULL;
2252cdf0e10cSrcweir pLast = NULL;
2253cdf0e10cSrcweir pFirstGeneratedDelContent = NULL;
2254cdf0e10cSrcweir pLastCutMove = NULL;
2255cdf0e10cSrcweir pLinkInsertCol = NULL;
2256cdf0e10cSrcweir pLinkInsertRow = NULL;
2257cdf0e10cSrcweir pLinkInsertTab = NULL;
2258cdf0e10cSrcweir pLinkMove = NULL;
2259cdf0e10cSrcweir pBlockModifyMsg = NULL;
2260cdf0e10cSrcweir nActionMax = 0;
2261cdf0e10cSrcweir nGeneratedMin = SC_CHGTRACK_GENERATED_START;
2262cdf0e10cSrcweir nMarkLastSaved = 0;
2263cdf0e10cSrcweir nStartLastCut = 0;
2264cdf0e10cSrcweir nEndLastCut = 0;
2265cdf0e10cSrcweir nLastMerge = 0;
2266cdf0e10cSrcweir eMergeState = SC_CTMS_NONE;
2267cdf0e10cSrcweir nLoadedFileFormatVersion = SC_CHGTRACK_FILEFORMAT;
2268cdf0e10cSrcweir bLoadSave = sal_False;
2269cdf0e10cSrcweir bInDelete = sal_False;
2270cdf0e10cSrcweir bInDeleteTop = sal_False;
2271cdf0e10cSrcweir bInDeleteUndo = sal_False;
2272cdf0e10cSrcweir bInPasteCut = sal_False;
2273cdf0e10cSrcweir bUseFixDateTime = sal_False;
2274cdf0e10cSrcweir bTime100thSeconds = sal_True;
2275cdf0e10cSrcweir
2276cdf0e10cSrcweir const SvtUserOptions& rUserOpt = SC_MOD()->GetUserOptions();
2277cdf0e10cSrcweir aUser = rUserOpt.GetFirstName();
2278cdf0e10cSrcweir aUser += ' ';
2279cdf0e10cSrcweir aUser += (String)rUserOpt.GetLastName();
2280cdf0e10cSrcweir aUserCollection.Insert( new StrData( aUser ) );
2281cdf0e10cSrcweir }
2282cdf0e10cSrcweir
2283cdf0e10cSrcweir
DtorClear()2284cdf0e10cSrcweir void ScChangeTrack::DtorClear()
2285cdf0e10cSrcweir {
2286cdf0e10cSrcweir ScChangeAction* p;
2287cdf0e10cSrcweir ScChangeAction* pNext;
2288cdf0e10cSrcweir for ( p = GetFirst(); p; p = pNext )
2289cdf0e10cSrcweir {
2290cdf0e10cSrcweir pNext = p->GetNext();
2291cdf0e10cSrcweir delete p;
2292cdf0e10cSrcweir }
2293cdf0e10cSrcweir for ( p = pFirstGeneratedDelContent; p; p = pNext )
2294cdf0e10cSrcweir {
2295cdf0e10cSrcweir pNext = p->GetNext();
2296cdf0e10cSrcweir delete p;
2297cdf0e10cSrcweir }
2298cdf0e10cSrcweir for ( p = aPasteCutTable.First(); p; p = aPasteCutTable.Next() )
2299cdf0e10cSrcweir {
2300cdf0e10cSrcweir delete p;
2301cdf0e10cSrcweir }
2302cdf0e10cSrcweir delete pLastCutMove;
2303cdf0e10cSrcweir ClearMsgQueue();
2304cdf0e10cSrcweir }
2305cdf0e10cSrcweir
2306cdf0e10cSrcweir
ClearMsgQueue()2307cdf0e10cSrcweir void ScChangeTrack::ClearMsgQueue()
2308cdf0e10cSrcweir {
2309cdf0e10cSrcweir if ( pBlockModifyMsg )
2310cdf0e10cSrcweir {
2311cdf0e10cSrcweir delete pBlockModifyMsg;
2312cdf0e10cSrcweir pBlockModifyMsg = NULL;
2313cdf0e10cSrcweir }
2314cdf0e10cSrcweir ScChangeTrackMsgInfo* pMsgInfo;
2315cdf0e10cSrcweir while ( ( pMsgInfo = aMsgStackTmp.Pop() ) != NULL )
2316cdf0e10cSrcweir delete pMsgInfo;
2317cdf0e10cSrcweir while ( ( pMsgInfo = aMsgStackFinal.Pop() ) != NULL )
2318cdf0e10cSrcweir delete pMsgInfo;
2319cdf0e10cSrcweir while ( ( pMsgInfo = aMsgQueue.Get() ) != NULL )
2320cdf0e10cSrcweir delete pMsgInfo;
2321cdf0e10cSrcweir }
2322cdf0e10cSrcweir
2323cdf0e10cSrcweir
Clear()2324cdf0e10cSrcweir void ScChangeTrack::Clear()
2325cdf0e10cSrcweir {
2326cdf0e10cSrcweir DtorClear();
2327cdf0e10cSrcweir aTable.Clear();
2328cdf0e10cSrcweir aGeneratedTable.Clear();
2329cdf0e10cSrcweir aPasteCutTable.Clear();
2330cdf0e10cSrcweir aUserCollection.FreeAll();
2331cdf0e10cSrcweir aUser.Erase();
2332cdf0e10cSrcweir Init();
2333cdf0e10cSrcweir }
2334cdf0e10cSrcweir
2335cdf0e10cSrcweir
ConfigurationChanged(utl::ConfigurationBroadcaster *,sal_uInt32)2336cdf0e10cSrcweir void __EXPORT ScChangeTrack::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 )
2337cdf0e10cSrcweir {
2338cdf0e10cSrcweir if ( !pDoc->IsInDtorClear() )
2339cdf0e10cSrcweir {
2340cdf0e10cSrcweir const SvtUserOptions& rUserOptions = SC_MOD()->GetUserOptions();
2341cdf0e10cSrcweir sal_uInt16 nOldCount = aUserCollection.GetCount();
2342cdf0e10cSrcweir
2343cdf0e10cSrcweir String aStr( rUserOptions.GetFirstName() );
2344cdf0e10cSrcweir aStr += ' ';
2345cdf0e10cSrcweir aStr += (String)rUserOptions.GetLastName();
2346cdf0e10cSrcweir SetUser( aStr );
2347cdf0e10cSrcweir
2348cdf0e10cSrcweir if ( aUserCollection.GetCount() != nOldCount )
2349cdf0e10cSrcweir {
2350cdf0e10cSrcweir // New user in collection -> have to repaint because
2351cdf0e10cSrcweir // colors may be different now (#106697#).
2352cdf0e10cSrcweir // (Has to be done in the Notify handler, to be sure
2353cdf0e10cSrcweir // the user collection has already been updated)
2354cdf0e10cSrcweir
2355cdf0e10cSrcweir SfxObjectShell* pDocSh = pDoc->GetDocumentShell();
2356cdf0e10cSrcweir if (pDocSh)
2357cdf0e10cSrcweir pDocSh->Broadcast( ScPaintHint( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB), PAINT_GRID ) );
2358cdf0e10cSrcweir }
2359cdf0e10cSrcweir }
2360cdf0e10cSrcweir }
2361cdf0e10cSrcweir
2362cdf0e10cSrcweir
SetUser(const String & rUser)2363cdf0e10cSrcweir void ScChangeTrack::SetUser( const String& rUser )
2364cdf0e10cSrcweir {
2365cdf0e10cSrcweir if ( IsLoadSave() )
2366cdf0e10cSrcweir return ; // nicht die Collection zerschiessen
2367cdf0e10cSrcweir
2368cdf0e10cSrcweir aUser = rUser;
2369cdf0e10cSrcweir StrData* pStrData = new StrData( aUser );
2370cdf0e10cSrcweir if ( !aUserCollection.Insert( pStrData ) )
2371cdf0e10cSrcweir delete pStrData;
2372cdf0e10cSrcweir }
2373cdf0e10cSrcweir
2374cdf0e10cSrcweir
StartBlockModify(ScChangeTrackMsgType eMsgType,sal_uLong nStartAction)2375cdf0e10cSrcweir void ScChangeTrack::StartBlockModify( ScChangeTrackMsgType eMsgType,
2376cdf0e10cSrcweir sal_uLong nStartAction )
2377cdf0e10cSrcweir {
2378cdf0e10cSrcweir if ( aModifiedLink.IsSet() )
2379cdf0e10cSrcweir {
2380cdf0e10cSrcweir if ( pBlockModifyMsg )
2381cdf0e10cSrcweir aMsgStackTmp.Push( pBlockModifyMsg ); // Block im Block
2382cdf0e10cSrcweir pBlockModifyMsg = new ScChangeTrackMsgInfo;
2383cdf0e10cSrcweir pBlockModifyMsg->eMsgType = eMsgType;
2384cdf0e10cSrcweir pBlockModifyMsg->nStartAction = nStartAction;
2385cdf0e10cSrcweir }
2386cdf0e10cSrcweir }
2387cdf0e10cSrcweir
2388cdf0e10cSrcweir
EndBlockModify(sal_uLong nEndAction)2389cdf0e10cSrcweir void ScChangeTrack::EndBlockModify( sal_uLong nEndAction )
2390cdf0e10cSrcweir {
2391cdf0e10cSrcweir if ( aModifiedLink.IsSet() )
2392cdf0e10cSrcweir {
2393cdf0e10cSrcweir if ( pBlockModifyMsg )
2394cdf0e10cSrcweir {
2395cdf0e10cSrcweir if ( pBlockModifyMsg->nStartAction <= nEndAction )
2396cdf0e10cSrcweir {
2397cdf0e10cSrcweir pBlockModifyMsg->nEndAction = nEndAction;
2398cdf0e10cSrcweir // Blocks in Blocks aufgeloest
2399cdf0e10cSrcweir aMsgStackFinal.Push( pBlockModifyMsg );
2400cdf0e10cSrcweir }
2401cdf0e10cSrcweir else
2402cdf0e10cSrcweir delete pBlockModifyMsg;
2403cdf0e10cSrcweir pBlockModifyMsg = aMsgStackTmp.Pop(); // evtl. Block im Block
2404cdf0e10cSrcweir }
2405cdf0e10cSrcweir if ( !pBlockModifyMsg )
2406cdf0e10cSrcweir {
2407cdf0e10cSrcweir sal_Bool bNew = sal_False;
2408cdf0e10cSrcweir ScChangeTrackMsgInfo* pMsg;
2409cdf0e10cSrcweir while ( ( pMsg = aMsgStackFinal.Pop() ) != NULL )
2410cdf0e10cSrcweir {
2411cdf0e10cSrcweir aMsgQueue.Put( pMsg );
2412cdf0e10cSrcweir bNew = sal_True;
2413cdf0e10cSrcweir }
2414cdf0e10cSrcweir if ( bNew )
2415cdf0e10cSrcweir aModifiedLink.Call( this );
2416cdf0e10cSrcweir }
2417cdf0e10cSrcweir }
2418cdf0e10cSrcweir }
2419cdf0e10cSrcweir
2420cdf0e10cSrcweir
NotifyModified(ScChangeTrackMsgType eMsgType,sal_uLong nStartAction,sal_uLong nEndAction)2421cdf0e10cSrcweir void ScChangeTrack::NotifyModified( ScChangeTrackMsgType eMsgType,
2422cdf0e10cSrcweir sal_uLong nStartAction, sal_uLong nEndAction )
2423cdf0e10cSrcweir {
2424cdf0e10cSrcweir if ( aModifiedLink.IsSet() )
2425cdf0e10cSrcweir {
2426cdf0e10cSrcweir if ( !pBlockModifyMsg || pBlockModifyMsg->eMsgType != eMsgType ||
2427cdf0e10cSrcweir (IsGenerated( nStartAction ) &&
2428cdf0e10cSrcweir (eMsgType == SC_CTM_APPEND || eMsgType == SC_CTM_REMOVE)) )
2429cdf0e10cSrcweir { // Append innerhalb von Append z.B. nicht
2430cdf0e10cSrcweir StartBlockModify( eMsgType, nStartAction );
2431cdf0e10cSrcweir EndBlockModify( nEndAction );
2432cdf0e10cSrcweir }
2433cdf0e10cSrcweir }
2434cdf0e10cSrcweir }
2435cdf0e10cSrcweir
2436cdf0e10cSrcweir
MasterLinks(ScChangeAction * pAppend)2437cdf0e10cSrcweir void ScChangeTrack::MasterLinks( ScChangeAction* pAppend )
2438cdf0e10cSrcweir {
2439cdf0e10cSrcweir ScChangeActionType eType = pAppend->GetType();
2440cdf0e10cSrcweir
2441cdf0e10cSrcweir if ( eType == SC_CAT_CONTENT )
2442cdf0e10cSrcweir {
2443cdf0e10cSrcweir if ( !IsGenerated( pAppend->GetActionNumber() ) )
2444cdf0e10cSrcweir {
2445cdf0e10cSrcweir SCSIZE nSlot = ComputeContentSlot(
2446cdf0e10cSrcweir pAppend->GetBigRange().aStart.Row() );
2447cdf0e10cSrcweir ((ScChangeActionContent*)pAppend)->InsertInSlot(
2448cdf0e10cSrcweir &ppContentSlots[nSlot] );
2449cdf0e10cSrcweir }
2450cdf0e10cSrcweir return ;
2451cdf0e10cSrcweir }
2452cdf0e10cSrcweir
2453cdf0e10cSrcweir if ( pAppend->IsRejecting() )
2454cdf0e10cSrcweir return ; // Rejects haben keine Abhaengigkeiten
2455cdf0e10cSrcweir
2456cdf0e10cSrcweir switch ( eType )
2457cdf0e10cSrcweir {
2458cdf0e10cSrcweir case SC_CAT_INSERT_COLS :
2459cdf0e10cSrcweir {
2460cdf0e10cSrcweir ScChangeActionLinkEntry* pLink = new ScChangeActionLinkEntry(
2461cdf0e10cSrcweir &pLinkInsertCol, pAppend );
2462cdf0e10cSrcweir pAppend->AddLink( NULL, pLink );
2463cdf0e10cSrcweir }
2464cdf0e10cSrcweir break;
2465cdf0e10cSrcweir case SC_CAT_INSERT_ROWS :
2466cdf0e10cSrcweir {
2467cdf0e10cSrcweir ScChangeActionLinkEntry* pLink = new ScChangeActionLinkEntry(
2468cdf0e10cSrcweir &pLinkInsertRow, pAppend );
2469cdf0e10cSrcweir pAppend->AddLink( NULL, pLink );
2470cdf0e10cSrcweir }
2471cdf0e10cSrcweir break;
2472cdf0e10cSrcweir case SC_CAT_INSERT_TABS :
2473cdf0e10cSrcweir {
2474cdf0e10cSrcweir ScChangeActionLinkEntry* pLink = new ScChangeActionLinkEntry(
2475cdf0e10cSrcweir &pLinkInsertTab, pAppend );
2476cdf0e10cSrcweir pAppend->AddLink( NULL, pLink );
2477cdf0e10cSrcweir }
2478cdf0e10cSrcweir break;
2479cdf0e10cSrcweir case SC_CAT_MOVE :
2480cdf0e10cSrcweir {
2481cdf0e10cSrcweir ScChangeActionLinkEntry* pLink = new ScChangeActionLinkEntry(
2482cdf0e10cSrcweir &pLinkMove, pAppend );
2483cdf0e10cSrcweir pAppend->AddLink( NULL, pLink );
2484cdf0e10cSrcweir }
2485cdf0e10cSrcweir break;
2486cdf0e10cSrcweir default:
2487cdf0e10cSrcweir {
2488cdf0e10cSrcweir // added to avoid warnings
2489cdf0e10cSrcweir }
2490cdf0e10cSrcweir }
2491cdf0e10cSrcweir }
2492cdf0e10cSrcweir
2493cdf0e10cSrcweir
AppendLoaded(ScChangeAction * pAppend)2494cdf0e10cSrcweir void ScChangeTrack::AppendLoaded( ScChangeAction* pAppend )
2495cdf0e10cSrcweir {
2496cdf0e10cSrcweir aTable.Insert( pAppend->GetActionNumber(), pAppend );
2497cdf0e10cSrcweir if ( !pLast )
2498cdf0e10cSrcweir pFirst = pLast = pAppend;
2499cdf0e10cSrcweir else
2500cdf0e10cSrcweir {
2501cdf0e10cSrcweir pLast->pNext = pAppend;
2502cdf0e10cSrcweir pAppend->pPrev = pLast;
2503cdf0e10cSrcweir pLast = pAppend;
2504cdf0e10cSrcweir }
2505cdf0e10cSrcweir MasterLinks( pAppend );
2506cdf0e10cSrcweir }
2507cdf0e10cSrcweir
2508cdf0e10cSrcweir
Append(ScChangeAction * pAppend,sal_uLong nAction)2509cdf0e10cSrcweir void ScChangeTrack::Append( ScChangeAction* pAppend, sal_uLong nAction )
2510cdf0e10cSrcweir {
2511cdf0e10cSrcweir if ( nActionMax < nAction )
2512cdf0e10cSrcweir nActionMax = nAction;
2513cdf0e10cSrcweir pAppend->SetUser( aUser );
2514cdf0e10cSrcweir if ( bUseFixDateTime )
2515cdf0e10cSrcweir pAppend->SetDateTimeUTC( aFixDateTime );
2516cdf0e10cSrcweir pAppend->SetActionNumber( nAction );
2517cdf0e10cSrcweir aTable.Insert( nAction, pAppend );
2518cdf0e10cSrcweir // UpdateReference Inserts vor Dependencies.
2519cdf0e10cSrcweir // Delete rejectendes Insert hatte UpdateReference mit Delete-Undo.
2520cdf0e10cSrcweir // UpdateReference auch wenn pLast==NULL, weil pAppend ein Delete sein
2521cdf0e10cSrcweir // kann, dass DelContents generiert haben kann
2522cdf0e10cSrcweir if ( pAppend->IsInsertType() && !pAppend->IsRejecting() )
2523cdf0e10cSrcweir UpdateReference( pAppend, sal_False );
2524cdf0e10cSrcweir if ( !pLast )
2525cdf0e10cSrcweir pFirst = pLast = pAppend;
2526cdf0e10cSrcweir else
2527cdf0e10cSrcweir {
2528cdf0e10cSrcweir pLast->pNext = pAppend;
2529cdf0e10cSrcweir pAppend->pPrev = pLast;
2530cdf0e10cSrcweir pLast = pAppend;
2531cdf0e10cSrcweir Dependencies( pAppend );
2532cdf0e10cSrcweir }
2533cdf0e10cSrcweir // UpdateReference Inserts nicht nach Dependencies.
2534cdf0e10cSrcweir // Move rejectendes Move hatte UpdateReference mit Move-Undo, Inhalt in
2535cdf0e10cSrcweir // ToRange nicht deleten.
2536cdf0e10cSrcweir if ( !pAppend->IsInsertType() &&
2537cdf0e10cSrcweir !(pAppend->GetType() == SC_CAT_MOVE && pAppend->IsRejecting()) )
2538cdf0e10cSrcweir UpdateReference( pAppend, sal_False );
2539cdf0e10cSrcweir MasterLinks( pAppend );
2540cdf0e10cSrcweir
2541cdf0e10cSrcweir if ( aModifiedLink.IsSet() )
2542cdf0e10cSrcweir {
2543cdf0e10cSrcweir NotifyModified( SC_CTM_APPEND, nAction, nAction );
2544cdf0e10cSrcweir if ( pAppend->GetType() == SC_CAT_CONTENT )
2545cdf0e10cSrcweir {
2546cdf0e10cSrcweir ScChangeActionContent* pContent = (ScChangeActionContent*) pAppend;
2547cdf0e10cSrcweir if ( ( pContent = pContent->GetPrevContent() ) != NULL )
2548cdf0e10cSrcweir {
2549cdf0e10cSrcweir sal_uLong nMod = pContent->GetActionNumber();
2550cdf0e10cSrcweir NotifyModified( SC_CTM_CHANGE, nMod, nMod );
2551cdf0e10cSrcweir }
2552cdf0e10cSrcweir }
2553cdf0e10cSrcweir else
2554cdf0e10cSrcweir NotifyModified( SC_CTM_CHANGE, pFirst->GetActionNumber(),
2555cdf0e10cSrcweir pLast->GetActionNumber() );
2556cdf0e10cSrcweir }
2557cdf0e10cSrcweir }
2558cdf0e10cSrcweir
2559cdf0e10cSrcweir
Append(ScChangeAction * pAppend)2560cdf0e10cSrcweir void ScChangeTrack::Append( ScChangeAction* pAppend )
2561cdf0e10cSrcweir {
2562cdf0e10cSrcweir Append( pAppend, ++nActionMax );
2563cdf0e10cSrcweir }
2564cdf0e10cSrcweir
2565cdf0e10cSrcweir
AppendDeleteRange(const ScRange & rRange,ScDocument * pRefDoc,sal_uLong & nStartAction,sal_uLong & nEndAction,SCsTAB nDz)2566cdf0e10cSrcweir void ScChangeTrack::AppendDeleteRange( const ScRange& rRange,
2567cdf0e10cSrcweir ScDocument* pRefDoc, sal_uLong& nStartAction, sal_uLong& nEndAction, SCsTAB nDz )
2568cdf0e10cSrcweir {
2569cdf0e10cSrcweir nStartAction = GetActionMax() + 1;
2570cdf0e10cSrcweir AppendDeleteRange( rRange, pRefDoc, nDz, 0 );
2571cdf0e10cSrcweir nEndAction = GetActionMax();
2572cdf0e10cSrcweir }
2573cdf0e10cSrcweir
2574cdf0e10cSrcweir
AppendDeleteRange(const ScRange & rRange,ScDocument * pRefDoc,SCsTAB nDz,sal_uLong nRejectingInsert)2575cdf0e10cSrcweir void ScChangeTrack::AppendDeleteRange( const ScRange& rRange,
2576cdf0e10cSrcweir ScDocument* pRefDoc, SCsTAB nDz, sal_uLong nRejectingInsert )
2577cdf0e10cSrcweir {
2578cdf0e10cSrcweir SetInDeleteRange( rRange );
2579cdf0e10cSrcweir StartBlockModify( SC_CTM_APPEND, GetActionMax() + 1 );
2580cdf0e10cSrcweir SCCOL nCol1;
2581cdf0e10cSrcweir SCROW nRow1;
2582cdf0e10cSrcweir SCTAB nTab1;
2583cdf0e10cSrcweir SCCOL nCol2;
2584cdf0e10cSrcweir SCROW nRow2;
2585cdf0e10cSrcweir SCTAB nTab2;
2586cdf0e10cSrcweir rRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
2587cdf0e10cSrcweir for ( SCTAB nTab = nTab1; nTab <= nTab2; nTab++ )
2588cdf0e10cSrcweir {
2589cdf0e10cSrcweir if ( !pRefDoc || nTab < pRefDoc->GetTableCount() )
2590cdf0e10cSrcweir {
2591cdf0e10cSrcweir if ( nCol1 == 0 && nCol2 == MAXCOL )
2592cdf0e10cSrcweir { // ganze Zeilen und/oder Tabellen
2593cdf0e10cSrcweir if ( nRow1 == 0 && nRow2 == MAXROW )
2594cdf0e10cSrcweir { // ganze Tabellen
2595cdf0e10cSrcweir //2do: geht nicht auch komplette Tabelle als ganzes?
2596cdf0e10cSrcweir ScRange aRange( 0, 0, nTab, 0, MAXROW, nTab );
2597cdf0e10cSrcweir for ( SCCOL nCol = nCol1; nCol <= nCol2; nCol++ )
2598cdf0e10cSrcweir { // spaltenweise ist weniger als zeilenweise
2599cdf0e10cSrcweir aRange.aStart.SetCol( nCol );
2600cdf0e10cSrcweir aRange.aEnd.SetCol( nCol );
2601cdf0e10cSrcweir if ( nCol == nCol2 )
2602cdf0e10cSrcweir SetInDeleteTop( sal_True );
2603cdf0e10cSrcweir AppendOneDeleteRange( aRange, pRefDoc, nCol-nCol1, 0,
2604cdf0e10cSrcweir nTab-nTab1 + nDz, nRejectingInsert );
2605cdf0e10cSrcweir }
2606cdf0e10cSrcweir //! immer noch InDeleteTop
2607cdf0e10cSrcweir AppendOneDeleteRange( rRange, pRefDoc, 0, 0,
2608cdf0e10cSrcweir nTab-nTab1 + nDz, nRejectingInsert );
2609cdf0e10cSrcweir }
2610cdf0e10cSrcweir else
2611cdf0e10cSrcweir { // ganze Zeilen
2612cdf0e10cSrcweir ScRange aRange( 0, 0, nTab, MAXCOL, 0, nTab );
2613cdf0e10cSrcweir for ( SCROW nRow = nRow1; nRow <= nRow2; nRow++ )
2614cdf0e10cSrcweir {
2615cdf0e10cSrcweir aRange.aStart.SetRow( nRow );
2616cdf0e10cSrcweir aRange.aEnd.SetRow( nRow );
2617cdf0e10cSrcweir if ( nRow == nRow2 )
2618cdf0e10cSrcweir SetInDeleteTop( sal_True );
2619cdf0e10cSrcweir AppendOneDeleteRange( aRange, pRefDoc, 0, nRow-nRow1,
2620cdf0e10cSrcweir 0, nRejectingInsert );
2621cdf0e10cSrcweir }
2622cdf0e10cSrcweir }
2623cdf0e10cSrcweir }
2624cdf0e10cSrcweir else if ( nRow1 == 0 && nRow2 == MAXROW )
2625cdf0e10cSrcweir { // ganze Spalten
2626cdf0e10cSrcweir ScRange aRange( 0, 0, nTab, 0, MAXROW, nTab );
2627cdf0e10cSrcweir for ( SCCOL nCol = nCol1; nCol <= nCol2; nCol++ )
2628cdf0e10cSrcweir {
2629cdf0e10cSrcweir aRange.aStart.SetCol( nCol );
2630cdf0e10cSrcweir aRange.aEnd.SetCol( nCol );
2631cdf0e10cSrcweir if ( nCol == nCol2 )
2632cdf0e10cSrcweir SetInDeleteTop( sal_True );
2633cdf0e10cSrcweir AppendOneDeleteRange( aRange, pRefDoc, nCol-nCol1, 0,
2634cdf0e10cSrcweir 0, nRejectingInsert );
2635cdf0e10cSrcweir }
2636cdf0e10cSrcweir }
2637cdf0e10cSrcweir else
2638cdf0e10cSrcweir {
2639cdf0e10cSrcweir DBG_ERROR( "ScChangeTrack::AppendDeleteRange: Block not supported!" );
2640cdf0e10cSrcweir }
2641cdf0e10cSrcweir SetInDeleteTop( sal_False );
2642cdf0e10cSrcweir }
2643cdf0e10cSrcweir }
2644cdf0e10cSrcweir EndBlockModify( GetActionMax() );
2645cdf0e10cSrcweir }
2646cdf0e10cSrcweir
2647cdf0e10cSrcweir
AppendOneDeleteRange(const ScRange & rOrgRange,ScDocument * pRefDoc,SCsCOL nDx,SCsROW nDy,SCsTAB nDz,sal_uLong nRejectingInsert)2648cdf0e10cSrcweir void ScChangeTrack::AppendOneDeleteRange( const ScRange& rOrgRange,
2649cdf0e10cSrcweir ScDocument* pRefDoc, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
2650cdf0e10cSrcweir sal_uLong nRejectingInsert )
2651cdf0e10cSrcweir {
2652cdf0e10cSrcweir ScRange aTrackRange( rOrgRange );
2653cdf0e10cSrcweir if ( nDx )
2654cdf0e10cSrcweir {
2655cdf0e10cSrcweir aTrackRange.aStart.IncCol( -nDx );
2656cdf0e10cSrcweir aTrackRange.aEnd.IncCol( -nDx );
2657cdf0e10cSrcweir }
2658cdf0e10cSrcweir if ( nDy )
2659cdf0e10cSrcweir {
2660cdf0e10cSrcweir aTrackRange.aStart.IncRow( -nDy );
2661cdf0e10cSrcweir aTrackRange.aEnd.IncRow( -nDy );
2662cdf0e10cSrcweir }
2663cdf0e10cSrcweir if ( nDz )
2664cdf0e10cSrcweir {
2665cdf0e10cSrcweir aTrackRange.aStart.IncTab( -nDz );
2666cdf0e10cSrcweir aTrackRange.aEnd.IncTab( -nDz );
2667cdf0e10cSrcweir }
2668cdf0e10cSrcweir ScChangeActionDel* pAct = new ScChangeActionDel( aTrackRange, nDx, nDy,
2669cdf0e10cSrcweir this );
2670cdf0e10cSrcweir // TabDelete keine Contents, sind in einzelnen Spalten
2671cdf0e10cSrcweir if ( !(rOrgRange.aStart.Col() == 0 && rOrgRange.aStart.Row() == 0 &&
2672cdf0e10cSrcweir rOrgRange.aEnd.Col() == MAXCOL && rOrgRange.aEnd.Row() == MAXROW) )
2673cdf0e10cSrcweir LookUpContents( rOrgRange, pRefDoc, -nDx, -nDy, -nDz );
2674cdf0e10cSrcweir if ( nRejectingInsert )
2675cdf0e10cSrcweir {
2676cdf0e10cSrcweir pAct->SetRejectAction( nRejectingInsert );
2677cdf0e10cSrcweir pAct->SetState( SC_CAS_ACCEPTED );
2678cdf0e10cSrcweir }
2679cdf0e10cSrcweir Append( pAct );
2680cdf0e10cSrcweir }
2681cdf0e10cSrcweir
2682cdf0e10cSrcweir
LookUpContents(const ScRange & rOrgRange,ScDocument * pRefDoc,SCsCOL nDx,SCsROW nDy,SCsTAB nDz)2683cdf0e10cSrcweir void ScChangeTrack::LookUpContents( const ScRange& rOrgRange,
2684cdf0e10cSrcweir ScDocument* pRefDoc, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
2685cdf0e10cSrcweir {
2686cdf0e10cSrcweir if ( pRefDoc )
2687cdf0e10cSrcweir {
2688cdf0e10cSrcweir ScAddress aPos;
2689cdf0e10cSrcweir ScBigAddress aBigPos;
2690cdf0e10cSrcweir ScCellIterator aIter( pRefDoc, rOrgRange );
2691cdf0e10cSrcweir ScBaseCell* pCell = aIter.GetFirst();
2692cdf0e10cSrcweir while ( pCell )
2693cdf0e10cSrcweir {
2694cdf0e10cSrcweir if ( ScChangeActionContent::GetContentCellType( pCell ) )
2695cdf0e10cSrcweir {
2696cdf0e10cSrcweir aBigPos.Set( aIter.GetCol() + nDx, aIter.GetRow() + nDy,
2697cdf0e10cSrcweir aIter.GetTab() + nDz );
2698cdf0e10cSrcweir ScChangeActionContent* pContent = SearchContentAt( aBigPos, NULL );
2699cdf0e10cSrcweir if ( !pContent )
2700cdf0e10cSrcweir { // nicht getrackte Contents
2701cdf0e10cSrcweir aPos.Set( aIter.GetCol() + nDx, aIter.GetRow() + nDy,
2702cdf0e10cSrcweir aIter.GetTab() + nDz );
2703cdf0e10cSrcweir GenerateDelContent( aPos, pCell, pRefDoc );
2704cdf0e10cSrcweir //! der Content wird hier _nicht_ per AddContent hinzugefuegt,
2705cdf0e10cSrcweir //! sondern in UpdateReference, um z.B. auch kreuzende Deletes
2706cdf0e10cSrcweir //! korrekt zu erfassen
2707cdf0e10cSrcweir }
2708cdf0e10cSrcweir }
2709cdf0e10cSrcweir pCell = aIter.GetNext();
2710cdf0e10cSrcweir }
2711cdf0e10cSrcweir }
2712cdf0e10cSrcweir }
2713cdf0e10cSrcweir
2714cdf0e10cSrcweir
AppendMove(const ScRange & rFromRange,const ScRange & rToRange,ScDocument * pRefDoc)2715cdf0e10cSrcweir void ScChangeTrack::AppendMove( const ScRange& rFromRange,
2716cdf0e10cSrcweir const ScRange& rToRange, ScDocument* pRefDoc )
2717cdf0e10cSrcweir {
2718cdf0e10cSrcweir ScChangeActionMove* pAct = new ScChangeActionMove( rFromRange, rToRange, this );
2719cdf0e10cSrcweir LookUpContents( rToRange, pRefDoc, 0, 0, 0 ); // ueberschriebene Contents
2720cdf0e10cSrcweir Append( pAct );
2721cdf0e10cSrcweir }
2722cdf0e10cSrcweir
2723cdf0e10cSrcweir
2724cdf0e10cSrcweir // static
IsMatrixFormulaRangeDifferent(const ScBaseCell * pOldCell,const ScBaseCell * pNewCell)2725cdf0e10cSrcweir sal_Bool ScChangeTrack::IsMatrixFormulaRangeDifferent( const ScBaseCell* pOldCell,
2726cdf0e10cSrcweir const ScBaseCell* pNewCell )
2727cdf0e10cSrcweir {
2728cdf0e10cSrcweir SCCOL nC1, nC2;
2729cdf0e10cSrcweir SCROW nR1, nR2;
2730cdf0e10cSrcweir nC1 = nC2 = 0;
2731cdf0e10cSrcweir nR1 = nR2 = 0;
2732cdf0e10cSrcweir if ( pOldCell && (pOldCell->GetCellType() == CELLTYPE_FORMULA) &&
2733cdf0e10cSrcweir ((const ScFormulaCell*)pOldCell)->GetMatrixFlag() == MM_FORMULA )
2734cdf0e10cSrcweir ((const ScFormulaCell*)pOldCell)->GetMatColsRows( nC1, nR1 );
2735cdf0e10cSrcweir if ( pNewCell && (pNewCell->GetCellType() == CELLTYPE_FORMULA) &&
2736cdf0e10cSrcweir ((const ScFormulaCell*)pNewCell)->GetMatrixFlag() == MM_FORMULA )
2737cdf0e10cSrcweir ((const ScFormulaCell*)pNewCell)->GetMatColsRows( nC1, nR1 );
2738cdf0e10cSrcweir return nC1 != nC2 || nR1 != nR2;
2739cdf0e10cSrcweir }
2740cdf0e10cSrcweir
2741cdf0e10cSrcweir
AppendContent(const ScAddress & rPos,const String & rNewValue,ScBaseCell * pOldCell)2742cdf0e10cSrcweir void ScChangeTrack::AppendContent( const ScAddress& rPos,
2743cdf0e10cSrcweir const String& rNewValue, ScBaseCell* pOldCell )
2744cdf0e10cSrcweir {
2745cdf0e10cSrcweir String aOldValue;
2746cdf0e10cSrcweir ScChangeActionContent::GetStringOfCell( aOldValue, pOldCell, pDoc, rPos );
2747cdf0e10cSrcweir if ( aOldValue != rNewValue ||
2748cdf0e10cSrcweir IsMatrixFormulaRangeDifferent( pOldCell, NULL ) )
2749cdf0e10cSrcweir { // nur wirkliche Aenderung tracken
2750cdf0e10cSrcweir ScRange aRange( rPos );
2751cdf0e10cSrcweir ScChangeActionContent* pAct = new ScChangeActionContent( aRange );
2752cdf0e10cSrcweir pAct->SetOldValue( pOldCell, pDoc, pDoc );
2753cdf0e10cSrcweir pAct->SetNewValue( rNewValue, pDoc );
2754cdf0e10cSrcweir Append( pAct );
2755cdf0e10cSrcweir }
2756cdf0e10cSrcweir }
2757cdf0e10cSrcweir
2758cdf0e10cSrcweir
AppendContent(const ScAddress & rPos,const ScBaseCell * pOldCell,sal_uLong nOldFormat,ScDocument * pRefDoc)2759cdf0e10cSrcweir void ScChangeTrack::AppendContent( const ScAddress& rPos,
2760cdf0e10cSrcweir const ScBaseCell* pOldCell, sal_uLong nOldFormat, ScDocument* pRefDoc )
2761cdf0e10cSrcweir {
2762cdf0e10cSrcweir if ( !pRefDoc )
2763cdf0e10cSrcweir pRefDoc = pDoc;
2764cdf0e10cSrcweir String aOldValue;
2765cdf0e10cSrcweir ScChangeActionContent::GetStringOfCell( aOldValue, pOldCell, pRefDoc, nOldFormat );
2766cdf0e10cSrcweir String aNewValue;
2767cdf0e10cSrcweir ScBaseCell* pNewCell = pDoc->GetCell( rPos );
2768cdf0e10cSrcweir ScChangeActionContent::GetStringOfCell( aNewValue, pNewCell, pDoc, rPos );
2769cdf0e10cSrcweir if ( aOldValue != aNewValue ||
2770cdf0e10cSrcweir IsMatrixFormulaRangeDifferent( pOldCell, pNewCell ) )
2771cdf0e10cSrcweir { // nur wirkliche Aenderung tracken
2772cdf0e10cSrcweir ScRange aRange( rPos );
2773cdf0e10cSrcweir ScChangeActionContent* pAct = new ScChangeActionContent( aRange );
2774cdf0e10cSrcweir pAct->SetOldValue( pOldCell, pRefDoc, pDoc, nOldFormat );
2775cdf0e10cSrcweir pAct->SetNewValue( pNewCell, pDoc );
2776cdf0e10cSrcweir Append( pAct );
2777cdf0e10cSrcweir }
2778cdf0e10cSrcweir }
2779cdf0e10cSrcweir
2780cdf0e10cSrcweir
AppendContent(const ScAddress & rPos,ScDocument * pRefDoc)2781cdf0e10cSrcweir void ScChangeTrack::AppendContent( const ScAddress& rPos,
2782cdf0e10cSrcweir ScDocument* pRefDoc )
2783cdf0e10cSrcweir {
2784cdf0e10cSrcweir String aOldValue;
2785cdf0e10cSrcweir ScBaseCell* pOldCell = pRefDoc->GetCell( rPos );
2786cdf0e10cSrcweir ScChangeActionContent::GetStringOfCell( aOldValue, pOldCell, pRefDoc, rPos );
2787cdf0e10cSrcweir String aNewValue;
2788cdf0e10cSrcweir ScBaseCell* pNewCell = pDoc->GetCell( rPos );
2789cdf0e10cSrcweir ScChangeActionContent::GetStringOfCell( aNewValue, pNewCell, pDoc, rPos );
2790cdf0e10cSrcweir if ( aOldValue != aNewValue ||
2791cdf0e10cSrcweir IsMatrixFormulaRangeDifferent( pOldCell, pNewCell ) )
2792cdf0e10cSrcweir { // nur wirkliche Aenderung tracken
2793cdf0e10cSrcweir ScRange aRange( rPos );
2794cdf0e10cSrcweir ScChangeActionContent* pAct = new ScChangeActionContent( aRange );
2795cdf0e10cSrcweir pAct->SetOldValue( pOldCell, pRefDoc, pDoc );
2796cdf0e10cSrcweir pAct->SetNewValue( pNewCell, pDoc );
2797cdf0e10cSrcweir Append( pAct );
2798cdf0e10cSrcweir }
2799cdf0e10cSrcweir }
2800cdf0e10cSrcweir
2801cdf0e10cSrcweir
AppendContent(const ScAddress & rPos,const ScBaseCell * pOldCell)2802cdf0e10cSrcweir void ScChangeTrack::AppendContent( const ScAddress& rPos,
2803cdf0e10cSrcweir const ScBaseCell* pOldCell )
2804cdf0e10cSrcweir {
2805cdf0e10cSrcweir if ( ScChangeActionContent::NeedsNumberFormat( pOldCell ) )
2806cdf0e10cSrcweir AppendContent( rPos, pOldCell, pDoc->GetNumberFormat( rPos ), pDoc );
2807cdf0e10cSrcweir else
2808cdf0e10cSrcweir AppendContent( rPos, pOldCell, 0, pDoc );
2809cdf0e10cSrcweir }
2810cdf0e10cSrcweir
2811cdf0e10cSrcweir
SetLastCutMoveRange(const ScRange & rRange,ScDocument * pRefDoc)2812cdf0e10cSrcweir void ScChangeTrack::SetLastCutMoveRange( const ScRange& rRange,
2813cdf0e10cSrcweir ScDocument* pRefDoc )
2814cdf0e10cSrcweir {
2815cdf0e10cSrcweir if ( pLastCutMove )
2816cdf0e10cSrcweir {
2817cdf0e10cSrcweir // ToRange nicht mit Deletes linken und nicht in der Groesse aendern,
2818cdf0e10cSrcweir // eigentlich unnoetig, da ein Delete vorher in
2819cdf0e10cSrcweir // ScViewFunc::PasteFromClip ein ResetLastCut ausloest
2820cdf0e10cSrcweir ScBigRange& r = pLastCutMove->GetBigRange();
2821cdf0e10cSrcweir r.aEnd.SetCol( -1 );
2822cdf0e10cSrcweir r.aEnd.SetRow( -1 );
2823cdf0e10cSrcweir r.aEnd.SetTab( -1 );
2824cdf0e10cSrcweir r.aStart.SetCol( -1 - (rRange.aEnd.Col() - rRange.aStart.Col()) );
2825cdf0e10cSrcweir r.aStart.SetRow( -1 - (rRange.aEnd.Row() - rRange.aStart.Row()) );
2826cdf0e10cSrcweir r.aStart.SetTab( -1 - (rRange.aEnd.Tab() - rRange.aStart.Tab()) );
2827cdf0e10cSrcweir // zu ueberschreibende Contents im FromRange
2828cdf0e10cSrcweir LookUpContents( rRange, pRefDoc, 0, 0, 0 );
2829cdf0e10cSrcweir }
2830cdf0e10cSrcweir }
2831cdf0e10cSrcweir
2832cdf0e10cSrcweir
AppendContentRange(const ScRange & rRange,ScDocument * pRefDoc,sal_uLong & nStartAction,sal_uLong & nEndAction,ScChangeActionClipMode eClipMode)2833cdf0e10cSrcweir void ScChangeTrack::AppendContentRange( const ScRange& rRange,
2834cdf0e10cSrcweir ScDocument* pRefDoc, sal_uLong& nStartAction, sal_uLong& nEndAction,
2835cdf0e10cSrcweir ScChangeActionClipMode eClipMode )
2836cdf0e10cSrcweir {
2837cdf0e10cSrcweir if ( eClipMode == SC_CACM_CUT )
2838cdf0e10cSrcweir {
2839cdf0e10cSrcweir ResetLastCut();
2840cdf0e10cSrcweir pLastCutMove = new ScChangeActionMove( rRange, rRange, this );
2841cdf0e10cSrcweir SetLastCutMoveRange( rRange, pRefDoc );
2842cdf0e10cSrcweir }
2843cdf0e10cSrcweir SCCOL nCol1;
2844cdf0e10cSrcweir SCROW nRow1;
2845cdf0e10cSrcweir SCTAB nTab1;
2846cdf0e10cSrcweir SCCOL nCol2;
2847cdf0e10cSrcweir SCROW nRow2;
2848cdf0e10cSrcweir SCTAB nTab2;
2849cdf0e10cSrcweir rRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
2850cdf0e10cSrcweir sal_Bool bDoContents;
2851cdf0e10cSrcweir if ( eClipMode == SC_CACM_PASTE && HasLastCut() )
2852cdf0e10cSrcweir {
2853cdf0e10cSrcweir bDoContents = sal_False;
2854cdf0e10cSrcweir SetInPasteCut( sal_True );
2855cdf0e10cSrcweir // Paste und Cut abstimmen, Paste kann groesserer Range sein
2856cdf0e10cSrcweir ScRange aRange( rRange );
2857cdf0e10cSrcweir ScBigRange& r = pLastCutMove->GetBigRange();
2858cdf0e10cSrcweir SCCOL nTmpCol;
2859cdf0e10cSrcweir if ( (nTmpCol = (SCCOL) (r.aEnd.Col() - r.aStart.Col())) != (nCol2 - nCol1) )
2860cdf0e10cSrcweir {
2861cdf0e10cSrcweir aRange.aEnd.SetCol( aRange.aStart.Col() + nTmpCol );
2862cdf0e10cSrcweir nCol1 += nTmpCol + 1;
2863cdf0e10cSrcweir bDoContents = sal_True;
2864cdf0e10cSrcweir }
2865cdf0e10cSrcweir SCROW nTmpRow;
2866cdf0e10cSrcweir if ( (nTmpRow = (SCROW) (r.aEnd.Row() - r.aStart.Row())) != (nRow2 - nRow1) )
2867cdf0e10cSrcweir {
2868cdf0e10cSrcweir aRange.aEnd.SetRow( aRange.aStart.Row() + nTmpRow );
2869cdf0e10cSrcweir nRow1 += nTmpRow + 1;
2870cdf0e10cSrcweir bDoContents = sal_True;
2871cdf0e10cSrcweir }
2872cdf0e10cSrcweir SCTAB nTmpTab;
2873cdf0e10cSrcweir if ( (nTmpTab = (SCTAB) (r.aEnd.Tab() - r.aStart.Tab())) != (nTab2 - nTab1) )
2874cdf0e10cSrcweir {
2875cdf0e10cSrcweir aRange.aEnd.SetTab( aRange.aStart.Tab() + nTmpTab );
2876cdf0e10cSrcweir nTab1 += nTmpTab + 1;
2877cdf0e10cSrcweir bDoContents = sal_True;
2878cdf0e10cSrcweir }
2879cdf0e10cSrcweir r = aRange;
2880cdf0e10cSrcweir Undo( nStartLastCut, nEndLastCut ); // hier werden sich die Cuts gemerkt
2881cdf0e10cSrcweir //! StartAction erst nach Undo
2882cdf0e10cSrcweir nStartAction = GetActionMax() + 1;
2883cdf0e10cSrcweir StartBlockModify( SC_CTM_APPEND, nStartAction );
2884cdf0e10cSrcweir // zu ueberschreibende Contents im ToRange
2885cdf0e10cSrcweir LookUpContents( aRange, pRefDoc, 0, 0, 0 );
2886cdf0e10cSrcweir pLastCutMove->SetStartLastCut( nStartLastCut );
2887cdf0e10cSrcweir pLastCutMove->SetEndLastCut( nEndLastCut );
2888cdf0e10cSrcweir Append( pLastCutMove );
2889cdf0e10cSrcweir pLastCutMove = NULL;
2890cdf0e10cSrcweir ResetLastCut();
2891cdf0e10cSrcweir SetInPasteCut( sal_False );
2892cdf0e10cSrcweir }
2893cdf0e10cSrcweir else
2894cdf0e10cSrcweir {
2895cdf0e10cSrcweir bDoContents = sal_True;
2896cdf0e10cSrcweir nStartAction = GetActionMax() + 1;
2897cdf0e10cSrcweir StartBlockModify( SC_CTM_APPEND, nStartAction );
2898cdf0e10cSrcweir }
2899cdf0e10cSrcweir if ( bDoContents )
2900cdf0e10cSrcweir {
2901cdf0e10cSrcweir ScAddress aPos;
2902cdf0e10cSrcweir for ( SCTAB nTab = nTab1; nTab <= nTab2; nTab++ )
2903cdf0e10cSrcweir {
2904cdf0e10cSrcweir aPos.SetTab( nTab );
2905cdf0e10cSrcweir for ( SCCOL nCol = nCol1; nCol <= nCol2; nCol++ )
2906cdf0e10cSrcweir {
2907cdf0e10cSrcweir aPos.SetCol( nCol );
2908cdf0e10cSrcweir for ( SCROW nRow = nRow1; nRow <= nRow2; nRow++ )
2909cdf0e10cSrcweir {
2910cdf0e10cSrcweir aPos.SetRow( nRow );
2911cdf0e10cSrcweir AppendContent( aPos, pRefDoc );
2912cdf0e10cSrcweir }
2913cdf0e10cSrcweir }
2914cdf0e10cSrcweir }
2915cdf0e10cSrcweir }
2916cdf0e10cSrcweir nEndAction = GetActionMax();
2917cdf0e10cSrcweir EndBlockModify( nEndAction );
2918cdf0e10cSrcweir if ( eClipMode == SC_CACM_CUT )
2919cdf0e10cSrcweir {
2920cdf0e10cSrcweir nStartLastCut = nStartAction;
2921cdf0e10cSrcweir nEndLastCut = nEndAction;
2922cdf0e10cSrcweir }
2923cdf0e10cSrcweir }
2924cdf0e10cSrcweir
2925cdf0e10cSrcweir
AppendContentsIfInRefDoc(ScDocument * pRefDoc,sal_uLong & nStartAction,sal_uLong & nEndAction)2926cdf0e10cSrcweir void ScChangeTrack::AppendContentsIfInRefDoc( ScDocument* pRefDoc,
2927cdf0e10cSrcweir sal_uLong& nStartAction, sal_uLong& nEndAction )
2928cdf0e10cSrcweir {
2929cdf0e10cSrcweir ScDocumentIterator aIter( pRefDoc, 0, MAXTAB );
2930cdf0e10cSrcweir if ( aIter.GetFirst() )
2931cdf0e10cSrcweir {
2932cdf0e10cSrcweir nStartAction = GetActionMax() + 1;
2933cdf0e10cSrcweir StartBlockModify( SC_CTM_APPEND, nStartAction );
2934cdf0e10cSrcweir SvNumberFormatter* pFormatter = pRefDoc->GetFormatTable();
2935cdf0e10cSrcweir do
2936cdf0e10cSrcweir {
2937cdf0e10cSrcweir SCCOL nCol;
2938cdf0e10cSrcweir SCROW nRow;
2939cdf0e10cSrcweir SCTAB nTab;
2940cdf0e10cSrcweir aIter.GetPos( nCol, nRow, nTab );
2941cdf0e10cSrcweir ScAddress aPos( nCol, nRow, nTab );
2942cdf0e10cSrcweir AppendContent( aPos, aIter.GetCell(),
2943cdf0e10cSrcweir aIter.GetPattern()->GetNumberFormat( pFormatter ), pRefDoc );
2944cdf0e10cSrcweir } while ( aIter.GetNext() );
2945cdf0e10cSrcweir nEndAction = GetActionMax();
2946cdf0e10cSrcweir EndBlockModify( nEndAction );
2947cdf0e10cSrcweir }
2948cdf0e10cSrcweir else
2949cdf0e10cSrcweir nStartAction = nEndAction = 0;
2950cdf0e10cSrcweir }
2951cdf0e10cSrcweir
2952cdf0e10cSrcweir
AppendContentOnTheFly(const ScAddress & rPos,ScBaseCell * pOldCell,ScBaseCell * pNewCell,sal_uLong nOldFormat,sal_uLong nNewFormat)2953cdf0e10cSrcweir ScChangeActionContent* ScChangeTrack::AppendContentOnTheFly(
2954cdf0e10cSrcweir const ScAddress& rPos, ScBaseCell* pOldCell, ScBaseCell* pNewCell,
2955cdf0e10cSrcweir sal_uLong nOldFormat, sal_uLong nNewFormat )
2956cdf0e10cSrcweir {
2957cdf0e10cSrcweir ScRange aRange( rPos );
2958cdf0e10cSrcweir ScChangeActionContent* pAct = new ScChangeActionContent( aRange );
2959cdf0e10cSrcweir pAct->SetOldNewCells( pOldCell, nOldFormat, pNewCell, nNewFormat, pDoc );
2960cdf0e10cSrcweir Append( pAct );
2961cdf0e10cSrcweir return pAct;
2962cdf0e10cSrcweir }
2963cdf0e10cSrcweir
2964cdf0e10cSrcweir
AppendInsert(const ScRange & rRange)2965cdf0e10cSrcweir void ScChangeTrack::AppendInsert( const ScRange& rRange )
2966cdf0e10cSrcweir {
2967cdf0e10cSrcweir ScChangeActionIns* pAct = new ScChangeActionIns( rRange );
2968cdf0e10cSrcweir Append( pAct );
2969cdf0e10cSrcweir }
2970cdf0e10cSrcweir
2971cdf0e10cSrcweir
DeleteCellEntries(ScChangeActionCellListEntry * & pCellList,ScChangeAction * pDeletor)2972cdf0e10cSrcweir void ScChangeTrack::DeleteCellEntries( ScChangeActionCellListEntry*& pCellList,
2973cdf0e10cSrcweir ScChangeAction* pDeletor )
2974cdf0e10cSrcweir {
2975cdf0e10cSrcweir ScChangeActionCellListEntry* pE = pCellList;
2976cdf0e10cSrcweir while ( pE )
2977cdf0e10cSrcweir {
2978cdf0e10cSrcweir ScChangeActionCellListEntry* pNext = pE->pNext;
2979cdf0e10cSrcweir pE->pContent->RemoveDeletedIn( pDeletor );
2980cdf0e10cSrcweir if ( IsGenerated( pE->pContent->GetActionNumber() ) &&
2981cdf0e10cSrcweir !pE->pContent->IsDeletedIn() )
2982cdf0e10cSrcweir DeleteGeneratedDelContent( pE->pContent );
2983cdf0e10cSrcweir delete pE;
2984cdf0e10cSrcweir pE = pNext;
2985cdf0e10cSrcweir }
2986cdf0e10cSrcweir pCellList = NULL;
2987cdf0e10cSrcweir }
2988cdf0e10cSrcweir
2989cdf0e10cSrcweir
GenerateDelContent(const ScAddress & rPos,const ScBaseCell * pCell,const ScDocument * pFromDoc)2990cdf0e10cSrcweir ScChangeActionContent* ScChangeTrack::GenerateDelContent(
2991cdf0e10cSrcweir const ScAddress& rPos, const ScBaseCell* pCell,
2992cdf0e10cSrcweir const ScDocument* pFromDoc )
2993cdf0e10cSrcweir {
2994cdf0e10cSrcweir ScChangeActionContent* pContent = new ScChangeActionContent(
2995cdf0e10cSrcweir ScRange( rPos ) );
2996cdf0e10cSrcweir pContent->SetActionNumber( --nGeneratedMin );
2997cdf0e10cSrcweir // nur NewValue
2998cdf0e10cSrcweir ScChangeActionContent::SetValue( pContent->aNewValue, pContent->pNewCell,
2999cdf0e10cSrcweir rPos, pCell, pFromDoc, pDoc );
3000cdf0e10cSrcweir // pNextContent und pPrevContent werden nicht gesetzt
3001cdf0e10cSrcweir if ( pFirstGeneratedDelContent )
3002cdf0e10cSrcweir { // vorne reinhaengen
3003cdf0e10cSrcweir pFirstGeneratedDelContent->pPrev = pContent;
3004cdf0e10cSrcweir pContent->pNext = pFirstGeneratedDelContent;
3005cdf0e10cSrcweir }
3006cdf0e10cSrcweir pFirstGeneratedDelContent = pContent;
3007cdf0e10cSrcweir aGeneratedTable.Insert( nGeneratedMin, pContent );
3008cdf0e10cSrcweir NotifyModified( SC_CTM_APPEND, nGeneratedMin, nGeneratedMin );
3009cdf0e10cSrcweir return pContent;
3010cdf0e10cSrcweir }
3011cdf0e10cSrcweir
3012cdf0e10cSrcweir
DeleteGeneratedDelContent(ScChangeActionContent * pContent)3013cdf0e10cSrcweir void ScChangeTrack::DeleteGeneratedDelContent( ScChangeActionContent* pContent )
3014cdf0e10cSrcweir {
3015cdf0e10cSrcweir sal_uLong nAct = pContent->GetActionNumber();
3016cdf0e10cSrcweir aGeneratedTable.Remove( nAct );
3017cdf0e10cSrcweir if ( pFirstGeneratedDelContent == pContent )
3018cdf0e10cSrcweir pFirstGeneratedDelContent = (ScChangeActionContent*) pContent->pNext;
3019cdf0e10cSrcweir if ( pContent->pNext )
3020cdf0e10cSrcweir pContent->pNext->pPrev = pContent->pPrev;
3021cdf0e10cSrcweir if ( pContent->pPrev )
3022cdf0e10cSrcweir pContent->pPrev->pNext = pContent->pNext;
3023cdf0e10cSrcweir delete pContent;
3024cdf0e10cSrcweir NotifyModified( SC_CTM_REMOVE, nAct, nAct );
3025cdf0e10cSrcweir if ( nAct == nGeneratedMin )
3026cdf0e10cSrcweir ++nGeneratedMin; //! erst nach NotifyModified wg. IsGenerated
3027cdf0e10cSrcweir }
3028cdf0e10cSrcweir
3029cdf0e10cSrcweir
SearchContentAt(const ScBigAddress & rPos,ScChangeAction * pButNotThis) const3030cdf0e10cSrcweir ScChangeActionContent* ScChangeTrack::SearchContentAt(
3031cdf0e10cSrcweir const ScBigAddress& rPos, ScChangeAction* pButNotThis ) const
3032cdf0e10cSrcweir {
3033cdf0e10cSrcweir SCSIZE nSlot = ComputeContentSlot( rPos.Row() );
3034cdf0e10cSrcweir for ( ScChangeActionContent* p = ppContentSlots[nSlot]; p;
3035cdf0e10cSrcweir p = p->GetNextInSlot() )
3036cdf0e10cSrcweir {
3037cdf0e10cSrcweir if ( p != pButNotThis && !p->IsDeletedIn() &&
3038cdf0e10cSrcweir p->GetBigRange().aStart == rPos )
3039cdf0e10cSrcweir {
3040cdf0e10cSrcweir ScChangeActionContent* pContent = p->GetTopContent();
3041cdf0e10cSrcweir if ( !pContent->IsDeletedIn() )
3042cdf0e10cSrcweir return pContent;
3043cdf0e10cSrcweir }
3044cdf0e10cSrcweir }
3045cdf0e10cSrcweir return NULL;
3046cdf0e10cSrcweir }
3047cdf0e10cSrcweir
3048cdf0e10cSrcweir
AddDependentWithNotify(ScChangeAction * pParent,ScChangeAction * pDependent)3049cdf0e10cSrcweir void ScChangeTrack::AddDependentWithNotify( ScChangeAction* pParent,
3050cdf0e10cSrcweir ScChangeAction* pDependent )
3051cdf0e10cSrcweir {
3052cdf0e10cSrcweir ScChangeActionLinkEntry* pLink = pParent->AddDependent( pDependent );
3053cdf0e10cSrcweir pDependent->AddLink( pParent, pLink );
3054cdf0e10cSrcweir if ( aModifiedLink.IsSet() )
3055cdf0e10cSrcweir {
3056cdf0e10cSrcweir sal_uLong nMod = pParent->GetActionNumber();
3057cdf0e10cSrcweir NotifyModified( SC_CTM_PARENT, nMod, nMod );
3058cdf0e10cSrcweir }
3059cdf0e10cSrcweir }
3060cdf0e10cSrcweir
3061cdf0e10cSrcweir
Dependencies(ScChangeAction * pAct)3062cdf0e10cSrcweir void ScChangeTrack::Dependencies( ScChangeAction* pAct )
3063cdf0e10cSrcweir {
3064cdf0e10cSrcweir // Finde die letzte Abhaengigkeit fuer jeweils Col/Row/Tab.
3065cdf0e10cSrcweir // Content an gleicher Position verketten.
3066cdf0e10cSrcweir // Move Abhaengigkeiten.
3067cdf0e10cSrcweir ScChangeActionType eActType = pAct->GetType();
3068cdf0e10cSrcweir if ( eActType == SC_CAT_REJECT ||
3069cdf0e10cSrcweir (eActType == SC_CAT_MOVE && pAct->IsRejecting()) )
3070cdf0e10cSrcweir return ; // diese Rejects sind nicht abhaengig
3071cdf0e10cSrcweir
3072cdf0e10cSrcweir if ( eActType == SC_CAT_CONTENT )
3073cdf0e10cSrcweir {
3074cdf0e10cSrcweir if ( !(((ScChangeActionContent*)pAct)->GetNextContent() ||
3075cdf0e10cSrcweir ((ScChangeActionContent*)pAct)->GetPrevContent()) )
3076cdf0e10cSrcweir { // Contents an gleicher Position verketten
3077cdf0e10cSrcweir ScChangeActionContent* pContent = SearchContentAt(
3078cdf0e10cSrcweir pAct->GetBigRange().aStart, pAct );
3079cdf0e10cSrcweir if ( pContent )
3080cdf0e10cSrcweir {
3081cdf0e10cSrcweir pContent->SetNextContent( (ScChangeActionContent*) pAct );
3082cdf0e10cSrcweir ((ScChangeActionContent*)pAct)->SetPrevContent( pContent );
3083cdf0e10cSrcweir }
3084cdf0e10cSrcweir }
3085cdf0e10cSrcweir const ScBaseCell* pCell = ((ScChangeActionContent*)pAct)->GetNewCell();
3086cdf0e10cSrcweir if ( ScChangeActionContent::GetContentCellType( pCell ) == SC_CACCT_MATREF )
3087cdf0e10cSrcweir {
3088cdf0e10cSrcweir ScAddress aOrg;
3089cdf0e10cSrcweir ((const ScFormulaCell*)pCell)->GetMatrixOrigin( aOrg );
3090cdf0e10cSrcweir ScChangeActionContent* pContent = SearchContentAt( aOrg, pAct );
3091cdf0e10cSrcweir if ( pContent && pContent->IsMatrixOrigin() )
3092cdf0e10cSrcweir {
3093cdf0e10cSrcweir AddDependentWithNotify( pContent, pAct );
3094cdf0e10cSrcweir }
3095cdf0e10cSrcweir else
3096cdf0e10cSrcweir {
3097cdf0e10cSrcweir DBG_ERRORFILE( "ScChangeTrack::Dependencies: MatOrg not found" );
3098cdf0e10cSrcweir }
3099cdf0e10cSrcweir }
3100cdf0e10cSrcweir }
3101cdf0e10cSrcweir
3102cdf0e10cSrcweir if ( !(pLinkInsertCol || pLinkInsertRow || pLinkInsertTab || pLinkMove) )
3103cdf0e10cSrcweir return ; // keine Dependencies
3104cdf0e10cSrcweir if ( pAct->IsRejecting() )
3105cdf0e10cSrcweir return ; // ausser Content keine Dependencies
3106cdf0e10cSrcweir
3107cdf0e10cSrcweir // Insert in einem entsprechenden Insert haengt davon ab, sonst muesste
3108cdf0e10cSrcweir // der vorherige Insert gesplittet werden.
3109cdf0e10cSrcweir // Sich kreuzende Inserts und Deletes sind nicht abhaengig.
3110cdf0e10cSrcweir // Alles andere ist abhaengig.
3111cdf0e10cSrcweir
3112cdf0e10cSrcweir // Der zuletzt eingelinkte Insert steht am Anfang einer Kette,
3113cdf0e10cSrcweir // also genau richtig
3114cdf0e10cSrcweir
3115cdf0e10cSrcweir const ScBigRange& rRange = pAct->GetBigRange();
3116cdf0e10cSrcweir sal_Bool bActNoInsert = !pAct->IsInsertType();
3117cdf0e10cSrcweir sal_Bool bActColDel = ( eActType == SC_CAT_DELETE_COLS );
3118cdf0e10cSrcweir sal_Bool bActRowDel = ( eActType == SC_CAT_DELETE_ROWS );
3119cdf0e10cSrcweir sal_Bool bActTabDel = ( eActType == SC_CAT_DELETE_TABS );
3120cdf0e10cSrcweir
3121cdf0e10cSrcweir if ( pLinkInsertCol && (eActType == SC_CAT_INSERT_COLS ||
3122cdf0e10cSrcweir (bActNoInsert && !bActRowDel && !bActTabDel)) )
3123cdf0e10cSrcweir {
3124cdf0e10cSrcweir for ( ScChangeActionLinkEntry* pL = pLinkInsertCol; pL; pL = pL->GetNext() )
3125cdf0e10cSrcweir {
3126cdf0e10cSrcweir ScChangeActionIns* pTest = (ScChangeActionIns*) pL->GetAction();
3127cdf0e10cSrcweir if ( !pTest->IsRejected() &&
3128cdf0e10cSrcweir pTest->GetBigRange().Intersects( rRange ) )
3129cdf0e10cSrcweir {
3130cdf0e10cSrcweir AddDependentWithNotify( pTest, pAct );
3131cdf0e10cSrcweir break; // for
3132cdf0e10cSrcweir }
3133cdf0e10cSrcweir }
3134cdf0e10cSrcweir }
3135cdf0e10cSrcweir if ( pLinkInsertRow && (eActType == SC_CAT_INSERT_ROWS ||
3136cdf0e10cSrcweir (bActNoInsert && !bActColDel && !bActTabDel)) )
3137cdf0e10cSrcweir {
3138cdf0e10cSrcweir for ( ScChangeActionLinkEntry* pL = pLinkInsertRow; pL; pL = pL->GetNext() )
3139cdf0e10cSrcweir {
3140cdf0e10cSrcweir ScChangeActionIns* pTest = (ScChangeActionIns*) pL->GetAction();
3141cdf0e10cSrcweir if ( !pTest->IsRejected() &&
3142cdf0e10cSrcweir pTest->GetBigRange().Intersects( rRange ) )
3143cdf0e10cSrcweir {
3144cdf0e10cSrcweir AddDependentWithNotify( pTest, pAct );
3145cdf0e10cSrcweir break; // for
3146cdf0e10cSrcweir }
3147cdf0e10cSrcweir }
3148cdf0e10cSrcweir }
3149cdf0e10cSrcweir if ( pLinkInsertTab && (eActType == SC_CAT_INSERT_TABS ||
3150cdf0e10cSrcweir (bActNoInsert && !bActColDel && !bActRowDel)) )
3151cdf0e10cSrcweir {
3152cdf0e10cSrcweir for ( ScChangeActionLinkEntry* pL = pLinkInsertTab; pL; pL = pL->GetNext() )
3153cdf0e10cSrcweir {
3154cdf0e10cSrcweir ScChangeActionIns* pTest = (ScChangeActionIns*) pL->GetAction();
3155cdf0e10cSrcweir if ( !pTest->IsRejected() &&
3156cdf0e10cSrcweir pTest->GetBigRange().Intersects( rRange ) )
3157cdf0e10cSrcweir {
3158cdf0e10cSrcweir AddDependentWithNotify( pTest, pAct );
3159cdf0e10cSrcweir break; // for
3160cdf0e10cSrcweir }
3161cdf0e10cSrcweir }
3162cdf0e10cSrcweir }
3163cdf0e10cSrcweir
3164cdf0e10cSrcweir if ( pLinkMove )
3165cdf0e10cSrcweir {
3166cdf0e10cSrcweir if ( eActType == SC_CAT_CONTENT )
3167cdf0e10cSrcweir { // Content ist von FromRange abhaengig
3168cdf0e10cSrcweir const ScBigAddress& rPos = rRange.aStart;
3169cdf0e10cSrcweir for ( ScChangeActionLinkEntry* pL = pLinkMove; pL; pL = pL->GetNext() )
3170cdf0e10cSrcweir {
3171cdf0e10cSrcweir ScChangeActionMove* pTest = (ScChangeActionMove*) pL->GetAction();
3172cdf0e10cSrcweir if ( !pTest->IsRejected() &&
3173cdf0e10cSrcweir pTest->GetFromRange().In( rPos ) )
3174cdf0e10cSrcweir {
3175cdf0e10cSrcweir AddDependentWithNotify( pTest, pAct );
3176cdf0e10cSrcweir }
3177cdf0e10cSrcweir }
3178cdf0e10cSrcweir }
3179cdf0e10cSrcweir else if ( eActType == SC_CAT_MOVE )
3180cdf0e10cSrcweir { // Move FromRange ist von ToRange abhaengig
3181cdf0e10cSrcweir const ScBigRange& rFromRange = ((ScChangeActionMove*)pAct)->GetFromRange();
3182cdf0e10cSrcweir for ( ScChangeActionLinkEntry* pL = pLinkMove; pL; pL = pL->GetNext() )
3183cdf0e10cSrcweir {
3184cdf0e10cSrcweir ScChangeActionMove* pTest = (ScChangeActionMove*) pL->GetAction();
3185cdf0e10cSrcweir if ( !pTest->IsRejected() &&
3186cdf0e10cSrcweir pTest->GetBigRange().Intersects( rFromRange ) )
3187cdf0e10cSrcweir {
3188cdf0e10cSrcweir AddDependentWithNotify( pTest, pAct );
3189cdf0e10cSrcweir }
3190cdf0e10cSrcweir }
3191cdf0e10cSrcweir }
3192cdf0e10cSrcweir else
3193cdf0e10cSrcweir { // Inserts und Deletes sind abhaengig, sobald sie FromRange oder
3194cdf0e10cSrcweir // ToRange kreuzen
3195cdf0e10cSrcweir for ( ScChangeActionLinkEntry* pL = pLinkMove; pL; pL = pL->GetNext() )
3196cdf0e10cSrcweir {
3197cdf0e10cSrcweir ScChangeActionMove* pTest = (ScChangeActionMove*) pL->GetAction();
3198cdf0e10cSrcweir if ( !pTest->IsRejected() &&
3199cdf0e10cSrcweir (pTest->GetFromRange().Intersects( rRange ) ||
3200cdf0e10cSrcweir pTest->GetBigRange().Intersects( rRange )) )
3201cdf0e10cSrcweir {
3202cdf0e10cSrcweir AddDependentWithNotify( pTest, pAct );
3203cdf0e10cSrcweir }
3204cdf0e10cSrcweir }
3205cdf0e10cSrcweir }
3206cdf0e10cSrcweir }
3207cdf0e10cSrcweir }
3208cdf0e10cSrcweir
3209cdf0e10cSrcweir
Remove(ScChangeAction * pRemove)3210cdf0e10cSrcweir void ScChangeTrack::Remove( ScChangeAction* pRemove )
3211cdf0e10cSrcweir {
3212cdf0e10cSrcweir // aus Track ausklinken
3213cdf0e10cSrcweir sal_uLong nAct = pRemove->GetActionNumber();
3214cdf0e10cSrcweir aTable.Remove( nAct );
3215cdf0e10cSrcweir if ( nAct == nActionMax )
3216cdf0e10cSrcweir --nActionMax;
3217cdf0e10cSrcweir if ( pRemove == pLast )
3218cdf0e10cSrcweir pLast = pRemove->pPrev;
3219cdf0e10cSrcweir if ( pRemove == pFirst )
3220cdf0e10cSrcweir pFirst = pRemove->pNext;
3221cdf0e10cSrcweir if ( nAct == nMarkLastSaved )
3222cdf0e10cSrcweir nMarkLastSaved =
3223cdf0e10cSrcweir ( pRemove->pPrev ? pRemove->pPrev->GetActionNumber() : 0 );
3224cdf0e10cSrcweir
3225cdf0e10cSrcweir // aus der globalen Kette ausklinken
3226cdf0e10cSrcweir if ( pRemove->pNext )
3227cdf0e10cSrcweir pRemove->pNext->pPrev = pRemove->pPrev;
3228cdf0e10cSrcweir if ( pRemove->pPrev )
3229cdf0e10cSrcweir pRemove->pPrev->pNext = pRemove->pNext;
3230cdf0e10cSrcweir
3231cdf0e10cSrcweir // Dependencies nicht loeschen, passiert on delete automatisch durch
3232cdf0e10cSrcweir // LinkEntry, ohne Listen abzuklappern
3233cdf0e10cSrcweir
3234cdf0e10cSrcweir if ( aModifiedLink.IsSet() )
3235cdf0e10cSrcweir {
3236cdf0e10cSrcweir NotifyModified( SC_CTM_REMOVE, nAct, nAct );
3237cdf0e10cSrcweir if ( pRemove->GetType() == SC_CAT_CONTENT )
3238cdf0e10cSrcweir {
3239cdf0e10cSrcweir ScChangeActionContent* pContent = (ScChangeActionContent*) pRemove;
3240cdf0e10cSrcweir if ( ( pContent = pContent->GetPrevContent() ) != NULL )
3241cdf0e10cSrcweir {
3242cdf0e10cSrcweir sal_uLong nMod = pContent->GetActionNumber();
3243cdf0e10cSrcweir NotifyModified( SC_CTM_CHANGE, nMod, nMod );
3244cdf0e10cSrcweir }
3245cdf0e10cSrcweir }
3246cdf0e10cSrcweir else if ( pLast )
3247cdf0e10cSrcweir NotifyModified( SC_CTM_CHANGE, pFirst->GetActionNumber(),
3248cdf0e10cSrcweir pLast->GetActionNumber() );
3249cdf0e10cSrcweir }
3250cdf0e10cSrcweir
3251cdf0e10cSrcweir if ( IsInPasteCut() && pRemove->GetType() == SC_CAT_CONTENT )
3252cdf0e10cSrcweir { //! Content wird wiederverwertet
3253cdf0e10cSrcweir ScChangeActionContent* pContent = (ScChangeActionContent*) pRemove;
3254cdf0e10cSrcweir pContent->RemoveAllLinks();
3255cdf0e10cSrcweir pContent->ClearTrack();
3256cdf0e10cSrcweir pContent->pNext = pContent->pPrev = NULL;
3257cdf0e10cSrcweir pContent->pNextContent = pContent->pPrevContent = NULL;
3258cdf0e10cSrcweir }
3259cdf0e10cSrcweir }
3260cdf0e10cSrcweir
3261cdf0e10cSrcweir
Undo(sal_uLong nStartAction,sal_uLong nEndAction,bool bMerge)3262cdf0e10cSrcweir void ScChangeTrack::Undo( sal_uLong nStartAction, sal_uLong nEndAction, bool bMerge )
3263cdf0e10cSrcweir {
3264cdf0e10cSrcweir // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
3265cdf0e10cSrcweir if ( bMerge )
3266cdf0e10cSrcweir {
3267cdf0e10cSrcweir SetMergeState( SC_CTMS_UNDO );
3268cdf0e10cSrcweir }
3269cdf0e10cSrcweir
3270cdf0e10cSrcweir if ( nStartAction == 0 )
3271cdf0e10cSrcweir ++nStartAction;
3272cdf0e10cSrcweir if ( nEndAction > nActionMax )
3273cdf0e10cSrcweir nEndAction = nActionMax;
3274cdf0e10cSrcweir if ( nEndAction && nStartAction <= nEndAction )
3275cdf0e10cSrcweir {
3276cdf0e10cSrcweir if ( nStartAction == nStartLastCut && nEndAction == nEndLastCut &&
3277cdf0e10cSrcweir !IsInPasteCut() )
3278cdf0e10cSrcweir ResetLastCut();
3279cdf0e10cSrcweir StartBlockModify( SC_CTM_REMOVE, nStartAction );
3280cdf0e10cSrcweir for ( sal_uLong j = nEndAction; j >= nStartAction; --j )
3281cdf0e10cSrcweir { // rueckwaerts um evtl. nActionMax zu recyclen und schnelleren
3282cdf0e10cSrcweir // Zugriff via pLast, Deletes in richtiger Reihenfolge
3283cdf0e10cSrcweir ScChangeAction* pAct = ( (j == nActionMax && pLast &&
3284cdf0e10cSrcweir pLast->GetActionNumber() == j) ? pLast : GetAction( j ) );
3285cdf0e10cSrcweir if ( pAct )
3286cdf0e10cSrcweir {
3287cdf0e10cSrcweir if ( pAct->IsDeleteType() )
3288cdf0e10cSrcweir {
3289cdf0e10cSrcweir if ( j == nEndAction || (pAct != pLast &&
3290cdf0e10cSrcweir ((ScChangeActionDel*)pAct)->IsTopDelete()) )
3291cdf0e10cSrcweir {
3292cdf0e10cSrcweir SetInDeleteTop( sal_True );
3293cdf0e10cSrcweir SetInDeleteRange( ((ScChangeActionDel*)pAct)->
3294cdf0e10cSrcweir GetOverAllRange().MakeRange() );
3295cdf0e10cSrcweir }
3296cdf0e10cSrcweir }
3297cdf0e10cSrcweir UpdateReference( pAct, sal_True );
3298cdf0e10cSrcweir SetInDeleteTop( sal_False );
3299cdf0e10cSrcweir Remove( pAct );
3300cdf0e10cSrcweir if ( IsInPasteCut() )
3301cdf0e10cSrcweir aPasteCutTable.Insert( pAct->GetActionNumber(), pAct );
3302cdf0e10cSrcweir else
3303cdf0e10cSrcweir {
3304cdf0e10cSrcweir if ( j == nStartAction && pAct->GetType() == SC_CAT_MOVE )
3305cdf0e10cSrcweir {
3306cdf0e10cSrcweir ScChangeActionMove* pMove = (ScChangeActionMove*) pAct;
3307cdf0e10cSrcweir sal_uLong nStart = pMove->GetStartLastCut();
3308cdf0e10cSrcweir sal_uLong nEnd = pMove->GetEndLastCut();
3309cdf0e10cSrcweir if ( nStart && nStart <= nEnd )
3310cdf0e10cSrcweir { // LastCut wiederherstellen
3311cdf0e10cSrcweir //! Links vor Cut-Append aufloesen
3312cdf0e10cSrcweir pMove->RemoveAllLinks();
3313cdf0e10cSrcweir StartBlockModify( SC_CTM_APPEND, nStart );
3314cdf0e10cSrcweir for ( sal_uLong nCut = nStart; nCut <= nEnd; nCut++ )
3315cdf0e10cSrcweir {
3316cdf0e10cSrcweir ScChangeAction* pCut = aPasteCutTable.Remove( nCut );
3317cdf0e10cSrcweir if ( pCut )
3318cdf0e10cSrcweir {
3319cdf0e10cSrcweir DBG_ASSERT( !aTable.Get( nCut ), "ScChangeTrack::Undo: nCut dup" );
3320cdf0e10cSrcweir Append( pCut, nCut );
3321cdf0e10cSrcweir }
3322cdf0e10cSrcweir else
3323cdf0e10cSrcweir {
3324cdf0e10cSrcweir DBG_ERROR( "ScChangeTrack::Undo: nCut not found" );
3325cdf0e10cSrcweir }
3326cdf0e10cSrcweir }
3327cdf0e10cSrcweir EndBlockModify( nEnd );
3328cdf0e10cSrcweir ResetLastCut();
3329cdf0e10cSrcweir nStartLastCut = nStart;
3330cdf0e10cSrcweir nEndLastCut = nEnd;
3331cdf0e10cSrcweir pLastCutMove = pMove;
3332cdf0e10cSrcweir SetLastCutMoveRange(
3333cdf0e10cSrcweir pMove->GetFromRange().MakeRange(), pDoc );
3334cdf0e10cSrcweir }
3335cdf0e10cSrcweir else
3336cdf0e10cSrcweir delete pMove;
3337cdf0e10cSrcweir }
3338cdf0e10cSrcweir else
3339cdf0e10cSrcweir delete pAct;
3340cdf0e10cSrcweir }
3341cdf0e10cSrcweir }
3342cdf0e10cSrcweir }
3343cdf0e10cSrcweir EndBlockModify( nEndAction );
3344cdf0e10cSrcweir }
3345cdf0e10cSrcweir
3346cdf0e10cSrcweir // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
3347cdf0e10cSrcweir if ( bMerge )
3348cdf0e10cSrcweir {
3349cdf0e10cSrcweir SetMergeState( SC_CTMS_OTHER );
3350cdf0e10cSrcweir }
3351cdf0e10cSrcweir }
3352cdf0e10cSrcweir
3353cdf0e10cSrcweir
3354cdf0e10cSrcweir // static
MergeIgnore(const ScChangeAction & rAction,sal_uLong nFirstMerge)3355cdf0e10cSrcweir sal_Bool ScChangeTrack::MergeIgnore( const ScChangeAction& rAction, sal_uLong nFirstMerge )
3356cdf0e10cSrcweir {
3357cdf0e10cSrcweir if ( rAction.IsRejected() )
3358cdf0e10cSrcweir return sal_True; // da kommt noch eine passende Reject-Action
3359cdf0e10cSrcweir
3360cdf0e10cSrcweir if ( rAction.IsRejecting() && rAction.GetRejectAction() >= nFirstMerge )
3361cdf0e10cSrcweir return sal_True; // da ist sie
3362cdf0e10cSrcweir
3363cdf0e10cSrcweir return sal_False; // alles andere
3364cdf0e10cSrcweir }
3365cdf0e10cSrcweir
3366cdf0e10cSrcweir
MergePrepare(ScChangeAction * pFirstMerge,bool bShared)3367cdf0e10cSrcweir void ScChangeTrack::MergePrepare( ScChangeAction* pFirstMerge, bool bShared )
3368cdf0e10cSrcweir {
3369cdf0e10cSrcweir SetMergeState( SC_CTMS_PREPARE );
3370cdf0e10cSrcweir sal_uLong nFirstMerge = pFirstMerge->GetActionNumber();
3371cdf0e10cSrcweir ScChangeAction* pAct = GetLast();
3372cdf0e10cSrcweir if ( pAct )
3373cdf0e10cSrcweir {
3374cdf0e10cSrcweir SetLastMerge( pAct->GetActionNumber() );
3375cdf0e10cSrcweir while ( pAct )
3376cdf0e10cSrcweir { // rueckwaerts, Deletes in richtiger Reihenfolge
3377cdf0e10cSrcweir // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
3378cdf0e10cSrcweir if ( bShared || !ScChangeTrack::MergeIgnore( *pAct, nFirstMerge ) )
3379cdf0e10cSrcweir {
3380cdf0e10cSrcweir if ( pAct->IsDeleteType() )
3381cdf0e10cSrcweir {
3382cdf0e10cSrcweir if ( ((ScChangeActionDel*)pAct)->IsTopDelete() )
3383cdf0e10cSrcweir {
3384cdf0e10cSrcweir SetInDeleteTop( sal_True );
3385cdf0e10cSrcweir SetInDeleteRange( ((ScChangeActionDel*)pAct)->
3386cdf0e10cSrcweir GetOverAllRange().MakeRange() );
3387cdf0e10cSrcweir }
3388cdf0e10cSrcweir }
3389cdf0e10cSrcweir UpdateReference( pAct, sal_True );
3390cdf0e10cSrcweir SetInDeleteTop( sal_False );
3391cdf0e10cSrcweir pAct->DeleteCellEntries(); // sonst GPF bei Track Clear()
3392cdf0e10cSrcweir }
3393cdf0e10cSrcweir pAct = ( pAct == pFirstMerge ? NULL : pAct->GetPrev() );
3394cdf0e10cSrcweir }
3395cdf0e10cSrcweir }
3396cdf0e10cSrcweir SetMergeState( SC_CTMS_OTHER ); //! nachfolgende per default MergeOther
3397cdf0e10cSrcweir }
3398cdf0e10cSrcweir
3399cdf0e10cSrcweir
MergeOwn(ScChangeAction * pAct,sal_uLong nFirstMerge,bool bShared)3400cdf0e10cSrcweir void ScChangeTrack::MergeOwn( ScChangeAction* pAct, sal_uLong nFirstMerge, bool bShared )
3401cdf0e10cSrcweir {
3402cdf0e10cSrcweir // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
3403cdf0e10cSrcweir if ( bShared || !ScChangeTrack::MergeIgnore( *pAct, nFirstMerge ) )
3404cdf0e10cSrcweir {
3405cdf0e10cSrcweir SetMergeState( SC_CTMS_OWN );
3406cdf0e10cSrcweir if ( pAct->IsDeleteType() )
3407cdf0e10cSrcweir {
3408cdf0e10cSrcweir if ( ((ScChangeActionDel*)pAct)->IsTopDelete() )
3409cdf0e10cSrcweir {
3410cdf0e10cSrcweir SetInDeleteTop( sal_True );
3411cdf0e10cSrcweir SetInDeleteRange( ((ScChangeActionDel*)pAct)->
3412cdf0e10cSrcweir GetOverAllRange().MakeRange() );
3413cdf0e10cSrcweir }
3414cdf0e10cSrcweir }
3415cdf0e10cSrcweir UpdateReference( pAct, sal_False );
3416cdf0e10cSrcweir SetInDeleteTop( sal_False );
3417cdf0e10cSrcweir SetMergeState( SC_CTMS_OTHER ); //! nachfolgende per default MergeOther
3418cdf0e10cSrcweir }
3419cdf0e10cSrcweir }
3420cdf0e10cSrcweir
3421cdf0e10cSrcweir
UpdateReference(ScChangeAction * pAct,sal_Bool bUndo)3422cdf0e10cSrcweir void ScChangeTrack::UpdateReference( ScChangeAction* pAct, sal_Bool bUndo )
3423cdf0e10cSrcweir {
3424cdf0e10cSrcweir ScChangeActionType eActType = pAct->GetType();
3425cdf0e10cSrcweir if ( eActType == SC_CAT_CONTENT || eActType == SC_CAT_REJECT )
3426cdf0e10cSrcweir return ;
3427cdf0e10cSrcweir
3428cdf0e10cSrcweir //! Formelzellen haengen nicht im Dokument
3429cdf0e10cSrcweir sal_Bool bOldAutoCalc = pDoc->GetAutoCalc();
3430cdf0e10cSrcweir pDoc->SetAutoCalc( sal_False );
3431cdf0e10cSrcweir sal_Bool bOldNoListening = pDoc->GetNoListening();
3432cdf0e10cSrcweir pDoc->SetNoListening( sal_True );
3433cdf0e10cSrcweir //! Formelzellen ExpandRefs synchronisiert zu denen im Dokument
3434cdf0e10cSrcweir sal_Bool bOldExpandRefs = pDoc->IsExpandRefs();
3435cdf0e10cSrcweir if ( (!bUndo && pAct->IsInsertType()) || (bUndo && pAct->IsDeleteType()) )
3436cdf0e10cSrcweir pDoc->SetExpandRefs( SC_MOD()->GetInputOptions().GetExpandRefs() );
3437cdf0e10cSrcweir
3438cdf0e10cSrcweir if ( pAct->IsDeleteType() )
3439cdf0e10cSrcweir {
3440cdf0e10cSrcweir SetInDeleteUndo( bUndo );
3441cdf0e10cSrcweir SetInDelete( sal_True );
3442cdf0e10cSrcweir }
3443cdf0e10cSrcweir else if ( GetMergeState() == SC_CTMS_OWN )
3444cdf0e10cSrcweir {
3445cdf0e10cSrcweir // Referenzen von Formelzellen wiederherstellen,
3446cdf0e10cSrcweir // vorheriges MergePrepare war bei einem Insert wie ein Delete
3447cdf0e10cSrcweir if ( pAct->IsInsertType() )
3448cdf0e10cSrcweir SetInDeleteUndo( sal_True );
3449cdf0e10cSrcweir }
3450cdf0e10cSrcweir
3451cdf0e10cSrcweir //! erst die generated, als waeren sie vorher getrackt worden
3452cdf0e10cSrcweir if ( pFirstGeneratedDelContent )
3453cdf0e10cSrcweir UpdateReference( (ScChangeAction**)&pFirstGeneratedDelContent, pAct,
3454cdf0e10cSrcweir bUndo );
3455cdf0e10cSrcweir UpdateReference( &pFirst, pAct, bUndo );
3456cdf0e10cSrcweir
3457cdf0e10cSrcweir SetInDelete( sal_False );
3458cdf0e10cSrcweir SetInDeleteUndo( sal_False );
3459cdf0e10cSrcweir
3460cdf0e10cSrcweir pDoc->SetExpandRefs( bOldExpandRefs );
3461cdf0e10cSrcweir pDoc->SetNoListening( bOldNoListening );
3462cdf0e10cSrcweir pDoc->SetAutoCalc( bOldAutoCalc );
3463cdf0e10cSrcweir }
3464cdf0e10cSrcweir
3465cdf0e10cSrcweir
UpdateReference(ScChangeAction ** ppFirstAction,ScChangeAction * pAct,sal_Bool bUndo)3466cdf0e10cSrcweir void ScChangeTrack::UpdateReference( ScChangeAction** ppFirstAction,
3467cdf0e10cSrcweir ScChangeAction* pAct, sal_Bool bUndo )
3468cdf0e10cSrcweir {
3469cdf0e10cSrcweir ScChangeActionType eActType = pAct->GetType();
3470cdf0e10cSrcweir sal_Bool bGeneratedDelContents =
3471cdf0e10cSrcweir ( ppFirstAction == (ScChangeAction**)&pFirstGeneratedDelContent );
3472cdf0e10cSrcweir const ScBigRange& rOrgRange = pAct->GetBigRange();
3473cdf0e10cSrcweir ScBigRange aRange( rOrgRange );
3474cdf0e10cSrcweir ScBigRange aDelRange( rOrgRange );
3475cdf0e10cSrcweir sal_Int32 nDx, nDy, nDz;
3476cdf0e10cSrcweir nDx = nDy = nDz = 0;
3477cdf0e10cSrcweir UpdateRefMode eMode = URM_INSDEL;
3478cdf0e10cSrcweir sal_Bool bDel = sal_False;
3479cdf0e10cSrcweir switch ( eActType )
3480cdf0e10cSrcweir {
3481cdf0e10cSrcweir case SC_CAT_INSERT_COLS :
3482cdf0e10cSrcweir aRange.aEnd.SetCol( nInt32Max );
3483cdf0e10cSrcweir nDx = rOrgRange.aEnd.Col() - rOrgRange.aStart.Col() + 1;
3484cdf0e10cSrcweir break;
3485cdf0e10cSrcweir case SC_CAT_INSERT_ROWS :
3486cdf0e10cSrcweir aRange.aEnd.SetRow( nInt32Max );
3487cdf0e10cSrcweir nDy = rOrgRange.aEnd.Row() - rOrgRange.aStart.Row() + 1;
3488cdf0e10cSrcweir break;
3489cdf0e10cSrcweir case SC_CAT_INSERT_TABS :
3490cdf0e10cSrcweir aRange.aEnd.SetTab( nInt32Max );
3491cdf0e10cSrcweir nDz = rOrgRange.aEnd.Tab() - rOrgRange.aStart.Tab() + 1;
3492cdf0e10cSrcweir break;
3493cdf0e10cSrcweir case SC_CAT_DELETE_COLS :
3494cdf0e10cSrcweir aRange.aEnd.SetCol( nInt32Max );
3495cdf0e10cSrcweir nDx = -(rOrgRange.aEnd.Col() - rOrgRange.aStart.Col() + 1);
3496cdf0e10cSrcweir aDelRange.aEnd.SetCol( aDelRange.aStart.Col() - nDx - 1 );
3497cdf0e10cSrcweir bDel = sal_True;
3498cdf0e10cSrcweir break;
3499cdf0e10cSrcweir case SC_CAT_DELETE_ROWS :
3500cdf0e10cSrcweir aRange.aEnd.SetRow( nInt32Max );
3501cdf0e10cSrcweir nDy = -(rOrgRange.aEnd.Row() - rOrgRange.aStart.Row() + 1);
3502cdf0e10cSrcweir aDelRange.aEnd.SetRow( aDelRange.aStart.Row() - nDy - 1 );
3503cdf0e10cSrcweir bDel = sal_True;
3504cdf0e10cSrcweir break;
3505cdf0e10cSrcweir case SC_CAT_DELETE_TABS :
3506cdf0e10cSrcweir aRange.aEnd.SetTab( nInt32Max );
3507cdf0e10cSrcweir nDz = -(rOrgRange.aEnd.Tab() - rOrgRange.aStart.Tab() + 1);
3508cdf0e10cSrcweir aDelRange.aEnd.SetTab( aDelRange.aStart.Tab() - nDz - 1 );
3509cdf0e10cSrcweir bDel = sal_True;
3510cdf0e10cSrcweir break;
3511cdf0e10cSrcweir case SC_CAT_MOVE :
3512cdf0e10cSrcweir eMode = URM_MOVE;
3513cdf0e10cSrcweir ((ScChangeActionMove*)pAct)->GetDelta( nDx, nDy, nDz );
3514cdf0e10cSrcweir break;
3515cdf0e10cSrcweir default:
3516cdf0e10cSrcweir DBG_ERROR( "ScChangeTrack::UpdateReference: unknown Type" );
3517cdf0e10cSrcweir }
3518cdf0e10cSrcweir if ( bUndo )
3519cdf0e10cSrcweir {
3520cdf0e10cSrcweir nDx = -nDx;
3521cdf0e10cSrcweir nDy = -nDy;
3522cdf0e10cSrcweir nDz = -nDz;
3523cdf0e10cSrcweir }
3524cdf0e10cSrcweir if ( bDel )
3525cdf0e10cSrcweir { //! fuer diesen Mechanismus gilt:
3526cdf0e10cSrcweir //! es gibt nur ganze, einfache geloeschte Spalten/Zeilen
3527cdf0e10cSrcweir ScChangeActionDel* pActDel = (ScChangeActionDel*) pAct;
3528cdf0e10cSrcweir if ( !bUndo )
3529cdf0e10cSrcweir { // Delete
3530cdf0e10cSrcweir ScChangeActionType eInsType = SC_CAT_NONE; // for Insert-Undo-"Deletes"
3531cdf0e10cSrcweir switch ( eActType )
3532cdf0e10cSrcweir {
3533cdf0e10cSrcweir case SC_CAT_DELETE_COLS :
3534cdf0e10cSrcweir eInsType = SC_CAT_INSERT_COLS;
3535cdf0e10cSrcweir break;
3536cdf0e10cSrcweir case SC_CAT_DELETE_ROWS :
3537cdf0e10cSrcweir eInsType = SC_CAT_INSERT_ROWS;
3538cdf0e10cSrcweir break;
3539cdf0e10cSrcweir case SC_CAT_DELETE_TABS :
3540cdf0e10cSrcweir eInsType = SC_CAT_INSERT_TABS;
3541cdf0e10cSrcweir break;
3542cdf0e10cSrcweir default:
3543cdf0e10cSrcweir {
3544cdf0e10cSrcweir // added to avoid warnings
3545cdf0e10cSrcweir }
3546cdf0e10cSrcweir }
3547cdf0e10cSrcweir for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
3548cdf0e10cSrcweir {
3549cdf0e10cSrcweir if ( p == pAct )
3550cdf0e10cSrcweir continue; // for
3551cdf0e10cSrcweir sal_Bool bUpdate = sal_True;
3552cdf0e10cSrcweir if ( GetMergeState() == SC_CTMS_OTHER &&
3553cdf0e10cSrcweir p->GetActionNumber() <= GetLastMerge() )
3554cdf0e10cSrcweir { // Delete in mergendem Dokument, Action im zu mergenden
3555cdf0e10cSrcweir if ( p->IsInsertType() )
3556cdf0e10cSrcweir {
3557cdf0e10cSrcweir // Bei Insert Referenzen nur anpassen, wenn das Delete
3558cdf0e10cSrcweir // das Insert nicht schneidet.
3559cdf0e10cSrcweir if ( !aDelRange.Intersects( p->GetBigRange() ) )
3560cdf0e10cSrcweir p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz );
3561cdf0e10cSrcweir bUpdate = sal_False;
3562cdf0e10cSrcweir }
3563cdf0e10cSrcweir else if ( p->GetType() == SC_CAT_CONTENT &&
3564cdf0e10cSrcweir p->IsDeletedInDelType( eInsType ) )
3565cdf0e10cSrcweir { // Content in Insert-Undo-"Delete"
3566cdf0e10cSrcweir // Nicht anpassen, wenn dieses Delete in dem
3567cdf0e10cSrcweir // Insert-"Delete" sein wuerde (ist nur verschoben).
3568cdf0e10cSrcweir if ( aDelRange.In( p->GetBigRange().aStart ) )
3569cdf0e10cSrcweir bUpdate = sal_False;
3570cdf0e10cSrcweir else
3571cdf0e10cSrcweir {
3572cdf0e10cSrcweir const ScChangeActionLinkEntry* pLink = p->GetDeletedIn();
3573cdf0e10cSrcweir while ( pLink && bUpdate )
3574cdf0e10cSrcweir {
3575cdf0e10cSrcweir const ScChangeAction* pDel = pLink->GetAction();
3576cdf0e10cSrcweir if ( pDel && pDel->GetType() == eInsType &&
3577cdf0e10cSrcweir pDel->GetBigRange().In( aDelRange ) )
3578cdf0e10cSrcweir bUpdate = sal_False;
3579cdf0e10cSrcweir pLink = pLink->GetNext();
3580cdf0e10cSrcweir }
3581cdf0e10cSrcweir }
3582cdf0e10cSrcweir }
3583cdf0e10cSrcweir if ( !bUpdate )
3584cdf0e10cSrcweir continue; // for
3585cdf0e10cSrcweir }
3586cdf0e10cSrcweir if ( aDelRange.In( p->GetBigRange() ) )
3587cdf0e10cSrcweir {
3588cdf0e10cSrcweir // Innerhalb eines gerade geloeschten Bereiches nicht
3589cdf0e10cSrcweir // anpassen, stattdessen dem Bereich zuordnen.
3590cdf0e10cSrcweir // Mehrfache geloeschte Bereiche "stapeln".
3591cdf0e10cSrcweir // Kreuzende Deletes setzen mehrfach geloescht.
3592cdf0e10cSrcweir if ( !p->IsDeletedInDelType( eActType ) )
3593cdf0e10cSrcweir {
3594cdf0e10cSrcweir p->SetDeletedIn( pActDel );
3595cdf0e10cSrcweir // GeneratedDelContent in zu loeschende Liste aufnehmen
3596cdf0e10cSrcweir if ( bGeneratedDelContents )
3597cdf0e10cSrcweir pActDel->AddContent( (ScChangeActionContent*) p );
3598cdf0e10cSrcweir }
3599cdf0e10cSrcweir bUpdate = sal_False;
3600cdf0e10cSrcweir }
3601cdf0e10cSrcweir else
3602cdf0e10cSrcweir {
3603cdf0e10cSrcweir // Eingefuegte Bereiche abschneiden, wenn Start/End im
3604cdf0e10cSrcweir // Delete liegt, aber das Insert nicht komplett innerhalb
3605cdf0e10cSrcweir // des Delete liegt bzw. das Delete nicht komplett im
3606cdf0e10cSrcweir // Insert. Das Delete merkt sich, welchem Insert es was
3607cdf0e10cSrcweir // abgeschnitten hat, es kann auch nur ein einziges Insert
3608cdf0e10cSrcweir // sein (weil Delete einspaltig/einzeilig ist).
3609cdf0e10cSrcweir // Abgeschnittene Moves kann es viele geben.
3610cdf0e10cSrcweir //! Ein Delete ist immer einspaltig/einzeilig, deswegen 1
3611cdf0e10cSrcweir //! ohne die Ueberlappung auszurechnen.
3612cdf0e10cSrcweir switch ( p->GetType() )
3613cdf0e10cSrcweir {
3614cdf0e10cSrcweir case SC_CAT_INSERT_COLS :
3615cdf0e10cSrcweir if ( eActType == SC_CAT_DELETE_COLS )
3616cdf0e10cSrcweir {
3617cdf0e10cSrcweir if ( aDelRange.In( p->GetBigRange().aStart ) )
3618cdf0e10cSrcweir {
3619cdf0e10cSrcweir pActDel->SetCutOffInsert(
3620cdf0e10cSrcweir (ScChangeActionIns*) p, 1 );
3621cdf0e10cSrcweir p->GetBigRange().aStart.IncCol( 1 );
3622cdf0e10cSrcweir }
3623cdf0e10cSrcweir else if ( aDelRange.In( p->GetBigRange().aEnd ) )
3624cdf0e10cSrcweir {
3625cdf0e10cSrcweir pActDel->SetCutOffInsert(
3626cdf0e10cSrcweir (ScChangeActionIns*) p, -1 );
3627cdf0e10cSrcweir p->GetBigRange().aEnd.IncCol( -1 );
3628cdf0e10cSrcweir }
3629cdf0e10cSrcweir }
3630cdf0e10cSrcweir break;
3631cdf0e10cSrcweir case SC_CAT_INSERT_ROWS :
3632cdf0e10cSrcweir if ( eActType == SC_CAT_DELETE_ROWS )
3633cdf0e10cSrcweir {
3634cdf0e10cSrcweir if ( aDelRange.In( p->GetBigRange().aStart ) )
3635cdf0e10cSrcweir {
3636cdf0e10cSrcweir pActDel->SetCutOffInsert(
3637cdf0e10cSrcweir (ScChangeActionIns*) p, 1 );
3638cdf0e10cSrcweir p->GetBigRange().aStart.IncRow( 1 );
3639cdf0e10cSrcweir }
3640cdf0e10cSrcweir else if ( aDelRange.In( p->GetBigRange().aEnd ) )
3641cdf0e10cSrcweir {
3642cdf0e10cSrcweir pActDel->SetCutOffInsert(
3643cdf0e10cSrcweir (ScChangeActionIns*) p, -1 );
3644cdf0e10cSrcweir p->GetBigRange().aEnd.IncRow( -1 );
3645cdf0e10cSrcweir }
3646cdf0e10cSrcweir }
3647cdf0e10cSrcweir break;
3648cdf0e10cSrcweir case SC_CAT_INSERT_TABS :
3649cdf0e10cSrcweir if ( eActType == SC_CAT_DELETE_TABS )
3650cdf0e10cSrcweir {
3651cdf0e10cSrcweir if ( aDelRange.In( p->GetBigRange().aStart ) )
3652cdf0e10cSrcweir {
3653cdf0e10cSrcweir pActDel->SetCutOffInsert(
3654cdf0e10cSrcweir (ScChangeActionIns*) p, 1 );
3655cdf0e10cSrcweir p->GetBigRange().aStart.IncTab( 1 );
3656cdf0e10cSrcweir }
3657cdf0e10cSrcweir else if ( aDelRange.In( p->GetBigRange().aEnd ) )
3658cdf0e10cSrcweir {
3659cdf0e10cSrcweir pActDel->SetCutOffInsert(
3660cdf0e10cSrcweir (ScChangeActionIns*) p, -1 );
3661cdf0e10cSrcweir p->GetBigRange().aEnd.IncTab( -1 );
3662cdf0e10cSrcweir }
3663cdf0e10cSrcweir }
3664cdf0e10cSrcweir break;
3665cdf0e10cSrcweir case SC_CAT_MOVE :
3666cdf0e10cSrcweir {
3667cdf0e10cSrcweir ScChangeActionMove* pMove = (ScChangeActionMove*) p;
3668cdf0e10cSrcweir short nFrom = 0;
3669cdf0e10cSrcweir short nTo = 0;
3670cdf0e10cSrcweir if ( aDelRange.In( pMove->GetBigRange().aStart ) )
3671cdf0e10cSrcweir nTo = 1;
3672cdf0e10cSrcweir else if ( aDelRange.In( pMove->GetBigRange().aEnd ) )
3673cdf0e10cSrcweir nTo = -1;
3674cdf0e10cSrcweir if ( aDelRange.In( pMove->GetFromRange().aStart ) )
3675cdf0e10cSrcweir nFrom = 1;
3676cdf0e10cSrcweir else if ( aDelRange.In( pMove->GetFromRange().aEnd ) )
3677cdf0e10cSrcweir nFrom = -1;
3678cdf0e10cSrcweir if ( nFrom )
3679cdf0e10cSrcweir {
3680cdf0e10cSrcweir switch ( eActType )
3681cdf0e10cSrcweir {
3682cdf0e10cSrcweir case SC_CAT_DELETE_COLS :
3683cdf0e10cSrcweir if ( nFrom > 0 )
3684cdf0e10cSrcweir pMove->GetFromRange().aStart.IncCol( nFrom );
3685cdf0e10cSrcweir else
3686cdf0e10cSrcweir pMove->GetFromRange().aEnd.IncCol( nFrom );
3687cdf0e10cSrcweir break;
3688cdf0e10cSrcweir case SC_CAT_DELETE_ROWS :
3689cdf0e10cSrcweir if ( nFrom > 0 )
3690cdf0e10cSrcweir pMove->GetFromRange().aStart.IncRow( nFrom );
3691cdf0e10cSrcweir else
3692cdf0e10cSrcweir pMove->GetFromRange().aEnd.IncRow( nFrom );
3693cdf0e10cSrcweir break;
3694cdf0e10cSrcweir case SC_CAT_DELETE_TABS :
3695cdf0e10cSrcweir if ( nFrom > 0 )
3696cdf0e10cSrcweir pMove->GetFromRange().aStart.IncTab( nFrom );
3697cdf0e10cSrcweir else
3698cdf0e10cSrcweir pMove->GetFromRange().aEnd.IncTab( nFrom );
3699cdf0e10cSrcweir break;
3700cdf0e10cSrcweir default:
3701cdf0e10cSrcweir {
3702cdf0e10cSrcweir // added to avoid warnings
3703cdf0e10cSrcweir }
3704cdf0e10cSrcweir }
3705cdf0e10cSrcweir }
3706cdf0e10cSrcweir if ( nTo )
3707cdf0e10cSrcweir {
3708cdf0e10cSrcweir switch ( eActType )
3709cdf0e10cSrcweir {
3710cdf0e10cSrcweir case SC_CAT_DELETE_COLS :
3711cdf0e10cSrcweir if ( nTo > 0 )
3712cdf0e10cSrcweir pMove->GetBigRange().aStart.IncCol( nTo );
3713cdf0e10cSrcweir else
3714cdf0e10cSrcweir pMove->GetBigRange().aEnd.IncCol( nTo );
3715cdf0e10cSrcweir break;
3716cdf0e10cSrcweir case SC_CAT_DELETE_ROWS :
3717cdf0e10cSrcweir if ( nTo > 0 )
3718cdf0e10cSrcweir pMove->GetBigRange().aStart.IncRow( nTo );
3719cdf0e10cSrcweir else
3720cdf0e10cSrcweir pMove->GetBigRange().aEnd.IncRow( nTo );
3721cdf0e10cSrcweir break;
3722cdf0e10cSrcweir case SC_CAT_DELETE_TABS :
3723cdf0e10cSrcweir if ( nTo > 0 )
3724cdf0e10cSrcweir pMove->GetBigRange().aStart.IncTab( nTo );
3725cdf0e10cSrcweir else
3726cdf0e10cSrcweir pMove->GetBigRange().aEnd.IncTab( nTo );
3727cdf0e10cSrcweir break;
3728cdf0e10cSrcweir default:
3729cdf0e10cSrcweir {
3730cdf0e10cSrcweir // added to avoid warnings
3731cdf0e10cSrcweir }
3732cdf0e10cSrcweir }
3733cdf0e10cSrcweir }
3734cdf0e10cSrcweir if ( nFrom || nTo )
3735cdf0e10cSrcweir {
3736cdf0e10cSrcweir ScChangeActionDelMoveEntry* pLink =
3737cdf0e10cSrcweir pActDel->AddCutOffMove( pMove, nFrom, nTo );
3738cdf0e10cSrcweir pMove->AddLink( pActDel, pLink );
3739cdf0e10cSrcweir }
3740cdf0e10cSrcweir }
3741cdf0e10cSrcweir break;
3742cdf0e10cSrcweir default:
3743cdf0e10cSrcweir {
3744cdf0e10cSrcweir // added to avoid warnings
3745cdf0e10cSrcweir }
3746cdf0e10cSrcweir }
3747cdf0e10cSrcweir }
3748cdf0e10cSrcweir if ( bUpdate )
3749cdf0e10cSrcweir {
3750cdf0e10cSrcweir p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz );
3751cdf0e10cSrcweir if ( p->GetType() == eActType && !p->IsRejected() &&
3752cdf0e10cSrcweir !pActDel->IsDeletedIn() &&
3753cdf0e10cSrcweir p->GetBigRange().In( aDelRange ) )
3754cdf0e10cSrcweir pActDel->SetDeletedIn( p ); // "druntergerutscht"
3755cdf0e10cSrcweir }
3756cdf0e10cSrcweir }
3757cdf0e10cSrcweir }
3758cdf0e10cSrcweir else
3759cdf0e10cSrcweir { // Undo Delete
3760cdf0e10cSrcweir for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
3761cdf0e10cSrcweir {
3762cdf0e10cSrcweir if ( p == pAct )
3763cdf0e10cSrcweir continue; // for
3764cdf0e10cSrcweir sal_Bool bUpdate = sal_True;
3765cdf0e10cSrcweir if ( aDelRange.In( p->GetBigRange() ) )
3766cdf0e10cSrcweir {
3767cdf0e10cSrcweir // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
3768cdf0e10cSrcweir if ( GetMergeState() == SC_CTMS_UNDO && !p->IsDeletedIn( pAct ) && pAct->IsDeleteType() &&
3769cdf0e10cSrcweir ( p->GetType() == SC_CAT_CONTENT ||
3770cdf0e10cSrcweir p->GetType() == SC_CAT_DELETE_ROWS || p->GetType() == SC_CAT_DELETE_COLS ||
3771cdf0e10cSrcweir p->GetType() == SC_CAT_INSERT_ROWS || p->GetType() == SC_CAT_INSERT_COLS ) )
3772cdf0e10cSrcweir {
3773cdf0e10cSrcweir p->SetDeletedIn( pAct );
3774cdf0e10cSrcweir }
3775cdf0e10cSrcweir
3776cdf0e10cSrcweir if ( p->IsDeletedInDelType( eActType ) )
3777cdf0e10cSrcweir {
3778cdf0e10cSrcweir if ( p->IsDeletedIn( pActDel ) )
3779cdf0e10cSrcweir {
3780cdf0e10cSrcweir if ( p->GetType() != SC_CAT_CONTENT ||
3781cdf0e10cSrcweir ((ScChangeActionContent*)p)->IsTopContent() )
3782cdf0e10cSrcweir { // erst der TopContent wird wirklich entfernt
3783cdf0e10cSrcweir p->RemoveDeletedIn( pActDel );
3784cdf0e10cSrcweir // GeneratedDelContent _nicht_ aus Liste loeschen,
3785cdf0e10cSrcweir // wir brauchen ihn evtl. noch fuer Reject,
3786cdf0e10cSrcweir // geloescht wird in DeleteCellEntries
3787cdf0e10cSrcweir }
3788cdf0e10cSrcweir }
3789cdf0e10cSrcweir bUpdate = sal_False;
3790cdf0e10cSrcweir }
3791cdf0e10cSrcweir else if ( eActType != SC_CAT_DELETE_TABS &&
3792cdf0e10cSrcweir p->IsDeletedInDelType( SC_CAT_DELETE_TABS ) )
3793cdf0e10cSrcweir { // in geloeschten Tabellen nicht updaten,
3794cdf0e10cSrcweir // ausser wenn Tabelle verschoben wird
3795cdf0e10cSrcweir bUpdate = sal_False;
3796cdf0e10cSrcweir }
3797cdf0e10cSrcweir if ( p->GetType() == eActType && pActDel->IsDeletedIn( p ) )
3798cdf0e10cSrcweir {
3799cdf0e10cSrcweir pActDel->RemoveDeletedIn( p ); // "druntergerutscht"
3800cdf0e10cSrcweir bUpdate = sal_True;
3801cdf0e10cSrcweir }
3802cdf0e10cSrcweir }
3803cdf0e10cSrcweir if ( bUpdate )
3804cdf0e10cSrcweir p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz );
3805cdf0e10cSrcweir }
3806cdf0e10cSrcweir if ( !bGeneratedDelContents )
3807cdf0e10cSrcweir { // die werden sonst noch fuer das echte Undo gebraucht
3808cdf0e10cSrcweir pActDel->UndoCutOffInsert();
3809cdf0e10cSrcweir pActDel->UndoCutOffMoves();
3810cdf0e10cSrcweir }
3811cdf0e10cSrcweir }
3812cdf0e10cSrcweir }
3813cdf0e10cSrcweir else if ( eActType == SC_CAT_MOVE )
3814cdf0e10cSrcweir {
3815cdf0e10cSrcweir ScChangeActionMove* pActMove = (ScChangeActionMove*) pAct;
3816cdf0e10cSrcweir sal_Bool bLastCutMove = ( pActMove == pLastCutMove );
3817cdf0e10cSrcweir const ScBigRange& rTo = pActMove->GetBigRange();
3818cdf0e10cSrcweir const ScBigRange& rFrom = pActMove->GetFromRange();
3819cdf0e10cSrcweir if ( !bUndo )
3820cdf0e10cSrcweir { // Move
3821cdf0e10cSrcweir for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
3822cdf0e10cSrcweir {
3823cdf0e10cSrcweir if ( p == pAct )
3824cdf0e10cSrcweir continue; // for
3825cdf0e10cSrcweir if ( p->GetType() == SC_CAT_CONTENT )
3826cdf0e10cSrcweir {
3827cdf0e10cSrcweir // Inhalt in Ziel deleten (Inhalt in Quelle moven)
3828cdf0e10cSrcweir if ( rTo.In( p->GetBigRange() ) )
3829cdf0e10cSrcweir {
3830cdf0e10cSrcweir if ( !p->IsDeletedIn( pActMove ) )
3831cdf0e10cSrcweir {
3832cdf0e10cSrcweir p->SetDeletedIn( pActMove );
3833cdf0e10cSrcweir // GeneratedDelContent in zu loeschende Liste aufnehmen
3834cdf0e10cSrcweir if ( bGeneratedDelContents )
3835cdf0e10cSrcweir pActMove->AddContent( (ScChangeActionContent*) p );
3836cdf0e10cSrcweir }
3837cdf0e10cSrcweir }
3838cdf0e10cSrcweir else if ( bLastCutMove &&
3839cdf0e10cSrcweir p->GetActionNumber() > nEndLastCut &&
3840cdf0e10cSrcweir rFrom.In( p->GetBigRange() ) )
3841cdf0e10cSrcweir { // Paste Cut: neuer Content nach Cut eingefuegt, bleibt.
3842cdf0e10cSrcweir // Aufsplitten der ContentChain
3843cdf0e10cSrcweir ScChangeActionContent *pHere, *pTmp;
3844cdf0e10cSrcweir pHere = (ScChangeActionContent*) p;
3845cdf0e10cSrcweir while ( (pTmp = pHere->GetPrevContent()) != NULL &&
3846cdf0e10cSrcweir pTmp->GetActionNumber() > nEndLastCut )
3847cdf0e10cSrcweir pHere = pTmp;
3848cdf0e10cSrcweir if ( pTmp )
3849cdf0e10cSrcweir { // wird TopContent des Move
3850cdf0e10cSrcweir pTmp->SetNextContent( NULL );
3851cdf0e10cSrcweir pHere->SetPrevContent( NULL );
3852cdf0e10cSrcweir }
3853cdf0e10cSrcweir do
3854cdf0e10cSrcweir { // Abhaengigkeit vom FromRange herstellen
3855cdf0e10cSrcweir AddDependentWithNotify( pActMove, pHere );
3856cdf0e10cSrcweir } while ( ( pHere = pHere->GetNextContent() ) != NULL );
3857cdf0e10cSrcweir }
3858cdf0e10cSrcweir // #i87003# [Collaboration] Move range and insert content in FromRange is not merged correctly
3859cdf0e10cSrcweir else if ( ( GetMergeState() != SC_CTMS_PREPARE && GetMergeState() != SC_CTMS_OWN ) || p->GetActionNumber() <= pAct->GetActionNumber() )
3860cdf0e10cSrcweir p->UpdateReference( this, eMode, rFrom, nDx, nDy, nDz );
3861cdf0e10cSrcweir }
3862cdf0e10cSrcweir }
3863cdf0e10cSrcweir }
3864cdf0e10cSrcweir else
3865cdf0e10cSrcweir { // Undo Move
3866cdf0e10cSrcweir sal_Bool bActRejected = pActMove->IsRejected();
3867cdf0e10cSrcweir for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
3868cdf0e10cSrcweir {
3869cdf0e10cSrcweir if ( p == pAct )
3870cdf0e10cSrcweir continue; // for
3871cdf0e10cSrcweir if ( p->GetType() == SC_CAT_CONTENT )
3872cdf0e10cSrcweir {
3873cdf0e10cSrcweir // Inhalt in Ziel moven, wenn nicht deleted, sonst undelete
3874cdf0e10cSrcweir if ( p->IsDeletedIn( pActMove ) )
3875cdf0e10cSrcweir {
3876cdf0e10cSrcweir if ( ((ScChangeActionContent*)p)->IsTopContent() )
3877cdf0e10cSrcweir { // erst der TopContent wird wirklich entfernt
3878cdf0e10cSrcweir p->RemoveDeletedIn( pActMove );
3879cdf0e10cSrcweir // GeneratedDelContent _nicht_ aus Liste loeschen,
3880cdf0e10cSrcweir // wir brauchen ihn evtl. noch fuer Reject,
3881cdf0e10cSrcweir // geloescht wird in DeleteCellEntries
3882cdf0e10cSrcweir }
3883cdf0e10cSrcweir }
3884cdf0e10cSrcweir // #i87003# [Collaboration] Move range and insert content in FromRange is not merged correctly
3885cdf0e10cSrcweir else if ( ( GetMergeState() != SC_CTMS_PREPARE && GetMergeState() != SC_CTMS_OWN ) || p->GetActionNumber() <= pAct->GetActionNumber() )
3886cdf0e10cSrcweir p->UpdateReference( this, eMode, rTo, nDx, nDy, nDz );
3887cdf0e10cSrcweir if ( bActRejected &&
3888cdf0e10cSrcweir ((ScChangeActionContent*)p)->IsTopContent() &&
3889cdf0e10cSrcweir rFrom.In( p->GetBigRange() ) )
3890cdf0e10cSrcweir { // Abhaengigkeit herstellen, um Content zu schreiben
3891cdf0e10cSrcweir ScChangeActionLinkEntry* pLink =
3892cdf0e10cSrcweir pActMove->AddDependent( p );
3893cdf0e10cSrcweir p->AddLink( pActMove, pLink );
3894cdf0e10cSrcweir }
3895cdf0e10cSrcweir }
3896cdf0e10cSrcweir }
3897cdf0e10cSrcweir }
3898cdf0e10cSrcweir }
3899cdf0e10cSrcweir else
3900cdf0e10cSrcweir { // Insert / Undo Insert
3901cdf0e10cSrcweir switch ( GetMergeState() )
3902cdf0e10cSrcweir {
3903cdf0e10cSrcweir case SC_CTMS_NONE :
3904cdf0e10cSrcweir case SC_CTMS_OTHER :
3905cdf0e10cSrcweir {
3906cdf0e10cSrcweir for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
3907cdf0e10cSrcweir {
3908cdf0e10cSrcweir if ( p == pAct )
3909cdf0e10cSrcweir continue; // for
3910cdf0e10cSrcweir p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz );
3911cdf0e10cSrcweir }
3912cdf0e10cSrcweir }
3913cdf0e10cSrcweir break;
3914cdf0e10cSrcweir case SC_CTMS_PREPARE :
3915cdf0e10cSrcweir {
3916cdf0e10cSrcweir // in Insert-Undo "Deleten"
3917cdf0e10cSrcweir const ScChangeActionLinkEntry* pLink = pAct->GetFirstDependentEntry();
3918cdf0e10cSrcweir while ( pLink )
3919cdf0e10cSrcweir {
3920cdf0e10cSrcweir ScChangeAction* p = (ScChangeAction*) pLink->GetAction();
3921cdf0e10cSrcweir if ( p )
3922cdf0e10cSrcweir p->SetDeletedIn( pAct );
3923cdf0e10cSrcweir pLink = pLink->GetNext();
3924cdf0e10cSrcweir }
3925cdf0e10cSrcweir
3926cdf0e10cSrcweir // #i87049# [Collaboration] Conflict between delete row and insert content is not merged correctly
3927cdf0e10cSrcweir for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
3928cdf0e10cSrcweir {
3929cdf0e10cSrcweir if ( !p->IsDeletedIn( pAct ) && pAct->IsInsertType() &&
3930cdf0e10cSrcweir // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
3931cdf0e10cSrcweir ( p->GetType() == SC_CAT_CONTENT ||
3932cdf0e10cSrcweir p->GetType() == SC_CAT_DELETE_ROWS || p->GetType() == SC_CAT_DELETE_COLS ||
3933cdf0e10cSrcweir p->GetType() == SC_CAT_INSERT_ROWS || p->GetType() == SC_CAT_INSERT_COLS ) &&
3934cdf0e10cSrcweir pAct->GetBigRange().Intersects( p->GetBigRange() ) )
3935cdf0e10cSrcweir {
3936cdf0e10cSrcweir p->SetDeletedIn( pAct );
3937cdf0e10cSrcweir }
3938cdf0e10cSrcweir }
3939cdf0e10cSrcweir
3940cdf0e10cSrcweir for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
3941cdf0e10cSrcweir {
3942cdf0e10cSrcweir if ( p == pAct )
3943cdf0e10cSrcweir continue; // for
3944cdf0e10cSrcweir if ( !p->IsDeletedIn( pAct )
3945cdf0e10cSrcweir // #i95212# [Collaboration] Bad handling of row insertion in shared spreadsheet
3946cdf0e10cSrcweir && p->GetActionNumber() <= pAct->GetActionNumber() )
3947cdf0e10cSrcweir {
3948cdf0e10cSrcweir p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz );
3949cdf0e10cSrcweir }
3950cdf0e10cSrcweir }
3951cdf0e10cSrcweir }
3952cdf0e10cSrcweir break;
3953cdf0e10cSrcweir case SC_CTMS_OWN :
3954cdf0e10cSrcweir {
3955cdf0e10cSrcweir for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
3956cdf0e10cSrcweir {
3957cdf0e10cSrcweir if ( p == pAct )
3958cdf0e10cSrcweir continue; // for
3959cdf0e10cSrcweir if ( !p->IsDeletedIn( pAct )
3960cdf0e10cSrcweir // #i95212# [Collaboration] Bad handling of row insertion in shared spreadsheet
3961cdf0e10cSrcweir && p->GetActionNumber() <= pAct->GetActionNumber() )
3962cdf0e10cSrcweir {
3963cdf0e10cSrcweir p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz );
3964cdf0e10cSrcweir }
3965cdf0e10cSrcweir }
3966cdf0e10cSrcweir // in Insert-Undo "Delete" rueckgaengig
3967cdf0e10cSrcweir const ScChangeActionLinkEntry* pLink = pAct->GetFirstDependentEntry();
3968cdf0e10cSrcweir while ( pLink )
3969cdf0e10cSrcweir {
3970cdf0e10cSrcweir ScChangeAction* p = (ScChangeAction*) pLink->GetAction();
3971cdf0e10cSrcweir if ( p )
3972cdf0e10cSrcweir p->RemoveDeletedIn( pAct );
3973cdf0e10cSrcweir pLink = pLink->GetNext();
3974cdf0e10cSrcweir }
3975cdf0e10cSrcweir
3976cdf0e10cSrcweir // #i87049# [Collaboration] Conflict between delete row and insert content is not merged correctly
3977cdf0e10cSrcweir for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
3978cdf0e10cSrcweir {
3979cdf0e10cSrcweir if ( p->IsDeletedIn( pAct ) && pAct->IsInsertType() &&
3980cdf0e10cSrcweir // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
3981cdf0e10cSrcweir ( p->GetType() == SC_CAT_CONTENT ||
3982cdf0e10cSrcweir p->GetType() == SC_CAT_DELETE_ROWS || p->GetType() == SC_CAT_DELETE_COLS ||
3983cdf0e10cSrcweir p->GetType() == SC_CAT_INSERT_ROWS || p->GetType() == SC_CAT_INSERT_COLS ) &&
3984cdf0e10cSrcweir pAct->GetBigRange().Intersects( p->GetBigRange() ) )
3985cdf0e10cSrcweir {
3986cdf0e10cSrcweir p->RemoveDeletedIn( pAct );
3987cdf0e10cSrcweir }
3988cdf0e10cSrcweir }
3989cdf0e10cSrcweir }
3990cdf0e10cSrcweir break;
3991cdf0e10cSrcweir // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
3992cdf0e10cSrcweir case SC_CTMS_UNDO :
3993cdf0e10cSrcweir {
3994cdf0e10cSrcweir for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
3995cdf0e10cSrcweir {
3996cdf0e10cSrcweir if ( !p->IsDeletedIn( pAct ) && pAct->IsInsertType() &&
3997cdf0e10cSrcweir ( p->GetType() == SC_CAT_CONTENT ||
3998cdf0e10cSrcweir p->GetType() == SC_CAT_DELETE_ROWS || p->GetType() == SC_CAT_DELETE_COLS ||
3999cdf0e10cSrcweir p->GetType() == SC_CAT_INSERT_ROWS || p->GetType() == SC_CAT_INSERT_COLS ) &&
4000cdf0e10cSrcweir pAct->GetBigRange().Intersects( p->GetBigRange() ) )
4001cdf0e10cSrcweir {
4002cdf0e10cSrcweir p->SetDeletedIn( pAct );
4003cdf0e10cSrcweir }
4004cdf0e10cSrcweir }
4005cdf0e10cSrcweir
4006cdf0e10cSrcweir for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() )
4007cdf0e10cSrcweir {
4008cdf0e10cSrcweir if ( p == pAct )
4009cdf0e10cSrcweir {
4010cdf0e10cSrcweir continue;
4011cdf0e10cSrcweir }
4012cdf0e10cSrcweir if ( !p->IsDeletedIn( pAct ) && p->GetActionNumber() <= pAct->GetActionNumber() )
4013cdf0e10cSrcweir {
4014cdf0e10cSrcweir p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz );
4015cdf0e10cSrcweir }
4016cdf0e10cSrcweir }
4017cdf0e10cSrcweir }
4018cdf0e10cSrcweir break;
4019cdf0e10cSrcweir }
4020cdf0e10cSrcweir }
4021cdf0e10cSrcweir }
4022cdf0e10cSrcweir
4023cdf0e10cSrcweir
GetDependents(ScChangeAction * pAct,ScChangeActionTable & rTable,sal_Bool bListMasterDelete,sal_Bool bAllFlat) const4024cdf0e10cSrcweir void ScChangeTrack::GetDependents( ScChangeAction* pAct,
4025cdf0e10cSrcweir ScChangeActionTable& rTable, sal_Bool bListMasterDelete, sal_Bool bAllFlat ) const
4026cdf0e10cSrcweir {
4027cdf0e10cSrcweir //! bAllFlat==TRUE: intern aus Accept oder Reject gerufen,
4028cdf0e10cSrcweir //! => Generated werden nicht aufgenommen
4029cdf0e10cSrcweir
4030cdf0e10cSrcweir sal_Bool bIsDelete = pAct->IsDeleteType();
4031cdf0e10cSrcweir sal_Bool bIsMasterDelete = ( bListMasterDelete && pAct->IsMasterDelete() );
4032cdf0e10cSrcweir
4033cdf0e10cSrcweir const ScChangeAction* pCur = pAct;
4034cdf0e10cSrcweir ScChangeActionStack* pStack = new ScChangeActionStack;
4035cdf0e10cSrcweir do
4036cdf0e10cSrcweir {
4037cdf0e10cSrcweir if ( pCur->IsInsertType() )
4038cdf0e10cSrcweir {
4039cdf0e10cSrcweir const ScChangeActionLinkEntry* pL = pCur->GetFirstDependentEntry();
4040cdf0e10cSrcweir while ( pL )
4041cdf0e10cSrcweir {
4042cdf0e10cSrcweir ScChangeAction* p = (ScChangeAction*) pL->GetAction();
4043cdf0e10cSrcweir if ( p != pAct )
4044cdf0e10cSrcweir {
4045cdf0e10cSrcweir if ( bAllFlat )
4046cdf0e10cSrcweir {
4047cdf0e10cSrcweir sal_uLong n = p->GetActionNumber();
4048cdf0e10cSrcweir if ( !IsGenerated( n ) && rTable.Insert( n, p ) )
4049cdf0e10cSrcweir if ( p->HasDependent() )
4050cdf0e10cSrcweir pStack->Push( p );
4051cdf0e10cSrcweir }
4052cdf0e10cSrcweir else
4053cdf0e10cSrcweir {
4054cdf0e10cSrcweir if ( p->GetType() == SC_CAT_CONTENT )
4055cdf0e10cSrcweir {
4056cdf0e10cSrcweir if ( ((ScChangeActionContent*)p)->IsTopContent() )
4057cdf0e10cSrcweir rTable.Insert( p->GetActionNumber(), p );
4058cdf0e10cSrcweir }
4059cdf0e10cSrcweir else
4060cdf0e10cSrcweir rTable.Insert( p->GetActionNumber(), p );
4061cdf0e10cSrcweir }
4062cdf0e10cSrcweir }
4063cdf0e10cSrcweir pL = pL->GetNext();
4064cdf0e10cSrcweir }
4065cdf0e10cSrcweir }
4066cdf0e10cSrcweir else if ( pCur->IsDeleteType() )
4067cdf0e10cSrcweir {
4068cdf0e10cSrcweir if ( bIsDelete )
4069cdf0e10cSrcweir { // Inhalte geloeschter Bereiche interessieren nur bei Delete
4070cdf0e10cSrcweir ScChangeActionDel* pDel = (ScChangeActionDel*) pCur;
4071cdf0e10cSrcweir if ( !bAllFlat && bIsMasterDelete && pCur == pAct )
4072cdf0e10cSrcweir {
4073cdf0e10cSrcweir // zu diesem Delete gehoerende Deletes in gleiche Ebene,
4074cdf0e10cSrcweir // wenn dieses Delete das momentan oberste einer Reihe ist,
4075cdf0e10cSrcweir ScChangeActionType eType = pDel->GetType();
4076cdf0e10cSrcweir ScChangeAction* p = pDel;
4077cdf0e10cSrcweir while ( (p = p->GetPrev()) != NULL && p->GetType() == eType &&
4078cdf0e10cSrcweir !((ScChangeActionDel*)p)->IsTopDelete() )
4079cdf0e10cSrcweir rTable.Insert( p->GetActionNumber(), p );
4080cdf0e10cSrcweir // dieses Delete auch in Table!
4081cdf0e10cSrcweir rTable.Insert( pAct->GetActionNumber(), pAct );
4082cdf0e10cSrcweir }
4083cdf0e10cSrcweir else
4084cdf0e10cSrcweir {
4085cdf0e10cSrcweir const ScChangeActionLinkEntry* pL = pCur->GetFirstDeletedEntry();
4086cdf0e10cSrcweir while ( pL )
4087cdf0e10cSrcweir {
4088cdf0e10cSrcweir ScChangeAction* p = (ScChangeAction*) pL->GetAction();
4089cdf0e10cSrcweir if ( p != pAct )
4090cdf0e10cSrcweir {
4091cdf0e10cSrcweir if ( bAllFlat )
4092cdf0e10cSrcweir {
4093cdf0e10cSrcweir // nur ein TopContent einer Kette ist in LinkDeleted
4094cdf0e10cSrcweir sal_uLong n = p->GetActionNumber();
4095cdf0e10cSrcweir if ( !IsGenerated( n ) && rTable.Insert( n, p ) )
4096cdf0e10cSrcweir if ( p->HasDeleted() ||
4097cdf0e10cSrcweir p->GetType() == SC_CAT_CONTENT )
4098cdf0e10cSrcweir pStack->Push( p );
4099cdf0e10cSrcweir }
4100cdf0e10cSrcweir else
4101cdf0e10cSrcweir {
4102cdf0e10cSrcweir if ( p->IsDeleteType() )
4103cdf0e10cSrcweir { // weiteres TopDelete in gleiche Ebene,
4104cdf0e10cSrcweir // es ist nicht rejectable
4105cdf0e10cSrcweir if ( ((ScChangeActionDel*)p)->IsTopDelete() )
4106cdf0e10cSrcweir rTable.Insert( p->GetActionNumber(), p );
4107cdf0e10cSrcweir }
4108cdf0e10cSrcweir else
4109cdf0e10cSrcweir rTable.Insert( p->GetActionNumber(), p );
4110cdf0e10cSrcweir }
4111cdf0e10cSrcweir }
4112cdf0e10cSrcweir pL = pL->GetNext();
4113cdf0e10cSrcweir }
4114cdf0e10cSrcweir }
4115cdf0e10cSrcweir }
4116cdf0e10cSrcweir }
4117cdf0e10cSrcweir else if ( pCur->GetType() == SC_CAT_MOVE )
4118cdf0e10cSrcweir {
4119cdf0e10cSrcweir // geloeschte Contents im ToRange
4120cdf0e10cSrcweir const ScChangeActionLinkEntry* pL = pCur->GetFirstDeletedEntry();
4121cdf0e10cSrcweir while ( pL )
4122cdf0e10cSrcweir {
4123cdf0e10cSrcweir ScChangeAction* p = (ScChangeAction*) pL->GetAction();
4124cdf0e10cSrcweir if ( p != pAct && rTable.Insert( p->GetActionNumber(), p ) )
4125cdf0e10cSrcweir {
4126cdf0e10cSrcweir // nur ein TopContent einer Kette ist in LinkDeleted
4127cdf0e10cSrcweir if ( bAllFlat && (p->HasDeleted() ||
4128cdf0e10cSrcweir p->GetType() == SC_CAT_CONTENT) )
4129cdf0e10cSrcweir pStack->Push( p );
4130cdf0e10cSrcweir }
4131cdf0e10cSrcweir pL = pL->GetNext();
4132cdf0e10cSrcweir }
4133cdf0e10cSrcweir // neue Contents im FromRange oder neuer FromRange im ToRange
4134cdf0e10cSrcweir // oder Inserts/Deletes in FromRange/ToRange
4135cdf0e10cSrcweir pL = pCur->GetFirstDependentEntry();
4136cdf0e10cSrcweir while ( pL )
4137cdf0e10cSrcweir {
4138cdf0e10cSrcweir ScChangeAction* p = (ScChangeAction*) pL->GetAction();
4139cdf0e10cSrcweir if ( p != pAct )
4140cdf0e10cSrcweir {
4141cdf0e10cSrcweir if ( bAllFlat )
4142cdf0e10cSrcweir {
4143cdf0e10cSrcweir sal_uLong n = p->GetActionNumber();
4144cdf0e10cSrcweir if ( !IsGenerated( n ) && rTable.Insert( n, p ) )
4145cdf0e10cSrcweir if ( p->HasDependent() || p->HasDeleted() )
4146cdf0e10cSrcweir pStack->Push( p );
4147cdf0e10cSrcweir }
4148cdf0e10cSrcweir else
4149cdf0e10cSrcweir {
4150cdf0e10cSrcweir if ( p->GetType() == SC_CAT_CONTENT )
4151cdf0e10cSrcweir {
4152cdf0e10cSrcweir if ( ((ScChangeActionContent*)p)->IsTopContent() )
4153cdf0e10cSrcweir rTable.Insert( p->GetActionNumber(), p );
4154cdf0e10cSrcweir }
4155cdf0e10cSrcweir else
4156cdf0e10cSrcweir rTable.Insert( p->GetActionNumber(), p );
4157cdf0e10cSrcweir }
4158cdf0e10cSrcweir }
4159cdf0e10cSrcweir pL = pL->GetNext();
4160cdf0e10cSrcweir }
4161cdf0e10cSrcweir }
4162cdf0e10cSrcweir else if ( pCur->GetType() == SC_CAT_CONTENT )
4163cdf0e10cSrcweir { // alle Aenderungen an gleicher Position
4164cdf0e10cSrcweir ScChangeActionContent* pContent = (ScChangeActionContent*) pCur;
4165cdf0e10cSrcweir // alle vorherigen
4166cdf0e10cSrcweir while ( ( pContent = pContent->GetPrevContent() ) != NULL )
4167cdf0e10cSrcweir {
4168cdf0e10cSrcweir if ( !pContent->IsRejected() )
4169cdf0e10cSrcweir rTable.Insert( pContent->GetActionNumber(), pContent );
4170cdf0e10cSrcweir }
4171cdf0e10cSrcweir pContent = (ScChangeActionContent*) pCur;
4172cdf0e10cSrcweir // alle nachfolgenden
4173cdf0e10cSrcweir while ( ( pContent = pContent->GetNextContent() ) != NULL )
4174cdf0e10cSrcweir {
4175cdf0e10cSrcweir if ( !pContent->IsRejected() )
4176cdf0e10cSrcweir rTable.Insert( pContent->GetActionNumber(), pContent );
4177cdf0e10cSrcweir }
4178cdf0e10cSrcweir // all MatrixReferences of a MatrixOrigin
4179cdf0e10cSrcweir const ScChangeActionLinkEntry* pL = pCur->GetFirstDependentEntry();
4180cdf0e10cSrcweir while ( pL )
4181cdf0e10cSrcweir {
4182cdf0e10cSrcweir ScChangeAction* p = (ScChangeAction*) pL->GetAction();
4183cdf0e10cSrcweir if ( p != pAct )
4184cdf0e10cSrcweir {
4185cdf0e10cSrcweir if ( bAllFlat )
4186cdf0e10cSrcweir {
4187cdf0e10cSrcweir sal_uLong n = p->GetActionNumber();
4188cdf0e10cSrcweir if ( !IsGenerated( n ) && rTable.Insert( n, p ) )
4189cdf0e10cSrcweir if ( p->HasDependent() )
4190cdf0e10cSrcweir pStack->Push( p );
4191cdf0e10cSrcweir }
4192cdf0e10cSrcweir else
4193cdf0e10cSrcweir rTable.Insert( p->GetActionNumber(), p );
4194cdf0e10cSrcweir }
4195cdf0e10cSrcweir pL = pL->GetNext();
4196cdf0e10cSrcweir }
4197cdf0e10cSrcweir }
4198cdf0e10cSrcweir else if ( pCur->GetType() == SC_CAT_REJECT )
4199cdf0e10cSrcweir {
4200cdf0e10cSrcweir if ( bAllFlat )
4201cdf0e10cSrcweir {
4202cdf0e10cSrcweir ScChangeAction* p = GetAction(
4203cdf0e10cSrcweir ((ScChangeActionReject*)pCur)->GetRejectAction() );
4204cdf0e10cSrcweir if ( p != pAct && !rTable.Get( p->GetActionNumber() ) )
4205cdf0e10cSrcweir pStack->Push( p );
4206cdf0e10cSrcweir }
4207cdf0e10cSrcweir }
4208cdf0e10cSrcweir } while ( ( pCur = pStack->Pop() ) != NULL );
4209cdf0e10cSrcweir delete pStack;
4210cdf0e10cSrcweir }
4211cdf0e10cSrcweir
4212cdf0e10cSrcweir
SelectContent(ScChangeAction * pAct,sal_Bool bOldest)4213cdf0e10cSrcweir sal_Bool ScChangeTrack::SelectContent( ScChangeAction* pAct, sal_Bool bOldest )
4214cdf0e10cSrcweir {
4215cdf0e10cSrcweir if ( pAct->GetType() != SC_CAT_CONTENT )
4216cdf0e10cSrcweir return sal_False;
4217cdf0e10cSrcweir
4218cdf0e10cSrcweir ScChangeActionContent* pContent = (ScChangeActionContent*) pAct;
4219cdf0e10cSrcweir if ( bOldest )
4220cdf0e10cSrcweir {
4221cdf0e10cSrcweir pContent = pContent->GetTopContent();
4222cdf0e10cSrcweir ScChangeActionContent* pPrevContent;
4223cdf0e10cSrcweir while ( (pPrevContent = pContent->GetPrevContent()) != NULL &&
4224cdf0e10cSrcweir pPrevContent->IsVirgin() )
4225cdf0e10cSrcweir pContent = pPrevContent;
4226cdf0e10cSrcweir }
4227cdf0e10cSrcweir
4228cdf0e10cSrcweir if ( !pContent->IsClickable() )
4229cdf0e10cSrcweir return sal_False;
4230cdf0e10cSrcweir
4231cdf0e10cSrcweir ScBigRange aBigRange( pContent->GetBigRange() );
4232cdf0e10cSrcweir const ScBaseCell* pCell = (bOldest ? pContent->GetOldCell() :
4233cdf0e10cSrcweir pContent->GetNewCell());
4234cdf0e10cSrcweir if ( ScChangeActionContent::GetContentCellType( pCell ) == SC_CACCT_MATORG )
4235cdf0e10cSrcweir {
4236cdf0e10cSrcweir SCCOL nC;
4237cdf0e10cSrcweir SCROW nR;
4238cdf0e10cSrcweir ((const ScFormulaCell*)pCell)->GetMatColsRows( nC, nR );
4239cdf0e10cSrcweir aBigRange.aEnd.IncCol( nC-1 );
4240cdf0e10cSrcweir aBigRange.aEnd.IncRow( nR-1 );
4241cdf0e10cSrcweir }
4242cdf0e10cSrcweir
4243cdf0e10cSrcweir if ( !aBigRange.IsValid( pDoc ) )
4244cdf0e10cSrcweir return sal_False;
4245cdf0e10cSrcweir
4246cdf0e10cSrcweir ScRange aRange( aBigRange.MakeRange() );
4247cdf0e10cSrcweir if ( !pDoc->IsBlockEditable( aRange.aStart.Tab(), aRange.aStart.Col(),
4248cdf0e10cSrcweir aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row() ) )
4249cdf0e10cSrcweir return sal_False;
4250cdf0e10cSrcweir
4251cdf0e10cSrcweir if ( pContent->HasDependent() )
4252cdf0e10cSrcweir {
4253cdf0e10cSrcweir sal_Bool bOk = sal_True;
4254cdf0e10cSrcweir Stack aRejectActions;
4255cdf0e10cSrcweir const ScChangeActionLinkEntry* pL = pContent->GetFirstDependentEntry();
4256cdf0e10cSrcweir while ( pL )
4257cdf0e10cSrcweir {
4258cdf0e10cSrcweir ScChangeAction* p = (ScChangeAction*) pL->GetAction();
4259cdf0e10cSrcweir if ( p != pContent )
4260cdf0e10cSrcweir {
4261cdf0e10cSrcweir if ( p->GetType() == SC_CAT_CONTENT )
4262cdf0e10cSrcweir {
4263cdf0e10cSrcweir // we don't need no recursion here, do we?
4264cdf0e10cSrcweir bOk &= ((ScChangeActionContent*)p)->Select( pDoc, this,
4265cdf0e10cSrcweir bOldest, &aRejectActions );
4266cdf0e10cSrcweir }
4267cdf0e10cSrcweir else
4268cdf0e10cSrcweir {
4269cdf0e10cSrcweir DBG_ERRORFILE( "ScChangeTrack::SelectContent: content dependent no content" );
4270cdf0e10cSrcweir }
4271cdf0e10cSrcweir }
4272cdf0e10cSrcweir pL = pL->GetNext();
4273cdf0e10cSrcweir }
4274cdf0e10cSrcweir
4275cdf0e10cSrcweir bOk &= pContent->Select( pDoc, this, bOldest, NULL );
4276cdf0e10cSrcweir // now the matrix is inserted and new content values are ready
4277cdf0e10cSrcweir
4278cdf0e10cSrcweir ScChangeActionContent* pNew;
4279cdf0e10cSrcweir while ( ( pNew = (ScChangeActionContent*) aRejectActions.Pop() ) != NULL )
4280cdf0e10cSrcweir {
4281cdf0e10cSrcweir ScAddress aPos( pNew->GetBigRange().aStart.MakeAddress() );
4282cdf0e10cSrcweir pNew->SetNewValue( pDoc->GetCell( aPos ), pDoc );
4283cdf0e10cSrcweir Append( pNew );
4284cdf0e10cSrcweir }
4285cdf0e10cSrcweir return bOk;
4286cdf0e10cSrcweir }
4287cdf0e10cSrcweir else
4288cdf0e10cSrcweir return pContent->Select( pDoc, this, bOldest, NULL );
4289cdf0e10cSrcweir }
4290cdf0e10cSrcweir
4291cdf0e10cSrcweir
AcceptAll()4292cdf0e10cSrcweir void ScChangeTrack::AcceptAll()
4293cdf0e10cSrcweir {
4294cdf0e10cSrcweir for ( ScChangeAction* p = GetFirst(); p; p = p->GetNext() )
4295cdf0e10cSrcweir {
4296cdf0e10cSrcweir p->Accept();
4297cdf0e10cSrcweir }
4298cdf0e10cSrcweir }
4299cdf0e10cSrcweir
4300cdf0e10cSrcweir
Accept(ScChangeAction * pAct)4301cdf0e10cSrcweir sal_Bool ScChangeTrack::Accept( ScChangeAction* pAct )
4302cdf0e10cSrcweir {
4303cdf0e10cSrcweir if ( !pAct->IsClickable() )
4304cdf0e10cSrcweir return sal_False;
4305cdf0e10cSrcweir
4306cdf0e10cSrcweir if ( pAct->IsDeleteType() || pAct->GetType() == SC_CAT_CONTENT )
4307cdf0e10cSrcweir {
4308cdf0e10cSrcweir ScChangeActionTable aActionTable;
4309cdf0e10cSrcweir GetDependents( pAct, aActionTable, sal_False, sal_True );
4310cdf0e10cSrcweir for ( ScChangeAction* p = aActionTable.First(); p; p = aActionTable.Next() )
4311cdf0e10cSrcweir {
4312cdf0e10cSrcweir p->Accept();
4313cdf0e10cSrcweir }
4314cdf0e10cSrcweir }
4315cdf0e10cSrcweir pAct->Accept();
4316cdf0e10cSrcweir return sal_True;
4317cdf0e10cSrcweir }
4318cdf0e10cSrcweir
4319cdf0e10cSrcweir
RejectAll()4320cdf0e10cSrcweir sal_Bool ScChangeTrack::RejectAll()
4321cdf0e10cSrcweir {
4322cdf0e10cSrcweir sal_Bool bOk = sal_True;
4323cdf0e10cSrcweir for ( ScChangeAction* p = GetLast(); p && bOk; p = p->GetPrev() )
4324cdf0e10cSrcweir { //! rueckwaerts, weil abhaengige hinten und RejectActions angehaengt
4325cdf0e10cSrcweir if ( p->IsInternalRejectable() )
4326cdf0e10cSrcweir bOk = Reject( p );
4327cdf0e10cSrcweir }
4328cdf0e10cSrcweir return bOk;
4329cdf0e10cSrcweir }
4330cdf0e10cSrcweir
4331cdf0e10cSrcweir
Reject(ScChangeAction * pAct,bool bShared)4332cdf0e10cSrcweir sal_Bool ScChangeTrack::Reject( ScChangeAction* pAct, bool bShared )
4333cdf0e10cSrcweir {
4334cdf0e10cSrcweir // #i100895# When collaboration changes are reversed, it must be possible
4335cdf0e10cSrcweir // to reject a deleted row above another deleted row.
4336cdf0e10cSrcweir if ( bShared && pAct->IsDeletedIn() )
4337cdf0e10cSrcweir pAct->RemoveAllDeletedIn();
4338cdf0e10cSrcweir
4339cdf0e10cSrcweir if ( !pAct->IsRejectable() )
4340cdf0e10cSrcweir return sal_False;
4341cdf0e10cSrcweir
4342cdf0e10cSrcweir ScChangeActionTable* pTable = NULL;
4343cdf0e10cSrcweir if ( pAct->HasDependent() )
4344cdf0e10cSrcweir {
4345cdf0e10cSrcweir pTable = new ScChangeActionTable;
4346cdf0e10cSrcweir GetDependents( pAct, *pTable, sal_False, sal_True );
4347cdf0e10cSrcweir }
4348cdf0e10cSrcweir sal_Bool bRejected = Reject( pAct, pTable, sal_False );
4349cdf0e10cSrcweir if ( pTable )
4350cdf0e10cSrcweir delete pTable;
4351cdf0e10cSrcweir return bRejected;
4352cdf0e10cSrcweir }
4353cdf0e10cSrcweir
4354cdf0e10cSrcweir
Reject(ScChangeAction * pAct,ScChangeActionTable * pTable,sal_Bool bRecursion)4355cdf0e10cSrcweir sal_Bool ScChangeTrack::Reject( ScChangeAction* pAct, ScChangeActionTable* pTable,
4356cdf0e10cSrcweir sal_Bool bRecursion )
4357cdf0e10cSrcweir {
4358cdf0e10cSrcweir if ( !pAct->IsInternalRejectable() )
4359cdf0e10cSrcweir return sal_False;
4360cdf0e10cSrcweir
4361cdf0e10cSrcweir sal_Bool bOk = sal_True;
4362cdf0e10cSrcweir sal_Bool bRejected = sal_False;
4363cdf0e10cSrcweir if ( pAct->IsInsertType() )
4364cdf0e10cSrcweir {
4365cdf0e10cSrcweir if ( pAct->HasDependent() && !bRecursion )
4366cdf0e10cSrcweir {
4367cdf0e10cSrcweir DBG_ASSERT( pTable, "ScChangeTrack::Reject: Insert ohne Table" );
4368cdf0e10cSrcweir for ( ScChangeAction* p = pTable->Last(); p && bOk; p = pTable->Prev() )
4369cdf0e10cSrcweir {
4370cdf0e10cSrcweir // keine Contents restoren, die eh geloescht werden wuerden
4371cdf0e10cSrcweir if ( p->GetType() == SC_CAT_CONTENT )
4372cdf0e10cSrcweir p->SetRejected();
4373cdf0e10cSrcweir else if ( p->IsDeleteType() )
4374cdf0e10cSrcweir p->Accept(); // geloeschtes ins Nirvana
4375cdf0e10cSrcweir else
4376cdf0e10cSrcweir bOk = Reject( p, NULL, sal_True ); //! rekursiv
4377cdf0e10cSrcweir }
4378cdf0e10cSrcweir }
4379cdf0e10cSrcweir if ( bOk && (bRejected = pAct->Reject( pDoc )) != sal_False )
4380cdf0e10cSrcweir {
4381cdf0e10cSrcweir // pRefDoc NULL := geloeschte Zellen nicht speichern
4382cdf0e10cSrcweir AppendDeleteRange( pAct->GetBigRange().MakeRange(), NULL, (short) 0,
4383cdf0e10cSrcweir pAct->GetActionNumber() );
4384cdf0e10cSrcweir }
4385cdf0e10cSrcweir }
4386cdf0e10cSrcweir else if ( pAct->IsDeleteType() )
4387cdf0e10cSrcweir {
4388cdf0e10cSrcweir DBG_ASSERT( !pTable, "ScChangeTrack::Reject: Delete mit Table" );
4389cdf0e10cSrcweir ScBigRange aDelRange;
4390cdf0e10cSrcweir sal_uLong nRejectAction = pAct->GetActionNumber();
4391cdf0e10cSrcweir sal_Bool bTabDel, bTabDelOk;
4392cdf0e10cSrcweir if ( pAct->GetType() == SC_CAT_DELETE_TABS )
4393cdf0e10cSrcweir {
4394cdf0e10cSrcweir bTabDel = sal_True;
4395cdf0e10cSrcweir aDelRange = pAct->GetBigRange();
4396cdf0e10cSrcweir bOk = bTabDelOk = pAct->Reject( pDoc );
4397cdf0e10cSrcweir if ( bOk )
4398cdf0e10cSrcweir {
4399cdf0e10cSrcweir pAct = pAct->GetPrev();
4400cdf0e10cSrcweir bOk = ( pAct && pAct->GetType() == SC_CAT_DELETE_COLS );
4401cdf0e10cSrcweir }
4402cdf0e10cSrcweir }
4403cdf0e10cSrcweir else
4404cdf0e10cSrcweir bTabDel = bTabDelOk = sal_False;
4405cdf0e10cSrcweir ScChangeActionDel* pDel = (ScChangeActionDel*) pAct;
4406cdf0e10cSrcweir if ( bOk )
4407cdf0e10cSrcweir {
4408cdf0e10cSrcweir aDelRange = pDel->GetOverAllRange();
4409cdf0e10cSrcweir bOk = aDelRange.IsValid( pDoc );
4410cdf0e10cSrcweir }
4411cdf0e10cSrcweir sal_Bool bOneOk = sal_False;
4412cdf0e10cSrcweir if ( bOk )
4413cdf0e10cSrcweir {
4414cdf0e10cSrcweir ScChangeActionType eActType = pAct->GetType();
4415cdf0e10cSrcweir switch ( eActType )
4416cdf0e10cSrcweir {
4417cdf0e10cSrcweir case SC_CAT_DELETE_COLS :
4418cdf0e10cSrcweir aDelRange.aStart.SetCol( aDelRange.aEnd.Col() );
4419cdf0e10cSrcweir break;
4420cdf0e10cSrcweir case SC_CAT_DELETE_ROWS :
4421cdf0e10cSrcweir aDelRange.aStart.SetRow( aDelRange.aEnd.Row() );
4422cdf0e10cSrcweir break;
4423cdf0e10cSrcweir case SC_CAT_DELETE_TABS :
4424cdf0e10cSrcweir aDelRange.aStart.SetTab( aDelRange.aEnd.Tab() );
4425cdf0e10cSrcweir break;
4426cdf0e10cSrcweir default:
4427cdf0e10cSrcweir {
4428cdf0e10cSrcweir // added to avoid warnings
4429cdf0e10cSrcweir }
4430cdf0e10cSrcweir }
4431cdf0e10cSrcweir ScChangeAction* p = pAct;
4432cdf0e10cSrcweir sal_Bool bLoop = sal_True;
4433cdf0e10cSrcweir do
4434cdf0e10cSrcweir {
4435cdf0e10cSrcweir pDel = (ScChangeActionDel*) p;
4436cdf0e10cSrcweir bOk = pDel->Reject( pDoc );
4437cdf0e10cSrcweir if ( bOk )
4438cdf0e10cSrcweir {
4439cdf0e10cSrcweir if ( bOneOk )
4440cdf0e10cSrcweir {
4441cdf0e10cSrcweir switch ( pDel->GetType() )
4442cdf0e10cSrcweir {
4443cdf0e10cSrcweir case SC_CAT_DELETE_COLS :
4444cdf0e10cSrcweir aDelRange.aStart.IncCol( -1 );
4445cdf0e10cSrcweir break;
4446cdf0e10cSrcweir case SC_CAT_DELETE_ROWS :
4447cdf0e10cSrcweir aDelRange.aStart.IncRow( -1 );
4448cdf0e10cSrcweir break;
4449cdf0e10cSrcweir case SC_CAT_DELETE_TABS :
4450cdf0e10cSrcweir aDelRange.aStart.IncTab( -1 );
4451cdf0e10cSrcweir break;
4452cdf0e10cSrcweir default:
4453cdf0e10cSrcweir {
4454cdf0e10cSrcweir // added to avoid warnings
4455cdf0e10cSrcweir }
4456cdf0e10cSrcweir }
4457cdf0e10cSrcweir }
4458cdf0e10cSrcweir else
4459cdf0e10cSrcweir bOneOk = sal_True;
4460cdf0e10cSrcweir }
4461cdf0e10cSrcweir if ( pDel->IsBaseDelete() )
4462cdf0e10cSrcweir bLoop = sal_False;
4463cdf0e10cSrcweir else
4464cdf0e10cSrcweir p = p->GetPrev();
4465cdf0e10cSrcweir } while ( bOk && bLoop && p && p->GetType() == eActType &&
4466cdf0e10cSrcweir !((ScChangeActionDel*)p)->IsTopDelete() );
4467cdf0e10cSrcweir }
4468cdf0e10cSrcweir bRejected = bOk;
4469cdf0e10cSrcweir if ( bOneOk || (bTabDel && bTabDelOk) )
4470cdf0e10cSrcweir {
4471cdf0e10cSrcweir // Delete-Reject machte UpdateReference Undo
4472cdf0e10cSrcweir ScChangeActionIns* pReject = new ScChangeActionIns(
4473cdf0e10cSrcweir aDelRange.MakeRange() );
4474cdf0e10cSrcweir pReject->SetRejectAction( nRejectAction );
4475cdf0e10cSrcweir pReject->SetState( SC_CAS_ACCEPTED );
4476cdf0e10cSrcweir Append( pReject );
4477cdf0e10cSrcweir }
4478cdf0e10cSrcweir }
4479cdf0e10cSrcweir else if ( pAct->GetType() == SC_CAT_MOVE )
4480cdf0e10cSrcweir {
4481cdf0e10cSrcweir if ( pAct->HasDependent() && !bRecursion )
4482cdf0e10cSrcweir {
4483cdf0e10cSrcweir DBG_ASSERT( pTable, "ScChangeTrack::Reject: Move ohne Table" );
4484cdf0e10cSrcweir for ( ScChangeAction* p = pTable->Last(); p && bOk; p = pTable->Prev() )
4485cdf0e10cSrcweir {
4486cdf0e10cSrcweir bOk = Reject( p, NULL, sal_True ); //! rekursiv
4487cdf0e10cSrcweir }
4488cdf0e10cSrcweir }
4489cdf0e10cSrcweir if ( bOk && (bRejected = pAct->Reject( pDoc )) != sal_False )
4490cdf0e10cSrcweir {
4491cdf0e10cSrcweir ScChangeActionMove* pReject = new ScChangeActionMove(
4492cdf0e10cSrcweir pAct->GetBigRange().MakeRange(),
4493cdf0e10cSrcweir ((ScChangeActionMove*)pAct)->GetFromRange().MakeRange(), this );
4494cdf0e10cSrcweir pReject->SetRejectAction( pAct->GetActionNumber() );
4495cdf0e10cSrcweir pReject->SetState( SC_CAS_ACCEPTED );
4496cdf0e10cSrcweir Append( pReject );
4497cdf0e10cSrcweir }
4498cdf0e10cSrcweir }
4499cdf0e10cSrcweir else if ( pAct->GetType() == SC_CAT_CONTENT )
4500cdf0e10cSrcweir {
4501cdf0e10cSrcweir ScRange aRange;
4502cdf0e10cSrcweir ScChangeActionContent* pReject;
4503cdf0e10cSrcweir if ( bRecursion )
4504cdf0e10cSrcweir pReject = NULL;
4505cdf0e10cSrcweir else
4506cdf0e10cSrcweir {
4507cdf0e10cSrcweir aRange = pAct->GetBigRange().aStart.MakeAddress();
4508cdf0e10cSrcweir pReject = new ScChangeActionContent( aRange );
4509cdf0e10cSrcweir pReject->SetOldValue( pDoc->GetCell( aRange.aStart ), pDoc, pDoc );
4510cdf0e10cSrcweir }
4511cdf0e10cSrcweir if ( (bRejected = pAct->Reject( pDoc )) != sal_False && !bRecursion )
4512cdf0e10cSrcweir {
4513cdf0e10cSrcweir pReject->SetNewValue( pDoc->GetCell( aRange.aStart ), pDoc );
4514cdf0e10cSrcweir pReject->SetRejectAction( pAct->GetActionNumber() );
4515cdf0e10cSrcweir pReject->SetState( SC_CAS_ACCEPTED );
4516cdf0e10cSrcweir Append( pReject );
4517cdf0e10cSrcweir }
4518cdf0e10cSrcweir else if ( pReject )
4519cdf0e10cSrcweir delete pReject;
4520cdf0e10cSrcweir }
4521cdf0e10cSrcweir else
4522cdf0e10cSrcweir {
4523cdf0e10cSrcweir DBG_ERROR( "ScChangeTrack::Reject: say what?" );
4524cdf0e10cSrcweir }
4525cdf0e10cSrcweir
4526cdf0e10cSrcweir return bRejected;
4527cdf0e10cSrcweir }
4528cdf0e10cSrcweir
4529cdf0e10cSrcweir
AddLoadedGenerated(ScBaseCell * pNewCell,const ScBigRange & aBigRange,const String & sNewValue)4530cdf0e10cSrcweir sal_uLong ScChangeTrack::AddLoadedGenerated(ScBaseCell* pNewCell, const ScBigRange& aBigRange, const String& sNewValue )
4531cdf0e10cSrcweir {
4532cdf0e10cSrcweir ScChangeActionContent* pAct = new ScChangeActionContent( --nGeneratedMin, pNewCell, aBigRange, pDoc, sNewValue );
4533cdf0e10cSrcweir if ( pAct )
4534cdf0e10cSrcweir {
4535cdf0e10cSrcweir if ( pFirstGeneratedDelContent )
4536cdf0e10cSrcweir pFirstGeneratedDelContent->pPrev = pAct;
4537cdf0e10cSrcweir pAct->pNext = pFirstGeneratedDelContent;
4538cdf0e10cSrcweir pFirstGeneratedDelContent = pAct;
4539cdf0e10cSrcweir aGeneratedTable.Insert( pAct->GetActionNumber(), pAct );
4540cdf0e10cSrcweir return pAct->GetActionNumber();
4541cdf0e10cSrcweir }
4542cdf0e10cSrcweir return 0;
4543cdf0e10cSrcweir }
4544cdf0e10cSrcweir
AppendCloned(ScChangeAction * pAppend)4545cdf0e10cSrcweir void ScChangeTrack::AppendCloned( ScChangeAction* pAppend )
4546cdf0e10cSrcweir {
4547cdf0e10cSrcweir aTable.Insert( pAppend->GetActionNumber(), pAppend );
4548cdf0e10cSrcweir if ( !pLast )
4549cdf0e10cSrcweir pFirst = pLast = pAppend;
4550cdf0e10cSrcweir else
4551cdf0e10cSrcweir {
4552cdf0e10cSrcweir pLast->pNext = pAppend;
4553cdf0e10cSrcweir pAppend->pPrev = pLast;
4554cdf0e10cSrcweir pLast = pAppend;
4555cdf0e10cSrcweir }
4556cdf0e10cSrcweir }
4557cdf0e10cSrcweir
Clone(ScDocument * pDocument) const4558cdf0e10cSrcweir ScChangeTrack* ScChangeTrack::Clone( ScDocument* pDocument ) const
4559cdf0e10cSrcweir {
4560cdf0e10cSrcweir if ( !pDocument )
4561cdf0e10cSrcweir {
4562cdf0e10cSrcweir return NULL;
4563cdf0e10cSrcweir }
4564cdf0e10cSrcweir
4565cdf0e10cSrcweir ScChangeTrack* pClonedTrack = new ScChangeTrack( pDocument );
4566cdf0e10cSrcweir pClonedTrack->SetTime100thSeconds( IsTime100thSeconds() );
4567cdf0e10cSrcweir
4568cdf0e10cSrcweir // clone generated actions
4569cdf0e10cSrcweir ::std::stack< const ScChangeAction* > aGeneratedStack;
4570cdf0e10cSrcweir const ScChangeAction* pGenerated = GetFirstGenerated();
4571cdf0e10cSrcweir while ( pGenerated )
4572cdf0e10cSrcweir {
4573cdf0e10cSrcweir aGeneratedStack.push( pGenerated );
4574cdf0e10cSrcweir pGenerated = pGenerated->GetNext();
4575cdf0e10cSrcweir }
4576cdf0e10cSrcweir while ( !aGeneratedStack.empty() )
4577cdf0e10cSrcweir {
4578cdf0e10cSrcweir pGenerated = aGeneratedStack.top();
4579cdf0e10cSrcweir aGeneratedStack.pop();
4580cdf0e10cSrcweir const ScChangeActionContent* pContent = dynamic_cast< const ScChangeActionContent* >( pGenerated );
4581cdf0e10cSrcweir DBG_ASSERT( pContent, "ScChangeTrack::Clone: pContent is null!" );
4582cdf0e10cSrcweir const ScBaseCell* pNewCell = pContent->GetNewCell();
4583cdf0e10cSrcweir if ( pNewCell )
4584cdf0e10cSrcweir {
4585cdf0e10cSrcweir ScBaseCell* pClonedNewCell = pNewCell->CloneWithoutNote( *pDocument );
4586cdf0e10cSrcweir String aNewValue;
4587cdf0e10cSrcweir pContent->GetNewString( aNewValue );
4588cdf0e10cSrcweir pClonedTrack->nGeneratedMin = pGenerated->GetActionNumber() + 1;
4589cdf0e10cSrcweir pClonedTrack->AddLoadedGenerated( pClonedNewCell, pGenerated->GetBigRange(), aNewValue );
4590cdf0e10cSrcweir }
4591cdf0e10cSrcweir }
4592cdf0e10cSrcweir
4593cdf0e10cSrcweir // clone actions
4594cdf0e10cSrcweir const ScChangeAction* pAction = GetFirst();
4595cdf0e10cSrcweir while ( pAction )
4596cdf0e10cSrcweir {
4597cdf0e10cSrcweir ScChangeAction* pClonedAction = NULL;
4598cdf0e10cSrcweir
4599cdf0e10cSrcweir switch ( pAction->GetType() )
4600cdf0e10cSrcweir {
4601cdf0e10cSrcweir case SC_CAT_INSERT_COLS:
4602cdf0e10cSrcweir case SC_CAT_INSERT_ROWS:
4603cdf0e10cSrcweir case SC_CAT_INSERT_TABS:
4604cdf0e10cSrcweir {
4605cdf0e10cSrcweir pClonedAction = new ScChangeActionIns(
4606cdf0e10cSrcweir pAction->GetActionNumber(),
4607cdf0e10cSrcweir pAction->GetState(),
4608cdf0e10cSrcweir pAction->GetRejectAction(),
4609cdf0e10cSrcweir pAction->GetBigRange(),
4610cdf0e10cSrcweir pAction->GetUser(),
4611cdf0e10cSrcweir pAction->GetDateTimeUTC(),
4612cdf0e10cSrcweir pAction->GetComment(),
4613cdf0e10cSrcweir pAction->GetType() );
4614cdf0e10cSrcweir }
4615cdf0e10cSrcweir break;
4616cdf0e10cSrcweir case SC_CAT_DELETE_COLS:
4617cdf0e10cSrcweir case SC_CAT_DELETE_ROWS:
4618cdf0e10cSrcweir case SC_CAT_DELETE_TABS:
4619cdf0e10cSrcweir {
4620cdf0e10cSrcweir const ScChangeActionDel* pDelete = dynamic_cast< const ScChangeActionDel* >( pAction );
4621cdf0e10cSrcweir DBG_ASSERT( pDelete, "ScChangeTrack::Clone: pDelete is null!" );
4622cdf0e10cSrcweir
4623cdf0e10cSrcweir SCsCOLROW nD = 0;
4624cdf0e10cSrcweir ScChangeActionType eType = pAction->GetType();
4625cdf0e10cSrcweir if ( eType == SC_CAT_DELETE_COLS )
4626cdf0e10cSrcweir {
4627cdf0e10cSrcweir nD = static_cast< SCsCOLROW >( pDelete->GetDx() );
4628cdf0e10cSrcweir }
4629cdf0e10cSrcweir else if ( eType == SC_CAT_DELETE_ROWS )
4630cdf0e10cSrcweir {
4631cdf0e10cSrcweir nD = static_cast< SCsCOLROW >( pDelete->GetDy() );
4632cdf0e10cSrcweir }
4633cdf0e10cSrcweir
4634cdf0e10cSrcweir pClonedAction = new ScChangeActionDel(
4635cdf0e10cSrcweir pAction->GetActionNumber(),
4636cdf0e10cSrcweir pAction->GetState(),
4637cdf0e10cSrcweir pAction->GetRejectAction(),
4638cdf0e10cSrcweir pAction->GetBigRange(),
4639cdf0e10cSrcweir pAction->GetUser(),
4640cdf0e10cSrcweir pAction->GetDateTimeUTC(),
4641cdf0e10cSrcweir pAction->GetComment(),
4642cdf0e10cSrcweir eType,
4643cdf0e10cSrcweir nD,
4644cdf0e10cSrcweir pClonedTrack );
4645cdf0e10cSrcweir }
4646cdf0e10cSrcweir break;
4647cdf0e10cSrcweir case SC_CAT_MOVE:
4648cdf0e10cSrcweir {
4649cdf0e10cSrcweir const ScChangeActionMove* pMove = dynamic_cast< const ScChangeActionMove* >( pAction );
4650cdf0e10cSrcweir DBG_ASSERT( pMove, "ScChangeTrack::Clone: pMove is null!" );
4651cdf0e10cSrcweir
4652cdf0e10cSrcweir pClonedAction = new ScChangeActionMove(
4653cdf0e10cSrcweir pAction->GetActionNumber(),
4654cdf0e10cSrcweir pAction->GetState(),
4655cdf0e10cSrcweir pAction->GetRejectAction(),
4656cdf0e10cSrcweir pAction->GetBigRange(),
4657cdf0e10cSrcweir pAction->GetUser(),
4658cdf0e10cSrcweir pAction->GetDateTimeUTC(),
4659cdf0e10cSrcweir pAction->GetComment(),
4660cdf0e10cSrcweir pMove->GetFromRange(),
4661cdf0e10cSrcweir pClonedTrack );
4662cdf0e10cSrcweir }
4663cdf0e10cSrcweir break;
4664cdf0e10cSrcweir case SC_CAT_CONTENT:
4665cdf0e10cSrcweir {
4666cdf0e10cSrcweir const ScChangeActionContent* pContent = dynamic_cast< const ScChangeActionContent* >( pAction );
4667cdf0e10cSrcweir DBG_ASSERT( pContent, "ScChangeTrack::Clone: pContent is null!" );
4668cdf0e10cSrcweir const ScBaseCell* pOldCell = pContent->GetOldCell();
4669cdf0e10cSrcweir ScBaseCell* pClonedOldCell = pOldCell ? pOldCell->CloneWithoutNote( *pDocument ) : 0;
4670cdf0e10cSrcweir String aOldValue;
4671cdf0e10cSrcweir pContent->GetOldString( aOldValue );
4672cdf0e10cSrcweir
4673cdf0e10cSrcweir ScChangeActionContent* pClonedContent = new ScChangeActionContent(
4674cdf0e10cSrcweir pAction->GetActionNumber(),
4675cdf0e10cSrcweir pAction->GetState(),
4676cdf0e10cSrcweir pAction->GetRejectAction(),
4677cdf0e10cSrcweir pAction->GetBigRange(),
4678cdf0e10cSrcweir pAction->GetUser(),
4679cdf0e10cSrcweir pAction->GetDateTimeUTC(),
4680cdf0e10cSrcweir pAction->GetComment(),
4681cdf0e10cSrcweir pClonedOldCell,
4682cdf0e10cSrcweir pDocument,
4683cdf0e10cSrcweir aOldValue );
4684cdf0e10cSrcweir
4685cdf0e10cSrcweir const ScBaseCell* pNewCell = pContent->GetNewCell();
4686cdf0e10cSrcweir if ( pNewCell )
4687cdf0e10cSrcweir {
4688cdf0e10cSrcweir ScBaseCell* pClonedNewCell = pNewCell->CloneWithoutNote( *pDocument );
4689cdf0e10cSrcweir pClonedContent->SetNewValue( pClonedNewCell, pDocument );
4690cdf0e10cSrcweir }
4691cdf0e10cSrcweir
4692cdf0e10cSrcweir pClonedAction = pClonedContent;
4693cdf0e10cSrcweir }
4694cdf0e10cSrcweir break;
4695cdf0e10cSrcweir case SC_CAT_REJECT:
4696cdf0e10cSrcweir {
4697cdf0e10cSrcweir pClonedAction = new ScChangeActionReject(
4698cdf0e10cSrcweir pAction->GetActionNumber(),
4699cdf0e10cSrcweir pAction->GetState(),
4700cdf0e10cSrcweir pAction->GetRejectAction(),
4701cdf0e10cSrcweir pAction->GetBigRange(),
4702cdf0e10cSrcweir pAction->GetUser(),
4703cdf0e10cSrcweir pAction->GetDateTimeUTC(),
4704cdf0e10cSrcweir pAction->GetComment() );
4705cdf0e10cSrcweir }
4706cdf0e10cSrcweir break;
4707cdf0e10cSrcweir default:
4708cdf0e10cSrcweir {
4709cdf0e10cSrcweir }
4710cdf0e10cSrcweir break;
4711cdf0e10cSrcweir }
4712cdf0e10cSrcweir
4713cdf0e10cSrcweir if ( pClonedAction )
4714cdf0e10cSrcweir {
4715cdf0e10cSrcweir pClonedTrack->AppendCloned( pClonedAction );
4716cdf0e10cSrcweir }
4717cdf0e10cSrcweir
4718cdf0e10cSrcweir pAction = pAction->GetNext();
4719cdf0e10cSrcweir }
4720cdf0e10cSrcweir
4721cdf0e10cSrcweir if ( pClonedTrack->GetLast() )
4722cdf0e10cSrcweir {
4723cdf0e10cSrcweir pClonedTrack->SetActionMax( pClonedTrack->GetLast()->GetActionNumber() );
4724cdf0e10cSrcweir }
4725cdf0e10cSrcweir
4726cdf0e10cSrcweir // set dependencies for Deleted/DeletedIn
4727cdf0e10cSrcweir pAction = GetFirst();
4728cdf0e10cSrcweir while ( pAction )
4729cdf0e10cSrcweir {
4730cdf0e10cSrcweir if ( pAction->HasDeleted() )
4731cdf0e10cSrcweir {
4732cdf0e10cSrcweir ::std::stack< sal_uLong > aStack;
4733cdf0e10cSrcweir const ScChangeActionLinkEntry* pL = pAction->GetFirstDeletedEntry();
4734cdf0e10cSrcweir while ( pL )
4735cdf0e10cSrcweir {
4736cdf0e10cSrcweir const ScChangeAction* pDeleted = pL->GetAction();
4737cdf0e10cSrcweir if ( pDeleted )
4738cdf0e10cSrcweir {
4739cdf0e10cSrcweir aStack.push( pDeleted->GetActionNumber() );
4740cdf0e10cSrcweir }
4741cdf0e10cSrcweir pL = pL->GetNext();
4742cdf0e10cSrcweir }
4743cdf0e10cSrcweir ScChangeAction* pClonedAction = pClonedTrack->GetAction( pAction->GetActionNumber() );
4744cdf0e10cSrcweir if ( pClonedAction )
4745cdf0e10cSrcweir {
4746cdf0e10cSrcweir while ( !aStack.empty() )
4747cdf0e10cSrcweir {
4748cdf0e10cSrcweir ScChangeAction* pClonedDeleted = pClonedTrack->GetActionOrGenerated( aStack.top() );
4749cdf0e10cSrcweir aStack.pop();
4750cdf0e10cSrcweir if ( pClonedDeleted )
4751cdf0e10cSrcweir {
4752cdf0e10cSrcweir pClonedDeleted->SetDeletedIn( pClonedAction );
4753cdf0e10cSrcweir }
4754cdf0e10cSrcweir }
4755cdf0e10cSrcweir }
4756cdf0e10cSrcweir }
4757cdf0e10cSrcweir pAction = pAction->GetNext();
4758cdf0e10cSrcweir }
4759cdf0e10cSrcweir
4760cdf0e10cSrcweir // set dependencies for Dependent/Any
4761cdf0e10cSrcweir pAction = GetLast();
4762cdf0e10cSrcweir while ( pAction )
4763cdf0e10cSrcweir {
4764cdf0e10cSrcweir if ( pAction->HasDependent() )
4765cdf0e10cSrcweir {
4766cdf0e10cSrcweir ::std::stack< sal_uLong > aStack;
4767cdf0e10cSrcweir const ScChangeActionLinkEntry* pL = pAction->GetFirstDependentEntry();
4768cdf0e10cSrcweir while ( pL )
4769cdf0e10cSrcweir {
4770cdf0e10cSrcweir const ScChangeAction* pDependent = pL->GetAction();
4771cdf0e10cSrcweir if ( pDependent )
4772cdf0e10cSrcweir {
4773cdf0e10cSrcweir aStack.push( pDependent->GetActionNumber() );
4774cdf0e10cSrcweir }
4775cdf0e10cSrcweir pL = pL->GetNext();
4776cdf0e10cSrcweir }
4777cdf0e10cSrcweir ScChangeAction* pClonedAction = pClonedTrack->GetAction( pAction->GetActionNumber() );
4778cdf0e10cSrcweir if ( pClonedAction )
4779cdf0e10cSrcweir {
4780cdf0e10cSrcweir while ( !aStack.empty() )
4781cdf0e10cSrcweir {
4782cdf0e10cSrcweir ScChangeAction* pClonedDependent = pClonedTrack->GetActionOrGenerated( aStack.top() );
4783cdf0e10cSrcweir aStack.pop();
4784cdf0e10cSrcweir if ( pClonedDependent )
4785cdf0e10cSrcweir {
4786cdf0e10cSrcweir ScChangeActionLinkEntry* pLink = pClonedAction->AddDependent( pClonedDependent );
4787cdf0e10cSrcweir pClonedDependent->AddLink( pClonedAction, pLink );
4788cdf0e10cSrcweir }
4789cdf0e10cSrcweir }
4790cdf0e10cSrcweir }
4791cdf0e10cSrcweir }
4792cdf0e10cSrcweir pAction = pAction->GetPrev();
4793cdf0e10cSrcweir }
4794cdf0e10cSrcweir
4795cdf0e10cSrcweir // masterlinks
4796cdf0e10cSrcweir ScChangeAction* pClonedAction = pClonedTrack->GetFirst();
4797cdf0e10cSrcweir while ( pClonedAction )
4798cdf0e10cSrcweir {
4799cdf0e10cSrcweir pClonedTrack->MasterLinks( pClonedAction );
4800cdf0e10cSrcweir pClonedAction = pClonedAction->GetNext();
4801cdf0e10cSrcweir }
4802cdf0e10cSrcweir
4803cdf0e10cSrcweir if ( IsProtected() )
4804cdf0e10cSrcweir {
4805cdf0e10cSrcweir pClonedTrack->SetProtection( GetProtection() );
4806cdf0e10cSrcweir }
4807cdf0e10cSrcweir
4808cdf0e10cSrcweir if ( pClonedTrack->GetLast() )
4809cdf0e10cSrcweir {
4810cdf0e10cSrcweir pClonedTrack->SetLastSavedActionNumber( pClonedTrack->GetLast()->GetActionNumber() );
4811cdf0e10cSrcweir }
4812cdf0e10cSrcweir
4813cdf0e10cSrcweir pDocument->SetChangeTrack( pClonedTrack );
4814cdf0e10cSrcweir
4815cdf0e10cSrcweir return pClonedTrack;
4816cdf0e10cSrcweir }
4817cdf0e10cSrcweir
MergeActionState(ScChangeAction * pAct,const ScChangeAction * pOtherAct)4818cdf0e10cSrcweir void ScChangeTrack::MergeActionState( ScChangeAction* pAct, const ScChangeAction* pOtherAct )
4819cdf0e10cSrcweir {
4820cdf0e10cSrcweir if ( pAct->IsVirgin() )
4821cdf0e10cSrcweir {
4822cdf0e10cSrcweir if ( pOtherAct->IsAccepted() )
4823cdf0e10cSrcweir {
4824cdf0e10cSrcweir pAct->Accept();
4825cdf0e10cSrcweir if ( pOtherAct->IsRejecting() )
4826cdf0e10cSrcweir {
4827cdf0e10cSrcweir pAct->SetRejectAction( pOtherAct->GetRejectAction() );
4828cdf0e10cSrcweir }
4829cdf0e10cSrcweir }
4830cdf0e10cSrcweir else if ( pOtherAct->IsRejected() )
4831cdf0e10cSrcweir {
4832cdf0e10cSrcweir pAct->SetRejected();
4833cdf0e10cSrcweir }
4834cdf0e10cSrcweir }
4835cdf0e10cSrcweir }
4836cdf0e10cSrcweir
4837cdf0e10cSrcweir #if DEBUG_CHANGETRACK
ToString() const4838cdf0e10cSrcweir String ScChangeTrack::ToString() const
4839cdf0e10cSrcweir {
4840cdf0e10cSrcweir String aReturn;
4841cdf0e10cSrcweir
4842cdf0e10cSrcweir aReturn += String::CreateFromAscii( "============================================================\n" );
4843cdf0e10cSrcweir
4844cdf0e10cSrcweir const ScChangeAction* pGenerated = GetFirstGenerated();
4845cdf0e10cSrcweir while ( pGenerated )
4846cdf0e10cSrcweir {
4847cdf0e10cSrcweir aReturn += pGenerated->ToString( pDoc );
4848cdf0e10cSrcweir aReturn += '\n';
4849cdf0e10cSrcweir pGenerated = pGenerated->GetNext();
4850cdf0e10cSrcweir }
4851cdf0e10cSrcweir
4852cdf0e10cSrcweir aReturn += String::CreateFromAscii( "------------------------------------------------------------\n" );
4853cdf0e10cSrcweir
4854cdf0e10cSrcweir const ScChangeAction* pAction = GetFirst();
4855cdf0e10cSrcweir while ( pAction )
4856cdf0e10cSrcweir {
4857cdf0e10cSrcweir aReturn += pAction->ToString( pDoc );
4858cdf0e10cSrcweir aReturn += '\n';
4859cdf0e10cSrcweir pAction = pAction->GetNext();
4860cdf0e10cSrcweir }
4861cdf0e10cSrcweir aReturn += String::CreateFromAscii( "============================================================\n" );
4862cdf0e10cSrcweir
4863cdf0e10cSrcweir return aReturn;
4864cdf0e10cSrcweir }
4865cdf0e10cSrcweir #endif // DEBUG_CHANGETRACK
4866