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"
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
;
121 pPaintLockData
->AddRange( ScRange( nCol1
, nRow1
, nTab1
,
122 nCol2
, nRow2
, nTab2
), nLockPart
);
125 nPart
&= PAINT_EXTRAS
; // for broadcasting
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
) )
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();
237 sal_uInt16 nParts
= pPaint
->GetParts();
238 for ( size_t i
= 0, nCount
= xRangeList
->size(); i
< nCount
; i
++ )
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(),
248 if ( pPaint
->GetModified() )
249 SetDocumentModified();
256 OSL_FAIL("UnlockPaint ohne LockPaint");
260 void ScDocShell::LockDocument_Impl(sal_uInt16 nNew
)
264 ScDrawLayer
* pDrawLayer
= aDocument
.GetDrawLayer();
266 pDrawLayer
->setLock(true);
268 nDocumentLock
= nNew
;
271 void ScDocShell::UnlockDocument_Impl(sal_uInt16 nNew
)
273 nDocumentLock
= nNew
;
276 ScDrawLayer
* pDrawLayer
= aDocument
.GetDrawLayer();
278 pDrawLayer
->setLock(false);
282 void ScDocShell::SetLockCount(sal_uInt16 nNew
)
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()
319 UnlockPaint_Impl(true);
320 UnlockDocument_Impl(nDocumentLock
- 1);
324 OSL_FAIL("UnlockDocument without LockDocument");
328 void ScDocShell::SetInplace( bool bInplace
)
330 if (bIsInplace
!= bInplace
)
332 bIsInplace
= bInplace
;
337 void ScDocShell::CalcOutputFactor()
341 nPrtToScreenFactor
= 1.0; // passt sonst nicht zur inaktiven Darstellung
345 bool bTextWysiwyg
= SC_MOD()->GetInputOptions().GetTextWysiwyg();
348 nPrtToScreenFactor
= 1.0;
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
));
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
;
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
;
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() ) );
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
);
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 );
475 if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
478 ScModule
* pScMod
= SC_MOD();
479 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( this );
482 SfxViewShell
* pSh
= pFrame
->GetViewShell();
483 if (pSh
&& pSh
->ISA(ScTabViewShell
))
485 ScTabViewShell
* pViewSh
= static_cast<ScTabViewShell
*>(pSh
);
486 ScInputHandler
* pInputHdl
= pScMod
->GetInputHdl(pViewSh
);
488 pInputHdl
->UpdateRefDevice();
490 pFrame
= SfxViewFrame::GetNext( *pFrame
, this );
494 else if (nDiffFlags
& SfxPrinterChangeFlags::JOBSETUP
)
496 SfxPrinter
* pOldPrinter
= aDocument
.GetPrinter();
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
));
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
);
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
);
554 ScChangeAction
* ScDocShell::GetChangeAction( const ScAddress
& rPos
)
556 ScChangeTrack
* pTrack
= GetDocument().GetChangeTrack();
560 SCTAB nTab
= rPos
.Tab();
562 const ScChangeAction
* pFound
= NULL
;
564 const ScChangeAction
* pAction
= pTrack
->GetFirst();
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
587 if ( pAction
->GetType() == SC_CAT_MOVE
)
590 static_cast<const ScChangeActionMove
*>(pAction
)->
591 GetFromRange().MakeRange();
592 if ( aRange
.In( rPos
) )
599 pAction
= pAction
->GetNext();
602 return const_cast<ScChangeAction
*>(pFound
);
605 void ScDocShell::SetChangeComment( ScChangeAction
* pAction
, const OUString
& rComment
)
609 pAction
->SetComment( rComment
);
611 SetDocumentModified();
614 ScChangeTrack
* pTrack
= GetDocument().GetChangeTrack();
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
);
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
,
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
));
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();
662 pTrack
= aDocument
.GetChangeTrack();
665 aOldUser
= pTrack
->GetUser();
667 // check if comparing to same document
670 const SfxMedium
* pThisMed
= GetMedium();
672 aThisFile
= pThisMed
->GetName();
674 SfxObjectShell
* pOtherSh
= rOtherDoc
.GetDocumentShell();
677 const SfxMedium
* pOtherMed
= pOtherSh
->GetMedium();
679 aOtherFile
= pOtherMed
->GetName();
681 bool bSameDoc
= ( aThisFile
== aOtherFile
&& !aThisFile
.isEmpty() );
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();
705 pTrack
->SetUser( aOldUser
);
708 SetDocumentModified();
711 // Merge (Aenderungen zusammenfuehren)
713 static inline bool lcl_Equal( const ScChangeAction
* pA
, const ScChangeAction
* pB
, bool bIgnore100Sec
)
716 pA
->GetActionNumber() == pB
->GetActionNumber() &&
717 pA
->GetType() == pB
->GetType() &&
718 pA
->GetUser() == pB
->GetUser() &&
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
)
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() &&
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);
746 pA
->GetDescription(aADesc
, pSearchDoc
, true);
747 if (aActionDesc
.equals(aADesc
))
749 OSL_FAIL( "lcl_FindAction(): found equal action!" );
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
765 ScChangeTrack
* pSourceTrack
= rOtherDoc
.GetChangeTrack();
767 return; //! nichts zu tun - Fehlermeldung?
769 ScChangeTrack
* pThisTrack
= aDocument
.GetChangeTrack();
772 aDocument
.StartChangeTracking();
773 pThisTrack
= aDocument
.GetChangeTrack();
774 OSL_ENSURE(pThisTrack
,"ChangeTracking nicht angeschaltet?");
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
;
815 if ( bShared
|| !ScChangeTrack::MergeIgnore( *pCount
, nFirstNewNumber
) )
817 pCount
= pCount
->GetNext();
819 if (!nNewActionCount
)
820 return; //! nichts zu tun - Fehlermeldung?
821 // ab hier kein return mehr
823 ScProgress
aProgress( this, OUString("..."),
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();
840 case SC_CAT_INSERT_COLS
:
841 case SC_CAT_INSERT_ROWS
:
842 case SC_CAT_INSERT_TABS
:
843 pSourceTrack
->AppendInsert( pThisAction
->GetBigRange().MakeRange() );
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
);
860 const ScChangeActionMove
* pMove
= static_cast<const ScChangeActionMove
*>(pThisAction
);
861 pSourceTrack
->AppendMove( pMove
->GetFromRange().MakeRange(),
862 pMove
->GetBigRange().MakeRange(), NULL
);
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;
888 if ( !bCheckDuplicates
|| !lcl_FindAction( &rOtherDoc
, pSourceAction
, &aDocument
, pFirstSearchAction
, pLastSearchAction
, bIgnore100Sec
) )
895 if ( !ScChangeTrack::MergeIgnore( *pSourceAction
, nFirstNewNumber
) )
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
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() );
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();
937 if ( nReject
>= nFirstNewNumber
)
941 ScChangeAction
* pOldAction
= pThisTrack
->GetAction( nReject
);
942 if ( pOldAction
&& pOldAction
->IsVirgin() )
944 pThisTrack
->Reject( pOldAction
);
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
969 ScRange aSourceRange
= pSourceAction
->GetBigRange().MakeRange();
970 rMarkData
.SelectOneTable( aSourceRange
.aStart
.Tab() );
971 switch ( eSourceType
)
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
;
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();
989 pViewSh
->EnterData( aPos
.Col(), aPos
.Row(), aPos
.Tab(), aValue
);
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
);
1004 case MM_REFERENCE
: // do nothing
1007 OSL_FAIL( "MergeDocument: MatrixFlag MM_FAKE" );
1008 pViewSh
->EnterData( aPos
.Col(), aPos
.Row(), aPos
.Tab(), aValue
);
1011 OSL_FAIL( "MergeDocument: unknown MatrixFlag" );
1015 case SC_CAT_INSERT_TABS
:
1018 aDocument
.CreateValidTabName( aName
);
1019 GetDocFunc().InsertTable( aSourceRange
.aStart
.Tab(), aName
, true, false );
1022 case SC_CAT_INSERT_ROWS
:
1023 GetDocFunc().InsertCells( aSourceRange
, NULL
, INS_INSROWS
, true, false );
1025 case SC_CAT_INSERT_COLS
:
1026 GetDocFunc().InsertCells( aSourceRange
, NULL
, INS_INSCOLS
, true, false );
1028 case SC_CAT_DELETE_TABS
:
1029 GetDocFunc().DeleteTable( aSourceRange
.aStart
.Tab(), true, false );
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
1042 ScChangeAction
* pAct
= pThisTrack
->GetLast();
1043 if ( pAct
&& pAct
->GetType() == eSourceType
&& pAct
->IsDeletedIn() && !pSourceAction
->IsDeletedIn() )
1045 pAct
->RemoveAllDeletedIn();
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 );
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 );
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
);
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
);
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
)
1112 (*pMergeMap
)[ nAction
++ ] = nSourceAction
++;
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
1134 PostPaintGridAll(); // Reject() paintet nicht selber
1139 bool ScDocShell::MergeSharedDocument( ScDocShell
* pSharedDocShell
)
1141 if ( !pSharedDocShell
)
1146 ScChangeTrack
* pThisTrack
= aDocument
.GetChangeTrack();
1152 ScDocument
& rSharedDoc
= pSharedDocShell
->GetDocument();
1153 ScChangeTrack
* pSharedTrack
= rSharedDoc
.GetChangeTrack();
1154 if ( !pSharedTrack
)
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
)
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
)
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 );
1192 sal_uLong nActStartOwn
= nActEndShared
+ 1;
1193 sal_uLong nActEndOwn
= pSharedTrack
->GetActionMax();
1196 ScConflictsList aConflictsList
;
1197 ScConflictsFinder
aFinder( pSharedTrack
, nActStartShared
, nActEndShared
, nActStartOwn
, nActEndOwn
, aConflictsList
);
1198 if ( aFinder
.Find() )
1200 ScConflictsListHelper::TransformConflictsList( aConflictsList
, NULL
, &aOwnInverseMergeMap
);
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
)
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
)
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
);
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();
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
);
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: */