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 SfxPrinter
*pOld
= aDocument
.GetPrinter( FALSE
);
487 if ( pOld
&& pOld
->IsPrinting() )
488 return SFX_PRINTERROR_BUSY
;
490 if (nDiffFlags
& SFX_PRINTER_PRINTER
)
492 if ( aDocument
.GetPrinter() != pNewPrinter
)
494 aDocument
.SetPrinter( pNewPrinter
);
495 aDocument
.SetPrintOptions();
497 // MT: Use UpdateFontList: Will use Printer fonts only if needed!
499 delete pImpl->pFontList;
500 pImpl->pFontList = new FontList( pNewPrinter, Application::GetDefaultDevice() );
501 SvxFontListItem aFontListItem( pImpl->pFontList, SID_ATTR_CHAR_FONTLIST );
502 PutItem( aFontListItem );
506 if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
509 ScModule
* pScMod
= SC_MOD();
510 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( this );
513 SfxViewShell
* pSh
= pFrame
->GetViewShell();
514 if (pSh
&& pSh
->ISA(ScTabViewShell
))
516 ScTabViewShell
* pViewSh
= (ScTabViewShell
*)pSh
;
517 ScInputHandler
* pInputHdl
= pScMod
->GetInputHdl(pViewSh
);
519 pInputHdl
->UpdateRefDevice();
521 pFrame
= SfxViewFrame::GetNext( *pFrame
, this );
525 else if (nDiffFlags
& SFX_PRINTER_JOBSETUP
)
527 SfxPrinter
* pOldPrinter
= aDocument
.GetPrinter();
530 pOldPrinter
->SetJobSetup( pNewPrinter
->GetJobSetup() );
532 // #i6706# Call SetPrinter with the old printer again, so the drawing layer
533 // RefDevice is set (calling ReformatAllTextObjects and rebuilding charts),
534 // because the JobSetup (printer device settings) may affect text layout.
535 aDocument
.SetPrinter( pOldPrinter
);
536 CalcOutputFactor(); // also with the new settings
540 if (nDiffFlags
& SFX_PRINTER_OPTIONS
)
542 aDocument
.SetPrintOptions(); //! aus neuem Printer ???
545 if (nDiffFlags
& (SFX_PRINTER_CHG_ORIENTATION
| SFX_PRINTER_CHG_SIZE
))
547 String aStyle
= aDocument
.GetPageStyle( GetCurTab() );
548 ScStyleSheetPool
* pStPl
= aDocument
.GetStyleSheetPool();
549 SfxStyleSheet
* pStyleSheet
= (SfxStyleSheet
*)pStPl
->Find(aStyle
, SFX_STYLE_FAMILY_PAGE
);
552 SfxItemSet
& rSet
= pStyleSheet
->GetItemSet();
554 if (nDiffFlags
& SFX_PRINTER_CHG_ORIENTATION
)
556 const SvxPageItem
& rOldItem
= (const SvxPageItem
&)rSet
.Get(ATTR_PAGE
);
557 BOOL bWasLand
= rOldItem
.IsLandscape();
558 BOOL bNewLand
= ( pNewPrinter
->GetOrientation() == ORIENTATION_LANDSCAPE
);
559 if (bNewLand
!= bWasLand
)
561 SvxPageItem
aNewItem( rOldItem
);
562 aNewItem
.SetLandscape( bNewLand
);
563 rSet
.Put( aNewItem
);
566 Size aOldSize
= ((const SvxSizeItem
&)rSet
.Get(ATTR_PAGE_SIZE
)).GetSize();
567 Size
aNewSize(aOldSize
.Height(),aOldSize
.Width());
568 SvxSizeItem
aNewSItem(ATTR_PAGE_SIZE
,aNewSize
);
569 rSet
.Put( aNewSItem
);
572 if (nDiffFlags
& SFX_PRINTER_CHG_SIZE
)
574 SvxSizeItem
aPaperSizeItem( ATTR_PAGE_SIZE
, SvxPaperInfo::GetPaperSize(pNewPrinter
) );
575 rSet
.Put( aPaperSizeItem
);
580 PostPaint(0,0,0,MAXCOL
,MAXROW
,MAXTAB
,PAINT_ALL
);
585 //---------------------------------------------------------------------
587 ScChangeAction
* ScDocShell::GetChangeAction( const ScAddress
& rPos
)
589 ScChangeTrack
* pTrack
= GetDocument()->GetChangeTrack();
593 SCTAB nTab
= rPos
.Tab();
595 const ScChangeAction
* pFound
= NULL
;
596 const ScChangeAction
* pFoundContent
= NULL
;
597 const ScChangeAction
* pFoundMove
= NULL
;
599 const ScChangeAction
* pAction
= pTrack
->GetFirst();
602 ScChangeActionType eType
= pAction
->GetType();
603 //! ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc )...
604 if ( pAction
->IsVisible() && eType
!= SC_CAT_DELETE_TABS
)
606 const ScBigRange
& rBig
= pAction
->GetBigRange();
607 if ( rBig
.aStart
.Tab() == nTab
)
609 ScRange aRange
= rBig
.MakeRange();
611 if ( eType
== SC_CAT_DELETE_ROWS
)
612 aRange
.aEnd
.SetRow( aRange
.aStart
.Row() );
613 else if ( eType
== SC_CAT_DELETE_COLS
)
614 aRange
.aEnd
.SetCol( aRange
.aStart
.Col() );
616 if ( aRange
.In( rPos
) )
618 pFound
= pAction
; // der letzte gewinnt
619 switch ( pAction
->GetType() )
621 case SC_CAT_CONTENT
:
622 pFoundContent
= pAction
;
625 pFoundMove
= pAction
;
629 // added to avoid warnings
635 if ( pAction
->GetType() == SC_CAT_MOVE
)
638 ((const ScChangeActionMove
*)pAction
)->
639 GetFromRange().MakeRange();
640 if ( aRange
.In( rPos
) )
647 pAction
= pAction
->GetNext();
650 return (ScChangeAction
*)pFound
;
653 void ScDocShell::SetChangeComment( ScChangeAction
* pAction
, const String
& rComment
)
657 pAction
->SetComment( rComment
);
659 SetDocumentModified();
662 ScChangeTrack
* pTrack
= GetDocument()->GetChangeTrack();
665 ULONG nNumber
= pAction
->GetActionNumber();
666 pTrack
->NotifyModified( SC_CTM_CHANGE
, nNumber
, nNumber
);
671 void ScDocShell::ExecuteChangeCommentDialog( ScChangeAction
* pAction
, Window
* pParent
,BOOL bPrevNext
)
673 if (!pAction
) return; // ohne Aktion ist nichts..
675 String aComment
= pAction
->GetComment();
676 String aAuthor
= pAction
->GetUser();
678 DateTime aDT
= pAction
->GetDateTime();
679 String aDate
= ScGlobal::pLocaleData
->getDate( aDT
);
681 aDate
+= ScGlobal::pLocaleData
->getTime( aDT
, FALSE
, FALSE
);
683 SfxItemSet
aSet( GetPool(),
684 SID_ATTR_POSTIT_AUTHOR
, SID_ATTR_POSTIT_AUTHOR
,
685 SID_ATTR_POSTIT_DATE
, SID_ATTR_POSTIT_DATE
,
686 SID_ATTR_POSTIT_TEXT
, SID_ATTR_POSTIT_TEXT
,
689 aSet
.Put( SvxPostItTextItem ( aComment
, SID_ATTR_POSTIT_TEXT
) );
690 aSet
.Put( SvxPostItAuthorItem( aAuthor
, SID_ATTR_POSTIT_AUTHOR
) );
691 aSet
.Put( SvxPostItDateItem ( aDate
, SID_ATTR_POSTIT_DATE
) );
693 ScRedComDialog
* pDlg
= new ScRedComDialog( pParent
, aSet
,this,pAction
,bPrevNext
);
700 //---------------------------------------------------------------------
702 void ScDocShell::CompareDocument( ScDocument
& rOtherDoc
)
704 ScChangeTrack
* pTrack
= aDocument
.GetChangeTrack();
705 if ( pTrack
&& pTrack
->GetFirst() )
707 //! Changes vorhanden -> Nachfrage ob geloescht werden soll
710 aDocument
.EndChangeTracking();
711 aDocument
.StartChangeTracking();
714 pTrack
= aDocument
.GetChangeTrack();
717 aOldUser
= pTrack
->GetUser();
719 // check if comparing to same document
722 const SfxMedium
* pThisMed
= GetMedium();
724 aThisFile
= pThisMed
->GetName();
726 SfxObjectShell
* pOtherSh
= rOtherDoc
.GetDocumentShell();
729 const SfxMedium
* pOtherMed
= pOtherSh
->GetMedium();
731 aOtherFile
= pOtherMed
->GetName();
733 BOOL bSameDoc
= ( aThisFile
== aOtherFile
&& aThisFile
.Len() );
736 // create change actions from comparing with the name of the user
737 // who last saved the document
738 // (only if comparing different documents)
740 using namespace ::com::sun::star
;
741 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
742 GetModel(), uno::UNO_QUERY_THROW
);
743 uno::Reference
<document::XDocumentProperties
> xDocProps(
744 xDPS
->getDocumentProperties());
745 DBG_ASSERT(xDocProps
.is(), "no DocumentProperties");
746 String aDocUser
= xDocProps
->getModifiedBy();
748 if ( aDocUser
.Len() )
749 pTrack
->SetUser( aDocUser
);
753 aDocument
.CompareDocument( rOtherDoc
);
755 pTrack
= aDocument
.GetChangeTrack();
757 pTrack
->SetUser( aOldUser
);
760 SetDocumentModified();
763 //---------------------------------------------------------------------
765 // Merge (Aenderungen zusammenfuehren)
767 //---------------------------------------------------------------------
769 inline BOOL
lcl_Equal( const ScChangeAction
* pA
, const ScChangeAction
* pB
, BOOL bIgnore100Sec
)
772 pA
->GetActionNumber() == pB
->GetActionNumber() &&
773 pA
->GetType() == pB
->GetType() &&
774 pA
->GetUser() == pB
->GetUser() &&
776 pA
->GetDateTimeUTC().IsEqualIgnore100Sec( pB
->GetDateTimeUTC() ) :
777 pA
->GetDateTimeUTC() == pB
->GetDateTimeUTC());
778 // State nicht vergleichen, falls eine alte Aenderung akzeptiert wurde
781 bool lcl_FindAction( ScDocument
* pDoc
, const ScChangeAction
* pAction
, ScDocument
* pSearchDoc
, const ScChangeAction
* pFirstSearchAction
, const ScChangeAction
* pLastSearchAction
, BOOL bIgnore100Sec
)
783 if ( !pDoc
|| !pAction
|| !pSearchDoc
|| !pFirstSearchAction
|| !pLastSearchAction
)
788 ULONG nLastSearchAction
= pLastSearchAction
->GetActionNumber();
789 const ScChangeAction
* pA
= pFirstSearchAction
;
790 while ( pA
&& pA
->GetActionNumber() <= nLastSearchAction
)
792 if ( pAction
->GetType() == pA
->GetType() &&
793 pAction
->GetUser() == pA
->GetUser() &&
795 pAction
->GetDateTimeUTC().IsEqualIgnore100Sec( pA
->GetDateTimeUTC() ) :
796 pAction
->GetDateTimeUTC() == pA
->GetDateTimeUTC() ) &&
797 pAction
->GetBigRange() == pA
->GetBigRange() )
800 pAction
->GetDescription( aActionDesc
, pDoc
, TRUE
);
802 pA
->GetDescription( aADesc
, pSearchDoc
, TRUE
);
803 if ( aActionDesc
.Equals( aADesc
) )
805 DBG_ERROR( "lcl_FindAction(): found equal action!" );
815 void ScDocShell::MergeDocument( ScDocument
& rOtherDoc
, bool bShared
, bool bCheckDuplicates
, ULONG nOffset
, ScChangeActionMergeMap
* pMergeMap
, bool bInverseMap
)
817 ScTabViewShell
* pViewSh
= GetBestViewShell( FALSE
); //! Funktionen an die DocShell
821 ScChangeTrack
* pSourceTrack
= rOtherDoc
.GetChangeTrack();
823 return; //! nichts zu tun - Fehlermeldung?
825 ScChangeTrack
* pThisTrack
= aDocument
.GetChangeTrack();
828 aDocument
.StartChangeTracking();
829 pThisTrack
= aDocument
.GetChangeTrack();
830 DBG_ASSERT(pThisTrack
,"ChangeTracking nicht angeschaltet?");
833 // #51138# visuelles RedLining einschalten
834 ScChangeViewSettings aChangeViewSet
;
835 aChangeViewSet
.SetShowChanges(TRUE
);
836 aDocument
.SetChangeViewSettings(aChangeViewSet
);
840 // #97286# include 100th seconds in compare?
841 BOOL bIgnore100Sec
= !pSourceTrack
->IsTime100thSeconds() ||
842 !pThisTrack
->IsTime100thSeconds();
844 // gemeinsame Ausgangsposition suchen
845 ULONG nFirstNewNumber
= 0;
846 const ScChangeAction
* pSourceAction
= pSourceTrack
->GetFirst();
847 const ScChangeAction
* pThisAction
= pThisTrack
->GetFirst();
848 // skip identical actions
849 while ( lcl_Equal( pSourceAction
, pThisAction
, bIgnore100Sec
) )
851 nFirstNewNumber
= pSourceAction
->GetActionNumber() + 1;
852 pSourceAction
= pSourceAction
->GetNext();
853 pThisAction
= pThisAction
->GetNext();
855 // pSourceAction und pThisAction zeigen jetzt auf die ersten "eigenen" Aktionen
856 // Die gemeinsamen Aktionen davor interessieren ueberhaupt nicht
858 //! Abfrage, ob die Dokumente vor dem Change-Tracking gleich waren !!!
861 const ScChangeAction
* pFirstMergeAction
= pSourceAction
;
862 const ScChangeAction
* pFirstSearchAction
= pThisAction
;
864 // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
865 const ScChangeAction
* pLastSearchAction
= pThisTrack
->GetLast();
867 // MergeChangeData aus den folgenden Aktionen erzeugen
868 ULONG nNewActionCount
= 0;
869 const ScChangeAction
* pCount
= pSourceAction
;
872 if ( bShared
|| !ScChangeTrack::MergeIgnore( *pCount
, nFirstNewNumber
) )
874 pCount
= pCount
->GetNext();
876 if (!nNewActionCount
)
877 return; //! nichts zu tun - Fehlermeldung?
878 // ab hier kein return mehr
880 ScProgress
aProgress( this,
881 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("...")),
884 ULONG nLastMergeAction
= pSourceTrack
->GetLast()->GetActionNumber();
885 // UpdateReference-Undo, gueltige Referenzen fuer den letzten gemeinsamen Zustand
886 pSourceTrack
->MergePrepare( (ScChangeAction
*) pFirstMergeAction
, bShared
);
888 // MergeChangeData an alle noch folgenden Aktionen in diesem Dokument anpassen
889 // -> Referenzen gueltig fuer dieses Dokument
890 while ( pThisAction
)
892 // #i87049# [Collaboration] Conflict between delete row and insert content is not merged correctly
893 if ( !bShared
|| !ScChangeTrack::MergeIgnore( *pThisAction
, nFirstNewNumber
) )
895 ScChangeActionType eType
= pThisAction
->GetType();
898 case SC_CAT_INSERT_COLS
:
899 case SC_CAT_INSERT_ROWS
:
900 case SC_CAT_INSERT_TABS
:
901 pSourceTrack
->AppendInsert( pThisAction
->GetBigRange().MakeRange() );
903 case SC_CAT_DELETE_COLS
:
904 case SC_CAT_DELETE_ROWS
:
905 case SC_CAT_DELETE_TABS
:
907 const ScChangeActionDel
* pDel
= (const ScChangeActionDel
*) pThisAction
;
908 if ( pDel
->IsTopDelete() && !pDel
->IsTabDeleteCol() )
909 { // deleted Table enthaelt deleted Cols, die nicht
911 pSourceTrack
->AppendDeleteRange(
912 pDel
->GetOverAllRange().MakeRange(), NULL
, nStart
, nEnd
);
918 const ScChangeActionMove
* pMove
= (const ScChangeActionMove
*) pThisAction
;
919 pSourceTrack
->AppendMove( pMove
->GetFromRange().MakeRange(),
920 pMove
->GetBigRange().MakeRange(), NULL
);
925 // added to avoid warnings
929 pThisAction
= pThisAction
->GetNext();
932 LockPaint(); // #i73877# no repainting after each action
934 // MergeChangeData in das aktuelle Dokument uebernehmen
935 BOOL bHasRejected
= FALSE
;
936 String aOldUser
= pThisTrack
->GetUser();
937 pThisTrack
->SetUseFixDateTime( TRUE
);
938 ScMarkData
& rMarkData
= pViewSh
->GetViewData()->GetMarkData();
939 ScMarkData
aOldMarkData( rMarkData
);
940 pSourceAction
= pFirstMergeAction
;
941 while ( pSourceAction
&& pSourceAction
->GetActionNumber() <= nLastMergeAction
)
943 bool bMergeAction
= false;
946 if ( !bCheckDuplicates
|| !lcl_FindAction( &rOtherDoc
, pSourceAction
, &aDocument
, pFirstSearchAction
, pLastSearchAction
, bIgnore100Sec
) )
953 if ( !ScChangeTrack::MergeIgnore( *pSourceAction
, nFirstNewNumber
) )
961 ScChangeActionType eSourceType
= pSourceAction
->GetType();
962 if ( !bShared
&& pSourceAction
->IsDeletedIn() )
964 //! muss hier noch festgestellt werden, ob wirklich in
965 //! _diesem_ Dokument geloescht?
967 // liegt in einem Bereich, der in diesem Dokument geloescht wurde
968 // -> wird weggelassen
969 //! ??? Loesch-Aktion rueckgaengig machen ???
970 //! ??? Aktion irgendwo anders speichern ???
973 if ( eSourceType
== SC_CAT_CONTENT
)
974 ((const ScChangeActionContent
*)pSourceAction
)->GetNewString( aValue
);
975 ByteString
aError( aValue
, gsl_getSystemTextEncoding() );
976 aError
+= " weggelassen";
977 DBG_ERROR( aError
.GetBuffer() );
982 //! Datum/Autor/Kommentar der Source-Aktion uebernehmen!
984 pThisTrack
->SetUser( pSourceAction
->GetUser() );
985 pThisTrack
->SetFixDateTimeUTC( pSourceAction
->GetDateTimeUTC() );
986 ULONG nOldActionMax
= pThisTrack
->GetActionMax();
988 bool bExecute
= true;
989 ULONG nReject
= pSourceAction
->GetRejectAction();
994 if ( nReject
>= nFirstNewNumber
)
998 ScChangeAction
* pOldAction
= pThisTrack
->GetAction( nReject
);
999 if ( pOldAction
&& pOldAction
->IsVirgin() )
1001 pThisTrack
->Reject( pOldAction
);
1002 bHasRejected
= TRUE
;
1008 // alte Aktion (aus den gemeinsamen) ablehnen
1009 ScChangeAction
* pOldAction
= pThisTrack
->GetAction( nReject
);
1010 if (pOldAction
&& pOldAction
->GetState() == SC_CAS_VIRGIN
)
1012 //! was passiert bei Aktionen, die in diesem Dokument accepted worden sind???
1013 //! Fehlermeldung oder was???
1014 //! oder Reject-Aenderung normal ausfuehren
1016 pThisTrack
->Reject(pOldAction
);
1017 bHasRejected
= TRUE
; // fuer Paint
1025 // normal ausfuehren
1026 ScRange aSourceRange
= pSourceAction
->GetBigRange().MakeRange();
1027 rMarkData
.SelectOneTable( aSourceRange
.aStart
.Tab() );
1028 switch ( eSourceType
)
1030 case SC_CAT_CONTENT
:
1032 //! Test, ob es ganz unten im Dokument war, dann automatisches
1033 //! Zeilen-Einfuegen ???
1035 DBG_ASSERT( aSourceRange
.aStart
== aSourceRange
.aEnd
, "huch?" );
1036 ScAddress aPos
= aSourceRange
.aStart
;
1038 ((const ScChangeActionContent
*)pSourceAction
)->GetNewString( aValue
);
1039 BYTE eMatrix
= MM_NONE
;
1040 const ScBaseCell
* pCell
= ((const ScChangeActionContent
*)pSourceAction
)->GetNewCell();
1041 if ( pCell
&& pCell
->GetCellType() == CELLTYPE_FORMULA
)
1042 eMatrix
= ((const ScFormulaCell
*)pCell
)->GetMatrixFlag();
1046 pViewSh
->EnterData( aPos
.Col(), aPos
.Row(), aPos
.Tab(), aValue
);
1052 ((const ScFormulaCell
*)pCell
)->GetMatColsRows( nCols
, nRows
);
1053 aSourceRange
.aEnd
.SetCol( aPos
.Col() + nCols
- 1 );
1054 aSourceRange
.aEnd
.SetRow( aPos
.Row() + nRows
- 1 );
1055 aValue
.Erase( 0, 1 );
1056 aValue
.Erase( aValue
.Len()-1, 1 );
1057 GetDocFunc().EnterMatrix( aSourceRange
,
1058 NULL
, NULL
, aValue
, FALSE
, FALSE
,
1059 EMPTY_STRING
, formula::FormulaGrammar::GRAM_DEFAULT
);
1062 case MM_REFERENCE
: // do nothing
1065 DBG_WARNING( "MergeDocument: MatrixFlag MM_FAKE" );
1066 pViewSh
->EnterData( aPos
.Col(), aPos
.Row(), aPos
.Tab(), aValue
);
1069 DBG_ERROR( "MergeDocument: unknown MatrixFlag" );
1073 case SC_CAT_INSERT_TABS
:
1076 aDocument
.CreateValidTabName( aName
);
1077 GetDocFunc().InsertTable( aSourceRange
.aStart
.Tab(), aName
, TRUE
, FALSE
);
1080 case SC_CAT_INSERT_ROWS
:
1081 GetDocFunc().InsertCells( aSourceRange
, NULL
, INS_INSROWS
, TRUE
, FALSE
);
1083 case SC_CAT_INSERT_COLS
:
1084 GetDocFunc().InsertCells( aSourceRange
, NULL
, INS_INSCOLS
, TRUE
, FALSE
);
1086 case SC_CAT_DELETE_TABS
:
1087 GetDocFunc().DeleteTable( aSourceRange
.aStart
.Tab(), TRUE
, FALSE
);
1089 case SC_CAT_DELETE_ROWS
:
1091 const ScChangeActionDel
* pDel
= (const ScChangeActionDel
*) pSourceAction
;
1092 if ( pDel
->IsTopDelete() )
1094 aSourceRange
= pDel
->GetOverAllRange().MakeRange();
1095 GetDocFunc().DeleteCells( aSourceRange
, NULL
, DEL_DELROWS
, TRUE
, FALSE
);
1099 case SC_CAT_DELETE_COLS
:
1101 const ScChangeActionDel
* pDel
= (const ScChangeActionDel
*) pSourceAction
;
1102 if ( pDel
->IsTopDelete() && !pDel
->IsTabDeleteCol() )
1103 { // deleted Table enthaelt deleted Cols, die nicht
1104 aSourceRange
= pDel
->GetOverAllRange().MakeRange();
1105 GetDocFunc().DeleteCells( aSourceRange
, NULL
, DEL_DELCOLS
, TRUE
, FALSE
);
1111 const ScChangeActionMove
* pMove
= (const ScChangeActionMove
*) pSourceAction
;
1112 ScRange
aFromRange( pMove
->GetFromRange().MakeRange() );
1113 GetDocFunc().MoveBlock( aFromRange
,
1114 aSourceRange
.aStart
, TRUE
, TRUE
, FALSE
, FALSE
);
1119 // added to avoid warnings
1123 const String
& rComment
= pSourceAction
->GetComment();
1124 if ( rComment
.Len() )
1126 ScChangeAction
* pAct
= pThisTrack
->GetLast();
1127 if ( pAct
&& pAct
->GetActionNumber() > nOldActionMax
)
1128 pAct
->SetComment( rComment
);
1131 DBG_ERROR( "MergeDocument: wohin mit dem Kommentar?!?" );
1135 // Referenzen anpassen
1136 pSourceTrack
->MergeOwn( (ScChangeAction
*) pSourceAction
, nFirstNewNumber
, bShared
);
1138 // merge action state
1139 if ( bShared
&& !pSourceAction
->IsRejected() )
1141 ScChangeAction
* pAct
= pThisTrack
->GetLast();
1142 if ( pAct
&& pAct
->GetActionNumber() > nOldActionMax
)
1144 pThisTrack
->MergeActionState( pAct
, pSourceAction
);
1149 if ( bShared
&& pMergeMap
)
1151 ScChangeAction
* pAct
= pThisTrack
->GetLast();
1152 if ( pAct
&& pAct
->GetActionNumber() > nOldActionMax
)
1154 ULONG nActionMax
= pAct
->GetActionNumber();
1155 ULONG nActionCount
= nActionMax
- nOldActionMax
;
1156 ULONG nAction
= nActionMax
- nActionCount
+ 1;
1157 ULONG nSourceAction
= pSourceAction
->GetActionNumber() - nActionCount
+ 1;
1158 while ( nAction
<= nActionMax
)
1162 (*pMergeMap
)[ nAction
++ ] = nSourceAction
++;
1166 (*pMergeMap
)[ nSourceAction
++ ] = nAction
++;
1172 aProgress
.SetStateCountDown( --nNewActionCount
);
1174 pSourceAction
= pSourceAction
->GetNext();
1177 rMarkData
= aOldMarkData
;
1178 pThisTrack
->SetUser(aOldUser
);
1179 pThisTrack
->SetUseFixDateTime( FALSE
);
1181 pSourceTrack
->Clear(); //! der ist jetzt verhunzt
1184 PostPaintGridAll(); // Reject() paintet nicht selber
1189 bool ScDocShell::MergeSharedDocument( ScDocShell
* pSharedDocShell
)
1191 if ( !pSharedDocShell
)
1196 ScChangeTrack
* pThisTrack
= aDocument
.GetChangeTrack();
1202 ScDocument
& rSharedDoc
= *( pSharedDocShell
->GetDocument() );
1203 ScChangeTrack
* pSharedTrack
= rSharedDoc
.GetChangeTrack();
1204 if ( !pSharedTrack
)
1209 #if DEBUG_CHANGETRACK
1210 ::rtl::OUString aMessage
= ::rtl::OUString::createFromAscii( "\nbefore merge:\n" );
1211 aMessage
+= pThisTrack
->ToString();
1212 ::rtl::OString aMsg
= ::rtl::OUStringToOString( aMessage
, RTL_TEXTENCODING_UTF8
);
1213 OSL_ENSURE( false, aMsg
.getStr() );
1214 //fprintf( stdout, "%s ", aMsg.getStr() );
1216 #endif // DEBUG_CHANGETRACK
1218 // reset show changes
1219 ScChangeViewSettings aChangeViewSet
;
1220 aChangeViewSet
.SetShowChanges( FALSE
);
1221 aDocument
.SetChangeViewSettings( aChangeViewSet
);
1223 // find first merge action in this document
1224 BOOL bIgnore100Sec
= !pThisTrack
->IsTime100thSeconds() || !pSharedTrack
->IsTime100thSeconds();
1225 ScChangeAction
* pThisAction
= pThisTrack
->GetFirst();
1226 ScChangeAction
* pSharedAction
= pSharedTrack
->GetFirst();
1227 while ( lcl_Equal( pThisAction
, pSharedAction
, bIgnore100Sec
) )
1229 pThisAction
= pThisAction
->GetNext();
1230 pSharedAction
= pSharedAction
->GetNext();
1233 if ( pSharedAction
)
1237 // merge own changes into shared document
1238 ULONG nActStartShared
= pSharedAction
->GetActionNumber();
1239 ULONG nActEndShared
= pSharedTrack
->GetActionMax();
1240 ScDocument
* pTmpDoc
= new ScDocument
;
1241 for ( sal_Int32 nIndex
= 0; nIndex
< aDocument
.GetTableCount(); ++nIndex
)
1244 pTmpDoc
->CreateValidTabName( sTabName
);
1245 pTmpDoc
->InsertTab( SC_TAB_APPEND
, sTabName
);
1247 aDocument
.GetChangeTrack()->Clone( pTmpDoc
);
1248 ScChangeActionMergeMap aOwnInverseMergeMap
;
1249 pSharedDocShell
->MergeDocument( *pTmpDoc
, true, true, 0, &aOwnInverseMergeMap
, true );
1251 ULONG nActStartOwn
= nActEndShared
+ 1;
1252 ULONG nActEndOwn
= pSharedTrack
->GetActionMax();
1255 ScConflictsList aConflictsList
;
1256 ScConflictsFinder
aFinder( pSharedTrack
, nActStartShared
, nActEndShared
, nActStartOwn
, nActEndOwn
, aConflictsList
);
1257 if ( aFinder
.Find() )
1259 ScConflictsListHelper::TransformConflictsList( aConflictsList
, NULL
, &aOwnInverseMergeMap
);
1264 ScConflictsDlg
aDlg( GetActiveDialogParent(), GetViewData(), &rSharedDoc
, aConflictsList
);
1265 if ( aDlg
.Execute() == RET_CANCEL
)
1267 QueryBox
aBox( GetActiveDialogParent(), WinBits( WB_YES_NO
| WB_DEF_YES
),
1268 ScGlobal::GetRscString( STR_DOC_WILLNOTBESAVED
) );
1269 if ( aBox
.Execute() == RET_YES
)
1281 // undo own changes in shared document
1282 pSharedTrack
->Undo( nActStartOwn
, nActEndOwn
);
1284 // clone change track for merging into own document
1285 pTmpDoc
= new ScDocument
;
1286 for ( sal_Int32 nIndex
= 0; nIndex
< aDocument
.GetTableCount(); ++nIndex
)
1289 pTmpDoc
->CreateValidTabName( sTabName
);
1290 pTmpDoc
->InsertTab( SC_TAB_APPEND
, sTabName
);
1292 pThisTrack
->Clone( pTmpDoc
);
1294 // undo own changes since last save in own document
1295 ULONG nStartShared
= pThisAction
->GetActionNumber();
1296 ScChangeAction
* pAction
= pThisTrack
->GetLast();
1297 while ( pAction
&& pAction
->GetActionNumber() >= nStartShared
)
1299 pThisTrack
->Reject( pAction
, true );
1300 pAction
= pAction
->GetPrev();
1303 // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
1304 pThisTrack
->Undo( nStartShared
, pThisTrack
->GetActionMax(), true );
1306 // merge shared changes into own document
1307 ScChangeActionMergeMap aSharedMergeMap
;
1308 MergeDocument( rSharedDoc
, true, true, 0, &aSharedMergeMap
);
1309 ULONG nEndShared
= pThisTrack
->GetActionMax();
1311 // resolve conflicts for shared non-content actions
1312 if ( !aConflictsList
.empty() )
1314 ScConflictsListHelper::TransformConflictsList( aConflictsList
, &aSharedMergeMap
, NULL
);
1315 ScConflictsResolver
aResolver( pThisTrack
, aConflictsList
);
1316 pAction
= pThisTrack
->GetAction( nEndShared
);
1317 while ( pAction
&& pAction
->GetActionNumber() >= nStartShared
)
1319 aResolver
.HandleAction( pAction
, true /*bIsSharedAction*/,
1320 false /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
1321 pAction
= pAction
->GetPrev();
1324 nEndShared
= pThisTrack
->GetActionMax();
1326 // only show changes from shared document
1327 aChangeViewSet
.SetShowChanges( TRUE
);
1328 aChangeViewSet
.SetShowAccepted( TRUE
);
1329 aChangeViewSet
.SetHasActionRange( true );
1330 aChangeViewSet
.SetTheActionRange( nStartShared
, nEndShared
);
1331 aDocument
.SetChangeViewSettings( aChangeViewSet
);
1333 // merge own changes back into own document
1334 ULONG nStartOwn
= nEndShared
+ 1;
1335 ScChangeActionMergeMap aOwnMergeMap
;
1336 MergeDocument( *pTmpDoc
, true, true, nEndShared
- nStartShared
+ 1, &aOwnMergeMap
);
1338 ULONG nEndOwn
= pThisTrack
->GetActionMax();
1340 // resolve conflicts for shared content actions and own actions
1341 if ( !aConflictsList
.empty() )
1343 ScConflictsListHelper::TransformConflictsList( aConflictsList
, NULL
, &aOwnMergeMap
);
1344 ScConflictsResolver
aResolver( pThisTrack
, aConflictsList
);
1345 pAction
= pThisTrack
->GetAction( nEndShared
);
1346 while ( pAction
&& pAction
->GetActionNumber() >= nStartShared
)
1348 aResolver
.HandleAction( pAction
, true /*bIsSharedAction*/,
1349 true /*bHandleContentAction*/, false /*bHandleNonContentAction*/ );
1350 pAction
= pAction
->GetPrev();
1353 pAction
= pThisTrack
->GetAction( nEndOwn
);
1354 while ( pAction
&& pAction
->GetActionNumber() >= nStartOwn
)
1356 aResolver
.HandleAction( pAction
, false /*bIsSharedAction*/,
1357 true /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
1358 pAction
= pAction
->GetPrev();
1361 nEndOwn
= pThisTrack
->GetActionMax();
1365 // merge shared changes into own document
1366 ULONG nStartShared
= pThisTrack
->GetActionMax() + 1;
1367 MergeDocument( rSharedDoc
, true, true );
1368 ULONG nEndShared
= pThisTrack
->GetActionMax();
1370 // only show changes from shared document
1371 aChangeViewSet
.SetShowChanges( TRUE
);
1372 aChangeViewSet
.SetShowAccepted( TRUE
);
1373 aChangeViewSet
.SetHasActionRange( true );
1374 aChangeViewSet
.SetTheActionRange( nStartShared
, nEndShared
);
1375 aDocument
.SetChangeViewSettings( aChangeViewSet
);
1382 InfoBox
aInfoBox( GetActiveDialogParent(), ScGlobal::GetRscString( STR_DOC_UPDATED
) );
1386 #if DEBUG_CHANGETRACK
1387 aMessage
= ::rtl::OUString::createFromAscii( "\nafter merge:\n" );
1388 aMessage
+= pThisTrack
->ToString();
1389 aMsg
= ::rtl::OUStringToOString( aMessage
, RTL_TEXTENCODING_UTF8
);
1390 OSL_ENSURE( false, aMsg
.getStr() );
1391 //fprintf( stdout, "%s ", aMsg.getStr() );
1393 #endif // DEBUG_CHANGETRACK
1395 return ( pThisAction
!= NULL
);