fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / docshell / docsh3.cxx
blob2bb995f36829e844f09b4a22e24c742a2ebd0b4e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
21 #include <com/sun/star/document/XDocumentProperties.hpp>
23 #include "scitems.hxx"
24 #include "rangelst.hxx"
25 #include <editeng/flstitem.hxx>
26 #include <editeng/paperinf.hxx>
27 #include <editeng/sizeitem.hxx>
28 #include <rtl/strbuf.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <sfx2/app.hxx>
31 #include <sfx2/docfile.hxx>
32 #include <sfx2/printer.hxx>
33 #include <svx/postattr.hxx>
34 #include <unotools/misccfg.hxx>
35 #include <vcl/virdev.hxx>
36 #include <vcl/msgbox.hxx>
38 #include "docsh.hxx"
39 #include "docshimp.hxx"
40 #include "scmod.hxx"
41 #include "tabvwsh.hxx"
42 #include "viewdata.hxx"
43 #include "docpool.hxx"
44 #include "stlpool.hxx"
45 #include "patattr.hxx"
46 #include "uiitems.hxx"
47 #include "hints.hxx"
48 #include "docoptio.hxx"
49 #include "viewopti.hxx"
50 #include "pntlock.hxx"
51 #include "chgtrack.hxx"
52 #include "docfunc.hxx"
53 #include "formulacell.hxx"
54 #include "chgviset.hxx"
55 #include "progress.hxx"
56 #include "redcom.hxx"
57 #include "sc.hrc"
58 #include "inputopt.hxx"
59 #include "drwlayer.hxx"
60 #include "inputhdl.hxx"
61 #include "conflictsdlg.hxx"
62 #include "globstr.hrc"
63 #include "markdata.hxx"
64 #include <boost/scoped_ptr.hpp>
66 // Redraw - Benachrichtigungen
68 void ScDocShell::PostEditView( ScEditEngineDefaulter* pEditEngine, const ScAddress& rCursorPos )
70 // Broadcast( ScEditViewHint( pEditEngine, rCursorPos ) );
72 // Test: nur aktive ViewShell
74 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
75 if (pViewSh && pViewSh->GetViewData().GetDocShell() == this)
77 ScEditViewHint aHint( pEditEngine, rCursorPos );
78 pViewSh->Notify( *this, aHint );
82 void ScDocShell::PostDataChanged()
84 Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
85 SfxGetpApp()->Broadcast(SfxSimpleHint( FID_ANYDATACHANGED )); // Navigator
86 aDocument.ClearFormulaContext();
87 //! Navigator direkt benachrichtigen!
90 void ScDocShell::PostPaint( SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab,
91 SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, sal_uInt16 nPart,
92 sal_uInt16 nExtFlags )
94 ScRange aRange(nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
95 PostPaint(aRange, nPart, nExtFlags);
98 void ScDocShell::PostPaint( const ScRangeList& rRanges, sal_uInt16 nPart, sal_uInt16 nExtFlags )
100 ScRangeList aPaintRanges;
101 for (size_t i = 0, n = rRanges.size(); i < n; ++i)
103 const ScRange& rRange = *rRanges[i];
104 SCCOL nCol1 = rRange.aStart.Col(), nCol2 = rRange.aEnd.Col();
105 SCROW nRow1 = rRange.aStart.Row(), nRow2 = rRange.aEnd.Row();
106 SCTAB nTab1 = rRange.aStart.Tab(), nTab2 = rRange.aEnd.Tab();
108 if (!ValidCol(nCol1)) nCol1 = MAXCOL;
109 if (!ValidRow(nRow1)) nRow1 = MAXROW;
110 if (!ValidCol(nCol2)) nCol2 = MAXCOL;
111 if (!ValidRow(nRow2)) nRow2 = MAXROW;
113 if ( pPaintLockData )
115 // #i54081# PAINT_EXTRAS still has to be broadcast because it changes the
116 // current sheet if it's invalid. All other flags added to pPaintLockData.
117 sal_uInt16 nLockPart = nPart & ~PAINT_EXTRAS;
118 if ( nLockPart )
120 //! nExtFlags ???
121 pPaintLockData->AddRange( ScRange( nCol1, nRow1, nTab1,
122 nCol2, nRow2, nTab2 ), nLockPart );
125 nPart &= PAINT_EXTRAS; // for broadcasting
126 if (!nPart)
127 continue;
130 if (nExtFlags & SC_PF_LINES) // Platz fuer Linien beruecksichtigen
132 //! Abfrage auf versteckte Spalten/Zeilen!
133 if (nCol1>0) --nCol1;
134 if (nCol2<MAXCOL) ++nCol2;
135 if (nRow1>0) --nRow1;
136 if (nRow2<MAXROW) ++nRow2;
139 // um zusammengefasste erweitern
140 if (nExtFlags & SC_PF_TESTMERGE)
141 aDocument.ExtendMerge( nCol1, nRow1, nCol2, nRow2, nTab1 );
143 if ( nCol1 != 0 || nCol2 != MAXCOL )
145 // Extend to whole rows if SC_PF_WHOLEROWS is set, or rotated or non-left
146 // aligned cells are contained (see UpdatePaintExt).
147 // Special handling for RTL text (#i9731#) is unnecessary now with full
148 // support of right-aligned text.
150 if ( ( nExtFlags & SC_PF_WHOLEROWS ) ||
151 aDocument.HasAttrib( nCol1,nRow1,nTab1,
152 MAXCOL,nRow2,nTab2, HASATTR_ROTATE | HASATTR_RIGHTORCENTER ) )
154 nCol1 = 0;
155 nCol2 = MAXCOL;
158 aPaintRanges.Append(ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2));
161 Broadcast(ScPaintHint(aPaintRanges.Combine(), nPart));
164 void ScDocShell::PostPaintGridAll()
166 PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
169 void ScDocShell::PostPaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
171 PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID, SC_PF_TESTMERGE );
174 void ScDocShell::PostPaintCell( const ScAddress& rPos )
176 PostPaintCell( rPos.Col(), rPos.Row(), rPos.Tab() );
179 void ScDocShell::PostPaintExtras()
181 PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS );
184 void ScDocShell::UpdatePaintExt( sal_uInt16& rExtFlags, const ScRange& rRange )
186 if ( ( rExtFlags & SC_PF_LINES ) == 0 && aDocument.HasAttrib( rRange, HASATTR_PAINTEXT ) )
188 // If the range contains lines, shadow or conditional formats,
189 // set SC_PF_LINES to include one extra cell in all directions.
191 rExtFlags |= SC_PF_LINES;
194 if ( ( rExtFlags & SC_PF_WHOLEROWS ) == 0 &&
195 ( rRange.aStart.Col() != 0 || rRange.aEnd.Col() != MAXCOL ) &&
196 aDocument.HasAttrib( rRange, HASATTR_ROTATE | HASATTR_RIGHTORCENTER ) )
198 // If the range contains (logically) right- or center-aligned cells,
199 // or rotated cells, set SC_PF_WHOLEROWS to paint the whole rows.
200 // This test isn't needed after the cell changes, because it's also
201 // tested in PostPaint. UpdatePaintExt may later be changed to do this
202 // only if called before the changes.
204 rExtFlags |= SC_PF_WHOLEROWS;
208 void ScDocShell::UpdatePaintExt( sal_uInt16& rExtFlags, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab,
209 SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab )
211 UpdatePaintExt( rExtFlags, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ) );
214 void ScDocShell::LockPaint_Impl(bool bDoc)
216 if ( !pPaintLockData )
217 pPaintLockData = new ScPaintLockData;
218 pPaintLockData->IncLevel(bDoc);
221 void ScDocShell::UnlockPaint_Impl(bool bDoc)
223 if ( pPaintLockData )
225 if ( pPaintLockData->GetLevel(bDoc) )
226 pPaintLockData->DecLevel(bDoc);
227 if (!pPaintLockData->GetLevel(!bDoc) && !pPaintLockData->GetLevel(bDoc))
229 // Paint jetzt ausfuehren
231 ScPaintLockData* pPaint = pPaintLockData;
232 pPaintLockData = NULL; // nicht weitersammeln
234 ScRangeListRef xRangeList = pPaint->GetRangeList();
235 if (xRangeList)
237 sal_uInt16 nParts = pPaint->GetParts();
238 for ( size_t i = 0, nCount = xRangeList->size(); i < nCount; i++ )
240 //! nExtFlags ???
241 ScRange aRange = *(*xRangeList)[i];
242 PostPaint( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab(),
243 aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab(),
244 nParts );
248 if ( pPaint->GetModified() )
249 SetDocumentModified();
251 delete pPaint;
254 else
256 OSL_FAIL("UnlockPaint ohne LockPaint");
260 void ScDocShell::LockDocument_Impl(sal_uInt16 nNew)
262 if (!nDocumentLock)
264 ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
265 if (pDrawLayer)
266 pDrawLayer->setLock(true);
268 nDocumentLock = nNew;
271 void ScDocShell::UnlockDocument_Impl(sal_uInt16 nNew)
273 nDocumentLock = nNew;
274 if (!nDocumentLock)
276 ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
277 if (pDrawLayer)
278 pDrawLayer->setLock(false);
282 void ScDocShell::SetLockCount(sal_uInt16 nNew)
284 if (nNew) // setzen
286 if ( !pPaintLockData )
287 pPaintLockData = new ScPaintLockData;
288 pPaintLockData->SetLevel(nNew-1, true);
289 LockDocument_Impl(nNew);
291 else if (pPaintLockData) // loeschen
293 pPaintLockData->SetLevel(0, true); // bei Unlock sofort ausfuehren
294 UnlockPaint_Impl(true); // jetzt
295 UnlockDocument_Impl(0);
299 void ScDocShell::LockPaint()
301 LockPaint_Impl(false);
304 void ScDocShell::UnlockPaint()
306 UnlockPaint_Impl(false);
309 void ScDocShell::LockDocument()
311 LockPaint_Impl(true);
312 LockDocument_Impl(nDocumentLock + 1);
315 void ScDocShell::UnlockDocument()
317 if (nDocumentLock)
319 UnlockPaint_Impl(true);
320 UnlockDocument_Impl(nDocumentLock - 1);
322 else
324 OSL_FAIL("UnlockDocument without LockDocument");
328 void ScDocShell::SetInplace( bool bInplace )
330 if (bIsInplace != bInplace)
332 bIsInplace = bInplace;
333 CalcOutputFactor();
337 void ScDocShell::CalcOutputFactor()
339 if (bIsInplace)
341 nPrtToScreenFactor = 1.0; // passt sonst nicht zur inaktiven Darstellung
342 return;
345 bool bTextWysiwyg = SC_MOD()->GetInputOptions().GetTextWysiwyg();
346 if (bTextWysiwyg)
348 nPrtToScreenFactor = 1.0;
349 return;
352 OUString aTestString(
353 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789");
354 long nPrinterWidth = 0;
355 long nWindowWidth = 0;
356 const ScPatternAttr* pPattern = static_cast<const ScPatternAttr*>(&aDocument.GetPool()->
357 GetDefaultItem(ATTR_PATTERN));
359 vcl::Font aDefFont;
360 OutputDevice* pRefDev = GetRefDevice();
361 MapMode aOldMode = pRefDev->GetMapMode();
362 vcl::Font aOldFont = pRefDev->GetFont();
364 pRefDev->SetMapMode(MAP_PIXEL);
365 pPattern->GetFont(aDefFont, SC_AUTOCOL_BLACK, pRefDev); // font color doesn't matter here
366 pRefDev->SetFont(aDefFont);
367 nPrinterWidth = pRefDev->PixelToLogic( Size( pRefDev->GetTextWidth(aTestString), 0 ), MAP_100TH_MM ).Width();
368 pRefDev->SetFont(aOldFont);
369 pRefDev->SetMapMode(aOldMode);
371 ScopedVclPtrInstance< VirtualDevice > pVirtWindow( *Application::GetDefaultDevice() );
372 pVirtWindow->SetMapMode(MAP_PIXEL);
373 pPattern->GetFont(aDefFont, SC_AUTOCOL_BLACK, pVirtWindow); // font color doesn't matter here
374 pVirtWindow->SetFont(aDefFont);
375 nWindowWidth = pVirtWindow->GetTextWidth(aTestString);
376 nWindowWidth = (long) ( nWindowWidth / ScGlobal::nScreenPPTX * HMM_PER_TWIPS );
378 if (nPrinterWidth && nWindowWidth)
379 nPrtToScreenFactor = nPrinterWidth / (double) nWindowWidth;
380 else
382 OSL_FAIL("GetTextSize gibt 0 ??");
383 nPrtToScreenFactor = 1.0;
387 void ScDocShell::InitOptions(bool bForLoading) // called from InitNew and Load
389 // Einstellungen aus dem SpellCheckCfg kommen in Doc- und ViewOptions
391 sal_uInt16 nDefLang, nCjkLang, nCtlLang;
392 bool bAutoSpell;
393 ScModule::GetSpellSettings( nDefLang, nCjkLang, nCtlLang, bAutoSpell );
394 ScModule* pScMod = SC_MOD();
396 ScDocOptions aDocOpt = pScMod->GetDocOptions();
397 ScFormulaOptions aFormulaOpt = pScMod->GetFormulaOptions();
398 ScViewOptions aViewOpt = pScMod->GetViewOptions();
399 aDocOpt.SetAutoSpell( bAutoSpell );
401 // zweistellige Jahreszahleneingabe aus Extras->Optionen->Allgemein->Sonstiges
402 aDocOpt.SetYear2000( sal::static_int_cast<sal_uInt16>( ::utl::MiscCfg().GetYear2000() ) );
404 if (bForLoading)
406 // #i112123# No style:decimal-places attribute means automatic decimals, not the configured default,
407 // so it must not be taken from the global options.
408 // Calculation settings are handled separately in ScXMLBodyContext::EndElement.
409 aDocOpt.SetStdPrecision( SvNumberFormatter::UNLIMITED_PRECISION );
411 // fdo#78294 The default null-date if
412 // <table:null-date table:date-value='...' />
413 // is absent is 1899-12-30 regardless what the configuration is set to.
414 // Import filters may override this value.
415 aDocOpt.SetDate( 30, 12, 1899);
418 aDocument.SetDocOptions( aDocOpt );
419 aDocument.SetViewOptions( aViewOpt );
420 SetFormulaOptions( aFormulaOpt, bForLoading );
422 // Druck-Optionen werden jetzt direkt vor dem Drucken gesetzt
424 aDocument.SetLanguage( (LanguageType) nDefLang, (LanguageType) nCjkLang, (LanguageType) nCtlLang );
427 Printer* ScDocShell::GetDocumentPrinter() // fuer OLE
429 return aDocument.GetPrinter();
432 SfxPrinter* ScDocShell::GetPrinter(bool bCreateIfNotExist)
434 return aDocument.GetPrinter(bCreateIfNotExist);
437 void ScDocShell::UpdateFontList()
439 delete pImpl->pFontList;
440 // pImpl->pFontList = new FontList( GetPrinter(), Application::GetDefaultDevice() );
441 pImpl->pFontList = new FontList( GetRefDevice(), NULL, false ); // sal_False or sal_True???
442 SvxFontListItem aFontListItem( pImpl->pFontList, SID_ATTR_CHAR_FONTLIST );
443 PutItem( aFontListItem );
445 CalcOutputFactor();
448 OutputDevice* ScDocShell::GetRefDevice()
450 return aDocument.GetRefDevice();
453 sal_uInt16 ScDocShell::SetPrinter( SfxPrinter* pNewPrinter, SfxPrinterChangeFlags nDiffFlags )
455 SfxPrinter *pOld = aDocument.GetPrinter( false );
456 if ( pOld && pOld->IsPrinting() )
457 return SFX_PRINTERROR_BUSY;
459 if (nDiffFlags & SfxPrinterChangeFlags::PRINTER)
461 if ( aDocument.GetPrinter() != pNewPrinter )
463 aDocument.SetPrinter( pNewPrinter );
464 aDocument.SetPrintOptions();
466 // MT: Use UpdateFontList: Will use Printer fonts only if needed!
468 delete pImpl->pFontList;
469 pImpl->pFontList = new FontList( pNewPrinter, Application::GetDefaultDevice() );
470 SvxFontListItem aFontListItem( pImpl->pFontList, SID_ATTR_CHAR_FONTLIST );
471 PutItem( aFontListItem );
473 CalcOutputFactor();
475 if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
476 UpdateFontList();
478 ScModule* pScMod = SC_MOD();
479 SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this );
480 while (pFrame)
482 SfxViewShell* pSh = pFrame->GetViewShell();
483 if (pSh && pSh->ISA(ScTabViewShell))
485 ScTabViewShell* pViewSh = static_cast<ScTabViewShell*>(pSh);
486 ScInputHandler* pInputHdl = pScMod->GetInputHdl(pViewSh);
487 if (pInputHdl)
488 pInputHdl->UpdateRefDevice();
490 pFrame = SfxViewFrame::GetNext( *pFrame, this );
494 else if (nDiffFlags & SfxPrinterChangeFlags::JOBSETUP)
496 SfxPrinter* pOldPrinter = aDocument.GetPrinter();
497 if (pOldPrinter)
499 pOldPrinter->SetJobSetup( pNewPrinter->GetJobSetup() );
501 // #i6706# Call SetPrinter with the old printer again, so the drawing layer
502 // RefDevice is set (calling ReformatAllTextObjects and rebuilding charts),
503 // because the JobSetup (printer device settings) may affect text layout.
504 aDocument.SetPrinter( pOldPrinter );
505 CalcOutputFactor(); // also with the new settings
509 if (nDiffFlags & SfxPrinterChangeFlags::OPTIONS)
511 aDocument.SetPrintOptions(); //! aus neuem Printer ???
514 if (nDiffFlags & (SfxPrinterChangeFlags::CHG_ORIENTATION | SfxPrinterChangeFlags::CHG_SIZE))
516 OUString aStyle = aDocument.GetPageStyle( GetCurTab() );
517 ScStyleSheetPool* pStPl = aDocument.GetStyleSheetPool();
518 SfxStyleSheet* pStyleSheet = static_cast<SfxStyleSheet*>(pStPl->Find(aStyle, SFX_STYLE_FAMILY_PAGE));
519 if (pStyleSheet)
521 SfxItemSet& rSet = pStyleSheet->GetItemSet();
523 if (nDiffFlags & SfxPrinterChangeFlags::CHG_ORIENTATION)
525 const SvxPageItem& rOldItem = static_cast<const SvxPageItem&>(rSet.Get(ATTR_PAGE));
526 bool bWasLand = rOldItem.IsLandscape();
527 bool bNewLand = ( pNewPrinter->GetOrientation() == ORIENTATION_LANDSCAPE );
528 if (bNewLand != bWasLand)
530 SvxPageItem aNewItem( rOldItem );
531 aNewItem.SetLandscape( bNewLand );
532 rSet.Put( aNewItem );
534 // Groesse umdrehen
535 Size aOldSize = static_cast<const SvxSizeItem&>(rSet.Get(ATTR_PAGE_SIZE)).GetSize();
536 Size aNewSize(aOldSize.Height(),aOldSize.Width());
537 SvxSizeItem aNewSItem(ATTR_PAGE_SIZE,aNewSize);
538 rSet.Put( aNewSItem );
541 if (nDiffFlags & SfxPrinterChangeFlags::CHG_SIZE)
543 SvxSizeItem aPaperSizeItem( ATTR_PAGE_SIZE, SvxPaperInfo::GetPaperSize(pNewPrinter) );
544 rSet.Put( aPaperSizeItem );
549 PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB,PAINT_ALL);
551 return 0;
554 ScChangeAction* ScDocShell::GetChangeAction( const ScAddress& rPos )
556 ScChangeTrack* pTrack = GetDocument().GetChangeTrack();
557 if (!pTrack)
558 return NULL;
560 SCTAB nTab = rPos.Tab();
562 const ScChangeAction* pFound = NULL;
563 long nModified = 0;
564 const ScChangeAction* pAction = pTrack->GetFirst();
565 while (pAction)
567 ScChangeActionType eType = pAction->GetType();
568 //! ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc )...
569 if ( pAction->IsVisible() && eType != SC_CAT_DELETE_TABS )
571 const ScBigRange& rBig = pAction->GetBigRange();
572 if ( rBig.aStart.Tab() == nTab )
574 ScRange aRange = rBig.MakeRange();
576 if ( eType == SC_CAT_DELETE_ROWS )
577 aRange.aEnd.SetRow( aRange.aStart.Row() );
578 else if ( eType == SC_CAT_DELETE_COLS )
579 aRange.aEnd.SetCol( aRange.aStart.Col() );
581 if ( aRange.In( rPos ) )
583 pFound = pAction; // der letzte gewinnt
584 ++nModified;
587 if ( pAction->GetType() == SC_CAT_MOVE )
589 ScRange aRange =
590 static_cast<const ScChangeActionMove*>(pAction)->
591 GetFromRange().MakeRange();
592 if ( aRange.In( rPos ) )
594 pFound = pAction;
595 ++nModified;
599 pAction = pAction->GetNext();
602 return const_cast<ScChangeAction*>(pFound);
605 void ScDocShell::SetChangeComment( ScChangeAction* pAction, const OUString& rComment )
607 if (pAction)
609 pAction->SetComment( rComment );
610 //! Undo ???
611 SetDocumentModified();
613 // Dialog-Notify
614 ScChangeTrack* pTrack = GetDocument().GetChangeTrack();
615 if (pTrack)
617 sal_uLong nNumber = pAction->GetActionNumber();
618 pTrack->NotifyModified( SC_CTM_CHANGE, nNumber, nNumber );
623 void ScDocShell::ExecuteChangeCommentDialog( ScChangeAction* pAction, vcl::Window* pParent, bool bPrevNext)
625 if (!pAction) return; // ohne Aktion ist nichts..
627 OUString aComment = pAction->GetComment();
628 OUString aAuthor = pAction->GetUser();
630 DateTime aDT = pAction->GetDateTime();
631 OUString aDate = ScGlobal::pLocaleData->getDate( aDT );
632 aDate += " ";
633 aDate += ScGlobal::pLocaleData->getTime( aDT, false, false );
635 SfxItemSet aSet( GetPool(),
636 SID_ATTR_POSTIT_AUTHOR, SID_ATTR_POSTIT_AUTHOR,
637 SID_ATTR_POSTIT_DATE, SID_ATTR_POSTIT_DATE,
638 SID_ATTR_POSTIT_TEXT, SID_ATTR_POSTIT_TEXT,
639 0 );
641 aSet.Put( SvxPostItTextItem ( aComment, SID_ATTR_POSTIT_TEXT ) );
642 aSet.Put( SvxPostItAuthorItem( aAuthor, SID_ATTR_POSTIT_AUTHOR ) );
643 aSet.Put( SvxPostItDateItem ( aDate, SID_ATTR_POSTIT_DATE ) );
645 boost::scoped_ptr<ScRedComDialog> pDlg(new ScRedComDialog( pParent, aSet,this,pAction,bPrevNext));
647 pDlg->Execute();
650 void ScDocShell::CompareDocument( ScDocument& rOtherDoc )
652 ScChangeTrack* pTrack = aDocument.GetChangeTrack();
653 if ( pTrack && pTrack->GetFirst() )
655 //! Changes vorhanden -> Nachfrage ob geloescht werden soll
658 aDocument.EndChangeTracking();
659 aDocument.StartChangeTracking();
661 OUString aOldUser;
662 pTrack = aDocument.GetChangeTrack();
663 if ( pTrack )
665 aOldUser = pTrack->GetUser();
667 // check if comparing to same document
669 OUString aThisFile;
670 const SfxMedium* pThisMed = GetMedium();
671 if (pThisMed)
672 aThisFile = pThisMed->GetName();
673 OUString aOtherFile;
674 SfxObjectShell* pOtherSh = rOtherDoc.GetDocumentShell();
675 if (pOtherSh)
677 const SfxMedium* pOtherMed = pOtherSh->GetMedium();
678 if (pOtherMed)
679 aOtherFile = pOtherMed->GetName();
681 bool bSameDoc = ( aThisFile == aOtherFile && !aThisFile.isEmpty() );
682 if ( !bSameDoc )
684 // create change actions from comparing with the name of the user
685 // who last saved the document
686 // (only if comparing different documents)
688 using namespace ::com::sun::star;
689 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
690 GetModel(), uno::UNO_QUERY_THROW);
691 uno::Reference<document::XDocumentProperties> xDocProps(
692 xDPS->getDocumentProperties());
693 OSL_ENSURE(xDocProps.is(), "no DocumentProperties");
694 OUString aDocUser = xDocProps->getModifiedBy();
696 if ( !aDocUser.isEmpty() )
697 pTrack->SetUser( aDocUser );
701 aDocument.CompareDocument( rOtherDoc );
703 pTrack = aDocument.GetChangeTrack();
704 if ( pTrack )
705 pTrack->SetUser( aOldUser );
707 PostPaintGridAll();
708 SetDocumentModified();
711 // Merge (Aenderungen zusammenfuehren)
713 static inline bool lcl_Equal( const ScChangeAction* pA, const ScChangeAction* pB, bool bIgnore100Sec )
715 return pA && pB &&
716 pA->GetActionNumber() == pB->GetActionNumber() &&
717 pA->GetType() == pB->GetType() &&
718 pA->GetUser() == pB->GetUser() &&
719 (bIgnore100Sec ?
720 pA->GetDateTimeUTC().IsEqualIgnoreNanoSec( pB->GetDateTimeUTC() ) :
721 pA->GetDateTimeUTC() == pB->GetDateTimeUTC());
722 // State nicht vergleichen, falls eine alte Aenderung akzeptiert wurde
725 static bool lcl_FindAction( ScDocument* pDoc, const ScChangeAction* pAction, ScDocument* pSearchDoc, const ScChangeAction* pFirstSearchAction, const ScChangeAction* pLastSearchAction, bool bIgnore100Sec )
727 if ( !pDoc || !pAction || !pSearchDoc || !pFirstSearchAction || !pLastSearchAction )
729 return false;
732 sal_uLong nLastSearchAction = pLastSearchAction->GetActionNumber();
733 const ScChangeAction* pA = pFirstSearchAction;
734 while ( pA && pA->GetActionNumber() <= nLastSearchAction )
736 if ( pAction->GetType() == pA->GetType() &&
737 pAction->GetUser() == pA->GetUser() &&
738 (bIgnore100Sec ?
739 pAction->GetDateTimeUTC().IsEqualIgnoreNanoSec( pA->GetDateTimeUTC() ) :
740 pAction->GetDateTimeUTC() == pA->GetDateTimeUTC() ) &&
741 pAction->GetBigRange() == pA->GetBigRange() )
743 OUString aActionDesc;
744 pAction->GetDescription(aActionDesc, pDoc, true);
745 OUString aADesc;
746 pA->GetDescription(aADesc, pSearchDoc, true);
747 if (aActionDesc.equals(aADesc))
749 OSL_FAIL( "lcl_FindAction(): found equal action!" );
750 return true;
753 pA = pA->GetNext();
756 return false;
759 void ScDocShell::MergeDocument( ScDocument& rOtherDoc, bool bShared, bool bCheckDuplicates, sal_uLong nOffset, ScChangeActionMergeMap* pMergeMap, bool bInverseMap )
761 ScTabViewShell* pViewSh = GetBestViewShell( false ); //! Funktionen an die DocShell
762 if (!pViewSh)
763 return;
765 ScChangeTrack* pSourceTrack = rOtherDoc.GetChangeTrack();
766 if (!pSourceTrack)
767 return; //! nichts zu tun - Fehlermeldung?
769 ScChangeTrack* pThisTrack = aDocument.GetChangeTrack();
770 if ( !pThisTrack )
771 { // anschalten
772 aDocument.StartChangeTracking();
773 pThisTrack = aDocument.GetChangeTrack();
774 OSL_ENSURE(pThisTrack,"ChangeTracking nicht angeschaltet?");
775 if ( !bShared )
777 // visuelles RedLining einschalten
778 ScChangeViewSettings aChangeViewSet;
779 aChangeViewSet.SetShowChanges(true);
780 aDocument.SetChangeViewSettings(aChangeViewSet);
784 // include Nano seconds in compare?
785 bool bIgnore100Sec = !pSourceTrack->IsTimeNanoSeconds() ||
786 !pThisTrack->IsTimeNanoSeconds();
788 // gemeinsame Ausgangsposition suchen
789 sal_uLong nFirstNewNumber = 0;
790 const ScChangeAction* pSourceAction = pSourceTrack->GetFirst();
791 const ScChangeAction* pThisAction = pThisTrack->GetFirst();
792 // skip identical actions
793 while ( lcl_Equal( pSourceAction, pThisAction, bIgnore100Sec ) )
795 nFirstNewNumber = pSourceAction->GetActionNumber() + 1;
796 pSourceAction = pSourceAction->GetNext();
797 pThisAction = pThisAction->GetNext();
799 // pSourceAction und pThisAction zeigen jetzt auf die ersten "eigenen" Aktionen
800 // Die gemeinsamen Aktionen davor interessieren ueberhaupt nicht
802 //! Abfrage, ob die Dokumente vor dem Change-Tracking gleich waren !!!
804 const ScChangeAction* pFirstMergeAction = pSourceAction;
805 const ScChangeAction* pFirstSearchAction = pThisAction;
807 // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
808 const ScChangeAction* pLastSearchAction = pThisTrack->GetLast();
810 // MergeChangeData aus den folgenden Aktionen erzeugen
811 sal_uLong nNewActionCount = 0;
812 const ScChangeAction* pCount = pSourceAction;
813 while ( pCount )
815 if ( bShared || !ScChangeTrack::MergeIgnore( *pCount, nFirstNewNumber ) )
816 ++nNewActionCount;
817 pCount = pCount->GetNext();
819 if (!nNewActionCount)
820 return; //! nichts zu tun - Fehlermeldung?
821 // ab hier kein return mehr
823 ScProgress aProgress( this, OUString("..."),
824 nNewActionCount );
826 sal_uLong nLastMergeAction = pSourceTrack->GetLast()->GetActionNumber();
827 // UpdateReference-Undo, gueltige Referenzen fuer den letzten gemeinsamen Zustand
828 pSourceTrack->MergePrepare( const_cast<ScChangeAction*>(pFirstMergeAction), bShared );
830 // MergeChangeData an alle noch folgenden Aktionen in diesem Dokument anpassen
831 // -> Referenzen gueltig fuer dieses Dokument
832 while ( pThisAction )
834 // #i87049# [Collaboration] Conflict between delete row and insert content is not merged correctly
835 if ( !bShared || !ScChangeTrack::MergeIgnore( *pThisAction, nFirstNewNumber ) )
837 ScChangeActionType eType = pThisAction->GetType();
838 switch ( eType )
840 case SC_CAT_INSERT_COLS :
841 case SC_CAT_INSERT_ROWS :
842 case SC_CAT_INSERT_TABS :
843 pSourceTrack->AppendInsert( pThisAction->GetBigRange().MakeRange() );
844 break;
845 case SC_CAT_DELETE_COLS :
846 case SC_CAT_DELETE_ROWS :
847 case SC_CAT_DELETE_TABS :
849 const ScChangeActionDel* pDel = static_cast<const ScChangeActionDel*>(pThisAction);
850 if ( pDel->IsTopDelete() && !pDel->IsTabDeleteCol() )
851 { // deleted Table enthaelt deleted Cols, die nicht
852 sal_uLong nStart, nEnd;
853 pSourceTrack->AppendDeleteRange(
854 pDel->GetOverAllRange().MakeRange(), NULL, nStart, nEnd );
857 break;
858 case SC_CAT_MOVE :
860 const ScChangeActionMove* pMove = static_cast<const ScChangeActionMove*>(pThisAction);
861 pSourceTrack->AppendMove( pMove->GetFromRange().MakeRange(),
862 pMove->GetBigRange().MakeRange(), NULL );
864 break;
865 default:
867 // added to avoid warnings
871 pThisAction = pThisAction->GetNext();
874 LockPaint(); // #i73877# no repainting after each action
876 // MergeChangeData in das aktuelle Dokument uebernehmen
877 bool bHasRejected = false;
878 OUString aOldUser = pThisTrack->GetUser();
879 pThisTrack->SetUseFixDateTime( true );
880 ScMarkData& rMarkData = pViewSh->GetViewData().GetMarkData();
881 ScMarkData aOldMarkData( rMarkData );
882 pSourceAction = pFirstMergeAction;
883 while ( pSourceAction && pSourceAction->GetActionNumber() <= nLastMergeAction )
885 bool bMergeAction = false;
886 if ( bShared )
888 if ( !bCheckDuplicates || !lcl_FindAction( &rOtherDoc, pSourceAction, &aDocument, pFirstSearchAction, pLastSearchAction, bIgnore100Sec ) )
890 bMergeAction = true;
893 else
895 if ( !ScChangeTrack::MergeIgnore( *pSourceAction, nFirstNewNumber ) )
897 bMergeAction = true;
901 if ( bMergeAction )
903 ScChangeActionType eSourceType = pSourceAction->GetType();
904 if ( !bShared && pSourceAction->IsDeletedIn() )
906 //! muss hier noch festgestellt werden, ob wirklich in
907 //! _diesem_ Dokument geloescht?
909 // liegt in einem Bereich, der in diesem Dokument geloescht wurde
910 // -> wird weggelassen
911 //! ??? Loesch-Aktion rueckgaengig machen ???
912 //! ??? Aktion irgendwo anders speichern ???
913 #if OSL_DEBUG_LEVEL > 0
914 OUString aValue;
915 if ( eSourceType == SC_CAT_CONTENT )
916 static_cast<const ScChangeActionContent*>(pSourceAction)->GetNewString( aValue, &aDocument );
917 OStringBuffer aError(OUStringToOString(aValue,
918 osl_getThreadTextEncoding()));
919 aError.append(" weggelassen");
920 OSL_FAIL( aError.getStr() );
921 #endif
923 else
925 //! Datum/Autor/Kommentar der Source-Aktion uebernehmen!
927 pThisTrack->SetUser( pSourceAction->GetUser() );
928 pThisTrack->SetFixDateTimeUTC( pSourceAction->GetDateTimeUTC() );
929 sal_uLong nOldActionMax = pThisTrack->GetActionMax();
931 bool bExecute = true;
932 sal_uLong nReject = pSourceAction->GetRejectAction();
933 if ( nReject )
935 if ( bShared )
937 if ( nReject >= nFirstNewNumber )
939 nReject += nOffset;
941 ScChangeAction* pOldAction = pThisTrack->GetAction( nReject );
942 if ( pOldAction && pOldAction->IsVirgin() )
944 pThisTrack->Reject( pOldAction );
945 bHasRejected = true;
946 bExecute = false;
949 else
951 // alte Aktion (aus den gemeinsamen) ablehnen
952 ScChangeAction* pOldAction = pThisTrack->GetAction( nReject );
953 if (pOldAction && pOldAction->GetState() == SC_CAS_VIRGIN)
955 //! was passiert bei Aktionen, die in diesem Dokument accepted worden sind???
956 //! Fehlermeldung oder was???
957 //! oder Reject-Aenderung normal ausfuehren
959 pThisTrack->Reject(pOldAction);
960 bHasRejected = true; // fuer Paint
962 bExecute = false;
966 if ( bExecute )
968 // normal ausfuehren
969 ScRange aSourceRange = pSourceAction->GetBigRange().MakeRange();
970 rMarkData.SelectOneTable( aSourceRange.aStart.Tab() );
971 switch ( eSourceType )
973 case SC_CAT_CONTENT:
975 //! Test, ob es ganz unten im Dokument war, dann automatisches
976 //! Zeilen-Einfuegen ???
978 OSL_ENSURE( aSourceRange.aStart == aSourceRange.aEnd, "huch?" );
979 ScAddress aPos = aSourceRange.aStart;
980 OUString aValue;
981 static_cast<const ScChangeActionContent*>(pSourceAction)->GetNewString( aValue, &aDocument );
982 sal_uInt8 eMatrix = MM_NONE;
983 const ScCellValue& rCell = static_cast<const ScChangeActionContent*>(pSourceAction)->GetNewCell();
984 if (rCell.meType == CELLTYPE_FORMULA)
985 eMatrix = rCell.mpFormula->GetMatrixFlag();
986 switch ( eMatrix )
988 case MM_NONE :
989 pViewSh->EnterData( aPos.Col(), aPos.Row(), aPos.Tab(), aValue );
990 break;
991 case MM_FORMULA :
993 SCCOL nCols;
994 SCROW nRows;
995 rCell.mpFormula->GetMatColsRows(nCols, nRows);
996 aSourceRange.aEnd.SetCol( aPos.Col() + nCols - 1 );
997 aSourceRange.aEnd.SetRow( aPos.Row() + nRows - 1 );
998 aValue = aValue.copy(1, aValue.getLength()-2); // remove the 1st and last characters.
999 GetDocFunc().EnterMatrix( aSourceRange,
1000 NULL, NULL, aValue, false, false,
1001 EMPTY_OUSTRING, formula::FormulaGrammar::GRAM_DEFAULT );
1003 break;
1004 case MM_REFERENCE : // do nothing
1005 break;
1006 case MM_FAKE :
1007 OSL_FAIL( "MergeDocument: MatrixFlag MM_FAKE" );
1008 pViewSh->EnterData( aPos.Col(), aPos.Row(), aPos.Tab(), aValue );
1009 break;
1010 default:
1011 OSL_FAIL( "MergeDocument: unknown MatrixFlag" );
1014 break;
1015 case SC_CAT_INSERT_TABS :
1017 OUString aName;
1018 aDocument.CreateValidTabName( aName );
1019 GetDocFunc().InsertTable( aSourceRange.aStart.Tab(), aName, true, false );
1021 break;
1022 case SC_CAT_INSERT_ROWS:
1023 GetDocFunc().InsertCells( aSourceRange, NULL, INS_INSROWS, true, false );
1024 break;
1025 case SC_CAT_INSERT_COLS:
1026 GetDocFunc().InsertCells( aSourceRange, NULL, INS_INSCOLS, true, false );
1027 break;
1028 case SC_CAT_DELETE_TABS :
1029 GetDocFunc().DeleteTable( aSourceRange.aStart.Tab(), true, false );
1030 break;
1031 case SC_CAT_DELETE_ROWS:
1033 const ScChangeActionDel* pDel = static_cast<const ScChangeActionDel*>(pSourceAction);
1034 if ( pDel->IsTopDelete() )
1036 aSourceRange = pDel->GetOverAllRange().MakeRange();
1037 GetDocFunc().DeleteCells( aSourceRange, NULL, DEL_DELROWS, true, false );
1039 // #i101099# [Collaboration] Changes are not correctly shown
1040 if ( bShared )
1042 ScChangeAction* pAct = pThisTrack->GetLast();
1043 if ( pAct && pAct->GetType() == eSourceType && pAct->IsDeletedIn() && !pSourceAction->IsDeletedIn() )
1045 pAct->RemoveAllDeletedIn();
1050 break;
1051 case SC_CAT_DELETE_COLS:
1053 const ScChangeActionDel* pDel = static_cast<const ScChangeActionDel*>(pSourceAction);
1054 if ( pDel->IsTopDelete() && !pDel->IsTabDeleteCol() )
1055 { // deleted Table enthaelt deleted Cols, die nicht
1056 aSourceRange = pDel->GetOverAllRange().MakeRange();
1057 GetDocFunc().DeleteCells( aSourceRange, NULL, DEL_DELCOLS, true, false );
1060 break;
1061 case SC_CAT_MOVE :
1063 const ScChangeActionMove* pMove = static_cast<const ScChangeActionMove*>(pSourceAction);
1064 ScRange aFromRange( pMove->GetFromRange().MakeRange() );
1065 GetDocFunc().MoveBlock( aFromRange,
1066 aSourceRange.aStart, true, true, false, false );
1068 break;
1069 default:
1071 // added to avoid warnings
1075 const OUString& rComment = pSourceAction->GetComment();
1076 if ( !rComment.isEmpty() )
1078 ScChangeAction* pAct = pThisTrack->GetLast();
1079 if ( pAct && pAct->GetActionNumber() > nOldActionMax )
1080 pAct->SetComment( rComment );
1081 else
1082 OSL_FAIL( "MergeDocument: wohin mit dem Kommentar?!?" );
1085 // Referenzen anpassen
1086 pSourceTrack->MergeOwn( const_cast<ScChangeAction*>(pSourceAction), nFirstNewNumber, bShared );
1088 // merge action state
1089 if ( bShared && !pSourceAction->IsRejected() )
1091 ScChangeAction* pAct = pThisTrack->GetLast();
1092 if ( pAct && pAct->GetActionNumber() > nOldActionMax )
1094 ScChangeTrack::MergeActionState( pAct, pSourceAction );
1098 // fill merge map
1099 if ( bShared && pMergeMap )
1101 ScChangeAction* pAct = pThisTrack->GetLast();
1102 if ( pAct && pAct->GetActionNumber() > nOldActionMax )
1104 sal_uLong nActionMax = pAct->GetActionNumber();
1105 sal_uLong nActionCount = nActionMax - nOldActionMax;
1106 sal_uLong nAction = nActionMax - nActionCount + 1;
1107 sal_uLong nSourceAction = pSourceAction->GetActionNumber() - nActionCount + 1;
1108 while ( nAction <= nActionMax )
1110 if ( bInverseMap )
1112 (*pMergeMap)[ nAction++ ] = nSourceAction++;
1114 else
1116 (*pMergeMap)[ nSourceAction++ ] = nAction++;
1122 aProgress.SetStateCountDown( --nNewActionCount );
1124 pSourceAction = pSourceAction->GetNext();
1127 rMarkData = aOldMarkData;
1128 pThisTrack->SetUser(aOldUser);
1129 pThisTrack->SetUseFixDateTime( false );
1131 pSourceTrack->Clear(); //! der ist jetzt verhunzt
1133 if (bHasRejected)
1134 PostPaintGridAll(); // Reject() paintet nicht selber
1136 UnlockPaint();
1139 bool ScDocShell::MergeSharedDocument( ScDocShell* pSharedDocShell )
1141 if ( !pSharedDocShell )
1143 return false;
1146 ScChangeTrack* pThisTrack = aDocument.GetChangeTrack();
1147 if ( !pThisTrack )
1149 return false;
1152 ScDocument& rSharedDoc = pSharedDocShell->GetDocument();
1153 ScChangeTrack* pSharedTrack = rSharedDoc.GetChangeTrack();
1154 if ( !pSharedTrack )
1156 return false;
1159 // reset show changes
1160 ScChangeViewSettings aChangeViewSet;
1161 aChangeViewSet.SetShowChanges( false );
1162 aDocument.SetChangeViewSettings( aChangeViewSet );
1164 // find first merge action in this document
1165 bool bIgnore100Sec = !pThisTrack->IsTimeNanoSeconds() || !pSharedTrack->IsTimeNanoSeconds();
1166 ScChangeAction* pThisAction = pThisTrack->GetFirst();
1167 ScChangeAction* pSharedAction = pSharedTrack->GetFirst();
1168 while ( lcl_Equal( pThisAction, pSharedAction, bIgnore100Sec ) )
1170 pThisAction = pThisAction->GetNext();
1171 pSharedAction = pSharedAction->GetNext();
1174 if ( pSharedAction )
1176 if ( pThisAction )
1178 // merge own changes into shared document
1179 sal_uLong nActStartShared = pSharedAction->GetActionNumber();
1180 sal_uLong nActEndShared = pSharedTrack->GetActionMax();
1181 ScDocument* pTmpDoc = new ScDocument;
1182 for ( sal_Int32 nIndex = 0; nIndex < aDocument.GetTableCount(); ++nIndex )
1184 OUString sTabName;
1185 pTmpDoc->CreateValidTabName( sTabName );
1186 pTmpDoc->InsertTab( SC_TAB_APPEND, sTabName );
1188 aDocument.GetChangeTrack()->Clone( pTmpDoc );
1189 ScChangeActionMergeMap aOwnInverseMergeMap;
1190 pSharedDocShell->MergeDocument( *pTmpDoc, true, true, 0, &aOwnInverseMergeMap, true );
1191 delete pTmpDoc;
1192 sal_uLong nActStartOwn = nActEndShared + 1;
1193 sal_uLong nActEndOwn = pSharedTrack->GetActionMax();
1195 // find conflicts
1196 ScConflictsList aConflictsList;
1197 ScConflictsFinder aFinder( pSharedTrack, nActStartShared, nActEndShared, nActStartOwn, nActEndOwn, aConflictsList );
1198 if ( aFinder.Find() )
1200 ScConflictsListHelper::TransformConflictsList( aConflictsList, NULL, &aOwnInverseMergeMap );
1201 bool bLoop = true;
1202 while ( bLoop )
1204 bLoop = false;
1205 ScopedVclPtrInstance< ScConflictsDlg > aDlg( GetActiveDialogParent(), GetViewData(), &rSharedDoc, aConflictsList );
1206 if ( aDlg->Execute() == RET_CANCEL )
1208 ScopedVclPtrInstance<QueryBox> aBox( GetActiveDialogParent(), WinBits( WB_YES_NO | WB_DEF_YES ),
1209 ScGlobal::GetRscString( STR_DOC_WILLNOTBESAVED ) );
1210 if ( aBox->Execute() == RET_YES )
1212 return false;
1214 else
1216 bLoop = true;
1222 // undo own changes in shared document
1223 pSharedTrack->Undo( nActStartOwn, nActEndOwn );
1225 // clone change track for merging into own document
1226 pTmpDoc = new ScDocument;
1227 for ( sal_Int32 nIndex = 0; nIndex < aDocument.GetTableCount(); ++nIndex )
1229 OUString sTabName;
1230 pTmpDoc->CreateValidTabName( sTabName );
1231 pTmpDoc->InsertTab( SC_TAB_APPEND, sTabName );
1233 pThisTrack->Clone( pTmpDoc );
1235 // undo own changes since last save in own document
1236 sal_uLong nStartShared = pThisAction->GetActionNumber();
1237 ScChangeAction* pAction = pThisTrack->GetLast();
1238 while ( pAction && pAction->GetActionNumber() >= nStartShared )
1240 pThisTrack->Reject( pAction, true );
1241 pAction = pAction->GetPrev();
1244 // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
1245 pThisTrack->Undo( nStartShared, pThisTrack->GetActionMax(), true );
1247 // merge shared changes into own document
1248 ScChangeActionMergeMap aSharedMergeMap;
1249 MergeDocument( rSharedDoc, true, true, 0, &aSharedMergeMap );
1250 sal_uLong nEndShared = pThisTrack->GetActionMax();
1252 // resolve conflicts for shared non-content actions
1253 if ( !aConflictsList.empty() )
1255 ScConflictsListHelper::TransformConflictsList( aConflictsList, &aSharedMergeMap, NULL );
1256 ScConflictsResolver aResolver( pThisTrack, aConflictsList );
1257 pAction = pThisTrack->GetAction( nEndShared );
1258 while ( pAction && pAction->GetActionNumber() >= nStartShared )
1260 aResolver.HandleAction( pAction, true /*bIsSharedAction*/,
1261 false /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
1262 pAction = pAction->GetPrev();
1265 nEndShared = pThisTrack->GetActionMax();
1267 // only show changes from shared document
1268 aChangeViewSet.SetShowChanges( true );
1269 aChangeViewSet.SetShowAccepted( true );
1270 aChangeViewSet.SetHasActionRange( true );
1271 aChangeViewSet.SetTheActionRange( nStartShared, nEndShared );
1272 aDocument.SetChangeViewSettings( aChangeViewSet );
1274 // merge own changes back into own document
1275 sal_uLong nStartOwn = nEndShared + 1;
1276 ScChangeActionMergeMap aOwnMergeMap;
1277 MergeDocument( *pTmpDoc, true, true, nEndShared - nStartShared + 1, &aOwnMergeMap );
1278 delete pTmpDoc;
1279 sal_uLong nEndOwn = pThisTrack->GetActionMax();
1281 // resolve conflicts for shared content actions and own actions
1282 if ( !aConflictsList.empty() )
1284 ScConflictsListHelper::TransformConflictsList( aConflictsList, NULL, &aOwnMergeMap );
1285 ScConflictsResolver aResolver( pThisTrack, aConflictsList );
1286 pAction = pThisTrack->GetAction( nEndShared );
1287 while ( pAction && pAction->GetActionNumber() >= nStartShared )
1289 aResolver.HandleAction( pAction, true /*bIsSharedAction*/,
1290 true /*bHandleContentAction*/, false /*bHandleNonContentAction*/ );
1291 pAction = pAction->GetPrev();
1294 pAction = pThisTrack->GetAction( nEndOwn );
1295 while ( pAction && pAction->GetActionNumber() >= nStartOwn )
1297 aResolver.HandleAction( pAction, false /*bIsSharedAction*/,
1298 true /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
1299 pAction = pAction->GetPrev();
1302 nEndOwn = pThisTrack->GetActionMax();
1304 else
1306 // merge shared changes into own document
1307 sal_uLong nStartShared = pThisTrack->GetActionMax() + 1;
1308 MergeDocument( rSharedDoc, true, true );
1309 sal_uLong nEndShared = pThisTrack->GetActionMax();
1311 // only show changes from shared document
1312 aChangeViewSet.SetShowChanges( true );
1313 aChangeViewSet.SetShowAccepted( true );
1314 aChangeViewSet.SetHasActionRange( true );
1315 aChangeViewSet.SetTheActionRange( nStartShared, nEndShared );
1316 aDocument.SetChangeViewSettings( aChangeViewSet );
1319 // update view
1320 PostPaintExtras();
1321 PostPaintGridAll();
1323 ScopedVclPtrInstance< InfoBox > aInfoBox( GetActiveDialogParent(), ScGlobal::GetRscString( STR_DOC_UPDATED ) );
1324 aInfoBox->Execute();
1327 return ( pThisAction != NULL );
1330 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */