xref: /trunk/main/sfx2/source/appl/linkmgr2.cxx (revision 45fd3b9abd7258384488f2747dad7bc0899f1720)
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
10cdf0e10cSrcweir  *
11d119d52dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
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.
19cdf0e10cSrcweir  *
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>
43*45fd3b9aSArmin 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)
68cdf0e10cSrcweir     : pPersist( p )
69cdf0e10cSrcweir {
70cdf0e10cSrcweir }
71cdf0e10cSrcweir 
72cdf0e10cSrcweir 
73cdf0e10cSrcweir LinkManager::~LinkManager()
74cdf0e10cSrcweir {
75cdf0e10cSrcweir     SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData();
76cdf0e10cSrcweir     for( sal_uInt16 n = aLinkTbl.Count(); n; --n, ++ppRef )
77cdf0e10cSrcweir     {
78cdf0e10cSrcweir         if( (*ppRef)->Is() )
79cdf0e10cSrcweir         {
80cdf0e10cSrcweir             (*(*ppRef))->Disconnect();
81cdf0e10cSrcweir             (*(*ppRef))->SetLinkManager( NULL );
82cdf0e10cSrcweir         }
83cdf0e10cSrcweir         delete *ppRef;
84cdf0e10cSrcweir     }
85cdf0e10cSrcweir }
86cdf0e10cSrcweir 
87cdf0e10cSrcweir 
88cdf0e10cSrcweir /************************************************************************
89cdf0e10cSrcweir |*    LinkManager::Remove()
90cdf0e10cSrcweir |*
91cdf0e10cSrcweir |*    Beschreibung
92cdf0e10cSrcweir *************************************************************************/
93cdf0e10cSrcweir 
94cdf0e10cSrcweir void LinkManager::Remove( SvBaseLink *pLink )
95cdf0e10cSrcweir {
96cdf0e10cSrcweir     // keine Links doppelt einfuegen
97cdf0e10cSrcweir     int bFound = sal_False;
98cdf0e10cSrcweir     SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData();
99cdf0e10cSrcweir     for( sal_uInt16 n = aLinkTbl.Count(); n; --n, ++ppRef )
100cdf0e10cSrcweir     {
101cdf0e10cSrcweir         if( pLink == *(*ppRef) )
102cdf0e10cSrcweir         {
103cdf0e10cSrcweir             (*(*ppRef))->Disconnect();
104cdf0e10cSrcweir             (*(*ppRef))->SetLinkManager( NULL );
105cdf0e10cSrcweir             (*(*ppRef)).Clear();
106cdf0e10cSrcweir             bFound = sal_True;
107cdf0e10cSrcweir         }
108cdf0e10cSrcweir 
109cdf0e10cSrcweir         // falls noch leere rum stehen sollten, weg damit
110cdf0e10cSrcweir         if( !(*ppRef)->Is() )
111cdf0e10cSrcweir         {
112cdf0e10cSrcweir             delete *ppRef;
113cdf0e10cSrcweir             aLinkTbl.Remove( aLinkTbl.Count() - n, 1 );
114cdf0e10cSrcweir             if( bFound )
115cdf0e10cSrcweir                 return ;
116cdf0e10cSrcweir             --ppRef;
117cdf0e10cSrcweir         }
118cdf0e10cSrcweir     }
119cdf0e10cSrcweir }
120cdf0e10cSrcweir 
121cdf0e10cSrcweir 
122cdf0e10cSrcweir void LinkManager::Remove( sal_uInt16 nPos, sal_uInt16 nCnt )
123cdf0e10cSrcweir {
124cdf0e10cSrcweir     if( nCnt && nPos < aLinkTbl.Count() )
125cdf0e10cSrcweir     {
126cdf0e10cSrcweir         if( nPos + nCnt > aLinkTbl.Count() )
127cdf0e10cSrcweir             nCnt = aLinkTbl.Count() - nPos;
128cdf0e10cSrcweir 
129cdf0e10cSrcweir         SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData() + nPos;
130cdf0e10cSrcweir         for( sal_uInt16 n = nCnt; n; --n, ++ppRef )
131cdf0e10cSrcweir         {
132cdf0e10cSrcweir             if( (*ppRef)->Is() )
133cdf0e10cSrcweir             {
134cdf0e10cSrcweir                 (*(*ppRef))->Disconnect();
135cdf0e10cSrcweir                 (*(*ppRef))->SetLinkManager( NULL );
136cdf0e10cSrcweir             }
137cdf0e10cSrcweir             delete *ppRef;
138cdf0e10cSrcweir         }
139cdf0e10cSrcweir         aLinkTbl.Remove( nPos, nCnt );
140cdf0e10cSrcweir     }
141cdf0e10cSrcweir }
142cdf0e10cSrcweir 
143cdf0e10cSrcweir 
144cdf0e10cSrcweir sal_Bool LinkManager::Insert( SvBaseLink* pLink )
145cdf0e10cSrcweir {
146cdf0e10cSrcweir     // keine Links doppelt einfuegen
147cdf0e10cSrcweir     for( sal_uInt16 n = 0; n < aLinkTbl.Count(); ++n )
148cdf0e10cSrcweir     {
149cdf0e10cSrcweir         SvBaseLinkRef* pTmp = aLinkTbl[ n ];
150cdf0e10cSrcweir         if( !pTmp->Is() )
151cdf0e10cSrcweir             aLinkTbl.DeleteAndDestroy( n-- );
152cdf0e10cSrcweir 
153cdf0e10cSrcweir         if( pLink == *pTmp )
154cdf0e10cSrcweir             return sal_False;
155cdf0e10cSrcweir     }
156cdf0e10cSrcweir 
157cdf0e10cSrcweir     SvBaseLinkRef* pTmp = new SvBaseLinkRef( pLink );
158cdf0e10cSrcweir     pLink->SetLinkManager( this );
159cdf0e10cSrcweir     aLinkTbl.Insert( pTmp, aLinkTbl.Count() );
160cdf0e10cSrcweir     return sal_True;
161cdf0e10cSrcweir }
162cdf0e10cSrcweir 
163cdf0e10cSrcweir 
164cdf0e10cSrcweir sal_Bool LinkManager::InsertLink( SvBaseLink * pLink,
165cdf0e10cSrcweir                                 sal_uInt16 nObjType,
166cdf0e10cSrcweir                                 sal_uInt16 nUpdateMode,
167cdf0e10cSrcweir                                 const String* pName )
168cdf0e10cSrcweir {
169cdf0e10cSrcweir     // unbedingt zuerst
170cdf0e10cSrcweir     pLink->SetObjType( nObjType );
171cdf0e10cSrcweir     if( pName )
172cdf0e10cSrcweir         pLink->SetName( *pName );
173cdf0e10cSrcweir     pLink->SetUpdateMode( nUpdateMode );
174cdf0e10cSrcweir     return Insert( pLink );
175cdf0e10cSrcweir }
176cdf0e10cSrcweir 
177cdf0e10cSrcweir 
178cdf0e10cSrcweir sal_Bool LinkManager::InsertDDELink( SvBaseLink * pLink,
179cdf0e10cSrcweir                                     const String& rServer,
180cdf0e10cSrcweir                                     const String& rTopic,
181cdf0e10cSrcweir                                     const String& rItem )
182cdf0e10cSrcweir {
183cdf0e10cSrcweir     if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
184cdf0e10cSrcweir         return sal_False;
185cdf0e10cSrcweir 
186cdf0e10cSrcweir     String sCmd;
187cdf0e10cSrcweir     ::sfx2::MakeLnkName( sCmd, &rServer, rTopic, rItem );
188cdf0e10cSrcweir 
189cdf0e10cSrcweir     pLink->SetObjType( OBJECT_CLIENT_DDE );
190cdf0e10cSrcweir     pLink->SetName( sCmd );
191cdf0e10cSrcweir     return Insert( pLink );
192cdf0e10cSrcweir }
193cdf0e10cSrcweir 
194cdf0e10cSrcweir 
195cdf0e10cSrcweir sal_Bool LinkManager::InsertDDELink( SvBaseLink * pLink )
196cdf0e10cSrcweir {
197cdf0e10cSrcweir     DBG_ASSERT( OBJECT_CLIENT_SO & pLink->GetObjType(), "no OBJECT_CLIENT_SO" );
198cdf0e10cSrcweir     if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
199cdf0e10cSrcweir         return sal_False;
200cdf0e10cSrcweir 
201cdf0e10cSrcweir     if( pLink->GetObjType() == OBJECT_CLIENT_SO )
202cdf0e10cSrcweir         pLink->SetObjType( OBJECT_CLIENT_DDE );
203cdf0e10cSrcweir 
204cdf0e10cSrcweir     return Insert( pLink );
205cdf0e10cSrcweir }
206cdf0e10cSrcweir 
207cdf0e10cSrcweir 
208cdf0e10cSrcweir // erfrage die Strings fuer den Dialog
209cdf0e10cSrcweir sal_Bool LinkManager::GetDisplayNames( const SvBaseLink * pLink,
210cdf0e10cSrcweir                                         String* pType,
211cdf0e10cSrcweir                                         String* pFile,
212cdf0e10cSrcweir                                         String* pLinkStr,
213cdf0e10cSrcweir                                         String* pFilter ) const
214cdf0e10cSrcweir {
215cdf0e10cSrcweir     sal_Bool bRet = sal_False;
216cdf0e10cSrcweir     const String sLNm( pLink->GetLinkSourceName() );
217cdf0e10cSrcweir     if( sLNm.Len() )
218cdf0e10cSrcweir     {
219cdf0e10cSrcweir         switch( pLink->GetObjType() )
220cdf0e10cSrcweir         {
221cdf0e10cSrcweir             case OBJECT_CLIENT_FILE:
222cdf0e10cSrcweir             case OBJECT_CLIENT_GRF:
223cdf0e10cSrcweir             case OBJECT_CLIENT_OLE:
224cdf0e10cSrcweir                 {
225cdf0e10cSrcweir                     sal_uInt16 nPos = 0;
226cdf0e10cSrcweir                     String sFile( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) );
227cdf0e10cSrcweir                     String sRange( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) );
228cdf0e10cSrcweir 
229cdf0e10cSrcweir                     if( pFile )
230cdf0e10cSrcweir                         *pFile = sFile;
231cdf0e10cSrcweir                     if( pLinkStr )
232cdf0e10cSrcweir                         *pLinkStr = sRange;
233cdf0e10cSrcweir                     if( pFilter )
234cdf0e10cSrcweir                         *pFilter = sLNm.Copy( nPos );
235cdf0e10cSrcweir 
236cdf0e10cSrcweir                     if( pType )
237cdf0e10cSrcweir                     {
238cdf0e10cSrcweir                         sal_uInt16 nObjType = pLink->GetObjType();
239cdf0e10cSrcweir                         *pType = String( SfxResId(
240cdf0e10cSrcweir                                     ( OBJECT_CLIENT_FILE == nObjType || OBJECT_CLIENT_OLE == nObjType )
241cdf0e10cSrcweir                                             ? RID_SVXSTR_FILELINK
242cdf0e10cSrcweir                                             : RID_SVXSTR_GRAFIKLINK ));
243cdf0e10cSrcweir                     }
244cdf0e10cSrcweir                     bRet = sal_True;
245cdf0e10cSrcweir                 }
246cdf0e10cSrcweir                 break;
247cdf0e10cSrcweir             case OBJECT_CLIENT_DDE:
248cdf0e10cSrcweir                 {
249cdf0e10cSrcweir                     sal_uInt16 nTmp = 0;
250cdf0e10cSrcweir                     String sCmd( sLNm );
251cdf0e10cSrcweir                     String sServer( sCmd.GetToken( 0, cTokenSeperator, nTmp ) );
252cdf0e10cSrcweir                     String sTopic( sCmd.GetToken( 0, cTokenSeperator, nTmp ) );
253cdf0e10cSrcweir 
254cdf0e10cSrcweir                     if( pType )
255cdf0e10cSrcweir                         *pType = sServer;
256cdf0e10cSrcweir                     if( pFile )
257cdf0e10cSrcweir                         *pFile = sTopic;
258cdf0e10cSrcweir                     if( pLinkStr )
259cdf0e10cSrcweir                         *pLinkStr = sCmd.Copy( nTmp );
260cdf0e10cSrcweir                     bRet = sal_True;
261cdf0e10cSrcweir                 }
262cdf0e10cSrcweir                 break;
263cdf0e10cSrcweir             default:
264cdf0e10cSrcweir                 break;
265cdf0e10cSrcweir         }
266cdf0e10cSrcweir     }
267cdf0e10cSrcweir 
268cdf0e10cSrcweir     return bRet;
269cdf0e10cSrcweir }
270cdf0e10cSrcweir 
271cdf0e10cSrcweir 
272cdf0e10cSrcweir void LinkManager::UpdateAllLinks(
273cdf0e10cSrcweir     sal_Bool bAskUpdate,
274cdf0e10cSrcweir     sal_Bool /*bCallErrHdl*/,
275cdf0e10cSrcweir     sal_Bool bUpdateGrfLinks,
276cdf0e10cSrcweir     Window* pParentWin )
277cdf0e10cSrcweir {
278cdf0e10cSrcweir     SvStringsDtor aApps, aTopics, aItems;
279cdf0e10cSrcweir     String sApp, sTopic, sItem;
280cdf0e10cSrcweir 
281cdf0e10cSrcweir     // erstmal eine Kopie vom Array machen, damit sich updatende Links in
282cdf0e10cSrcweir     // Links in ... nicht dazwischen funken!!
283cdf0e10cSrcweir     SvPtrarr aTmpArr( 255, 50 );
284cdf0e10cSrcweir     sal_uInt16 n;
285cdf0e10cSrcweir     for( n = 0; n < aLinkTbl.Count(); ++n )
286cdf0e10cSrcweir     {
287cdf0e10cSrcweir         SvBaseLink* pLink = *aLinkTbl[ n ];
288cdf0e10cSrcweir         if( !pLink )
289cdf0e10cSrcweir         {
290cdf0e10cSrcweir             Remove( n-- );
291cdf0e10cSrcweir             continue;
292cdf0e10cSrcweir         }
293cdf0e10cSrcweir         aTmpArr.Insert( pLink, aTmpArr.Count() );
294cdf0e10cSrcweir     }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir     for( n = 0; n < aTmpArr.Count(); ++n )
297cdf0e10cSrcweir     {
298cdf0e10cSrcweir         SvBaseLink* pLink = (SvBaseLink*)aTmpArr[ n ];
299cdf0e10cSrcweir 
300cdf0e10cSrcweir         // suche erstmal im Array nach dem Eintrag
301cdf0e10cSrcweir         sal_uInt16 nFndPos = USHRT_MAX;
302cdf0e10cSrcweir         for( sal_uInt16 i = 0; i < aLinkTbl.Count(); ++i )
303cdf0e10cSrcweir             if( pLink == *aLinkTbl[ i ] )
304cdf0e10cSrcweir             {
305cdf0e10cSrcweir                 nFndPos = i;
306cdf0e10cSrcweir                 break;
307cdf0e10cSrcweir             }
308cdf0e10cSrcweir 
309cdf0e10cSrcweir         if( USHRT_MAX == nFndPos )
310cdf0e10cSrcweir             continue;                   // war noch nicht vorhanden!
311cdf0e10cSrcweir 
312cdf0e10cSrcweir         // Graphic-Links noch nicht updaten
313cdf0e10cSrcweir         if( !pLink->IsVisible() ||
314cdf0e10cSrcweir             ( !bUpdateGrfLinks && OBJECT_CLIENT_GRF == pLink->GetObjType() ))
315cdf0e10cSrcweir             continue;
316cdf0e10cSrcweir 
317cdf0e10cSrcweir         if( bAskUpdate )
318cdf0e10cSrcweir         {
319cdf0e10cSrcweir             int nRet = QueryBox( pParentWin, WB_YES_NO | WB_DEF_YES, SfxResId( STR_QUERY_UPDATE_LINKS ) ).Execute();
320cdf0e10cSrcweir             if( RET_YES != nRet )
321cdf0e10cSrcweir                 return ;        // es soll nichts geupdatet werden
322cdf0e10cSrcweir             bAskUpdate = sal_False;     // einmal reicht
323cdf0e10cSrcweir         }
324cdf0e10cSrcweir 
325cdf0e10cSrcweir         pLink->Update();
326cdf0e10cSrcweir     }
327cdf0e10cSrcweir }
328cdf0e10cSrcweir 
329cdf0e10cSrcweir /************************************************************************
330cdf0e10cSrcweir |*    SvBaseLink::CreateObject()
331cdf0e10cSrcweir |*
332cdf0e10cSrcweir |*    Beschreibung
333cdf0e10cSrcweir *************************************************************************/
334cdf0e10cSrcweir 
335cdf0e10cSrcweir SvLinkSourceRef LinkManager::CreateObj( SvBaseLink * pLink )
336cdf0e10cSrcweir {
337cdf0e10cSrcweir     switch( pLink->GetObjType() )
338cdf0e10cSrcweir     {
339cdf0e10cSrcweir         case OBJECT_CLIENT_FILE:
340cdf0e10cSrcweir         case OBJECT_CLIENT_GRF:
341cdf0e10cSrcweir         case OBJECT_CLIENT_OLE:
342cdf0e10cSrcweir             return new SvFileObject;
343cdf0e10cSrcweir         case OBJECT_INTERN:
344cdf0e10cSrcweir             return new SvxInternalLink;
345cdf0e10cSrcweir         case OBJECT_CLIENT_DDE:
346cdf0e10cSrcweir             return new SvDDEObject;
347cdf0e10cSrcweir         default:
348cdf0e10cSrcweir             return SvLinkSourceRef();
349cdf0e10cSrcweir     }
350cdf0e10cSrcweir }
351cdf0e10cSrcweir 
352cdf0e10cSrcweir sal_Bool LinkManager::InsertServer( SvLinkSource* pObj )
353cdf0e10cSrcweir {
354cdf0e10cSrcweir     // keine doppelt einfuegen
355cdf0e10cSrcweir     if( !pObj || USHRT_MAX != aServerTbl.GetPos( pObj ) )
356cdf0e10cSrcweir         return sal_False;
357cdf0e10cSrcweir 
358cdf0e10cSrcweir     aServerTbl.Insert( pObj, aServerTbl.Count() );
359cdf0e10cSrcweir     return sal_True;
360cdf0e10cSrcweir }
361cdf0e10cSrcweir 
362cdf0e10cSrcweir 
363cdf0e10cSrcweir void LinkManager::RemoveServer( SvLinkSource* pObj )
364cdf0e10cSrcweir {
365cdf0e10cSrcweir     sal_uInt16 nPos = aServerTbl.GetPos( pObj );
366cdf0e10cSrcweir     if( USHRT_MAX != nPos )
367cdf0e10cSrcweir         aServerTbl.Remove( nPos, 1 );
368cdf0e10cSrcweir }
369cdf0e10cSrcweir 
370cdf0e10cSrcweir 
371cdf0e10cSrcweir void MakeLnkName( String& rName, const String* pType, const String& rFile,
372cdf0e10cSrcweir                     const String& rLink, const String* pFilter )
373cdf0e10cSrcweir {
374cdf0e10cSrcweir     if( pType )
375cdf0e10cSrcweir         (rName = *pType).EraseLeadingChars().EraseTrailingChars() += cTokenSeperator;
376cdf0e10cSrcweir     else if( rName.Len() )
377cdf0e10cSrcweir         rName.Erase();
378cdf0e10cSrcweir 
379cdf0e10cSrcweir     ((rName += rFile).EraseLeadingChars().EraseTrailingChars() +=
380cdf0e10cSrcweir         cTokenSeperator ).EraseLeadingChars().EraseTrailingChars() += rLink;
381cdf0e10cSrcweir     if( pFilter )
382cdf0e10cSrcweir         ((rName += cTokenSeperator ) += *pFilter).EraseLeadingChars().EraseTrailingChars();
383cdf0e10cSrcweir }
384cdf0e10cSrcweir 
385cdf0e10cSrcweir sal_Bool LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink,
386cdf0e10cSrcweir                                     sal_uInt16 nFileType,
387cdf0e10cSrcweir                                     const String& rFileNm,
388cdf0e10cSrcweir                                     const String* pFilterNm,
389cdf0e10cSrcweir                                     const String* pRange )
390cdf0e10cSrcweir {
391cdf0e10cSrcweir     if( !( OBJECT_CLIENT_SO & rLink.GetObjType() ))
392cdf0e10cSrcweir         return sal_False;
393cdf0e10cSrcweir 
394cdf0e10cSrcweir     String sCmd( rFileNm );
395cdf0e10cSrcweir     sCmd += ::sfx2::cTokenSeperator;
396cdf0e10cSrcweir     if( pRange )
397cdf0e10cSrcweir         sCmd += *pRange;
398cdf0e10cSrcweir     if( pFilterNm )
399cdf0e10cSrcweir         ( sCmd += ::sfx2::cTokenSeperator ) += *pFilterNm;
400cdf0e10cSrcweir 
401cdf0e10cSrcweir     return InsertLink( &rLink, nFileType, sfx2::LINKUPDATE_ONCALL, &sCmd );
402cdf0e10cSrcweir }
403cdf0e10cSrcweir 
404cdf0e10cSrcweir sal_Bool LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink )
405cdf0e10cSrcweir {
406cdf0e10cSrcweir     if( OBJECT_CLIENT_FILE == ( OBJECT_CLIENT_FILE & rLink.GetObjType() ))
407cdf0e10cSrcweir         return InsertLink( &rLink, rLink.GetObjType(), sfx2::LINKUPDATE_ONCALL );
408cdf0e10cSrcweir     return sal_False;
409cdf0e10cSrcweir }
410cdf0e10cSrcweir 
411cdf0e10cSrcweir // eine Uebertragung wird abgebrochen, also alle DownloadMedien canceln
412cdf0e10cSrcweir // (ist zur Zeit nur fuer die FileLinks interressant!)
413cdf0e10cSrcweir void LinkManager::CancelTransfers()
414cdf0e10cSrcweir {
415cdf0e10cSrcweir     SvFileObject* pFileObj;
416cdf0e10cSrcweir     sfx2::SvBaseLink* pLnk;
417cdf0e10cSrcweir 
418cdf0e10cSrcweir     const sfx2::SvBaseLinks& rLnks = GetLinks();
419cdf0e10cSrcweir     for( sal_uInt16 n = rLnks.Count(); n; )
420cdf0e10cSrcweir         if( 0 != ( pLnk = &(*rLnks[ --n ])) &&
421cdf0e10cSrcweir             OBJECT_CLIENT_FILE == (OBJECT_CLIENT_FILE & pLnk->GetObjType()) &&
422cdf0e10cSrcweir             0 != ( pFileObj = (SvFileObject*)pLnk->GetObj() ) )
423cdf0e10cSrcweir //          0 != ( pFileObj = (SvFileObject*)SvFileObject::ClassFactory()->
424cdf0e10cSrcweir //                                  CastAndAddRef( pLnk->GetObj() )) )
425cdf0e10cSrcweir             pFileObj->CancelTransfers();
426cdf0e10cSrcweir }
427cdf0e10cSrcweir 
428cdf0e10cSrcweir     // um Status Informationen aus dem FileObject an den BaseLink zu
429cdf0e10cSrcweir     // senden, gibt es eine eigene ClipBoardId. Das SvData-Object hat
430cdf0e10cSrcweir     // dann die entsprechenden Informationen als String.
431cdf0e10cSrcweir     // Wird zur Zeit fuer FileObject in Verbindung mit JavaScript benoetigt
432cdf0e10cSrcweir     // - das braucht Informationen ueber Load/Abort/Error
433cdf0e10cSrcweir sal_uIntPtr LinkManager::RegisterStatusInfoId()
434cdf0e10cSrcweir {
435cdf0e10cSrcweir     static sal_uIntPtr nFormat = 0;
436cdf0e10cSrcweir 
437cdf0e10cSrcweir     if( !nFormat )
438cdf0e10cSrcweir     {
439cdf0e10cSrcweir // wie sieht die neue Schnittstelle aus?
440cdf0e10cSrcweir //      nFormat = Exchange::RegisterFormatName( "StatusInfo vom SvxInternalLink" );
441cdf0e10cSrcweir         nFormat = SotExchange::RegisterFormatName(
442cdf0e10cSrcweir                     String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM(
443cdf0e10cSrcweir                                 "StatusInfo vom SvxInternalLink" )));
444cdf0e10cSrcweir     }
445cdf0e10cSrcweir     return nFormat;
446cdf0e10cSrcweir }
447cdf0e10cSrcweir 
448cdf0e10cSrcweir // ----------------------------------------------------------------------
449cdf0e10cSrcweir 
450cdf0e10cSrcweir sal_Bool LinkManager::GetGraphicFromAny( const String& rMimeType,
451cdf0e10cSrcweir                                 const ::com::sun::star::uno::Any & rValue,
452cdf0e10cSrcweir                                 Graphic& rGrf )
453cdf0e10cSrcweir {
454cdf0e10cSrcweir     sal_Bool bRet = sal_False;
455cdf0e10cSrcweir     ::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
456cdf0e10cSrcweir     if( rValue.hasValue() && ( rValue >>= aSeq ) )
457cdf0e10cSrcweir     {
458cdf0e10cSrcweir         SvMemoryStream aMemStm( (void*)aSeq.getConstArray(), aSeq.getLength(),
459cdf0e10cSrcweir                                 STREAM_READ );
460cdf0e10cSrcweir         aMemStm.Seek( 0 );
461cdf0e10cSrcweir 
462cdf0e10cSrcweir         switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
463cdf0e10cSrcweir         {
464cdf0e10cSrcweir         case SOT_FORMATSTR_ID_SVXB:
465cdf0e10cSrcweir             {
466cdf0e10cSrcweir                 aMemStm >> rGrf;
467cdf0e10cSrcweir                 bRet = sal_True;
468cdf0e10cSrcweir             }
469cdf0e10cSrcweir             break;
470cdf0e10cSrcweir         case FORMAT_GDIMETAFILE:
471cdf0e10cSrcweir             {
472cdf0e10cSrcweir                 GDIMetaFile aMtf;
473cdf0e10cSrcweir                 aMtf.Read( aMemStm );
474cdf0e10cSrcweir                 rGrf = aMtf;
475cdf0e10cSrcweir                 bRet = sal_True;
476cdf0e10cSrcweir             }
477cdf0e10cSrcweir             break;
478cdf0e10cSrcweir         case FORMAT_BITMAP:
479cdf0e10cSrcweir             {
480cdf0e10cSrcweir                 Bitmap aBmp;
481*45fd3b9aSArmin Le Grand                 ReadDIB(aBmp, aMemStm, true);
482cdf0e10cSrcweir                 rGrf = aBmp;
483cdf0e10cSrcweir                 bRet = sal_True;
484cdf0e10cSrcweir             }
485cdf0e10cSrcweir             break;
486cdf0e10cSrcweir         }
487cdf0e10cSrcweir     }
488cdf0e10cSrcweir     return bRet;
489cdf0e10cSrcweir }
490cdf0e10cSrcweir 
491cdf0e10cSrcweir 
492cdf0e10cSrcweir // ----------------------------------------------------------------------
493cdf0e10cSrcweir String lcl_DDE_RelToAbs( const String& rTopic, const String& rBaseURL )
494cdf0e10cSrcweir {
495cdf0e10cSrcweir     String sRet;
496cdf0e10cSrcweir     INetURLObject aURL( rTopic );
497cdf0e10cSrcweir     if( INET_PROT_NOT_VALID == aURL.GetProtocol() )
498cdf0e10cSrcweir         utl::LocalFileHelper::ConvertSystemPathToURL( rTopic, rBaseURL, sRet );
499cdf0e10cSrcweir     if( !sRet.Len() )
500cdf0e10cSrcweir         sRet = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), rTopic, URIHelper::GetMaybeFileHdl(), true );
501cdf0e10cSrcweir     return sRet;
502cdf0e10cSrcweir }
503cdf0e10cSrcweir 
504cdf0e10cSrcweir sal_Bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink )
505cdf0e10cSrcweir {
506cdf0e10cSrcweir     SfxObjectShell* pFndShell = 0;
507cdf0e10cSrcweir     sal_uInt16 nUpdateMode = com::sun::star::document::UpdateDocMode::NO_UPDATE;
508cdf0e10cSrcweir     String sTopic, sItem, sReferer;
509cdf0e10cSrcweir     if( pLink->GetLinkManager() &&
510cdf0e10cSrcweir         pLink->GetLinkManager()->GetDisplayNames( pLink, 0, &sTopic, &sItem )
511cdf0e10cSrcweir         && sTopic.Len() )
512cdf0e10cSrcweir     {
513cdf0e10cSrcweir         // erstmal nur ueber die DocumentShells laufen und die mit dem
514cdf0e10cSrcweir         // Namen heraussuchen:
515cdf0e10cSrcweir 
516cdf0e10cSrcweir         com::sun::star::lang::Locale aLocale;
517cdf0e10cSrcweir         MsLangId::convertLanguageToLocale( LANGUAGE_SYSTEM, aLocale );
518cdf0e10cSrcweir         CharClass aCC( aLocale );
519cdf0e10cSrcweir 
520cdf0e10cSrcweir         String sNm( sTopic ), sTmp;
521cdf0e10cSrcweir         aCC.toLower( sNm );
522cdf0e10cSrcweir 
523cdf0e10cSrcweir         TypeId aType( TYPE(SfxObjectShell) );
524cdf0e10cSrcweir 
525cdf0e10cSrcweir         sal_Bool bFirst = sal_True;
526cdf0e10cSrcweir         SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist();
527cdf0e10cSrcweir         if( pShell && pShell->GetMedium() )
528cdf0e10cSrcweir         {
529cdf0e10cSrcweir             sReferer = pShell->GetMedium()->GetBaseURL();
530cdf0e10cSrcweir             SFX_ITEMSET_ARG( pShell->GetMedium()->GetItemSet(), pItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False );
531cdf0e10cSrcweir             if ( pItem )
532cdf0e10cSrcweir                 nUpdateMode = pItem->GetValue();
533cdf0e10cSrcweir         }
534cdf0e10cSrcweir 
535cdf0e10cSrcweir         String sNmURL( lcl_DDE_RelToAbs( sTopic, sReferer ) );
536cdf0e10cSrcweir         aCC.toLower( sNmURL );
537cdf0e10cSrcweir 
538cdf0e10cSrcweir         if ( !pShell )
539cdf0e10cSrcweir         {
540cdf0e10cSrcweir             bFirst = sal_False;
541cdf0e10cSrcweir             pShell = SfxObjectShell::GetFirst( &aType, sal_False );
542cdf0e10cSrcweir         }
543cdf0e10cSrcweir 
544cdf0e10cSrcweir         while( pShell )
545cdf0e10cSrcweir         {
546cdf0e10cSrcweir             if( !sTmp.Len() )
547cdf0e10cSrcweir             {
548cdf0e10cSrcweir                 sTmp = pShell->GetTitle( SFX_TITLE_FULLNAME );
549cdf0e10cSrcweir                 sTmp = lcl_DDE_RelToAbs(sTmp, sReferer );
550cdf0e10cSrcweir             }
551cdf0e10cSrcweir 
552cdf0e10cSrcweir 
553cdf0e10cSrcweir             aCC.toLower( sTmp );
554cdf0e10cSrcweir             if( sTmp == sNmURL )        // die wollen wir haben
555cdf0e10cSrcweir             {
556cdf0e10cSrcweir                 pFndShell = pShell;
557cdf0e10cSrcweir                 break;
558cdf0e10cSrcweir             }
559cdf0e10cSrcweir 
560cdf0e10cSrcweir             if( bFirst )
561cdf0e10cSrcweir             {
562cdf0e10cSrcweir                 bFirst = sal_False;
563cdf0e10cSrcweir                 pShell = SfxObjectShell::GetFirst( &aType, sal_False );
564cdf0e10cSrcweir             }
565cdf0e10cSrcweir             else
566cdf0e10cSrcweir                 pShell = SfxObjectShell::GetNext( *pShell, &aType, sal_False );
567cdf0e10cSrcweir 
568cdf0e10cSrcweir             sTmp.Erase();
569cdf0e10cSrcweir         }
570cdf0e10cSrcweir     }
571cdf0e10cSrcweir 
572cdf0e10cSrcweir     // empty topics are not allowed - which document is it
573cdf0e10cSrcweir     if( !sTopic.Len() )
574cdf0e10cSrcweir         return sal_False;
575cdf0e10cSrcweir 
576cdf0e10cSrcweir     if( !pFndShell )
577cdf0e10cSrcweir     {
578cdf0e10cSrcweir         // dann versuche die Datei zu laden:
579cdf0e10cSrcweir         INetURLObject aURL( sTopic );
580cdf0e10cSrcweir         INetProtocol eOld = aURL.GetProtocol();
581cdf0e10cSrcweir         aURL.SetURL( sTopic = lcl_DDE_RelToAbs( sTopic, sReferer ) );
582cdf0e10cSrcweir         if( INET_PROT_NOT_VALID != eOld ||
583cdf0e10cSrcweir             INET_PROT_HTTP != aURL.GetProtocol() )
584cdf0e10cSrcweir         {
585cdf0e10cSrcweir             SfxStringItem aName( SID_FILE_NAME, sTopic );
586cdf0e10cSrcweir             SfxBoolItem aMinimized(SID_MINIMIZED, sal_True);
587cdf0e10cSrcweir             SfxBoolItem aHidden(SID_HIDDEN, sal_True);
588cdf0e10cSrcweir             SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
589cdf0e10cSrcweir             SfxStringItem aReferer( SID_REFERER, sReferer );
590cdf0e10cSrcweir             SfxUInt16Item aUpdate( SID_UPDATEDOCMODE, nUpdateMode );
591cdf0e10cSrcweir             SfxBoolItem aReadOnly(SID_DOC_READONLY, sal_True);
592cdf0e10cSrcweir 
593cdf0e10cSrcweir             // #i14200# (DDE-link crashes wordprocessor)
594cdf0e10cSrcweir             SfxAllItemSet aArgs( SFX_APP()->GetPool() );
595cdf0e10cSrcweir             aArgs.Put(aReferer);
596cdf0e10cSrcweir             aArgs.Put(aTarget);
597cdf0e10cSrcweir             aArgs.Put(aHidden);
598cdf0e10cSrcweir             aArgs.Put(aMinimized);
599cdf0e10cSrcweir             aArgs.Put(aName);
600cdf0e10cSrcweir             aArgs.Put(aUpdate);
601cdf0e10cSrcweir             aArgs.Put(aReadOnly);
602cdf0e10cSrcweir             pFndShell = SfxObjectShell::CreateAndLoadObject( aArgs );
603cdf0e10cSrcweir         }
604cdf0e10cSrcweir     }
605cdf0e10cSrcweir 
606cdf0e10cSrcweir     sal_Bool bRet = sal_False;
607cdf0e10cSrcweir     if( pFndShell )
608cdf0e10cSrcweir     {
609cdf0e10cSrcweir         sfx2::SvLinkSource* pNewSrc = pFndShell->DdeCreateLinkSource( sItem );
610cdf0e10cSrcweir         if( pNewSrc )
611cdf0e10cSrcweir         {
612cdf0e10cSrcweir             bRet = sal_True;
613cdf0e10cSrcweir 
614cdf0e10cSrcweir             ::com::sun::star::datatransfer::DataFlavor aFl;
615cdf0e10cSrcweir             SotExchange::GetFormatDataFlavor( pLink->GetContentType(), aFl );
616cdf0e10cSrcweir 
617cdf0e10cSrcweir             pLink->SetObj( pNewSrc );
618cdf0e10cSrcweir             pNewSrc->AddDataAdvise( pLink, aFl.MimeType,
619cdf0e10cSrcweir                                 sfx2::LINKUPDATE_ONCALL == pLink->GetUpdateMode()
620cdf0e10cSrcweir                                     ? ADVISEMODE_ONLYONCE
621cdf0e10cSrcweir                                     : 0 );
622cdf0e10cSrcweir         }
623cdf0e10cSrcweir     }
624cdf0e10cSrcweir     return bRet;
625cdf0e10cSrcweir }
626cdf0e10cSrcweir 
627cdf0e10cSrcweir 
628cdf0e10cSrcweir }
629cdf0e10cSrcweir 
630cdf0e10cSrcweir 
631cdf0e10cSrcweir 
632