xref: /aoo42x/main/sfx2/source/appl/fileobj.cxx (revision d119d52d)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sfx2.hxx"
26 
27 #include <vcl/wrkwin.hxx>
28 #include <vcl/msgbox.hxx>
29 #include <tools/urlobj.hxx>
30 #include <tools/stream.hxx>
31 #include <sot/formats.hxx>
32 #include <svtools/filter.hxx>
33 #include <sfx2/lnkbase.hxx>
34 #include <sfx2/app.hxx>
35 #include <sfx2/progress.hxx>
36 #include <sfx2/docfilt.hxx>
37 #include <sfx2/filedlghelper.hxx>
38 #include <sot/exchange.hxx>
39 #include <com/sun/star/uno/Any.hxx>
40 #include <com/sun/star/uno/Sequence.hxx>
41 #include <sfx2/docfac.hxx>
42 #include <com/sun/star/document/XTypeDetection.hpp>
43 #include <comphelper/mediadescriptor.hxx>
44 #include <comphelper/processfactory.hxx>
45 #include <sfx2/linkmgr.hxx>
46 #include <sfx2/opengrf.hxx>
47 #include "sfx2/sfxresid.hxx"
48 #include "fileobj.hxx"
49 #include "app.hrc"
50 
51 namespace css = ::com::sun::star;
52 
53 #define FILETYPE_TEXT		1
54 #define FILETYPE_GRF		2
55 #define FILETYPE_OBJECT		3
56 
57 struct Impl_DownLoadData
58 {
59 	Graphic aGrf;
60 	Timer aTimer;
61 
62 	Impl_DownLoadData( const Link& rLink )
63 	{
64 		aTimer.SetTimeout( 100 );
65 		aTimer.SetTimeoutHdl( rLink  );
66 		aGrf.SetDefaultType();
67 	}
68 	~Impl_DownLoadData()
69 	{
70 		aTimer.Stop();
71 	}
72 };
73 
74 // --------------------------------------------------------------------------
75 
76 
77 SvFileObject::SvFileObject() :
78 	pDownLoadData( NULL ), pOldParent( NULL ), nType( FILETYPE_TEXT )
79 {
80 	bLoadAgain = sal_True;
81 	bSynchron = bLoadError = bWaitForData = bDataReady = bNativFormat =
82 	bClearMedium = bStateChangeCalled = bInCallDownLoad = sal_False;
83 }
84 
85 
86 SvFileObject::~SvFileObject()
87 {
88 	if ( xMed.Is() )
89 	{
90 		xMed->SetDataAvailableLink( Link() );
91 		xMed->SetDoneLink( Link() );
92 		xMed.Clear();
93 	}
94 	delete pDownLoadData;
95 }
96 
97 
98 sal_Bool SvFileObject::GetData( ::com::sun::star::uno::Any & rData,
99 								const String & rMimeType,
100 								sal_Bool bGetSynchron )
101 {
102 	sal_uIntPtr nFmt = SotExchange::GetFormatStringId( rMimeType );
103 	switch( nType )
104 	{
105 	case FILETYPE_TEXT:
106 		if( FORMAT_FILE == nFmt )
107 		{
108 			// das Medium muss in der Applikation geoffnet werden, um die
109 			// relativen Datei Links aufzuloesen!!!! Wird ueber den
110 			// LinkManager und damit von dessen Storage erledigt.
111 			rData <<= rtl::OUString( sFileNm );
112 		}
113 		break;
114 
115 	case FILETYPE_GRF:
116 		if( !bLoadError )
117 		{
118 			SfxMediumRef xTmpMed;
119 
120 			if( FORMAT_GDIMETAFILE == nFmt || FORMAT_BITMAP == nFmt ||
121 				SOT_FORMATSTR_ID_SVXB == nFmt )
122 			{
123 				Graphic aGrf;
124 
125 				//JP 15.07.98: Bug 52959
126 				//		falls das Nativformat doch erwuenscht ist, muss am
127 				//		Ende das Flag zurueckgesetzt werden.
128 // wird einzig und allein im sw/ndgrf.cxx benutzt, wenn der Link vom
129 // GraphicNode entfernt wird.
130 				sal_Bool bOldNativFormat = bNativFormat;
131 //!!??				bNativFormat = 0 != (ASPECT_ICON & pSvData->GetAspect());
132 
133 				// falls gedruckt werden soll, warten wir bis die
134 				// Daten vorhanden sind
135 				if( bGetSynchron )
136 				{
137 					// testhalber mal ein LoadFile rufen um das nach-
138 					// laden ueberahaupt anzustossen
139 					if( !xMed.Is() )
140 						LoadFile_Impl();
141 
142 					if( !bInCallDownLoad )
143 					{
144 						xTmpMed = xMed;
145 						while( bWaitForData )
146 							Application::Reschedule();
147 
148 						xMed = xTmpMed;
149 						bClearMedium = sal_True;
150 					}
151 				}
152 
153 				if( pDownLoadData ||
154 					( !bWaitForData && ( xMed.Is() || 		// wurde als URL geladen
155 						( bSynchron && LoadFile_Impl() && xMed.Is() ) )) )
156 				{
157 					// falls
158 
159 					// falls es uebers Internet gesogen wurde, nicht
160 					// wieder versuchen
161 					if( !bGetSynchron )
162 						bLoadAgain = !xMed->IsRemote();
163 					bLoadError = !GetGraphic_Impl( aGrf, xMed->GetInStream() );
164 				}
165 				else if( !LoadFile_Impl() ||
166 						!GetGraphic_Impl( aGrf, xMed.Is() ? xMed->GetInStream() : 0 ))
167 				{
168 					if( !xMed.Is() )
169 						break;
170 					aGrf.SetDefaultType();
171 				}
172 
173 				if( SOT_FORMATSTR_ID_SVXB != nFmt )
174 					nFmt = (bLoadError || GRAPHIC_BITMAP == aGrf.GetType())
175 								? FORMAT_BITMAP
176 								: FORMAT_GDIMETAFILE;
177 
178 				SvMemoryStream aMemStm( 0, 65535 );
179 				switch ( nFmt )
180 				{
181 				case SOT_FORMATSTR_ID_SVXB:
182 					if( GRAPHIC_NONE != aGrf.GetType() )
183 					{
184 						aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
185 						aMemStm << aGrf;
186 					}
187 					break;
188 
189 				case  FORMAT_BITMAP:
190 					if( !aGrf.GetBitmap().IsEmpty())
191 						aMemStm << aGrf.GetBitmap();
192 					break;
193 
194 				default:
195 					if( aGrf.GetGDIMetaFile().GetActionCount() )
196 					{
197 						GDIMetaFile aMeta( aGrf.GetGDIMetaFile() );
198 						aMeta.Write( aMemStm );
199 					}
200 				}
201                 rData <<= css::uno::Sequence< sal_Int8 >( (sal_Int8*) aMemStm.GetData(),
202 										aMemStm.Seek( STREAM_SEEK_TO_END ) );
203 
204 				bNativFormat = bOldNativFormat;
205 
206 				// alles fertig?
207 				if( xMed.Is() && !bSynchron && bClearMedium )
208 				{
209 					xMed.Clear();
210 					bClearMedium = sal_False;
211 				}
212 			}
213 		}
214 		break;
215 	case FILETYPE_OBJECT:
216 		// TODO/LATER: possibility to insert a new object
217 		rData <<= rtl::OUString( sFileNm );
218 		break;
219 	}
220 	return sal_True/*0 != aTypeList.Count()*/;
221 }
222 
223 
224 
225 
226 sal_Bool SvFileObject::Connect( sfx2::SvBaseLink* pLink )
227 {
228 	if( !pLink || !pLink->GetLinkManager() )
229 		return sal_False;
230 
231 	// teste doch mal, ob nicht ein anderer Link mit der gleichen
232 	// Verbindung schon existiert
233 	pLink->GetLinkManager()->GetDisplayNames( pLink, 0, &sFileNm, 0, &sFilter );
234 
235 	if( OBJECT_CLIENT_GRF == pLink->GetObjType() )
236 	{
237         SfxObjectShellRef pShell = pLink->GetLinkManager()->GetPersist();
238         if( pShell.Is() )
239 		{
240 			if( pShell->IsAbortingImport() )
241 				return sal_False;
242 
243 			if( pShell->GetMedium() )
244 				sReferer = pShell->GetMedium()->GetName();
245         }
246 	}
247 
248 	switch( pLink->GetObjType() )
249 	{
250 	case OBJECT_CLIENT_GRF:
251 		nType = FILETYPE_GRF;
252 		bSynchron = pLink->IsSynchron();
253 		break;
254 
255 	case OBJECT_CLIENT_FILE:
256 		nType = FILETYPE_TEXT;
257 		break;
258 
259 	case OBJECT_CLIENT_OLE:
260 		nType = FILETYPE_OBJECT;
261 		// TODO/LATER: introduce own type to be used for exchanging
262 		break;
263 
264 	default:
265 		return sal_False;
266 	}
267 
268 	SetUpdateTimeout( 0 );
269 
270 	// und jetzt bei diesem oder gefundenem Pseudo-Object anmelden
271 	AddDataAdvise( pLink, SotExchange::GetFormatMimeType( pLink->GetContentType()), 0 );
272 	return sal_True;
273 }
274 
275 
276 sal_Bool SvFileObject::LoadFile_Impl()
277 {
278 	// wir sind noch im Laden!!
279 	if( bWaitForData || !bLoadAgain || xMed.Is() || pDownLoadData )
280 		return sal_False;
281 
282 	// z.Z. nur auf die aktuelle DocShell
283 	xMed = new SfxMedium( sFileNm, STREAM_STD_READ, sal_True );
284     SvLinkSource::StreamToLoadFrom aStreamToLoadFrom =
285         getStreamToLoadFrom();
286     xMed->setStreamToLoadFrom(
287         aStreamToLoadFrom.m_xInputStreamToLoadFrom,
288         aStreamToLoadFrom.m_bIsReadOnly);
289 	// setStreamToLoadFrom(0,0);
290 	if( sReferer.Len() )
291 		xMed->SetReferer( sReferer );
292 
293 	if( !bSynchron )
294 	{
295 		bLoadAgain = bDataReady = bInNewData = sal_False;
296 		bWaitForData = sal_True;
297 
298 		SfxMediumRef xTmpMed = xMed;
299 		xMed->SetDataAvailableLink( STATIC_LINK( this, SvFileObject, LoadGrfNewData_Impl ) );
300 		bInCallDownLoad = sal_True;
301 		xMed->DownLoad( STATIC_LINK( this, SvFileObject, LoadGrfReady_Impl ) );
302 		bInCallDownLoad = sal_False;
303 
304 		bClearMedium = !xMed.Is();
305 		if( bClearMedium )
306 			xMed = xTmpMed;		// falls gleich im DownLoad schon schluss ist
307 		return bDataReady;
308 	}
309 
310 	bWaitForData = sal_True;
311 	bDataReady = bInNewData = sal_False;
312 	xMed->DownLoad();
313 	bLoadAgain = !xMed->IsRemote();
314 	bWaitForData = sal_False;
315 
316 	// Grafik ist fertig, also DataChanged von der Statusaederung schicken:
317 	SendStateChg_Impl( xMed->GetInStream() && xMed->GetInStream()->GetError()
318 						? sfx2::LinkManager::STATE_LOAD_ERROR : sfx2::LinkManager::STATE_LOAD_OK );
319 	return sal_True;
320 }
321 
322 
323 sal_Bool SvFileObject::GetGraphic_Impl( Graphic& rGrf, SvStream* pStream )
324 {
325 	GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
326 
327 	const sal_uInt16 nFilter = sFilter.Len() && pGF->GetImportFormatCount()
328 							? pGF->GetImportFormatNumber( sFilter )
329 							: GRFILTER_FORMAT_DONTKNOW;
330 
331 	String aEmptyStr;
332 	int nRes;
333 
334 	// vermeiden, dass ein native Link angelegt wird
335 	if( ( !pStream || !pDownLoadData ) && !rGrf.IsLink() &&
336 		!rGrf.GetContext() && !bNativFormat )
337 		rGrf.SetLink( GfxLink() );
338 
339 	if( !pStream )
340 		nRes = xMed.Is() ? GRFILTER_OPENERROR
341 						 : pGF->ImportGraphic( rGrf, INetURLObject(sFileNm),
342 							nFilter );
343 	else if( !pDownLoadData )
344 	{
345 		pStream->Seek( STREAM_SEEK_TO_BEGIN );
346 		nRes = pGF->ImportGraphic( rGrf, aEmptyStr, *pStream, nFilter );
347 	}
348 	else
349 	{
350 		nRes = pGF->ImportGraphic( pDownLoadData->aGrf, aEmptyStr,
351 									*pStream, nFilter );
352 
353 		if( pDownLoadData )
354 		{
355 			rGrf = pDownLoadData->aGrf;
356 			if( GRAPHIC_NONE == rGrf.GetType() )
357 				rGrf.SetDefaultType();
358 
359 
360 			if( !pDownLoadData->aGrf.GetContext() )
361 			{
362 				xMed->SetDataAvailableLink( Link() );
363 //				xMed->SetDoneLink( Link() );
364 				delete pDownLoadData, pDownLoadData = 0;
365 				bDataReady = sal_True;
366 				bWaitForData = sal_False;
367 			}
368 			else if( sal_False )
369 			{
370 				// Timer aufsetzen, um zurueck zukehren
371 				pDownLoadData->aTimer.Start();
372 			}
373 		}
374 	}
375 
376 	if( pStream && ERRCODE_IO_PENDING == pStream->GetError() )
377 		pStream->ResetError();
378 
379 #ifdef DBG_UTIL
380 	if( nRes )
381 	{
382 		if( xMed.Is() && !pStream )
383 		{
384 			DBG_WARNING3( "GrafikFehler [%d] - [%s] URL[%s]",
385 							nRes,
386 							xMed->GetPhysicalName().GetBuffer(),
387 							sFileNm.GetBuffer() );
388 		}
389 		else
390 		{
391 			DBG_WARNING2( "GrafikFehler [%d] - [%s]",
392 							nRes, sFileNm.GetBuffer() );
393 		}
394 	}
395 #endif
396 
397 	return GRFILTER_OK == nRes;
398 }
399 
400 /** detect the filter of the given file
401 
402     @param _rURL
403         specifies the URL of the file which filter is to detected.<br/>
404         If the URL doesn't denote a valid (existent and accessible) file, the
405         request is silently dropped.
406 */
407 String impl_getFilter( const String& _rURL )
408 {
409     String sFilter;
410     if ( _rURL.Len() == 0 )
411         return sFilter;
412 
413     try
414     {
415         css::uno::Reference< ::com::sun::star::document::XTypeDetection > xTypeDetection(
416             ::comphelper::getProcessServiceFactory()->createInstance(
417                 ::rtl::OUString::createFromAscii("com.sun.star.document.TypeDetection") ),
418                 css::uno::UNO_QUERY );
419         if ( xTypeDetection.is() )
420         {
421             ::comphelper::MediaDescriptor aDescr;
422             aDescr[ ::comphelper::MediaDescriptor::PROP_URL() ] <<= ::rtl::OUString( _rURL );
423             css::uno::Sequence< css::beans::PropertyValue > aDescrList =
424                 aDescr.getAsConstPropertyValueList();
425             ::rtl::OUString sType = xTypeDetection->queryTypeByDescriptor( aDescrList, sal_True );
426             if ( sType.getLength() )
427             {
428                 css::uno::Reference< css::container::XNameAccess > xTypeCont( xTypeDetection,
429                                                                               css::uno::UNO_QUERY );
430                 if ( xTypeCont.is() )
431                 {
432                     ::comphelper::SequenceAsHashMap lTypeProps( xTypeCont->getByName( sType ) );
433                     sFilter = lTypeProps.getUnpackedValueOrDefault(
434                         ::rtl::OUString::createFromAscii("PreferredFilter"), ::rtl::OUString() );
435                 }
436             }
437         }
438     }
439     catch( const css::uno::Exception& )
440     {
441     }
442 
443     return sFilter;
444 }
445 
446 void SvFileObject::Edit( Window* pParent, sfx2::SvBaseLink* pLink, const Link& rEndEditHdl )
447 {
448     aEndEditLink = rEndEditHdl;
449     String sFile, sRange, sTmpFilter;
450     if( pLink && pLink->GetLinkManager() )
451     {
452         pLink->GetLinkManager()->GetDisplayNames( pLink, 0, &sFile, &sRange, &sTmpFilter );
453 
454         switch( pLink->GetObjType() )
455         {
456             case OBJECT_CLIENT_GRF:
457             {
458                 nType = FILETYPE_GRF;       // falls noch nicht gesetzt
459 
460                 SvxOpenGraphicDialog aDlg(SfxResId(RID_SVXSTR_EDITGRFLINK));
461                 aDlg.EnableLink(sal_False);
462                 aDlg.SetPath( sFile, sal_True );
463                 aDlg.SetCurrentFilter( sTmpFilter );
464 
465                 if( !aDlg.Execute() )
466                 {
467                     sFile = aDlg.GetPath();
468                     sFile += ::sfx2::cTokenSeperator;
469                     sFile += ::sfx2::cTokenSeperator;
470                     sFile += aDlg.GetCurrentFilter();
471 
472                     if ( aEndEditLink.IsSet() )
473                         aEndEditLink.Call( &sFile );
474                 }
475                 else
476                     sFile.Erase();
477             }
478             break;
479 
480             case OBJECT_CLIENT_OLE:
481             {
482                 nType = FILETYPE_OBJECT; // if not set already
483                 pOldParent = Application::GetDefDialogParent();
484                 Application::SetDefDialogParent( pParent );
485 
486                 ::sfx2::FileDialogHelper* pFileDlg =
487                     pLink->GetFileDialog( (SFXWB_INSERT | WB_3DLOOK), String() );
488                 pFileDlg->StartExecuteModal( LINK( this, SvFileObject, DialogClosedHdl ) );
489             }
490             break;
491 
492             case OBJECT_CLIENT_FILE:
493             {
494                 nType = FILETYPE_TEXT; // if not set already
495                 pOldParent = Application::GetDefDialogParent();
496                 Application::SetDefDialogParent( pParent );
497 
498                 String sFactory;
499                 SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist();
500                 if ( pShell )
501                     sFactory = pShell->GetFactory().GetFactoryName();
502 
503                 ::sfx2::FileDialogHelper* pFileDlg =
504                     pLink->GetFileDialog( (SFXWB_INSERT | WB_3DLOOK), sFactory );
505                 pFileDlg->StartExecuteModal( LINK( this, SvFileObject, DialogClosedHdl ) );
506             }
507             break;
508 
509             default:
510                 sFile.Erase();
511         }
512 	}
513 }
514 
515 IMPL_STATIC_LINK( SvFileObject, LoadGrfReady_Impl, void*, EMPTYARG )
516 {
517 	// wenn wir von hier kommen, kann es kein Fehler mehr sein
518 	pThis->bLoadError = sal_False;
519 	pThis->bWaitForData = sal_False;
520 	pThis->bInCallDownLoad = sal_False;
521 
522 	if( !pThis->bInNewData && !pThis->bDataReady )
523 	{
524 			// Grafik ist fertig, also DataChanged von der Status-
525 			// aederung schicken:
526 		pThis->bDataReady = sal_True;
527 		pThis->SendStateChg_Impl( sfx2::LinkManager::STATE_LOAD_OK );
528 
529 			// und dann nochmal die Daten senden
530 		pThis->NotifyDataChanged();
531 	}
532 
533 	if( pThis->bDataReady )
534 	{
535 		pThis->bLoadAgain = sal_True;
536 		if( pThis->xMed.Is() )
537 		{
538 			pThis->xMed->SetDataAvailableLink( Link() );
539 			pThis->xMed->SetDoneLink( Link() );
540 
541 			Application::PostUserEvent(
542 						STATIC_LINK( pThis, SvFileObject, DelMedium_Impl ),
543 						new SfxMediumRef( pThis->xMed ));
544 			pThis->xMed.Clear();
545 		}
546 		if( pThis->pDownLoadData )
547 			delete pThis->pDownLoadData, pThis->pDownLoadData = 0;
548 	}
549 
550 	return 0;
551 }
552 
553 IMPL_STATIC_LINK( SvFileObject, DelMedium_Impl, SfxMediumRef*, pDelMed )
554 {
555 	(void)pThis;
556 	delete pDelMed;
557 	return 0;
558 }
559 
560 IMPL_STATIC_LINK( SvFileObject, LoadGrfNewData_Impl, void*, EMPTYARG )
561 {
562 	// wenn wir von hier kommen, kann es kein Fehler mehr sein
563 	if( pThis->bInNewData )
564 		return 0;
565 
566 	pThis->bInNewData = sal_True;
567 	pThis->bLoadError = sal_False;
568 
569 	if( !pThis->pDownLoadData )
570 	{
571 		pThis->pDownLoadData = new Impl_DownLoadData(
572 						STATIC_LINK( pThis, SvFileObject, LoadGrfNewData_Impl ) );
573 
574 		// Null-Link setzen, damit keine temporaeren Grafiken
575 		// rausgeswapt werden; der Filter prueft, ob schon
576 		// ein Link gesetzt ist => falls dies zutrifft, wird
577 		// _kein_ neuer Link gesetzt; der Link muss hier gesetzt werden,
578 		// (bevor das erste Mal gefiltert wird), um zu verhindern,
579 		// dass der Kontext zurueckgesetzt wird (aynchrones Laden)
580 		if( !pThis->bNativFormat )
581 		{
582 			static GfxLink aDummyLink;
583 			pThis->pDownLoadData->aGrf.SetLink( aDummyLink );
584 		}
585 	}
586 
587 	pThis->NotifyDataChanged();
588 
589 	SvStream* pStrm = pThis->xMed.Is() ? pThis->xMed->GetInStream() : 0;
590 	if( pStrm && pStrm->GetError() )
591 	{
592 		if( ERRCODE_IO_PENDING == pStrm->GetError() )
593 			pStrm->ResetError();
594 
595 		// im DataChanged ein DataReady?
596 		else if( pThis->bWaitForData && pThis->pDownLoadData )
597 		{
598 			pThis->bLoadError = sal_True;
599 		}
600 	}
601 
602 	if( pThis->bDataReady )
603 	{
604 		// Grafik ist fertig, also DataChanged von der Status-
605 		// aederung schicken:
606 		pThis->SendStateChg_Impl( pStrm->GetError() ? sfx2::LinkManager::STATE_LOAD_ERROR : sfx2::LinkManager::STATE_LOAD_OK );
607 	}
608 
609 	pThis->bInNewData = sal_False;
610 	return 0;
611 }
612 
613 IMPL_LINK( SvFileObject, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg )
614 {
615     String sFile;
616     Application::SetDefDialogParent( pOldParent );
617 
618     if ( FILETYPE_TEXT == nType || FILETYPE_OBJECT == nType )
619     {
620         if ( _pFileDlg && _pFileDlg->GetError() == ERRCODE_NONE )
621         {
622             String sURL( _pFileDlg->GetPath() );
623             sFile = sURL;
624             sFile += ::sfx2::cTokenSeperator;
625             sFile += ::sfx2::cTokenSeperator;
626             sFile += impl_getFilter( sURL );
627         }
628     }
629     else
630     {
631         DBG_ERRORFILE( "SvFileObject::DialogClosedHdl(): wrong file type" );
632     }
633 
634     if ( aEndEditLink.IsSet() )
635         aEndEditLink.Call( &sFile );
636     return 0;
637 }
638 
639 /*	[Beschreibung]
640 
641 	Die Methode stellt fest, ob aus einem DDE-Object die Daten gelesen
642 	werden kann.
643 	Zurueckgegeben wird:
644 		ERRCODE_NONE 			wenn sie komplett gelesen wurde
645 		ERRCODE_SO_PENDING		wenn sie noch nicht komplett gelesen wurde
646 		ERRCODE_SO_FALSE		sonst
647 */
648 sal_Bool SvFileObject::IsPending() const
649 {
650 	return FILETYPE_GRF == nType && !bLoadError &&
651 			( pDownLoadData || bWaitForData );
652 }
653 sal_Bool SvFileObject::IsDataComplete() const
654 {
655 	sal_Bool bRet = sal_False;
656 	if( FILETYPE_GRF != nType )
657 		bRet = sal_True;
658 	else if( !bLoadError && ( !bWaitForData && !pDownLoadData ))
659 	{
660 		SvFileObject* pThis = (SvFileObject*)this;
661 		if( bDataReady ||
662 			( bSynchron && pThis->LoadFile_Impl() && xMed.Is() ) )
663 			bRet = sal_True;
664 		else
665 		{
666 			INetURLObject aUrl( sFileNm );
667 			if( aUrl.HasError() ||
668 				INET_PROT_NOT_VALID == aUrl.GetProtocol() )
669 				bRet = sal_True;
670 		}
671 	}
672 	return bRet;
673 }
674 
675 
676 
677 void SvFileObject::CancelTransfers()
678 {
679 	// und aus dem Cache austragen, wenn man mitten im Laden ist
680 	if( !bDataReady )
681 	{
682 		// nicht noch mal aufsetzen
683 		bLoadAgain = sal_False;
684 		bDataReady = bLoadError = bWaitForData = sal_True;
685 		SendStateChg_Impl( sfx2::LinkManager::STATE_LOAD_ABORT );
686 	}
687 }
688 
689 
690 void SvFileObject::SendStateChg_Impl( sfx2::LinkManager::LinkState nState )
691 {
692 	if( !bStateChangeCalled && HasDataLinks() )
693 	{
694         css::uno::Any aAny;
695 		aAny <<= rtl::OUString::valueOf( (sal_Int32)nState );
696 		DataChanged( SotExchange::GetFormatName(
697 						sfx2::LinkManager::RegisterStatusInfoId()), aAny );
698 		bStateChangeCalled = sal_True;
699 	}
700 }
701 
702 
703