954f752cf1
I left a prefix on the names "Map" so that I would not have to re-arrange each name too much, since I can't start identifiers with digits like "100thMM" And remove RSC_EXTRAMAPUNIT, which doesn't seem to be doing anything anymore. Change-Id: I5187824aa87e30caf5357b51b5384b5ab919d224 Reviewed-on: https://gerrit.libreoffice.org/29096 Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk> Tested-by: Noel Grandin <noel.grandin@collabora.co.uk>
707 lines
23 KiB
C++
707 lines
23 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 <linkdlg.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include "helpid.hrc"
|
|
|
|
#include <tools/urlobj.hxx>
|
|
#include <svtools/svmedit.hxx>
|
|
#include <vcl/dialog.hxx>
|
|
#include <vcl/button.hxx>
|
|
#include <vcl/fixed.hxx>
|
|
#include <vcl/group.hxx>
|
|
#include <vcl/lstbox.hxx>
|
|
#include <vcl/msgbox.hxx>
|
|
#include <vcl/timer.hxx>
|
|
#include <vcl/idle.hxx>
|
|
#include <svtools/svtabbx.hxx>
|
|
#include "svtools/treelistentry.hxx"
|
|
|
|
#include <svuidlg.hrc>
|
|
#include <sfx2/linkmgr.hxx>
|
|
#include <sfx2/linksrc.hxx>
|
|
#include <svtools/soerr.hxx>
|
|
#include <sfx2/lnkbase.hxx>
|
|
#include <sfx2/objsh.hxx>
|
|
|
|
#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
|
|
#include <com/sun/star/ui/dialogs/FolderPicker.hpp>
|
|
#include <comphelper/processfactory.hxx>
|
|
|
|
#include <dialmgr.hxx>
|
|
|
|
|
|
#define FILEOBJECT ( OBJECT_CLIENT_FILE & ~OBJECT_CLIENT_SO )
|
|
|
|
using namespace sfx2;
|
|
using namespace ::com::sun::star;
|
|
|
|
class SvBaseLinkMemberList {
|
|
private:
|
|
std::vector<SvBaseLink*> mLinks;
|
|
|
|
public:
|
|
~SvBaseLinkMemberList()
|
|
{
|
|
for( std::vector<SvBaseLink*>::const_iterator it = mLinks.begin(); it != mLinks.end(); ++it )
|
|
{
|
|
SvBaseLink* p = *it;
|
|
if( p )
|
|
p->ReleaseRef();
|
|
}
|
|
}
|
|
|
|
size_t size() const { return mLinks.size(); }
|
|
|
|
SvBaseLink *operator[](size_t i) const { return mLinks[i]; }
|
|
|
|
void push_back(SvBaseLink* p)
|
|
{
|
|
mLinks.push_back(p);
|
|
p->AddFirstRef();
|
|
}
|
|
};
|
|
|
|
// attention, this array is indexed directly (0, 1, ...) in the code
|
|
static long nTabs[] =
|
|
{ 4, // Number of Tabs
|
|
0, 77, 144, 209
|
|
};
|
|
|
|
|
|
SvBaseLinksDlg::SvBaseLinksDlg( vcl::Window * pParent, LinkManager* pMgr, bool bHtml )
|
|
: ModalDialog( pParent, "BaseLinksDialog", "cui/ui/baselinksdialog.ui"),
|
|
aStrAutolink( CUI_RES( STR_AUTOLINK ) ),
|
|
aStrManuallink( CUI_RES( STR_MANUALLINK ) ),
|
|
aStrBrokenlink( CUI_RES( STR_BROKENLINK ) ),
|
|
aStrCloselinkmsg( CUI_RES( STR_CLOSELINKMSG ) ),
|
|
aStrCloselinkmsgMulti( CUI_RES( STR_CLOSELINKMSG_MULTI ) ),
|
|
aStrWaitinglink( CUI_RES( STR_WAITINGLINK ) ),
|
|
pLinkMgr( nullptr ),
|
|
bHtmlMode(bHtml),
|
|
aUpdateIdle("cui SvBaseLinksDlg UpdateIdle")
|
|
{
|
|
get(m_pTbLinks, "TB_LINKS");
|
|
Size aSize(LogicToPixel(Size(257, 87), MapUnit::MapAppFont));
|
|
m_pTbLinks->set_width_request(aSize.Width());
|
|
m_pTbLinks->set_height_request(aSize.Height());
|
|
get(m_pFtFullFileName, "FULL_FILE_NAME");
|
|
get(m_pFtFullSourceName, "FULL_SOURCE_NAME");
|
|
get(m_pFtFullTypeName, "FULL_TYPE_NAME");
|
|
get(m_pRbAutomatic, "AUTOMATIC");
|
|
get(m_pRbManual, "MANUAL");
|
|
get(m_pPbUpdateNow, "UPDATE_NOW");
|
|
get(m_pPbOpenSource, "OPEN");
|
|
get(m_pPbChangeSource, "CHANGE_SOURCE");
|
|
get(m_pPbBreakLink, "BREAK_LINK");
|
|
|
|
m_pTbLinks->SetSelectionMode( SelectionMode::Multiple );
|
|
m_pTbLinks->SetTabs( &nTabs[0] );
|
|
FixedText *pFtFiles = get<FixedText>("FILES");
|
|
pFtFiles->set_width_request(LogicToPixel(Size(nTabs[2] - nTabs[1] - 2, 0), MapUnit::MapAppFont).Width());
|
|
FixedText *pFtLinks = get<FixedText>("LINKS");
|
|
pFtLinks->set_width_request(LogicToPixel(Size(nTabs[3] - nTabs[2] - 2, 0), MapUnit::MapAppFont).Width());
|
|
FixedText *pFtTypes = get<FixedText>("TYPE");
|
|
pFtTypes->set_width_request(LogicToPixel(Size(nTabs[4] - nTabs[3] - 2, 0), MapUnit::MapAppFont).Width());
|
|
m_pTbLinks->Resize(); // OS: hack for correct selection
|
|
|
|
// UpdateTimer for DDE-/Grf-links, which are waited for
|
|
aUpdateIdle.SetIdleHdl( LINK( this, SvBaseLinksDlg, UpdateWaitingHdl ) );
|
|
aUpdateIdle.SetPriority( SchedulerPriority::LOWEST );
|
|
|
|
m_pPbOpenSource->Hide();
|
|
|
|
m_pTbLinks->SetSelectHdl( LINK( this, SvBaseLinksDlg, LinksSelectHdl ) );
|
|
m_pTbLinks->SetDoubleClickHdl( LINK( this, SvBaseLinksDlg, LinksDoubleClickHdl ) );
|
|
m_pRbAutomatic->SetClickHdl( LINK( this, SvBaseLinksDlg, AutomaticClickHdl ) );
|
|
m_pRbManual->SetClickHdl( LINK( this, SvBaseLinksDlg, ManualClickHdl ) );
|
|
m_pPbUpdateNow->SetClickHdl( LINK( this, SvBaseLinksDlg, UpdateNowClickHdl ) );
|
|
m_pPbChangeSource->SetClickHdl( LINK( this, SvBaseLinksDlg, ChangeSourceClickHdl ) );
|
|
if(!bHtmlMode)
|
|
m_pPbBreakLink->SetClickHdl( LINK( this, SvBaseLinksDlg, BreakLinkClickHdl ) );
|
|
else
|
|
m_pPbBreakLink->Hide();
|
|
|
|
SetManager( pMgr );
|
|
}
|
|
|
|
SvBaseLinksDlg::~SvBaseLinksDlg()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void SvBaseLinksDlg::dispose()
|
|
{
|
|
m_pTbLinks.clear();
|
|
m_pFtFullFileName.clear();
|
|
m_pFtFullSourceName.clear();
|
|
m_pFtFullTypeName.clear();
|
|
m_pRbAutomatic.clear();
|
|
m_pRbManual.clear();
|
|
m_pPbUpdateNow.clear();
|
|
m_pPbOpenSource.clear();
|
|
m_pPbChangeSource.clear();
|
|
m_pPbBreakLink.clear();
|
|
ModalDialog::dispose();
|
|
}
|
|
|
|
/*************************************************************************
|
|
|* SvBaseLinksDlg::Handler()
|
|
*************************************************************************/
|
|
IMPL_LINK( SvBaseLinksDlg, LinksSelectHdl, SvTreeListBox *, pSvTabListBox, void )
|
|
{
|
|
const sal_uLong nSelectionCount = pSvTabListBox ?
|
|
pSvTabListBox->GetSelectionCount() : 0;
|
|
if(nSelectionCount > 1)
|
|
{
|
|
// possibly deselect old entries in case of multi-selection
|
|
SvTreeListEntry* pEntry = nullptr;
|
|
SvBaseLink* pLink = nullptr;
|
|
pEntry = pSvTabListBox->GetHdlEntry();
|
|
pLink = static_cast<SvBaseLink*>(pEntry->GetUserData());
|
|
sal_uInt16 nObjectType = pLink->GetObjType();
|
|
if((OBJECT_CLIENT_FILE & nObjectType) != OBJECT_CLIENT_FILE)
|
|
{
|
|
pSvTabListBox->SelectAll(false);
|
|
pSvTabListBox->Select(pEntry);
|
|
}
|
|
else
|
|
{
|
|
for( sal_uLong i = 0; i < nSelectionCount; i++)
|
|
{
|
|
pEntry = i == 0 ? pSvTabListBox->FirstSelected() :
|
|
pSvTabListBox->NextSelected(pEntry);
|
|
DBG_ASSERT(pEntry, "Wo ist der Entry?");
|
|
if (!pEntry)
|
|
continue;
|
|
pLink = static_cast<SvBaseLink*>(pEntry->GetUserData());
|
|
DBG_ASSERT(pLink, "Wo ist der Link?");
|
|
if (!pLink)
|
|
continue;
|
|
if( (OBJECT_CLIENT_FILE & pLink->GetObjType()) != OBJECT_CLIENT_FILE )
|
|
pSvTabListBox->Select( pEntry, false );
|
|
|
|
}
|
|
}
|
|
|
|
m_pPbUpdateNow->Enable();
|
|
|
|
m_pRbAutomatic->Disable();
|
|
m_pRbManual->Check();
|
|
m_pRbManual->Disable();
|
|
}
|
|
else
|
|
{
|
|
sal_uLong nPos;
|
|
SvBaseLink* pLink = GetSelEntry( &nPos );
|
|
if( !pLink )
|
|
return;
|
|
|
|
m_pPbUpdateNow->Enable();
|
|
|
|
OUString sType, sLink;
|
|
OUString *pLinkNm = &sLink, *pFilter = nullptr;
|
|
|
|
if( FILEOBJECT & pLink->GetObjType() )
|
|
{
|
|
m_pRbAutomatic->Disable();
|
|
m_pRbManual->Check();
|
|
m_pRbManual->Disable();
|
|
if( OBJECT_CLIENT_GRF == pLink->GetObjType() )
|
|
{
|
|
pLinkNm = nullptr;
|
|
pFilter = &sLink;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_pRbAutomatic->Enable();
|
|
m_pRbManual->Enable();
|
|
|
|
if( SfxLinkUpdateMode::ALWAYS == pLink->GetUpdateMode() )
|
|
m_pRbAutomatic->Check();
|
|
else
|
|
m_pRbManual->Check();
|
|
}
|
|
|
|
OUString aFileName;
|
|
sfx2::LinkManager::GetDisplayNames( pLink, &sType, &aFileName, pLinkNm, pFilter );
|
|
aFileName = INetURLObject::decode(aFileName, INetURLObject::DECODE_UNAMBIGUOUS);
|
|
m_pFtFullFileName->SetText( aFileName );
|
|
m_pFtFullSourceName->SetText( sLink );
|
|
m_pFtFullTypeName->SetText( sType );
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SvBaseLinksDlg, LinksDoubleClickHdl, SvTreeListBox *, bool )
|
|
{
|
|
ChangeSourceClickHdl( nullptr );
|
|
return false;
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SvBaseLinksDlg, AutomaticClickHdl, Button*, void )
|
|
{
|
|
sal_uLong nPos;
|
|
SvBaseLink* pLink = GetSelEntry( &nPos );
|
|
if( pLink && !( FILEOBJECT & pLink->GetObjType() ) &&
|
|
SfxLinkUpdateMode::ALWAYS != pLink->GetUpdateMode() )
|
|
SetType( *pLink, nPos, SfxLinkUpdateMode::ALWAYS );
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SvBaseLinksDlg, ManualClickHdl, Button*, void )
|
|
{
|
|
sal_uLong nPos;
|
|
SvBaseLink* pLink = GetSelEntry( &nPos );
|
|
if( pLink && !( FILEOBJECT & pLink->GetObjType() ) &&
|
|
SfxLinkUpdateMode::ONCALL != pLink->GetUpdateMode())
|
|
SetType( *pLink, nPos, SfxLinkUpdateMode::ONCALL );
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SvBaseLinksDlg, UpdateNowClickHdl, Button*, void)
|
|
{
|
|
SvTabListBox& rListBox = *m_pTbLinks;
|
|
|
|
std::vector< SvBaseLink* > aLnkArr;
|
|
std::vector< sal_Int16 > aPosArr;
|
|
|
|
SvTreeListEntry* pE = rListBox.FirstSelected();
|
|
while( pE )
|
|
{
|
|
sal_uLong nFndPos = rListBox.GetModel()->GetAbsPos( pE );
|
|
if( TREELIST_ENTRY_NOTFOUND != nFndPos )
|
|
{
|
|
aLnkArr.push_back( static_cast< SvBaseLink* >( pE->GetUserData() ) );
|
|
aPosArr.push_back( nFndPos );
|
|
}
|
|
pE = rListBox.NextSelected( pE );
|
|
}
|
|
|
|
if( !aLnkArr.empty() )
|
|
{
|
|
for( size_t n = 0; n < aLnkArr.size(); ++n )
|
|
{
|
|
tools::SvRef<SvBaseLink> xLink = aLnkArr[ n ];
|
|
|
|
// first look for the entry in the array
|
|
for(const auto & i : pLinkMgr->GetLinks())
|
|
if( xLink == i )
|
|
{
|
|
xLink->SetUseCache( false );
|
|
SetType( *xLink, aPosArr[ n ], xLink->GetUpdateMode() );
|
|
xLink->SetUseCache( true );
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if somebody is of the opinion to swap his links (SD)
|
|
LinkManager* pNewMgr = pLinkMgr;
|
|
pLinkMgr = nullptr;
|
|
SetManager( pNewMgr );
|
|
|
|
|
|
if( nullptr == (pE = rListBox.GetEntry( aPosArr[ 0 ] )) ||
|
|
pE->GetUserData() != aLnkArr[ 0 ] )
|
|
{
|
|
// search the link
|
|
pE = rListBox.First();
|
|
while( pE )
|
|
{
|
|
if( pE->GetUserData() == aLnkArr[ 0 ] )
|
|
break;
|
|
pE = rListBox.Next( pE );
|
|
}
|
|
|
|
if( !pE )
|
|
pE = rListBox.FirstSelected();
|
|
}
|
|
|
|
if( pE )
|
|
{
|
|
SvTreeListEntry* pSelEntry = rListBox.FirstSelected();
|
|
if( pE != pSelEntry )
|
|
rListBox.Select( pSelEntry, false );
|
|
rListBox.Select( pE );
|
|
rListBox.MakeVisible( pE );
|
|
}
|
|
|
|
pNewMgr->CloseCachedComps();
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SvBaseLinksDlg, ChangeSourceClickHdl, Button *, void )
|
|
{
|
|
sal_uLong nSelectionCount = m_pTbLinks->GetSelectionCount();
|
|
if(nSelectionCount > 1)
|
|
{
|
|
try
|
|
{
|
|
uno::Reference<ui::dialogs::XFolderPicker2> xFolderPicker = ui::dialogs::FolderPicker::create(comphelper::getProcessComponentContext());
|
|
|
|
OUString sType, sFile, sLinkName;
|
|
OUString sFilter;
|
|
SvTreeListEntry* pEntry = m_pTbLinks->FirstSelected();
|
|
SvBaseLink* pLink = static_cast<SvBaseLink*>(pEntry->GetUserData());
|
|
sfx2::LinkManager::GetDisplayNames( pLink, &sType, &sFile );
|
|
INetURLObject aUrl(sFile);
|
|
if(aUrl.GetProtocol() == INetProtocol::File)
|
|
{
|
|
OUString sOldPath(aUrl.PathToFileName());
|
|
sal_Int32 nLen = aUrl.GetName().getLength();
|
|
sOldPath = sOldPath.copy(0, sOldPath.getLength() - nLen);
|
|
xFolderPicker->setDisplayDirectory(sOldPath);
|
|
}
|
|
if (xFolderPicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
|
|
{
|
|
OUString aPath = xFolderPicker->getDirectory();
|
|
|
|
for( sal_uLong i = 0; i < nSelectionCount; i++)
|
|
{
|
|
pEntry = i==0 ?
|
|
m_pTbLinks->FirstSelected() :
|
|
m_pTbLinks->NextSelected( pEntry );
|
|
DBG_ASSERT(pEntry,"Where is the entry?");
|
|
if (!pEntry)
|
|
continue;
|
|
pLink = static_cast<SvBaseLink*>(pEntry->GetUserData());
|
|
DBG_ASSERT(pLink,"Where is the link?");
|
|
if (!pLink)
|
|
continue;
|
|
sfx2::LinkManager::GetDisplayNames( pLink, &sType, &sFile, &sLinkName, &sFilter );
|
|
INetURLObject aUrl_(sFile);
|
|
INetURLObject aUrl2(aPath, INetProtocol::File);
|
|
aUrl2.insertName( aUrl_.getName() );
|
|
OUString sNewLinkName;
|
|
MakeLnkName( sNewLinkName, nullptr ,
|
|
aUrl2.GetMainURL(INetURLObject::DECODE_TO_IURI), sLinkName, &sFilter);
|
|
pLink->SetLinkSourceName( sNewLinkName );
|
|
pLink->Update();
|
|
}
|
|
if( pLinkMgr->GetPersist() )
|
|
pLinkMgr->GetPersist()->SetModified();
|
|
LinkManager* pNewMgr = pLinkMgr;
|
|
pLinkMgr = nullptr;
|
|
SetManager( pNewMgr );
|
|
}
|
|
}
|
|
catch (uno::Exception & e)
|
|
{
|
|
SAL_WARN("cui.dialogs", "SvBaseLinksDlg: caught UNO exception: " << e.Message);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sal_uLong nPos;
|
|
SvBaseLink* pLink = GetSelEntry( &nPos );
|
|
if ( pLink && !pLink->GetLinkSourceName().isEmpty() )
|
|
pLink->Edit( this, LINK( this, SvBaseLinksDlg, EndEditHdl ) );
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SvBaseLinksDlg, BreakLinkClickHdl, Button*, void )
|
|
{
|
|
bool bModified = false;
|
|
if(m_pTbLinks->GetSelectionCount() <= 1)
|
|
{
|
|
sal_uLong nPos;
|
|
tools::SvRef<SvBaseLink> xLink = GetSelEntry( &nPos );
|
|
if( !xLink.Is() )
|
|
return;
|
|
|
|
ScopedVclPtrInstance< QueryBox > aBox( this, WB_YES_NO | WB_DEF_YES, Closelinkmsg() );
|
|
|
|
if( RET_YES == aBox->Execute() )
|
|
{
|
|
m_pTbLinks->GetModel()->Remove( m_pTbLinks->GetEntry( nPos ) );
|
|
|
|
// close object, if it's still existing
|
|
bool bNewLnkMgr = OBJECT_CLIENT_FILE == xLink->GetObjType();
|
|
|
|
// tell the link that it will be resolved!
|
|
xLink->Closed();
|
|
|
|
// if somebody has forgotten to deregister himself
|
|
if( xLink.Is() )
|
|
pLinkMgr->Remove( &xLink );
|
|
|
|
if( bNewLnkMgr )
|
|
{
|
|
LinkManager* pNewMgr = pLinkMgr;
|
|
pLinkMgr = nullptr;
|
|
SetManager( pNewMgr );
|
|
|
|
SvTreeListEntry* pEntry = m_pTbLinks->GetEntry( nPos ? --nPos : 0 );
|
|
if( pEntry )
|
|
m_pTbLinks->SetCurEntry( pEntry );
|
|
}
|
|
bModified = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ScopedVclPtrInstance< QueryBox > aBox( this, WB_YES_NO | WB_DEF_YES, CloselinkmsgMulti() );
|
|
|
|
if( RET_YES == aBox->Execute() )
|
|
{
|
|
|
|
SvBaseLinkMemberList aLinkList;
|
|
SvTreeListEntry* pEntry = m_pTbLinks->FirstSelected();
|
|
while ( pEntry )
|
|
{
|
|
void * pUD = pEntry->GetUserData();
|
|
if( pUD )
|
|
aLinkList.push_back( static_cast<SvBaseLink*>(pUD) );
|
|
pEntry = m_pTbLinks->NextSelected(pEntry);
|
|
}
|
|
m_pTbLinks->RemoveSelection();
|
|
for( sal_uLong i = 0; i < aLinkList.size(); i++ )
|
|
{
|
|
tools::SvRef<SvBaseLink> xLink = aLinkList[i];
|
|
// tell the link that it will be resolved!
|
|
xLink->Closed();
|
|
|
|
// if somebody has forgotten to deregister himself
|
|
pLinkMgr->Remove( &xLink );
|
|
bModified = true;
|
|
}
|
|
// then remove all selected entries
|
|
}
|
|
}
|
|
if(bModified)
|
|
{
|
|
if( !m_pTbLinks->GetEntryCount() )
|
|
{
|
|
m_pRbAutomatic->Disable();
|
|
m_pRbManual->Disable();
|
|
m_pPbUpdateNow->Disable();
|
|
m_pPbChangeSource->Disable();
|
|
m_pPbBreakLink->Disable();
|
|
|
|
m_pFtFullSourceName->SetText( "" );
|
|
m_pFtFullTypeName->SetText( "" );
|
|
}
|
|
if( pLinkMgr && pLinkMgr->GetPersist() )
|
|
pLinkMgr->GetPersist()->SetModified();
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG( SvBaseLinksDlg, UpdateWaitingHdl, Idle*, void )
|
|
{
|
|
m_pTbLinks->SetUpdateMode(false);
|
|
for( sal_uLong nPos = m_pTbLinks->GetEntryCount(); nPos; )
|
|
{
|
|
SvTreeListEntry* pBox = m_pTbLinks->GetEntry( --nPos );
|
|
tools::SvRef<SvBaseLink> xLink( static_cast<SvBaseLink*>(pBox->GetUserData()) );
|
|
if( xLink.Is() )
|
|
{
|
|
OUString sCur( ImplGetStateStr( *xLink ) ),
|
|
sOld( SvTabListBox::GetEntryText( pBox, 3 ) );
|
|
if( sCur != sOld )
|
|
m_pTbLinks->SetEntryText( sCur, pBox, 3 );
|
|
}
|
|
}
|
|
m_pTbLinks->SetUpdateMode(true);
|
|
}
|
|
|
|
IMPL_LINK( SvBaseLinksDlg, EndEditHdl, sfx2::SvBaseLink&, _rLink, void )
|
|
{
|
|
sal_uLong nPos;
|
|
GetSelEntry( &nPos );
|
|
|
|
if( _rLink.WasLastEditOK() )
|
|
{
|
|
// StarImpress/Draw swap the LinkObjects themselves!
|
|
// So search for the link in the manager; if it does not exist
|
|
// anymore, fill the list completely new. Otherwise only the
|
|
// edited link needs to be refreshed.
|
|
bool bLinkFnd = false;
|
|
for( size_t n = pLinkMgr->GetLinks().size(); n; )
|
|
if( &_rLink == &(*pLinkMgr->GetLinks()[ --n ]) )
|
|
{
|
|
bLinkFnd = true;
|
|
break;
|
|
}
|
|
|
|
if( bLinkFnd )
|
|
{
|
|
m_pTbLinks->SetUpdateMode(false);
|
|
m_pTbLinks->GetModel()->Remove( m_pTbLinks->GetEntry( nPos ) );
|
|
SvTreeListEntry* pToUnselect = m_pTbLinks->FirstSelected();
|
|
InsertEntry( _rLink, nPos, true );
|
|
if(pToUnselect)
|
|
m_pTbLinks->Select(pToUnselect, false);
|
|
m_pTbLinks->SetUpdateMode(true);
|
|
}
|
|
else
|
|
{
|
|
LinkManager* pNewMgr = pLinkMgr;
|
|
pLinkMgr = nullptr;
|
|
SetManager( pNewMgr );
|
|
}
|
|
if (pLinkMgr && pLinkMgr->GetPersist())
|
|
pLinkMgr->GetPersist()->SetModified();
|
|
}
|
|
}
|
|
|
|
OUString SvBaseLinksDlg::ImplGetStateStr( const SvBaseLink& rLnk )
|
|
{
|
|
OUString sRet;
|
|
if( !rLnk.GetObj() )
|
|
sRet = Brokenlink();
|
|
else if( rLnk.GetObj()->IsPending() )
|
|
{
|
|
sRet = Waitinglink();
|
|
StartUpdateTimer();
|
|
}
|
|
else if( SfxLinkUpdateMode::ALWAYS == rLnk.GetUpdateMode() )
|
|
sRet = Autolink();
|
|
else
|
|
sRet = Manuallink();
|
|
|
|
return sRet;
|
|
}
|
|
|
|
void SvBaseLinksDlg::SetManager( LinkManager* pNewMgr )
|
|
{
|
|
if( pLinkMgr == pNewMgr )
|
|
return;
|
|
|
|
if( pNewMgr )
|
|
// update has to be stopped before clear
|
|
m_pTbLinks->SetUpdateMode( false );
|
|
|
|
m_pTbLinks->Clear();
|
|
pLinkMgr = pNewMgr;
|
|
|
|
if( pLinkMgr )
|
|
{
|
|
SvBaseLinks& rLnks = (SvBaseLinks&)pLinkMgr->GetLinks();
|
|
for( size_t n = 0; n < rLnks.size(); ++n )
|
|
{
|
|
tools::SvRef<SvBaseLink>& rLinkRef = rLnks[ n ];
|
|
if( !rLinkRef.Is() )
|
|
{
|
|
rLnks.erase( rLnks.begin() + n );
|
|
--n;
|
|
continue;
|
|
}
|
|
if( rLinkRef->IsVisible() )
|
|
InsertEntry( *rLinkRef );
|
|
}
|
|
|
|
if( !rLnks.empty() )
|
|
{
|
|
SvTreeListEntry* pEntry = m_pTbLinks->GetEntry( 0 );
|
|
m_pTbLinks->SetCurEntry( pEntry );
|
|
m_pTbLinks->Select( pEntry );
|
|
LinksSelectHdl( nullptr );
|
|
}
|
|
m_pTbLinks->SetUpdateMode( true );
|
|
m_pTbLinks->Invalidate();
|
|
}
|
|
}
|
|
|
|
|
|
void SvBaseLinksDlg::InsertEntry( const SvBaseLink& rLink, sal_uLong nPos, bool bSelect )
|
|
{
|
|
OUString aEntry, sFileNm, sLinkNm, sTypeNm, sFilter;
|
|
|
|
sfx2::LinkManager::GetDisplayNames( &rLink, &sTypeNm, &sFileNm, &sLinkNm, &sFilter );
|
|
|
|
// GetTab(0) gives the position of the bitmap which is automatically inserted by the TabListBox.
|
|
// So the first text column's width is Tab(2)-Tab(1).
|
|
long nWidthPixel = m_pTbLinks->GetLogicTab( 2 ) - m_pTbLinks->GetLogicTab( 1 );
|
|
nWidthPixel -= SV_TAB_BORDER;
|
|
OUString aTxt = m_pTbLinks->GetEllipsisString( sFileNm, nWidthPixel, DrawTextFlags::PathEllipsis );
|
|
INetURLObject aPath( sFileNm, INetProtocol::File );
|
|
OUString aFileName = aPath.getName();
|
|
aFileName = INetURLObject::decode(aFileName, INetURLObject::DECODE_UNAMBIGUOUS);
|
|
|
|
if( aFileName.getLength() > aTxt.getLength() )
|
|
aTxt = aFileName;
|
|
else if( aTxt.indexOf( aFileName, aTxt.getLength() - aFileName.getLength() ) == -1 )
|
|
// filename not in string
|
|
aTxt = aFileName;
|
|
|
|
aEntry = aTxt + "\t";
|
|
if( OBJECT_CLIENT_GRF == rLink.GetObjType() )
|
|
aEntry += sFilter;
|
|
else
|
|
aEntry += sLinkNm;
|
|
aEntry += "\t" + sTypeNm + "\t" + ImplGetStateStr( rLink );
|
|
|
|
SvTreeListEntry * pE = m_pTbLinks->InsertEntryToColumn( aEntry, nPos );
|
|
pE->SetUserData( const_cast<SvBaseLink *>(&rLink) );
|
|
if(bSelect)
|
|
m_pTbLinks->Select(pE);
|
|
}
|
|
|
|
SvBaseLink* SvBaseLinksDlg::GetSelEntry( sal_uLong* pPos )
|
|
{
|
|
SvTreeListEntry* pE = m_pTbLinks->FirstSelected();
|
|
sal_uLong nPos;
|
|
if( pE && TREELIST_ENTRY_NOTFOUND !=
|
|
( nPos = m_pTbLinks->GetModel()->GetAbsPos( pE ) ) )
|
|
{
|
|
DBG_ASSERT( pE, "wo kommt der leere Eintrag her?" );
|
|
|
|
if( pPos )
|
|
*pPos = nPos;
|
|
return static_cast<SvBaseLink*>(pE->GetUserData());
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void SvBaseLinksDlg::SetType( SvBaseLink& rLink,
|
|
sal_uLong nSelPos,
|
|
SfxLinkUpdateMode nType )
|
|
{
|
|
rLink.SetUpdateMode( nType );
|
|
rLink.Update();
|
|
SvTreeListEntry* pBox = m_pTbLinks->GetEntry( nSelPos );
|
|
m_pTbLinks->SetEntryText( ImplGetStateStr( rLink ), pBox, 3 );
|
|
if( pLinkMgr->GetPersist() )
|
|
pLinkMgr->GetPersist()->SetModified();
|
|
}
|
|
|
|
void SvBaseLinksDlg::SetActLink( SvBaseLink * pLink )
|
|
{
|
|
if( pLinkMgr )
|
|
{
|
|
const SvBaseLinks& rLnks = pLinkMgr->GetLinks();
|
|
sal_uLong nSelect = 0;
|
|
for(const auto & rLinkRef : rLnks)
|
|
{
|
|
// #109573# only visible links have been inserted into the TreeListBox,
|
|
// invisible ones have to be skipped here
|
|
if( rLinkRef->IsVisible() )
|
|
{
|
|
if( pLink == rLinkRef.get() )
|
|
{
|
|
m_pTbLinks->Select( m_pTbLinks->GetEntry( nSelect ) );
|
|
LinksSelectHdl( nullptr );
|
|
return ;
|
|
}
|
|
nSelect++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|