diff options
Diffstat (limited to 'sfx2/source/appl/linkmgr2.cxx')
-rw-r--r-- | sfx2/source/appl/linkmgr2.cxx | 210 |
1 files changed, 143 insertions, 67 deletions
diff --git a/sfx2/source/appl/linkmgr2.cxx b/sfx2/source/appl/linkmgr2.cxx index e689b3f22282..9829c3bed5ce 100644 --- a/sfx2/source/appl/linkmgr2.cxx +++ b/sfx2/source/appl/linkmgr2.cxx @@ -1,3 +1,4 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -55,6 +56,16 @@ #define _SVSTDARR_STRINGSDTOR #include <svl/svstdarr.hxx> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/util/XCloseable.hpp> + +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::lang::XComponent; +using ::com::sun::star::util::XCloseable; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; + namespace sfx2 { @@ -89,16 +100,30 @@ LinkManager::~LinkManager() } } +void LinkManager::InsertCachedComp(const Reference<XComponent>& xComp) +{ + maCachedComps.push_back(xComp); +} -/************************************************************************ -|* LinkManager::Remove() -|* -|* Beschreibung -*************************************************************************/ +void LinkManager::CloseCachedComps() +{ + CompVector::iterator itr = maCachedComps.begin(), itrEnd = maCachedComps.end(); + for (; itr != itrEnd; ++itr) + { + Reference<XCloseable> xCloseable(*itr, UNO_QUERY); + if (!xCloseable.is()) + continue; + + xCloseable->close(true); + } + maCachedComps.clear(); +} + +//-------------------------------------------------------------------------- void LinkManager::Remove( SvBaseLink *pLink ) { - // keine Links doppelt einfuegen + // No duplicate links inserted int bFound = sal_False; SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData(); for( sal_uInt16 n = aLinkTbl.Count(); n; --n, ++ppRef ) @@ -111,7 +136,7 @@ void LinkManager::Remove( SvBaseLink *pLink ) bFound = sal_True; } - // falls noch leere rum stehen sollten, weg damit + // Remove emty ones if they exist if( !(*ppRef)->Is() ) { delete *ppRef; @@ -148,7 +173,7 @@ void LinkManager::Remove( sal_uInt16 nPos, sal_uInt16 nCnt ) sal_Bool LinkManager::Insert( SvBaseLink* pLink ) { - // keine Links doppelt einfuegen + // No duplicate links inserted for( sal_uInt16 n = 0; n < aLinkTbl.Count(); ++n ) { SvBaseLinkRef* pTmp = aLinkTbl[ n ]; @@ -171,7 +196,7 @@ sal_Bool LinkManager::InsertLink( SvBaseLink * pLink, sal_uInt16 nUpdateMode, const String* pName ) { - // unbedingt zuerst + // This First pLink->SetObjType( nObjType ); if( pName ) pLink->SetName( *pName ); @@ -210,7 +235,7 @@ sal_Bool LinkManager::InsertDDELink( SvBaseLink * pLink ) } -// erfrage die Strings fuer den Dialog +// Obtain the string for the dialog sal_Bool LinkManager::GetDisplayNames( const SvBaseLink * pLink, String* pType, String* pFile, @@ -283,8 +308,8 @@ void LinkManager::UpdateAllLinks( SvStringsDtor aApps, aTopics, aItems; String sApp, sTopic, sItem; - // erstmal eine Kopie vom Array machen, damit sich updatende Links in - // Links in ... nicht dazwischen funken!! + // First make a copy of the array in order to update links + // links in ... no contact between them! SvPtrarr aTmpArr( 255, 50 ); sal_uInt16 n; for( n = 0; n < aLinkTbl.Count(); ++n ) @@ -302,7 +327,7 @@ void LinkManager::UpdateAllLinks( { SvBaseLink* pLink = (SvBaseLink*)aTmpArr[ n ]; - // suche erstmal im Array nach dem Eintrag + // search first in the array after the entry sal_uInt16 nFndPos = USHRT_MAX; for( sal_uInt16 i = 0; i < aLinkTbl.Count(); ++i ) if( pLink == *aLinkTbl[ i ] ) @@ -312,9 +337,9 @@ void LinkManager::UpdateAllLinks( } if( USHRT_MAX == nFndPos ) - continue; // war noch nicht vorhanden! + continue; // was not available! - // Graphic-Links noch nicht updaten + // Graphic-Links not to update yet if( !pLink->IsVisible() || ( !bUpdateGrfLinks && OBJECT_CLIENT_GRF == pLink->GetObjType() )) continue; @@ -323,19 +348,16 @@ void LinkManager::UpdateAllLinks( { int nRet = QueryBox( pParentWin, WB_YES_NO | WB_DEF_YES, SfxResId( STR_QUERY_UPDATE_LINKS ) ).Execute(); if( RET_YES != nRet ) - return ; // es soll nichts geupdatet werden - bAskUpdate = sal_False; // einmal reicht + return ; // nothing should be updated + bAskUpdate = sal_False; // once is enough } pLink->Update(); } + CloseCachedComps(); } -/************************************************************************ -|* SvBaseLink::CreateObject() -|* -|* Beschreibung -*************************************************************************/ +//-------------------------------------------------------------------------- SvLinkSourceRef LinkManager::CreateObj( SvBaseLink * pLink ) { @@ -356,7 +378,7 @@ SvLinkSourceRef LinkManager::CreateObj( SvBaseLink * pLink ) sal_Bool LinkManager::InsertServer( SvLinkSource* pObj ) { - // keine doppelt einfuegen + // no duplicate inserts if( !pObj || USHRT_MAX != aServerTbl.GetPos( pObj ) ) return sal_False; @@ -387,6 +409,56 @@ void MakeLnkName( String& rName, const String* pType, const String& rFile, ((rName += cTokenSeperator ) += *pFilter).EraseLeadingChars().EraseTrailingChars(); } +void LinkManager::ReconnectDdeLink(SfxObjectShell& rServer) +{ + SfxMedium* pMed = rServer.GetMedium(); + if (!pMed) + return; + + const ::sfx2::SvBaseLinks& rLinks = GetLinks(); + sal_uInt16 n = rLinks.Count(); + + for (sal_uInt16 i = 0; i < n; ++i) + { + ::sfx2::SvBaseLink* p = *rLinks[i]; + String aType, aFile, aLink, aFilter; + if (!GetDisplayNames(p, &aType, &aFile, &aLink, &aFilter)) + continue; + + if (!aType.EqualsAscii("soffice")) + // DDE connections between OOo apps are always named 'soffice'. + continue; + + String aTmp; + OUString aURL = aFile; + if (utl::LocalFileHelper::ConvertPhysicalNameToURL(aFile, aTmp)) + aURL = aTmp; + + if (!aURL.equalsIgnoreAsciiCase(pMed->GetName())) + // This DDE link is not associated with this server shell... Skip it. + continue; + + if (!aLink.Len()) + continue; + + LinkServerShell(aLink, rServer, *p); + } +} + +void LinkManager::LinkServerShell(const OUString& rPath, SfxObjectShell& rServer, ::sfx2::SvBaseLink& rLink) const +{ + ::sfx2::SvLinkSource* pSrvSrc = rServer.DdeCreateLinkSource(rPath); + if (pSrvSrc) + { + ::com::sun::star::datatransfer::DataFlavor aFl; + SotExchange::GetFormatDataFlavor(rLink.GetContentType(), aFl); + rLink.SetObj(pSrvSrc); + pSrvSrc->AddDataAdvise( + &rLink, aFl.MimeType, + sfx2::LINKUPDATE_ONCALL == rLink.GetUpdateMode() ? ADVISEMODE_ONLYONCE : 0); + } +} + sal_Bool LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink, sal_uInt16 nFileType, const String& rFileNm, @@ -413,8 +485,8 @@ sal_Bool LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink ) return sal_False; } -// eine Uebertragung wird abgebrochen, also alle DownloadMedien canceln -// (ist zur Zeit nur fuer die FileLinks interressant!) +// A transfer is aborted, so cancel all download media +// (for now this is only of interest for the file links!) void LinkManager::CancelTransfers() { SvFileObject* pFileObj; @@ -425,27 +497,22 @@ void LinkManager::CancelTransfers() if( 0 != ( pLnk = &(*rLnks[ --n ])) && OBJECT_CLIENT_FILE == (OBJECT_CLIENT_FILE & pLnk->GetObjType()) && 0 != ( pFileObj = (SvFileObject*)pLnk->GetObj() ) ) -// 0 != ( pFileObj = (SvFileObject*)SvFileObject::ClassFactory()-> -// CastAndAddRef( pLnk->GetObj() )) ) pFileObj->CancelTransfers(); } - - // um Status Informationen aus dem FileObject an den BaseLink zu - // senden, gibt es eine eigene ClipBoardId. Das SvData-Object hat - // dann die entsprechenden Informationen als String. - // Wird zur Zeit fuer FileObject in Verbindung mit JavaScript benoetigt - // - das braucht Informationen ueber Load/Abort/Error + // For the purpose of sending Status information from the file object to + // the base link, there exist a dedicated ClipBoardId. The SvData-object + // gets the appropriate information as a string + // For now this is required for file object in conjunction with JavaScript + // - needs information about Load/Abort/Error sal_uIntPtr LinkManager::RegisterStatusInfoId() { static sal_uIntPtr nFormat = 0; if( !nFormat ) { -// wie sieht die neue Schnittstelle aus? -// nFormat = Exchange::RegisterFormatName( "StatusInfo vom SvxInternalLink" ); nFormat = SotExchange::RegisterFormatName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( - "StatusInfo vom SvxInternalLink" ))); + "StatusInfo from SvxInternalLink" ))); } return nFormat; } @@ -511,13 +578,11 @@ sal_Bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink ) SfxObjectShell* pFndShell = 0; sal_uInt16 nUpdateMode = com::sun::star::document::UpdateDocMode::NO_UPDATE; String sTopic, sItem, sReferer; - if( pLink->GetLinkManager() && - pLink->GetLinkManager()->GetDisplayNames( pLink, 0, &sTopic, &sItem ) - && sTopic.Len() ) + LinkManager* pLinkMgr = pLink->GetLinkManager(); + if (pLinkMgr && pLinkMgr->GetDisplayNames(pLink, 0, &sTopic, &sItem) && sTopic.Len()) { - // erstmal nur ueber die DocumentShells laufen und die mit dem - // Namen heraussuchen: - + // first only loop over the DocumentShells the shells and find those + // with the name: com::sun::star::lang::Locale aLocale; MsLangId::convertLanguageToLocale( LANGUAGE_SYSTEM, aLocale ); CharClass aCC( aLocale ); @@ -528,7 +593,7 @@ sal_Bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink ) TypeId aType( TYPE(SfxObjectShell) ); sal_Bool bFirst = sal_True; - SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist(); + SfxObjectShell* pShell = pLinkMgr->GetPersist(); if( pShell && pShell->GetMedium() ) { sReferer = pShell->GetMedium()->GetBaseURL(); @@ -556,7 +621,7 @@ sal_Bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink ) aCC.toLower( sTmp ); - if( sTmp == sNmURL ) // die wollen wir haben + if( sTmp == sNmURL ) // we want these { pFndShell = pShell; break; @@ -578,9 +643,25 @@ sal_Bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink ) if( !sTopic.Len() ) return sal_False; - if( !pFndShell ) + if (pFndShell) { - // dann versuche die Datei zu laden: + sfx2::SvLinkSource* pNewSrc = pFndShell->DdeCreateLinkSource( sItem ); + if( pNewSrc ) + { + ::com::sun::star::datatransfer::DataFlavor aFl; + SotExchange::GetFormatDataFlavor( pLink->GetContentType(), aFl ); + + pLink->SetObj( pNewSrc ); + pNewSrc->AddDataAdvise( pLink, aFl.MimeType, + sfx2::LINKUPDATE_ONCALL == pLink->GetUpdateMode() + ? ADVISEMODE_ONLYONCE + : 0 ); + return true; + } + } + else + { + // then try to download the file: INetURLObject aURL( sTopic ); INetProtocol eOld = aURL.GetProtocol(); aURL.SetURL( sTopic = lcl_DDE_RelToAbs( sTopic, sReferer ) ); @@ -593,7 +674,11 @@ sal_Bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink ) SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") ); SfxStringItem aReferer( SID_REFERER, sReferer ); SfxUInt16Item aUpdate( SID_UPDATEDOCMODE, nUpdateMode ); - SfxBoolItem aReadOnly(SID_DOC_READONLY, sal_True); + SfxBoolItem aReadOnly(SID_DOC_READONLY, false); + + // Disable automatic re-connection to avoid this link instance + // being destroyed at re-connection. + SfxBoolItem aDdeConnect(SID_DDE_RECONNECT_ONLOAD, false); // #i14200# (DDE-link crashes wordprocessor) SfxAllItemSet aArgs( SFX_APP()->GetPool() ); @@ -604,29 +689,19 @@ sal_Bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink ) aArgs.Put(aName); aArgs.Put(aUpdate); aArgs.Put(aReadOnly); - pFndShell = SfxObjectShell::CreateAndLoadObject( aArgs ); + aArgs.Put(aDdeConnect); + Reference<XComponent> xComp = SfxObjectShell::CreateAndLoadComponent(aArgs); + pFndShell = SfxObjectShell::GetShellFromComponent(xComp); + if (xComp.is() && pFndShell) + { + pLinkMgr->InsertCachedComp(xComp); + pLinkMgr->LinkServerShell(sItem, *pFndShell, *pLink); + return true; + } } } - sal_Bool bRet = sal_False; - if( pFndShell ) - { - sfx2::SvLinkSource* pNewSrc = pFndShell->DdeCreateLinkSource( sItem ); - if( pNewSrc ) - { - bRet = sal_True; - - ::com::sun::star::datatransfer::DataFlavor aFl; - SotExchange::GetFormatDataFlavor( pLink->GetContentType(), aFl ); - - pLink->SetObj( pNewSrc ); - pNewSrc->AddDataAdvise( pLink, aFl.MimeType, - sfx2::LINKUPDATE_ONCALL == pLink->GetUpdateMode() - ? ADVISEMODE_ONLYONCE - : 0 ); - } - } - return bRet; + return false; } @@ -634,3 +709,4 @@ sal_Bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink ) +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |