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