xref: /aoo41x/main/sfx2/source/appl/linkmgr2.cxx (revision a621bfbf)
1d119d52dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3d119d52dSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4d119d52dSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5d119d52dSAndrew Rist  * distributed with this work for additional information
6d119d52dSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7d119d52dSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8d119d52dSAndrew Rist  * "License"); you may not use this file except in compliance
9d119d52dSAndrew Rist  * with the License.  You may obtain a copy of the License at
10d119d52dSAndrew Rist  *
11d119d52dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12d119d52dSAndrew Rist  *
13d119d52dSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14d119d52dSAndrew Rist  * software distributed under the License is distributed on an
15d119d52dSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16d119d52dSAndrew Rist  * KIND, either express or implied.  See the License for the
17d119d52dSAndrew Rist  * specific language governing permissions and limitations
18d119d52dSAndrew Rist  * under the License.
19d119d52dSAndrew Rist  *
20d119d52dSAndrew Rist  *************************************************************/
21d119d52dSAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_sfx2.hxx"
24cdf0e10cSrcweir 
25cdf0e10cSrcweir #include <sfx2/linkmgr.hxx>
26cdf0e10cSrcweir #include <com/sun/star/document/UpdateDocMode.hpp>
27cdf0e10cSrcweir #include <sfx2/objsh.hxx>
28cdf0e10cSrcweir #include <svl/urihelper.hxx>
29cdf0e10cSrcweir #include <sot/formats.hxx>
30cdf0e10cSrcweir #include <tools/urlobj.hxx>
31cdf0e10cSrcweir #include <sot/exchange.hxx>
32cdf0e10cSrcweir #include <tools/debug.hxx>
33cdf0e10cSrcweir #include <vcl/msgbox.hxx>
34cdf0e10cSrcweir #include <sfx2/lnkbase.hxx>
35cdf0e10cSrcweir #include <sfx2/app.hxx>
36cdf0e10cSrcweir #include <vcl/graph.hxx>
37cdf0e10cSrcweir #include <svl/stritem.hxx>
38cdf0e10cSrcweir #include <svl/eitem.hxx>
39cdf0e10cSrcweir #include <svl/intitem.hxx>
40cdf0e10cSrcweir #include <unotools/localfilehelper.hxx>
41cdf0e10cSrcweir #include <i18npool/mslangid.hxx>
42cdf0e10cSrcweir #include <sfx2/request.hxx>
4345fd3b9aSArmin Le Grand #include <vcl/dibtools.hxx>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #include "fileobj.hxx"
46cdf0e10cSrcweir #include "impldde.hxx"
47cdf0e10cSrcweir #include "app.hrc"
48cdf0e10cSrcweir #include "sfx2/sfxresid.hxx"
49cdf0e10cSrcweir 
50cdf0e10cSrcweir #define _SVSTDARR_STRINGSDTOR
51cdf0e10cSrcweir #include <svl/svstdarr.hxx>
52cdf0e10cSrcweir 
53cdf0e10cSrcweir namespace sfx2
54cdf0e10cSrcweir {
55cdf0e10cSrcweir 
56cdf0e10cSrcweir class SvxInternalLink : public sfx2::SvLinkSource
57cdf0e10cSrcweir {
58cdf0e10cSrcweir public:
59cdf0e10cSrcweir 	SvxInternalLink() {}
60cdf0e10cSrcweir 
61cdf0e10cSrcweir     virtual sal_Bool Connect( sfx2::SvBaseLink* );
62cdf0e10cSrcweir };
63cdf0e10cSrcweir 
64cdf0e10cSrcweir 
65cdf0e10cSrcweir SV_IMPL_PTRARR( SvBaseLinks, SvBaseLinkRefPtr )
66cdf0e10cSrcweir 
67cdf0e10cSrcweir LinkManager::LinkManager(SfxObjectShell* p)
68611fcdabSJim Jagielski 	: pPersist(p),
69611fcdabSJim Jagielski 	mUpdateAsked(sal_False),
70611fcdabSJim Jagielski 	mAutoAskUpdateAllLinks(sal_False)
71cdf0e10cSrcweir {
72cdf0e10cSrcweir }
73cdf0e10cSrcweir 
74cdf0e10cSrcweir LinkManager::~LinkManager()
75cdf0e10cSrcweir {
76cdf0e10cSrcweir 	SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData();
77cdf0e10cSrcweir 	for( sal_uInt16 n = aLinkTbl.Count(); n; --n, ++ppRef )
78cdf0e10cSrcweir 	{
79cdf0e10cSrcweir 		if( (*ppRef)->Is() )
80cdf0e10cSrcweir 		{
81cdf0e10cSrcweir 			(*(*ppRef))->Disconnect();
82cdf0e10cSrcweir             (*(*ppRef))->SetLinkManager( NULL );
83cdf0e10cSrcweir 		}
84cdf0e10cSrcweir 		delete *ppRef;
85cdf0e10cSrcweir 	}
86cdf0e10cSrcweir }
87cdf0e10cSrcweir 
88cdf0e10cSrcweir 
89cdf0e10cSrcweir /************************************************************************
90cdf0e10cSrcweir |*    LinkManager::Remove()
91cdf0e10cSrcweir |*
92cdf0e10cSrcweir |*    Beschreibung
93cdf0e10cSrcweir *************************************************************************/
94cdf0e10cSrcweir 
95cdf0e10cSrcweir void LinkManager::Remove( SvBaseLink *pLink )
96cdf0e10cSrcweir {
97cdf0e10cSrcweir 	// keine Links doppelt einfuegen
98cdf0e10cSrcweir 	int bFound = sal_False;
99cdf0e10cSrcweir 	SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData();
100cdf0e10cSrcweir 	for( sal_uInt16 n = aLinkTbl.Count(); n; --n, ++ppRef )
101cdf0e10cSrcweir 	{
102cdf0e10cSrcweir 		if( pLink == *(*ppRef) )
103cdf0e10cSrcweir 		{
104cdf0e10cSrcweir 			(*(*ppRef))->Disconnect();
105cdf0e10cSrcweir             (*(*ppRef))->SetLinkManager( NULL );
106cdf0e10cSrcweir 			(*(*ppRef)).Clear();
107cdf0e10cSrcweir 			bFound = sal_True;
108cdf0e10cSrcweir 		}
109cdf0e10cSrcweir 
110cdf0e10cSrcweir 		// falls noch leere rum stehen sollten, weg damit
111cdf0e10cSrcweir 		if( !(*ppRef)->Is() )
112cdf0e10cSrcweir 		{
113cdf0e10cSrcweir 			delete *ppRef;
114cdf0e10cSrcweir 			aLinkTbl.Remove( aLinkTbl.Count() - n, 1 );
115cdf0e10cSrcweir 			if( bFound )
116cdf0e10cSrcweir 				return ;
117cdf0e10cSrcweir 			--ppRef;
118cdf0e10cSrcweir 		}
119cdf0e10cSrcweir 	}
120cdf0e10cSrcweir }
121cdf0e10cSrcweir 
122cdf0e10cSrcweir 
123cdf0e10cSrcweir void LinkManager::Remove( sal_uInt16 nPos, sal_uInt16 nCnt )
124cdf0e10cSrcweir {
125cdf0e10cSrcweir 	if( nCnt && nPos < aLinkTbl.Count() )
126cdf0e10cSrcweir 	{
127cdf0e10cSrcweir 		if( nPos + nCnt > aLinkTbl.Count() )
128cdf0e10cSrcweir 			nCnt = aLinkTbl.Count() - nPos;
129cdf0e10cSrcweir 
130cdf0e10cSrcweir 		SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData() + nPos;
131cdf0e10cSrcweir 		for( sal_uInt16 n = nCnt; n; --n, ++ppRef )
132cdf0e10cSrcweir 		{
133cdf0e10cSrcweir 			if( (*ppRef)->Is() )
134cdf0e10cSrcweir 			{
135cdf0e10cSrcweir 				(*(*ppRef))->Disconnect();
136cdf0e10cSrcweir                 (*(*ppRef))->SetLinkManager( NULL );
137cdf0e10cSrcweir 			}
138cdf0e10cSrcweir 			delete *ppRef;
139cdf0e10cSrcweir 		}
140cdf0e10cSrcweir 		aLinkTbl.Remove( nPos, nCnt );
141cdf0e10cSrcweir 	}
142cdf0e10cSrcweir }
143cdf0e10cSrcweir 
144cdf0e10cSrcweir 
145cdf0e10cSrcweir sal_Bool LinkManager::Insert( SvBaseLink* pLink )
146cdf0e10cSrcweir {
147cdf0e10cSrcweir 	// keine Links doppelt einfuegen
148cdf0e10cSrcweir 	for( sal_uInt16 n = 0; n < aLinkTbl.Count(); ++n )
149cdf0e10cSrcweir 	{
150cdf0e10cSrcweir 		SvBaseLinkRef* pTmp = aLinkTbl[ n ];
151cdf0e10cSrcweir 		if( !pTmp->Is() )
152cdf0e10cSrcweir 			aLinkTbl.DeleteAndDestroy( n-- );
153cdf0e10cSrcweir 
154cdf0e10cSrcweir 		if( pLink == *pTmp )
155cdf0e10cSrcweir 			return sal_False;
156cdf0e10cSrcweir 	}
157cdf0e10cSrcweir 
158cdf0e10cSrcweir 	SvBaseLinkRef* pTmp = new SvBaseLinkRef( pLink );
159cdf0e10cSrcweir     pLink->SetLinkManager( this );
160cdf0e10cSrcweir 	aLinkTbl.Insert( pTmp, aLinkTbl.Count() );
161611fcdabSJim Jagielski 	Window *parent = GetPersist()->GetDialogParent();
162611fcdabSJim Jagielski 	if (mAutoAskUpdateAllLinks)
163611fcdabSJim Jagielski 	{
164611fcdabSJim Jagielski 		SetUserAllowsLinkUpdate(pLink, GetUserAllowsLinkUpdate(parent));
165611fcdabSJim Jagielski 	}
166611fcdabSJim Jagielski 
167cdf0e10cSrcweir 	return sal_True;
168cdf0e10cSrcweir }
169cdf0e10cSrcweir 
170cdf0e10cSrcweir 
171cdf0e10cSrcweir sal_Bool LinkManager::InsertLink( SvBaseLink * pLink,
172cdf0e10cSrcweir 								sal_uInt16 nObjType,
173cdf0e10cSrcweir 								sal_uInt16 nUpdateMode,
174cdf0e10cSrcweir 								const String* pName )
175cdf0e10cSrcweir {
176cdf0e10cSrcweir 	// unbedingt zuerst
177cdf0e10cSrcweir 	pLink->SetObjType( nObjType );
178cdf0e10cSrcweir 	if( pName )
179cdf0e10cSrcweir 		pLink->SetName( *pName );
180cdf0e10cSrcweir 	pLink->SetUpdateMode( nUpdateMode );
181cdf0e10cSrcweir 	return Insert( pLink );
182cdf0e10cSrcweir }
183cdf0e10cSrcweir 
184cdf0e10cSrcweir 
185cdf0e10cSrcweir sal_Bool LinkManager::InsertDDELink( SvBaseLink * pLink,
186cdf0e10cSrcweir 									const String& rServer,
187cdf0e10cSrcweir 									const String& rTopic,
188cdf0e10cSrcweir 									const String& rItem )
189cdf0e10cSrcweir {
190cdf0e10cSrcweir 	if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
191cdf0e10cSrcweir 		return sal_False;
192cdf0e10cSrcweir 
193cdf0e10cSrcweir 	String sCmd;
194cdf0e10cSrcweir 	::sfx2::MakeLnkName( sCmd, &rServer, rTopic, rItem );
195cdf0e10cSrcweir 
196cdf0e10cSrcweir 	pLink->SetObjType( OBJECT_CLIENT_DDE );
197cdf0e10cSrcweir 	pLink->SetName( sCmd );
198cdf0e10cSrcweir 	return Insert( pLink );
199cdf0e10cSrcweir }
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 
202cdf0e10cSrcweir sal_Bool LinkManager::InsertDDELink( SvBaseLink * pLink )
203cdf0e10cSrcweir {
204cdf0e10cSrcweir 	DBG_ASSERT( OBJECT_CLIENT_SO & pLink->GetObjType(), "no OBJECT_CLIENT_SO" );
205cdf0e10cSrcweir 	if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
206cdf0e10cSrcweir 		return sal_False;
207cdf0e10cSrcweir 
208cdf0e10cSrcweir 	if( pLink->GetObjType() == OBJECT_CLIENT_SO )
209cdf0e10cSrcweir 		pLink->SetObjType( OBJECT_CLIENT_DDE );
210cdf0e10cSrcweir 
211cdf0e10cSrcweir 	return Insert( pLink );
212cdf0e10cSrcweir }
213cdf0e10cSrcweir 
214cdf0e10cSrcweir 
215cdf0e10cSrcweir // erfrage die Strings fuer den Dialog
216cdf0e10cSrcweir sal_Bool LinkManager::GetDisplayNames( const SvBaseLink * pLink,
217cdf0e10cSrcweir 										String* pType,
218cdf0e10cSrcweir 										String* pFile,
219cdf0e10cSrcweir 										String* pLinkStr,
220cdf0e10cSrcweir 										String* pFilter ) const
221cdf0e10cSrcweir {
222cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
223cdf0e10cSrcweir 	const String sLNm( pLink->GetLinkSourceName() );
224cdf0e10cSrcweir 	if( sLNm.Len() )
225cdf0e10cSrcweir 	{
226cdf0e10cSrcweir 		switch( pLink->GetObjType() )
227cdf0e10cSrcweir 		{
228cdf0e10cSrcweir 		    case OBJECT_CLIENT_FILE:
229cdf0e10cSrcweir 		    case OBJECT_CLIENT_GRF:
230cdf0e10cSrcweir 		    case OBJECT_CLIENT_OLE:
231cdf0e10cSrcweir 			    {
232cdf0e10cSrcweir 				    sal_uInt16 nPos = 0;
233cdf0e10cSrcweir 				    String sFile( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) );
234cdf0e10cSrcweir 				    String sRange( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) );
235cdf0e10cSrcweir 
236cdf0e10cSrcweir 				    if( pFile )
237cdf0e10cSrcweir 					    *pFile = sFile;
238cdf0e10cSrcweir 				    if( pLinkStr )
239cdf0e10cSrcweir 					    *pLinkStr = sRange;
240cdf0e10cSrcweir 				    if( pFilter )
241cdf0e10cSrcweir 					    *pFilter = sLNm.Copy( nPos );
242cdf0e10cSrcweir 
243cdf0e10cSrcweir 				    if( pType )
244cdf0e10cSrcweir 				    {
245cdf0e10cSrcweir 					    sal_uInt16 nObjType = pLink->GetObjType();
246cdf0e10cSrcweir 					    *pType = String( SfxResId(
247cdf0e10cSrcweir 								    ( OBJECT_CLIENT_FILE == nObjType || OBJECT_CLIENT_OLE == nObjType )
248cdf0e10cSrcweir 										    ? RID_SVXSTR_FILELINK
249cdf0e10cSrcweir 										    : RID_SVXSTR_GRAFIKLINK ));
250cdf0e10cSrcweir 				    }
251cdf0e10cSrcweir 				    bRet = sal_True;
252cdf0e10cSrcweir 			    }
253cdf0e10cSrcweir 			    break;
254cdf0e10cSrcweir 		    case OBJECT_CLIENT_DDE:
255cdf0e10cSrcweir 	            {
256cdf0e10cSrcweir 		            sal_uInt16 nTmp = 0;
257cdf0e10cSrcweir 		            String sCmd( sLNm );
258cdf0e10cSrcweir 		            String sServer( sCmd.GetToken( 0, cTokenSeperator, nTmp ) );
259cdf0e10cSrcweir 		            String sTopic( sCmd.GetToken( 0, cTokenSeperator, nTmp ) );
260cdf0e10cSrcweir 
261cdf0e10cSrcweir 		            if( pType )
262cdf0e10cSrcweir 			            *pType = sServer;
263cdf0e10cSrcweir 		            if( pFile )
264cdf0e10cSrcweir 			            *pFile = sTopic;
265cdf0e10cSrcweir 		            if( pLinkStr )
266cdf0e10cSrcweir 			            *pLinkStr = sCmd.Copy( nTmp );
267cdf0e10cSrcweir 		            bRet = sal_True;
268cdf0e10cSrcweir 		        }
269cdf0e10cSrcweir 		        break;
270cdf0e10cSrcweir 	        default:
271cdf0e10cSrcweir 	            break;
272cdf0e10cSrcweir 	    }
273cdf0e10cSrcweir 	}
274cdf0e10cSrcweir 
275cdf0e10cSrcweir 	return bRet;
276cdf0e10cSrcweir }
277cdf0e10cSrcweir 
278611fcdabSJim Jagielski void LinkManager::SetAutoAskUpdateAllLinks()
279611fcdabSJim Jagielski {
280611fcdabSJim Jagielski 	mAutoAskUpdateAllLinks = sal_True;
281611fcdabSJim Jagielski }
282611fcdabSJim Jagielski 
283611fcdabSJim Jagielski sal_Bool LinkManager::GetUserAllowsLinkUpdate(Window *pParentWin)
284611fcdabSJim Jagielski {
285611fcdabSJim Jagielski 	if (!mUpdateAsked)
286611fcdabSJim Jagielski 	{
287611fcdabSJim Jagielski 		if (QueryBox(pParentWin, WB_YES_NO | WB_DEF_NO, SfxResId(STR_QUERY_UPDATE_LINKS)).Execute() == RET_YES)
288611fcdabSJim Jagielski 			mAllowUpdate = sal_True;
289611fcdabSJim Jagielski 		else
290611fcdabSJim Jagielski 			mAllowUpdate = sal_False;
291611fcdabSJim Jagielski 		mUpdateAsked = sal_True;
292611fcdabSJim Jagielski 	}
293611fcdabSJim Jagielski 	return mAllowUpdate;
294611fcdabSJim Jagielski }
295611fcdabSJim Jagielski 
296611fcdabSJim Jagielski void LinkManager::SetUserAllowsLinkUpdate(SvBaseLink *pLink, sal_Bool allows)
297611fcdabSJim Jagielski {
298611fcdabSJim Jagielski 	SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist();
299611fcdabSJim Jagielski 
300611fcdabSJim Jagielski 	if (pShell)
301611fcdabSJim Jagielski 	{
302611fcdabSJim Jagielski 		comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = pShell->getEmbeddedObjectContainer();
303611fcdabSJim Jagielski 		rEmbeddedObjectContainer.setUserAllowsLinkUpdate(allows);
304611fcdabSJim Jagielski 	}
305611fcdabSJim Jagielski }
306611fcdabSJim Jagielski 
307cdf0e10cSrcweir 
308cdf0e10cSrcweir void LinkManager::UpdateAllLinks(
309cdf0e10cSrcweir     sal_Bool bAskUpdate,
310cdf0e10cSrcweir     sal_Bool /*bCallErrHdl*/,
311cdf0e10cSrcweir     sal_Bool bUpdateGrfLinks,
312cdf0e10cSrcweir     Window* pParentWin )
313cdf0e10cSrcweir {
314cdf0e10cSrcweir 	SvStringsDtor aApps, aTopics, aItems;
315cdf0e10cSrcweir 	String sApp, sTopic, sItem;
316cdf0e10cSrcweir 
317cdf0e10cSrcweir 	// erstmal eine Kopie vom Array machen, damit sich updatende Links in
318cdf0e10cSrcweir 	// Links in ... nicht dazwischen funken!!
319cdf0e10cSrcweir 	SvPtrarr aTmpArr( 255, 50 );
320cdf0e10cSrcweir 	sal_uInt16 n;
321cdf0e10cSrcweir 	for( n = 0; n < aLinkTbl.Count(); ++n )
322cdf0e10cSrcweir 	{
323cdf0e10cSrcweir 		SvBaseLink* pLink = *aLinkTbl[ n ];
324cdf0e10cSrcweir 		if( !pLink )
325cdf0e10cSrcweir 		{
326cdf0e10cSrcweir 			Remove( n-- );
327cdf0e10cSrcweir 			continue;
328cdf0e10cSrcweir 		}
329cdf0e10cSrcweir 		aTmpArr.Insert( pLink, aTmpArr.Count() );
330cdf0e10cSrcweir 	}
331cdf0e10cSrcweir 
332cdf0e10cSrcweir 	for( n = 0; n < aTmpArr.Count(); ++n )
333cdf0e10cSrcweir 	{
334cdf0e10cSrcweir 		SvBaseLink* pLink = (SvBaseLink*)aTmpArr[ n ];
335cdf0e10cSrcweir 
336cdf0e10cSrcweir 		// suche erstmal im Array nach dem Eintrag
337cdf0e10cSrcweir 		sal_uInt16 nFndPos = USHRT_MAX;
338cdf0e10cSrcweir 		for( sal_uInt16 i = 0; i < aLinkTbl.Count(); ++i )
339cdf0e10cSrcweir 			if( pLink == *aLinkTbl[ i ] )
340cdf0e10cSrcweir 			{
341cdf0e10cSrcweir 				nFndPos = i;
342cdf0e10cSrcweir 				break;
343cdf0e10cSrcweir 			}
344cdf0e10cSrcweir 
345cdf0e10cSrcweir 		if( USHRT_MAX == nFndPos )
346cdf0e10cSrcweir 			continue;					// war noch nicht vorhanden!
347cdf0e10cSrcweir 
348cf914f84SJim Jagielski 		// do not update graphic links yet
349cdf0e10cSrcweir 		if( !pLink->IsVisible() ||
350cdf0e10cSrcweir 			( !bUpdateGrfLinks && OBJECT_CLIENT_GRF == pLink->GetObjType() ))
351cdf0e10cSrcweir 			continue;
352611fcdabSJim Jagielski 
353*a621bfbfSJim Jagielski 		sal_Bool allows = sal_True;
354611fcdabSJim Jagielski 
355611fcdabSJim Jagielski 		if (bAskUpdate)
356cdf0e10cSrcweir 		{
357611fcdabSJim Jagielski 			allows = GetUserAllowsLinkUpdate(pParentWin);
358611fcdabSJim Jagielski 		}
3590dfb9e37SArmin Le Grand 
360611fcdabSJim Jagielski 		SetUserAllowsLinkUpdate(pLink, allows);
361611fcdabSJim Jagielski 	    bAskUpdate = sal_False;		// one time is OK
3620dfb9e37SArmin Le Grand 
363611fcdabSJim Jagielski 		if (allows)
364611fcdabSJim Jagielski 			pLink->Update();
365cdf0e10cSrcweir 
366cdf0e10cSrcweir 	}
367cdf0e10cSrcweir }
368cdf0e10cSrcweir 
369cdf0e10cSrcweir /************************************************************************
370cdf0e10cSrcweir |*    SvBaseLink::CreateObject()
371cdf0e10cSrcweir |*
372cdf0e10cSrcweir |*    Beschreibung
373cdf0e10cSrcweir *************************************************************************/
374cdf0e10cSrcweir 
375cdf0e10cSrcweir SvLinkSourceRef LinkManager::CreateObj( SvBaseLink * pLink )
376cdf0e10cSrcweir {
377cdf0e10cSrcweir 	switch( pLink->GetObjType() )
378cdf0e10cSrcweir 	{
379cdf0e10cSrcweir 	    case OBJECT_CLIENT_FILE:
380cdf0e10cSrcweir 	    case OBJECT_CLIENT_GRF:
381cdf0e10cSrcweir 	    case OBJECT_CLIENT_OLE:
382cdf0e10cSrcweir 		    return new SvFileObject;
383cdf0e10cSrcweir 	    case OBJECT_INTERN:
384cdf0e10cSrcweir 		    return new SvxInternalLink;
385cdf0e10cSrcweir         case OBJECT_CLIENT_DDE:
386cdf0e10cSrcweir 		    return new SvDDEObject;
387cdf0e10cSrcweir 	    default:
388cdf0e10cSrcweir         	return SvLinkSourceRef();
389cdf0e10cSrcweir    	}
390cdf0e10cSrcweir }
391cdf0e10cSrcweir 
392cdf0e10cSrcweir sal_Bool LinkManager::InsertServer( SvLinkSource* pObj )
393cdf0e10cSrcweir {
394cdf0e10cSrcweir 	// keine doppelt einfuegen
395cdf0e10cSrcweir 	if( !pObj || USHRT_MAX != aServerTbl.GetPos( pObj ) )
396cdf0e10cSrcweir 		return sal_False;
397cdf0e10cSrcweir 
398cdf0e10cSrcweir 	aServerTbl.Insert( pObj, aServerTbl.Count() );
399cdf0e10cSrcweir 	return sal_True;
400cdf0e10cSrcweir }
401cdf0e10cSrcweir 
402cdf0e10cSrcweir 
403cdf0e10cSrcweir void LinkManager::RemoveServer( SvLinkSource* pObj )
404cdf0e10cSrcweir {
405cdf0e10cSrcweir 	sal_uInt16 nPos = aServerTbl.GetPos( pObj );
406cdf0e10cSrcweir 	if( USHRT_MAX != nPos )
407cdf0e10cSrcweir 		aServerTbl.Remove( nPos, 1 );
408cdf0e10cSrcweir }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir 
411cdf0e10cSrcweir void MakeLnkName( String& rName, const String* pType, const String& rFile,
412cdf0e10cSrcweir 					const String& rLink, const String* pFilter )
413cdf0e10cSrcweir {
414cdf0e10cSrcweir 	if( pType )
415cdf0e10cSrcweir 		(rName = *pType).EraseLeadingChars().EraseTrailingChars() += cTokenSeperator;
416cdf0e10cSrcweir 	else if( rName.Len() )
417cdf0e10cSrcweir 		rName.Erase();
418cdf0e10cSrcweir 
419cdf0e10cSrcweir 	((rName += rFile).EraseLeadingChars().EraseTrailingChars() +=
420cdf0e10cSrcweir 		cTokenSeperator ).EraseLeadingChars().EraseTrailingChars() += rLink;
421cdf0e10cSrcweir 	if( pFilter )
422cdf0e10cSrcweir 		((rName += cTokenSeperator ) += *pFilter).EraseLeadingChars().EraseTrailingChars();
423cdf0e10cSrcweir }
424cdf0e10cSrcweir 
425cdf0e10cSrcweir sal_Bool LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink,
426cdf0e10cSrcweir 									sal_uInt16 nFileType,
427cdf0e10cSrcweir 									const String& rFileNm,
428cdf0e10cSrcweir 									const String* pFilterNm,
429cdf0e10cSrcweir 									const String* pRange )
430cdf0e10cSrcweir {
431cdf0e10cSrcweir 	if( !( OBJECT_CLIENT_SO & rLink.GetObjType() ))
432cdf0e10cSrcweir 		return sal_False;
433cdf0e10cSrcweir 
434cdf0e10cSrcweir 	String sCmd( rFileNm );
435cdf0e10cSrcweir 	sCmd += ::sfx2::cTokenSeperator;
436cdf0e10cSrcweir 	if( pRange )
437cdf0e10cSrcweir 		sCmd += *pRange;
438cdf0e10cSrcweir 	if( pFilterNm )
439cdf0e10cSrcweir 		( sCmd += ::sfx2::cTokenSeperator ) += *pFilterNm;
440cdf0e10cSrcweir 
441cdf0e10cSrcweir 	return InsertLink( &rLink, nFileType, sfx2::LINKUPDATE_ONCALL, &sCmd );
442cdf0e10cSrcweir }
443cdf0e10cSrcweir 
444cdf0e10cSrcweir sal_Bool LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink )
445cdf0e10cSrcweir {
446cdf0e10cSrcweir 	if( OBJECT_CLIENT_FILE == ( OBJECT_CLIENT_FILE & rLink.GetObjType() ))
447cdf0e10cSrcweir 		return InsertLink( &rLink, rLink.GetObjType(), sfx2::LINKUPDATE_ONCALL );
448cdf0e10cSrcweir 	return sal_False;
449cdf0e10cSrcweir }
450cdf0e10cSrcweir 
451cdf0e10cSrcweir // eine Uebertragung wird abgebrochen, also alle DownloadMedien canceln
452cdf0e10cSrcweir // (ist zur Zeit nur fuer die FileLinks interressant!)
453cdf0e10cSrcweir void LinkManager::CancelTransfers()
454cdf0e10cSrcweir {
455cdf0e10cSrcweir 	SvFileObject* pFileObj;
456cdf0e10cSrcweir 	sfx2::SvBaseLink* pLnk;
457cdf0e10cSrcweir 
458cdf0e10cSrcweir 	const sfx2::SvBaseLinks& rLnks = GetLinks();
459cdf0e10cSrcweir 	for( sal_uInt16 n = rLnks.Count(); n; )
460cdf0e10cSrcweir 		if( 0 != ( pLnk = &(*rLnks[ --n ])) &&
461cdf0e10cSrcweir 			OBJECT_CLIENT_FILE == (OBJECT_CLIENT_FILE & pLnk->GetObjType()) &&
462cdf0e10cSrcweir 			0 != ( pFileObj = (SvFileObject*)pLnk->GetObj() ) )
463cdf0e10cSrcweir //			0 != ( pFileObj = (SvFileObject*)SvFileObject::ClassFactory()->
464cdf0e10cSrcweir //									CastAndAddRef( pLnk->GetObj() )) )
465cdf0e10cSrcweir 			pFileObj->CancelTransfers();
466cdf0e10cSrcweir }
467cdf0e10cSrcweir 
468cdf0e10cSrcweir 	// um Status Informationen aus dem FileObject an den BaseLink zu
469cdf0e10cSrcweir 	// senden, gibt es eine eigene ClipBoardId. Das SvData-Object hat
470cdf0e10cSrcweir 	// dann die entsprechenden Informationen als String.
471cdf0e10cSrcweir 	// Wird zur Zeit fuer FileObject in Verbindung mit JavaScript benoetigt
472cdf0e10cSrcweir 	// - das braucht Informationen ueber Load/Abort/Error
473cdf0e10cSrcweir sal_uIntPtr LinkManager::RegisterStatusInfoId()
474cdf0e10cSrcweir {
475cdf0e10cSrcweir 	static sal_uIntPtr nFormat = 0;
476cdf0e10cSrcweir 
477cdf0e10cSrcweir 	if( !nFormat )
478cdf0e10cSrcweir 	{
479cdf0e10cSrcweir // wie sieht die neue Schnittstelle aus?
480cdf0e10cSrcweir //		nFormat = Exchange::RegisterFormatName( "StatusInfo vom SvxInternalLink" );
481cdf0e10cSrcweir 		nFormat = SotExchange::RegisterFormatName(
482cdf0e10cSrcweir 					String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM(
483cdf0e10cSrcweir 								"StatusInfo vom SvxInternalLink" )));
484cdf0e10cSrcweir 	}
485cdf0e10cSrcweir 	return nFormat;
486cdf0e10cSrcweir }
487cdf0e10cSrcweir 
488cdf0e10cSrcweir // ----------------------------------------------------------------------
489cdf0e10cSrcweir 
490cdf0e10cSrcweir sal_Bool LinkManager::GetGraphicFromAny( const String& rMimeType,
491cdf0e10cSrcweir 								const ::com::sun::star::uno::Any & rValue,
492cdf0e10cSrcweir 								Graphic& rGrf )
493cdf0e10cSrcweir {
494cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
495cdf0e10cSrcweir 	::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
496cdf0e10cSrcweir 	if( rValue.hasValue() && ( rValue >>= aSeq ) )
497cdf0e10cSrcweir 	{
498cdf0e10cSrcweir 		SvMemoryStream aMemStm( (void*)aSeq.getConstArray(), aSeq.getLength(),
499cdf0e10cSrcweir 								STREAM_READ );
500cdf0e10cSrcweir 		aMemStm.Seek( 0 );
501cdf0e10cSrcweir 
502cdf0e10cSrcweir 		switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
503cdf0e10cSrcweir 		{
504cdf0e10cSrcweir 		case SOT_FORMATSTR_ID_SVXB:
505cdf0e10cSrcweir 			{
506cdf0e10cSrcweir 				aMemStm >> rGrf;
507cdf0e10cSrcweir 				bRet = sal_True;
508cdf0e10cSrcweir 			}
509cdf0e10cSrcweir 			break;
510cdf0e10cSrcweir 		case FORMAT_GDIMETAFILE:
511cdf0e10cSrcweir 			{
512cdf0e10cSrcweir 				GDIMetaFile aMtf;
513cdf0e10cSrcweir 				aMtf.Read( aMemStm );
514cdf0e10cSrcweir 				rGrf = aMtf;
515cdf0e10cSrcweir 				bRet = sal_True;
516cdf0e10cSrcweir 			}
517cdf0e10cSrcweir 			break;
518cdf0e10cSrcweir 		case FORMAT_BITMAP:
519cdf0e10cSrcweir 			{
520cdf0e10cSrcweir 				Bitmap aBmp;
52145fd3b9aSArmin Le Grand                 ReadDIB(aBmp, aMemStm, true);
522cdf0e10cSrcweir 				rGrf = aBmp;
523cdf0e10cSrcweir 				bRet = sal_True;
524cdf0e10cSrcweir 			}
525cdf0e10cSrcweir 			break;
526cdf0e10cSrcweir 		}
527cdf0e10cSrcweir 	}
528cdf0e10cSrcweir 	return bRet;
529cdf0e10cSrcweir }
530cdf0e10cSrcweir 
531cdf0e10cSrcweir 
532cdf0e10cSrcweir // ----------------------------------------------------------------------
533cdf0e10cSrcweir String lcl_DDE_RelToAbs( const String& rTopic, const String& rBaseURL )
534cdf0e10cSrcweir {
535cdf0e10cSrcweir 	String sRet;
536cdf0e10cSrcweir 	INetURLObject aURL( rTopic );
537cdf0e10cSrcweir 	if( INET_PROT_NOT_VALID == aURL.GetProtocol() )
538cdf0e10cSrcweir         utl::LocalFileHelper::ConvertSystemPathToURL( rTopic, rBaseURL, sRet );
539cdf0e10cSrcweir 	if( !sRet.Len() )
540cdf0e10cSrcweir         sRet = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), rTopic, URIHelper::GetMaybeFileHdl(), true );
541cdf0e10cSrcweir 	return sRet;
542cdf0e10cSrcweir }
543cdf0e10cSrcweir 
544cdf0e10cSrcweir sal_Bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink )
545cdf0e10cSrcweir {
546cdf0e10cSrcweir 	SfxObjectShell* pFndShell = 0;
547cdf0e10cSrcweir 	sal_uInt16 nUpdateMode = com::sun::star::document::UpdateDocMode::NO_UPDATE;
548cdf0e10cSrcweir 	String sTopic, sItem, sReferer;
549cdf0e10cSrcweir 	if( pLink->GetLinkManager() &&
550cdf0e10cSrcweir 		pLink->GetLinkManager()->GetDisplayNames( pLink, 0, &sTopic, &sItem )
551cdf0e10cSrcweir 		&& sTopic.Len() )
552cdf0e10cSrcweir 	{
553cdf0e10cSrcweir 		// erstmal nur ueber die DocumentShells laufen und die mit dem
554cdf0e10cSrcweir 		// Namen heraussuchen:
555cdf0e10cSrcweir 
556cdf0e10cSrcweir 	    com::sun::star::lang::Locale aLocale;
557cdf0e10cSrcweir 	    MsLangId::convertLanguageToLocale( LANGUAGE_SYSTEM, aLocale );
558cdf0e10cSrcweir 		CharClass aCC( aLocale );
559cdf0e10cSrcweir 
560cdf0e10cSrcweir         String sNm( sTopic ), sTmp;
561cdf0e10cSrcweir 		aCC.toLower( sNm );
562cdf0e10cSrcweir 
563cdf0e10cSrcweir 		TypeId aType( TYPE(SfxObjectShell) );
564cdf0e10cSrcweir 
565cdf0e10cSrcweir 		sal_Bool bFirst = sal_True;
566cdf0e10cSrcweir         SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist();
567cdf0e10cSrcweir         if( pShell && pShell->GetMedium() )
568cdf0e10cSrcweir 		{
569cdf0e10cSrcweir             sReferer = pShell->GetMedium()->GetBaseURL();
570cdf0e10cSrcweir 			SFX_ITEMSET_ARG( pShell->GetMedium()->GetItemSet(), pItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False );
571cdf0e10cSrcweir 			if ( pItem )
572cdf0e10cSrcweir 				nUpdateMode = pItem->GetValue();
573cdf0e10cSrcweir 		}
574cdf0e10cSrcweir 
575cdf0e10cSrcweir         String sNmURL( lcl_DDE_RelToAbs( sTopic, sReferer ) );
576cdf0e10cSrcweir 		aCC.toLower( sNmURL );
577cdf0e10cSrcweir 
578cdf0e10cSrcweir 		if ( !pShell )
579cdf0e10cSrcweir 		{
580cdf0e10cSrcweir 			bFirst = sal_False;
581cdf0e10cSrcweir             pShell = SfxObjectShell::GetFirst( &aType, sal_False );
582cdf0e10cSrcweir 		}
583cdf0e10cSrcweir 
584cdf0e10cSrcweir 		while( pShell )
585cdf0e10cSrcweir 		{
586cdf0e10cSrcweir 			if( !sTmp.Len() )
587cdf0e10cSrcweir 			{
588cdf0e10cSrcweir 				sTmp = pShell->GetTitle( SFX_TITLE_FULLNAME );
589cdf0e10cSrcweir                 sTmp = lcl_DDE_RelToAbs(sTmp, sReferer );
590cdf0e10cSrcweir 			}
591cdf0e10cSrcweir 
592cdf0e10cSrcweir 
593cdf0e10cSrcweir 			aCC.toLower( sTmp );
594cdf0e10cSrcweir 			if( sTmp == sNmURL )		// die wollen wir haben
595cdf0e10cSrcweir 			{
596cdf0e10cSrcweir 				pFndShell = pShell;
597cdf0e10cSrcweir 				break;
598cdf0e10cSrcweir 			}
599cdf0e10cSrcweir 
600cdf0e10cSrcweir 			if( bFirst )
601cdf0e10cSrcweir 			{
602cdf0e10cSrcweir 				bFirst = sal_False;
603cdf0e10cSrcweir                 pShell = SfxObjectShell::GetFirst( &aType, sal_False );
604cdf0e10cSrcweir 			}
605cdf0e10cSrcweir 			else
606cdf0e10cSrcweir                 pShell = SfxObjectShell::GetNext( *pShell, &aType, sal_False );
607cdf0e10cSrcweir 
608cdf0e10cSrcweir 			sTmp.Erase();
609cdf0e10cSrcweir 		}
610cdf0e10cSrcweir 	}
611cdf0e10cSrcweir 
612cdf0e10cSrcweir 	// empty topics are not allowed - which document is it
613cdf0e10cSrcweir 	if( !sTopic.Len() )
614cdf0e10cSrcweir 		return sal_False;
615cdf0e10cSrcweir 
616cdf0e10cSrcweir 	if( !pFndShell )
617cdf0e10cSrcweir 	{
618cdf0e10cSrcweir 		// dann versuche die Datei zu laden:
619cdf0e10cSrcweir 		INetURLObject aURL( sTopic );
620cdf0e10cSrcweir 		INetProtocol eOld = aURL.GetProtocol();
621cdf0e10cSrcweir         aURL.SetURL( sTopic = lcl_DDE_RelToAbs( sTopic, sReferer ) );
622cdf0e10cSrcweir 		if( INET_PROT_NOT_VALID != eOld ||
623cdf0e10cSrcweir 			INET_PROT_HTTP != aURL.GetProtocol() )
624cdf0e10cSrcweir 		{
625cdf0e10cSrcweir 			SfxStringItem aName( SID_FILE_NAME, sTopic );
626cdf0e10cSrcweir             SfxBoolItem aMinimized(SID_MINIMIZED, sal_True);
627cdf0e10cSrcweir             SfxBoolItem aHidden(SID_HIDDEN, sal_True);
628cdf0e10cSrcweir             SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
629cdf0e10cSrcweir 			SfxStringItem aReferer( SID_REFERER, sReferer );
630cdf0e10cSrcweir 			SfxUInt16Item aUpdate( SID_UPDATEDOCMODE, nUpdateMode );
631cdf0e10cSrcweir             SfxBoolItem aReadOnly(SID_DOC_READONLY, sal_True);
632cdf0e10cSrcweir 
633cdf0e10cSrcweir             // #i14200# (DDE-link crashes wordprocessor)
634cdf0e10cSrcweir             SfxAllItemSet aArgs( SFX_APP()->GetPool() );
635cdf0e10cSrcweir             aArgs.Put(aReferer);
636cdf0e10cSrcweir             aArgs.Put(aTarget);
637cdf0e10cSrcweir             aArgs.Put(aHidden);
638cdf0e10cSrcweir             aArgs.Put(aMinimized);
639cdf0e10cSrcweir             aArgs.Put(aName);
640cdf0e10cSrcweir 			aArgs.Put(aUpdate);
641cdf0e10cSrcweir 			aArgs.Put(aReadOnly);
642cdf0e10cSrcweir             pFndShell = SfxObjectShell::CreateAndLoadObject( aArgs );
643cdf0e10cSrcweir 		}
644cdf0e10cSrcweir 	}
645cdf0e10cSrcweir 
646cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
647cdf0e10cSrcweir 	if( pFndShell )
648cdf0e10cSrcweir 	{
649cdf0e10cSrcweir 		sfx2::SvLinkSource* pNewSrc = pFndShell->DdeCreateLinkSource( sItem );
650cdf0e10cSrcweir 		if( pNewSrc )
651cdf0e10cSrcweir 		{
652cdf0e10cSrcweir 			bRet = sal_True;
653cdf0e10cSrcweir 
654cdf0e10cSrcweir 			::com::sun::star::datatransfer::DataFlavor aFl;
655cdf0e10cSrcweir 			SotExchange::GetFormatDataFlavor( pLink->GetContentType(), aFl );
656cdf0e10cSrcweir 
657cdf0e10cSrcweir 			pLink->SetObj( pNewSrc );
658cdf0e10cSrcweir 			pNewSrc->AddDataAdvise( pLink, aFl.MimeType,
659cdf0e10cSrcweir 								sfx2::LINKUPDATE_ONCALL == pLink->GetUpdateMode()
660cdf0e10cSrcweir 									? ADVISEMODE_ONLYONCE
661cdf0e10cSrcweir 									: 0 );
662cdf0e10cSrcweir 		}
663cdf0e10cSrcweir 	}
664cdf0e10cSrcweir 	return bRet;
665cdf0e10cSrcweir }
666cdf0e10cSrcweir 
667cdf0e10cSrcweir 
668cdf0e10cSrcweir }
669cdf0e10cSrcweir 
670cdf0e10cSrcweir 
671cdf0e10cSrcweir 
672