1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: docsh3.cxx,v $
10 * $Revision: 1.38.52.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
38 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
39 #include <com/sun/star/document/XDocumentProperties.hpp>
41 #include "scitems.hxx"
42 #include "rangelst.hxx"
43 #include <svx/flstitem.hxx>
44 #include <svx/pageitem.hxx>
45 #include <svx/paperinf.hxx>
46 #include <svx/postattr.hxx>
47 //#include <svx/postdlg.hxx>
48 #include <svx/sizeitem.hxx>
50 #include <sfx2/viewfrm.hxx>
51 #include <sfx2/app.hxx>
52 #include <sfx2/docfile.hxx>
53 #include <svtools/misccfg.hxx>
54 #include <sfx2/printer.hxx>
55 #include <svtools/ctrltool.hxx>
56 #include <vcl/virdev.hxx>
57 #include <vcl/svapp.hxx>
58 #include <vcl/msgbox.hxx>
59 #include <unotools/localedatawrapper.hxx>
62 #include "docshimp.hxx"
64 #include "tabvwsh.hxx"
65 #include "viewdata.hxx"
66 #include "docpool.hxx"
67 #include "stlpool.hxx"
68 #include "patattr.hxx"
69 #include "uiitems.hxx"
71 #include "docoptio.hxx"
72 #include "viewopti.hxx"
73 #include "pntlock.hxx"
74 #include "chgtrack.hxx"
75 #include "docfunc.hxx"
77 #include "chgviset.hxx"
78 #include "progress.hxx"
81 #include "inputopt.hxx"
82 #include "drwlayer.hxx"
83 #include "inputhdl.hxx"
84 #include "conflictsdlg.hxx"
85 #include "globstr.hrc"
89 #endif // DEBUG_CHANGETRACK
92 //------------------------------------------------------------------
95 // Redraw - Benachrichtigungen
99 void ScDocShell::PostEditView( ScEditEngineDefaulter
* pEditEngine
, const ScAddress
& rCursorPos
)
101 // Broadcast( ScEditViewHint( pEditEngine, rCursorPos ) );
103 // Test: nur aktive ViewShell
105 ScTabViewShell
* pViewSh
= ScTabViewShell::GetActiveViewShell();
106 if (pViewSh
&& pViewSh
->GetViewData()->GetDocShell() == this)
108 ScEditViewHint
aHint( pEditEngine
, rCursorPos
);
109 pViewSh
->Notify( *this, aHint
);
113 void ScDocShell::PostDataChanged()
115 Broadcast( SfxSimpleHint( FID_DATACHANGED
) );
116 aDocument
.ResetChanged( ScRange(0,0,0,MAXCOL
,MAXROW
,MAXTAB
) );
118 SFX_APP()->Broadcast(SfxSimpleHint( FID_ANYDATACHANGED
)); // Navigator
119 //! Navigator direkt benachrichtigen!
122 void ScDocShell::PostPaint( SCCOL nStartCol
, SCROW nStartRow
, SCTAB nStartTab
,
123 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nEndTab
, USHORT nPart
,
126 if (!ValidCol(nStartCol
)) nStartCol
= MAXCOL
;
127 if (!ValidRow(nStartRow
)) nStartRow
= MAXROW
;
128 if (!ValidCol(nEndCol
)) nEndCol
= MAXCOL
;
129 if (!ValidRow(nEndRow
)) nEndRow
= MAXROW
;
131 if ( pPaintLockData
)
133 // #i54081# PAINT_EXTRAS still has to be brodcast because it changes the
134 // current sheet if it's invalid. All other flags added to pPaintLockData.
135 USHORT nLockPart
= nPart
& ~PAINT_EXTRAS
;
139 pPaintLockData
->AddRange( ScRange( nStartCol
, nStartRow
, nStartTab
,
140 nEndCol
, nEndRow
, nEndTab
), nLockPart
);
143 nPart
&= PAINT_EXTRAS
; // for broadcasting
149 if (nExtFlags
& SC_PF_LINES
) // Platz fuer Linien beruecksichtigen
151 //! Abfrage auf versteckte Spalten/Zeilen!
152 if (nStartCol
>0) --nStartCol
;
153 if (nEndCol
<MAXCOL
) ++nEndCol
;
154 if (nStartRow
>0) --nStartRow
;
155 if (nEndRow
<MAXROW
) ++nEndRow
;
158 // um zusammengefasste erweitern
159 if (nExtFlags
& SC_PF_TESTMERGE
)
160 aDocument
.ExtendMerge( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nStartTab
);
162 if ( nStartCol
!= 0 || nEndCol
!= MAXCOL
)
164 // Extend to whole rows if SC_PF_WHOLEROWS is set, or rotated or non-left
165 // aligned cells are contained (see UpdatePaintExt).
166 // Special handling for RTL text (#i9731#) is unnecessary now with full
167 // support of right-aligned text.
169 if ( ( nExtFlags
& SC_PF_WHOLEROWS
) ||
170 aDocument
.HasAttrib( nStartCol
,nStartRow
,nStartTab
,
171 MAXCOL
,nEndRow
,nEndTab
, HASATTR_ROTATE
| HASATTR_RIGHTORCENTER
) )
178 Broadcast( ScPaintHint( ScRange( nStartCol
, nStartRow
, nStartTab
,
179 nEndCol
, nEndRow
, nEndTab
), nPart
) );
181 if ( nPart
& PAINT_GRID
)
182 aDocument
.ResetChanged( ScRange(nStartCol
,nStartRow
,nStartTab
,nEndCol
,nEndRow
,nEndTab
) );
185 void ScDocShell::PostPaint( const ScRange
& rRange
, USHORT nPart
, USHORT nExtFlags
)
187 PostPaint( rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aStart
.Tab(),
188 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), rRange
.aEnd
.Tab(),
192 void ScDocShell::PostPaintGridAll()
194 PostPaint( 0,0,0, MAXCOL
,MAXROW
,MAXTAB
, PAINT_GRID
);
197 void ScDocShell::PostPaintCell( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
199 PostPaint( nCol
,nRow
,nTab
, nCol
,nRow
,nTab
, PAINT_GRID
, SC_PF_TESTMERGE
);
202 void ScDocShell::PostPaintCell( const ScAddress
& rPos
)
204 PostPaintCell( rPos
.Col(), rPos
.Row(), rPos
.Tab() );
207 void ScDocShell::PostPaintExtras()
209 PostPaint( 0,0,0, MAXCOL
,MAXROW
,MAXTAB
, PAINT_EXTRAS
);
212 void ScDocShell::UpdatePaintExt( USHORT
& rExtFlags
, const ScRange
& rRange
)
214 if ( ( rExtFlags
& SC_PF_LINES
) == 0 && aDocument
.HasAttrib( rRange
, HASATTR_PAINTEXT
) )
216 // If the range contains lines, shadow or conditional formats,
217 // set SC_PF_LINES to include one extra cell in all directions.
219 rExtFlags
|= SC_PF_LINES
;
222 if ( ( rExtFlags
& SC_PF_WHOLEROWS
) == 0 &&
223 ( rRange
.aStart
.Col() != 0 || rRange
.aEnd
.Col() != MAXCOL
) &&
224 aDocument
.HasAttrib( rRange
, HASATTR_ROTATE
| HASATTR_RIGHTORCENTER
) )
226 // If the range contains (logically) right- or center-aligned cells,
227 // or rotated cells, set SC_PF_WHOLEROWS to paint the whole rows.
228 // This test isn't needed after the cell changes, because it's also
229 // tested in PostPaint. UpdatePaintExt may later be changed to do this
230 // only if called before the changes.
232 rExtFlags
|= SC_PF_WHOLEROWS
;
236 void ScDocShell::UpdatePaintExt( USHORT
& rExtFlags
, SCCOL nStartCol
, SCROW nStartRow
, SCTAB nStartTab
,
237 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nEndTab
)
239 UpdatePaintExt( rExtFlags
, ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
) );
242 //------------------------------------------------------------------
244 void ScDocShell::LockPaint_Impl(BOOL bDoc
)
246 if ( !pPaintLockData
)
247 pPaintLockData
= new ScPaintLockData(0); //! Modus...
248 pPaintLockData
->IncLevel(bDoc
);
251 void ScDocShell::UnlockPaint_Impl(BOOL bDoc
)
253 if ( pPaintLockData
)
255 if ( pPaintLockData
->GetLevel(bDoc
) )
256 pPaintLockData
->DecLevel(bDoc
);
257 if (!pPaintLockData
->GetLevel(!bDoc
) && !pPaintLockData
->GetLevel(bDoc
))
259 // Paint jetzt ausfuehren
261 ScPaintLockData
* pPaint
= pPaintLockData
;
262 pPaintLockData
= NULL
; // nicht weitersammeln
264 ScRangeListRef xRangeList
= pPaint
->GetRangeList();
267 USHORT nParts
= pPaint
->GetParts();
268 ULONG nCount
= xRangeList
->Count();
269 for ( ULONG i
=0; i
<nCount
; i
++ )
272 ScRange aRange
= *xRangeList
->GetObject(i
);
273 PostPaint( aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aStart
.Tab(),
274 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), aRange
.aEnd
.Tab(),
279 if ( pPaint
->GetModified() )
280 SetDocumentModified();
287 DBG_ERROR("UnlockPaint ohne LockPaint");
291 void ScDocShell::LockDocument_Impl(USHORT nNew
)
295 ScDrawLayer
* pDrawLayer
= aDocument
.GetDrawLayer();
297 pDrawLayer
->setLock(TRUE
);
299 nDocumentLock
= nNew
;
302 void ScDocShell::UnlockDocument_Impl(USHORT nNew
)
304 nDocumentLock
= nNew
;
307 ScDrawLayer
* pDrawLayer
= aDocument
.GetDrawLayer();
309 pDrawLayer
->setLock(FALSE
);
313 USHORT
ScDocShell::GetLockCount() const
315 return nDocumentLock
;
318 void ScDocShell::SetLockCount(USHORT nNew
)
322 if ( !pPaintLockData
)
323 pPaintLockData
= new ScPaintLockData(0); //! Modus...
324 pPaintLockData
->SetLevel(nNew
-1, TRUE
);
325 LockDocument_Impl(nNew
);
327 else if (pPaintLockData
) // loeschen
329 pPaintLockData
->SetLevel(0, TRUE
); // bei Unlock sofort ausfuehren
330 UnlockPaint_Impl(TRUE
); // jetzt
331 UnlockDocument_Impl(0);
335 void ScDocShell::LockPaint()
337 LockPaint_Impl(FALSE
);
340 void ScDocShell::UnlockPaint()
342 UnlockPaint_Impl(FALSE
);
345 void ScDocShell::LockDocument()
347 LockPaint_Impl(TRUE
);
348 LockDocument_Impl(nDocumentLock
+ 1);
351 void ScDocShell::UnlockDocument()
355 UnlockPaint_Impl(TRUE
);
356 UnlockDocument_Impl(nDocumentLock
- 1);
360 DBG_ERROR("UnlockDocument without LockDocument");
364 //------------------------------------------------------------------
366 void ScDocShell::SetInplace( BOOL bInplace
)
368 if (bIsInplace
!= bInplace
)
370 bIsInplace
= bInplace
;
375 void ScDocShell::CalcOutputFactor()
379 nPrtToScreenFactor
= 1.0; // passt sonst nicht zur inaktiven Darstellung
383 BOOL bTextWysiwyg
= SC_MOD()->GetInputOptions().GetTextWysiwyg();
386 nPrtToScreenFactor
= 1.0;
390 String aTestString
= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(
391 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789" ));
392 long nPrinterWidth
= 0;
393 long nWindowWidth
= 0;
394 const ScPatternAttr
* pPattern
= (const ScPatternAttr
*)&aDocument
.GetPool()->
395 GetDefaultItem(ATTR_PATTERN
);
398 OutputDevice
* pRefDev
= GetRefDevice();
399 MapMode aOldMode
= pRefDev
->GetMapMode();
400 Font aOldFont
= pRefDev
->GetFont();
402 pRefDev
->SetMapMode(MAP_PIXEL
);
403 pPattern
->GetFont(aDefFont
, SC_AUTOCOL_BLACK
, pRefDev
); // font color doesn't matter here
404 pRefDev
->SetFont(aDefFont
);
405 nPrinterWidth
= pRefDev
->PixelToLogic( Size( pRefDev
->GetTextWidth(aTestString
), 0 ), MAP_100TH_MM
).Width();
406 pRefDev
->SetFont(aOldFont
);
407 pRefDev
->SetMapMode(aOldMode
);
409 VirtualDevice
aVirtWindow( *Application::GetDefaultDevice() );
410 aVirtWindow
.SetMapMode(MAP_PIXEL
);
411 pPattern
->GetFont(aDefFont
, SC_AUTOCOL_BLACK
, &aVirtWindow
); // font color doesn't matter here
412 aVirtWindow
.SetFont(aDefFont
);
413 nWindowWidth
= aVirtWindow
.GetTextWidth(aTestString
);
414 nWindowWidth
= (long) ( nWindowWidth
/ ScGlobal::nScreenPPTX
* HMM_PER_TWIPS
);
416 if (nPrinterWidth
&& nWindowWidth
)
417 nPrtToScreenFactor
= nPrinterWidth
/ (double) nWindowWidth
;
420 DBG_ERROR("GetTextSize gibt 0 ??");
421 nPrtToScreenFactor
= 1.0;
425 double ScDocShell::GetOutputFactor() const
427 return nPrtToScreenFactor
;
430 //---------------------------------------------------------------------
432 void ScDocShell::InitOptions() // Fortsetzung von InitNew (CLOOKs)
434 // Einstellungen aus dem SpellCheckCfg kommen in Doc- und ViewOptions
436 USHORT nDefLang
, nCjkLang
, nCtlLang
;
438 ScModule::GetSpellSettings( nDefLang
, nCjkLang
, nCtlLang
, bAutoSpell
);
439 ScModule
* pScMod
= SC_MOD();
441 ScDocOptions aDocOpt
= pScMod
->GetDocOptions();
442 ScViewOptions aViewOpt
= pScMod
->GetViewOptions();
443 aDocOpt
.SetAutoSpell( bAutoSpell
);
445 // zweistellige Jahreszahleneingabe aus Extras->Optionen->Allgemein->Sonstiges
446 aDocOpt
.SetYear2000( sal::static_int_cast
<USHORT
>( SFX_APP()->GetMiscConfig()->GetYear2000() ) );
448 aDocument
.SetDocOptions( aDocOpt
);
449 aDocument
.SetViewOptions( aViewOpt
);
451 // Druck-Optionen werden jetzt direkt vor dem Drucken gesetzt
453 aDocument
.SetLanguage( (LanguageType
) nDefLang
, (LanguageType
) nCjkLang
, (LanguageType
) nCtlLang
);
456 //---------------------------------------------------------------------
458 Printer
* ScDocShell::GetDocumentPrinter() // fuer OLE
460 return aDocument
.GetPrinter();
463 SfxPrinter
* ScDocShell::GetPrinter(BOOL bCreateIfNotExist
)
465 return aDocument
.GetPrinter(bCreateIfNotExist
);
468 void ScDocShell::UpdateFontList()
470 delete pImpl
->pFontList
;
471 // pImpl->pFontList = new FontList( GetPrinter(), Application::GetDefaultDevice() );
472 pImpl
->pFontList
= new FontList( GetRefDevice(), NULL
, FALSE
); // FALSE or TRUE???
473 SvxFontListItem
aFontListItem( pImpl
->pFontList
, SID_ATTR_CHAR_FONTLIST
);
474 PutItem( aFontListItem
);
479 OutputDevice
* ScDocShell::GetRefDevice()
481 return aDocument
.GetRefDevice();
484 USHORT
ScDocShell::SetPrinter( SfxPrinter
* pNewPrinter
, USHORT nDiffFlags
)
486 if (nDiffFlags
& SFX_PRINTER_PRINTER
)
488 if ( aDocument
.GetPrinter() != pNewPrinter
)
490 aDocument
.SetPrinter( pNewPrinter
);
491 aDocument
.SetPrintOptions();
493 // MT: Use UpdateFontList: Will use Printer fonts only if needed!
495 delete pImpl->pFontList;
496 pImpl->pFontList = new FontList( pNewPrinter, Application::GetDefaultDevice() );
497 SvxFontListItem aFontListItem( pImpl->pFontList, SID_ATTR_CHAR_FONTLIST );
498 PutItem( aFontListItem );
502 if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
505 ScModule
* pScMod
= SC_MOD();
506 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( this );
509 SfxViewShell
* pSh
= pFrame
->GetViewShell();
510 if (pSh
&& pSh
->ISA(ScTabViewShell
))
512 ScTabViewShell
* pViewSh
= (ScTabViewShell
*)pSh
;
513 ScInputHandler
* pInputHdl
= pScMod
->GetInputHdl(pViewSh
);
515 pInputHdl
->UpdateRefDevice();
517 pFrame
= SfxViewFrame::GetNext( *pFrame
, this );
521 else if (nDiffFlags
& SFX_PRINTER_JOBSETUP
)
523 SfxPrinter
* pOldPrinter
= aDocument
.GetPrinter();
526 pOldPrinter
->SetJobSetup( pNewPrinter
->GetJobSetup() );
528 // #i6706# Call SetPrinter with the old printer again, so the drawing layer
529 // RefDevice is set (calling ReformatAllTextObjects and rebuilding charts),
530 // because the JobSetup (printer device settings) may affect text layout.
531 aDocument
.SetPrinter( pOldPrinter
);
532 CalcOutputFactor(); // also with the new settings
536 if (nDiffFlags
& SFX_PRINTER_OPTIONS
)
538 aDocument
.SetPrintOptions(); //! aus neuem Printer ???
541 if (nDiffFlags
& (SFX_PRINTER_CHG_ORIENTATION
| SFX_PRINTER_CHG_SIZE
))
543 String aStyle
= aDocument
.GetPageStyle( GetCurTab() );
544 ScStyleSheetPool
* pStPl
= aDocument
.GetStyleSheetPool();
545 SfxStyleSheet
* pStyleSheet
= (SfxStyleSheet
*)pStPl
->Find(aStyle
, SFX_STYLE_FAMILY_PAGE
);
548 SfxItemSet
& rSet
= pStyleSheet
->GetItemSet();
550 if (nDiffFlags
& SFX_PRINTER_CHG_ORIENTATION
)
552 const SvxPageItem
& rOldItem
= (const SvxPageItem
&)rSet
.Get(ATTR_PAGE
);
553 BOOL bWasLand
= rOldItem
.IsLandscape();
554 BOOL bNewLand
= ( pNewPrinter
->GetOrientation() == ORIENTATION_LANDSCAPE
);
555 if (bNewLand
!= bWasLand
)
557 SvxPageItem
aNewItem( rOldItem
);
558 aNewItem
.SetLandscape( bNewLand
);
559 rSet
.Put( aNewItem
);
562 Size aOldSize
= ((const SvxSizeItem
&)rSet
.Get(ATTR_PAGE_SIZE
)).GetSize();
563 Size
aNewSize(aOldSize
.Height(),aOldSize
.Width());
564 SvxSizeItem
aNewSItem(ATTR_PAGE_SIZE
,aNewSize
);
565 rSet
.Put( aNewSItem
);
568 if (nDiffFlags
& SFX_PRINTER_CHG_SIZE
)
570 SvxSizeItem
aPaperSizeItem( ATTR_PAGE_SIZE
, SvxPaperInfo::GetPaperSize(pNewPrinter
) );
571 rSet
.Put( aPaperSizeItem
);
576 PostPaint(0,0,0,MAXCOL
,MAXROW
,MAXTAB
,PAINT_ALL
);
581 //---------------------------------------------------------------------
583 ScChangeAction
* ScDocShell::GetChangeAction( const ScAddress
& rPos
)
585 ScChangeTrack
* pTrack
= GetDocument()->GetChangeTrack();
589 SCTAB nTab
= rPos
.Tab();
591 const ScChangeAction
* pFound
= NULL
;
592 const ScChangeAction
* pFoundContent
= NULL
;
593 const ScChangeAction
* pFoundMove
= NULL
;
595 const ScChangeAction
* pAction
= pTrack
->GetFirst();
598 ScChangeActionType eType
= pAction
->GetType();
599 //! ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc )...
600 if ( pAction
->IsVisible() && eType
!= SC_CAT_DELETE_TABS
)
602 const ScBigRange
& rBig
= pAction
->GetBigRange();
603 if ( rBig
.aStart
.Tab() == nTab
)
605 ScRange aRange
= rBig
.MakeRange();
607 if ( eType
== SC_CAT_DELETE_ROWS
)
608 aRange
.aEnd
.SetRow( aRange
.aStart
.Row() );
609 else if ( eType
== SC_CAT_DELETE_COLS
)
610 aRange
.aEnd
.SetCol( aRange
.aStart
.Col() );
612 if ( aRange
.In( rPos
) )
614 pFound
= pAction
; // der letzte gewinnt
615 switch ( pAction
->GetType() )
617 case SC_CAT_CONTENT
:
618 pFoundContent
= pAction
;
621 pFoundMove
= pAction
;
625 // added to avoid warnings
631 if ( pAction
->GetType() == SC_CAT_MOVE
)
634 ((const ScChangeActionMove
*)pAction
)->
635 GetFromRange().MakeRange();
636 if ( aRange
.In( rPos
) )
643 pAction
= pAction
->GetNext();
646 return (ScChangeAction
*)pFound
;
649 void ScDocShell::SetChangeComment( ScChangeAction
* pAction
, const String
& rComment
)
653 pAction
->SetComment( rComment
);
655 SetDocumentModified();
658 ScChangeTrack
* pTrack
= GetDocument()->GetChangeTrack();
661 ULONG nNumber
= pAction
->GetActionNumber();
662 pTrack
->NotifyModified( SC_CTM_CHANGE
, nNumber
, nNumber
);
667 void ScDocShell::ExecuteChangeCommentDialog( ScChangeAction
* pAction
, Window
* pParent
,BOOL bPrevNext
)
669 if (!pAction
) return; // ohne Aktion ist nichts..
671 String aComment
= pAction
->GetComment();
672 String aAuthor
= pAction
->GetUser();
674 DateTime aDT
= pAction
->GetDateTime();
675 String aDate
= ScGlobal::pLocaleData
->getDate( aDT
);
677 aDate
+= ScGlobal::pLocaleData
->getTime( aDT
, FALSE
, FALSE
);
679 SfxItemSet
aSet( GetPool(),
680 SID_ATTR_POSTIT_AUTHOR
, SID_ATTR_POSTIT_AUTHOR
,
681 SID_ATTR_POSTIT_DATE
, SID_ATTR_POSTIT_DATE
,
682 SID_ATTR_POSTIT_TEXT
, SID_ATTR_POSTIT_TEXT
,
685 aSet
.Put( SvxPostItTextItem ( aComment
, SID_ATTR_POSTIT_TEXT
) );
686 aSet
.Put( SvxPostItAuthorItem( aAuthor
, SID_ATTR_POSTIT_AUTHOR
) );
687 aSet
.Put( SvxPostItDateItem ( aDate
, SID_ATTR_POSTIT_DATE
) );
689 ScRedComDialog
* pDlg
= new ScRedComDialog( pParent
, aSet
,this,pAction
,bPrevNext
);
696 //---------------------------------------------------------------------
698 void ScDocShell::CompareDocument( ScDocument
& rOtherDoc
)
700 ScChangeTrack
* pTrack
= aDocument
.GetChangeTrack();
701 if ( pTrack
&& pTrack
->GetFirst() )
703 //! Changes vorhanden -> Nachfrage ob geloescht werden soll
706 aDocument
.EndChangeTracking();
707 aDocument
.StartChangeTracking();
710 pTrack
= aDocument
.GetChangeTrack();
713 aOldUser
= pTrack
->GetUser();
715 // check if comparing to same document
718 const SfxMedium
* pThisMed
= GetMedium();
720 aThisFile
= pThisMed
->GetName();
722 SfxObjectShell
* pOtherSh
= rOtherDoc
.GetDocumentShell();
725 const SfxMedium
* pOtherMed
= pOtherSh
->GetMedium();
727 aOtherFile
= pOtherMed
->GetName();
729 BOOL bSameDoc
= ( aThisFile
== aOtherFile
&& aThisFile
.Len() );
732 // create change actions from comparing with the name of the user
733 // who last saved the document
734 // (only if comparing different documents)
736 using namespace ::com::sun::star
;
737 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
738 GetModel(), uno::UNO_QUERY_THROW
);
739 uno::Reference
<document::XDocumentProperties
> xDocProps(
740 xDPS
->getDocumentProperties());
741 DBG_ASSERT(xDocProps
.is(), "no DocumentProperties");
742 String aDocUser
= xDocProps
->getModifiedBy();
744 if ( aDocUser
.Len() )
745 pTrack
->SetUser( aDocUser
);
749 aDocument
.CompareDocument( rOtherDoc
);
751 pTrack
= aDocument
.GetChangeTrack();
753 pTrack
->SetUser( aOldUser
);
756 SetDocumentModified();
759 //---------------------------------------------------------------------
761 // Merge (Aenderungen zusammenfuehren)
763 //---------------------------------------------------------------------
765 inline BOOL
lcl_Equal( const ScChangeAction
* pA
, const ScChangeAction
* pB
, BOOL bIgnore100Sec
)
768 pA
->GetActionNumber() == pB
->GetActionNumber() &&
769 pA
->GetType() == pB
->GetType() &&
770 pA
->GetUser() == pB
->GetUser() &&
772 pA
->GetDateTimeUTC().IsEqualIgnore100Sec( pB
->GetDateTimeUTC() ) :
773 pA
->GetDateTimeUTC() == pB
->GetDateTimeUTC());
774 // State nicht vergleichen, falls eine alte Aenderung akzeptiert wurde
777 bool lcl_FindAction( ScDocument
* pDoc
, const ScChangeAction
* pAction
, ScDocument
* pSearchDoc
, const ScChangeAction
* pFirstSearchAction
, const ScChangeAction
* pLastSearchAction
, BOOL bIgnore100Sec
)
779 if ( !pDoc
|| !pAction
|| !pSearchDoc
|| !pFirstSearchAction
|| !pLastSearchAction
)
784 ULONG nLastSearchAction
= pLastSearchAction
->GetActionNumber();
785 const ScChangeAction
* pA
= pFirstSearchAction
;
786 while ( pA
&& pA
->GetActionNumber() <= nLastSearchAction
)
788 if ( pAction
->GetType() == pA
->GetType() &&
789 pAction
->GetUser() == pA
->GetUser() &&
791 pAction
->GetDateTimeUTC().IsEqualIgnore100Sec( pA
->GetDateTimeUTC() ) :
792 pAction
->GetDateTimeUTC() == pA
->GetDateTimeUTC() ) &&
793 pAction
->GetBigRange() == pA
->GetBigRange() )
796 pAction
->GetDescription( aActionDesc
, pDoc
, TRUE
);
798 pA
->GetDescription( aADesc
, pSearchDoc
, TRUE
);
799 if ( aActionDesc
.Equals( aADesc
) )
801 DBG_ERROR( "lcl_FindAction(): found equal action!" );
811 void ScDocShell::MergeDocument( ScDocument
& rOtherDoc
, bool bShared
, bool bCheckDuplicates
, ULONG nOffset
, ScChangeActionMergeMap
* pMergeMap
, bool bInverseMap
)
813 ScTabViewShell
* pViewSh
= GetBestViewShell( FALSE
); //! Funktionen an die DocShell
817 ScChangeTrack
* pSourceTrack
= rOtherDoc
.GetChangeTrack();
819 return; //! nichts zu tun - Fehlermeldung?
821 ScChangeTrack
* pThisTrack
= aDocument
.GetChangeTrack();
824 aDocument
.StartChangeTracking();
825 pThisTrack
= aDocument
.GetChangeTrack();
826 DBG_ASSERT(pThisTrack
,"ChangeTracking nicht angeschaltet?");
829 // #51138# visuelles RedLining einschalten
830 ScChangeViewSettings aChangeViewSet
;
831 aChangeViewSet
.SetShowChanges(TRUE
);
832 aDocument
.SetChangeViewSettings(aChangeViewSet
);
836 // #97286# include 100th seconds in compare?
837 BOOL bIgnore100Sec
= !pSourceTrack
->IsTime100thSeconds() ||
838 !pThisTrack
->IsTime100thSeconds();
840 // gemeinsame Ausgangsposition suchen
841 ULONG nFirstNewNumber
= 0;
842 const ScChangeAction
* pSourceAction
= pSourceTrack
->GetFirst();
843 const ScChangeAction
* pThisAction
= pThisTrack
->GetFirst();
844 // skip identical actions
845 while ( lcl_Equal( pSourceAction
, pThisAction
, bIgnore100Sec
) )
847 nFirstNewNumber
= pSourceAction
->GetActionNumber() + 1;
848 pSourceAction
= pSourceAction
->GetNext();
849 pThisAction
= pThisAction
->GetNext();
851 // pSourceAction und pThisAction zeigen jetzt auf die ersten "eigenen" Aktionen
852 // Die gemeinsamen Aktionen davor interessieren ueberhaupt nicht
854 //! Abfrage, ob die Dokumente vor dem Change-Tracking gleich waren !!!
857 const ScChangeAction
* pFirstMergeAction
= pSourceAction
;
858 const ScChangeAction
* pFirstSearchAction
= pThisAction
;
860 // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
861 const ScChangeAction
* pLastSearchAction
= pThisTrack
->GetLast();
863 // MergeChangeData aus den folgenden Aktionen erzeugen
864 ULONG nNewActionCount
= 0;
865 const ScChangeAction
* pCount
= pSourceAction
;
868 if ( bShared
|| !ScChangeTrack::MergeIgnore( *pCount
, nFirstNewNumber
) )
870 pCount
= pCount
->GetNext();
872 if (!nNewActionCount
)
873 return; //! nichts zu tun - Fehlermeldung?
874 // ab hier kein return mehr
876 ScProgress
aProgress( this,
877 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("...")),
880 ULONG nLastMergeAction
= pSourceTrack
->GetLast()->GetActionNumber();
881 // UpdateReference-Undo, gueltige Referenzen fuer den letzten gemeinsamen Zustand
882 pSourceTrack
->MergePrepare( (ScChangeAction
*) pFirstMergeAction
, bShared
);
884 // MergeChangeData an alle noch folgenden Aktionen in diesem Dokument anpassen
885 // -> Referenzen gueltig fuer dieses Dokument
886 while ( pThisAction
)
888 // #i87049# [Collaboration] Conflict between delete row and insert content is not merged correctly
889 if ( !bShared
|| !ScChangeTrack::MergeIgnore( *pThisAction
, nFirstNewNumber
) )
891 ScChangeActionType eType
= pThisAction
->GetType();
894 case SC_CAT_INSERT_COLS
:
895 case SC_CAT_INSERT_ROWS
:
896 case SC_CAT_INSERT_TABS
:
897 pSourceTrack
->AppendInsert( pThisAction
->GetBigRange().MakeRange() );
899 case SC_CAT_DELETE_COLS
:
900 case SC_CAT_DELETE_ROWS
:
901 case SC_CAT_DELETE_TABS
:
903 const ScChangeActionDel
* pDel
= (const ScChangeActionDel
*) pThisAction
;
904 if ( pDel
->IsTopDelete() && !pDel
->IsTabDeleteCol() )
905 { // deleted Table enthaelt deleted Cols, die nicht
907 pSourceTrack
->AppendDeleteRange(
908 pDel
->GetOverAllRange().MakeRange(), NULL
, nStart
, nEnd
);
914 const ScChangeActionMove
* pMove
= (const ScChangeActionMove
*) pThisAction
;
915 pSourceTrack
->AppendMove( pMove
->GetFromRange().MakeRange(),
916 pMove
->GetBigRange().MakeRange(), NULL
);
921 // added to avoid warnings
925 pThisAction
= pThisAction
->GetNext();
928 LockPaint(); // #i73877# no repainting after each action
930 // MergeChangeData in das aktuelle Dokument uebernehmen
931 BOOL bHasRejected
= FALSE
;
932 String aOldUser
= pThisTrack
->GetUser();
933 pThisTrack
->SetUseFixDateTime( TRUE
);
934 ScMarkData
& rMarkData
= pViewSh
->GetViewData()->GetMarkData();
935 ScMarkData
aOldMarkData( rMarkData
);
936 pSourceAction
= pFirstMergeAction
;
937 while ( pSourceAction
&& pSourceAction
->GetActionNumber() <= nLastMergeAction
)
939 bool bMergeAction
= false;
942 if ( !bCheckDuplicates
|| !lcl_FindAction( &rOtherDoc
, pSourceAction
, &aDocument
, pFirstSearchAction
, pLastSearchAction
, bIgnore100Sec
) )
949 if ( !ScChangeTrack::MergeIgnore( *pSourceAction
, nFirstNewNumber
) )
957 ScChangeActionType eSourceType
= pSourceAction
->GetType();
958 if ( !bShared
&& pSourceAction
->IsDeletedIn() )
960 //! muss hier noch festgestellt werden, ob wirklich in
961 //! _diesem_ Dokument geloescht?
963 // liegt in einem Bereich, der in diesem Dokument geloescht wurde
964 // -> wird weggelassen
965 //! ??? Loesch-Aktion rueckgaengig machen ???
966 //! ??? Aktion irgendwo anders speichern ???
969 if ( eSourceType
== SC_CAT_CONTENT
)
970 ((const ScChangeActionContent
*)pSourceAction
)->GetNewString( aValue
);
971 ByteString
aError( aValue
, gsl_getSystemTextEncoding() );
972 aError
+= " weggelassen";
973 DBG_ERROR( aError
.GetBuffer() );
978 //! Datum/Autor/Kommentar der Source-Aktion uebernehmen!
980 pThisTrack
->SetUser( pSourceAction
->GetUser() );
981 pThisTrack
->SetFixDateTimeUTC( pSourceAction
->GetDateTimeUTC() );
982 ULONG nOldActionMax
= pThisTrack
->GetActionMax();
984 bool bExecute
= true;
985 ULONG nReject
= pSourceAction
->GetRejectAction();
990 if ( nReject
>= nFirstNewNumber
)
994 ScChangeAction
* pOldAction
= pThisTrack
->GetAction( nReject
);
995 if ( pOldAction
&& pOldAction
->IsVirgin() )
997 pThisTrack
->Reject( pOldAction
);
1004 // alte Aktion (aus den gemeinsamen) ablehnen
1005 ScChangeAction
* pOldAction
= pThisTrack
->GetAction( nReject
);
1006 if (pOldAction
&& pOldAction
->GetState() == SC_CAS_VIRGIN
)
1008 //! was passiert bei Aktionen, die in diesem Dokument accepted worden sind???
1009 //! Fehlermeldung oder was???
1010 //! oder Reject-Aenderung normal ausfuehren
1012 pThisTrack
->Reject(pOldAction
);
1013 bHasRejected
= TRUE
; // fuer Paint
1021 // normal ausfuehren
1022 ScRange aSourceRange
= pSourceAction
->GetBigRange().MakeRange();
1023 rMarkData
.SelectOneTable( aSourceRange
.aStart
.Tab() );
1024 switch ( eSourceType
)
1026 case SC_CAT_CONTENT
:
1028 //! Test, ob es ganz unten im Dokument war, dann automatisches
1029 //! Zeilen-Einfuegen ???
1031 DBG_ASSERT( aSourceRange
.aStart
== aSourceRange
.aEnd
, "huch?" );
1032 ScAddress aPos
= aSourceRange
.aStart
;
1034 ((const ScChangeActionContent
*)pSourceAction
)->GetNewString( aValue
);
1035 BYTE eMatrix
= MM_NONE
;
1036 const ScBaseCell
* pCell
= ((const ScChangeActionContent
*)pSourceAction
)->GetNewCell();
1037 if ( pCell
&& pCell
->GetCellType() == CELLTYPE_FORMULA
)
1038 eMatrix
= ((const ScFormulaCell
*)pCell
)->GetMatrixFlag();
1042 pViewSh
->EnterData( aPos
.Col(), aPos
.Row(), aPos
.Tab(), aValue
);
1048 ((const ScFormulaCell
*)pCell
)->GetMatColsRows( nCols
, nRows
);
1049 aSourceRange
.aEnd
.SetCol( aPos
.Col() + nCols
- 1 );
1050 aSourceRange
.aEnd
.SetRow( aPos
.Row() + nRows
- 1 );
1051 aValue
.Erase( 0, 1 );
1052 aValue
.Erase( aValue
.Len()-1, 1 );
1053 GetDocFunc().EnterMatrix( aSourceRange
,
1054 NULL
, NULL
, aValue
, FALSE
, FALSE
,
1055 EMPTY_STRING
, formula::FormulaGrammar::GRAM_DEFAULT
);
1058 case MM_REFERENCE
: // do nothing
1061 DBG_WARNING( "MergeDocument: MatrixFlag MM_FAKE" );
1062 pViewSh
->EnterData( aPos
.Col(), aPos
.Row(), aPos
.Tab(), aValue
);
1065 DBG_ERROR( "MergeDocument: unknown MatrixFlag" );
1069 case SC_CAT_INSERT_TABS
:
1072 aDocument
.CreateValidTabName( aName
);
1073 GetDocFunc().InsertTable( aSourceRange
.aStart
.Tab(), aName
, TRUE
, FALSE
);
1076 case SC_CAT_INSERT_ROWS
:
1077 GetDocFunc().InsertCells( aSourceRange
, NULL
, INS_INSROWS
, TRUE
, FALSE
);
1079 case SC_CAT_INSERT_COLS
:
1080 GetDocFunc().InsertCells( aSourceRange
, NULL
, INS_INSCOLS
, TRUE
, FALSE
);
1082 case SC_CAT_DELETE_TABS
:
1083 GetDocFunc().DeleteTable( aSourceRange
.aStart
.Tab(), TRUE
, FALSE
);
1085 case SC_CAT_DELETE_ROWS
:
1087 const ScChangeActionDel
* pDel
= (const ScChangeActionDel
*) pSourceAction
;
1088 if ( pDel
->IsTopDelete() )
1090 aSourceRange
= pDel
->GetOverAllRange().MakeRange();
1091 GetDocFunc().DeleteCells( aSourceRange
, NULL
, DEL_DELROWS
, TRUE
, FALSE
);
1095 case SC_CAT_DELETE_COLS
:
1097 const ScChangeActionDel
* pDel
= (const ScChangeActionDel
*) pSourceAction
;
1098 if ( pDel
->IsTopDelete() && !pDel
->IsTabDeleteCol() )
1099 { // deleted Table enthaelt deleted Cols, die nicht
1100 aSourceRange
= pDel
->GetOverAllRange().MakeRange();
1101 GetDocFunc().DeleteCells( aSourceRange
, NULL
, DEL_DELCOLS
, TRUE
, FALSE
);
1107 const ScChangeActionMove
* pMove
= (const ScChangeActionMove
*) pSourceAction
;
1108 ScRange
aFromRange( pMove
->GetFromRange().MakeRange() );
1109 GetDocFunc().MoveBlock( aFromRange
,
1110 aSourceRange
.aStart
, TRUE
, TRUE
, FALSE
, FALSE
);
1115 // added to avoid warnings
1119 const String
& rComment
= pSourceAction
->GetComment();
1120 if ( rComment
.Len() )
1122 ScChangeAction
* pAct
= pThisTrack
->GetLast();
1123 if ( pAct
&& pAct
->GetActionNumber() > nOldActionMax
)
1124 pAct
->SetComment( rComment
);
1127 DBG_ERROR( "MergeDocument: wohin mit dem Kommentar?!?" );
1131 // Referenzen anpassen
1132 pSourceTrack
->MergeOwn( (ScChangeAction
*) pSourceAction
, nFirstNewNumber
, bShared
);
1134 // merge action state
1135 if ( bShared
&& !pSourceAction
->IsRejected() )
1137 ScChangeAction
* pAct
= pThisTrack
->GetLast();
1138 if ( pAct
&& pAct
->GetActionNumber() > nOldActionMax
)
1140 pThisTrack
->MergeActionState( pAct
, pSourceAction
);
1145 if ( bShared
&& pMergeMap
)
1147 ScChangeAction
* pAct
= pThisTrack
->GetLast();
1148 if ( pAct
&& pAct
->GetActionNumber() > nOldActionMax
)
1150 ULONG nActionMax
= pAct
->GetActionNumber();
1151 ULONG nActionCount
= nActionMax
- nOldActionMax
;
1152 ULONG nAction
= nActionMax
- nActionCount
+ 1;
1153 ULONG nSourceAction
= pSourceAction
->GetActionNumber() - nActionCount
+ 1;
1154 while ( nAction
<= nActionMax
)
1158 (*pMergeMap
)[ nAction
++ ] = nSourceAction
++;
1162 (*pMergeMap
)[ nSourceAction
++ ] = nAction
++;
1168 aProgress
.SetStateCountDown( --nNewActionCount
);
1170 pSourceAction
= pSourceAction
->GetNext();
1173 rMarkData
= aOldMarkData
;
1174 pThisTrack
->SetUser(aOldUser
);
1175 pThisTrack
->SetUseFixDateTime( FALSE
);
1177 pSourceTrack
->Clear(); //! der ist jetzt verhunzt
1180 PostPaintGridAll(); // Reject() paintet nicht selber
1185 bool ScDocShell::MergeSharedDocument( ScDocShell
* pSharedDocShell
)
1187 if ( !pSharedDocShell
)
1192 ScChangeTrack
* pThisTrack
= aDocument
.GetChangeTrack();
1198 ScDocument
& rSharedDoc
= *( pSharedDocShell
->GetDocument() );
1199 ScChangeTrack
* pSharedTrack
= rSharedDoc
.GetChangeTrack();
1200 if ( !pSharedTrack
)
1205 #if DEBUG_CHANGETRACK
1206 ::rtl::OUString aMessage
= ::rtl::OUString::createFromAscii( "\nbefore merge:\n" );
1207 aMessage
+= pThisTrack
->ToString();
1208 ::rtl::OString aMsg
= ::rtl::OUStringToOString( aMessage
, RTL_TEXTENCODING_UTF8
);
1209 OSL_ENSURE( false, aMsg
.getStr() );
1210 //fprintf( stdout, "%s ", aMsg.getStr() );
1212 #endif // DEBUG_CHANGETRACK
1214 // reset show changes
1215 ScChangeViewSettings aChangeViewSet
;
1216 aChangeViewSet
.SetShowChanges( FALSE
);
1217 aDocument
.SetChangeViewSettings( aChangeViewSet
);
1219 // find first merge action in this document
1220 BOOL bIgnore100Sec
= !pThisTrack
->IsTime100thSeconds() || !pSharedTrack
->IsTime100thSeconds();
1221 ScChangeAction
* pThisAction
= pThisTrack
->GetFirst();
1222 ScChangeAction
* pSharedAction
= pSharedTrack
->GetFirst();
1223 while ( lcl_Equal( pThisAction
, pSharedAction
, bIgnore100Sec
) )
1225 pThisAction
= pThisAction
->GetNext();
1226 pSharedAction
= pSharedAction
->GetNext();
1229 if ( pSharedAction
)
1233 // merge own changes into shared document
1234 ULONG nActStartShared
= pSharedAction
->GetActionNumber();
1235 ULONG nActEndShared
= pSharedTrack
->GetActionMax();
1236 ScDocument
* pTmpDoc
= new ScDocument
;
1237 for ( sal_Int32 nIndex
= 0; nIndex
< aDocument
.GetTableCount(); ++nIndex
)
1240 pTmpDoc
->CreateValidTabName( sTabName
);
1241 pTmpDoc
->InsertTab( SC_TAB_APPEND
, sTabName
);
1243 aDocument
.GetChangeTrack()->Clone( pTmpDoc
);
1244 ScChangeActionMergeMap aOwnInverseMergeMap
;
1245 pSharedDocShell
->MergeDocument( *pTmpDoc
, true, true, 0, &aOwnInverseMergeMap
, true );
1247 ULONG nActStartOwn
= nActEndShared
+ 1;
1248 ULONG nActEndOwn
= pSharedTrack
->GetActionMax();
1251 ScConflictsList aConflictsList
;
1252 ScConflictsFinder
aFinder( pSharedTrack
, nActStartShared
, nActEndShared
, nActStartOwn
, nActEndOwn
, aConflictsList
);
1253 if ( aFinder
.Find() )
1255 ScConflictsListHelper::TransformConflictsList( aConflictsList
, NULL
, &aOwnInverseMergeMap
);
1260 ScConflictsDlg
aDlg( GetActiveDialogParent(), GetViewData(), &rSharedDoc
, aConflictsList
);
1261 if ( aDlg
.Execute() == RET_CANCEL
)
1263 QueryBox
aBox( GetActiveDialogParent(), WinBits( WB_YES_NO
| WB_DEF_YES
),
1264 ScGlobal::GetRscString( STR_DOC_WILLNOTBESAVED
) );
1265 if ( aBox
.Execute() == RET_YES
)
1277 // undo own changes in shared document
1278 pSharedTrack
->Undo( nActStartOwn
, nActEndOwn
);
1280 // clone change track for merging into own document
1281 pTmpDoc
= new ScDocument
;
1282 for ( sal_Int32 nIndex
= 0; nIndex
< aDocument
.GetTableCount(); ++nIndex
)
1285 pTmpDoc
->CreateValidTabName( sTabName
);
1286 pTmpDoc
->InsertTab( SC_TAB_APPEND
, sTabName
);
1288 pThisTrack
->Clone( pTmpDoc
);
1290 // undo own changes since last save in own document
1291 ULONG nStartShared
= pThisAction
->GetActionNumber();
1292 ScChangeAction
* pAction
= pThisTrack
->GetLast();
1293 while ( pAction
&& pAction
->GetActionNumber() >= nStartShared
)
1295 pThisTrack
->Reject( pAction
, true );
1296 pAction
= pAction
->GetPrev();
1299 // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
1300 pThisTrack
->Undo( nStartShared
, pThisTrack
->GetActionMax(), true );
1302 // merge shared changes into own document
1303 ScChangeActionMergeMap aSharedMergeMap
;
1304 MergeDocument( rSharedDoc
, true, true, 0, &aSharedMergeMap
);
1305 ULONG nEndShared
= pThisTrack
->GetActionMax();
1307 // resolve conflicts for shared non-content actions
1308 if ( !aConflictsList
.empty() )
1310 ScConflictsListHelper::TransformConflictsList( aConflictsList
, &aSharedMergeMap
, NULL
);
1311 ScConflictsResolver
aResolver( pThisTrack
, aConflictsList
);
1312 pAction
= pThisTrack
->GetAction( nEndShared
);
1313 while ( pAction
&& pAction
->GetActionNumber() >= nStartShared
)
1315 aResolver
.HandleAction( pAction
, true /*bIsSharedAction*/,
1316 false /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
1317 pAction
= pAction
->GetPrev();
1320 nEndShared
= pThisTrack
->GetActionMax();
1322 // only show changes from shared document
1323 aChangeViewSet
.SetShowChanges( TRUE
);
1324 aChangeViewSet
.SetShowAccepted( TRUE
);
1325 aChangeViewSet
.SetHasActionRange( true );
1326 aChangeViewSet
.SetTheActionRange( nStartShared
, nEndShared
);
1327 aDocument
.SetChangeViewSettings( aChangeViewSet
);
1329 // merge own changes back into own document
1330 ULONG nStartOwn
= nEndShared
+ 1;
1331 ScChangeActionMergeMap aOwnMergeMap
;
1332 MergeDocument( *pTmpDoc
, true, true, nEndShared
- nStartShared
+ 1, &aOwnMergeMap
);
1334 ULONG nEndOwn
= pThisTrack
->GetActionMax();
1336 // resolve conflicts for shared content actions and own actions
1337 if ( !aConflictsList
.empty() )
1339 ScConflictsListHelper::TransformConflictsList( aConflictsList
, NULL
, &aOwnMergeMap
);
1340 ScConflictsResolver
aResolver( pThisTrack
, aConflictsList
);
1341 pAction
= pThisTrack
->GetAction( nEndShared
);
1342 while ( pAction
&& pAction
->GetActionNumber() >= nStartShared
)
1344 aResolver
.HandleAction( pAction
, true /*bIsSharedAction*/,
1345 true /*bHandleContentAction*/, false /*bHandleNonContentAction*/ );
1346 pAction
= pAction
->GetPrev();
1349 pAction
= pThisTrack
->GetAction( nEndOwn
);
1350 while ( pAction
&& pAction
->GetActionNumber() >= nStartOwn
)
1352 aResolver
.HandleAction( pAction
, false /*bIsSharedAction*/,
1353 true /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
1354 pAction
= pAction
->GetPrev();
1357 nEndOwn
= pThisTrack
->GetActionMax();
1361 // merge shared changes into own document
1362 ULONG nStartShared
= pThisTrack
->GetActionMax() + 1;
1363 MergeDocument( rSharedDoc
, true, true );
1364 ULONG nEndShared
= pThisTrack
->GetActionMax();
1366 // only show changes from shared document
1367 aChangeViewSet
.SetShowChanges( TRUE
);
1368 aChangeViewSet
.SetShowAccepted( TRUE
);
1369 aChangeViewSet
.SetHasActionRange( true );
1370 aChangeViewSet
.SetTheActionRange( nStartShared
, nEndShared
);
1371 aDocument
.SetChangeViewSettings( aChangeViewSet
);
1378 InfoBox
aInfoBox( GetActiveDialogParent(), ScGlobal::GetRscString( STR_DOC_UPDATED
) );
1382 #if DEBUG_CHANGETRACK
1383 aMessage
= ::rtl::OUString::createFromAscii( "\nafter merge:\n" );
1384 aMessage
+= pThisTrack
->ToString();
1385 aMsg
= ::rtl::OUStringToOString( aMessage
, RTL_TEXTENCODING_UTF8
);
1386 OSL_ENSURE( false, aMsg
.getStr() );
1387 //fprintf( stdout, "%s ", aMsg.getStr() );
1389 #endif // DEBUG_CHANGETRACK
1391 return ( pThisAction
!= NULL
);