diff options
-rw-r--r-- | basic/source/uno/dlgcont.cxx | 33 | ||||
-rw-r--r-- | dbaccess/source/core/dataaccess/databasedocument.cxx | 104 | ||||
-rw-r--r-- | svtools/inc/svtools/grfmgr.hxx | 5 | ||||
-rw-r--r-- | svtools/source/graphic/grfmgr.cxx | 40 |
4 files changed, 151 insertions, 31 deletions
diff --git a/basic/source/uno/dlgcont.cxx b/basic/source/uno/dlgcont.cxx index b4f4470a819b..6378a9532823 100644 --- a/basic/source/uno/dlgcont.cxx +++ b/basic/source/uno/dlgcont.cxx @@ -55,7 +55,7 @@ #include <cppuhelper/factory.hxx> #include <svtools/sfxecode.hxx> #include <svtools/ehdl.hxx> - +#include <svtools/grfmgr.hxx> namespace basic { @@ -229,35 +229,6 @@ void SAL_CALL SfxDialogLibraryContainer::writeLibraryElement xInput->closeInput(); } -void lcl_deepInspectForEmbeddedImages( const Reference< XInterface >& xIf, std::vector< rtl::OUString >& rvEmbedImgUrls ) -{ - static rtl::OUString sImageURL= OUString(RTL_CONSTASCII_USTRINGPARAM( "ImageURL" ) ); - Reference< beans::XPropertySet > xProps( xIf, UNO_QUERY ); - if ( xProps.is() ) - { - - if ( xProps->getPropertySetInfo()->hasPropertyByName( sImageURL ) ) - { - rtl::OUString sURL; - xProps->getPropertyValue( sImageURL ) >>= sURL; - if ( sURL.getLength() && sURL.compareToAscii( GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH( GRAPHOBJ_URLPREFIX ) ) == 0 ) - rvEmbedImgUrls.push_back( sURL ); - } - } - Reference< XNameContainer > xContainer( xIf, UNO_QUERY ); - if ( xContainer.is() ) - { - Sequence< rtl::OUString > sNames = xContainer->getElementNames(); - sal_Int32 nContainees = sNames.getLength(); - for ( sal_Int32 index = 0; index < nContainees; ++index ) - { - Reference< XInterface > xCtrl; - xContainer->getByName( sNames[ index ] ) >>= xCtrl; - lcl_deepInspectForEmbeddedImages( xCtrl, rvEmbedImgUrls ); - } - } -} - void SfxDialogLibraryContainer::storeLibrariesToStorage( const uno::Reference< embed::XStorage >& xStorage ) throw ( RuntimeException ) { LibraryContainerMethodGuard aGuard( *this ); @@ -315,7 +286,7 @@ void SfxDialogLibraryContainer::storeLibrariesToStorage( const uno::Reference< e OSL_VERIFY( xProps->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")) ) >>= xContext ); ::xmlscript::importDialogModel( xInput, xDialogModel, xContext, mxOwnerDocument ); std::vector< rtl::OUString > vEmbeddedImageURLs; - lcl_deepInspectForEmbeddedImages( Reference< XInterface >( xDialogModel, UNO_QUERY ), vEmbeddedImageURLs ); + GraphicObject::InspectForGraphicObjectImageURL( Reference< XInterface >( xDialogModel, UNO_QUERY ), vEmbeddedImageURLs ); if ( !vEmbeddedImageURLs.empty() ) { // Export the images to the storage diff --git a/dbaccess/source/core/dataaccess/databasedocument.cxx b/dbaccess/source/core/dataaccess/databasedocument.cxx index d8132a543e28..37f60919d56b 100644 --- a/dbaccess/source/core/dataaccess/databasedocument.cxx +++ b/dbaccess/source/core/dataaccess/databasedocument.cxx @@ -64,6 +64,12 @@ #include <com/sun/star/xml/sax/XDocumentHandler.hpp> #include <com/sun/star/ucb/XContent.hpp> #include <com/sun/star/sdb/application/XDatabaseDocumentUI.hpp> + +#include <com/sun/star/script/XStorageBasedLibraryContainer.hpp> +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/XDialogProvider.hpp> +#include <com/sun/star/document/XGraphicObjectResolver.hpp> + /** === end UNO includes === **/ #include <comphelper/documentconstants.hxx> @@ -95,6 +101,7 @@ #include <functional> #include <list> +#include <svtools/grfmgr.hxx> #define MAP_LEN(x) x, sizeof(x) - 1 using namespace ::com::sun::star::uno; @@ -384,6 +391,85 @@ namespace } } +static rtl::OUString sPictures( RTL_CONSTASCII_USTRINGPARAM("Pictures") ); + +// base documents seem to have a different behaviour to other documents, the +// root storage contents at least seem to be re-used over different saves, thus if there is a +// top level Picture directory it is never cleared. +// If we delete the 'Pictures' directory then the dialog library storage which does store +// any embed images will not work properly. ( this is due to the fact it will +// try to load the dialog which will try and access the embed images, if those images are not cached in +// memory it will try to read them from the Picture directory which is now gone, so... we have to use this +// inglorious hack below which basically will +// a) create a temp storage +// b) introspect any dialogs for any embed graphics and grab the associate URL(s) +// c) populate the temp storage with the associated embed images ( will be stored in a 'Pictures' folder ) +// d) delete the 'Picture' element from the root storage +// e) copy the Pictures element of the temp storage to the root storage +// +// this assumes that we don't use the Pictures folder in the root of the base +// document for anything, I believe this is a valid assumption ( as much as +// I could check anyway ) + +void lcl_uglyHackToStoreDialogeEmbedImages( const Reference< XStorageBasedLibraryContainer >& xDlgCont, const Reference< XStorage >& xStorage, const Reference< XModel >& rxModel, const ::comphelper::ComponentContext& aContext ) throw ( RuntimeException ) +{ + Sequence< rtl::OUString > sLibraries = xDlgCont->getElementNames(); + Reference< XStorage > xTmpPic = xStorage->openStorageElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("tempPictures") ), ElementModes::READWRITE ); + + std::vector< rtl::OUString > vEmbedImgUrls; + for ( sal_Int32 i=0; i < sLibraries.getLength(); ++i ) + { + rtl::OUString sLibrary( sLibraries[ i ] ); + xDlgCont->loadLibrary( sLibrary ); + Reference< XNameContainer > xLib; + xDlgCont->getByName( sLibrary ) >>= xLib; + if ( xLib.is() ) + { + Sequence< rtl::OUString > sDialogs = xLib->getElementNames(); + sal_Int32 nDialogs( sDialogs.getLength() ); + for ( sal_Int32 j=0; j < nDialogs; ++j ) + { + Reference < ::com::sun::star::awt::XDialogProvider > xDlgPrv; + Sequence< Any > aArgs(1); + aArgs[ 0 ] <<= rxModel; + xDlgPrv.set( aContext.createComponentWithArguments( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.DialogProvider")) , aArgs), UNO_QUERY ); + rtl::OUString sDialogUrl = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.script:") ); + sDialogUrl = sDialogUrl.concat( sLibraries[ i ] ).concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("." ) ) ).concat ( sDialogs[ j ] ).concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("?location=document") ) ); + + Reference< ::com::sun::star::awt::XControl > xDialog( xDlgPrv->createDialog( sDialogUrl ), UNO_QUERY ); + Reference< XInterface > xModel = xDialog->getModel(); + GraphicObject::InspectForGraphicObjectImageURL( xModel, vEmbedImgUrls ); + } + } + } + // if we have any image urls, make sure we copy the associated images into tempPictures + if ( vEmbedImgUrls.size() ) + { + // Export the images to the storage + Sequence< Any > aArgs( 1 ); + aArgs[ 0 ] <<= xTmpPic; + Reference< XGraphicObjectResolver > xGraphicResolver( + aContext.createComponentWithArguments( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Svx.GraphicExportHelper" ) ), aArgs ), UNO_QUERY ); + std::vector< rtl::OUString >::iterator it = vEmbedImgUrls.begin(); + std::vector< rtl::OUString >::iterator it_end = vEmbedImgUrls.end(); + if ( xGraphicResolver.is() ) + { + for ( sal_Int32 count = 0; it != it_end; ++it, ++count ) + xGraphicResolver->resolveGraphicObjectURL( *it ); + } + + // delete old 'Pictures' storage and copy the contents of tempPictures into xStorage + xStorage->removeElement( sPictures ); + xTmpPic->copyElementTo( sPictures, xStorage, sPictures ); + } + else + { + // clean up an existing Pictures dir + if ( xStorage->isStorageElement( sPictures ) ) + xStorage->removeElement( sPictures ); + } +} + void ODatabaseDocument::impl_setInitialized() { m_eInitState = Initialized; @@ -1600,6 +1686,24 @@ void ODatabaseDocument::impl_writeStorage_throw( const Reference< XStorage >& _r WriteThroughComponent( xComponent, "content.xml", "com.sun.star.comp.sdb.DBExportFilter", aDelegatorArguments, aMediaDescriptor, _rxTargetStorage ); + if ( _rxTargetStorage->hasByName ( sPictures ) ) + { + try + { + // Delete any previously existing Pictures folder and regenerate + // any needed content if needed + Reference< XStorageBasedLibraryContainer > xDlgs = m_pImpl->getLibraryContainer( false ); + if ( xDlgs.is() ) + { + Reference< XModel > xModel(const_cast< ODatabaseDocument*>(this)); + lcl_uglyHackToStoreDialogeEmbedImages( m_pImpl->getLibraryContainer(false), _rxTargetStorage, xModel, m_pImpl->m_aContext ); + } + } + catch ( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } m_pImpl->storeLibraryContainersTo( _rxTargetStorage ); } diff --git a/svtools/inc/svtools/grfmgr.hxx b/svtools/inc/svtools/grfmgr.hxx index 25d8929d7f87..f43aec4cbae9 100644 --- a/svtools/inc/svtools/grfmgr.hxx +++ b/svtools/inc/svtools/grfmgr.hxx @@ -536,6 +536,11 @@ public: friend SvStream& operator>>( SvStream& rIStm, GraphicObject& rGraphicObj ); static GraphicObject CreateGraphicObjectFromURL( const ::rtl::OUString &rURL ); + // will inspect an object ( e.g. a control ) for any 'ImageURL' + // properties and return these in a vector. Note: this implementation + // will cater for XNameContainer objects and deepinspect any containees + // if they exist + static void InspectForGraphicObjectImageURL( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxIf, std::vector< rtl::OUString >& rvEmbedImgUrls ); }; // ------------------ diff --git a/svtools/source/graphic/grfmgr.cxx b/svtools/source/graphic/grfmgr.cxx index f41b26e24278..43b8687515a9 100644 --- a/svtools/source/graphic/grfmgr.cxx +++ b/svtools/source/graphic/grfmgr.cxx @@ -47,9 +47,19 @@ #include <vcl/pdfextoutdevdata.hxx> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + #define WATERMARK_LUM_OFFSET 50 #define WATERMARK_CON_OFFSET -70 +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::Sequence; +using com::sun::star::container::XNameContainer; +using com::sun::star::beans::XPropertySet; + GraphicManager* GraphicObject::mpGlobalMgr = NULL; struct GrfSimpleCacheObj @@ -1183,4 +1193,34 @@ GraphicObject GraphicObject::CreateGraphicObjectFromURL( const ::rtl::OUString & } } +void +GraphicObject::InspectForGraphicObjectImageURL( const Reference< XInterface >& xIf, std::vector< rtl::OUString >& rvEmbedImgUrls ) +{ + static rtl::OUString sImageURL(RTL_CONSTASCII_USTRINGPARAM( "ImageURL" ) ); + Reference< XPropertySet > xProps( xIf, UNO_QUERY ); + if ( xProps.is() ) + { + + if ( xProps->getPropertySetInfo()->hasPropertyByName( sImageURL ) ) + { + rtl::OUString sURL; + xProps->getPropertyValue( sImageURL ) >>= sURL; + if ( sURL.getLength() && sURL.compareToAscii( UNO_NAME_GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH( UNO_NAME_GRAPHOBJ_URLPREFIX ) ) == 0 ) + rvEmbedImgUrls.push_back( sURL ); + } + } + Reference< XNameContainer > xContainer( xIf, UNO_QUERY ); + if ( xContainer.is() ) + { + Sequence< rtl::OUString > sNames = xContainer->getElementNames(); + sal_Int32 nContainees = sNames.getLength(); + for ( sal_Int32 index = 0; index < nContainees; ++index ) + { + Reference< XInterface > xCtrl; + xContainer->getByName( sNames[ index ] ) >>= xCtrl; + InspectForGraphicObjectImageURL( xCtrl, rvEmbedImgUrls ); + } + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |