644 lines
22 KiB
C++
644 lines
22 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <comphelper/string.hxx>
|
|
#include <osl/diagnose.h>
|
|
|
|
#include <conflictsdlg.hxx>
|
|
#include <o3tl/safeint.hxx>
|
|
#include <strings.hrc>
|
|
#include <scresid.hxx>
|
|
#include <viewdata.hxx>
|
|
#include <dbfunc.hxx>
|
|
#include <chgtrack.hxx>
|
|
|
|
// struct ScConflictsListEntry
|
|
|
|
bool ScConflictsListEntry::HasSharedAction( sal_uLong nSharedAction ) const
|
|
{
|
|
auto aEnd = maSharedActions.cend();
|
|
auto aItr = std::find(maSharedActions.cbegin(), aEnd, nSharedAction);
|
|
|
|
return aItr != aEnd;
|
|
}
|
|
|
|
bool ScConflictsListEntry::HasOwnAction( sal_uLong nOwnAction ) const
|
|
{
|
|
auto aEnd = maOwnActions.cend();
|
|
auto aItr = std::find(maOwnActions.cbegin(), aEnd, nOwnAction);
|
|
|
|
return aItr != aEnd;
|
|
}
|
|
|
|
|
|
bool ScConflictsListHelper::HasOwnAction( ScConflictsList& rConflictsList, sal_uLong nOwnAction )
|
|
{
|
|
return std::any_of(rConflictsList.begin(), rConflictsList.end(),
|
|
[nOwnAction](ScConflictsListEntry& rConflict) { return rConflict.HasOwnAction( nOwnAction ); });
|
|
}
|
|
|
|
ScConflictsListEntry* ScConflictsListHelper::GetSharedActionEntry( ScConflictsList& rConflictsList, sal_uLong nSharedAction )
|
|
{
|
|
auto aEnd = rConflictsList.end();
|
|
auto aItr = std::find_if(rConflictsList.begin(), aEnd,
|
|
[nSharedAction](ScConflictsListEntry& rConflict) { return rConflict.HasSharedAction( nSharedAction ); });
|
|
|
|
if (aItr != aEnd)
|
|
return &(*aItr);
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
ScConflictsListEntry* ScConflictsListHelper::GetOwnActionEntry( ScConflictsList& rConflictsList, sal_uLong nOwnAction )
|
|
{
|
|
auto aEnd = rConflictsList.end();
|
|
auto aItr = std::find_if(rConflictsList.begin(), aEnd,
|
|
[nOwnAction](ScConflictsListEntry& rConflict) { return rConflict.HasOwnAction( nOwnAction ); });
|
|
|
|
if (aItr != aEnd)
|
|
return &(*aItr);
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void ScConflictsListHelper::Transform_Impl( std::vector<sal_uLong>& rActionList, ScChangeActionMergeMap* pMergeMap )
|
|
{
|
|
if ( !pMergeMap )
|
|
{
|
|
return;
|
|
}
|
|
|
|
for ( auto aItr = rActionList.begin(); aItr != rActionList.end(); )
|
|
{
|
|
ScChangeActionMergeMap::iterator aItrMap = pMergeMap->find( *aItr );
|
|
if ( aItrMap != pMergeMap->end() )
|
|
{
|
|
*aItr = aItrMap->second;
|
|
++aItr;
|
|
}
|
|
else
|
|
{
|
|
aItr = rActionList.erase( aItr );
|
|
OSL_FAIL( "ScConflictsListHelper::Transform_Impl: erased action from conflicts list!" );
|
|
}
|
|
}
|
|
}
|
|
|
|
void ScConflictsListHelper::TransformConflictsList( ScConflictsList& rConflictsList,
|
|
ScChangeActionMergeMap* pSharedMap, ScChangeActionMergeMap* pOwnMap )
|
|
{
|
|
for ( auto& rConflictEntry : rConflictsList )
|
|
{
|
|
if ( pSharedMap )
|
|
{
|
|
ScConflictsListHelper::Transform_Impl( rConflictEntry.maSharedActions, pSharedMap );
|
|
}
|
|
|
|
if ( pOwnMap )
|
|
{
|
|
ScConflictsListHelper::Transform_Impl( rConflictEntry.maOwnActions, pOwnMap );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
ScConflictsFinder::ScConflictsFinder( ScChangeTrack* pTrack, sal_uLong nStartShared, sal_uLong nEndShared,
|
|
sal_uLong nStartOwn, sal_uLong nEndOwn, ScConflictsList& rConflictsList )
|
|
:mpTrack( pTrack )
|
|
,mnStartShared( nStartShared )
|
|
,mnEndShared( nEndShared )
|
|
,mnStartOwn( nStartOwn )
|
|
,mnEndOwn( nEndOwn )
|
|
,mrConflictsList( rConflictsList )
|
|
{
|
|
}
|
|
|
|
bool ScConflictsFinder::DoActionsIntersect( const ScChangeAction* pAction1, const ScChangeAction* pAction2 )
|
|
{
|
|
return pAction1 && pAction2 && pAction1->GetBigRange().Intersects( pAction2->GetBigRange() );
|
|
}
|
|
|
|
ScConflictsListEntry* ScConflictsFinder::GetIntersectingEntry( const ScChangeAction* pAction ) const
|
|
{
|
|
auto doActionsIntersect = [this, pAction](const sal_uLong& aAction) { return DoActionsIntersect( mpTrack->GetAction( aAction ), pAction ); };
|
|
|
|
for ( auto& rConflict : mrConflictsList )
|
|
{
|
|
if (std::any_of( rConflict.maSharedActions.cbegin(), rConflict.maSharedActions.cend(), doActionsIntersect ))
|
|
return &rConflict;
|
|
|
|
if (std::any_of( rConflict.maOwnActions.cbegin(), rConflict.maOwnActions.cend(), doActionsIntersect ))
|
|
return &rConflict;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
ScConflictsListEntry& ScConflictsFinder::GetEntry( sal_uLong nSharedAction, const std::vector<sal_uLong>& rOwnActions )
|
|
{
|
|
// try to get a list entry which already contains the shared action
|
|
ScConflictsListEntry* pEntry = ScConflictsListHelper::GetSharedActionEntry( mrConflictsList, nSharedAction );
|
|
if ( pEntry )
|
|
{
|
|
return *pEntry;
|
|
}
|
|
|
|
// try to get a list entry for which the shared action intersects with any
|
|
// other action of this entry
|
|
pEntry = GetIntersectingEntry( mpTrack->GetAction( nSharedAction ) );
|
|
if ( pEntry )
|
|
{
|
|
pEntry->maSharedActions.push_back( nSharedAction );
|
|
return *pEntry;
|
|
}
|
|
|
|
// try to get a list entry for which any of the own actions intersects with
|
|
// any other action of this entry
|
|
for ( auto& rOwnAction : rOwnActions )
|
|
{
|
|
pEntry = GetIntersectingEntry( mpTrack->GetAction( rOwnAction ) );
|
|
if ( pEntry )
|
|
{
|
|
pEntry->maSharedActions.push_back( nSharedAction );
|
|
return *pEntry;
|
|
}
|
|
}
|
|
|
|
// if no entry was found, create a new one
|
|
ScConflictsListEntry aEntry;
|
|
aEntry.meConflictAction = SC_CONFLICT_ACTION_NONE;
|
|
aEntry.maSharedActions.push_back( nSharedAction );
|
|
mrConflictsList.push_back( aEntry );
|
|
return mrConflictsList.back();
|
|
}
|
|
|
|
bool ScConflictsFinder::Find()
|
|
{
|
|
if ( !mpTrack )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool bReturn = false;
|
|
ScChangeAction* pSharedAction = mpTrack->GetAction( mnStartShared );
|
|
while ( pSharedAction && pSharedAction->GetActionNumber() <= mnEndShared )
|
|
{
|
|
std::vector<sal_uLong> aOwnActions;
|
|
ScChangeAction* pOwnAction = mpTrack->GetAction( mnStartOwn );
|
|
while ( pOwnAction && pOwnAction->GetActionNumber() <= mnEndOwn )
|
|
{
|
|
if ( DoActionsIntersect( pSharedAction, pOwnAction ) )
|
|
{
|
|
aOwnActions.push_back( pOwnAction->GetActionNumber() );
|
|
}
|
|
pOwnAction = pOwnAction->GetNext();
|
|
}
|
|
|
|
if ( !aOwnActions.empty() )
|
|
{
|
|
ScConflictsListEntry& rEntry = GetEntry(pSharedAction->GetActionNumber(), aOwnActions);
|
|
for ( const auto& aOwnAction : aOwnActions )
|
|
{
|
|
if (!ScConflictsListHelper::HasOwnAction(mrConflictsList, aOwnAction))
|
|
{
|
|
rEntry.maOwnActions.push_back(aOwnAction);
|
|
}
|
|
}
|
|
bReturn = true;
|
|
}
|
|
|
|
pSharedAction = pSharedAction->GetNext();
|
|
}
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
|
|
ScConflictsResolver::ScConflictsResolver( ScChangeTrack* pTrack, ScConflictsList& rConflictsList )
|
|
:mpTrack ( pTrack )
|
|
,mrConflictsList ( rConflictsList )
|
|
{
|
|
OSL_ENSURE( mpTrack, "ScConflictsResolver CTOR: mpTrack is null!" );
|
|
}
|
|
|
|
void ScConflictsResolver::HandleAction( ScChangeAction* pAction, bool bIsSharedAction,
|
|
bool bHandleContentAction, bool bHandleNonContentAction )
|
|
{
|
|
if ( !mpTrack || !pAction )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( bIsSharedAction )
|
|
{
|
|
ScConflictsListEntry* pConflictEntry = ScConflictsListHelper::GetSharedActionEntry(
|
|
mrConflictsList, pAction->GetActionNumber() );
|
|
if ( pConflictEntry )
|
|
{
|
|
ScConflictAction eConflictAction = pConflictEntry->meConflictAction;
|
|
if ( eConflictAction == SC_CONFLICT_ACTION_KEEP_MINE )
|
|
{
|
|
if ( pAction->GetType() == SC_CAT_CONTENT )
|
|
{
|
|
if ( bHandleContentAction )
|
|
{
|
|
mpTrack->Reject( pAction );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( bHandleNonContentAction )
|
|
{
|
|
mpTrack->Reject( pAction );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ScConflictsListEntry* pConflictEntry = ScConflictsListHelper::GetOwnActionEntry(
|
|
mrConflictsList, pAction->GetActionNumber() );
|
|
if ( pConflictEntry )
|
|
{
|
|
ScConflictAction eConflictAction = pConflictEntry->meConflictAction;
|
|
if ( eConflictAction == SC_CONFLICT_ACTION_KEEP_MINE )
|
|
{
|
|
if ( pAction->GetType() == SC_CAT_CONTENT )
|
|
{
|
|
if ( bHandleContentAction )
|
|
{
|
|
// do nothing
|
|
//mpTrack->SelectContent( pAction );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( bHandleNonContentAction )
|
|
{
|
|
// do nothing
|
|
//mpTrack->Accept( pAction );
|
|
}
|
|
}
|
|
}
|
|
else if ( eConflictAction == SC_CONFLICT_ACTION_KEEP_OTHER )
|
|
{
|
|
if ( pAction->GetType() == SC_CAT_CONTENT )
|
|
{
|
|
if ( bHandleContentAction )
|
|
{
|
|
mpTrack->Reject( pAction );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( bHandleNonContentAction )
|
|
{
|
|
mpTrack->Reject( pAction );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
ScConflictsDlg::ScConflictsDlg(weld::Window* pParent, ScViewData* pViewData, ScDocument* pSharedDoc, ScConflictsList& rConflictsList)
|
|
: GenericDialogController(pParent, u"modules/scalc/ui/conflictsdialog.ui"_ustr, u"ConflictsDialog"_ustr)
|
|
, maStrUnknownUser ( ScResId( STR_UNKNOWN_USER_CONFLICT ) )
|
|
, mpViewData ( pViewData )
|
|
, mpOwnDoc ( nullptr )
|
|
, mpOwnTrack ( nullptr )
|
|
, mpSharedDoc ( pSharedDoc )
|
|
, mpSharedTrack ( nullptr )
|
|
, mrConflictsList ( rConflictsList )
|
|
, maSelectionIdle ( "ScConflictsDlg maSelectionIdle" )
|
|
, mbInSelectHdl ( false )
|
|
, m_xBtnKeepMine(m_xBuilder->weld_button(u"keepmine"_ustr))
|
|
, m_xBtnKeepOther(m_xBuilder->weld_button(u"keepother"_ustr))
|
|
, m_xBtnKeepAllMine(m_xBuilder->weld_button(u"keepallmine"_ustr))
|
|
, m_xBtnKeepAllOthers(m_xBuilder->weld_button(u"keepallothers"_ustr))
|
|
, m_xLbConflicts(new SvxRedlinTable(m_xBuilder->weld_tree_view(u"container"_ustr), nullptr,
|
|
nullptr))
|
|
{
|
|
OSL_ENSURE( mpViewData, "ScConflictsDlg CTOR: mpViewData is null!" );
|
|
mpOwnDoc = ( mpViewData ? &mpViewData->GetDocument() : nullptr );
|
|
OSL_ENSURE( mpOwnDoc, "ScConflictsDlg CTOR: mpOwnDoc is null!" );
|
|
mpOwnTrack = ( mpOwnDoc ? mpOwnDoc->GetChangeTrack() : nullptr );
|
|
OSL_ENSURE( mpOwnTrack, "ScConflictsDlg CTOR: mpOwnTrack is null!" );
|
|
OSL_ENSURE( mpSharedDoc, "ScConflictsDlg CTOR: mpSharedDoc is null!" );
|
|
mpSharedTrack = ( mpSharedDoc ? mpSharedDoc->GetChangeTrack() : nullptr );
|
|
OSL_ENSURE( mpSharedTrack, "ScConflictsDlg CTOR: mpSharedTrack is null!" );
|
|
|
|
weld::TreeView& rTreeView = m_xLbConflicts->GetWidget();
|
|
|
|
auto nDigitWidth = rTreeView.get_approximate_digit_width();
|
|
std::vector<int> aWidths
|
|
{
|
|
o3tl::narrowing<int>(nDigitWidth * 60),
|
|
o3tl::narrowing<int>(nDigitWidth * 20)
|
|
};
|
|
rTreeView.set_column_fixed_widths(aWidths);
|
|
|
|
rTreeView.set_selection_mode(SelectionMode::Multiple);
|
|
rTreeView.set_size_request(-1, rTreeView.get_height_rows(16));
|
|
|
|
maSelectionIdle.SetInvokeHandler( LINK( this, ScConflictsDlg, UpdateSelectionHdl ) );
|
|
|
|
rTreeView.connect_changed(LINK(this, ScConflictsDlg, SelectHandle));
|
|
|
|
m_xBtnKeepMine->connect_clicked( LINK( this, ScConflictsDlg, KeepMineHandle ) );
|
|
m_xBtnKeepOther->connect_clicked( LINK( this, ScConflictsDlg, KeepOtherHandle ) );
|
|
m_xBtnKeepAllMine->connect_clicked( LINK( this, ScConflictsDlg, KeepAllMineHandle ) );
|
|
m_xBtnKeepAllOthers->connect_clicked( LINK( this, ScConflictsDlg, KeepAllOthersHandle ) );
|
|
|
|
UpdateView();
|
|
|
|
std::unique_ptr<weld::TreeIter> xEntry(rTreeView.make_iterator());
|
|
if (rTreeView.get_iter_first(*xEntry))
|
|
rTreeView.select(*xEntry);
|
|
}
|
|
|
|
ScConflictsDlg::~ScConflictsDlg()
|
|
{
|
|
}
|
|
|
|
OUString ScConflictsDlg::GetConflictString( const ScConflictsListEntry& rConflictEntry )
|
|
{
|
|
OUString aString;
|
|
if ( mpOwnTrack )
|
|
{
|
|
const ScChangeAction* pAction = mpOwnTrack->GetAction( rConflictEntry.maOwnActions[ 0 ] );
|
|
if ( pAction && mpOwnDoc )
|
|
{
|
|
SCTAB nTab = pAction->GetBigRange().MakeRange( *mpOwnDoc ).aStart.Tab();
|
|
mpOwnDoc->GetName( nTab, aString );
|
|
}
|
|
}
|
|
return aString;
|
|
}
|
|
|
|
void ScConflictsDlg::SetActionString(const ScChangeAction* pAction, ScDocument* pDoc, const weld::TreeIter& rEntry)
|
|
{
|
|
OSL_ENSURE( pAction, "ScConflictsDlg::GetActionString(): pAction is null!" );
|
|
OSL_ENSURE( pDoc, "ScConflictsDlg::GetActionString(): pDoc is null!" );
|
|
if (!pAction || !pDoc)
|
|
return;
|
|
|
|
weld::TreeView& rTreeView = m_xLbConflicts->GetWidget();
|
|
OUString aDesc = pAction->GetDescription(*pDoc, true, false);
|
|
rTreeView.set_text(rEntry, aDesc, 0);
|
|
|
|
OUString aUser = comphelper::string::strip(pAction->GetUser(), ' ');
|
|
if ( aUser.isEmpty() )
|
|
{
|
|
aUser = maStrUnknownUser;
|
|
}
|
|
rTreeView.set_text(rEntry, aUser, 1);
|
|
|
|
DateTime aDateTime = pAction->GetDateTime();
|
|
OUString aString = ScGlobal::getLocaleData().getDate( aDateTime ) + " " +
|
|
ScGlobal::getLocaleData().getTime( aDateTime, false );
|
|
rTreeView.set_text(rEntry, aString, 2);
|
|
}
|
|
|
|
void ScConflictsDlg::HandleListBoxSelection()
|
|
{
|
|
weld::TreeView& rTreeView = m_xLbConflicts->GetWidget();
|
|
std::unique_ptr<weld::TreeIter> xEntry(rTreeView.make_iterator());
|
|
bool bSelEntry = rTreeView.get_cursor(xEntry.get());
|
|
if (!bSelEntry)
|
|
bSelEntry = rTreeView.get_selected(xEntry.get());
|
|
if (!bSelEntry)
|
|
return;
|
|
|
|
bool bSelectHandle = rTreeView.is_selected(*xEntry);
|
|
|
|
while (rTreeView.get_iter_depth(*xEntry))
|
|
rTreeView.iter_parent(*xEntry);
|
|
|
|
if (bSelectHandle)
|
|
rTreeView.unselect_all();
|
|
if (!rTreeView.is_selected(*xEntry))
|
|
rTreeView.select(*xEntry);
|
|
if (rTreeView.iter_children(*xEntry))
|
|
{
|
|
do
|
|
{
|
|
if (!rTreeView.is_selected(*xEntry))
|
|
rTreeView.select(*xEntry);
|
|
} while (rTreeView.iter_next_sibling(*xEntry));
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScConflictsDlg, SelectHandle, weld::TreeView&, void)
|
|
{
|
|
if (mbInSelectHdl)
|
|
return;
|
|
|
|
mbInSelectHdl = true;
|
|
HandleListBoxSelection();
|
|
maSelectionIdle.Start();
|
|
mbInSelectHdl = false;
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScConflictsDlg, UpdateSelectionHdl, Timer *, void)
|
|
{
|
|
if ( !mpViewData || !mpOwnDoc )
|
|
{
|
|
return;
|
|
}
|
|
|
|
ScTabView* pTabView = mpViewData->GetView();
|
|
pTabView->DoneBlockMode();
|
|
|
|
std::vector<const ScChangeAction*> aActions;
|
|
|
|
weld::TreeView& rTreeView = m_xLbConflicts->GetWidget();
|
|
rTreeView.selected_foreach([&rTreeView, &aActions](weld::TreeIter& rEntry){
|
|
if (rTreeView.get_iter_depth(rEntry))
|
|
{
|
|
RedlinData* pUserData = weld::fromId<RedlinData*>(rTreeView.get_id(rEntry));
|
|
if (pUserData)
|
|
{
|
|
ScChangeAction* pAction = static_cast< ScChangeAction* >( pUserData->pData );
|
|
if ( pAction && ( pAction->GetType() != SC_CAT_DELETE_TABS ) &&
|
|
( pAction->IsClickable() || pAction->IsVisible() ) )
|
|
{
|
|
aActions.push_back(pAction);
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
});
|
|
|
|
bool bContMark = false;
|
|
for (size_t i = 0, nCount = aActions.size(); i < nCount; ++i)
|
|
{
|
|
const ScBigRange& rBigRange = aActions[i]->GetBigRange();
|
|
if (rBigRange.IsValid(*mpOwnDoc))
|
|
{
|
|
bool bSetCursor = i == nCount - 1;
|
|
pTabView->MarkRange(rBigRange.MakeRange( *mpOwnDoc ), bSetCursor, bContMark);
|
|
bContMark = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ScConflictsDlg::SetConflictAction(const weld::TreeIter& rRootEntry, ScConflictAction eConflictAction)
|
|
{
|
|
weld::TreeView& rTreeView = m_xLbConflicts->GetWidget();
|
|
RedlinData* pUserData = weld::fromId<RedlinData*>(rTreeView.get_id(rRootEntry));
|
|
ScConflictsListEntry* pConflictEntry = static_cast< ScConflictsListEntry* >( pUserData ? pUserData->pData : nullptr );
|
|
if ( pConflictEntry )
|
|
{
|
|
pConflictEntry->meConflictAction = eConflictAction;
|
|
}
|
|
}
|
|
|
|
void ScConflictsDlg::KeepHandler(bool bMine)
|
|
{
|
|
weld::TreeView& rTreeView = m_xLbConflicts->GetWidget();
|
|
std::unique_ptr<weld::TreeIter> xEntry(rTreeView.make_iterator());
|
|
if (!rTreeView.get_selected(xEntry.get()))
|
|
return;
|
|
|
|
while (rTreeView.get_iter_depth(*xEntry))
|
|
rTreeView.iter_parent(*xEntry);
|
|
|
|
m_xDialog->set_busy_cursor(true);
|
|
ScConflictAction eConflictAction = ( bMine ? SC_CONFLICT_ACTION_KEEP_MINE : SC_CONFLICT_ACTION_KEEP_OTHER );
|
|
SetConflictAction(*xEntry, eConflictAction);
|
|
rTreeView.remove(*xEntry);
|
|
m_xDialog->set_busy_cursor(false);
|
|
if (rTreeView.n_children() == 0)
|
|
m_xDialog->response(RET_OK);
|
|
}
|
|
|
|
void ScConflictsDlg::KeepAllHandler( bool bMine )
|
|
{
|
|
weld::TreeView& rTreeView = m_xLbConflicts->GetWidget();
|
|
std::unique_ptr<weld::TreeIter> xEntry(rTreeView.make_iterator());
|
|
if (!rTreeView.get_iter_first(*xEntry))
|
|
return;
|
|
|
|
while (rTreeView.get_iter_depth(*xEntry))
|
|
rTreeView.iter_parent(*xEntry);
|
|
|
|
m_xDialog->set_busy_cursor(true);
|
|
|
|
ScConflictAction eConflictAction = ( bMine ? SC_CONFLICT_ACTION_KEEP_MINE : SC_CONFLICT_ACTION_KEEP_OTHER );
|
|
do
|
|
{
|
|
SetConflictAction(*xEntry, eConflictAction);
|
|
} while (rTreeView.iter_next_sibling(*xEntry));
|
|
|
|
rTreeView.freeze();
|
|
rTreeView.clear();
|
|
rTreeView.thaw();
|
|
|
|
m_xDialog->set_busy_cursor(false);
|
|
|
|
m_xDialog->response(RET_OK);
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScConflictsDlg, KeepMineHandle, weld::Button&, void)
|
|
{
|
|
KeepHandler( true );
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScConflictsDlg, KeepOtherHandle, weld::Button&, void)
|
|
{
|
|
KeepHandler( false );
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScConflictsDlg, KeepAllMineHandle, weld::Button&, void)
|
|
{
|
|
KeepAllHandler( true );
|
|
}
|
|
|
|
IMPL_LINK_NOARG(ScConflictsDlg, KeepAllOthersHandle, weld::Button&, void)
|
|
{
|
|
KeepAllHandler( false );
|
|
}
|
|
|
|
void ScConflictsDlg::UpdateView()
|
|
{
|
|
weld::TreeView& rTreeView = m_xLbConflicts->GetWidget();
|
|
for ( ScConflictsListEntry& rConflictEntry : mrConflictsList )
|
|
{
|
|
if (rConflictEntry.meConflictAction == SC_CONFLICT_ACTION_NONE)
|
|
{
|
|
std::unique_ptr<RedlinData> pRootUserData(new RedlinData());
|
|
pRootUserData->pData = static_cast<void*>(&rConflictEntry);
|
|
OUString sString(GetConflictString(rConflictEntry));
|
|
OUString sId(weld::toId(pRootUserData.release()));
|
|
std::unique_ptr<weld::TreeIter> xRootEntry(rTreeView.make_iterator());
|
|
std::unique_ptr<weld::TreeIter> xEntry(rTreeView.make_iterator());
|
|
rTreeView.insert(nullptr, -1, &sString, &sId, nullptr, nullptr, false, xRootEntry.get());
|
|
|
|
for ( const auto& aSharedAction : rConflictEntry.maSharedActions )
|
|
{
|
|
ScChangeAction* pAction = mpSharedTrack ? mpSharedTrack->GetAction(aSharedAction) : nullptr;
|
|
if ( pAction )
|
|
{
|
|
// only display shared top content entries
|
|
if ( pAction->GetType() == SC_CAT_CONTENT )
|
|
{
|
|
ScChangeActionContent* pNextContent = dynamic_cast<ScChangeActionContent&>(*pAction).GetNextContent();
|
|
if ( pNextContent && rConflictEntry.HasSharedAction( pNextContent->GetActionNumber() ) )
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
rTreeView.insert(xRootEntry.get(), -1, nullptr, nullptr, nullptr, nullptr, false, xEntry.get());
|
|
SetActionString(pAction, mpSharedDoc, *xEntry);
|
|
}
|
|
}
|
|
|
|
for ( const auto& aOwnAction : rConflictEntry.maOwnActions )
|
|
{
|
|
ScChangeAction* pAction = mpOwnTrack ? mpOwnTrack->GetAction(aOwnAction) : nullptr;
|
|
if ( pAction )
|
|
{
|
|
// only display own top content entries
|
|
if ( pAction->GetType() == SC_CAT_CONTENT )
|
|
{
|
|
ScChangeActionContent* pNextContent = dynamic_cast<ScChangeActionContent&>(*pAction).GetNextContent();
|
|
if ( pNextContent && rConflictEntry.HasOwnAction( pNextContent->GetActionNumber() ) )
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
std::unique_ptr<RedlinData> pUserData(new RedlinData());
|
|
pUserData->pData = static_cast< void* >( pAction );
|
|
OUString aId(weld::toId(pUserData.release()));
|
|
rTreeView.insert(xRootEntry.get(), -1, nullptr, &aId, nullptr, nullptr, false, xEntry.get());
|
|
SetActionString(pAction, mpOwnDoc, *xEntry);
|
|
}
|
|
}
|
|
|
|
rTreeView.expand_row(*xRootEntry);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|