diff options
author | Mathias Bauer <mba@openoffice.org> | 2010-01-13 22:25:07 +0100 |
---|---|---|
committer | Mathias Bauer <mba@openoffice.org> | 2010-01-13 22:25:07 +0100 |
commit | dd2fff67ae5c59de36a36480b9f6968122077706 (patch) | |
tree | adceabf2ef0de90733956542606d8dc5de579bfa /sfx2/source | |
parent | 7572bc9673bafdd5cdeb5a3df067529897f3364d (diff) |
#i107450#: move more code out of svx
Diffstat (limited to 'sfx2/source')
-rw-r--r-- | sfx2/source/appl/app.hrc | 12 | ||||
-rw-r--r-- | sfx2/source/appl/app.src | 39 | ||||
-rw-r--r-- | sfx2/source/appl/fileobj.cxx | 719 | ||||
-rw-r--r-- | sfx2/source/appl/fileobj.hxx | 99 | ||||
-rw-r--r-- | sfx2/source/appl/linkmgr2.cxx | 400 | ||||
-rw-r--r-- | sfx2/source/appl/lnkbase2.cxx | 15 | ||||
-rw-r--r-- | sfx2/source/appl/makefile.mk | 4 | ||||
-rw-r--r-- | sfx2/source/appl/opengrf.cxx | 298 |
8 files changed, 1533 insertions, 53 deletions
diff --git a/sfx2/source/appl/app.hrc b/sfx2/source/appl/app.hrc index c08f46effc81..70dca1cf1d6b 100644 --- a/sfx2/source/appl/app.hrc +++ b/sfx2/source/appl/app.hrc @@ -258,6 +258,18 @@ #define STR_DDE_ERROR (RID_SFX_APP_START + 193) #define RID_SECURITY_WARNING_NO_HYPERLINKS (RID_SFX_APP_START + 194) +#define RID_SVXSTR_FILELINK (RID_SFX_APP_START + 195) +#define RID_SVXSTR_GRAFIKLINK (RID_SFX_APP_START + 196) +#define RID_SVXSTR_EDITGRFLINK (RID_SFX_APP_START + 197) + +// strings for error messsages of OpenGraphics dialog +#define RID_SVXSTR_GRFILTER_OPENERROR (RID_SFX_APP_START + 198) +#define RID_SVXSTR_GRFILTER_IOERROR (RID_SFX_APP_START + 199) +#define RID_SVXSTR_GRFILTER_FORMATERROR (RID_SFX_APP_START + 200) +#define RID_SVXSTR_GRFILTER_VERSIONERROR (RID_SFX_APP_START + 201) +#define RID_SVXSTR_GRFILTER_FILTERERROR (RID_SFX_APP_START + 202) +#define RID_SVXSTR_GRFILTER_TOOBIG (RID_SFX_APP_START + 203) + #define MD_DDE_LINKEDIT (RID_SFX_APP_START + 1) #endif // #ifndef _SFX_APP_HRC diff --git a/sfx2/source/appl/app.src b/sfx2/source/appl/app.src index 463788d2d6d0..0530b5aeb9db 100644 --- a/sfx2/source/appl/app.src +++ b/sfx2/source/appl/app.src @@ -1061,3 +1061,42 @@ Image IMG_MISSING_4 { ImageBitmap = Bitmap { File = "sn064.bmp" ; }; }; + +String RID_SVXSTR_FILELINK +{ + Text [ en-US ] = "Document" ; +}; +String RID_SVXSTR_GRAFIKLINK +{ + Text [ en-US ] = "Graphic" ; +}; +String RID_SVXSTR_EDITGRFLINK +{ + Text [ en-US ] = "Link graphics" ; +}; + +String RID_SVXSTR_GRFILTER_OPENERROR +{ + Text [ en-US ] = "Graphics file cannot be opened" ; +}; +String RID_SVXSTR_GRFILTER_IOERROR +{ + Text [ en-US ] = "Graphics file cannot be read" ; +}; +String RID_SVXSTR_GRFILTER_FORMATERROR +{ + Text [ en-US ] = "Unknown graphics format" ; +}; +String RID_SVXSTR_GRFILTER_VERSIONERROR +{ + Text [ en-US ] = "This version of the graphics file is not supported" ; +}; +String RID_SVXSTR_GRFILTER_FILTERERROR +{ + Text [ en-US ] = "Graphics filter not found" ; +}; +String RID_SVXSTR_GRFILTER_TOOBIG +{ + Text [ en-US ] = "Not enough memory to insert graphic" ; +}; + diff --git a/sfx2/source/appl/fileobj.cxx b/sfx2/source/appl/fileobj.cxx new file mode 100644 index 000000000000..a414ccc8b07c --- /dev/null +++ b/sfx2/source/appl/fileobj.cxx @@ -0,0 +1,719 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: fileobj.cxx,v $ + * $Revision: 1.24 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include <vcl/wrkwin.hxx> +#include <vcl/msgbox.hxx> +#include <tools/urlobj.hxx> +#include <tools/stream.hxx> +#include <sot/formats.hxx> +#include <svtools/filter.hxx> +#include <sfx2/lnkbase.hxx> +#include <sfx2/app.hxx> +#include <sfx2/progress.hxx> +#include <sfx2/docfilt.hxx> +#include <sfx2/filedlghelper.hxx> +#include <sot/exchange.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <sfx2/docfac.hxx> +#include <com/sun/star/document/XTypeDetection.hpp> +#include <comphelper/mediadescriptor.hxx> +#include <comphelper/processfactory.hxx> +#include <sfx2/linkmgr.hxx> +#include <sfx2/opengrf.hxx> +#include "sfxresid.hxx" +#include "fileobj.hxx" +#include "app.hrc" + +namespace css = ::com::sun::star; + +#define FILETYPE_TEXT 1 +#define FILETYPE_GRF 2 +#define FILETYPE_OBJECT 3 + +struct Impl_DownLoadData +{ + Graphic aGrf; + Timer aTimer; + + Impl_DownLoadData( const Link& rLink ) + { + aTimer.SetTimeout( 100 ); + aTimer.SetTimeoutHdl( rLink ); + aGrf.SetDefaultType(); + } + ~Impl_DownLoadData() + { + aTimer.Stop(); + } +}; + +// -------------------------------------------------------------------------- + + +SvFileObject::SvFileObject() : + pDownLoadData( NULL ), pOldParent( NULL ), nType( FILETYPE_TEXT ) +{ + bLoadAgain = TRUE; + bSynchron = bLoadError = bWaitForData = bDataReady = bNativFormat = + bClearMedium = bStateChangeCalled = bInCallDownLoad = FALSE; +} + + +SvFileObject::~SvFileObject() +{ + if ( xMed.Is() ) + { + xMed->SetDataAvailableLink( Link() ); + xMed->SetDoneLink( Link() ); + xMed.Clear(); + } + delete pDownLoadData; +} + + +BOOL SvFileObject::GetData( ::com::sun::star::uno::Any & rData, + const String & rMimeType, + BOOL bGetSynchron ) +{ + ULONG nFmt = SotExchange::GetFormatStringId( rMimeType ); + switch( nType ) + { + case FILETYPE_TEXT: + if( FORMAT_FILE == nFmt ) + { + // das Medium muss in der Applikation geoffnet werden, um die + // relativen Datei Links aufzuloesen!!!! Wird ueber den + // LinkManager und damit von dessen Storage erledigt. + rData <<= rtl::OUString( sFileNm ); + } + break; + + case FILETYPE_GRF: + if( !bLoadError ) + { + SfxMediumRef xTmpMed; + + if( FORMAT_GDIMETAFILE == nFmt || FORMAT_BITMAP == nFmt || + SOT_FORMATSTR_ID_SVXB == nFmt ) + { + Graphic aGrf; + + //JP 15.07.98: Bug 52959 + // falls das Nativformat doch erwuenscht ist, muss am + // Ende das Flag zurueckgesetzt werden. +// wird einzig und allein im sw/ndgrf.cxx benutzt, wenn der Link vom +// GraphicNode entfernt wird. + BOOL bOldNativFormat = bNativFormat; +//!!?? bNativFormat = 0 != (ASPECT_ICON & pSvData->GetAspect()); + + // falls gedruckt werden soll, warten wir bis die + // Daten vorhanden sind + if( bGetSynchron ) + { + // testhalber mal ein LoadFile rufen um das nach- + // laden ueberahaupt anzustossen + if( !xMed.Is() ) + LoadFile_Impl(); + + if( !bInCallDownLoad ) + { + xTmpMed = xMed; + while( bWaitForData ) + Application::Reschedule(); + + xMed = xTmpMed; + bClearMedium = TRUE; + } + } + + if( pDownLoadData || + ( !bWaitForData && ( xMed.Is() || // wurde als URL geladen + ( bSynchron && LoadFile_Impl() && xMed.Is() ) )) ) + { + // falls + + // falls es uebers Internet gesogen wurde, nicht + // wieder versuchen + if( !bGetSynchron ) + bLoadAgain = !xMed->IsRemote(); + bLoadError = !GetGraphic_Impl( aGrf, xMed->GetInStream() ); + } + else if( !LoadFile_Impl() || + !GetGraphic_Impl( aGrf, xMed.Is() ? xMed->GetInStream() : 0 )) + { + if( !xMed.Is() ) + break; + aGrf.SetDefaultType(); + } + + if( SOT_FORMATSTR_ID_SVXB != nFmt ) + nFmt = (bLoadError || GRAPHIC_BITMAP == aGrf.GetType()) + ? FORMAT_BITMAP + : FORMAT_GDIMETAFILE; + + SvMemoryStream aMemStm( 0, 65535 ); + switch ( nFmt ) + { + case SOT_FORMATSTR_ID_SVXB: + if( GRAPHIC_NONE != aGrf.GetType() ) + { + aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 ); + aMemStm << aGrf; + } + break; + + case FORMAT_BITMAP: + if( !aGrf.GetBitmap().IsEmpty()) + aMemStm << aGrf.GetBitmap(); + break; + + default: + if( aGrf.GetGDIMetaFile().GetActionCount() ) + { + GDIMetaFile aMeta( aGrf.GetGDIMetaFile() ); + aMeta.Write( aMemStm ); + } + } + rData <<= css::uno::Sequence< sal_Int8 >( (sal_Int8*) aMemStm.GetData(), + aMemStm.Seek( STREAM_SEEK_TO_END ) ); + + bNativFormat = bOldNativFormat; + + // alles fertig? + if( xMed.Is() && !bSynchron && bClearMedium ) + { + xMed.Clear(); + bClearMedium = FALSE; + } + } + } + break; + case FILETYPE_OBJECT: + // TODO/LATER: possibility to insert a new object + rData <<= rtl::OUString( sFileNm ); + break; + } + return sal_True/*0 != aTypeList.Count()*/; +} + + + + +BOOL SvFileObject::Connect( sfx2::SvBaseLink* pLink ) +{ + if( !pLink || !pLink->GetLinkManager() ) + return FALSE; + + // teste doch mal, ob nicht ein anderer Link mit der gleichen + // Verbindung schon existiert + pLink->GetLinkManager()->GetDisplayNames( pLink, 0, &sFileNm, 0, &sFilter ); + + if( OBJECT_CLIENT_GRF == pLink->GetObjType() ) + { + SfxObjectShellRef pShell = pLink->GetLinkManager()->GetPersist(); + if( pShell.Is() ) + { + if( pShell->IsAbortingImport() ) + return FALSE; + + if( pShell->GetMedium() ) + sReferer = pShell->GetMedium()->GetName(); + } + } + + switch( pLink->GetObjType() ) + { + case OBJECT_CLIENT_GRF: + nType = FILETYPE_GRF; + bSynchron = pLink->IsSynchron(); + break; + + case OBJECT_CLIENT_FILE: + nType = FILETYPE_TEXT; + break; + + case OBJECT_CLIENT_OLE: + nType = FILETYPE_OBJECT; + // TODO/LATER: introduce own type to be used for exchanging + break; + + default: + return FALSE; + } + + SetUpdateTimeout( 0 ); + + // und jetzt bei diesem oder gefundenem Pseudo-Object anmelden + AddDataAdvise( pLink, SotExchange::GetFormatMimeType( pLink->GetContentType()), 0 ); + return TRUE; +} + + +BOOL SvFileObject::LoadFile_Impl() +{ + // wir sind noch im Laden!! + if( bWaitForData || !bLoadAgain || xMed.Is() || pDownLoadData ) + return FALSE; + + // z.Z. nur auf die aktuelle DocShell + xMed = new SfxMedium( sFileNm, STREAM_STD_READ, TRUE ); + SvLinkSource::StreamToLoadFrom aStreamToLoadFrom = + getStreamToLoadFrom(); + xMed->setStreamToLoadFrom( + aStreamToLoadFrom.m_xInputStreamToLoadFrom, + aStreamToLoadFrom.m_bIsReadOnly); + // setStreamToLoadFrom(0,0); + // Keinen Eintrag im Roter Button Menu + xMed->SetDontCreateCancellable(); + if( sReferer.Len() ) + xMed->SetReferer( sReferer ); + + if( !bSynchron ) + { + bLoadAgain = bDataReady = bInNewData = FALSE; + bWaitForData = TRUE; + + SfxMediumRef xTmpMed = xMed; + xMed->SetDataAvailableLink( STATIC_LINK( this, SvFileObject, LoadGrfNewData_Impl ) ); + bInCallDownLoad = TRUE; + xMed->DownLoad( STATIC_LINK( this, SvFileObject, LoadGrfReady_Impl ) ); + bInCallDownLoad = FALSE; + + bClearMedium = !xMed.Is(); + if( bClearMedium ) + xMed = xTmpMed; // falls gleich im DownLoad schon schluss ist + return bDataReady; + } + + bWaitForData = TRUE; + bDataReady = bInNewData = FALSE; + xMed->DownLoad(); + bLoadAgain = !xMed->IsRemote(); + bWaitForData = FALSE; + + // Grafik ist fertig, also DataChanged von der Statusaederung schicken: + SendStateChg_Impl( xMed->GetInStream() && xMed->GetInStream()->GetError() + ? sfx2::LinkManager::STATE_LOAD_ERROR : sfx2::LinkManager::STATE_LOAD_OK ); + return TRUE; +} + + +BOOL SvFileObject::GetGraphic_Impl( Graphic& rGrf, SvStream* pStream ) +{ + GraphicFilter* pGF = GraphicFilter::GetGraphicFilter(); + + const USHORT nFilter = sFilter.Len() && pGF->GetImportFormatCount() + ? pGF->GetImportFormatNumber( sFilter ) + : GRFILTER_FORMAT_DONTKNOW; + + String aEmptyStr; + int nRes; + + // vermeiden, dass ein native Link angelegt wird + if( ( !pStream || !pDownLoadData ) && !rGrf.IsLink() && + !rGrf.GetContext() && !bNativFormat ) + rGrf.SetLink( GfxLink() ); + + if( !pStream ) + nRes = xMed.Is() ? GRFILTER_OPENERROR + : pGF->ImportGraphic( rGrf, INetURLObject(sFileNm), + nFilter ); + else if( !pDownLoadData ) + { + pStream->Seek( STREAM_SEEK_TO_BEGIN ); + nRes = pGF->ImportGraphic( rGrf, aEmptyStr, *pStream, nFilter ); + } + else + { + nRes = pGF->ImportGraphic( pDownLoadData->aGrf, aEmptyStr, + *pStream, nFilter ); + + if( pDownLoadData ) + { + rGrf = pDownLoadData->aGrf; + if( GRAPHIC_NONE == rGrf.GetType() ) + rGrf.SetDefaultType(); + + + if( !pDownLoadData->aGrf.GetContext() ) + { + xMed->SetDataAvailableLink( Link() ); +// xMed->SetDoneLink( Link() ); + delete pDownLoadData, pDownLoadData = 0; + bDataReady = TRUE; + bWaitForData = FALSE; + } + else if( FALSE ) + { + // Timer aufsetzen, um zurueck zukehren + pDownLoadData->aTimer.Start(); + } + } + } + + if( pStream && ERRCODE_IO_PENDING == pStream->GetError() ) + pStream->ResetError(); + +#ifdef DBG_UTIL + if( nRes ) + { + if( xMed.Is() && !pStream ) + { + DBG_WARNING3( "GrafikFehler [%d] - [%s] URL[%s]", + nRes, + xMed->GetPhysicalName().GetBuffer(), + sFileNm.GetBuffer() ); + } + else + { + DBG_WARNING2( "GrafikFehler [%d] - [%s]", + nRes, sFileNm.GetBuffer() ); + } + } +#endif + + return GRFILTER_OK == nRes; +} + +/** detect the filter of the given file + + @param _rURL + specifies the URL of the file which filter is to detected.<br/> + If the URL doesn't denote a valid (existent and accessible) file, the + request is silently dropped. +*/ +String impl_getFilter( const String& _rURL ) +{ + String sFilter; + if ( _rURL.Len() == 0 ) + return sFilter; + + try + { + css::uno::Reference< ::com::sun::star::document::XTypeDetection > xTypeDetection( + ::comphelper::getProcessServiceFactory()->createInstance( + ::rtl::OUString::createFromAscii("com.sun.star.document.TypeDetection") ), + css::uno::UNO_QUERY ); + if ( xTypeDetection.is() ) + { + ::comphelper::MediaDescriptor aDescr; + aDescr[ ::comphelper::MediaDescriptor::PROP_URL() ] <<= ::rtl::OUString( _rURL ); + css::uno::Sequence< css::beans::PropertyValue > aDescrList = + aDescr.getAsConstPropertyValueList(); + ::rtl::OUString sType = xTypeDetection->queryTypeByDescriptor( aDescrList, sal_True ); + if ( sType.getLength() ) + { + css::uno::Reference< css::container::XNameAccess > xTypeCont( xTypeDetection, + css::uno::UNO_QUERY ); + if ( xTypeCont.is() ) + { + ::comphelper::SequenceAsHashMap lTypeProps( xTypeCont->getByName( sType ) ); + sFilter = lTypeProps.getUnpackedValueOrDefault( + ::rtl::OUString::createFromAscii("PreferredFilter"), ::rtl::OUString() ); + } + } + } + } + catch( const css::uno::Exception& ) + { + } + + return sFilter; +} + +void SvFileObject::Edit( Window* pParent, sfx2::SvBaseLink* pLink, const Link& rEndEditHdl ) +{ + aEndEditLink = rEndEditHdl; + String sFile, sRange, sTmpFilter; + if( pLink && pLink->GetLinkManager() ) + { + pLink->GetLinkManager()->GetDisplayNames( pLink, 0, &sFile, &sRange, &sTmpFilter ); + + switch( pLink->GetObjType() ) + { + case OBJECT_CLIENT_GRF: + { + nType = FILETYPE_GRF; // falls noch nicht gesetzt + + SvxOpenGraphicDialog aDlg(SfxResId(RID_SVXSTR_EDITGRFLINK)); + aDlg.EnableLink(sal_False); + aDlg.SetPath( sFile, sal_True ); + aDlg.SetCurrentFilter( sTmpFilter ); + + if( !aDlg.Execute() ) + { + sFile = aDlg.GetPath(); + sFile += ::sfx2::cTokenSeperator; + sFile += ::sfx2::cTokenSeperator; + sFile += aDlg.GetCurrentFilter(); + + if ( aEndEditLink.IsSet() ) + aEndEditLink.Call( &sFile ); + } + else + sFile.Erase(); + } + break; + + case OBJECT_CLIENT_OLE: + { + nType = FILETYPE_OBJECT; // if not set already + pOldParent = Application::GetDefDialogParent(); + Application::SetDefDialogParent( pParent ); + + ::sfx2::FileDialogHelper* pFileDlg = + pLink->GetFileDialog( (SFXWB_INSERT | WB_3DLOOK), String() ); + pFileDlg->StartExecuteModal( LINK( this, SvFileObject, DialogClosedHdl ) ); + } + break; + + case OBJECT_CLIENT_FILE: + { + nType = FILETYPE_TEXT; // if not set already + pOldParent = Application::GetDefDialogParent(); + Application::SetDefDialogParent( pParent ); + + String sFactory; + SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist(); + if ( pShell ) + sFactory = pShell->GetFactory().GetFactoryName(); + + ::sfx2::FileDialogHelper* pFileDlg = + pLink->GetFileDialog( (SFXWB_INSERT | WB_3DLOOK), sFactory ); + pFileDlg->StartExecuteModal( LINK( this, SvFileObject, DialogClosedHdl ) ); + } + break; + + default: + sFile.Erase(); + } + } +} + +IMPL_STATIC_LINK( SvFileObject, LoadGrfReady_Impl, void*, EMPTYARG ) +{ + // wenn wir von hier kommen, kann es kein Fehler mehr sein + pThis->bLoadError = FALSE; + pThis->bWaitForData = FALSE; + pThis->bInCallDownLoad = FALSE; + + if( !pThis->bInNewData && !pThis->bDataReady ) + { + // Grafik ist fertig, also DataChanged von der Status- + // aederung schicken: + pThis->bDataReady = TRUE; + pThis->SendStateChg_Impl( sfx2::LinkManager::STATE_LOAD_OK ); + + // und dann nochmal die Daten senden + pThis->NotifyDataChanged(); + } + + if( pThis->bDataReady ) + { + pThis->bLoadAgain = TRUE; + if( pThis->xMed.Is() ) + { + pThis->xMed->SetDataAvailableLink( Link() ); + pThis->xMed->SetDoneLink( Link() ); + + Application::PostUserEvent( + STATIC_LINK( pThis, SvFileObject, DelMedium_Impl ), + new SfxMediumRef( pThis->xMed )); + pThis->xMed.Clear(); + } + if( pThis->pDownLoadData ) + delete pThis->pDownLoadData, pThis->pDownLoadData = 0; + } + + return 0; +} + +IMPL_STATIC_LINK( SvFileObject, DelMedium_Impl, SfxMediumRef*, pDelMed ) +{ + (void)pThis; + delete pDelMed; + return 0; +} + +IMPL_STATIC_LINK( SvFileObject, LoadGrfNewData_Impl, void*, EMPTYARG ) +{ + // wenn wir von hier kommen, kann es kein Fehler mehr sein + if( pThis->bInNewData ) + return 0; + + pThis->bInNewData = TRUE; + pThis->bLoadError = FALSE; + + if( !pThis->pDownLoadData ) + { + pThis->pDownLoadData = new Impl_DownLoadData( + STATIC_LINK( pThis, SvFileObject, LoadGrfNewData_Impl ) ); + + // Null-Link setzen, damit keine temporaeren Grafiken + // rausgeswapt werden; der Filter prueft, ob schon + // ein Link gesetzt ist => falls dies zutrifft, wird + // _kein_ neuer Link gesetzt; der Link muss hier gesetzt werden, + // (bevor das erste Mal gefiltert wird), um zu verhindern, + // dass der Kontext zurueckgesetzt wird (aynchrones Laden) + if( !pThis->bNativFormat ) + { + static GfxLink aDummyLink; + pThis->pDownLoadData->aGrf.SetLink( aDummyLink ); + } + } + + pThis->NotifyDataChanged(); + + SvStream* pStrm = pThis->xMed.Is() ? pThis->xMed->GetInStream() : 0; + if( pStrm && pStrm->GetError() ) + { + if( ERRCODE_IO_PENDING == pStrm->GetError() ) + pStrm->ResetError(); + + // im DataChanged ein DataReady? + else if( pThis->bWaitForData && pThis->pDownLoadData ) + { + pThis->bLoadError = TRUE; + } + } + + if( pThis->bDataReady ) + { + // Grafik ist fertig, also DataChanged von der Status- + // aederung schicken: + pThis->SendStateChg_Impl( pStrm->GetError() ? sfx2::LinkManager::STATE_LOAD_ERROR : sfx2::LinkManager::STATE_LOAD_OK ); + } + + pThis->bInNewData = FALSE; + return 0; +} + +IMPL_LINK( SvFileObject, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg ) +{ + String sFile; + Application::SetDefDialogParent( pOldParent ); + + if ( FILETYPE_TEXT == nType || FILETYPE_OBJECT == nType ) + { + if ( _pFileDlg && _pFileDlg->GetError() == ERRCODE_NONE ) + { + String sURL( _pFileDlg->GetPath() ); + sFile = sURL; + sFile += ::sfx2::cTokenSeperator; + sFile += ::sfx2::cTokenSeperator; + sFile += impl_getFilter( sURL ); + } + } + else + { + DBG_ERRORFILE( "SvFileObject::DialogClosedHdl(): wrong file type" ); + } + + if ( aEndEditLink.IsSet() ) + aEndEditLink.Call( &sFile ); + return 0; +} + +/* [Beschreibung] + + Die Methode stellt fest, ob aus einem DDE-Object die Daten gelesen + werden kann. + Zurueckgegeben wird: + ERRCODE_NONE wenn sie komplett gelesen wurde + ERRCODE_SO_PENDING wenn sie noch nicht komplett gelesen wurde + ERRCODE_SO_FALSE sonst +*/ +BOOL SvFileObject::IsPending() const +{ + return FILETYPE_GRF == nType && !bLoadError && + ( pDownLoadData || bWaitForData ); +} +BOOL SvFileObject::IsDataComplete() const +{ + BOOL bRet = FALSE; + if( FILETYPE_GRF != nType ) + bRet = TRUE; + else if( !bLoadError && ( !bWaitForData && !pDownLoadData )) + { + SvFileObject* pThis = (SvFileObject*)this; + if( bDataReady || + ( bSynchron && pThis->LoadFile_Impl() && xMed.Is() ) ) + bRet = TRUE; + else + { + INetURLObject aUrl( sFileNm ); + if( aUrl.HasError() || + INET_PROT_NOT_VALID == aUrl.GetProtocol() ) + bRet = TRUE; + } + } + return bRet; +} + + + +void SvFileObject::CancelTransfers() +{ + if( xMed.Is() ) + xMed->CancelTransfers(); + + // und aus dem Cache austragen, wenn man mitten im Laden ist + if( !bDataReady ) + { + // nicht noch mal aufsetzen + bLoadAgain = FALSE; + bDataReady = bLoadError = bWaitForData = TRUE; + SendStateChg_Impl( sfx2::LinkManager::STATE_LOAD_ABORT ); + } +} + + +void SvFileObject::SetTransferPriority( USHORT ) +{ +} + + +void SvFileObject::SendStateChg_Impl( sfx2::LinkManager::LinkState nState ) +{ + if( !bStateChangeCalled && HasDataLinks() ) + { + css::uno::Any aAny; + aAny <<= rtl::OUString::valueOf( (sal_Int32)nState ); + DataChanged( SotExchange::GetFormatName( + sfx2::LinkManager::RegisterStatusInfoId()), aAny ); + bStateChangeCalled = TRUE; + } +} + + diff --git a/sfx2/source/appl/fileobj.hxx b/sfx2/source/appl/fileobj.hxx new file mode 100644 index 000000000000..a769ed9e2843 --- /dev/null +++ b/sfx2/source/appl/fileobj.hxx @@ -0,0 +1,99 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: fileobj.hxx,v $ + * $Revision: 1.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _FILEOBJ_HXX +#define _FILEOBJ_HXX + +#include <tools/string.hxx> +#include <sfx2/linksrc.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/linkmgr.hxx> + +class Graphic; +struct Impl_DownLoadData; +namespace sfx2 { class FileDialogHelper; } + +class SvFileObject : public sfx2::SvLinkSource +{ + String sFileNm; + String sFilter; + String sReferer; + Link aEndEditLink; + SfxMediumRef xMed; + Impl_DownLoadData* pDownLoadData; + Window* pOldParent; + + BYTE nType; + + BOOL bLoadAgain : 1; + BOOL bSynchron : 1; + BOOL bLoadError : 1; + BOOL bWaitForData : 1; + BOOL bInNewData : 1; + BOOL bDataReady : 1; + BOOL bMedUseCache : 1; + BOOL bNativFormat : 1; + BOOL bClearMedium : 1; + BOOL bStateChangeCalled : 1; + BOOL bInCallDownLoad : 1; + + BOOL GetGraphic_Impl( Graphic&, SvStream* pStream = 0 ); + BOOL LoadFile_Impl(); + void SendStateChg_Impl( sfx2::LinkManager::LinkState nState ); + + DECL_STATIC_LINK( SvFileObject, DelMedium_Impl, SfxMediumRef* ); + DECL_STATIC_LINK( SvFileObject, LoadGrfReady_Impl, void* ); + DECL_STATIC_LINK( SvFileObject, LoadGrfNewData_Impl, void* ); + DECL_LINK( DialogClosedHdl, sfx2::FileDialogHelper* ); + +protected: + virtual ~SvFileObject(); + +public: + SvFileObject(); + + virtual BOOL GetData( ::com::sun::star::uno::Any & rData /*out param*/, + const String & rMimeType, + BOOL bSynchron = FALSE ); + + virtual BOOL Connect( sfx2::SvBaseLink* ); + virtual void Edit( Window *, sfx2::SvBaseLink *, const Link& rEndEditHdl ); + + // erfrage ob das man direkt auf die Daten zugreifen kann oder ob das + // erst angestossen werden muss + virtual BOOL IsPending() const; + virtual BOOL IsDataComplete() const; + + void CancelTransfers(); + void SetTransferPriority( USHORT nPrio ); +}; + + +#endif + diff --git a/sfx2/source/appl/linkmgr2.cxx b/sfx2/source/appl/linkmgr2.cxx index 3533fb8a428f..bb1f1da13abd 100644 --- a/sfx2/source/appl/linkmgr2.cxx +++ b/sfx2/source/appl/linkmgr2.cxx @@ -31,37 +31,54 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sfx2.hxx" - -#include <tools/debug.hxx> #include <sfx2/linkmgr.hxx> - +#include <com/sun/star/document/UpdateDocMode.hpp> +#include <sfx2/objsh.hxx> +#include <svl/urihelper.hxx> +#include <sot/formats.hxx> +#include <tools/urlobj.hxx> +#include <sot/exchange.hxx> +#include <tools/debug.hxx> #include <vcl/msgbox.hxx> #include <sfx2/lnkbase.hxx> -//#include <sfx2/linksrc.hxx> +#include <sfx2/app.hxx> +#include <vcl/graph.hxx> +#include <svl/stritem.hxx> +#include <svl/eitem.hxx> +#include <svl/intitem.hxx> +#include <unotools/localfilehelper.hxx> +#include <i18npool/mslangid.hxx> +#include <sfx2/request.hxx> + +#include "fileobj.hxx" #include "impldde.hxx" -//#include "svuidlg.hrc" -//#include "iface.hxx" - #include "app.hrc" #include "sfxresid.hxx" #define _SVSTDARR_STRINGSDTOR - #include <svl/svstdarr.hxx> - namespace sfx2 { +class SvxInternalLink : public sfx2::SvLinkSource +{ +public: + SvxInternalLink() {} + + virtual BOOL Connect( sfx2::SvBaseLink* ); +}; + + SV_IMPL_PTRARR( SvBaseLinks, SvBaseLinkRefPtr ) -SvLinkManager::SvLinkManager() - : pPersist( 0 ) +LinkManager::LinkManager(SfxObjectShell* p) + : pPersist( p ) { } -SvLinkManager::~SvLinkManager() +LinkManager::~LinkManager() { SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData(); for( USHORT n = aLinkTbl.Count(); n; --n, ++ppRef ) @@ -77,12 +94,12 @@ SvLinkManager::~SvLinkManager() /************************************************************************ -|* SvLinkManager::Remove() +|* LinkManager::Remove() |* |* Beschreibung *************************************************************************/ -void SvLinkManager::Remove( SvBaseLink *pLink ) +void LinkManager::Remove( SvBaseLink *pLink ) { // keine Links doppelt einfuegen int bFound = FALSE; @@ -110,7 +127,7 @@ void SvLinkManager::Remove( SvBaseLink *pLink ) } -void SvLinkManager::Remove( USHORT nPos, USHORT nCnt ) +void LinkManager::Remove( USHORT nPos, USHORT nCnt ) { if( nCnt && nPos < aLinkTbl.Count() ) { @@ -132,7 +149,7 @@ void SvLinkManager::Remove( USHORT nPos, USHORT nCnt ) } -BOOL SvLinkManager::Insert( SvBaseLink* pLink ) +BOOL LinkManager::Insert( SvBaseLink* pLink ) { // keine Links doppelt einfuegen for( USHORT n = 0; n < aLinkTbl.Count(); ++n ) @@ -152,7 +169,7 @@ BOOL SvLinkManager::Insert( SvBaseLink* pLink ) } -BOOL SvLinkManager::InsertLink( SvBaseLink * pLink, +BOOL LinkManager::InsertLink( SvBaseLink * pLink, USHORT nObjType, USHORT nUpdateMode, const String* pName ) @@ -166,7 +183,7 @@ BOOL SvLinkManager::InsertLink( SvBaseLink * pLink, } -BOOL SvLinkManager::InsertDDELink( SvBaseLink * pLink, +BOOL LinkManager::InsertDDELink( SvBaseLink * pLink, const String& rServer, const String& rTopic, const String& rItem ) @@ -183,7 +200,7 @@ BOOL SvLinkManager::InsertDDELink( SvBaseLink * pLink, } -BOOL SvLinkManager::InsertDDELink( SvBaseLink * pLink ) +BOOL LinkManager::InsertDDELink( SvBaseLink * pLink ) { DBG_ASSERT( OBJECT_CLIENT_SO & pLink->GetObjType(), "no OBJECT_CLIENT_SO" ); if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) ) @@ -197,34 +214,70 @@ BOOL SvLinkManager::InsertDDELink( SvBaseLink * pLink ) // erfrage die Strings fuer den Dialog -BOOL SvLinkManager::GetDisplayNames( const SvBaseLink * pLink, +BOOL LinkManager::GetDisplayNames( const SvBaseLink * pLink, String* pType, String* pFile, String* pLinkStr, - String* /*pFilter*/ ) const + String* pFilter ) const { BOOL bRet = FALSE; - String aLN = pLink->GetLinkSourceName(); - if( aLN.Len() != 0 && pLink->GetObjType() == OBJECT_CLIENT_DDE ) + const String sLNm( pLink->GetLinkSourceName() ); + if( sLNm.Len() ) { - USHORT nTmp = 0; - String sCmd( aLN ); - String sServer( sCmd.GetToken( 0, cTokenSeperator, nTmp ) ); - String sTopic( sCmd.GetToken( 0, cTokenSeperator, nTmp ) ); - - if( pType ) - *pType = sServer; - if( pFile ) - *pFile = sTopic; - if( pLinkStr ) - *pLinkStr = sCmd.Copy( nTmp ); - bRet = TRUE; + switch( pLink->GetObjType() ) + { + case OBJECT_CLIENT_FILE: + case OBJECT_CLIENT_GRF: + case OBJECT_CLIENT_OLE: + { + USHORT nPos = 0; + String sFile( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) ); + String sRange( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) ); + + if( pFile ) + *pFile = sFile; + if( pLink ) + *pLinkStr = sRange; + if( pFilter ) + *pFilter = sLNm.Copy( nPos ); + + if( pType ) + { + sal_uInt16 nObjType = pLink->GetObjType(); + *pType = String( SfxResId( + ( OBJECT_CLIENT_FILE == nObjType || OBJECT_CLIENT_OLE == nObjType ) + ? RID_SVXSTR_FILELINK + : RID_SVXSTR_GRAFIKLINK )); + } + bRet = TRUE; + } + break; + case OBJECT_CLIENT_DDE: + { + USHORT nTmp = 0; + String sCmd( sLNm ); + String sServer( sCmd.GetToken( 0, cTokenSeperator, nTmp ) ); + String sTopic( sCmd.GetToken( 0, cTokenSeperator, nTmp ) ); + + if( pType ) + *pType = sServer; + if( pFile ) + *pFile = sTopic; + if( pLinkStr ) + *pLinkStr = sCmd.Copy( nTmp ); + bRet = TRUE; + } + break; + default: + break; + } } + return bRet; } -void SvLinkManager::UpdateAllLinks( +void LinkManager::UpdateAllLinks( BOOL bAskUpdate, BOOL /*bCallErrHdl*/, BOOL bUpdateGrfLinks, @@ -287,14 +340,24 @@ void SvLinkManager::UpdateAllLinks( |* Beschreibung *************************************************************************/ -SvLinkSourceRef SvLinkManager::CreateObj( SvBaseLink * pLink ) +SvLinkSourceRef LinkManager::CreateObj( SvBaseLink * pLink ) { - if( OBJECT_CLIENT_DDE == pLink->GetObjType() ) - return new SvDDEObject(); - return SvLinkSourceRef(); + switch( pLink->GetObjType() ) + { + case OBJECT_CLIENT_FILE: + case OBJECT_CLIENT_GRF: + case OBJECT_CLIENT_OLE: + return new SvFileObject; + case OBJECT_INTERN: + return new SvxInternalLink; + case OBJECT_CLIENT_DDE: + return new SvDDEObject; + default: + return SvLinkSourceRef(); + } } -BOOL SvLinkManager::InsertServer( SvLinkSource* pObj ) +BOOL LinkManager::InsertServer( SvLinkSource* pObj ) { // keine doppelt einfuegen if( !pObj || USHRT_MAX != aServerTbl.GetPos( pObj ) ) @@ -305,7 +368,7 @@ BOOL SvLinkManager::InsertServer( SvLinkSource* pObj ) } -void SvLinkManager::RemoveServer( SvLinkSource* pObj ) +void LinkManager::RemoveServer( SvLinkSource* pObj ) { USHORT nPos = aServerTbl.GetPos( pObj ); if( USHRT_MAX != nPos ) @@ -327,6 +390,259 @@ void MakeLnkName( String& rName, const String* pType, const String& rFile, ((rName += cTokenSeperator ) += *pFilter).EraseLeadingChars().EraseTrailingChars(); } +BOOL LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink, + USHORT nFileType, + const String& rFileNm, + const String* pFilterNm, + const String* pRange ) +{ + if( !( OBJECT_CLIENT_SO & rLink.GetObjType() )) + return FALSE; + + String sCmd( rFileNm ); + sCmd += ::sfx2::cTokenSeperator; + if( pRange ) + sCmd += *pRange; + if( pFilterNm ) + ( sCmd += ::sfx2::cTokenSeperator ) += *pFilterNm; + + return InsertLink( &rLink, nFileType, sfx2::LINKUPDATE_ONCALL, &sCmd ); +} + +BOOL LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink ) +{ + if( OBJECT_CLIENT_FILE == ( OBJECT_CLIENT_FILE & rLink.GetObjType() )) + return InsertLink( &rLink, rLink.GetObjType(), sfx2::LINKUPDATE_ONCALL ); + return FALSE; +} + +// eine Uebertragung wird abgebrochen, also alle DownloadMedien canceln +// (ist zur Zeit nur fuer die FileLinks interressant!) +void LinkManager::CancelTransfers() +{ + SvFileObject* pFileObj; + sfx2::SvBaseLink* pLnk; + + const sfx2::SvBaseLinks& rLnks = GetLinks(); + for( USHORT n = rLnks.Count(); n; ) + if( 0 != ( pLnk = &(*rLnks[ --n ])) && + OBJECT_CLIENT_FILE == (OBJECT_CLIENT_FILE & pLnk->GetObjType()) && + 0 != ( pFileObj = (SvFileObject*)pLnk->GetObj() ) ) +// 0 != ( pFileObj = (SvFileObject*)SvFileObject::ClassFactory()-> +// CastAndAddRef( pLnk->GetObj() )) ) + pFileObj->CancelTransfers(); +} + +void LinkManager::SetTransferPriority( sfx2::SvBaseLink& /*rLink*/, USHORT /*nPrio*/ ) +{ +// SvFileObject* pFileObj = +// (SvFileObject*)SvFileObject::ClassFactory()-> +// CastAndAddRef( rLink.GetObj() ); +// OBJECT_CLIENT_FILE == (OBJECT_CLIENT_FILE & rLink.GetObjType()) ? +// (SvFileObject*)rLink.GetObj() : 0; +} + + + // um Status Informationen aus dem FileObject an den BaseLink zu + // senden, gibt es eine eigene ClipBoardId. Das SvData-Object hat + // dann die entsprechenden Informationen als String. + // Wird zur Zeit fuer FileObject in Verbindung mit JavaScript benoetigt + // - das braucht Informationen ueber Load/Abort/Error +ULONG LinkManager::RegisterStatusInfoId() +{ + static ULONG nFormat = 0; + + if( !nFormat ) + { +// wie sieht die neue Schnittstelle aus? +// nFormat = Exchange::RegisterFormatName( "StatusInfo vom SvxInternalLink" ); + nFormat = SotExchange::RegisterFormatName( + String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( + "StatusInfo vom SvxInternalLink" ))); + } + return nFormat; +} + +// ---------------------------------------------------------------------- + +BOOL LinkManager::GetGraphicFromAny( const String& rMimeType, + const ::com::sun::star::uno::Any & rValue, + Graphic& rGrf ) +{ + BOOL bRet = FALSE; + ::com::sun::star::uno::Sequence< sal_Int8 > aSeq; + if( rValue.hasValue() && ( rValue >>= aSeq ) ) + { + SvMemoryStream aMemStm( (void*)aSeq.getConstArray(), aSeq.getLength(), + STREAM_READ ); + aMemStm.Seek( 0 ); + + switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) ) + { + case SOT_FORMATSTR_ID_SVXB: + { + aMemStm >> rGrf; + bRet = TRUE; + } + break; + case FORMAT_GDIMETAFILE: + { + GDIMetaFile aMtf; + aMtf.Read( aMemStm ); + rGrf = aMtf; + bRet = TRUE; + } + break; + case FORMAT_BITMAP: + { + Bitmap aBmp; + aMemStm >> aBmp; + rGrf = aBmp; + bRet = TRUE; + } + break; + } + } + return bRet; +} + + +// ---------------------------------------------------------------------- +String lcl_DDE_RelToAbs( const String& rTopic, const String& rBaseURL ) +{ + String sRet; + INetURLObject aURL( rTopic ); + if( INET_PROT_NOT_VALID == aURL.GetProtocol() ) + utl::LocalFileHelper::ConvertSystemPathToURL( rTopic, rBaseURL, sRet ); + if( !sRet.Len() ) + sRet = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), rTopic, URIHelper::GetMaybeFileHdl(), true ); + return sRet; +} + +BOOL SvxInternalLink::Connect( sfx2::SvBaseLink* pLink ) +{ + SfxObjectShell* pFndShell = 0; + USHORT nUpdateMode = com::sun::star::document::UpdateDocMode::NO_UPDATE; + String sTopic, sItem, sReferer; + if( pLink->GetLinkManager() && + pLink->GetLinkManager()->GetDisplayNames( pLink, 0, &sTopic, &sItem ) + && sTopic.Len() ) + { + // erstmal nur ueber die DocumentShells laufen und die mit dem + // Namen heraussuchen: + + com::sun::star::lang::Locale aLocale; + MsLangId::convertLanguageToLocale( LANGUAGE_SYSTEM, aLocale ); + CharClass aCC( aLocale ); + + String sNm( sTopic ), sTmp; + aCC.toLower( sNm ); + + TypeId aType( TYPE(SfxObjectShell) ); + + BOOL bFirst = TRUE; + SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist(); + if( pShell && pShell->GetMedium() ) + { + sReferer = pShell->GetMedium()->GetBaseURL(); + SFX_ITEMSET_ARG( pShell->GetMedium()->GetItemSet(), pItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False ); + if ( pItem ) + nUpdateMode = pItem->GetValue(); + } + + String sNmURL( lcl_DDE_RelToAbs( sTopic, sReferer ) ); + aCC.toLower( sNmURL ); + + if ( !pShell ) + { + bFirst = FALSE; + pShell = SfxObjectShell::GetFirst( &aType, sal_False ); + } + + while( pShell ) + { + if( !sTmp.Len() ) + { + sTmp = pShell->GetTitle( SFX_TITLE_FULLNAME ); + sTmp = lcl_DDE_RelToAbs(sTmp, sReferer ); + } + + + aCC.toLower( sTmp ); + if( sTmp == sNmURL ) // die wollen wir haben + { + pFndShell = pShell; + break; + } + + if( bFirst ) + { + bFirst = FALSE; + pShell = SfxObjectShell::GetFirst( &aType, sal_False ); + } + else + pShell = SfxObjectShell::GetNext( *pShell, &aType, sal_False ); + + sTmp.Erase(); + } + } + + // empty topics are not allowed - which document is it + if( !sTopic.Len() ) + return FALSE; + + if( !pFndShell ) + { + // dann versuche die Datei zu laden: + INetURLObject aURL( sTopic ); + INetProtocol eOld = aURL.GetProtocol(); + aURL.SetURL( sTopic = lcl_DDE_RelToAbs( sTopic, sReferer ) ); + if( INET_PROT_NOT_VALID != eOld || + INET_PROT_HTTP != aURL.GetProtocol() ) + { + SfxStringItem aName( SID_FILE_NAME, sTopic ); + SfxBoolItem aMinimized(SID_MINIMIZED, TRUE); + SfxBoolItem aHidden(SID_HIDDEN, TRUE); + SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") ); + SfxStringItem aReferer( SID_REFERER, sReferer ); + SfxUInt16Item aUpdate( SID_UPDATEDOCMODE, nUpdateMode ); + SfxBoolItem aReadOnly(SID_DOC_READONLY, TRUE); + + // #i14200# (DDE-link crashes wordprocessor) + SfxAllItemSet aArgs( SFX_APP()->GetPool() ); + aArgs.Put(aReferer); + aArgs.Put(aTarget); + aArgs.Put(aHidden); + aArgs.Put(aMinimized); + aArgs.Put(aName); + aArgs.Put(aUpdate); + aArgs.Put(aReadOnly); + pFndShell = SfxObjectShell::CreateAndLoadObject( aArgs ); + } + } + + BOOL bRet = FALSE; + if( pFndShell ) + { + sfx2::SvLinkSource* pNewSrc = pFndShell->DdeCreateLinkSource( sItem ); + if( pNewSrc ) + { + bRet = TRUE; + + ::com::sun::star::datatransfer::DataFlavor aFl; + SotExchange::GetFormatDataFlavor( pLink->GetContentType(), aFl ); + + pLink->SetObj( pNewSrc ); + pNewSrc->AddDataAdvise( pLink, aFl.MimeType, + sfx2::LINKUPDATE_ONCALL == pLink->GetUpdateMode() + ? ADVISEMODE_ONLYONCE + : 0 ); + } + } + return bRet; +} + + } diff --git a/sfx2/source/appl/lnkbase2.cxx b/sfx2/source/appl/lnkbase2.cxx index 8a852b44b6f7..516e7eccf400 100644 --- a/sfx2/source/appl/lnkbase2.cxx +++ b/sfx2/source/appl/lnkbase2.cxx @@ -37,19 +37,12 @@ #include <com/sun/star/uno/Any.hxx> #include <com/sun/star/uno/Sequence.hxx> #include <vcl/msgbox.hxx> - #include <sfx2/linkmgr.hxx> -//#include "svuidlg.hrc" -//#include "iface.hxx" #include <vcl/svapp.hxx> -//#include <soerr.hxx> - #include "app.hrc" #include "sfxresid.hxx" #include <sfx2/filedlghelper.hxx> - #include <tools/debug.hxx> - #include <svl/svdde.hxx> using namespace ::com::sun::star::uno; @@ -66,7 +59,7 @@ class ImplDdeItem; struct BaseLink_Impl { Link m_aEndEditLink; - SvLinkManager* m_pLinkMgr; + LinkManager* m_pLinkMgr; Window* m_pParentWin; FileDialogHelper* m_pFileDlg; bool m_bIsConnect; @@ -472,17 +465,17 @@ BOOL SvBaseLink::SetContentType( ULONG nType ) return FALSE; } -SvLinkManager* SvBaseLink::GetLinkManager() +LinkManager* SvBaseLink::GetLinkManager() { return pImpl->m_pLinkMgr; } -const SvLinkManager* SvBaseLink::GetLinkManager() const +const LinkManager* SvBaseLink::GetLinkManager() const { return pImpl->m_pLinkMgr; } -void SvBaseLink::SetLinkManager( SvLinkManager* _pMgr ) +void SvBaseLink::SetLinkManager( LinkManager* _pMgr ) { pImpl->m_pLinkMgr = _pMgr; } diff --git a/sfx2/source/appl/makefile.mk b/sfx2/source/appl/makefile.mk index 48d1258e2838..1673a4953a97 100644 --- a/sfx2/source/appl/makefile.mk +++ b/sfx2/source/appl/makefile.mk @@ -93,6 +93,7 @@ SFX_OBJECTS = \ $(SLO)$/appuno.obj \ $(SLO)$/appbaslib.obj \ $(SLO)$/childwin.obj \ + $(SLO)$/fileobj.obj \ $(SLO)$/helpdispatch.obj \ $(SLO)$/helpinterceptor.obj \ $(SLO)$/imagemgr.obj\ @@ -103,6 +104,7 @@ SFX_OBJECTS = \ $(SLO)$/lnkbase2.obj \ $(SLO)$/module.obj \ $(SLO)$/newhelp.obj \ + $(SLO)$/opengrf.obj \ $(SLO)$/sfxdll.obj \ $(SLO)$/sfxhelp.obj \ $(SLO)$/sfxpicklist.obj \ @@ -143,8 +145,10 @@ EXCEPTIONSFILES=\ $(SLO)$/appmisc.obj \ $(SLO)$/appinit.obj \ $(SLO)$/appcfg.obj \ + $(SLO)$/fileobj.obj \ $(SLO)$/helpinterceptor.obj \ $(SLO)$/newhelp.obj \ + $(SLO)$/opengrf.obj \ $(SLO)$/sfxhelp.obj \ $(SLO)$/shutdownicon.obj \ $(SLO)$/shutdowniconw32.obj \ diff --git a/sfx2/source/appl/opengrf.cxx b/sfx2/source/appl/opengrf.cxx new file mode 100644 index 000000000000..e10fa3899d39 --- /dev/null +++ b/sfx2/source/appl/opengrf.cxx @@ -0,0 +1,298 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: opengrf.cxx,v $ + * $Revision: 1.22 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sfx2.hxx" + +#include <tools/urlobj.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp> +#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> +#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> +#include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp> +#include <com/sun/star/ui/dialogs/ListboxControlActions.hpp> +#include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> +#include <com/sun/star/ui/dialogs/XFilePicker.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerListener.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp> +#include <com/sun/star/ui/dialogs/XFilePreview.hpp> +#include <com/sun/star/ui/dialogs/XFilterManager.hpp> +#include <svl/urihelper.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <svtools/transfer.hxx> +#include <sot/formats.hxx> +#include <vcl/msgbox.hxx> +#include <sfx2/filedlghelper.hxx> +#include <sfx2/docfile.hxx> +#include <unotools/pathoptions.hxx> +#include <sfx2/opengrf.hxx> +#include "app.hrc" +#include "sfxresid.hxx" + +//----------------------------------------------------------------------------- + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::ui::dialogs; +using namespace ::com::sun::star::uno; +using namespace ::rtl; +using namespace ::cppu; + + +//----------------------------------------------------------------------------- + +USHORT SvxOpenGrfErr2ResId( short err ) +{ + switch( err ) + { + case GRFILTER_OPENERROR: + return RID_SVXSTR_GRFILTER_OPENERROR; + case GRFILTER_IOERROR: + return RID_SVXSTR_GRFILTER_IOERROR; + case GRFILTER_VERSIONERROR: + return RID_SVXSTR_GRFILTER_VERSIONERROR; + case GRFILTER_FILTERERROR: + return RID_SVXSTR_GRFILTER_FILTERERROR; + case GRFILTER_FORMATERROR: + default: + return RID_SVXSTR_GRFILTER_FORMATERROR; + } +} + + +struct SvxOpenGrf_Impl +{ + SvxOpenGrf_Impl (); + + sfx2::FileDialogHelper aFileDlg; + uno::Reference < XFilePickerControlAccess > xCtrlAcc; +}; + + +SvxOpenGrf_Impl::SvxOpenGrf_Impl() : + aFileDlg(SFXWB_GRAPHIC) +{ + uno::Reference < XFilePicker > xFP = aFileDlg.GetFilePicker(); + xCtrlAcc = uno::Reference < XFilePickerControlAccess >(xFP, UNO_QUERY); +} + + +SvxOpenGraphicDialog::SvxOpenGraphicDialog( const String& rTitle ) : + mpImpl( new SvxOpenGrf_Impl ) +{ + mpImpl->aFileDlg.SetTitle(rTitle); +} + + +SvxOpenGraphicDialog::~SvxOpenGraphicDialog() +{ +} + + +short SvxOpenGraphicDialog::Execute() +{ + USHORT nImpRet; + BOOL bQuitLoop(FALSE); + + while( bQuitLoop == FALSE && + mpImpl->aFileDlg.Execute() == ERRCODE_NONE ) + { + if( GetPath().Len() ) + { + GraphicFilter* pFilter = GraphicFilter::GetGraphicFilter(); + INetURLObject aObj( GetPath() ); + + // check whether we can load the graphic + String aCurFilter( GetCurrentFilter() ); + USHORT nFormatNum = pFilter->GetImportFormatNumber( aCurFilter ); + USHORT nRetFormat = 0; + USHORT nFound = USHRT_MAX; + + // non-local? + if ( INET_PROT_FILE != aObj.GetProtocol() ) + { + SfxMedium aMed( aObj.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ, TRUE ); + aMed.DownLoad(); + SvStream* pStream = aMed.GetInStream(); + + if( pStream ) + nImpRet = pFilter->CanImportGraphic( aObj.GetMainURL( INetURLObject::NO_DECODE ), *pStream, nFormatNum, &nRetFormat ); + else + nImpRet = pFilter->CanImportGraphic( aObj, nFormatNum, &nRetFormat ); + + if ( GRFILTER_OK != nImpRet ) + { + if ( !pStream ) + nImpRet = pFilter->CanImportGraphic( aObj, GRFILTER_FORMAT_DONTKNOW, &nRetFormat ); + else + nImpRet = pFilter->CanImportGraphic( aObj.GetMainURL( INetURLObject::NO_DECODE ), *pStream, + GRFILTER_FORMAT_DONTKNOW, &nRetFormat ); + } + } + else + { + if( (nImpRet=pFilter->CanImportGraphic( aObj, nFormatNum, &nRetFormat )) != GRFILTER_OK ) + nImpRet = pFilter->CanImportGraphic( aObj, GRFILTER_FORMAT_DONTKNOW, &nRetFormat ); + } + + if ( GRFILTER_OK == nImpRet ) + nFound = nRetFormat; + + // could not load? + if ( nFound == USHRT_MAX ) + { + WarningBox aWarningBox( NULL, WB_3DLOOK | WB_RETRY_CANCEL, String( SfxResId( SvxOpenGrfErr2ResId(nImpRet) ) ) ); + bQuitLoop = aWarningBox.Execute()==RET_RETRY ? FALSE : TRUE; + } + else + { + // setup appropriate filter (so next time, it will work) + if( pFilter->GetImportFormatCount() ) + { + String aFormatName(pFilter->GetImportFormatName(nFound)); + SetCurrentFilter(aFormatName); + } + + return nImpRet; + } + } + } + + // cancel + return -1; +} + + +void SvxOpenGraphicDialog::SetPath( const String& rPath ) +{ + mpImpl->aFileDlg.SetDisplayDirectory(rPath); +} + +void SvxOpenGraphicDialog::SetPath( const String& rPath, sal_Bool bLinkState ) +{ + SetPath(rPath); + AsLink(bLinkState); +} + + +void SvxOpenGraphicDialog::EnableLink( sal_Bool state ) +{ + if( mpImpl->xCtrlAcc.is() ) + { + try + { + mpImpl->xCtrlAcc->enableControl( ExtendedFilePickerElementIds::CHECKBOX_LINK, state ); + } + catch(IllegalArgumentException) + { +#ifdef DBG_UTIL + DBG_ERROR( "Cannot enable \"link\" checkbox" ); +#endif + } + } +} + + +void SvxOpenGraphicDialog::AsLink(sal_Bool bState) +{ + if( mpImpl->xCtrlAcc.is() ) + { + try + { + Any aAny; aAny <<= bState; + mpImpl->xCtrlAcc->setValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, aAny ); + } + catch(IllegalArgumentException) + { +#ifdef DBG_UTIL + DBG_ERROR( "Cannot check \"link\" checkbox" ); +#endif + } + } +} + + +sal_Bool SvxOpenGraphicDialog::IsAsLink() const +{ + try + { + if( mpImpl->xCtrlAcc.is() ) + { + Any aVal = mpImpl->xCtrlAcc->getValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0 ); + DBG_ASSERT(aVal.hasValue(), "Value CBX_INSERT_AS_LINK not found"); + return aVal.hasValue() ? *(sal_Bool*) aVal.getValue() : sal_False; + } + } + catch(IllegalArgumentException) + { +#ifdef DBG_UTIL + DBG_ERROR( "Cannot access \"link\" checkbox" ); +#endif + } + + return sal_False; +} + + +int SvxOpenGraphicDialog::GetGraphic(Graphic& rGraphic) const +{ + return mpImpl->aFileDlg.GetGraphic(rGraphic); +} + + +String SvxOpenGraphicDialog::GetPath() const +{ + return mpImpl->aFileDlg.GetPath(); +} + + +String SvxOpenGraphicDialog::GetCurrentFilter() const +{ + return mpImpl->aFileDlg.GetCurrentFilter(); +} + + +void SvxOpenGraphicDialog::SetCurrentFilter(const String& rStr) +{ + mpImpl->aFileDlg.SetCurrentFilter(rStr); +} + +void SvxOpenGraphicDialog::SetControlHelpIds( const INT16* _pControlId, const INT32* _pHelpId ) +{ + mpImpl->aFileDlg.SetControlHelpIds( _pControlId, _pHelpId ); +} + +void SvxOpenGraphicDialog::SetDialogHelpId( const INT32 _nHelpId ) +{ + mpImpl->aFileDlg.SetDialogHelpId( _nHelpId ); +} |