Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / docshell / docsh3.cxx
blobad2806d94c1c60a0df16e615f8ab6c18aab13ec8
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"
65 //------------------------------------------------------------------
68 // Redraw - Benachrichtigungen
72 void ScDocShell::PostEditView( ScEditEngineDefaulter* pEditEngine, const ScAddress& rCursorPos )
74 // Broadcast( ScEditViewHint( pEditEngine, rCursorPos ) );
76 // Test: nur aktive ViewShell
78 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
79 if (pViewSh && pViewSh->GetViewData()->GetDocShell() == this)
81 ScEditViewHint aHint( pEditEngine, rCursorPos );
82 pViewSh->Notify( *this, aHint );
86 void ScDocShell::PostDataChanged()
88 Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
89 SFX_APP()->Broadcast(SfxSimpleHint( FID_ANYDATACHANGED )); // Navigator
90 aDocument.CellContentModified();
91 //! Navigator direkt benachrichtigen!
94 void ScDocShell::PostPaint( SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab,
95 SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, sal_uInt16 nPart,
96 sal_uInt16 nExtFlags )
98 ScRange aRange(nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
99 PostPaint(aRange, nPart, nExtFlags);
102 void ScDocShell::PostPaint( const ScRangeList& rRanges, sal_uInt16 nPart, sal_uInt16 nExtFlags )
104 ScRangeList aPaintRanges;
105 for (size_t i = 0, n = rRanges.size(); i < n; ++i)
107 const ScRange& rRange = *rRanges[i];
108 SCCOL nCol1 = rRange.aStart.Col(), nCol2 = rRange.aEnd.Col();
109 SCROW nRow1 = rRange.aStart.Row(), nRow2 = rRange.aEnd.Row();
110 SCTAB nTab1 = rRange.aStart.Tab(), nTab2 = rRange.aEnd.Tab();
112 if (!ValidCol(nCol1)) nCol1 = MAXCOL;
113 if (!ValidRow(nRow1)) nRow1 = MAXROW;
114 if (!ValidCol(nCol2)) nCol2 = MAXCOL;
115 if (!ValidRow(nRow2)) nRow2 = MAXROW;
117 if ( pPaintLockData )
119 // #i54081# PAINT_EXTRAS still has to be broadcast because it changes the
120 // current sheet if it's invalid. All other flags added to pPaintLockData.
121 sal_uInt16 nLockPart = nPart & ~PAINT_EXTRAS;
122 if ( nLockPart )
124 //! nExtFlags ???
125 pPaintLockData->AddRange( ScRange( nCol1, nRow1, nTab1,
126 nCol2, nRow2, nTab2 ), nLockPart );
129 nPart &= PAINT_EXTRAS; // for broadcasting
130 if (!nPart)
131 continue;
135 if (nExtFlags & SC_PF_LINES) // Platz fuer Linien beruecksichtigen
137 //! Abfrage auf versteckte Spalten/Zeilen!
138 if (nCol1>0) --nCol1;
139 if (nCol2<MAXCOL) ++nCol2;
140 if (nRow1>0) --nRow1;
141 if (nRow2<MAXROW) ++nRow2;
144 // um zusammengefasste erweitern
145 if (nExtFlags & SC_PF_TESTMERGE)
146 aDocument.ExtendMerge( nCol1, nRow1, nCol2, nRow2, nTab1 );
148 if ( nCol1 != 0 || nCol2 != MAXCOL )
150 // Extend to whole rows if SC_PF_WHOLEROWS is set, or rotated or non-left
151 // aligned cells are contained (see UpdatePaintExt).
152 // Special handling for RTL text (#i9731#) is unnecessary now with full
153 // support of right-aligned text.
155 if ( ( nExtFlags & SC_PF_WHOLEROWS ) ||
156 aDocument.HasAttrib( nCol1,nRow1,nTab1,
157 MAXCOL,nRow2,nTab2, HASATTR_ROTATE | HASATTR_RIGHTORCENTER ) )
159 nCol1 = 0;
160 nCol2 = MAXCOL;
163 aPaintRanges.Append(ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2));
166 Broadcast(ScPaintHint(aPaintRanges.Combine(), nPart));
169 void ScDocShell::PostPaintGridAll()
171 PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
174 void ScDocShell::PostPaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
176 PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID, SC_PF_TESTMERGE );
179 void ScDocShell::PostPaintCell( const ScAddress& rPos )
181 PostPaintCell( rPos.Col(), rPos.Row(), rPos.Tab() );
184 void ScDocShell::PostPaintExtras()
186 PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS );
189 void ScDocShell::UpdatePaintExt( sal_uInt16& rExtFlags, const ScRange& rRange )
191 if ( ( rExtFlags & SC_PF_LINES ) == 0 && aDocument.HasAttrib( rRange, HASATTR_PAINTEXT ) )
193 // If the range contains lines, shadow or conditional formats,
194 // set SC_PF_LINES to include one extra cell in all directions.
196 rExtFlags |= SC_PF_LINES;
199 if ( ( rExtFlags & SC_PF_WHOLEROWS ) == 0 &&
200 ( rRange.aStart.Col() != 0 || rRange.aEnd.Col() != MAXCOL ) &&
201 aDocument.HasAttrib( rRange, HASATTR_ROTATE | HASATTR_RIGHTORCENTER ) )
203 // If the range contains (logically) right- or center-aligned cells,
204 // or rotated cells, set SC_PF_WHOLEROWS to paint the whole rows.
205 // This test isn't needed after the cell changes, because it's also
206 // tested in PostPaint. UpdatePaintExt may later be changed to do this
207 // only if called before the changes.
209 rExtFlags |= SC_PF_WHOLEROWS;
213 void ScDocShell::UpdatePaintExt( sal_uInt16& rExtFlags, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab,
214 SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab )
216 UpdatePaintExt( rExtFlags, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ) );
219 //------------------------------------------------------------------
221 void ScDocShell::LockPaint_Impl(sal_Bool bDoc)
223 if ( !pPaintLockData )
224 pPaintLockData = new ScPaintLockData;
225 pPaintLockData->IncLevel(bDoc);
228 void ScDocShell::UnlockPaint_Impl(sal_Bool bDoc)
230 if ( pPaintLockData )
232 if ( pPaintLockData->GetLevel(bDoc) )
233 pPaintLockData->DecLevel(bDoc);
234 if (!pPaintLockData->GetLevel(!bDoc) && !pPaintLockData->GetLevel(bDoc))
236 // Paint jetzt ausfuehren
238 ScPaintLockData* pPaint = pPaintLockData;
239 pPaintLockData = NULL; // nicht weitersammeln
241 ScRangeListRef xRangeList = pPaint->GetRangeList();
242 if (xRangeList)
244 sal_uInt16 nParts = pPaint->GetParts();
245 for ( size_t i = 0, nCount = xRangeList->size(); i < nCount; i++ )
247 //! nExtFlags ???
248 ScRange aRange = *(*xRangeList)[i];
249 PostPaint( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab(),
250 aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab(),
251 nParts );
255 if ( pPaint->GetModified() )
256 SetDocumentModified();
258 delete pPaint;
261 else
263 OSL_FAIL("UnlockPaint ohne LockPaint");
267 void ScDocShell::LockDocument_Impl(sal_uInt16 nNew)
269 if (!nDocumentLock)
271 ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
272 if (pDrawLayer)
273 pDrawLayer->setLock(true);
275 nDocumentLock = nNew;
278 void ScDocShell::UnlockDocument_Impl(sal_uInt16 nNew)
280 nDocumentLock = nNew;
281 if (!nDocumentLock)
283 ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
284 if (pDrawLayer)
285 pDrawLayer->setLock(false);
289 sal_uInt16 ScDocShell::GetLockCount() const
291 return nDocumentLock;
294 void ScDocShell::SetLockCount(sal_uInt16 nNew)
296 if (nNew) // setzen
298 if ( !pPaintLockData )
299 pPaintLockData = new ScPaintLockData;
300 pPaintLockData->SetLevel(nNew-1, sal_True);
301 LockDocument_Impl(nNew);
303 else if (pPaintLockData) // loeschen
305 pPaintLockData->SetLevel(0, sal_True); // bei Unlock sofort ausfuehren
306 UnlockPaint_Impl(sal_True); // jetzt
307 UnlockDocument_Impl(0);
311 void ScDocShell::LockPaint()
313 LockPaint_Impl(false);
316 void ScDocShell::UnlockPaint()
318 UnlockPaint_Impl(false);
321 void ScDocShell::LockDocument()
323 LockPaint_Impl(sal_True);
324 LockDocument_Impl(nDocumentLock + 1);
327 void ScDocShell::UnlockDocument()
329 if (nDocumentLock)
331 UnlockPaint_Impl(sal_True);
332 UnlockDocument_Impl(nDocumentLock - 1);
334 else
336 OSL_FAIL("UnlockDocument without LockDocument");
340 //------------------------------------------------------------------
342 void ScDocShell::SetInplace( bool bInplace )
344 if (bIsInplace != bInplace)
346 bIsInplace = bInplace;
347 CalcOutputFactor();
351 void ScDocShell::CalcOutputFactor()
353 if (bIsInplace)
355 nPrtToScreenFactor = 1.0; // passt sonst nicht zur inaktiven Darstellung
356 return;
359 sal_Bool bTextWysiwyg = SC_MOD()->GetInputOptions().GetTextWysiwyg();
360 if (bTextWysiwyg)
362 nPrtToScreenFactor = 1.0;
363 return;
366 OUString aTestString(
367 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789");
368 long nPrinterWidth = 0;
369 long nWindowWidth = 0;
370 const ScPatternAttr* pPattern = (const ScPatternAttr*)&aDocument.GetPool()->
371 GetDefaultItem(ATTR_PATTERN);
373 Font aDefFont;
374 OutputDevice* pRefDev = GetRefDevice();
375 MapMode aOldMode = pRefDev->GetMapMode();
376 Font aOldFont = pRefDev->GetFont();
378 pRefDev->SetMapMode(MAP_PIXEL);
379 pPattern->GetFont(aDefFont, SC_AUTOCOL_BLACK, pRefDev); // font color doesn't matter here
380 pRefDev->SetFont(aDefFont);
381 nPrinterWidth = pRefDev->PixelToLogic( Size( pRefDev->GetTextWidth(aTestString), 0 ), MAP_100TH_MM ).Width();
382 pRefDev->SetFont(aOldFont);
383 pRefDev->SetMapMode(aOldMode);
385 VirtualDevice aVirtWindow( *Application::GetDefaultDevice() );
386 aVirtWindow.SetMapMode(MAP_PIXEL);
387 pPattern->GetFont(aDefFont, SC_AUTOCOL_BLACK, &aVirtWindow); // font color doesn't matter here
388 aVirtWindow.SetFont(aDefFont);
389 nWindowWidth = aVirtWindow.GetTextWidth(aTestString);
390 nWindowWidth = (long) ( nWindowWidth / ScGlobal::nScreenPPTX * HMM_PER_TWIPS );
392 if (nPrinterWidth && nWindowWidth)
393 nPrtToScreenFactor = nPrinterWidth / (double) nWindowWidth;
394 else
396 OSL_FAIL("GetTextSize gibt 0 ??");
397 nPrtToScreenFactor = 1.0;
401 double ScDocShell::GetOutputFactor() const
403 return nPrtToScreenFactor;
406 //---------------------------------------------------------------------
408 void ScDocShell::InitOptions(bool bForLoading) // called from InitNew and Load
410 // Einstellungen aus dem SpellCheckCfg kommen in Doc- und ViewOptions
412 sal_uInt16 nDefLang, nCjkLang, nCtlLang;
413 sal_Bool bAutoSpell;
414 ScModule::GetSpellSettings( nDefLang, nCjkLang, nCtlLang, bAutoSpell );
415 ScModule* pScMod = SC_MOD();
417 ScDocOptions aDocOpt = pScMod->GetDocOptions();
418 ScFormulaOptions aFormulaOpt = pScMod->GetFormulaOptions();
419 ScViewOptions aViewOpt = pScMod->GetViewOptions();
420 aDocOpt.SetAutoSpell( bAutoSpell );
422 // zweistellige Jahreszahleneingabe aus Extras->Optionen->Allgemein->Sonstiges
423 aDocOpt.SetYear2000( sal::static_int_cast<sal_uInt16>( ::utl::MiscCfg().GetYear2000() ) );
425 if (bForLoading)
427 // #i112123# No style:decimal-places attribute means automatic decimals, not the configured default,
428 // so it must not be taken from the global options.
429 // Calculation settings are handled separately in ScXMLBodyContext::EndElement.
430 aDocOpt.SetStdPrecision( SvNumberFormatter::UNLIMITED_PRECISION );
433 aDocument.SetDocOptions( aDocOpt );
434 aDocument.SetViewOptions( aViewOpt );
435 SetFormulaOptions( aFormulaOpt );
437 // Druck-Optionen werden jetzt direkt vor dem Drucken gesetzt
439 aDocument.SetLanguage( (LanguageType) nDefLang, (LanguageType) nCjkLang, (LanguageType) nCtlLang );
442 //---------------------------------------------------------------------
444 Printer* ScDocShell::GetDocumentPrinter() // fuer OLE
446 return aDocument.GetPrinter();
449 SfxPrinter* ScDocShell::GetPrinter(sal_Bool bCreateIfNotExist)
451 return aDocument.GetPrinter(bCreateIfNotExist);
454 void ScDocShell::UpdateFontList()
456 delete pImpl->pFontList;
457 // pImpl->pFontList = new FontList( GetPrinter(), Application::GetDefaultDevice() );
458 pImpl->pFontList = new FontList( GetRefDevice(), NULL, false ); // sal_False or sal_True???
459 SvxFontListItem aFontListItem( pImpl->pFontList, SID_ATTR_CHAR_FONTLIST );
460 PutItem( aFontListItem );
462 CalcOutputFactor();
465 OutputDevice* ScDocShell::GetRefDevice()
467 return aDocument.GetRefDevice();
470 sal_uInt16 ScDocShell::SetPrinter( SfxPrinter* pNewPrinter, sal_uInt16 nDiffFlags )
472 SfxPrinter *pOld = aDocument.GetPrinter( false );
473 if ( pOld && pOld->IsPrinting() )
474 return SFX_PRINTERROR_BUSY;
476 if (nDiffFlags & SFX_PRINTER_PRINTER)
478 if ( aDocument.GetPrinter() != pNewPrinter )
480 aDocument.SetPrinter( pNewPrinter );
481 aDocument.SetPrintOptions();
483 // MT: Use UpdateFontList: Will use Printer fonts only if needed!
485 delete pImpl->pFontList;
486 pImpl->pFontList = new FontList( pNewPrinter, Application::GetDefaultDevice() );
487 SvxFontListItem aFontListItem( pImpl->pFontList, SID_ATTR_CHAR_FONTLIST );
488 PutItem( aFontListItem );
490 CalcOutputFactor();
492 if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
493 UpdateFontList();
495 ScModule* pScMod = SC_MOD();
496 SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this );
497 while (pFrame)
499 SfxViewShell* pSh = pFrame->GetViewShell();
500 if (pSh && pSh->ISA(ScTabViewShell))
502 ScTabViewShell* pViewSh = (ScTabViewShell*)pSh;
503 ScInputHandler* pInputHdl = pScMod->GetInputHdl(pViewSh);
504 if (pInputHdl)
505 pInputHdl->UpdateRefDevice();
507 pFrame = SfxViewFrame::GetNext( *pFrame, this );
511 else if (nDiffFlags & SFX_PRINTER_JOBSETUP)
513 SfxPrinter* pOldPrinter = aDocument.GetPrinter();
514 if (pOldPrinter)
516 pOldPrinter->SetJobSetup( pNewPrinter->GetJobSetup() );
518 // #i6706# Call SetPrinter with the old printer again, so the drawing layer
519 // RefDevice is set (calling ReformatAllTextObjects and rebuilding charts),
520 // because the JobSetup (printer device settings) may affect text layout.
521 aDocument.SetPrinter( pOldPrinter );
522 CalcOutputFactor(); // also with the new settings
526 if (nDiffFlags & SFX_PRINTER_OPTIONS)
528 aDocument.SetPrintOptions(); //! aus neuem Printer ???
531 if (nDiffFlags & (SFX_PRINTER_CHG_ORIENTATION | SFX_PRINTER_CHG_SIZE))
533 OUString aStyle = aDocument.GetPageStyle( GetCurTab() );
534 ScStyleSheetPool* pStPl = aDocument.GetStyleSheetPool();
535 SfxStyleSheet* pStyleSheet = (SfxStyleSheet*)pStPl->Find(aStyle, SFX_STYLE_FAMILY_PAGE);
536 if (pStyleSheet)
538 SfxItemSet& rSet = pStyleSheet->GetItemSet();
540 if (nDiffFlags & SFX_PRINTER_CHG_ORIENTATION)
542 const SvxPageItem& rOldItem = (const SvxPageItem&)rSet.Get(ATTR_PAGE);
543 sal_Bool bWasLand = rOldItem.IsLandscape();
544 sal_Bool bNewLand = ( pNewPrinter->GetOrientation() == ORIENTATION_LANDSCAPE );
545 if (bNewLand != bWasLand)
547 SvxPageItem aNewItem( rOldItem );
548 aNewItem.SetLandscape( bNewLand );
549 rSet.Put( aNewItem );
551 // Groesse umdrehen
552 Size aOldSize = ((const SvxSizeItem&)rSet.Get(ATTR_PAGE_SIZE)).GetSize();
553 Size aNewSize(aOldSize.Height(),aOldSize.Width());
554 SvxSizeItem aNewSItem(ATTR_PAGE_SIZE,aNewSize);
555 rSet.Put( aNewSItem );
558 if (nDiffFlags & SFX_PRINTER_CHG_SIZE)
560 SvxSizeItem aPaperSizeItem( ATTR_PAGE_SIZE, SvxPaperInfo::GetPaperSize(pNewPrinter) );
561 rSet.Put( aPaperSizeItem );
566 PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB,PAINT_ALL);
568 return 0;
571 //---------------------------------------------------------------------
573 ScChangeAction* ScDocShell::GetChangeAction( const ScAddress& rPos )
575 ScChangeTrack* pTrack = GetDocument()->GetChangeTrack();
576 if (!pTrack)
577 return NULL;
579 SCTAB nTab = rPos.Tab();
581 const ScChangeAction* pFound = NULL;
582 long nModified = 0;
583 const ScChangeAction* pAction = pTrack->GetFirst();
584 while (pAction)
586 ScChangeActionType eType = pAction->GetType();
587 //! ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc )...
588 if ( pAction->IsVisible() && eType != SC_CAT_DELETE_TABS )
590 const ScBigRange& rBig = pAction->GetBigRange();
591 if ( rBig.aStart.Tab() == nTab )
593 ScRange aRange = rBig.MakeRange();
595 if ( eType == SC_CAT_DELETE_ROWS )
596 aRange.aEnd.SetRow( aRange.aStart.Row() );
597 else if ( eType == SC_CAT_DELETE_COLS )
598 aRange.aEnd.SetCol( aRange.aStart.Col() );
600 if ( aRange.In( rPos ) )
602 pFound = pAction; // der letzte gewinnt
603 ++nModified;
606 if ( pAction->GetType() == SC_CAT_MOVE )
608 ScRange aRange =
609 ((const ScChangeActionMove*)pAction)->
610 GetFromRange().MakeRange();
611 if ( aRange.In( rPos ) )
613 pFound = pAction;
614 ++nModified;
618 pAction = pAction->GetNext();
621 return (ScChangeAction*)pFound;
624 void ScDocShell::SetChangeComment( ScChangeAction* pAction, const OUString& rComment )
626 if (pAction)
628 pAction->SetComment( rComment );
629 //! Undo ???
630 SetDocumentModified();
632 // Dialog-Notify
633 ScChangeTrack* pTrack = GetDocument()->GetChangeTrack();
634 if (pTrack)
636 sal_uLong nNumber = pAction->GetActionNumber();
637 pTrack->NotifyModified( SC_CTM_CHANGE, nNumber, nNumber );
642 void ScDocShell::ExecuteChangeCommentDialog( ScChangeAction* pAction, Window* pParent,sal_Bool bPrevNext)
644 if (!pAction) return; // ohne Aktion ist nichts..
646 OUString aComment = pAction->GetComment();
647 OUString aAuthor = pAction->GetUser();
649 DateTime aDT = pAction->GetDateTime();
650 OUString aDate = ScGlobal::pLocaleData->getDate( aDT );
651 aDate += " ";
652 aDate += ScGlobal::pLocaleData->getTime( aDT, false, false );
654 SfxItemSet aSet( GetPool(),
655 SID_ATTR_POSTIT_AUTHOR, SID_ATTR_POSTIT_AUTHOR,
656 SID_ATTR_POSTIT_DATE, SID_ATTR_POSTIT_DATE,
657 SID_ATTR_POSTIT_TEXT, SID_ATTR_POSTIT_TEXT,
658 0 );
660 aSet.Put( SvxPostItTextItem ( aComment, SID_ATTR_POSTIT_TEXT ) );
661 aSet.Put( SvxPostItAuthorItem( aAuthor, SID_ATTR_POSTIT_AUTHOR ) );
662 aSet.Put( SvxPostItDateItem ( aDate, SID_ATTR_POSTIT_DATE ) );
664 ScRedComDialog* pDlg = new ScRedComDialog( pParent, aSet,this,pAction,bPrevNext);
666 pDlg->Execute();
668 delete pDlg;
671 //---------------------------------------------------------------------
673 void ScDocShell::CompareDocument( ScDocument& rOtherDoc )
675 ScChangeTrack* pTrack = aDocument.GetChangeTrack();
676 if ( pTrack && pTrack->GetFirst() )
678 //! Changes vorhanden -> Nachfrage ob geloescht werden soll
681 aDocument.EndChangeTracking();
682 aDocument.StartChangeTracking();
684 OUString aOldUser;
685 pTrack = aDocument.GetChangeTrack();
686 if ( pTrack )
688 aOldUser = pTrack->GetUser();
690 // check if comparing to same document
692 OUString aThisFile;
693 const SfxMedium* pThisMed = GetMedium();
694 if (pThisMed)
695 aThisFile = pThisMed->GetName();
696 OUString aOtherFile;
697 SfxObjectShell* pOtherSh = rOtherDoc.GetDocumentShell();
698 if (pOtherSh)
700 const SfxMedium* pOtherMed = pOtherSh->GetMedium();
701 if (pOtherMed)
702 aOtherFile = pOtherMed->GetName();
704 sal_Bool bSameDoc = ( aThisFile == aOtherFile && !aThisFile.isEmpty() );
705 if ( !bSameDoc )
707 // create change actions from comparing with the name of the user
708 // who last saved the document
709 // (only if comparing different documents)
711 using namespace ::com::sun::star;
712 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
713 GetModel(), uno::UNO_QUERY_THROW);
714 uno::Reference<document::XDocumentProperties> xDocProps(
715 xDPS->getDocumentProperties());
716 OSL_ENSURE(xDocProps.is(), "no DocumentProperties");
717 OUString aDocUser = xDocProps->getModifiedBy();
719 if ( !aDocUser.isEmpty() )
720 pTrack->SetUser( aDocUser );
724 aDocument.CompareDocument( rOtherDoc );
726 pTrack = aDocument.GetChangeTrack();
727 if ( pTrack )
728 pTrack->SetUser( aOldUser );
730 PostPaintGridAll();
731 SetDocumentModified();
734 //---------------------------------------------------------------------
736 // Merge (Aenderungen zusammenfuehren)
738 //---------------------------------------------------------------------
740 static inline sal_Bool lcl_Equal( const ScChangeAction* pA, const ScChangeAction* pB, sal_Bool bIgnore100Sec )
742 return pA && pB &&
743 pA->GetActionNumber() == pB->GetActionNumber() &&
744 pA->GetType() == pB->GetType() &&
745 pA->GetUser() == pB->GetUser() &&
746 (bIgnore100Sec ?
747 pA->GetDateTimeUTC().IsEqualIgnoreNanoSec( pB->GetDateTimeUTC() ) :
748 pA->GetDateTimeUTC() == pB->GetDateTimeUTC());
749 // State nicht vergleichen, falls eine alte Aenderung akzeptiert wurde
752 static bool lcl_FindAction( ScDocument* pDoc, const ScChangeAction* pAction, ScDocument* pSearchDoc, const ScChangeAction* pFirstSearchAction, const ScChangeAction* pLastSearchAction, sal_Bool bIgnore100Sec )
754 if ( !pDoc || !pAction || !pSearchDoc || !pFirstSearchAction || !pLastSearchAction )
756 return false;
759 sal_uLong nLastSearchAction = pLastSearchAction->GetActionNumber();
760 const ScChangeAction* pA = pFirstSearchAction;
761 while ( pA && pA->GetActionNumber() <= nLastSearchAction )
763 if ( pAction->GetType() == pA->GetType() &&
764 pAction->GetUser() == pA->GetUser() &&
765 (bIgnore100Sec ?
766 pAction->GetDateTimeUTC().IsEqualIgnoreNanoSec( pA->GetDateTimeUTC() ) :
767 pAction->GetDateTimeUTC() == pA->GetDateTimeUTC() ) &&
768 pAction->GetBigRange() == pA->GetBigRange() )
770 OUString aActionDesc;
771 pAction->GetDescription(aActionDesc, pDoc, true);
772 OUString aADesc;
773 pA->GetDescription(aADesc, pSearchDoc, true);
774 if (aActionDesc.equals(aADesc))
776 OSL_FAIL( "lcl_FindAction(): found equal action!" );
777 return true;
780 pA = pA->GetNext();
783 return false;
786 void ScDocShell::MergeDocument( ScDocument& rOtherDoc, bool bShared, bool bCheckDuplicates, sal_uLong nOffset, ScChangeActionMergeMap* pMergeMap, bool bInverseMap )
788 ScTabViewShell* pViewSh = GetBestViewShell( false ); //! Funktionen an die DocShell
789 if (!pViewSh)
790 return;
792 ScChangeTrack* pSourceTrack = rOtherDoc.GetChangeTrack();
793 if (!pSourceTrack)
794 return; //! nichts zu tun - Fehlermeldung?
796 ScChangeTrack* pThisTrack = aDocument.GetChangeTrack();
797 if ( !pThisTrack )
798 { // anschalten
799 aDocument.StartChangeTracking();
800 pThisTrack = aDocument.GetChangeTrack();
801 OSL_ENSURE(pThisTrack,"ChangeTracking nicht angeschaltet?");
802 if ( !bShared )
804 // visuelles RedLining einschalten
805 ScChangeViewSettings aChangeViewSet;
806 aChangeViewSet.SetShowChanges(sal_True);
807 aDocument.SetChangeViewSettings(aChangeViewSet);
811 // include Nano seconds in compare?
812 sal_Bool bIgnore100Sec = !pSourceTrack->IsTimeNanoSeconds() ||
813 !pThisTrack->IsTimeNanoSeconds();
815 // gemeinsame Ausgangsposition suchen
816 sal_uLong nFirstNewNumber = 0;
817 const ScChangeAction* pSourceAction = pSourceTrack->GetFirst();
818 const ScChangeAction* pThisAction = pThisTrack->GetFirst();
819 // skip identical actions
820 while ( lcl_Equal( pSourceAction, pThisAction, bIgnore100Sec ) )
822 nFirstNewNumber = pSourceAction->GetActionNumber() + 1;
823 pSourceAction = pSourceAction->GetNext();
824 pThisAction = pThisAction->GetNext();
826 // pSourceAction und pThisAction zeigen jetzt auf die ersten "eigenen" Aktionen
827 // Die gemeinsamen Aktionen davor interessieren ueberhaupt nicht
829 //! Abfrage, ob die Dokumente vor dem Change-Tracking gleich waren !!!
832 const ScChangeAction* pFirstMergeAction = pSourceAction;
833 const ScChangeAction* pFirstSearchAction = pThisAction;
835 // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
836 const ScChangeAction* pLastSearchAction = pThisTrack->GetLast();
838 // MergeChangeData aus den folgenden Aktionen erzeugen
839 sal_uLong nNewActionCount = 0;
840 const ScChangeAction* pCount = pSourceAction;
841 while ( pCount )
843 if ( bShared || !ScChangeTrack::MergeIgnore( *pCount, nFirstNewNumber ) )
844 ++nNewActionCount;
845 pCount = pCount->GetNext();
847 if (!nNewActionCount)
848 return; //! nichts zu tun - Fehlermeldung?
849 // ab hier kein return mehr
851 ScProgress aProgress( this, OUString("..."),
852 nNewActionCount );
854 sal_uLong nLastMergeAction = pSourceTrack->GetLast()->GetActionNumber();
855 // UpdateReference-Undo, gueltige Referenzen fuer den letzten gemeinsamen Zustand
856 pSourceTrack->MergePrepare( (ScChangeAction*) pFirstMergeAction, bShared );
858 // MergeChangeData an alle noch folgenden Aktionen in diesem Dokument anpassen
859 // -> Referenzen gueltig fuer dieses Dokument
860 while ( pThisAction )
862 // #i87049# [Collaboration] Conflict between delete row and insert content is not merged correctly
863 if ( !bShared || !ScChangeTrack::MergeIgnore( *pThisAction, nFirstNewNumber ) )
865 ScChangeActionType eType = pThisAction->GetType();
866 switch ( eType )
868 case SC_CAT_INSERT_COLS :
869 case SC_CAT_INSERT_ROWS :
870 case SC_CAT_INSERT_TABS :
871 pSourceTrack->AppendInsert( pThisAction->GetBigRange().MakeRange() );
872 break;
873 case SC_CAT_DELETE_COLS :
874 case SC_CAT_DELETE_ROWS :
875 case SC_CAT_DELETE_TABS :
877 const ScChangeActionDel* pDel = (const ScChangeActionDel*) pThisAction;
878 if ( pDel->IsTopDelete() && !pDel->IsTabDeleteCol() )
879 { // deleted Table enthaelt deleted Cols, die nicht
880 sal_uLong nStart, nEnd;
881 pSourceTrack->AppendDeleteRange(
882 pDel->GetOverAllRange().MakeRange(), NULL, nStart, nEnd );
885 break;
886 case SC_CAT_MOVE :
888 const ScChangeActionMove* pMove = (const ScChangeActionMove*) pThisAction;
889 pSourceTrack->AppendMove( pMove->GetFromRange().MakeRange(),
890 pMove->GetBigRange().MakeRange(), NULL );
892 break;
893 default:
895 // added to avoid warnings
899 pThisAction = pThisAction->GetNext();
902 LockPaint(); // #i73877# no repainting after each action
904 // MergeChangeData in das aktuelle Dokument uebernehmen
905 sal_Bool bHasRejected = false;
906 OUString aOldUser = pThisTrack->GetUser();
907 pThisTrack->SetUseFixDateTime( sal_True );
908 ScMarkData& rMarkData = pViewSh->GetViewData()->GetMarkData();
909 ScMarkData aOldMarkData( rMarkData );
910 pSourceAction = pFirstMergeAction;
911 while ( pSourceAction && pSourceAction->GetActionNumber() <= nLastMergeAction )
913 bool bMergeAction = false;
914 if ( bShared )
916 if ( !bCheckDuplicates || !lcl_FindAction( &rOtherDoc, pSourceAction, &aDocument, pFirstSearchAction, pLastSearchAction, bIgnore100Sec ) )
918 bMergeAction = true;
921 else
923 if ( !ScChangeTrack::MergeIgnore( *pSourceAction, nFirstNewNumber ) )
925 bMergeAction = true;
929 if ( bMergeAction )
931 ScChangeActionType eSourceType = pSourceAction->GetType();
932 if ( !bShared && pSourceAction->IsDeletedIn() )
934 //! muss hier noch festgestellt werden, ob wirklich in
935 //! _diesem_ Dokument geloescht?
937 // liegt in einem Bereich, der in diesem Dokument geloescht wurde
938 // -> wird weggelassen
939 //! ??? Loesch-Aktion rueckgaengig machen ???
940 //! ??? Aktion irgendwo anders speichern ???
941 #if OSL_DEBUG_LEVEL > 0
942 OUString aValue;
943 if ( eSourceType == SC_CAT_CONTENT )
944 ((const ScChangeActionContent*)pSourceAction)->GetNewString( aValue, &aDocument );
945 OStringBuffer aError(OUStringToOString(aValue,
946 osl_getThreadTextEncoding()));
947 aError.append(" weggelassen");
948 OSL_FAIL( aError.getStr() );
949 #endif
951 else
953 //! Datum/Autor/Kommentar der Source-Aktion uebernehmen!
955 pThisTrack->SetUser( pSourceAction->GetUser() );
956 pThisTrack->SetFixDateTimeUTC( pSourceAction->GetDateTimeUTC() );
957 sal_uLong nOldActionMax = pThisTrack->GetActionMax();
959 bool bExecute = true;
960 sal_uLong nReject = pSourceAction->GetRejectAction();
961 if ( nReject )
963 if ( bShared )
965 if ( nReject >= nFirstNewNumber )
967 nReject += nOffset;
969 ScChangeAction* pOldAction = pThisTrack->GetAction( nReject );
970 if ( pOldAction && pOldAction->IsVirgin() )
972 pThisTrack->Reject( pOldAction );
973 bHasRejected = sal_True;
974 bExecute = false;
977 else
979 // alte Aktion (aus den gemeinsamen) ablehnen
980 ScChangeAction* pOldAction = pThisTrack->GetAction( nReject );
981 if (pOldAction && pOldAction->GetState() == SC_CAS_VIRGIN)
983 //! was passiert bei Aktionen, die in diesem Dokument accepted worden sind???
984 //! Fehlermeldung oder was???
985 //! oder Reject-Aenderung normal ausfuehren
987 pThisTrack->Reject(pOldAction);
988 bHasRejected = sal_True; // fuer Paint
990 bExecute = false;
994 if ( bExecute )
996 // normal ausfuehren
997 ScRange aSourceRange = pSourceAction->GetBigRange().MakeRange();
998 rMarkData.SelectOneTable( aSourceRange.aStart.Tab() );
999 switch ( eSourceType )
1001 case SC_CAT_CONTENT:
1003 //! Test, ob es ganz unten im Dokument war, dann automatisches
1004 //! Zeilen-Einfuegen ???
1006 OSL_ENSURE( aSourceRange.aStart == aSourceRange.aEnd, "huch?" );
1007 ScAddress aPos = aSourceRange.aStart;
1008 OUString aValue;
1009 ((const ScChangeActionContent*)pSourceAction)->GetNewString( aValue, &aDocument );
1010 sal_uInt8 eMatrix = MM_NONE;
1011 const ScCellValue& rCell = ((const ScChangeActionContent*)pSourceAction)->GetNewCell();
1012 if (rCell.meType == CELLTYPE_FORMULA)
1013 eMatrix = rCell.mpFormula->GetMatrixFlag();
1014 switch ( eMatrix )
1016 case MM_NONE :
1017 pViewSh->EnterData( aPos.Col(), aPos.Row(), aPos.Tab(), aValue );
1018 break;
1019 case MM_FORMULA :
1021 SCCOL nCols;
1022 SCROW nRows;
1023 rCell.mpFormula->GetMatColsRows(nCols, nRows);
1024 aSourceRange.aEnd.SetCol( aPos.Col() + nCols - 1 );
1025 aSourceRange.aEnd.SetRow( aPos.Row() + nRows - 1 );
1026 aValue = aValue.copy(1, aValue.getLength()-2); // remove the 1st and last characters.
1027 GetDocFunc().EnterMatrix( aSourceRange,
1028 NULL, NULL, aValue, false, false,
1029 EMPTY_OUSTRING, formula::FormulaGrammar::GRAM_DEFAULT );
1031 break;
1032 case MM_REFERENCE : // do nothing
1033 break;
1034 case MM_FAKE :
1035 OSL_FAIL( "MergeDocument: MatrixFlag MM_FAKE" );
1036 pViewSh->EnterData( aPos.Col(), aPos.Row(), aPos.Tab(), aValue );
1037 break;
1038 default:
1039 OSL_FAIL( "MergeDocument: unknown MatrixFlag" );
1042 break;
1043 case SC_CAT_INSERT_TABS :
1045 OUString aName;
1046 aDocument.CreateValidTabName( aName );
1047 GetDocFunc().InsertTable( aSourceRange.aStart.Tab(), aName, sal_True, false );
1049 break;
1050 case SC_CAT_INSERT_ROWS:
1051 GetDocFunc().InsertCells( aSourceRange, NULL, INS_INSROWS, sal_True, false );
1052 break;
1053 case SC_CAT_INSERT_COLS:
1054 GetDocFunc().InsertCells( aSourceRange, NULL, INS_INSCOLS, sal_True, false );
1055 break;
1056 case SC_CAT_DELETE_TABS :
1057 GetDocFunc().DeleteTable( aSourceRange.aStart.Tab(), sal_True, false );
1058 break;
1059 case SC_CAT_DELETE_ROWS:
1061 const ScChangeActionDel* pDel = (const ScChangeActionDel*) pSourceAction;
1062 if ( pDel->IsTopDelete() )
1064 aSourceRange = pDel->GetOverAllRange().MakeRange();
1065 GetDocFunc().DeleteCells( aSourceRange, NULL, DEL_DELROWS, sal_True, false );
1067 // #i101099# [Collaboration] Changes are not correctly shown
1068 if ( bShared )
1070 ScChangeAction* pAct = pThisTrack->GetLast();
1071 if ( pAct && pAct->GetType() == eSourceType && pAct->IsDeletedIn() && !pSourceAction->IsDeletedIn() )
1073 pAct->RemoveAllDeletedIn();
1078 break;
1079 case SC_CAT_DELETE_COLS:
1081 const ScChangeActionDel* pDel = (const ScChangeActionDel*) pSourceAction;
1082 if ( pDel->IsTopDelete() && !pDel->IsTabDeleteCol() )
1083 { // deleted Table enthaelt deleted Cols, die nicht
1084 aSourceRange = pDel->GetOverAllRange().MakeRange();
1085 GetDocFunc().DeleteCells( aSourceRange, NULL, DEL_DELCOLS, sal_True, false );
1088 break;
1089 case SC_CAT_MOVE :
1091 const ScChangeActionMove* pMove = (const ScChangeActionMove*) pSourceAction;
1092 ScRange aFromRange( pMove->GetFromRange().MakeRange() );
1093 GetDocFunc().MoveBlock( aFromRange,
1094 aSourceRange.aStart, sal_True, sal_True, false, false );
1096 break;
1097 default:
1099 // added to avoid warnings
1103 const OUString& rComment = pSourceAction->GetComment();
1104 if ( !rComment.isEmpty() )
1106 ScChangeAction* pAct = pThisTrack->GetLast();
1107 if ( pAct && pAct->GetActionNumber() > nOldActionMax )
1108 pAct->SetComment( rComment );
1109 else
1110 OSL_FAIL( "MergeDocument: wohin mit dem Kommentar?!?" );
1113 // Referenzen anpassen
1114 pSourceTrack->MergeOwn( (ScChangeAction*) pSourceAction, nFirstNewNumber, bShared );
1116 // merge action state
1117 if ( bShared && !pSourceAction->IsRejected() )
1119 ScChangeAction* pAct = pThisTrack->GetLast();
1120 if ( pAct && pAct->GetActionNumber() > nOldActionMax )
1122 pThisTrack->MergeActionState( pAct, pSourceAction );
1126 // fill merge map
1127 if ( bShared && pMergeMap )
1129 ScChangeAction* pAct = pThisTrack->GetLast();
1130 if ( pAct && pAct->GetActionNumber() > nOldActionMax )
1132 sal_uLong nActionMax = pAct->GetActionNumber();
1133 sal_uLong nActionCount = nActionMax - nOldActionMax;
1134 sal_uLong nAction = nActionMax - nActionCount + 1;
1135 sal_uLong nSourceAction = pSourceAction->GetActionNumber() - nActionCount + 1;
1136 while ( nAction <= nActionMax )
1138 if ( bInverseMap )
1140 (*pMergeMap)[ nAction++ ] = nSourceAction++;
1142 else
1144 (*pMergeMap)[ nSourceAction++ ] = nAction++;
1150 aProgress.SetStateCountDown( --nNewActionCount );
1152 pSourceAction = pSourceAction->GetNext();
1155 rMarkData = aOldMarkData;
1156 pThisTrack->SetUser(aOldUser);
1157 pThisTrack->SetUseFixDateTime( false );
1159 pSourceTrack->Clear(); //! der ist jetzt verhunzt
1161 if (bHasRejected)
1162 PostPaintGridAll(); // Reject() paintet nicht selber
1164 UnlockPaint();
1167 bool ScDocShell::MergeSharedDocument( ScDocShell* pSharedDocShell )
1169 if ( !pSharedDocShell )
1171 return false;
1174 ScChangeTrack* pThisTrack = aDocument.GetChangeTrack();
1175 if ( !pThisTrack )
1177 return false;
1180 ScDocument& rSharedDoc = *( pSharedDocShell->GetDocument() );
1181 ScChangeTrack* pSharedTrack = rSharedDoc.GetChangeTrack();
1182 if ( !pSharedTrack )
1184 return false;
1187 // reset show changes
1188 ScChangeViewSettings aChangeViewSet;
1189 aChangeViewSet.SetShowChanges( false );
1190 aDocument.SetChangeViewSettings( aChangeViewSet );
1192 // find first merge action in this document
1193 sal_Bool bIgnore100Sec = !pThisTrack->IsTimeNanoSeconds() || !pSharedTrack->IsTimeNanoSeconds();
1194 ScChangeAction* pThisAction = pThisTrack->GetFirst();
1195 ScChangeAction* pSharedAction = pSharedTrack->GetFirst();
1196 while ( lcl_Equal( pThisAction, pSharedAction, bIgnore100Sec ) )
1198 pThisAction = pThisAction->GetNext();
1199 pSharedAction = pSharedAction->GetNext();
1202 if ( pSharedAction )
1204 if ( pThisAction )
1206 // merge own changes into shared document
1207 sal_uLong nActStartShared = pSharedAction->GetActionNumber();
1208 sal_uLong nActEndShared = pSharedTrack->GetActionMax();
1209 ScDocument* pTmpDoc = new ScDocument;
1210 for ( sal_Int32 nIndex = 0; nIndex < aDocument.GetTableCount(); ++nIndex )
1212 OUString sTabName;
1213 pTmpDoc->CreateValidTabName( sTabName );
1214 pTmpDoc->InsertTab( SC_TAB_APPEND, sTabName );
1216 aDocument.GetChangeTrack()->Clone( pTmpDoc );
1217 ScChangeActionMergeMap aOwnInverseMergeMap;
1218 pSharedDocShell->MergeDocument( *pTmpDoc, true, true, 0, &aOwnInverseMergeMap, true );
1219 delete pTmpDoc;
1220 sal_uLong nActStartOwn = nActEndShared + 1;
1221 sal_uLong nActEndOwn = pSharedTrack->GetActionMax();
1223 // find conflicts
1224 ScConflictsList aConflictsList;
1225 ScConflictsFinder aFinder( pSharedTrack, nActStartShared, nActEndShared, nActStartOwn, nActEndOwn, aConflictsList );
1226 if ( aFinder.Find() )
1228 ScConflictsListHelper::TransformConflictsList( aConflictsList, NULL, &aOwnInverseMergeMap );
1229 bool bLoop = true;
1230 while ( bLoop )
1232 bLoop = false;
1233 ScConflictsDlg aDlg( GetActiveDialogParent(), GetViewData(), &rSharedDoc, aConflictsList );
1234 if ( aDlg.Execute() == RET_CANCEL )
1236 QueryBox aBox( GetActiveDialogParent(), WinBits( WB_YES_NO | WB_DEF_YES ),
1237 ScGlobal::GetRscString( STR_DOC_WILLNOTBESAVED ) );
1238 if ( aBox.Execute() == RET_YES )
1240 return false;
1242 else
1244 bLoop = true;
1250 // undo own changes in shared document
1251 pSharedTrack->Undo( nActStartOwn, nActEndOwn );
1253 // clone change track for merging into own document
1254 pTmpDoc = new ScDocument;
1255 for ( sal_Int32 nIndex = 0; nIndex < aDocument.GetTableCount(); ++nIndex )
1257 OUString sTabName;
1258 pTmpDoc->CreateValidTabName( sTabName );
1259 pTmpDoc->InsertTab( SC_TAB_APPEND, sTabName );
1261 pThisTrack->Clone( pTmpDoc );
1263 // undo own changes since last save in own document
1264 sal_uLong nStartShared = pThisAction->GetActionNumber();
1265 ScChangeAction* pAction = pThisTrack->GetLast();
1266 while ( pAction && pAction->GetActionNumber() >= nStartShared )
1268 pThisTrack->Reject( pAction, true );
1269 pAction = pAction->GetPrev();
1272 // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
1273 pThisTrack->Undo( nStartShared, pThisTrack->GetActionMax(), true );
1275 // merge shared changes into own document
1276 ScChangeActionMergeMap aSharedMergeMap;
1277 MergeDocument( rSharedDoc, true, true, 0, &aSharedMergeMap );
1278 sal_uLong nEndShared = pThisTrack->GetActionMax();
1280 // resolve conflicts for shared non-content actions
1281 if ( !aConflictsList.empty() )
1283 ScConflictsListHelper::TransformConflictsList( aConflictsList, &aSharedMergeMap, NULL );
1284 ScConflictsResolver aResolver( pThisTrack, aConflictsList );
1285 pAction = pThisTrack->GetAction( nEndShared );
1286 while ( pAction && pAction->GetActionNumber() >= nStartShared )
1288 aResolver.HandleAction( pAction, true /*bIsSharedAction*/,
1289 false /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
1290 pAction = pAction->GetPrev();
1293 nEndShared = pThisTrack->GetActionMax();
1295 // only show changes from shared document
1296 aChangeViewSet.SetShowChanges( sal_True );
1297 aChangeViewSet.SetShowAccepted( sal_True );
1298 aChangeViewSet.SetHasActionRange( true );
1299 aChangeViewSet.SetTheActionRange( nStartShared, nEndShared );
1300 aDocument.SetChangeViewSettings( aChangeViewSet );
1302 // merge own changes back into own document
1303 sal_uLong nStartOwn = nEndShared + 1;
1304 ScChangeActionMergeMap aOwnMergeMap;
1305 MergeDocument( *pTmpDoc, true, true, nEndShared - nStartShared + 1, &aOwnMergeMap );
1306 delete pTmpDoc;
1307 sal_uLong nEndOwn = pThisTrack->GetActionMax();
1309 // resolve conflicts for shared content actions and own actions
1310 if ( !aConflictsList.empty() )
1312 ScConflictsListHelper::TransformConflictsList( aConflictsList, NULL, &aOwnMergeMap );
1313 ScConflictsResolver aResolver( pThisTrack, aConflictsList );
1314 pAction = pThisTrack->GetAction( nEndShared );
1315 while ( pAction && pAction->GetActionNumber() >= nStartShared )
1317 aResolver.HandleAction( pAction, true /*bIsSharedAction*/,
1318 true /*bHandleContentAction*/, false /*bHandleNonContentAction*/ );
1319 pAction = pAction->GetPrev();
1322 pAction = pThisTrack->GetAction( nEndOwn );
1323 while ( pAction && pAction->GetActionNumber() >= nStartOwn )
1325 aResolver.HandleAction( pAction, false /*bIsSharedAction*/,
1326 true /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
1327 pAction = pAction->GetPrev();
1330 nEndOwn = pThisTrack->GetActionMax();
1332 else
1334 // merge shared changes into own document
1335 sal_uLong nStartShared = pThisTrack->GetActionMax() + 1;
1336 MergeDocument( rSharedDoc, true, true );
1337 sal_uLong nEndShared = pThisTrack->GetActionMax();
1339 // only show changes from shared document
1340 aChangeViewSet.SetShowChanges( sal_True );
1341 aChangeViewSet.SetShowAccepted( sal_True );
1342 aChangeViewSet.SetHasActionRange( true );
1343 aChangeViewSet.SetTheActionRange( nStartShared, nEndShared );
1344 aDocument.SetChangeViewSettings( aChangeViewSet );
1347 // update view
1348 PostPaintExtras();
1349 PostPaintGridAll();
1351 InfoBox aInfoBox( GetActiveDialogParent(), ScGlobal::GetRscString( STR_DOC_UPDATED ) );
1352 aInfoBox.Execute();
1355 return ( pThisAction != NULL );
1358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */