1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
39 #include "docshimp.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"
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"
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
;
125 pPaintLockData
->AddRange( ScRange( nCol1
, nRow1
, nTab1
,
126 nCol2
, nRow2
, nTab2
), nLockPart
);
129 nPart
&= PAINT_EXTRAS
; // for broadcasting
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
) )
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();
244 sal_uInt16 nParts
= pPaint
->GetParts();
245 for ( size_t i
= 0, nCount
= xRangeList
->size(); i
< nCount
; i
++ )
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(),
255 if ( pPaint
->GetModified() )
256 SetDocumentModified();
263 OSL_FAIL("UnlockPaint ohne LockPaint");
267 void ScDocShell::LockDocument_Impl(sal_uInt16 nNew
)
271 ScDrawLayer
* pDrawLayer
= aDocument
.GetDrawLayer();
273 pDrawLayer
->setLock(true);
275 nDocumentLock
= nNew
;
278 void ScDocShell::UnlockDocument_Impl(sal_uInt16 nNew
)
280 nDocumentLock
= nNew
;
283 ScDrawLayer
* pDrawLayer
= aDocument
.GetDrawLayer();
285 pDrawLayer
->setLock(false);
289 sal_uInt16
ScDocShell::GetLockCount() const
291 return nDocumentLock
;
294 void ScDocShell::SetLockCount(sal_uInt16 nNew
)
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()
331 UnlockPaint_Impl(sal_True
);
332 UnlockDocument_Impl(nDocumentLock
- 1);
336 OSL_FAIL("UnlockDocument without LockDocument");
340 //------------------------------------------------------------------
342 void ScDocShell::SetInplace( bool bInplace
)
344 if (bIsInplace
!= bInplace
)
346 bIsInplace
= bInplace
;
351 void ScDocShell::CalcOutputFactor()
355 nPrtToScreenFactor
= 1.0; // passt sonst nicht zur inaktiven Darstellung
359 sal_Bool bTextWysiwyg
= SC_MOD()->GetInputOptions().GetTextWysiwyg();
362 nPrtToScreenFactor
= 1.0;
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
);
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
;
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
;
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() ) );
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
);
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 );
492 if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
495 ScModule
* pScMod
= SC_MOD();
496 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( this );
499 SfxViewShell
* pSh
= pFrame
->GetViewShell();
500 if (pSh
&& pSh
->ISA(ScTabViewShell
))
502 ScTabViewShell
* pViewSh
= (ScTabViewShell
*)pSh
;
503 ScInputHandler
* pInputHdl
= pScMod
->GetInputHdl(pViewSh
);
505 pInputHdl
->UpdateRefDevice();
507 pFrame
= SfxViewFrame::GetNext( *pFrame
, this );
511 else if (nDiffFlags
& SFX_PRINTER_JOBSETUP
)
513 SfxPrinter
* pOldPrinter
= aDocument
.GetPrinter();
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
);
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
);
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
);
571 //---------------------------------------------------------------------
573 ScChangeAction
* ScDocShell::GetChangeAction( const ScAddress
& rPos
)
575 ScChangeTrack
* pTrack
= GetDocument()->GetChangeTrack();
579 SCTAB nTab
= rPos
.Tab();
581 const ScChangeAction
* pFound
= NULL
;
583 const ScChangeAction
* pAction
= pTrack
->GetFirst();
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
606 if ( pAction
->GetType() == SC_CAT_MOVE
)
609 ((const ScChangeActionMove
*)pAction
)->
610 GetFromRange().MakeRange();
611 if ( aRange
.In( rPos
) )
618 pAction
= pAction
->GetNext();
621 return (ScChangeAction
*)pFound
;
624 void ScDocShell::SetChangeComment( ScChangeAction
* pAction
, const OUString
& rComment
)
628 pAction
->SetComment( rComment
);
630 SetDocumentModified();
633 ScChangeTrack
* pTrack
= GetDocument()->GetChangeTrack();
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
);
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
,
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
);
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();
685 pTrack
= aDocument
.GetChangeTrack();
688 aOldUser
= pTrack
->GetUser();
690 // check if comparing to same document
693 const SfxMedium
* pThisMed
= GetMedium();
695 aThisFile
= pThisMed
->GetName();
697 SfxObjectShell
* pOtherSh
= rOtherDoc
.GetDocumentShell();
700 const SfxMedium
* pOtherMed
= pOtherSh
->GetMedium();
702 aOtherFile
= pOtherMed
->GetName();
704 sal_Bool bSameDoc
= ( aThisFile
== aOtherFile
&& !aThisFile
.isEmpty() );
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();
728 pTrack
->SetUser( aOldUser
);
731 SetDocumentModified();
734 //---------------------------------------------------------------------
736 // Merge (Aenderungen zusammenfuehren)
738 //---------------------------------------------------------------------
740 static inline sal_Bool
lcl_Equal( const ScChangeAction
* pA
, const ScChangeAction
* pB
, sal_Bool bIgnore100Sec
)
743 pA
->GetActionNumber() == pB
->GetActionNumber() &&
744 pA
->GetType() == pB
->GetType() &&
745 pA
->GetUser() == pB
->GetUser() &&
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
)
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() &&
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);
773 pA
->GetDescription(aADesc
, pSearchDoc
, true);
774 if (aActionDesc
.equals(aADesc
))
776 OSL_FAIL( "lcl_FindAction(): found equal action!" );
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
792 ScChangeTrack
* pSourceTrack
= rOtherDoc
.GetChangeTrack();
794 return; //! nichts zu tun - Fehlermeldung?
796 ScChangeTrack
* pThisTrack
= aDocument
.GetChangeTrack();
799 aDocument
.StartChangeTracking();
800 pThisTrack
= aDocument
.GetChangeTrack();
801 OSL_ENSURE(pThisTrack
,"ChangeTracking nicht angeschaltet?");
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
;
843 if ( bShared
|| !ScChangeTrack::MergeIgnore( *pCount
, nFirstNewNumber
) )
845 pCount
= pCount
->GetNext();
847 if (!nNewActionCount
)
848 return; //! nichts zu tun - Fehlermeldung?
849 // ab hier kein return mehr
851 ScProgress
aProgress( this, OUString("..."),
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();
868 case SC_CAT_INSERT_COLS
:
869 case SC_CAT_INSERT_ROWS
:
870 case SC_CAT_INSERT_TABS
:
871 pSourceTrack
->AppendInsert( pThisAction
->GetBigRange().MakeRange() );
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
);
888 const ScChangeActionMove
* pMove
= (const ScChangeActionMove
*) pThisAction
;
889 pSourceTrack
->AppendMove( pMove
->GetFromRange().MakeRange(),
890 pMove
->GetBigRange().MakeRange(), NULL
);
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;
916 if ( !bCheckDuplicates
|| !lcl_FindAction( &rOtherDoc
, pSourceAction
, &aDocument
, pFirstSearchAction
, pLastSearchAction
, bIgnore100Sec
) )
923 if ( !ScChangeTrack::MergeIgnore( *pSourceAction
, nFirstNewNumber
) )
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
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() );
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();
965 if ( nReject
>= nFirstNewNumber
)
969 ScChangeAction
* pOldAction
= pThisTrack
->GetAction( nReject
);
970 if ( pOldAction
&& pOldAction
->IsVirgin() )
972 pThisTrack
->Reject( pOldAction
);
973 bHasRejected
= sal_True
;
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
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
;
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();
1017 pViewSh
->EnterData( aPos
.Col(), aPos
.Row(), aPos
.Tab(), aValue
);
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
);
1032 case MM_REFERENCE
: // do nothing
1035 OSL_FAIL( "MergeDocument: MatrixFlag MM_FAKE" );
1036 pViewSh
->EnterData( aPos
.Col(), aPos
.Row(), aPos
.Tab(), aValue
);
1039 OSL_FAIL( "MergeDocument: unknown MatrixFlag" );
1043 case SC_CAT_INSERT_TABS
:
1046 aDocument
.CreateValidTabName( aName
);
1047 GetDocFunc().InsertTable( aSourceRange
.aStart
.Tab(), aName
, sal_True
, false );
1050 case SC_CAT_INSERT_ROWS
:
1051 GetDocFunc().InsertCells( aSourceRange
, NULL
, INS_INSROWS
, sal_True
, false );
1053 case SC_CAT_INSERT_COLS
:
1054 GetDocFunc().InsertCells( aSourceRange
, NULL
, INS_INSCOLS
, sal_True
, false );
1056 case SC_CAT_DELETE_TABS
:
1057 GetDocFunc().DeleteTable( aSourceRange
.aStart
.Tab(), sal_True
, false );
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
1070 ScChangeAction
* pAct
= pThisTrack
->GetLast();
1071 if ( pAct
&& pAct
->GetType() == eSourceType
&& pAct
->IsDeletedIn() && !pSourceAction
->IsDeletedIn() )
1073 pAct
->RemoveAllDeletedIn();
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 );
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 );
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
);
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
);
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
)
1140 (*pMergeMap
)[ nAction
++ ] = nSourceAction
++;
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
1162 PostPaintGridAll(); // Reject() paintet nicht selber
1167 bool ScDocShell::MergeSharedDocument( ScDocShell
* pSharedDocShell
)
1169 if ( !pSharedDocShell
)
1174 ScChangeTrack
* pThisTrack
= aDocument
.GetChangeTrack();
1180 ScDocument
& rSharedDoc
= *( pSharedDocShell
->GetDocument() );
1181 ScChangeTrack
* pSharedTrack
= rSharedDoc
.GetChangeTrack();
1182 if ( !pSharedTrack
)
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
)
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
)
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 );
1220 sal_uLong nActStartOwn
= nActEndShared
+ 1;
1221 sal_uLong nActEndOwn
= pSharedTrack
->GetActionMax();
1224 ScConflictsList aConflictsList
;
1225 ScConflictsFinder
aFinder( pSharedTrack
, nActStartShared
, nActEndShared
, nActStartOwn
, nActEndOwn
, aConflictsList
);
1226 if ( aFinder
.Find() )
1228 ScConflictsListHelper::TransformConflictsList( aConflictsList
, NULL
, &aOwnInverseMergeMap
);
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
)
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
)
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
);
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();
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
);
1351 InfoBox
aInfoBox( GetActiveDialogParent(), ScGlobal::GetRscString( STR_DOC_UPDATED
) );
1355 return ( pThisAction
!= NULL
);
1358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */