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
10*b3f79822SAndrew Rist *
11*b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*b3f79822SAndrew Rist *
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.
19*b3f79822SAndrew Rist *
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
29cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
30cdf0e10cSrcweir
31cdf0e10cSrcweir #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
32cdf0e10cSrcweir #include <com/sun/star/document/XDocumentProperties.hpp>
33cdf0e10cSrcweir
34cdf0e10cSrcweir #include "scitems.hxx"
35cdf0e10cSrcweir #include "rangelst.hxx"
36cdf0e10cSrcweir #include <editeng/flstitem.hxx>
37cdf0e10cSrcweir #include <svx/pageitem.hxx>
38cdf0e10cSrcweir #include <editeng/paperinf.hxx>
39cdf0e10cSrcweir #include <svx/postattr.hxx>
40cdf0e10cSrcweir #include <editeng/sizeitem.hxx>
41cdf0e10cSrcweir #include <unotools/misccfg.hxx>
42cdf0e10cSrcweir #include <sfx2/viewfrm.hxx>
43cdf0e10cSrcweir #include <sfx2/app.hxx>
44cdf0e10cSrcweir #include <sfx2/docfile.hxx>
45cdf0e10cSrcweir #include <sfx2/printer.hxx>
46cdf0e10cSrcweir #include <svtools/ctrltool.hxx>
47cdf0e10cSrcweir #include <vcl/virdev.hxx>
48cdf0e10cSrcweir #include <vcl/svapp.hxx>
49cdf0e10cSrcweir #include <vcl/msgbox.hxx>
50cdf0e10cSrcweir #include <unotools/localedatawrapper.hxx>
51cdf0e10cSrcweir
52cdf0e10cSrcweir #include "docsh.hxx"
53cdf0e10cSrcweir #include "docshimp.hxx"
54cdf0e10cSrcweir #include "scmod.hxx"
55cdf0e10cSrcweir #include "tabvwsh.hxx"
56cdf0e10cSrcweir #include "viewdata.hxx"
57cdf0e10cSrcweir #include "docpool.hxx"
58cdf0e10cSrcweir #include "stlpool.hxx"
59cdf0e10cSrcweir #include "patattr.hxx"
60cdf0e10cSrcweir #include "uiitems.hxx"
61cdf0e10cSrcweir #include "hints.hxx"
62cdf0e10cSrcweir #include "docoptio.hxx"
63cdf0e10cSrcweir #include "viewopti.hxx"
64cdf0e10cSrcweir #include "pntlock.hxx"
65cdf0e10cSrcweir #include "chgtrack.hxx"
66cdf0e10cSrcweir #include "docfunc.hxx"
67cdf0e10cSrcweir #include "cell.hxx"
68cdf0e10cSrcweir #include "chgviset.hxx"
69cdf0e10cSrcweir #include "progress.hxx"
70cdf0e10cSrcweir #include "redcom.hxx"
71cdf0e10cSrcweir #include "sc.hrc"
72cdf0e10cSrcweir #include "inputopt.hxx"
73cdf0e10cSrcweir #include "drwlayer.hxx"
74cdf0e10cSrcweir #include "inputhdl.hxx"
75cdf0e10cSrcweir #include "conflictsdlg.hxx"
76cdf0e10cSrcweir #include "globstr.hrc"
77cdf0e10cSrcweir
78cdf0e10cSrcweir #if DEBUG_CHANGETRACK
79cdf0e10cSrcweir #include <stdio.h>
80cdf0e10cSrcweir #endif // DEBUG_CHANGETRACK
81cdf0e10cSrcweir
82cdf0e10cSrcweir
83cdf0e10cSrcweir //------------------------------------------------------------------
84cdf0e10cSrcweir
85cdf0e10cSrcweir //
86cdf0e10cSrcweir // Redraw - Benachrichtigungen
87cdf0e10cSrcweir //
88cdf0e10cSrcweir
89cdf0e10cSrcweir
PostEditView(ScEditEngineDefaulter * pEditEngine,const ScAddress & rCursorPos)90cdf0e10cSrcweir void ScDocShell::PostEditView( ScEditEngineDefaulter* pEditEngine, const ScAddress& rCursorPos )
91cdf0e10cSrcweir {
92cdf0e10cSrcweir // Broadcast( ScEditViewHint( pEditEngine, rCursorPos ) );
93cdf0e10cSrcweir
94cdf0e10cSrcweir // Test: nur aktive ViewShell
95cdf0e10cSrcweir
96cdf0e10cSrcweir ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
97cdf0e10cSrcweir if (pViewSh && pViewSh->GetViewData()->GetDocShell() == this)
98cdf0e10cSrcweir {
99cdf0e10cSrcweir ScEditViewHint aHint( pEditEngine, rCursorPos );
100cdf0e10cSrcweir pViewSh->Notify( *this, aHint );
101cdf0e10cSrcweir }
102cdf0e10cSrcweir }
103cdf0e10cSrcweir
PostDataChanged()104cdf0e10cSrcweir void ScDocShell::PostDataChanged()
105cdf0e10cSrcweir {
106cdf0e10cSrcweir Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
107cdf0e10cSrcweir aDocument.ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) );
108cdf0e10cSrcweir
109cdf0e10cSrcweir SFX_APP()->Broadcast(SfxSimpleHint( FID_ANYDATACHANGED )); // Navigator
110cdf0e10cSrcweir //! Navigator direkt benachrichtigen!
111cdf0e10cSrcweir }
112cdf0e10cSrcweir
PostPaint(SCCOL nStartCol,SCROW nStartRow,SCTAB nStartTab,SCCOL nEndCol,SCROW nEndRow,SCTAB nEndTab,sal_uInt16 nPart,sal_uInt16 nExtFlags)113cdf0e10cSrcweir void ScDocShell::PostPaint( SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab,
114cdf0e10cSrcweir SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, sal_uInt16 nPart,
115cdf0e10cSrcweir sal_uInt16 nExtFlags )
116cdf0e10cSrcweir {
117cdf0e10cSrcweir if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
118cdf0e10cSrcweir if (!ValidRow(nStartRow)) nStartRow = MAXROW;
119cdf0e10cSrcweir if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
120cdf0e10cSrcweir if (!ValidRow(nEndRow)) nEndRow = MAXROW;
121cdf0e10cSrcweir
122cdf0e10cSrcweir if ( pPaintLockData )
123cdf0e10cSrcweir {
124cdf0e10cSrcweir // #i54081# PAINT_EXTRAS still has to be brodcast because it changes the
125cdf0e10cSrcweir // current sheet if it's invalid. All other flags added to pPaintLockData.
126cdf0e10cSrcweir sal_uInt16 nLockPart = nPart & ~PAINT_EXTRAS;
127cdf0e10cSrcweir if ( nLockPart )
128cdf0e10cSrcweir {
129cdf0e10cSrcweir //! nExtFlags ???
130cdf0e10cSrcweir pPaintLockData->AddRange( ScRange( nStartCol, nStartRow, nStartTab,
131cdf0e10cSrcweir nEndCol, nEndRow, nEndTab ), nLockPart );
132cdf0e10cSrcweir }
133cdf0e10cSrcweir
134cdf0e10cSrcweir nPart &= PAINT_EXTRAS; // for broadcasting
135cdf0e10cSrcweir if ( !nPart )
136cdf0e10cSrcweir return;
137cdf0e10cSrcweir }
138cdf0e10cSrcweir
139cdf0e10cSrcweir
140cdf0e10cSrcweir if (nExtFlags & SC_PF_LINES) // Platz fuer Linien beruecksichtigen
141cdf0e10cSrcweir {
142cdf0e10cSrcweir //! Abfrage auf versteckte Spalten/Zeilen!
143cdf0e10cSrcweir if (nStartCol>0) --nStartCol;
144cdf0e10cSrcweir if (nEndCol<MAXCOL) ++nEndCol;
145cdf0e10cSrcweir if (nStartRow>0) --nStartRow;
146cdf0e10cSrcweir if (nEndRow<MAXROW) ++nEndRow;
147cdf0e10cSrcweir }
148cdf0e10cSrcweir
149cdf0e10cSrcweir // um zusammengefasste erweitern
150cdf0e10cSrcweir if (nExtFlags & SC_PF_TESTMERGE)
151cdf0e10cSrcweir aDocument.ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nStartTab );
152cdf0e10cSrcweir
153cdf0e10cSrcweir if ( nStartCol != 0 || nEndCol != MAXCOL )
154cdf0e10cSrcweir {
155cdf0e10cSrcweir // Extend to whole rows if SC_PF_WHOLEROWS is set, or rotated or non-left
156cdf0e10cSrcweir // aligned cells are contained (see UpdatePaintExt).
157cdf0e10cSrcweir // Special handling for RTL text (#i9731#) is unnecessary now with full
158cdf0e10cSrcweir // support of right-aligned text.
159cdf0e10cSrcweir
160cdf0e10cSrcweir if ( ( nExtFlags & SC_PF_WHOLEROWS ) ||
161cdf0e10cSrcweir aDocument.HasAttrib( nStartCol,nStartRow,nStartTab,
162cdf0e10cSrcweir MAXCOL,nEndRow,nEndTab, HASATTR_ROTATE | HASATTR_RIGHTORCENTER ) )
163cdf0e10cSrcweir {
164cdf0e10cSrcweir nStartCol = 0;
165cdf0e10cSrcweir nEndCol = MAXCOL;
166cdf0e10cSrcweir }
167cdf0e10cSrcweir }
168cdf0e10cSrcweir
169cdf0e10cSrcweir Broadcast( ScPaintHint( ScRange( nStartCol, nStartRow, nStartTab,
170cdf0e10cSrcweir nEndCol, nEndRow, nEndTab ), nPart ) );
171cdf0e10cSrcweir
172cdf0e10cSrcweir if ( nPart & PAINT_GRID )
173cdf0e10cSrcweir aDocument.ResetChanged( ScRange(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) );
174cdf0e10cSrcweir }
175cdf0e10cSrcweir
PostPaint(const ScRange & rRange,sal_uInt16 nPart,sal_uInt16 nExtFlags)176cdf0e10cSrcweir void ScDocShell::PostPaint( const ScRange& rRange, sal_uInt16 nPart, sal_uInt16 nExtFlags )
177cdf0e10cSrcweir {
178cdf0e10cSrcweir PostPaint( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
179cdf0e10cSrcweir rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(),
180cdf0e10cSrcweir nPart, nExtFlags );
181cdf0e10cSrcweir }
182cdf0e10cSrcweir
PostPaintGridAll()183cdf0e10cSrcweir void ScDocShell::PostPaintGridAll()
184cdf0e10cSrcweir {
185cdf0e10cSrcweir PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
186cdf0e10cSrcweir }
187cdf0e10cSrcweir
PostPaintCell(SCCOL nCol,SCROW nRow,SCTAB nTab)188cdf0e10cSrcweir void ScDocShell::PostPaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
189cdf0e10cSrcweir {
190cdf0e10cSrcweir PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID, SC_PF_TESTMERGE );
191cdf0e10cSrcweir }
192cdf0e10cSrcweir
PostPaintCell(const ScAddress & rPos)193cdf0e10cSrcweir void ScDocShell::PostPaintCell( const ScAddress& rPos )
194cdf0e10cSrcweir {
195cdf0e10cSrcweir PostPaintCell( rPos.Col(), rPos.Row(), rPos.Tab() );
196cdf0e10cSrcweir }
197cdf0e10cSrcweir
PostPaintExtras()198cdf0e10cSrcweir void ScDocShell::PostPaintExtras()
199cdf0e10cSrcweir {
200cdf0e10cSrcweir PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS );
201cdf0e10cSrcweir }
202cdf0e10cSrcweir
UpdatePaintExt(sal_uInt16 & rExtFlags,const ScRange & rRange)203cdf0e10cSrcweir void ScDocShell::UpdatePaintExt( sal_uInt16& rExtFlags, const ScRange& rRange )
204cdf0e10cSrcweir {
205cdf0e10cSrcweir if ( ( rExtFlags & SC_PF_LINES ) == 0 && aDocument.HasAttrib( rRange, HASATTR_PAINTEXT ) )
206cdf0e10cSrcweir {
207cdf0e10cSrcweir // If the range contains lines, shadow or conditional formats,
208cdf0e10cSrcweir // set SC_PF_LINES to include one extra cell in all directions.
209cdf0e10cSrcweir
210cdf0e10cSrcweir rExtFlags |= SC_PF_LINES;
211cdf0e10cSrcweir }
212cdf0e10cSrcweir
213cdf0e10cSrcweir if ( ( rExtFlags & SC_PF_WHOLEROWS ) == 0 &&
214cdf0e10cSrcweir ( rRange.aStart.Col() != 0 || rRange.aEnd.Col() != MAXCOL ) &&
215cdf0e10cSrcweir aDocument.HasAttrib( rRange, HASATTR_ROTATE | HASATTR_RIGHTORCENTER ) )
216cdf0e10cSrcweir {
217cdf0e10cSrcweir // If the range contains (logically) right- or center-aligned cells,
218cdf0e10cSrcweir // or rotated cells, set SC_PF_WHOLEROWS to paint the whole rows.
219cdf0e10cSrcweir // This test isn't needed after the cell changes, because it's also
220cdf0e10cSrcweir // tested in PostPaint. UpdatePaintExt may later be changed to do this
221cdf0e10cSrcweir // only if called before the changes.
222cdf0e10cSrcweir
223cdf0e10cSrcweir rExtFlags |= SC_PF_WHOLEROWS;
224cdf0e10cSrcweir }
225cdf0e10cSrcweir }
226cdf0e10cSrcweir
UpdatePaintExt(sal_uInt16 & rExtFlags,SCCOL nStartCol,SCROW nStartRow,SCTAB nStartTab,SCCOL nEndCol,SCROW nEndRow,SCTAB nEndTab)227cdf0e10cSrcweir void ScDocShell::UpdatePaintExt( sal_uInt16& rExtFlags, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab,
228cdf0e10cSrcweir SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab )
229cdf0e10cSrcweir {
230cdf0e10cSrcweir UpdatePaintExt( rExtFlags, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ) );
231cdf0e10cSrcweir }
232cdf0e10cSrcweir
233cdf0e10cSrcweir //------------------------------------------------------------------
234cdf0e10cSrcweir
LockPaint_Impl(sal_Bool bDoc)235cdf0e10cSrcweir void ScDocShell::LockPaint_Impl(sal_Bool bDoc)
236cdf0e10cSrcweir {
237cdf0e10cSrcweir if ( !pPaintLockData )
238cdf0e10cSrcweir pPaintLockData = new ScPaintLockData(0); //! Modus...
239cdf0e10cSrcweir pPaintLockData->IncLevel(bDoc);
240cdf0e10cSrcweir }
241cdf0e10cSrcweir
UnlockPaint_Impl(sal_Bool bDoc)242cdf0e10cSrcweir void ScDocShell::UnlockPaint_Impl(sal_Bool bDoc)
243cdf0e10cSrcweir {
244cdf0e10cSrcweir if ( pPaintLockData )
245cdf0e10cSrcweir {
246cdf0e10cSrcweir if ( pPaintLockData->GetLevel(bDoc) )
247cdf0e10cSrcweir pPaintLockData->DecLevel(bDoc);
248cdf0e10cSrcweir if (!pPaintLockData->GetLevel(!bDoc) && !pPaintLockData->GetLevel(bDoc))
249cdf0e10cSrcweir {
250cdf0e10cSrcweir // Paint jetzt ausfuehren
251cdf0e10cSrcweir
252cdf0e10cSrcweir ScPaintLockData* pPaint = pPaintLockData;
253cdf0e10cSrcweir pPaintLockData = NULL; // nicht weitersammeln
254cdf0e10cSrcweir
255cdf0e10cSrcweir ScRangeListRef xRangeList = pPaint->GetRangeList();
256cdf0e10cSrcweir if (xRangeList)
257cdf0e10cSrcweir {
258cdf0e10cSrcweir sal_uInt16 nParts = pPaint->GetParts();
259cdf0e10cSrcweir sal_uLong nCount = xRangeList->Count();
260cdf0e10cSrcweir for ( sal_uLong i=0; i<nCount; i++ )
261cdf0e10cSrcweir {
262cdf0e10cSrcweir //! nExtFlags ???
263cdf0e10cSrcweir ScRange aRange = *xRangeList->GetObject(i);
264cdf0e10cSrcweir PostPaint( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab(),
265cdf0e10cSrcweir aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab(),
266cdf0e10cSrcweir nParts );
267cdf0e10cSrcweir }
268cdf0e10cSrcweir }
269cdf0e10cSrcweir
270cdf0e10cSrcweir if ( pPaint->GetModified() )
271cdf0e10cSrcweir SetDocumentModified();
272cdf0e10cSrcweir
273cdf0e10cSrcweir delete pPaint;
274cdf0e10cSrcweir }
275cdf0e10cSrcweir }
276cdf0e10cSrcweir else
277cdf0e10cSrcweir {
278cdf0e10cSrcweir DBG_ERROR("UnlockPaint ohne LockPaint");
279cdf0e10cSrcweir }
280cdf0e10cSrcweir }
281cdf0e10cSrcweir
LockDocument_Impl(sal_uInt16 nNew)282cdf0e10cSrcweir void ScDocShell::LockDocument_Impl(sal_uInt16 nNew)
283cdf0e10cSrcweir {
284cdf0e10cSrcweir if (!nDocumentLock)
285cdf0e10cSrcweir {
286cdf0e10cSrcweir ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
287cdf0e10cSrcweir if (pDrawLayer)
288cdf0e10cSrcweir pDrawLayer->setLock(sal_True);
289cdf0e10cSrcweir }
290cdf0e10cSrcweir nDocumentLock = nNew;
291cdf0e10cSrcweir }
292cdf0e10cSrcweir
UnlockDocument_Impl(sal_uInt16 nNew)293cdf0e10cSrcweir void ScDocShell::UnlockDocument_Impl(sal_uInt16 nNew)
294cdf0e10cSrcweir {
295cdf0e10cSrcweir nDocumentLock = nNew;
296cdf0e10cSrcweir if (!nDocumentLock)
297cdf0e10cSrcweir {
298cdf0e10cSrcweir ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
299cdf0e10cSrcweir if (pDrawLayer)
300cdf0e10cSrcweir pDrawLayer->setLock(sal_False);
301cdf0e10cSrcweir }
302cdf0e10cSrcweir }
303cdf0e10cSrcweir
GetLockCount() const304cdf0e10cSrcweir sal_uInt16 ScDocShell::GetLockCount() const
305cdf0e10cSrcweir {
306cdf0e10cSrcweir return nDocumentLock;
307cdf0e10cSrcweir }
308cdf0e10cSrcweir
SetLockCount(sal_uInt16 nNew)309cdf0e10cSrcweir void ScDocShell::SetLockCount(sal_uInt16 nNew)
310cdf0e10cSrcweir {
311cdf0e10cSrcweir if (nNew) // setzen
312cdf0e10cSrcweir {
313cdf0e10cSrcweir if ( !pPaintLockData )
314cdf0e10cSrcweir pPaintLockData = new ScPaintLockData(0); //! Modus...
315cdf0e10cSrcweir pPaintLockData->SetLevel(nNew-1, sal_True);
316cdf0e10cSrcweir LockDocument_Impl(nNew);
317cdf0e10cSrcweir }
318cdf0e10cSrcweir else if (pPaintLockData) // loeschen
319cdf0e10cSrcweir {
320cdf0e10cSrcweir pPaintLockData->SetLevel(0, sal_True); // bei Unlock sofort ausfuehren
321cdf0e10cSrcweir UnlockPaint_Impl(sal_True); // jetzt
322cdf0e10cSrcweir UnlockDocument_Impl(0);
323cdf0e10cSrcweir }
324cdf0e10cSrcweir }
325cdf0e10cSrcweir
LockPaint()326cdf0e10cSrcweir void ScDocShell::LockPaint()
327cdf0e10cSrcweir {
328cdf0e10cSrcweir LockPaint_Impl(sal_False);
329cdf0e10cSrcweir }
330cdf0e10cSrcweir
UnlockPaint()331cdf0e10cSrcweir void ScDocShell::UnlockPaint()
332cdf0e10cSrcweir {
333cdf0e10cSrcweir UnlockPaint_Impl(sal_False);
334cdf0e10cSrcweir }
335cdf0e10cSrcweir
LockDocument()336cdf0e10cSrcweir void ScDocShell::LockDocument()
337cdf0e10cSrcweir {
338cdf0e10cSrcweir LockPaint_Impl(sal_True);
339cdf0e10cSrcweir LockDocument_Impl(nDocumentLock + 1);
340cdf0e10cSrcweir }
341cdf0e10cSrcweir
UnlockDocument()342cdf0e10cSrcweir void ScDocShell::UnlockDocument()
343cdf0e10cSrcweir {
344cdf0e10cSrcweir if (nDocumentLock)
345cdf0e10cSrcweir {
346cdf0e10cSrcweir UnlockPaint_Impl(sal_True);
347cdf0e10cSrcweir UnlockDocument_Impl(nDocumentLock - 1);
348cdf0e10cSrcweir }
349cdf0e10cSrcweir else
350cdf0e10cSrcweir {
351cdf0e10cSrcweir DBG_ERROR("UnlockDocument without LockDocument");
352cdf0e10cSrcweir }
353cdf0e10cSrcweir }
354cdf0e10cSrcweir
355cdf0e10cSrcweir //------------------------------------------------------------------
356cdf0e10cSrcweir
SetInplace(sal_Bool bInplace)357cdf0e10cSrcweir void ScDocShell::SetInplace( sal_Bool bInplace )
358cdf0e10cSrcweir {
359cdf0e10cSrcweir if (bIsInplace != bInplace)
360cdf0e10cSrcweir {
361cdf0e10cSrcweir bIsInplace = bInplace;
362cdf0e10cSrcweir CalcOutputFactor();
363cdf0e10cSrcweir }
364cdf0e10cSrcweir }
365cdf0e10cSrcweir
CalcOutputFactor()366cdf0e10cSrcweir void ScDocShell::CalcOutputFactor()
367cdf0e10cSrcweir {
368cdf0e10cSrcweir if (bIsInplace)
369cdf0e10cSrcweir {
370cdf0e10cSrcweir nPrtToScreenFactor = 1.0; // passt sonst nicht zur inaktiven Darstellung
371cdf0e10cSrcweir return;
372cdf0e10cSrcweir }
373cdf0e10cSrcweir
374cdf0e10cSrcweir sal_Bool bTextWysiwyg = SC_MOD()->GetInputOptions().GetTextWysiwyg();
375cdf0e10cSrcweir if (bTextWysiwyg)
376cdf0e10cSrcweir {
377cdf0e10cSrcweir nPrtToScreenFactor = 1.0;
378cdf0e10cSrcweir return;
379cdf0e10cSrcweir }
380cdf0e10cSrcweir
381cdf0e10cSrcweir String aTestString = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(
382cdf0e10cSrcweir "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789" ));
383cdf0e10cSrcweir long nPrinterWidth = 0;
384cdf0e10cSrcweir long nWindowWidth = 0;
385cdf0e10cSrcweir const ScPatternAttr* pPattern = (const ScPatternAttr*)&aDocument.GetPool()->
386cdf0e10cSrcweir GetDefaultItem(ATTR_PATTERN);
387cdf0e10cSrcweir
388cdf0e10cSrcweir Font aDefFont;
389cdf0e10cSrcweir OutputDevice* pRefDev = GetRefDevice();
390cdf0e10cSrcweir MapMode aOldMode = pRefDev->GetMapMode();
391cdf0e10cSrcweir Font aOldFont = pRefDev->GetFont();
392cdf0e10cSrcweir
393cdf0e10cSrcweir pRefDev->SetMapMode(MAP_PIXEL);
394cdf0e10cSrcweir pPattern->GetFont(aDefFont, SC_AUTOCOL_BLACK, pRefDev); // font color doesn't matter here
395cdf0e10cSrcweir pRefDev->SetFont(aDefFont);
396cdf0e10cSrcweir nPrinterWidth = pRefDev->PixelToLogic( Size( pRefDev->GetTextWidth(aTestString), 0 ), MAP_100TH_MM ).Width();
397cdf0e10cSrcweir pRefDev->SetFont(aOldFont);
398cdf0e10cSrcweir pRefDev->SetMapMode(aOldMode);
399cdf0e10cSrcweir
400cdf0e10cSrcweir VirtualDevice aVirtWindow( *Application::GetDefaultDevice() );
401cdf0e10cSrcweir aVirtWindow.SetMapMode(MAP_PIXEL);
402cdf0e10cSrcweir pPattern->GetFont(aDefFont, SC_AUTOCOL_BLACK, &aVirtWindow); // font color doesn't matter here
403cdf0e10cSrcweir aVirtWindow.SetFont(aDefFont);
404cdf0e10cSrcweir nWindowWidth = aVirtWindow.GetTextWidth(aTestString);
405cdf0e10cSrcweir nWindowWidth = (long) ( nWindowWidth / ScGlobal::nScreenPPTX * HMM_PER_TWIPS );
406cdf0e10cSrcweir
407cdf0e10cSrcweir if (nPrinterWidth && nWindowWidth)
408cdf0e10cSrcweir nPrtToScreenFactor = nPrinterWidth / (double) nWindowWidth;
409cdf0e10cSrcweir else
410cdf0e10cSrcweir {
411cdf0e10cSrcweir DBG_ERROR("GetTextSize gibt 0 ??");
412cdf0e10cSrcweir nPrtToScreenFactor = 1.0;
413cdf0e10cSrcweir }
414cdf0e10cSrcweir }
415cdf0e10cSrcweir
GetOutputFactor() const416cdf0e10cSrcweir double ScDocShell::GetOutputFactor() const
417cdf0e10cSrcweir {
418cdf0e10cSrcweir return nPrtToScreenFactor;
419cdf0e10cSrcweir }
420cdf0e10cSrcweir
421cdf0e10cSrcweir //---------------------------------------------------------------------
422cdf0e10cSrcweir
InitOptions(bool bForLoading)423cdf0e10cSrcweir void ScDocShell::InitOptions(bool bForLoading) // called from InitNew and Load
424cdf0e10cSrcweir {
425cdf0e10cSrcweir // Einstellungen aus dem SpellCheckCfg kommen in Doc- und ViewOptions
426cdf0e10cSrcweir
427cdf0e10cSrcweir sal_uInt16 nDefLang, nCjkLang, nCtlLang;
428cdf0e10cSrcweir sal_Bool bAutoSpell;
429cdf0e10cSrcweir ScModule::GetSpellSettings( nDefLang, nCjkLang, nCtlLang, bAutoSpell );
430cdf0e10cSrcweir ScModule* pScMod = SC_MOD();
431cdf0e10cSrcweir
432cdf0e10cSrcweir ScDocOptions aDocOpt = pScMod->GetDocOptions();
433cdf0e10cSrcweir ScViewOptions aViewOpt = pScMod->GetViewOptions();
434cdf0e10cSrcweir aDocOpt.SetAutoSpell( bAutoSpell );
435cdf0e10cSrcweir
436cdf0e10cSrcweir // zweistellige Jahreszahleneingabe aus Extras->Optionen->Allgemein->Sonstiges
437cdf0e10cSrcweir aDocOpt.SetYear2000( sal::static_int_cast<sal_uInt16>( ::utl::MiscCfg().GetYear2000() ) );
438cdf0e10cSrcweir
439cdf0e10cSrcweir if (bForLoading)
440cdf0e10cSrcweir {
441cdf0e10cSrcweir // #i112123# No style:decimal-places attribute means automatic decimals, not the configured default,
442cdf0e10cSrcweir // so it must not be taken from the global options.
443cdf0e10cSrcweir // Calculation settings are handled separately in ScXMLBodyContext::EndElement.
444cdf0e10cSrcweir aDocOpt.SetStdPrecision( SvNumberFormatter::UNLIMITED_PRECISION );
445cdf0e10cSrcweir }
446cdf0e10cSrcweir
447cdf0e10cSrcweir aDocument.SetDocOptions( aDocOpt );
448cdf0e10cSrcweir aDocument.SetViewOptions( aViewOpt );
449cdf0e10cSrcweir
450cdf0e10cSrcweir // Druck-Optionen werden jetzt direkt vor dem Drucken gesetzt
451cdf0e10cSrcweir
452cdf0e10cSrcweir aDocument.SetLanguage( (LanguageType) nDefLang, (LanguageType) nCjkLang, (LanguageType) nCtlLang );
453cdf0e10cSrcweir }
454cdf0e10cSrcweir
455cdf0e10cSrcweir //---------------------------------------------------------------------
456cdf0e10cSrcweir
GetDocumentPrinter()457cdf0e10cSrcweir Printer* ScDocShell::GetDocumentPrinter() // fuer OLE
458cdf0e10cSrcweir {
459cdf0e10cSrcweir return aDocument.GetPrinter();
460cdf0e10cSrcweir }
461cdf0e10cSrcweir
GetPrinter(sal_Bool bCreateIfNotExist)462cdf0e10cSrcweir SfxPrinter* ScDocShell::GetPrinter(sal_Bool bCreateIfNotExist)
463cdf0e10cSrcweir {
464cdf0e10cSrcweir return aDocument.GetPrinter(bCreateIfNotExist);
465cdf0e10cSrcweir }
466cdf0e10cSrcweir
UpdateFontList()467cdf0e10cSrcweir void ScDocShell::UpdateFontList()
468cdf0e10cSrcweir {
469cdf0e10cSrcweir delete pImpl->pFontList;
470cdf0e10cSrcweir // pImpl->pFontList = new FontList( GetPrinter(), Application::GetDefaultDevice() );
471cdf0e10cSrcweir pImpl->pFontList = new FontList( GetRefDevice(), NULL, sal_False ); // sal_False or sal_True???
472cdf0e10cSrcweir SvxFontListItem aFontListItem( pImpl->pFontList, SID_ATTR_CHAR_FONTLIST );
473cdf0e10cSrcweir PutItem( aFontListItem );
474cdf0e10cSrcweir
475cdf0e10cSrcweir CalcOutputFactor();
476cdf0e10cSrcweir }
477cdf0e10cSrcweir
GetRefDevice()478cdf0e10cSrcweir OutputDevice* ScDocShell::GetRefDevice()
479cdf0e10cSrcweir {
480cdf0e10cSrcweir return aDocument.GetRefDevice();
481cdf0e10cSrcweir }
482cdf0e10cSrcweir
SetPrinter(SfxPrinter * pNewPrinter,sal_uInt16 nDiffFlags)483cdf0e10cSrcweir sal_uInt16 ScDocShell::SetPrinter( SfxPrinter* pNewPrinter, sal_uInt16 nDiffFlags )
484cdf0e10cSrcweir {
485cdf0e10cSrcweir SfxPrinter *pOld = aDocument.GetPrinter( sal_False );
486cdf0e10cSrcweir if ( pOld && pOld->IsPrinting() )
487cdf0e10cSrcweir return SFX_PRINTERROR_BUSY;
488cdf0e10cSrcweir
489cdf0e10cSrcweir if (nDiffFlags & SFX_PRINTER_PRINTER)
490cdf0e10cSrcweir {
491cdf0e10cSrcweir if ( aDocument.GetPrinter() != pNewPrinter )
492cdf0e10cSrcweir {
493cdf0e10cSrcweir aDocument.SetPrinter( pNewPrinter );
494cdf0e10cSrcweir aDocument.SetPrintOptions();
495cdf0e10cSrcweir
496cdf0e10cSrcweir // MT: Use UpdateFontList: Will use Printer fonts only if needed!
497cdf0e10cSrcweir /*
498cdf0e10cSrcweir delete pImpl->pFontList;
499cdf0e10cSrcweir pImpl->pFontList = new FontList( pNewPrinter, Application::GetDefaultDevice() );
500cdf0e10cSrcweir SvxFontListItem aFontListItem( pImpl->pFontList, SID_ATTR_CHAR_FONTLIST );
501cdf0e10cSrcweir PutItem( aFontListItem );
502cdf0e10cSrcweir
503cdf0e10cSrcweir CalcOutputFactor();
504cdf0e10cSrcweir */
505cdf0e10cSrcweir if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
506cdf0e10cSrcweir UpdateFontList();
507cdf0e10cSrcweir
508cdf0e10cSrcweir ScModule* pScMod = SC_MOD();
509cdf0e10cSrcweir SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this );
510cdf0e10cSrcweir while (pFrame)
511cdf0e10cSrcweir {
512cdf0e10cSrcweir SfxViewShell* pSh = pFrame->GetViewShell();
513cdf0e10cSrcweir if (pSh && pSh->ISA(ScTabViewShell))
514cdf0e10cSrcweir {
515cdf0e10cSrcweir ScTabViewShell* pViewSh = (ScTabViewShell*)pSh;
516cdf0e10cSrcweir ScInputHandler* pInputHdl = pScMod->GetInputHdl(pViewSh);
517cdf0e10cSrcweir if (pInputHdl)
518cdf0e10cSrcweir pInputHdl->UpdateRefDevice();
519cdf0e10cSrcweir }
520cdf0e10cSrcweir pFrame = SfxViewFrame::GetNext( *pFrame, this );
521cdf0e10cSrcweir }
522cdf0e10cSrcweir }
523cdf0e10cSrcweir }
524cdf0e10cSrcweir else if (nDiffFlags & SFX_PRINTER_JOBSETUP)
525cdf0e10cSrcweir {
526cdf0e10cSrcweir SfxPrinter* pOldPrinter = aDocument.GetPrinter();
527cdf0e10cSrcweir if (pOldPrinter)
528cdf0e10cSrcweir {
529cdf0e10cSrcweir pOldPrinter->SetJobSetup( pNewPrinter->GetJobSetup() );
530cdf0e10cSrcweir
531cdf0e10cSrcweir // #i6706# Call SetPrinter with the old printer again, so the drawing layer
532cdf0e10cSrcweir // RefDevice is set (calling ReformatAllTextObjects and rebuilding charts),
533cdf0e10cSrcweir // because the JobSetup (printer device settings) may affect text layout.
534cdf0e10cSrcweir aDocument.SetPrinter( pOldPrinter );
535cdf0e10cSrcweir CalcOutputFactor(); // also with the new settings
536cdf0e10cSrcweir }
537cdf0e10cSrcweir }
538cdf0e10cSrcweir
539cdf0e10cSrcweir if (nDiffFlags & SFX_PRINTER_OPTIONS)
540cdf0e10cSrcweir {
541cdf0e10cSrcweir aDocument.SetPrintOptions(); //! aus neuem Printer ???
542cdf0e10cSrcweir }
543cdf0e10cSrcweir
544cdf0e10cSrcweir if (nDiffFlags & (SFX_PRINTER_CHG_ORIENTATION | SFX_PRINTER_CHG_SIZE))
545cdf0e10cSrcweir {
546cdf0e10cSrcweir String aStyle = aDocument.GetPageStyle( GetCurTab() );
547cdf0e10cSrcweir ScStyleSheetPool* pStPl = aDocument.GetStyleSheetPool();
548cdf0e10cSrcweir SfxStyleSheet* pStyleSheet = (SfxStyleSheet*)pStPl->Find(aStyle, SFX_STYLE_FAMILY_PAGE);
549cdf0e10cSrcweir if (pStyleSheet)
550cdf0e10cSrcweir {
551cdf0e10cSrcweir SfxItemSet& rSet = pStyleSheet->GetItemSet();
552cdf0e10cSrcweir
553cdf0e10cSrcweir if (nDiffFlags & SFX_PRINTER_CHG_ORIENTATION)
554cdf0e10cSrcweir {
555cdf0e10cSrcweir const SvxPageItem& rOldItem = (const SvxPageItem&)rSet.Get(ATTR_PAGE);
556cdf0e10cSrcweir sal_Bool bWasLand = rOldItem.IsLandscape();
557cdf0e10cSrcweir sal_Bool bNewLand = ( pNewPrinter->GetOrientation() == ORIENTATION_LANDSCAPE );
558cdf0e10cSrcweir if (bNewLand != bWasLand)
559cdf0e10cSrcweir {
560cdf0e10cSrcweir SvxPageItem aNewItem( rOldItem );
561cdf0e10cSrcweir aNewItem.SetLandscape( bNewLand );
562cdf0e10cSrcweir rSet.Put( aNewItem );
563cdf0e10cSrcweir
564cdf0e10cSrcweir // Groesse umdrehen
565cdf0e10cSrcweir Size aOldSize = ((const SvxSizeItem&)rSet.Get(ATTR_PAGE_SIZE)).GetSize();
566cdf0e10cSrcweir Size aNewSize(aOldSize.Height(),aOldSize.Width());
567cdf0e10cSrcweir SvxSizeItem aNewSItem(ATTR_PAGE_SIZE,aNewSize);
568cdf0e10cSrcweir rSet.Put( aNewSItem );
569cdf0e10cSrcweir }
570cdf0e10cSrcweir }
571cdf0e10cSrcweir if (nDiffFlags & SFX_PRINTER_CHG_SIZE)
572cdf0e10cSrcweir {
573cdf0e10cSrcweir SvxSizeItem aPaperSizeItem( ATTR_PAGE_SIZE, SvxPaperInfo::GetPaperSize(pNewPrinter) );
574cdf0e10cSrcweir rSet.Put( aPaperSizeItem );
575cdf0e10cSrcweir }
576cdf0e10cSrcweir }
577cdf0e10cSrcweir }
578cdf0e10cSrcweir
579cdf0e10cSrcweir PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB,PAINT_ALL);
580cdf0e10cSrcweir
581cdf0e10cSrcweir return 0;
582cdf0e10cSrcweir }
583cdf0e10cSrcweir
584cdf0e10cSrcweir //---------------------------------------------------------------------
585cdf0e10cSrcweir
GetChangeAction(const ScAddress & rPos)586cdf0e10cSrcweir ScChangeAction* ScDocShell::GetChangeAction( const ScAddress& rPos )
587cdf0e10cSrcweir {
588cdf0e10cSrcweir ScChangeTrack* pTrack = GetDocument()->GetChangeTrack();
589cdf0e10cSrcweir if (!pTrack)
590cdf0e10cSrcweir return NULL;
591cdf0e10cSrcweir
592cdf0e10cSrcweir SCTAB nTab = rPos.Tab();
593cdf0e10cSrcweir
594cdf0e10cSrcweir const ScChangeAction* pFound = NULL;
595cdf0e10cSrcweir const ScChangeAction* pFoundContent = NULL;
596cdf0e10cSrcweir const ScChangeAction* pFoundMove = NULL;
597cdf0e10cSrcweir long nModified = 0;
598cdf0e10cSrcweir const ScChangeAction* pAction = pTrack->GetFirst();
599cdf0e10cSrcweir while (pAction)
600cdf0e10cSrcweir {
601cdf0e10cSrcweir ScChangeActionType eType = pAction->GetType();
602cdf0e10cSrcweir //! ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc )...
603cdf0e10cSrcweir if ( pAction->IsVisible() && eType != SC_CAT_DELETE_TABS )
604cdf0e10cSrcweir {
605cdf0e10cSrcweir const ScBigRange& rBig = pAction->GetBigRange();
606cdf0e10cSrcweir if ( rBig.aStart.Tab() == nTab )
607cdf0e10cSrcweir {
608cdf0e10cSrcweir ScRange aRange = rBig.MakeRange();
609cdf0e10cSrcweir
610cdf0e10cSrcweir if ( eType == SC_CAT_DELETE_ROWS )
611cdf0e10cSrcweir aRange.aEnd.SetRow( aRange.aStart.Row() );
612cdf0e10cSrcweir else if ( eType == SC_CAT_DELETE_COLS )
613cdf0e10cSrcweir aRange.aEnd.SetCol( aRange.aStart.Col() );
614cdf0e10cSrcweir
615cdf0e10cSrcweir if ( aRange.In( rPos ) )
616cdf0e10cSrcweir {
617cdf0e10cSrcweir pFound = pAction; // der letzte gewinnt
618cdf0e10cSrcweir switch ( pAction->GetType() )
619cdf0e10cSrcweir {
620cdf0e10cSrcweir case SC_CAT_CONTENT :
621cdf0e10cSrcweir pFoundContent = pAction;
622cdf0e10cSrcweir break;
623cdf0e10cSrcweir case SC_CAT_MOVE :
624cdf0e10cSrcweir pFoundMove = pAction;
625cdf0e10cSrcweir break;
626cdf0e10cSrcweir default:
627cdf0e10cSrcweir {
628cdf0e10cSrcweir // added to avoid warnings
629cdf0e10cSrcweir }
630cdf0e10cSrcweir }
631cdf0e10cSrcweir ++nModified;
632cdf0e10cSrcweir }
633cdf0e10cSrcweir }
634cdf0e10cSrcweir if ( pAction->GetType() == SC_CAT_MOVE )
635cdf0e10cSrcweir {
636cdf0e10cSrcweir ScRange aRange =
637cdf0e10cSrcweir ((const ScChangeActionMove*)pAction)->
638cdf0e10cSrcweir GetFromRange().MakeRange();
639cdf0e10cSrcweir if ( aRange.In( rPos ) )
640cdf0e10cSrcweir {
641cdf0e10cSrcweir pFound = pAction;
642cdf0e10cSrcweir ++nModified;
643cdf0e10cSrcweir }
644cdf0e10cSrcweir }
645cdf0e10cSrcweir }
646cdf0e10cSrcweir pAction = pAction->GetNext();
647cdf0e10cSrcweir }
648cdf0e10cSrcweir
649cdf0e10cSrcweir return (ScChangeAction*)pFound;
650cdf0e10cSrcweir }
651cdf0e10cSrcweir
SetChangeComment(ScChangeAction * pAction,const String & rComment)652cdf0e10cSrcweir void ScDocShell::SetChangeComment( ScChangeAction* pAction, const String& rComment )
653cdf0e10cSrcweir {
654cdf0e10cSrcweir if (pAction)
655cdf0e10cSrcweir {
656cdf0e10cSrcweir pAction->SetComment( rComment );
657cdf0e10cSrcweir //! Undo ???
658cdf0e10cSrcweir SetDocumentModified();
659cdf0e10cSrcweir
660cdf0e10cSrcweir // Dialog-Notify
661cdf0e10cSrcweir ScChangeTrack* pTrack = GetDocument()->GetChangeTrack();
662cdf0e10cSrcweir if (pTrack)
663cdf0e10cSrcweir {
664cdf0e10cSrcweir sal_uLong nNumber = pAction->GetActionNumber();
665cdf0e10cSrcweir pTrack->NotifyModified( SC_CTM_CHANGE, nNumber, nNumber );
666cdf0e10cSrcweir }
667cdf0e10cSrcweir }
668cdf0e10cSrcweir }
669cdf0e10cSrcweir
ExecuteChangeCommentDialog(ScChangeAction * pAction,Window * pParent,sal_Bool bPrevNext)670cdf0e10cSrcweir void ScDocShell::ExecuteChangeCommentDialog( ScChangeAction* pAction, Window* pParent,sal_Bool bPrevNext)
671cdf0e10cSrcweir {
672cdf0e10cSrcweir if (!pAction) return; // ohne Aktion ist nichts..
673cdf0e10cSrcweir
674cdf0e10cSrcweir String aComment = pAction->GetComment();
675cdf0e10cSrcweir String aAuthor = pAction->GetUser();
676cdf0e10cSrcweir
677cdf0e10cSrcweir DateTime aDT = pAction->GetDateTime();
678cdf0e10cSrcweir String aDate = ScGlobal::pLocaleData->getDate( aDT );
679cdf0e10cSrcweir aDate += ' ';
680cdf0e10cSrcweir aDate += ScGlobal::pLocaleData->getTime( aDT, sal_False, sal_False );
681cdf0e10cSrcweir
682cdf0e10cSrcweir SfxItemSet aSet( GetPool(),
683cdf0e10cSrcweir SID_ATTR_POSTIT_AUTHOR, SID_ATTR_POSTIT_AUTHOR,
684cdf0e10cSrcweir SID_ATTR_POSTIT_DATE, SID_ATTR_POSTIT_DATE,
685cdf0e10cSrcweir SID_ATTR_POSTIT_TEXT, SID_ATTR_POSTIT_TEXT,
686cdf0e10cSrcweir 0 );
687cdf0e10cSrcweir
688cdf0e10cSrcweir aSet.Put( SvxPostItTextItem ( aComment, SID_ATTR_POSTIT_TEXT ) );
689cdf0e10cSrcweir aSet.Put( SvxPostItAuthorItem( aAuthor, SID_ATTR_POSTIT_AUTHOR ) );
690cdf0e10cSrcweir aSet.Put( SvxPostItDateItem ( aDate, SID_ATTR_POSTIT_DATE ) );
691cdf0e10cSrcweir
692cdf0e10cSrcweir ScRedComDialog* pDlg = new ScRedComDialog( pParent, aSet,this,pAction,bPrevNext);
693cdf0e10cSrcweir
694cdf0e10cSrcweir pDlg->Execute();
695cdf0e10cSrcweir
696cdf0e10cSrcweir delete pDlg;
697cdf0e10cSrcweir }
698cdf0e10cSrcweir
699cdf0e10cSrcweir //---------------------------------------------------------------------
700cdf0e10cSrcweir
CompareDocument(ScDocument & rOtherDoc)701cdf0e10cSrcweir void ScDocShell::CompareDocument( ScDocument& rOtherDoc )
702cdf0e10cSrcweir {
703cdf0e10cSrcweir ScChangeTrack* pTrack = aDocument.GetChangeTrack();
704cdf0e10cSrcweir if ( pTrack && pTrack->GetFirst() )
705cdf0e10cSrcweir {
706cdf0e10cSrcweir //! Changes vorhanden -> Nachfrage ob geloescht werden soll
707cdf0e10cSrcweir }
708cdf0e10cSrcweir
709cdf0e10cSrcweir aDocument.EndChangeTracking();
710cdf0e10cSrcweir aDocument.StartChangeTracking();
711cdf0e10cSrcweir
712cdf0e10cSrcweir String aOldUser;
713cdf0e10cSrcweir pTrack = aDocument.GetChangeTrack();
714cdf0e10cSrcweir if ( pTrack )
715cdf0e10cSrcweir {
716cdf0e10cSrcweir aOldUser = pTrack->GetUser();
717cdf0e10cSrcweir
718cdf0e10cSrcweir // check if comparing to same document
719cdf0e10cSrcweir
720cdf0e10cSrcweir String aThisFile;
721cdf0e10cSrcweir const SfxMedium* pThisMed = GetMedium();
722cdf0e10cSrcweir if (pThisMed)
723cdf0e10cSrcweir aThisFile = pThisMed->GetName();
724cdf0e10cSrcweir String aOtherFile;
725cdf0e10cSrcweir SfxObjectShell* pOtherSh = rOtherDoc.GetDocumentShell();
726cdf0e10cSrcweir if (pOtherSh)
727cdf0e10cSrcweir {
728cdf0e10cSrcweir const SfxMedium* pOtherMed = pOtherSh->GetMedium();
729cdf0e10cSrcweir if (pOtherMed)
730cdf0e10cSrcweir aOtherFile = pOtherMed->GetName();
731cdf0e10cSrcweir }
732cdf0e10cSrcweir sal_Bool bSameDoc = ( aThisFile == aOtherFile && aThisFile.Len() );
733cdf0e10cSrcweir if ( !bSameDoc )
734cdf0e10cSrcweir {
735cdf0e10cSrcweir // create change actions from comparing with the name of the user
736cdf0e10cSrcweir // who last saved the document
737cdf0e10cSrcweir // (only if comparing different documents)
738cdf0e10cSrcweir
739cdf0e10cSrcweir using namespace ::com::sun::star;
740cdf0e10cSrcweir uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
741cdf0e10cSrcweir GetModel(), uno::UNO_QUERY_THROW);
742cdf0e10cSrcweir uno::Reference<document::XDocumentProperties> xDocProps(
743cdf0e10cSrcweir xDPS->getDocumentProperties());
744cdf0e10cSrcweir DBG_ASSERT(xDocProps.is(), "no DocumentProperties");
745cdf0e10cSrcweir String aDocUser = xDocProps->getModifiedBy();
746cdf0e10cSrcweir
747cdf0e10cSrcweir if ( aDocUser.Len() )
748cdf0e10cSrcweir pTrack->SetUser( aDocUser );
749cdf0e10cSrcweir }
750cdf0e10cSrcweir }
751cdf0e10cSrcweir
752cdf0e10cSrcweir aDocument.CompareDocument( rOtherDoc );
753cdf0e10cSrcweir
754cdf0e10cSrcweir pTrack = aDocument.GetChangeTrack();
755cdf0e10cSrcweir if ( pTrack )
756cdf0e10cSrcweir pTrack->SetUser( aOldUser );
757cdf0e10cSrcweir
758cdf0e10cSrcweir PostPaintGridAll();
759cdf0e10cSrcweir SetDocumentModified();
760cdf0e10cSrcweir }
761cdf0e10cSrcweir
762cdf0e10cSrcweir //---------------------------------------------------------------------
763cdf0e10cSrcweir //
764cdf0e10cSrcweir // Merge (Aenderungen zusammenfuehren)
765cdf0e10cSrcweir //
766cdf0e10cSrcweir //---------------------------------------------------------------------
767cdf0e10cSrcweir
lcl_Equal(const ScChangeAction * pA,const ScChangeAction * pB,sal_Bool bIgnore100Sec)768cdf0e10cSrcweir inline sal_Bool lcl_Equal( const ScChangeAction* pA, const ScChangeAction* pB, sal_Bool bIgnore100Sec )
769cdf0e10cSrcweir {
770cdf0e10cSrcweir return pA && pB &&
771cdf0e10cSrcweir pA->GetActionNumber() == pB->GetActionNumber() &&
772cdf0e10cSrcweir pA->GetType() == pB->GetType() &&
773cdf0e10cSrcweir pA->GetUser() == pB->GetUser() &&
774cdf0e10cSrcweir (bIgnore100Sec ?
775cdf0e10cSrcweir pA->GetDateTimeUTC().IsEqualIgnore100Sec( pB->GetDateTimeUTC() ) :
776cdf0e10cSrcweir pA->GetDateTimeUTC() == pB->GetDateTimeUTC());
777cdf0e10cSrcweir // State nicht vergleichen, falls eine alte Aenderung akzeptiert wurde
778cdf0e10cSrcweir }
779cdf0e10cSrcweir
lcl_FindAction(ScDocument * pDoc,const ScChangeAction * pAction,ScDocument * pSearchDoc,const ScChangeAction * pFirstSearchAction,const ScChangeAction * pLastSearchAction,sal_Bool bIgnore100Sec)780cdf0e10cSrcweir bool lcl_FindAction( ScDocument* pDoc, const ScChangeAction* pAction, ScDocument* pSearchDoc, const ScChangeAction* pFirstSearchAction, const ScChangeAction* pLastSearchAction, sal_Bool bIgnore100Sec )
781cdf0e10cSrcweir {
782cdf0e10cSrcweir if ( !pDoc || !pAction || !pSearchDoc || !pFirstSearchAction || !pLastSearchAction )
783cdf0e10cSrcweir {
784cdf0e10cSrcweir return false;
785cdf0e10cSrcweir }
786cdf0e10cSrcweir
787cdf0e10cSrcweir sal_uLong nLastSearchAction = pLastSearchAction->GetActionNumber();
788cdf0e10cSrcweir const ScChangeAction* pA = pFirstSearchAction;
789cdf0e10cSrcweir while ( pA && pA->GetActionNumber() <= nLastSearchAction )
790cdf0e10cSrcweir {
791cdf0e10cSrcweir if ( pAction->GetType() == pA->GetType() &&
792cdf0e10cSrcweir pAction->GetUser() == pA->GetUser() &&
793cdf0e10cSrcweir (bIgnore100Sec ?
794cdf0e10cSrcweir pAction->GetDateTimeUTC().IsEqualIgnore100Sec( pA->GetDateTimeUTC() ) :
795cdf0e10cSrcweir pAction->GetDateTimeUTC() == pA->GetDateTimeUTC() ) &&
796cdf0e10cSrcweir pAction->GetBigRange() == pA->GetBigRange() )
797cdf0e10cSrcweir {
798cdf0e10cSrcweir String aActionDesc;
799cdf0e10cSrcweir pAction->GetDescription( aActionDesc, pDoc, sal_True );
800cdf0e10cSrcweir String aADesc;
801cdf0e10cSrcweir pA->GetDescription( aADesc, pSearchDoc, sal_True );
802cdf0e10cSrcweir if ( aActionDesc.Equals( aADesc ) )
803cdf0e10cSrcweir {
804cdf0e10cSrcweir DBG_ERROR( "lcl_FindAction(): found equal action!" );
805cdf0e10cSrcweir return true;
806cdf0e10cSrcweir }
807cdf0e10cSrcweir }
808cdf0e10cSrcweir pA = pA->GetNext();
809cdf0e10cSrcweir }
810cdf0e10cSrcweir
811cdf0e10cSrcweir return false;
812cdf0e10cSrcweir }
813cdf0e10cSrcweir
MergeDocument(ScDocument & rOtherDoc,bool bShared,bool bCheckDuplicates,sal_uLong nOffset,ScChangeActionMergeMap * pMergeMap,bool bInverseMap)814cdf0e10cSrcweir void ScDocShell::MergeDocument( ScDocument& rOtherDoc, bool bShared, bool bCheckDuplicates, sal_uLong nOffset, ScChangeActionMergeMap* pMergeMap, bool bInverseMap )
815cdf0e10cSrcweir {
816cdf0e10cSrcweir ScTabViewShell* pViewSh = GetBestViewShell( sal_False ); //! Funktionen an die DocShell
817cdf0e10cSrcweir if (!pViewSh)
818cdf0e10cSrcweir return;
819cdf0e10cSrcweir
820cdf0e10cSrcweir ScChangeTrack* pSourceTrack = rOtherDoc.GetChangeTrack();
821cdf0e10cSrcweir if (!pSourceTrack)
822cdf0e10cSrcweir return; //! nichts zu tun - Fehlermeldung?
823cdf0e10cSrcweir
824cdf0e10cSrcweir ScChangeTrack* pThisTrack = aDocument.GetChangeTrack();
825cdf0e10cSrcweir if ( !pThisTrack )
826cdf0e10cSrcweir { // anschalten
827cdf0e10cSrcweir aDocument.StartChangeTracking();
828cdf0e10cSrcweir pThisTrack = aDocument.GetChangeTrack();
829cdf0e10cSrcweir DBG_ASSERT(pThisTrack,"ChangeTracking nicht angeschaltet?");
830cdf0e10cSrcweir if ( !bShared )
831cdf0e10cSrcweir {
832cdf0e10cSrcweir // #51138# visuelles RedLining einschalten
833cdf0e10cSrcweir ScChangeViewSettings aChangeViewSet;
834cdf0e10cSrcweir aChangeViewSet.SetShowChanges(sal_True);
835cdf0e10cSrcweir aDocument.SetChangeViewSettings(aChangeViewSet);
836cdf0e10cSrcweir }
837cdf0e10cSrcweir }
838cdf0e10cSrcweir
839cdf0e10cSrcweir // #97286# include 100th seconds in compare?
840cdf0e10cSrcweir sal_Bool bIgnore100Sec = !pSourceTrack->IsTime100thSeconds() ||
841cdf0e10cSrcweir !pThisTrack->IsTime100thSeconds();
842cdf0e10cSrcweir
843cdf0e10cSrcweir // gemeinsame Ausgangsposition suchen
844cdf0e10cSrcweir sal_uLong nFirstNewNumber = 0;
845cdf0e10cSrcweir const ScChangeAction* pSourceAction = pSourceTrack->GetFirst();
846cdf0e10cSrcweir const ScChangeAction* pThisAction = pThisTrack->GetFirst();
847cdf0e10cSrcweir // skip identical actions
848cdf0e10cSrcweir while ( lcl_Equal( pSourceAction, pThisAction, bIgnore100Sec ) )
849cdf0e10cSrcweir {
850cdf0e10cSrcweir nFirstNewNumber = pSourceAction->GetActionNumber() + 1;
851cdf0e10cSrcweir pSourceAction = pSourceAction->GetNext();
852cdf0e10cSrcweir pThisAction = pThisAction->GetNext();
853cdf0e10cSrcweir }
854cdf0e10cSrcweir // pSourceAction und pThisAction zeigen jetzt auf die ersten "eigenen" Aktionen
855cdf0e10cSrcweir // Die gemeinsamen Aktionen davor interessieren ueberhaupt nicht
856cdf0e10cSrcweir
857cdf0e10cSrcweir //! Abfrage, ob die Dokumente vor dem Change-Tracking gleich waren !!!
858cdf0e10cSrcweir
859cdf0e10cSrcweir
860cdf0e10cSrcweir const ScChangeAction* pFirstMergeAction = pSourceAction;
861cdf0e10cSrcweir const ScChangeAction* pFirstSearchAction = pThisAction;
862cdf0e10cSrcweir
863cdf0e10cSrcweir // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
864cdf0e10cSrcweir const ScChangeAction* pLastSearchAction = pThisTrack->GetLast();
865cdf0e10cSrcweir
866cdf0e10cSrcweir // MergeChangeData aus den folgenden Aktionen erzeugen
867cdf0e10cSrcweir sal_uLong nNewActionCount = 0;
868cdf0e10cSrcweir const ScChangeAction* pCount = pSourceAction;
869cdf0e10cSrcweir while ( pCount )
870cdf0e10cSrcweir {
871cdf0e10cSrcweir if ( bShared || !ScChangeTrack::MergeIgnore( *pCount, nFirstNewNumber ) )
872cdf0e10cSrcweir ++nNewActionCount;
873cdf0e10cSrcweir pCount = pCount->GetNext();
874cdf0e10cSrcweir }
875cdf0e10cSrcweir if (!nNewActionCount)
876cdf0e10cSrcweir return; //! nichts zu tun - Fehlermeldung?
877cdf0e10cSrcweir // ab hier kein return mehr
878cdf0e10cSrcweir
879cdf0e10cSrcweir ScProgress aProgress( this,
880cdf0e10cSrcweir String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("...")),
881cdf0e10cSrcweir nNewActionCount );
882cdf0e10cSrcweir
883cdf0e10cSrcweir sal_uLong nLastMergeAction = pSourceTrack->GetLast()->GetActionNumber();
884cdf0e10cSrcweir // UpdateReference-Undo, gueltige Referenzen fuer den letzten gemeinsamen Zustand
885cdf0e10cSrcweir pSourceTrack->MergePrepare( (ScChangeAction*) pFirstMergeAction, bShared );
886cdf0e10cSrcweir
887cdf0e10cSrcweir // MergeChangeData an alle noch folgenden Aktionen in diesem Dokument anpassen
888cdf0e10cSrcweir // -> Referenzen gueltig fuer dieses Dokument
889cdf0e10cSrcweir while ( pThisAction )
890cdf0e10cSrcweir {
891cdf0e10cSrcweir // #i87049# [Collaboration] Conflict between delete row and insert content is not merged correctly
892cdf0e10cSrcweir if ( !bShared || !ScChangeTrack::MergeIgnore( *pThisAction, nFirstNewNumber ) )
893cdf0e10cSrcweir {
894cdf0e10cSrcweir ScChangeActionType eType = pThisAction->GetType();
895cdf0e10cSrcweir switch ( eType )
896cdf0e10cSrcweir {
897cdf0e10cSrcweir case SC_CAT_INSERT_COLS :
898cdf0e10cSrcweir case SC_CAT_INSERT_ROWS :
899cdf0e10cSrcweir case SC_CAT_INSERT_TABS :
900cdf0e10cSrcweir pSourceTrack->AppendInsert( pThisAction->GetBigRange().MakeRange() );
901cdf0e10cSrcweir break;
902cdf0e10cSrcweir case SC_CAT_DELETE_COLS :
903cdf0e10cSrcweir case SC_CAT_DELETE_ROWS :
904cdf0e10cSrcweir case SC_CAT_DELETE_TABS :
905cdf0e10cSrcweir {
906cdf0e10cSrcweir const ScChangeActionDel* pDel = (const ScChangeActionDel*) pThisAction;
907cdf0e10cSrcweir if ( pDel->IsTopDelete() && !pDel->IsTabDeleteCol() )
908cdf0e10cSrcweir { // deleted Table enthaelt deleted Cols, die nicht
909cdf0e10cSrcweir sal_uLong nStart, nEnd;
910cdf0e10cSrcweir pSourceTrack->AppendDeleteRange(
911cdf0e10cSrcweir pDel->GetOverAllRange().MakeRange(), NULL, nStart, nEnd );
912cdf0e10cSrcweir }
913cdf0e10cSrcweir }
914cdf0e10cSrcweir break;
915cdf0e10cSrcweir case SC_CAT_MOVE :
916cdf0e10cSrcweir {
917cdf0e10cSrcweir const ScChangeActionMove* pMove = (const ScChangeActionMove*) pThisAction;
918cdf0e10cSrcweir pSourceTrack->AppendMove( pMove->GetFromRange().MakeRange(),
919cdf0e10cSrcweir pMove->GetBigRange().MakeRange(), NULL );
920cdf0e10cSrcweir }
921cdf0e10cSrcweir break;
922cdf0e10cSrcweir default:
923cdf0e10cSrcweir {
924cdf0e10cSrcweir // added to avoid warnings
925cdf0e10cSrcweir }
926cdf0e10cSrcweir }
927cdf0e10cSrcweir }
928cdf0e10cSrcweir pThisAction = pThisAction->GetNext();
929cdf0e10cSrcweir }
930cdf0e10cSrcweir
931cdf0e10cSrcweir LockPaint(); // #i73877# no repainting after each action
932cdf0e10cSrcweir
933cdf0e10cSrcweir // MergeChangeData in das aktuelle Dokument uebernehmen
934cdf0e10cSrcweir sal_Bool bHasRejected = sal_False;
935cdf0e10cSrcweir String aOldUser = pThisTrack->GetUser();
936cdf0e10cSrcweir pThisTrack->SetUseFixDateTime( sal_True );
937cdf0e10cSrcweir ScMarkData& rMarkData = pViewSh->GetViewData()->GetMarkData();
938cdf0e10cSrcweir ScMarkData aOldMarkData( rMarkData );
939cdf0e10cSrcweir pSourceAction = pFirstMergeAction;
940cdf0e10cSrcweir while ( pSourceAction && pSourceAction->GetActionNumber() <= nLastMergeAction )
941cdf0e10cSrcweir {
942cdf0e10cSrcweir bool bMergeAction = false;
943cdf0e10cSrcweir if ( bShared )
944cdf0e10cSrcweir {
945cdf0e10cSrcweir if ( !bCheckDuplicates || !lcl_FindAction( &rOtherDoc, pSourceAction, &aDocument, pFirstSearchAction, pLastSearchAction, bIgnore100Sec ) )
946cdf0e10cSrcweir {
947cdf0e10cSrcweir bMergeAction = true;
948cdf0e10cSrcweir }
949cdf0e10cSrcweir }
950cdf0e10cSrcweir else
951cdf0e10cSrcweir {
952cdf0e10cSrcweir if ( !ScChangeTrack::MergeIgnore( *pSourceAction, nFirstNewNumber ) )
953cdf0e10cSrcweir {
954cdf0e10cSrcweir bMergeAction = true;
955cdf0e10cSrcweir }
956cdf0e10cSrcweir }
957cdf0e10cSrcweir
958cdf0e10cSrcweir if ( bMergeAction )
959cdf0e10cSrcweir {
960cdf0e10cSrcweir ScChangeActionType eSourceType = pSourceAction->GetType();
961cdf0e10cSrcweir if ( !bShared && pSourceAction->IsDeletedIn() )
962cdf0e10cSrcweir {
963cdf0e10cSrcweir //! muss hier noch festgestellt werden, ob wirklich in
964cdf0e10cSrcweir //! _diesem_ Dokument geloescht?
965cdf0e10cSrcweir
966cdf0e10cSrcweir // liegt in einem Bereich, der in diesem Dokument geloescht wurde
967cdf0e10cSrcweir // -> wird weggelassen
968cdf0e10cSrcweir //! ??? Loesch-Aktion rueckgaengig machen ???
969cdf0e10cSrcweir //! ??? Aktion irgendwo anders speichern ???
970cdf0e10cSrcweir #ifdef DBG_UTIL
971cdf0e10cSrcweir String aValue;
972cdf0e10cSrcweir if ( eSourceType == SC_CAT_CONTENT )
973cdf0e10cSrcweir ((const ScChangeActionContent*)pSourceAction)->GetNewString( aValue );
974cdf0e10cSrcweir ByteString aError( aValue, gsl_getSystemTextEncoding() );
975cdf0e10cSrcweir aError += " weggelassen";
976cdf0e10cSrcweir DBG_ERROR( aError.GetBuffer() );
977cdf0e10cSrcweir #endif
978cdf0e10cSrcweir }
979cdf0e10cSrcweir else
980cdf0e10cSrcweir {
981cdf0e10cSrcweir //! Datum/Autor/Kommentar der Source-Aktion uebernehmen!
982cdf0e10cSrcweir
983cdf0e10cSrcweir pThisTrack->SetUser( pSourceAction->GetUser() );
984cdf0e10cSrcweir pThisTrack->SetFixDateTimeUTC( pSourceAction->GetDateTimeUTC() );
985cdf0e10cSrcweir sal_uLong nOldActionMax = pThisTrack->GetActionMax();
986cdf0e10cSrcweir
987cdf0e10cSrcweir bool bExecute = true;
988cdf0e10cSrcweir sal_uLong nReject = pSourceAction->GetRejectAction();
989cdf0e10cSrcweir if ( nReject )
990cdf0e10cSrcweir {
991cdf0e10cSrcweir if ( bShared )
992cdf0e10cSrcweir {
993cdf0e10cSrcweir if ( nReject >= nFirstNewNumber )
994cdf0e10cSrcweir {
995cdf0e10cSrcweir nReject += nOffset;
996cdf0e10cSrcweir }
997cdf0e10cSrcweir ScChangeAction* pOldAction = pThisTrack->GetAction( nReject );
998cdf0e10cSrcweir if ( pOldAction && pOldAction->IsVirgin() )
999cdf0e10cSrcweir {
1000cdf0e10cSrcweir pThisTrack->Reject( pOldAction );
1001cdf0e10cSrcweir bHasRejected = sal_True;
1002cdf0e10cSrcweir bExecute = false;
1003cdf0e10cSrcweir }
1004cdf0e10cSrcweir }
1005cdf0e10cSrcweir else
1006cdf0e10cSrcweir {
1007cdf0e10cSrcweir // alte Aktion (aus den gemeinsamen) ablehnen
1008cdf0e10cSrcweir ScChangeAction* pOldAction = pThisTrack->GetAction( nReject );
1009cdf0e10cSrcweir if (pOldAction && pOldAction->GetState() == SC_CAS_VIRGIN)
1010cdf0e10cSrcweir {
1011cdf0e10cSrcweir //! was passiert bei Aktionen, die in diesem Dokument accepted worden sind???
1012cdf0e10cSrcweir //! Fehlermeldung oder was???
1013cdf0e10cSrcweir //! oder Reject-Aenderung normal ausfuehren
1014cdf0e10cSrcweir
1015cdf0e10cSrcweir pThisTrack->Reject(pOldAction);
1016cdf0e10cSrcweir bHasRejected = sal_True; // fuer Paint
1017cdf0e10cSrcweir }
1018cdf0e10cSrcweir bExecute = false;
1019cdf0e10cSrcweir }
1020cdf0e10cSrcweir }
1021cdf0e10cSrcweir
1022cdf0e10cSrcweir if ( bExecute )
1023cdf0e10cSrcweir {
1024cdf0e10cSrcweir // normal ausfuehren
1025cdf0e10cSrcweir ScRange aSourceRange = pSourceAction->GetBigRange().MakeRange();
1026cdf0e10cSrcweir rMarkData.SelectOneTable( aSourceRange.aStart.Tab() );
1027cdf0e10cSrcweir switch ( eSourceType )
1028cdf0e10cSrcweir {
1029cdf0e10cSrcweir case SC_CAT_CONTENT:
1030cdf0e10cSrcweir {
1031cdf0e10cSrcweir //! Test, ob es ganz unten im Dokument war, dann automatisches
1032cdf0e10cSrcweir //! Zeilen-Einfuegen ???
1033cdf0e10cSrcweir
1034cdf0e10cSrcweir DBG_ASSERT( aSourceRange.aStart == aSourceRange.aEnd, "huch?" );
1035cdf0e10cSrcweir ScAddress aPos = aSourceRange.aStart;
1036cdf0e10cSrcweir String aValue;
1037cdf0e10cSrcweir ((const ScChangeActionContent*)pSourceAction)->GetNewString( aValue );
1038cdf0e10cSrcweir sal_uInt8 eMatrix = MM_NONE;
1039cdf0e10cSrcweir const ScBaseCell* pCell = ((const ScChangeActionContent*)pSourceAction)->GetNewCell();
1040cdf0e10cSrcweir if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
1041cdf0e10cSrcweir eMatrix = ((const ScFormulaCell*)pCell)->GetMatrixFlag();
1042cdf0e10cSrcweir switch ( eMatrix )
1043cdf0e10cSrcweir {
1044cdf0e10cSrcweir case MM_NONE :
1045cdf0e10cSrcweir pViewSh->EnterData( aPos.Col(), aPos.Row(), aPos.Tab(), aValue );
1046cdf0e10cSrcweir break;
1047cdf0e10cSrcweir case MM_FORMULA :
1048cdf0e10cSrcweir {
1049cdf0e10cSrcweir SCCOL nCols;
1050cdf0e10cSrcweir SCROW nRows;
1051cdf0e10cSrcweir ((const ScFormulaCell*)pCell)->GetMatColsRows( nCols, nRows );
1052cdf0e10cSrcweir aSourceRange.aEnd.SetCol( aPos.Col() + nCols - 1 );
1053cdf0e10cSrcweir aSourceRange.aEnd.SetRow( aPos.Row() + nRows - 1 );
1054cdf0e10cSrcweir aValue.Erase( 0, 1 );
1055cdf0e10cSrcweir aValue.Erase( aValue.Len()-1, 1 );
1056cdf0e10cSrcweir GetDocFunc().EnterMatrix( aSourceRange,
1057cdf0e10cSrcweir NULL, NULL, aValue, sal_False, sal_False,
1058cdf0e10cSrcweir EMPTY_STRING, formula::FormulaGrammar::GRAM_DEFAULT );
1059cdf0e10cSrcweir }
1060cdf0e10cSrcweir break;
1061cdf0e10cSrcweir case MM_REFERENCE : // do nothing
1062cdf0e10cSrcweir break;
1063cdf0e10cSrcweir case MM_FAKE :
1064cdf0e10cSrcweir DBG_WARNING( "MergeDocument: MatrixFlag MM_FAKE" );
1065cdf0e10cSrcweir pViewSh->EnterData( aPos.Col(), aPos.Row(), aPos.Tab(), aValue );
1066cdf0e10cSrcweir break;
1067cdf0e10cSrcweir default:
1068cdf0e10cSrcweir DBG_ERROR( "MergeDocument: unknown MatrixFlag" );
1069cdf0e10cSrcweir }
1070cdf0e10cSrcweir }
1071cdf0e10cSrcweir break;
1072cdf0e10cSrcweir case SC_CAT_INSERT_TABS :
1073cdf0e10cSrcweir {
1074cdf0e10cSrcweir String aName;
1075cdf0e10cSrcweir aDocument.CreateValidTabName( aName );
1076cdf0e10cSrcweir GetDocFunc().InsertTable( aSourceRange.aStart.Tab(), aName, sal_True, sal_False );
1077cdf0e10cSrcweir }
1078cdf0e10cSrcweir break;
1079cdf0e10cSrcweir case SC_CAT_INSERT_ROWS:
1080cdf0e10cSrcweir GetDocFunc().InsertCells( aSourceRange, NULL, INS_INSROWS, sal_True, sal_False );
1081cdf0e10cSrcweir break;
1082cdf0e10cSrcweir case SC_CAT_INSERT_COLS:
1083cdf0e10cSrcweir GetDocFunc().InsertCells( aSourceRange, NULL, INS_INSCOLS, sal_True, sal_False );
1084cdf0e10cSrcweir break;
1085cdf0e10cSrcweir case SC_CAT_DELETE_TABS :
1086cdf0e10cSrcweir GetDocFunc().DeleteTable( aSourceRange.aStart.Tab(), sal_True, sal_False );
1087cdf0e10cSrcweir break;
1088cdf0e10cSrcweir case SC_CAT_DELETE_ROWS:
1089cdf0e10cSrcweir {
1090cdf0e10cSrcweir const ScChangeActionDel* pDel = (const ScChangeActionDel*) pSourceAction;
1091cdf0e10cSrcweir if ( pDel->IsTopDelete() )
1092cdf0e10cSrcweir {
1093cdf0e10cSrcweir aSourceRange = pDel->GetOverAllRange().MakeRange();
1094cdf0e10cSrcweir GetDocFunc().DeleteCells( aSourceRange, NULL, DEL_DELROWS, sal_True, sal_False );
1095cdf0e10cSrcweir
1096cdf0e10cSrcweir // #i101099# [Collaboration] Changes are not correctly shown
1097cdf0e10cSrcweir if ( bShared )
1098cdf0e10cSrcweir {
1099cdf0e10cSrcweir ScChangeAction* pAct = pThisTrack->GetLast();
1100cdf0e10cSrcweir if ( pAct && pAct->GetType() == eSourceType && pAct->IsDeletedIn() && !pSourceAction->IsDeletedIn() )
1101cdf0e10cSrcweir {
1102cdf0e10cSrcweir pAct->RemoveAllDeletedIn();
1103cdf0e10cSrcweir }
1104cdf0e10cSrcweir }
1105cdf0e10cSrcweir }
1106cdf0e10cSrcweir }
1107cdf0e10cSrcweir break;
1108cdf0e10cSrcweir case SC_CAT_DELETE_COLS:
1109cdf0e10cSrcweir {
1110cdf0e10cSrcweir const ScChangeActionDel* pDel = (const ScChangeActionDel*) pSourceAction;
1111cdf0e10cSrcweir if ( pDel->IsTopDelete() && !pDel->IsTabDeleteCol() )
1112cdf0e10cSrcweir { // deleted Table enthaelt deleted Cols, die nicht
1113cdf0e10cSrcweir aSourceRange = pDel->GetOverAllRange().MakeRange();
1114cdf0e10cSrcweir GetDocFunc().DeleteCells( aSourceRange, NULL, DEL_DELCOLS, sal_True, sal_False );
1115cdf0e10cSrcweir }
1116cdf0e10cSrcweir }
1117cdf0e10cSrcweir break;
1118cdf0e10cSrcweir case SC_CAT_MOVE :
1119cdf0e10cSrcweir {
1120cdf0e10cSrcweir const ScChangeActionMove* pMove = (const ScChangeActionMove*) pSourceAction;
1121cdf0e10cSrcweir ScRange aFromRange( pMove->GetFromRange().MakeRange() );
1122cdf0e10cSrcweir GetDocFunc().MoveBlock( aFromRange,
1123cdf0e10cSrcweir aSourceRange.aStart, sal_True, sal_True, sal_False, sal_False );
1124cdf0e10cSrcweir }
1125cdf0e10cSrcweir break;
1126cdf0e10cSrcweir default:
1127cdf0e10cSrcweir {
1128cdf0e10cSrcweir // added to avoid warnings
1129cdf0e10cSrcweir }
1130cdf0e10cSrcweir }
1131cdf0e10cSrcweir }
1132cdf0e10cSrcweir const String& rComment = pSourceAction->GetComment();
1133cdf0e10cSrcweir if ( rComment.Len() )
1134cdf0e10cSrcweir {
1135cdf0e10cSrcweir ScChangeAction* pAct = pThisTrack->GetLast();
1136cdf0e10cSrcweir if ( pAct && pAct->GetActionNumber() > nOldActionMax )
1137cdf0e10cSrcweir pAct->SetComment( rComment );
1138cdf0e10cSrcweir #ifdef DBG_UTIL
1139cdf0e10cSrcweir else
1140cdf0e10cSrcweir DBG_ERROR( "MergeDocument: wohin mit dem Kommentar?!?" );
1141cdf0e10cSrcweir #endif
1142cdf0e10cSrcweir }
1143cdf0e10cSrcweir
1144cdf0e10cSrcweir // Referenzen anpassen
1145cdf0e10cSrcweir pSourceTrack->MergeOwn( (ScChangeAction*) pSourceAction, nFirstNewNumber, bShared );
1146cdf0e10cSrcweir
1147cdf0e10cSrcweir // merge action state
1148cdf0e10cSrcweir if ( bShared && !pSourceAction->IsRejected() )
1149cdf0e10cSrcweir {
1150cdf0e10cSrcweir ScChangeAction* pAct = pThisTrack->GetLast();
1151cdf0e10cSrcweir if ( pAct && pAct->GetActionNumber() > nOldActionMax )
1152cdf0e10cSrcweir {
1153cdf0e10cSrcweir pThisTrack->MergeActionState( pAct, pSourceAction );
1154cdf0e10cSrcweir }
1155cdf0e10cSrcweir }
1156cdf0e10cSrcweir
1157cdf0e10cSrcweir // fill merge map
1158cdf0e10cSrcweir if ( bShared && pMergeMap )
1159cdf0e10cSrcweir {
1160cdf0e10cSrcweir ScChangeAction* pAct = pThisTrack->GetLast();
1161cdf0e10cSrcweir if ( pAct && pAct->GetActionNumber() > nOldActionMax )
1162cdf0e10cSrcweir {
1163cdf0e10cSrcweir sal_uLong nActionMax = pAct->GetActionNumber();
1164cdf0e10cSrcweir sal_uLong nActionCount = nActionMax - nOldActionMax;
1165cdf0e10cSrcweir sal_uLong nAction = nActionMax - nActionCount + 1;
1166cdf0e10cSrcweir sal_uLong nSourceAction = pSourceAction->GetActionNumber() - nActionCount + 1;
1167cdf0e10cSrcweir while ( nAction <= nActionMax )
1168cdf0e10cSrcweir {
1169cdf0e10cSrcweir if ( bInverseMap )
1170cdf0e10cSrcweir {
1171cdf0e10cSrcweir (*pMergeMap)[ nAction++ ] = nSourceAction++;
1172cdf0e10cSrcweir }
1173cdf0e10cSrcweir else
1174cdf0e10cSrcweir {
1175cdf0e10cSrcweir (*pMergeMap)[ nSourceAction++ ] = nAction++;
1176cdf0e10cSrcweir }
1177cdf0e10cSrcweir }
1178cdf0e10cSrcweir }
1179cdf0e10cSrcweir }
1180cdf0e10cSrcweir }
1181cdf0e10cSrcweir aProgress.SetStateCountDown( --nNewActionCount );
1182cdf0e10cSrcweir }
1183cdf0e10cSrcweir pSourceAction = pSourceAction->GetNext();
1184cdf0e10cSrcweir }
1185cdf0e10cSrcweir
1186cdf0e10cSrcweir rMarkData = aOldMarkData;
1187cdf0e10cSrcweir pThisTrack->SetUser(aOldUser);
1188cdf0e10cSrcweir pThisTrack->SetUseFixDateTime( sal_False );
1189cdf0e10cSrcweir
1190cdf0e10cSrcweir pSourceTrack->Clear(); //! der ist jetzt verhunzt
1191cdf0e10cSrcweir
1192cdf0e10cSrcweir if (bHasRejected)
1193cdf0e10cSrcweir PostPaintGridAll(); // Reject() paintet nicht selber
1194cdf0e10cSrcweir
1195cdf0e10cSrcweir UnlockPaint();
1196cdf0e10cSrcweir }
1197cdf0e10cSrcweir
MergeSharedDocument(ScDocShell * pSharedDocShell)1198cdf0e10cSrcweir bool ScDocShell::MergeSharedDocument( ScDocShell* pSharedDocShell )
1199cdf0e10cSrcweir {
1200cdf0e10cSrcweir if ( !pSharedDocShell )
1201cdf0e10cSrcweir {
1202cdf0e10cSrcweir return false;
1203cdf0e10cSrcweir }
1204cdf0e10cSrcweir
1205cdf0e10cSrcweir ScChangeTrack* pThisTrack = aDocument.GetChangeTrack();
1206cdf0e10cSrcweir if ( !pThisTrack )
1207cdf0e10cSrcweir {
1208cdf0e10cSrcweir return false;
1209cdf0e10cSrcweir }
1210cdf0e10cSrcweir
1211cdf0e10cSrcweir ScDocument& rSharedDoc = *( pSharedDocShell->GetDocument() );
1212cdf0e10cSrcweir ScChangeTrack* pSharedTrack = rSharedDoc.GetChangeTrack();
1213cdf0e10cSrcweir if ( !pSharedTrack )
1214cdf0e10cSrcweir {
1215cdf0e10cSrcweir return false;
1216cdf0e10cSrcweir }
1217cdf0e10cSrcweir
1218cdf0e10cSrcweir #if DEBUG_CHANGETRACK
1219cdf0e10cSrcweir ::rtl::OUString aMessage = ::rtl::OUString::createFromAscii( "\nbefore merge:\n" );
1220cdf0e10cSrcweir aMessage += pThisTrack->ToString();
1221cdf0e10cSrcweir ::rtl::OString aMsg = ::rtl::OUStringToOString( aMessage, RTL_TEXTENCODING_UTF8 );
1222cdf0e10cSrcweir OSL_ENSURE( false, aMsg.getStr() );
1223cdf0e10cSrcweir //fprintf( stdout, "%s ", aMsg.getStr() );
1224cdf0e10cSrcweir //fflush( stdout );
1225cdf0e10cSrcweir #endif // DEBUG_CHANGETRACK
1226cdf0e10cSrcweir
1227cdf0e10cSrcweir // reset show changes
1228cdf0e10cSrcweir ScChangeViewSettings aChangeViewSet;
1229cdf0e10cSrcweir aChangeViewSet.SetShowChanges( sal_False );
1230cdf0e10cSrcweir aDocument.SetChangeViewSettings( aChangeViewSet );
1231cdf0e10cSrcweir
1232cdf0e10cSrcweir // find first merge action in this document
1233cdf0e10cSrcweir sal_Bool bIgnore100Sec = !pThisTrack->IsTime100thSeconds() || !pSharedTrack->IsTime100thSeconds();
1234cdf0e10cSrcweir ScChangeAction* pThisAction = pThisTrack->GetFirst();
1235cdf0e10cSrcweir ScChangeAction* pSharedAction = pSharedTrack->GetFirst();
1236cdf0e10cSrcweir while ( lcl_Equal( pThisAction, pSharedAction, bIgnore100Sec ) )
1237cdf0e10cSrcweir {
1238cdf0e10cSrcweir pThisAction = pThisAction->GetNext();
1239cdf0e10cSrcweir pSharedAction = pSharedAction->GetNext();
1240cdf0e10cSrcweir }
1241cdf0e10cSrcweir
1242cdf0e10cSrcweir if ( pSharedAction )
1243cdf0e10cSrcweir {
1244cdf0e10cSrcweir if ( pThisAction )
1245cdf0e10cSrcweir {
1246cdf0e10cSrcweir // merge own changes into shared document
1247cdf0e10cSrcweir sal_uLong nActStartShared = pSharedAction->GetActionNumber();
1248cdf0e10cSrcweir sal_uLong nActEndShared = pSharedTrack->GetActionMax();
1249cdf0e10cSrcweir ScDocument* pTmpDoc = new ScDocument;
1250cdf0e10cSrcweir for ( sal_Int32 nIndex = 0; nIndex < aDocument.GetTableCount(); ++nIndex )
1251cdf0e10cSrcweir {
1252cdf0e10cSrcweir String sTabName;
1253cdf0e10cSrcweir pTmpDoc->CreateValidTabName( sTabName );
1254cdf0e10cSrcweir pTmpDoc->InsertTab( SC_TAB_APPEND, sTabName );
1255cdf0e10cSrcweir }
1256cdf0e10cSrcweir aDocument.GetChangeTrack()->Clone( pTmpDoc );
1257cdf0e10cSrcweir ScChangeActionMergeMap aOwnInverseMergeMap;
1258cdf0e10cSrcweir pSharedDocShell->MergeDocument( *pTmpDoc, true, true, 0, &aOwnInverseMergeMap, true );
1259cdf0e10cSrcweir delete pTmpDoc;
1260cdf0e10cSrcweir sal_uLong nActStartOwn = nActEndShared + 1;
1261cdf0e10cSrcweir sal_uLong nActEndOwn = pSharedTrack->GetActionMax();
1262cdf0e10cSrcweir
1263cdf0e10cSrcweir // find conflicts
1264cdf0e10cSrcweir ScConflictsList aConflictsList;
1265cdf0e10cSrcweir ScConflictsFinder aFinder( pSharedTrack, nActStartShared, nActEndShared, nActStartOwn, nActEndOwn, aConflictsList );
1266cdf0e10cSrcweir if ( aFinder.Find() )
1267cdf0e10cSrcweir {
1268cdf0e10cSrcweir ScConflictsListHelper::TransformConflictsList( aConflictsList, NULL, &aOwnInverseMergeMap );
1269cdf0e10cSrcweir bool bLoop = true;
1270cdf0e10cSrcweir while ( bLoop )
1271cdf0e10cSrcweir {
1272cdf0e10cSrcweir bLoop = false;
1273cdf0e10cSrcweir ScConflictsDlg aDlg( GetActiveDialogParent(), GetViewData(), &rSharedDoc, aConflictsList );
1274cdf0e10cSrcweir if ( aDlg.Execute() == RET_CANCEL )
1275cdf0e10cSrcweir {
1276cdf0e10cSrcweir QueryBox aBox( GetActiveDialogParent(), WinBits( WB_YES_NO | WB_DEF_YES ),
1277cdf0e10cSrcweir ScGlobal::GetRscString( STR_DOC_WILLNOTBESAVED ) );
1278cdf0e10cSrcweir if ( aBox.Execute() == RET_YES )
1279cdf0e10cSrcweir {
1280cdf0e10cSrcweir return false;
1281cdf0e10cSrcweir }
1282cdf0e10cSrcweir else
1283cdf0e10cSrcweir {
1284cdf0e10cSrcweir bLoop = true;
1285cdf0e10cSrcweir }
1286cdf0e10cSrcweir }
1287cdf0e10cSrcweir }
1288cdf0e10cSrcweir }
1289cdf0e10cSrcweir
1290cdf0e10cSrcweir // undo own changes in shared document
1291cdf0e10cSrcweir pSharedTrack->Undo( nActStartOwn, nActEndOwn );
1292cdf0e10cSrcweir
1293cdf0e10cSrcweir // clone change track for merging into own document
1294cdf0e10cSrcweir pTmpDoc = new ScDocument;
1295cdf0e10cSrcweir for ( sal_Int32 nIndex = 0; nIndex < aDocument.GetTableCount(); ++nIndex )
1296cdf0e10cSrcweir {
1297cdf0e10cSrcweir String sTabName;
1298cdf0e10cSrcweir pTmpDoc->CreateValidTabName( sTabName );
1299cdf0e10cSrcweir pTmpDoc->InsertTab( SC_TAB_APPEND, sTabName );
1300cdf0e10cSrcweir }
1301cdf0e10cSrcweir pThisTrack->Clone( pTmpDoc );
1302cdf0e10cSrcweir
1303cdf0e10cSrcweir // undo own changes since last save in own document
1304cdf0e10cSrcweir sal_uLong nStartShared = pThisAction->GetActionNumber();
1305cdf0e10cSrcweir ScChangeAction* pAction = pThisTrack->GetLast();
1306cdf0e10cSrcweir while ( pAction && pAction->GetActionNumber() >= nStartShared )
1307cdf0e10cSrcweir {
1308cdf0e10cSrcweir pThisTrack->Reject( pAction, true );
1309cdf0e10cSrcweir pAction = pAction->GetPrev();
1310cdf0e10cSrcweir }
1311cdf0e10cSrcweir
1312cdf0e10cSrcweir // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
1313cdf0e10cSrcweir pThisTrack->Undo( nStartShared, pThisTrack->GetActionMax(), true );
1314cdf0e10cSrcweir
1315cdf0e10cSrcweir // merge shared changes into own document
1316cdf0e10cSrcweir ScChangeActionMergeMap aSharedMergeMap;
1317cdf0e10cSrcweir MergeDocument( rSharedDoc, true, true, 0, &aSharedMergeMap );
1318cdf0e10cSrcweir sal_uLong nEndShared = pThisTrack->GetActionMax();
1319cdf0e10cSrcweir
1320cdf0e10cSrcweir // resolve conflicts for shared non-content actions
1321cdf0e10cSrcweir if ( !aConflictsList.empty() )
1322cdf0e10cSrcweir {
1323cdf0e10cSrcweir ScConflictsListHelper::TransformConflictsList( aConflictsList, &aSharedMergeMap, NULL );
1324cdf0e10cSrcweir ScConflictsResolver aResolver( pThisTrack, aConflictsList );
1325cdf0e10cSrcweir pAction = pThisTrack->GetAction( nEndShared );
1326cdf0e10cSrcweir while ( pAction && pAction->GetActionNumber() >= nStartShared )
1327cdf0e10cSrcweir {
1328cdf0e10cSrcweir aResolver.HandleAction( pAction, true /*bIsSharedAction*/,
1329cdf0e10cSrcweir false /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
1330cdf0e10cSrcweir pAction = pAction->GetPrev();
1331cdf0e10cSrcweir }
1332cdf0e10cSrcweir }
1333cdf0e10cSrcweir nEndShared = pThisTrack->GetActionMax();
1334cdf0e10cSrcweir
1335cdf0e10cSrcweir // only show changes from shared document
1336cdf0e10cSrcweir aChangeViewSet.SetShowChanges( sal_True );
1337cdf0e10cSrcweir aChangeViewSet.SetShowAccepted( sal_True );
1338cdf0e10cSrcweir aChangeViewSet.SetHasActionRange( true );
1339cdf0e10cSrcweir aChangeViewSet.SetTheActionRange( nStartShared, nEndShared );
1340cdf0e10cSrcweir aDocument.SetChangeViewSettings( aChangeViewSet );
1341cdf0e10cSrcweir
1342cdf0e10cSrcweir // merge own changes back into own document
1343cdf0e10cSrcweir sal_uLong nStartOwn = nEndShared + 1;
1344cdf0e10cSrcweir ScChangeActionMergeMap aOwnMergeMap;
1345cdf0e10cSrcweir MergeDocument( *pTmpDoc, true, true, nEndShared - nStartShared + 1, &aOwnMergeMap );
1346cdf0e10cSrcweir delete pTmpDoc;
1347cdf0e10cSrcweir sal_uLong nEndOwn = pThisTrack->GetActionMax();
1348cdf0e10cSrcweir
1349cdf0e10cSrcweir // resolve conflicts for shared content actions and own actions
1350cdf0e10cSrcweir if ( !aConflictsList.empty() )
1351cdf0e10cSrcweir {
1352cdf0e10cSrcweir ScConflictsListHelper::TransformConflictsList( aConflictsList, NULL, &aOwnMergeMap );
1353cdf0e10cSrcweir ScConflictsResolver aResolver( pThisTrack, aConflictsList );
1354cdf0e10cSrcweir pAction = pThisTrack->GetAction( nEndShared );
1355cdf0e10cSrcweir while ( pAction && pAction->GetActionNumber() >= nStartShared )
1356cdf0e10cSrcweir {
1357cdf0e10cSrcweir aResolver.HandleAction( pAction, true /*bIsSharedAction*/,
1358cdf0e10cSrcweir true /*bHandleContentAction*/, false /*bHandleNonContentAction*/ );
1359cdf0e10cSrcweir pAction = pAction->GetPrev();
1360cdf0e10cSrcweir }
1361cdf0e10cSrcweir
1362cdf0e10cSrcweir pAction = pThisTrack->GetAction( nEndOwn );
1363cdf0e10cSrcweir while ( pAction && pAction->GetActionNumber() >= nStartOwn )
1364cdf0e10cSrcweir {
1365cdf0e10cSrcweir aResolver.HandleAction( pAction, false /*bIsSharedAction*/,
1366cdf0e10cSrcweir true /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
1367cdf0e10cSrcweir pAction = pAction->GetPrev();
1368cdf0e10cSrcweir }
1369cdf0e10cSrcweir }
1370cdf0e10cSrcweir nEndOwn = pThisTrack->GetActionMax();
1371cdf0e10cSrcweir }
1372cdf0e10cSrcweir else
1373cdf0e10cSrcweir {
1374cdf0e10cSrcweir // merge shared changes into own document
1375cdf0e10cSrcweir sal_uLong nStartShared = pThisTrack->GetActionMax() + 1;
1376cdf0e10cSrcweir MergeDocument( rSharedDoc, true, true );
1377cdf0e10cSrcweir sal_uLong nEndShared = pThisTrack->GetActionMax();
1378cdf0e10cSrcweir
1379cdf0e10cSrcweir // only show changes from shared document
1380cdf0e10cSrcweir aChangeViewSet.SetShowChanges( sal_True );
1381cdf0e10cSrcweir aChangeViewSet.SetShowAccepted( sal_True );
1382cdf0e10cSrcweir aChangeViewSet.SetHasActionRange( true );
1383cdf0e10cSrcweir aChangeViewSet.SetTheActionRange( nStartShared, nEndShared );
1384cdf0e10cSrcweir aDocument.SetChangeViewSettings( aChangeViewSet );
1385cdf0e10cSrcweir }
1386cdf0e10cSrcweir
1387cdf0e10cSrcweir // update view
1388cdf0e10cSrcweir PostPaintExtras();
1389cdf0e10cSrcweir PostPaintGridAll();
1390cdf0e10cSrcweir
1391cdf0e10cSrcweir InfoBox aInfoBox( GetActiveDialogParent(), ScGlobal::GetRscString( STR_DOC_UPDATED ) );
1392cdf0e10cSrcweir aInfoBox.Execute();
1393cdf0e10cSrcweir }
1394cdf0e10cSrcweir
1395cdf0e10cSrcweir #if DEBUG_CHANGETRACK
1396cdf0e10cSrcweir aMessage = ::rtl::OUString::createFromAscii( "\nafter merge:\n" );
1397cdf0e10cSrcweir aMessage += pThisTrack->ToString();
1398cdf0e10cSrcweir aMsg = ::rtl::OUStringToOString( aMessage, RTL_TEXTENCODING_UTF8 );
1399cdf0e10cSrcweir OSL_ENSURE( false, aMsg.getStr() );
1400cdf0e10cSrcweir //fprintf( stdout, "%s ", aMsg.getStr() );
1401cdf0e10cSrcweir //fflush( stdout );
1402cdf0e10cSrcweir #endif // DEBUG_CHANGETRACK
1403cdf0e10cSrcweir
1404cdf0e10cSrcweir return ( pThisAction != NULL );
1405cdf0e10cSrcweir }
1406