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