summaryrefslogtreecommitdiff
path: root/sc/source/ui/docshell/docsh3.cxx
diff options
context:
space:
mode:
authorKurt Zenker <kz@openoffice.org>2008-03-07 11:19:32 +0000
committerKurt Zenker <kz@openoffice.org>2008-03-07 11:19:32 +0000
commit580a0790a35cacd5a2d1956244b4cba726c65db2 (patch)
treea02b492ead07ef7cd1e9c027a1c0ef3042937b81 /sc/source/ui/docshell/docsh3.cxx
parentc043dad1266a37256d7f88878e89f0a277b97902 (diff)
INTEGRATION: CWS calcshare_DEV300 (1.30.52); FILE MERGED
2008/02/28 13:20:30 tbe 1.30.52.12: #i8811# Allow multiple users to edit the same spreadsheet through workbook sharing 2008/02/23 11:42:08 tbe 1.30.52.11: #i8811# Allow multiple users to edit the same spreadsheet through workbook sharing 2008/02/20 12:41:48 tbe 1.30.52.10: ##i8811# Allow multiple users to edit the same spreadsheet through workbook sharing 2008/02/15 16:12:11 tbe 1.30.52.9: #i8811# Allow multiple users to edit the same spreadsheet through workbook sharing 2008/02/06 11:04:06 tbe 1.30.52.8: #i8811# Allow multiple users to edit the same spreadsheet through workbook sharing 2008/02/04 10:30:38 tbe 1.30.52.7: RESYNC: (1.30-1.32); FILE MERGED 2008/01/30 12:56:35 tbe 1.30.52.6: #i8811# Allow multiple users to edit the same spreadsheet through workbook sharing 2008/01/09 16:09:08 tbe 1.30.52.5: #i8811# Allow multiple users to edit the same spreadsheet through workbook sharing 2007/12/19 14:21:43 tbe 1.30.52.4: #i8811# Allow multiple users to edit the same spreadsheet through workbook sharing 2007/12/13 09:49:49 tbe 1.30.52.3: #i8811# Allow multiple users to edit the same spreadsheet through workbook sharing 2007/12/11 15:33:29 tbe 1.30.52.2: #i8811# Allow multiple users to edit the same spreadsheet through workbook sharing 2007/12/04 13:16:18 tbe 1.30.52.1: #i8811# Allow multiple users to edit the same spreadsheet through workbook sharing
Diffstat (limited to 'sc/source/ui/docshell/docsh3.cxx')
-rw-r--r--sc/source/ui/docshell/docsh3.cxx301
1 files changed, 281 insertions, 20 deletions
diff --git a/sc/source/ui/docshell/docsh3.cxx b/sc/source/ui/docshell/docsh3.cxx
index 24ce231cd7c0..ecdbbfbc8569 100644
--- a/sc/source/ui/docshell/docsh3.cxx
+++ b/sc/source/ui/docshell/docsh3.cxx
@@ -4,9 +4,9 @@
*
* $RCSfile: docsh3.cxx,v $
*
- * $Revision: 1.34 $
+ * $Revision: 1.35 $
*
- * last change: $Author: kz $ $Date: 2008-03-06 16:12:05 $
+ * last change: $Author: kz $ $Date: 2008-03-07 12:19:32 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
@@ -89,6 +89,8 @@
#include "inputopt.hxx"
#include "drwlayer.hxx"
#include "inputhdl.hxx"
+#include "conflictsdlg.hxx"
+#include "globstr.hrc"
//------------------------------------------------------------------
@@ -771,7 +773,40 @@ inline BOOL lcl_Equal( const ScChangeAction* pA, const ScChangeAction* pB, BOOL
// State nicht vergleichen, falls eine alte Aenderung akzeptiert wurde
}
-void ScDocShell::MergeDocument( ScDocument& rOtherDoc )
+bool lcl_FindAction( ScDocument* pDoc, const ScChangeAction* pAction, ScDocument* pSearchDoc, const ScChangeAction* pFirstSearchAction, BOOL bIgnore100Sec )
+{
+ if ( !pDoc || !pAction || !pSearchDoc || !pFirstSearchAction )
+ {
+ return false;
+ }
+
+ const ScChangeAction* pA = pFirstSearchAction;
+ while ( pA )
+ {
+ if ( pAction->GetType() == pA->GetType() &&
+ pAction->GetUser() == pA->GetUser() &&
+ (bIgnore100Sec ?
+ pAction->GetDateTimeUTC().IsEqualIgnore100Sec( pA->GetDateTimeUTC() ) :
+ pAction->GetDateTimeUTC() == pA->GetDateTimeUTC() ) &&
+ pAction->GetBigRange() == pA->GetBigRange() )
+ {
+ String aActionDesc;
+ pAction->GetDescription( aActionDesc, pDoc, TRUE );
+ String aADesc;
+ pA->GetDescription( aADesc, pSearchDoc, TRUE );
+ if ( aActionDesc.Equals( aADesc ) )
+ {
+ DBG_ERROR( "lcl_FindAction(): found equal action!" );
+ return true;
+ }
+ }
+ pA = pA->GetNext();
+ }
+
+ return false;
+}
+
+void ScDocShell::MergeDocument( ScDocument& rOtherDoc, bool bShared, bool bCheckDuplicates, ULONG nOffset )
{
ScTabViewShell* pViewSh = GetBestViewShell(); //! Funktionen an die DocShell
if (!pViewSh)
@@ -787,10 +822,13 @@ void ScDocShell::MergeDocument( ScDocument& rOtherDoc )
aDocument.StartChangeTracking();
pThisTrack = aDocument.GetChangeTrack();
DBG_ASSERT(pThisTrack,"ChangeTracking nicht angeschaltet?");
- // #51138# visuelles RedLining einschalten
- ScChangeViewSettings aChangeViewSet;
- aChangeViewSet.SetShowChanges(TRUE);
- aDocument.SetChangeViewSettings(aChangeViewSet);
+ if ( !bShared )
+ {
+ // #51138# visuelles RedLining einschalten
+ ScChangeViewSettings aChangeViewSet;
+ aChangeViewSet.SetShowChanges(TRUE);
+ aDocument.SetChangeViewSettings(aChangeViewSet);
+ }
}
@@ -816,12 +854,13 @@ void ScDocShell::MergeDocument( ScDocument& rOtherDoc )
const ScChangeAction* pFirstMergeAction = pSourceAction;
+ const ScChangeAction* pFirstSearchAction = pThisAction;
// MergeChangeData aus den folgenden Aktionen erzeugen
ULONG nNewActionCount = 0;
const ScChangeAction* pCount = pSourceAction;
while ( pCount )
{
- if ( !ScChangeTrack::MergeIgnore( *pCount, nFirstNewNumber ) )
+ if ( bShared || !ScChangeTrack::MergeIgnore( *pCount, nFirstNewNumber ) )
++nNewActionCount;
pCount = pCount->GetNext();
}
@@ -888,10 +927,26 @@ void ScDocShell::MergeDocument( ScDocument& rOtherDoc )
pSourceAction = pFirstMergeAction;
while ( pSourceAction && pSourceAction->GetActionNumber() <= nLastMergeAction )
{
- if ( !ScChangeTrack::MergeIgnore( *pSourceAction, nFirstNewNumber ) )
+ bool bMergeAction = false;
+ if ( bShared )
+ {
+ if ( !bCheckDuplicates || !lcl_FindAction( &rOtherDoc, pSourceAction, &aDocument, pFirstSearchAction, bIgnore100Sec ) )
+ {
+ bMergeAction = true;
+ }
+ }
+ else
+ {
+ if ( !ScChangeTrack::MergeIgnore( *pSourceAction, nFirstNewNumber ) )
+ {
+ bMergeAction = true;
+ }
+ }
+
+ if ( bMergeAction )
{
ScChangeActionType eSourceType = pSourceAction->GetType();
- if ( pSourceAction->IsDeletedIn() )
+ if ( !bShared && pSourceAction->IsDeletedIn() )
{
//! muss hier noch festgestellt werden, ob wirklich in
//! _diesem_ Dokument geloescht?
@@ -917,22 +972,42 @@ void ScDocShell::MergeDocument( ScDocument& rOtherDoc )
pThisTrack->SetFixDateTimeUTC( pSourceAction->GetDateTimeUTC() );
ULONG nNextAction = pThisTrack->GetActionMax() + 1;
+ bool bExecute = true;
ULONG nReject = pSourceAction->GetRejectAction();
- if (nReject)
+ if ( nReject )
{
- // alte Aktion (aus den gemeinsamen) ablehnen
- ScChangeAction* pOldAction = pThisTrack->GetAction( nReject );
- if (pOldAction && pOldAction->GetState() == SC_CAS_VIRGIN)
+ if ( bShared )
{
- //! was passiert bei Aktionen, die in diesem Dokument accepted worden sind???
- //! Fehlermeldung oder was???
- //! oder Reject-Aenderung normal ausfuehren
+ if ( nReject >= nFirstNewNumber )
+ {
+ nReject += nOffset;
+ }
+ ScChangeAction* pOldAction = pThisTrack->GetAction( nReject );
+ if ( pOldAction && pOldAction->GetState() == SC_CAS_VIRGIN )
+ {
+ pThisTrack->Reject( pOldAction );
+ bHasRejected = TRUE;
+ bExecute = false;
+ }
+ }
+ else
+ {
+ // alte Aktion (aus den gemeinsamen) ablehnen
+ ScChangeAction* pOldAction = pThisTrack->GetAction( nReject );
+ if (pOldAction && pOldAction->GetState() == SC_CAS_VIRGIN)
+ {
+ //! was passiert bei Aktionen, die in diesem Dokument accepted worden sind???
+ //! Fehlermeldung oder was???
+ //! oder Reject-Aenderung normal ausfuehren
- pThisTrack->Reject(pOldAction);
- bHasRejected = TRUE; // fuer Paint
+ pThisTrack->Reject(pOldAction);
+ bHasRejected = TRUE; // fuer Paint
+ }
+ bExecute = false;
}
}
- else
+
+ if ( bExecute )
{
// normal ausfuehren
ScRange aSourceRange = pSourceAction->GetBigRange().MakeRange();
@@ -1063,7 +1138,193 @@ void ScDocShell::MergeDocument( ScDocument& rOtherDoc )
UnlockPaint();
}
+void lcl_MergeActionStates( ScChangeTrack* pOwnTrack, ScChangeTrack* pSharedTrack )
+{
+ BOOL bIgnore100Sec = !pOwnTrack->IsTime100thSeconds() || !pSharedTrack->IsTime100thSeconds();
+ ScChangeAction* pOwnAction = pOwnTrack->GetFirst();
+ ScChangeAction* pSharedAction = pSharedTrack->GetFirst();
+ while ( lcl_Equal( pOwnAction, pSharedAction, bIgnore100Sec ) )
+ {
+ pOwnTrack->MergeActionState( pOwnAction, pSharedAction );
+ pOwnAction = pOwnAction->GetNext();
+ pSharedAction = pSharedAction->GetNext();
+ }
+}
+
+bool ScDocShell::MergeSharedDocument( ScDocument& rSharedDoc )
+{
+ ScChangeTrack* pThisTrack = aDocument.GetChangeTrack();
+ if ( !pThisTrack )
+ {
+ return false;
+ }
+ ScChangeTrack* pSharedTrack = rSharedDoc.GetChangeTrack();
+ if ( !pSharedTrack )
+ {
+ return false;
+ }
+ if ( getenv( "DEBUG_CHANGETRACK" ) != NULL )
+ {
+ ::rtl::OUString aMessage = ::rtl::OUString::createFromAscii( "\nbefore merge:\n" );
+ aMessage += pThisTrack->toString();
+ OSL_ENSURE( false, ::rtl::OUStringToOString( aMessage, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ }
+ // reset show changes
+ ScChangeViewSettings aChangeViewSet;
+ aChangeViewSet.SetShowChanges( FALSE );
+ aDocument.SetChangeViewSettings( aChangeViewSet );
+ // find first merge action in this document
+ BOOL bIgnore100Sec = !pThisTrack->IsTime100thSeconds() || !pSharedTrack->IsTime100thSeconds();
+ ScChangeAction* pThisAction = pThisTrack->GetFirst();
+ ScChangeAction* pSharedAction = pSharedTrack->GetFirst();
+ while ( lcl_Equal( pThisAction, pSharedAction, bIgnore100Sec ) )
+ {
+ pThisAction = pThisAction->GetNext();
+ pSharedAction = pSharedAction->GetNext();
+ }
+
+ if ( pSharedAction )
+ {
+ if ( pThisAction )
+ {
+ ScConflictsList aConflictsList;
+ ScConflictsFinder aFinder( pSharedTrack, pSharedAction->GetActionNumber(), pSharedTrack->GetActionMax(), pThisTrack, pThisAction->GetActionNumber(), pThisTrack->GetActionMax(), aConflictsList );
+ if ( aFinder.Find() )
+ {
+ bool bLoop = true;
+ while ( bLoop )
+ {
+ bLoop = false;
+ ScConflictsDlg aDlg( GetActiveDialogParent(), GetViewData(), &rSharedDoc, aConflictsList );
+ if ( aDlg.Execute() == RET_CANCEL )
+ {
+ QueryBox aBox( GetActiveDialogParent(), WinBits( WB_YES_NO | WB_DEF_YES ),
+ ScGlobal::GetRscString( STR_DOC_WILLNOTBESAVED ) );
+ if ( aBox.Execute() == RET_YES )
+ {
+ return false;
+ }
+ else
+ {
+ bLoop = true;
+ }
+ }
+ }
+ }
+
+ // create temp document with cloned change track
+ ScDocument* pTmpDoc = new ScDocument;
+ SCTAB nOrigCount = aDocument.GetTableCount();
+ String sTabName;
+ for ( sal_Int32 nIndex = 0; nIndex < nOrigCount; ++nIndex )
+ {
+ pTmpDoc->CreateValidTabName( sTabName );
+ pTmpDoc->InsertTab( SC_TAB_APPEND, sTabName );
+ }
+ pThisTrack->Clone( pTmpDoc );
+
+ // undo own change actions since last save
+ ULONG nStartShared = pThisAction->GetActionNumber();
+ ScChangeAction* pAction = pThisTrack->GetLast();
+ while ( pAction && pAction->GetActionNumber() >= nStartShared )
+ {
+ pThisTrack->Reject( pAction );
+ pAction = pAction->GetPrev();
+ }
+ pThisTrack->Undo( nStartShared, pThisTrack->GetActionMax() );
+
+ // merge changes from shared document
+ MergeDocument( rSharedDoc, true );
+ ULONG nEndShared = pThisTrack->GetActionMax();
+
+ // resolve conflicts for shared non-content actions
+ if ( !aConflictsList.empty() )
+ {
+ ScConflictsResolver aResolver( pThisTrack, aConflictsList );
+ ULONG nOffset = 0;
+ pAction = pThisTrack->GetAction( nStartShared );
+ while ( pAction && pAction->GetActionNumber() <= nEndShared )
+ {
+ aResolver.HandleAction( pAction, nOffset, true /*bIsSharedAction*/,
+ false /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
+ pAction = pAction->GetNext();
+ }
+ }
+ nEndShared = pThisTrack->GetActionMax();
+
+ // only show changes from shared document
+ aChangeViewSet.SetShowChanges( TRUE );
+ aChangeViewSet.SetShowAccepted( TRUE );
+ aChangeViewSet.SetHasActionRange( true );
+ aChangeViewSet.SetTheActionRange( nStartShared, nEndShared );
+ aDocument.SetChangeViewSettings( aChangeViewSet );
+
+ // merge changes from temp document
+ ULONG nStartOwn = pThisTrack->GetActionMax() + 1;
+ MergeDocument( *pTmpDoc, true, true, nEndShared - nStartShared + 1 );
+ delete pTmpDoc;
+ ULONG nEndOwn = pThisTrack->GetActionMax();
+
+ // resolve conflicts for shared content actions and own actions
+ if ( !aConflictsList.empty() )
+ {
+ ScConflictsResolver aResolver( pThisTrack, aConflictsList );
+ ULONG nOffset = 0;
+ pAction = pThisTrack->GetAction( nStartShared );
+ while ( pAction && pAction->GetActionNumber() <= nEndShared )
+ {
+ aResolver.HandleAction( pAction, nOffset, true /*bIsSharedAction*/,
+ true /*bHandleContentAction*/, false /*bHandleNonContentAction*/ );
+ pAction = pAction->GetNext();
+ }
+
+ nOffset = nEndShared - nStartShared + 1;
+ pAction = pThisTrack->GetAction( nStartOwn );
+ while ( pAction && pAction->GetActionNumber() <= nEndOwn )
+ {
+ aResolver.HandleAction( pAction, nOffset, false /*bIsSharedAction*/,
+ true /*bHandleContentAction*/, true /*bHandleNonContentAction*/ );
+ pAction = pAction->GetNext();
+ }
+ }
+ nEndOwn = pThisTrack->GetActionMax();
+ }
+ else
+ {
+ // merge changes from shared document
+ ULONG nStartShared = pThisTrack->GetActionMax() + 1;
+ MergeDocument( rSharedDoc, true );
+ ULONG nEndShared = pThisTrack->GetActionMax();
+
+ // only show changes from shared document
+ aChangeViewSet.SetShowChanges( TRUE );
+ aChangeViewSet.SetShowAccepted( TRUE );
+ aChangeViewSet.SetHasActionRange( true );
+ aChangeViewSet.SetTheActionRange( nStartShared, nEndShared );
+ aDocument.SetChangeViewSettings( aChangeViewSet );
+ }
+
+ // merge action states
+ lcl_MergeActionStates( pThisTrack, pSharedTrack );
+
+ // update view
+ PostPaintExtras();
+ PostPaintGridAll();
+
+ InfoBox aInfoBox( GetActiveDialogParent(), ScGlobal::GetRscString( STR_DOC_UPDATED ) );
+ aInfoBox.Execute();
+ }
+
+ if ( getenv( "DEBUG_CHANGETRACK" ) != NULL )
+ {
+ ::rtl::OUString aMessage = ::rtl::OUString::createFromAscii( "\nafter merge:\n" );
+ aMessage += pThisTrack->toString();
+ OSL_ENSURE( false, ::rtl::OUStringToOString( aMessage, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ }
+
+ return ( pThisAction != NULL );
+}