merge the formfield patch from ooo-build
[ooovba.git] / svx / source / svxlink / linkmgr.cxx
blob5d96e0cfc4e734c2888a1a390a8a6fa99016881b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: linkmgr.cxx,v $
10 * $Revision: 1.34 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include <com/sun/star/document/UpdateDocMode.hpp>
34 #include <com/sun/star/uno/Sequence.h>
35 #include <sot/formats.hxx>
36 #include <sot/exchange.hxx>
37 #include <vcl/graph.hxx>
38 #include <sfx2/lnkbase.hxx>
39 #include <tools/urlobj.hxx>
40 #include <svtools/stritem.hxx>
41 #include <svtools/eitem.hxx>
42 #include <svtools/intitem.hxx>
43 #include <svtools/rectitem.hxx>
44 #include <sfx2/app.hxx>
45 #include <sfx2/request.hxx>
46 #include <sfx2/objsh.hxx>
47 #ifndef _SFX_INTERNO_HXX //autogen
48 //#include <sfx2/interno.hxx>
49 #endif
50 #include <sfx2/dispatch.hxx>
51 #include <unotools/charclass.hxx>
52 #include <unotools/localfilehelper.hxx>
53 #include <svtools/itemset.hxx>
54 #include <svtools/urihelper.hxx>
55 #include <com/sun/star/datatransfer/DataFlavor.hpp>
57 #include "linkmgr.hxx"
58 #include "fileobj.hxx"
59 #include <svx/dialmgr.hxx>
60 #include <svx/dialogs.hrc>
61 #include "unolingu.hxx"
63 class SvxInternalLink : public sfx2::SvLinkSource
65 public:
66 SvxInternalLink() {}
68 virtual BOOL Connect( sfx2::SvBaseLink* );
71 SvxLinkManager::SvxLinkManager( SfxObjectShell* _pPersist )
73 SvLinkManager::SetPersist( _pPersist );
76 sfx2::SvLinkSourceRef SvxLinkManager::CreateObj( sfx2::SvBaseLink * pLink )
78 switch( pLink->GetObjType() )
80 case OBJECT_CLIENT_FILE:
81 case OBJECT_CLIENT_GRF:
82 case OBJECT_CLIENT_OLE:
83 return new SvFileObject;
85 case OBJECT_INTERN:
86 return new SvxInternalLink();
88 return SvLinkManager::CreateObj( pLink );
92 BOOL SvxLinkManager::InsertFileLink( sfx2::SvBaseLink& rLink,
93 USHORT nFileType,
94 const String& rFileNm,
95 const String* pFilterNm,
96 const String* pRange )
98 if( !( OBJECT_CLIENT_SO & rLink.GetObjType() ))
99 return FALSE;
101 String sCmd( rFileNm );
102 sCmd += ::sfx2::cTokenSeperator;
103 if( pRange )
104 sCmd += *pRange;
105 if( pFilterNm )
106 ( sCmd += ::sfx2::cTokenSeperator ) += *pFilterNm;
108 return SvLinkManager::InsertLink( &rLink, nFileType,
109 sfx2::LINKUPDATE_ONCALL, &sCmd );
112 BOOL SvxLinkManager::InsertFileLink( sfx2::SvBaseLink& rLink )
114 if( OBJECT_CLIENT_FILE == ( OBJECT_CLIENT_FILE & rLink.GetObjType() ))
115 return SvLinkManager::InsertLink( &rLink, rLink.GetObjType(),
116 sfx2::LINKUPDATE_ONCALL );
117 return FALSE;
120 // erfrage die Strings fuer den Dialog
121 BOOL SvxLinkManager::GetDisplayNames( const sfx2::SvBaseLink* pBaseLink,
122 String* pType,
123 String* pFile,
124 String* pLink,
125 String* pFilter ) const
127 BOOL bRet = FALSE;
128 const String sLNm( pBaseLink->GetLinkSourceName() );
129 if( sLNm.Len() )
130 switch( pBaseLink->GetObjType() )
132 case OBJECT_CLIENT_FILE:
133 case OBJECT_CLIENT_GRF:
134 case OBJECT_CLIENT_OLE:
136 USHORT nPos = 0;
137 String sFile( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) );
138 String sRange( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) );
140 if( pFile )
141 *pFile = sFile;
142 if( pLink )
143 *pLink = sRange;
144 if( pFilter )
145 *pFilter = sLNm.Copy( nPos );
147 if( pType )
149 sal_uInt16 nObjType = pBaseLink->GetObjType();
150 *pType = String( ResId(
151 ( OBJECT_CLIENT_FILE == nObjType || OBJECT_CLIENT_OLE == nObjType )
152 ? RID_SVXSTR_FILELINK
153 : RID_SVXSTR_GRAFIKLINK
154 , DIALOG_MGR() ));
156 bRet = TRUE;
158 break;
159 default:
160 bRet = SvLinkManager::GetDisplayNames( pBaseLink, pType, pFile,
161 pLink, pFilter );
162 break;
164 return bRet;
167 // eine Uebertragung wird abgebrochen, also alle DownloadMedien canceln
168 // (ist zur Zeit nur fuer die FileLinks interressant!)
169 void SvxLinkManager::CancelTransfers()
171 SvFileObject* pFileObj;
172 sfx2::SvBaseLink* pLnk;
174 const sfx2::SvBaseLinks& rLnks = GetLinks();
175 for( USHORT n = rLnks.Count(); n; )
176 if( 0 != ( pLnk = &(*rLnks[ --n ])) &&
177 OBJECT_CLIENT_FILE == (OBJECT_CLIENT_FILE & pLnk->GetObjType()) &&
178 0 != ( pFileObj = (SvFileObject*)pLnk->GetObj() ) )
179 // 0 != ( pFileObj = (SvFileObject*)SvFileObject::ClassFactory()->
180 // CastAndAddRef( pLnk->GetObj() )) )
181 pFileObj->CancelTransfers();
184 void SvxLinkManager::SetTransferPriority( sfx2::SvBaseLink& /*rLink*/, USHORT /*nPrio*/ )
186 // SvFileObject* pFileObj =
187 // (SvFileObject*)SvFileObject::ClassFactory()->
188 // CastAndAddRef( rLink.GetObj() );
189 // OBJECT_CLIENT_FILE == (OBJECT_CLIENT_FILE & rLink.GetObjType()) ?
190 // (SvFileObject*)rLink.GetObj() : 0;
194 // um Status Informationen aus dem FileObject an den BaseLink zu
195 // senden, gibt es eine eigene ClipBoardId. Das SvData-Object hat
196 // dann die entsprechenden Informationen als String.
197 // Wird zur Zeit fuer FileObject in Verbindung mit JavaScript benoetigt
198 // - das braucht Informationen ueber Load/Abort/Error
199 ULONG SvxLinkManager::RegisterStatusInfoId()
201 static ULONG nFormat = 0;
203 if( !nFormat )
205 // wie sieht die neue Schnittstelle aus?
206 // nFormat = Exchange::RegisterFormatName( "StatusInfo vom SvxInternalLink" );
207 nFormat = SotExchange::RegisterFormatName(
208 String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM(
209 "StatusInfo vom SvxInternalLink" )));
211 return nFormat;
214 // ----------------------------------------------------------------------
216 BOOL SvxLinkManager::GetGraphicFromAny( const String& rMimeType,
217 const ::com::sun::star::uno::Any & rValue,
218 Graphic& rGrf )
220 BOOL bRet = FALSE;
221 ::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
222 if( rValue.hasValue() && ( rValue >>= aSeq ) )
224 SvMemoryStream aMemStm( (void*)aSeq.getConstArray(), aSeq.getLength(),
225 STREAM_READ );
226 aMemStm.Seek( 0 );
228 switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
230 case SOT_FORMATSTR_ID_SVXB:
232 aMemStm >> rGrf;
233 bRet = TRUE;
235 break;
236 case FORMAT_GDIMETAFILE:
238 GDIMetaFile aMtf;
239 aMtf.Read( aMemStm );
240 rGrf = aMtf;
241 bRet = TRUE;
243 break;
244 case FORMAT_BITMAP:
246 Bitmap aBmp;
247 aMemStm >> aBmp;
248 rGrf = aBmp;
249 bRet = TRUE;
251 break;
254 return bRet;
258 // ----------------------------------------------------------------------
259 String lcl_DDE_RelToAbs( const String& rTopic, const String& rBaseURL )
261 String sRet;
262 INetURLObject aURL( rTopic );
263 if( INET_PROT_NOT_VALID == aURL.GetProtocol() )
264 utl::LocalFileHelper::ConvertSystemPathToURL( rTopic, rBaseURL, sRet );
265 if( !sRet.Len() )
266 sRet = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), rTopic, URIHelper::GetMaybeFileHdl(), true );
267 return sRet;
270 BOOL SvxInternalLink::Connect( sfx2::SvBaseLink* pLink )
272 SfxObjectShell* pFndShell = 0;
273 USHORT nUpdateMode = com::sun::star::document::UpdateDocMode::NO_UPDATE;
274 String sTopic, sItem, sReferer;
275 if( pLink->GetLinkManager() &&
276 pLink->GetLinkManager()->GetDisplayNames( pLink, 0, &sTopic, &sItem )
277 && sTopic.Len() )
279 // erstmal nur ueber die DocumentShells laufen und die mit dem
280 // Namen heraussuchen:
282 CharClass aCC( SvxCreateLocale( LANGUAGE_SYSTEM ));
283 String sNm( sTopic ), sTmp;
284 aCC.toLower( sNm );
286 TypeId aType( TYPE(SfxObjectShell) );
288 BOOL bFirst = TRUE;
289 SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist();
290 if( pShell && pShell->GetMedium() )
292 sReferer = pShell->GetMedium()->GetBaseURL();
293 SFX_ITEMSET_ARG( pShell->GetMedium()->GetItemSet(), pItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False );
294 if ( pItem )
295 nUpdateMode = pItem->GetValue();
298 String sNmURL( lcl_DDE_RelToAbs( sTopic, sReferer ) );
299 aCC.toLower( sNmURL );
301 if ( !pShell )
303 bFirst = FALSE;
304 pShell = SfxObjectShell::GetFirst( &aType, sal_False );
307 while( pShell )
309 if( !sTmp.Len() )
311 sTmp = pShell->GetTitle( SFX_TITLE_FULLNAME );
312 sTmp = lcl_DDE_RelToAbs(sTmp, sReferer );
316 aCC.toLower( sTmp );
317 if( sTmp == sNmURL ) // die wollen wir haben
319 pFndShell = pShell;
320 break;
323 if( bFirst )
325 bFirst = FALSE;
326 pShell = SfxObjectShell::GetFirst( &aType, sal_False );
328 else
329 pShell = SfxObjectShell::GetNext( *pShell, &aType, sal_False );
331 sTmp.Erase();
335 // empty topics are not allowed - which document is it
336 if( !sTopic.Len() )
337 return FALSE;
339 if( !pFndShell )
341 // dann versuche die Datei zu laden:
342 INetURLObject aURL( sTopic );
343 INetProtocol eOld = aURL.GetProtocol();
344 aURL.SetURL( sTopic = lcl_DDE_RelToAbs( sTopic, sReferer ) );
345 if( INET_PROT_NOT_VALID != eOld ||
346 INET_PROT_HTTP != aURL.GetProtocol() )
348 SfxStringItem aName( SID_FILE_NAME, sTopic );
349 SfxBoolItem aMinimized(SID_MINIMIZED, TRUE);
350 SfxBoolItem aHidden(SID_HIDDEN, TRUE);
351 SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
352 SfxStringItem aReferer( SID_REFERER, sReferer );
353 SfxUInt16Item aUpdate( SID_UPDATEDOCMODE, nUpdateMode );
354 SfxBoolItem aReadOnly(SID_DOC_READONLY, TRUE);
356 // #i14200# (DDE-link crashes wordprocessor)
357 SfxAllItemSet aArgs( SFX_APP()->GetPool() );
358 aArgs.Put(aReferer);
359 aArgs.Put(aTarget);
360 aArgs.Put(aHidden);
361 aArgs.Put(aMinimized);
362 aArgs.Put(aName);
363 aArgs.Put(aUpdate);
364 aArgs.Put(aReadOnly);
365 pFndShell = SfxObjectShell::CreateAndLoadObject( aArgs );
369 BOOL bRet = FALSE;
370 if( pFndShell )
372 sfx2::SvLinkSource* pNewSrc = pFndShell->DdeCreateLinkSource( sItem );
373 if( pNewSrc )
375 bRet = TRUE;
377 ::com::sun::star::datatransfer::DataFlavor aFl;
378 SotExchange::GetFormatDataFlavor( pLink->GetContentType(), aFl );
380 pLink->SetObj( pNewSrc );
381 pNewSrc->AddDataAdvise( pLink, aFl.MimeType,
382 sfx2::LINKUPDATE_ONCALL == pLink->GetUpdateMode()
383 ? ADVISEMODE_ONLYONCE
384 : 0 );
387 return bRet;