/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sfx2.hxx" //________________________________________________________________________________________________________ // my own includes //________________________________________________________________________________________________________ #include //________________________________________________________________________________________________________ // include of other projects //________________________________________________________________________________________________________ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // can be removed when this is a "real" service #include #include #include // can be removed when this is a "real" service #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //________________________________________________________________________________________________________ // includes of my own project //________________________________________________________________________________________________________ #include #include "sfx2/viewfac.hxx" #include "workwin.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "appdata.hxx" #include #include #include "sfx2/docstoragemodifylistener.hxx" #include "sfx2/brokenpackageint.hxx" #include "graphhelp.hxx" #include "docundomanager.hxx" #include #include #include //________________________________________________________________________________________________________ // const static const ::rtl::OUString SERVICENAME_DESKTOP = ::rtl::OUString::createFromAscii ("com.sun.star.frame.Desktop"); //________________________________________________________________________________________________________ // namespaces //________________________________________________________________________________________________________ namespace css = ::com::sun::star; using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using ::com::sun::star::beans::PropertyValue; using ::com::sun::star::frame::XFrame; using ::com::sun::star::frame::XController; using ::com::sun::star::frame::XController2; using ::com::sun::star::lang::IllegalArgumentException; using ::com::sun::star::io::IOException; using ::com::sun::star::lang::WrappedTargetException; using ::com::sun::star::uno::Type; using ::com::sun::star::uno::Sequence; using ::com::sun::star::document::XDocumentRecovery; using ::com::sun::star::document::XUndoManager; using ::com::sun::star::document::XUndoAction; using ::com::sun::star::document::UndoFailedException; using ::com::sun::star::frame::XModel; /** This Listener is used to get notified when the XDocumentProperties of the XModel change. */ class SfxDocInfoListener_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XModifyListener > { public: SfxObjectShell& m_rShell; SfxDocInfoListener_Impl( SfxObjectShell& i_rDoc ) : m_rShell(i_rDoc) { }; ~SfxDocInfoListener_Impl(); virtual void SAL_CALL disposing( const lang::EventObject& ) throw ( uno::RuntimeException ); virtual void SAL_CALL modified( const lang::EventObject& ) throw ( uno::RuntimeException ); }; SfxDocInfoListener_Impl::~SfxDocInfoListener_Impl() { } void SAL_CALL SfxDocInfoListener_Impl::modified( const lang::EventObject& ) throw ( uno::RuntimeException ) { ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); // notify changes to the SfxObjectShell m_rShell.FlushDocInfo(); } void SAL_CALL SfxDocInfoListener_Impl::disposing( const lang::EventObject& ) throw ( uno::RuntimeException ) { } //________________________________________________________________________________________________________ // impl. declarations //________________________________________________________________________________________________________ struct IMPL_SfxBaseModel_DataContainer : public ::sfx2::IModifiableDocument { // counter for SfxBaseModel instances created. static sal_Int64 g_nInstanceCounter ; SfxObjectShellRef m_pObjectShell ; ::rtl::OUString m_sURL ; ::rtl::OUString m_sRuntimeUID ; ::rtl::OUString m_aPreusedFilterName; ::cppu::OMultiTypeInterfaceContainerHelper m_aInterfaceContainer ; uno::Reference< uno::XInterface > m_xParent ; uno::Reference< frame::XController > m_xCurrent ; uno::Reference< document::XDocumentInfo > m_xDocumentInfo ; uno::Reference< document::XDocumentProperties > m_xDocumentProperties; uno::Reference< script::XStarBasicAccess > m_xStarBasicAccess ; uno::Reference< container::XNameReplace > m_xEvents ; uno::Sequence< beans::PropertyValue> m_seqArguments ; uno::Sequence< uno::Reference< frame::XController > > m_seqControllers ; uno::Reference< container::XIndexAccess > m_contViewData ; sal_uInt16 m_nControllerLockCount ; sal_Bool m_bClosed ; sal_Bool m_bClosing ; sal_Bool m_bSaving ; sal_Bool m_bSuicide ; sal_Bool m_bInitialized ; sal_Bool m_bExternalTitle ; sal_Bool m_bModifiedSinceLastSave; uno::Reference< com::sun::star::view::XPrintable> m_xPrintable ; uno::Reference< script::provider::XScriptProvider > m_xScriptProvider; uno::Reference< ui::XUIConfigurationManager > m_xUIConfigurationManager; ::rtl::Reference< ::sfx2::DocumentStorageModifyListener > m_pStorageModifyListen; ::rtl::OUString m_sModuleIdentifier; css::uno::Reference< css::frame::XTitle > m_xTitleHelper; css::uno::Reference< css::frame::XUntitledNumbers > m_xNumberedControllers; uno::Reference< rdf::XDocumentMetadataAccess> m_xDocumentMetadata; ::rtl::Reference< ::sfx2::DocumentUndoManager > m_pDocumentUndoManager; IMPL_SfxBaseModel_DataContainer( ::osl::Mutex& rMutex, SfxObjectShell* pObjectShell ) : m_pObjectShell ( pObjectShell ) , m_aInterfaceContainer ( rMutex ) , m_nControllerLockCount ( 0 ) , m_bClosed ( sal_False ) , m_bClosing ( sal_False ) , m_bSaving ( sal_False ) , m_bSuicide ( sal_False ) , m_bInitialized ( sal_False ) , m_bExternalTitle ( sal_False ) , m_bModifiedSinceLastSave( sal_False ) , m_pStorageModifyListen ( NULL ) , m_xTitleHelper () , m_xNumberedControllers () , m_xDocumentMetadata () // lazy , m_pDocumentUndoManager () { // increase global instance counter. ++g_nInstanceCounter; // set own Runtime UID m_sRuntimeUID = rtl::OUString::valueOf( g_nInstanceCounter ); } virtual ~IMPL_SfxBaseModel_DataContainer() { } // ::sfx2::IModifiableDocument virtual void storageIsModified() { if ( m_pObjectShell.Is() && !m_pObjectShell->IsModified() ) m_pObjectShell->SetModified( sal_True ); } uno::Reference GetDMA() { if (!m_xDocumentMetadata.is()) { OSL_ENSURE(m_pObjectShell, "GetDMA: no object shell?"); if (!m_pObjectShell) { return 0; } const uno::Reference xContext( ::comphelper::getProcessComponentContext()); ::rtl::OUString uri; const uno::Reference xModel( m_pObjectShell->GetModel()); const uno::Reference xMsf( xContext->getServiceManager()); const uno::Reference xTDDCF( xMsf->createInstanceWithContext( ::rtl::OUString::createFromAscii( "com.sun.star.frame." "TransientDocumentsDocumentContentFactory"), xContext), uno::UNO_QUERY_THROW); const uno::Reference xContent( xTDDCF->createDocumentContent(xModel) ); OSL_ENSURE(xContent.is(), "GetDMA: cannot create DocumentContent"); if (!xContent.is()) { return 0; } uri = xContent->getIdentifier()->getContentIdentifier(); OSL_ENSURE(uri.getLength(), "GetDMA: empty uri?"); if (uri.getLength() && !uri.endsWithAsciiL("/", 1)) { uri = uri + ::rtl::OUString::createFromAscii("/"); } m_xDocumentMetadata = new ::sfx2::DocumentMetadataAccess( xContext, *m_pObjectShell, uri); } return m_xDocumentMetadata; } uno::Reference CreateDMAUninitialized() { return (m_pObjectShell) ? new ::sfx2::DocumentMetadataAccess( ::comphelper::getProcessComponentContext(), *m_pObjectShell) : 0; } }; // static member initialization. sal_Int64 IMPL_SfxBaseModel_DataContainer::g_nInstanceCounter = 0; // ======================================================================================================= // Listener that forwards notifications from the PrintHelper to the "real" listeners class SfxPrintHelperListener_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::view::XPrintJobListener > { public: IMPL_SfxBaseModel_DataContainer* m_pData; SfxPrintHelperListener_Impl( IMPL_SfxBaseModel_DataContainer* pData ) : m_pData( pData ) {} virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw ( uno::RuntimeException ) ; virtual void SAL_CALL printJobEvent( const view::PrintJobEvent& rEvent ) throw ( uno::RuntimeException); }; void SAL_CALL SfxPrintHelperListener_Impl::disposing( const lang::EventObject& ) throw ( uno::RuntimeException ) { m_pData->m_xPrintable = 0; } void SAL_CALL SfxPrintHelperListener_Impl::printJobEvent( const view::PrintJobEvent& rEvent ) throw (uno::RuntimeException) { ::cppu::OInterfaceContainerHelper* pContainer = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType( ( const uno::Reference< view::XPrintJobListener >*) NULL ) ); if ( pContainer!=NULL ) { ::cppu::OInterfaceIteratorHelper pIterator(*pContainer); while (pIterator.hasMoreElements()) ((view::XPrintJobListener*)pIterator.next())->printJobEvent( rEvent ); } } // SfxOwnFramesLocker ==================================================================================== // allows to lock all the frames related to the provided SfxObjectShell class SfxOwnFramesLocker { uno::Sequence< uno::Reference< frame::XFrame > > m_aLockedFrames; Window* GetVCLWindow( const uno::Reference< frame::XFrame >& xFrame ); public: SfxOwnFramesLocker( SfxObjectShell* ObjechShell ); ~SfxOwnFramesLocker(); void UnlockFrames(); }; SfxOwnFramesLocker::SfxOwnFramesLocker( SfxObjectShell* pObjectShell ) { if ( !pObjectShell ) return; for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst( pObjectShell ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, pObjectShell ) ) { SfxFrame& rSfxFrame = pFrame->GetFrame(); try { // get vcl window related to the frame and lock it if it is still not locked uno::Reference< frame::XFrame > xFrame = rSfxFrame.GetFrameInterface(); Window* pWindow = GetVCLWindow( xFrame ); if ( !pWindow ) throw uno::RuntimeException(); if ( pWindow->IsEnabled() ) { pWindow->Disable(); try { sal_Int32 nLen = m_aLockedFrames.getLength(); m_aLockedFrames.realloc( nLen + 1 ); m_aLockedFrames[nLen] = xFrame; } catch( uno::Exception& ) { pWindow->Enable(); throw; } } } catch( uno::Exception& ) { OSL_ENSURE( sal_False, "Not possible to lock the frame window!\n" ); } } } SfxOwnFramesLocker::~SfxOwnFramesLocker() { UnlockFrames(); } Window* SfxOwnFramesLocker::GetVCLWindow( const uno::Reference< frame::XFrame >& xFrame ) { Window* pWindow = NULL; if ( xFrame.is() ) { uno::Reference< awt::XWindow > xWindow = xFrame->getContainerWindow(); if ( xWindow.is() ) pWindow = VCLUnoHelper::GetWindow( xWindow ); } return pWindow; } void SfxOwnFramesLocker::UnlockFrames() { for ( sal_Int32 nInd = 0; nInd < m_aLockedFrames.getLength(); nInd++ ) { try { if ( m_aLockedFrames[nInd].is() ) { // get vcl window related to the frame and unlock it Window* pWindow = GetVCLWindow( m_aLockedFrames[nInd] ); if ( !pWindow ) throw uno::RuntimeException(); pWindow->Enable(); m_aLockedFrames[nInd] = uno::Reference< frame::XFrame >(); } } catch( uno::Exception& ) { OSL_ENSURE( sal_False, "Can't unlock the frame window!\n" ); } } } // SfxSaveGuard ==================================================================================== class SfxSaveGuard { private: uno::Reference< frame::XModel > m_xModel; IMPL_SfxBaseModel_DataContainer* m_pData; SfxOwnFramesLocker* m_pFramesLock; public: SfxSaveGuard(const uno::Reference< frame::XModel >& xModel , IMPL_SfxBaseModel_DataContainer* pData , sal_Bool bRejectConcurrentSaveRequest); ~SfxSaveGuard(); }; SfxSaveGuard::SfxSaveGuard(const uno::Reference< frame::XModel >& xModel , IMPL_SfxBaseModel_DataContainer* pData , sal_Bool bRejectConcurrentSaveRequest) : m_xModel (xModel) , m_pData (pData ) , m_pFramesLock(0 ) { static ::rtl::OUString MSG_1 = ::rtl::OUString::createFromAscii("Object already disposed." ); static ::rtl::OUString MSG_2 = ::rtl::OUString::createFromAscii("Concurrent save requests on the same document are not possible."); if ( m_pData->m_bClosed ) throw ::com::sun::star::lang::DisposedException( MSG_1, ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >()); if ( bRejectConcurrentSaveRequest && m_pData->m_bSaving ) throw ::com::sun::star::io::IOException( MSG_2, ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >()); m_pData->m_bSaving = sal_True; m_pFramesLock = new SfxOwnFramesLocker(m_pData->m_pObjectShell); } SfxSaveGuard::~SfxSaveGuard() { SfxOwnFramesLocker* pFramesLock = m_pFramesLock; m_pFramesLock = 0; delete pFramesLock; m_pData->m_bSaving = sal_False; // m_bSuicide was set e.g. in case somewhere tried to close a document, while it was used for // storing at the same time. Further m_bSuicide was set to sal_True only if close(sal_True) was called. // So the owner ship was delegated to the place where a veto exception was thrown. // Now we have to call close() again and delegate the owner ship to the next one, which // can't accept that. Close(sal_False) can't work in this case. Because then the document will may be never closed ... if ( m_pData->m_bSuicide ) { // Reset this state. In case the new close() request is not accepted by somehwere else ... // it's not a good idea to have two "owners" for close .-) m_pData->m_bSuicide = sal_False; try { uno::Reference< util::XCloseable > xClose(m_xModel, uno::UNO_QUERY); if (xClose.is()) xClose->close(sal_True); } catch(const util::CloseVetoException&) {} } } // ======================================================================================================= //________________________________________________________________________________________________________ // constructor //________________________________________________________________________________________________________ DBG_NAME(sfx2_SfxBaseModel) SfxBaseModel::SfxBaseModel( SfxObjectShell *pObjectShell ) : BaseMutex() , m_pData( new IMPL_SfxBaseModel_DataContainer( m_aMutex, pObjectShell ) ) , m_bSupportEmbeddedScripts( pObjectShell && pObjectShell->Get_Impl() ? !pObjectShell->Get_Impl()->m_bNoBasicCapabilities : false ) , m_bSupportDocRecovery( pObjectShell && pObjectShell->Get_Impl() ? pObjectShell->Get_Impl()->m_bDocRecoverySupport : false ) { DBG_CTOR(sfx2_SfxBaseModel,NULL); if ( pObjectShell != NULL ) { StartListening( *pObjectShell ) ; } } //________________________________________________________________________________________________________ // destructor //________________________________________________________________________________________________________ SfxBaseModel::~SfxBaseModel() { DBG_DTOR(sfx2_SfxBaseModel,NULL); } //________________________________________________________________________________________________________ // XInterface //________________________________________________________________________________________________________ uno::Any SAL_CALL SfxBaseModel::queryInterface( const UNOTYPE& rType ) throw( uno::RuntimeException ) { if ( ( !m_bSupportEmbeddedScripts && rType.equals( XEMBEDDEDSCRIPTS::static_type() ) ) || ( !m_bSupportDocRecovery && rType.equals( XDocumentRecovery::static_type() ) ) ) return Any(); return SfxBaseModel_Base::queryInterface( rType ); } //________________________________________________________________________________________________________ // XInterface //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::acquire() throw( ) { // Attention: // Don't use mutex or guard in this method!!! Is a method of XInterface. // Forward to baseclass OWeakObject::acquire() ; } //________________________________________________________________________________________________________ // XInterface //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::release() throw( ) { // Attention: // Don't use mutex or guard in this method!!! Is a method of XInterface. // Forward to baseclass OWeakObject::release() ; } //________________________________________________________________________________________________________ // XTypeProvider //________________________________________________________________________________________________________ namespace { void lcl_stripType( Sequence< Type >& io_rTypes, const Type& i_rTypeToStrip ) { Sequence< UNOTYPE > aStrippedTypes( io_rTypes.getLength() - 1 ); ::std::remove_copy_if( io_rTypes.getConstArray(), io_rTypes.getConstArray() + io_rTypes.getLength(), aStrippedTypes.getArray(), ::std::bind2nd( ::std::equal_to< Type >(), i_rTypeToStrip ) ); io_rTypes = aStrippedTypes; } } uno::Sequence< UNOTYPE > SAL_CALL SfxBaseModel::getTypes() throw( uno::RuntimeException ) { uno::Sequence< UNOTYPE > aTypes( SfxBaseModel_Base::getTypes() ); if ( !m_bSupportEmbeddedScripts ) lcl_stripType( aTypes, XEMBEDDEDSCRIPTS::static_type() ); if ( !m_bSupportDocRecovery ) lcl_stripType( aTypes, XDocumentRecovery::static_type() ); return aTypes; } //________________________________________________________________________________________________________ // XTypeProvider //________________________________________________________________________________________________________ uno::Sequence< sal_Int8 > SAL_CALL SfxBaseModel::getImplementationId() throw( uno::RuntimeException ) { // Create one Id for all instances of this class. // Use ethernet address to do this! (sal_True) // Optimize this method // We initialize a static variable only one time. And we don't must use a mutex at every call! // For the first call; pID is NULL - for the second call pID is different from NULL! static ::cppu::OImplementationId* pID = NULL ; if ( pID == NULL ) { // Ready for multithreading; get global mutex for first call of this method only! see before ::osl::MutexGuard aGuard( MUTEX::getGlobalMutex() ) ; // Control these pointer again ... it can be, that another instance will be faster then these! if ( pID == NULL ) { // Create a new static ID ... static ::cppu::OImplementationId aID( sal_False ) ; // ... and set his address to static pointer! pID = &aID ; } } return pID->getImplementationId() ; } //________________________________________________________________________________________________________ // XStarBasicAccess //________________________________________________________________________________________________________ uno::Reference< script::XStarBasicAccess > implGetStarBasicAccess( SfxObjectShell* pObjectShell ) { uno::Reference< script::XStarBasicAccess > xRet; if( pObjectShell ) { BasicManager* pMgr = pObjectShell->GetBasicManager(); xRet = getStarBasicAccess( pMgr ); } return xRet; } uno::Reference< XNAMECONTAINER > SAL_CALL SfxBaseModel::getLibraryContainer() throw( uno::RuntimeException ) { SfxModelGuard aGuard( *this ); uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess; if( !rxAccess.is() && m_pData->m_pObjectShell.Is() ) rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell ); uno::Reference< XNAMECONTAINER > xRet; if( rxAccess.is() ) xRet = rxAccess->getLibraryContainer(); return xRet; } /**___________________________________________________________________________________________________ @seealso XStarBasicAccess */ void SAL_CALL SfxBaseModel::createLibrary( const ::rtl::OUString& LibName, const ::rtl::OUString& Password, const ::rtl::OUString& ExternalSourceURL, const ::rtl::OUString& LinkTargetURL ) throw(ELEMENTEXISTEXCEPTION, uno::RuntimeException) { SfxModelGuard aGuard( *this ); uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess; if( !rxAccess.is() && m_pData->m_pObjectShell.Is() ) rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell ); if( rxAccess.is() ) rxAccess->createLibrary( LibName, Password, ExternalSourceURL, LinkTargetURL ); } /**___________________________________________________________________________________________________ @seealso XStarBasicAccess */ void SAL_CALL SfxBaseModel::addModule( const ::rtl::OUString& LibraryName, const ::rtl::OUString& ModuleName, const ::rtl::OUString& Language, const ::rtl::OUString& Source ) throw( NOSUCHELEMENTEXCEPTION, uno::RuntimeException) { SfxModelGuard aGuard( *this ); uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess; if( !rxAccess.is() && m_pData->m_pObjectShell.Is() ) rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell ); if( rxAccess.is() ) rxAccess->addModule( LibraryName, ModuleName, Language, Source ); } /**___________________________________________________________________________________________________ @seealso XStarBasicAccess */ void SAL_CALL SfxBaseModel::addDialog( const ::rtl::OUString& LibraryName, const ::rtl::OUString& DialogName, const ::com::sun::star::uno::Sequence< sal_Int8 >& Data ) throw(NOSUCHELEMENTEXCEPTION, uno::RuntimeException) { SfxModelGuard aGuard( *this ); uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess; if( !rxAccess.is() && m_pData->m_pObjectShell.Is() ) rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell ); if( rxAccess.is() ) rxAccess->addDialog( LibraryName, DialogName, Data ); } //________________________________________________________________________________________________________ // XChild //________________________________________________________________________________________________________ uno::Reference< uno::XInterface > SAL_CALL SfxBaseModel::getParent() throw( uno::RuntimeException ) { SfxModelGuard aGuard( *this ); return m_pData->m_xParent; } //________________________________________________________________________________________________________ // XChild //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::setParent(const uno::Reference< uno::XInterface >& Parent) throw(NOSUPPORTEXCEPTION, uno::RuntimeException) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); m_pData->m_xParent = Parent; } //________________________________________________________________________________________________________ // XChild //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::dispose() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); if ( !m_pData->m_bClosed ) { // gracefully accept wrong dispose calls instead of close call // and try to make it work (may be really disposed later!) try { close( sal_True ); } catch ( com::sun::star::util::CloseVetoException& ) { } return; } if ( m_pData->m_pStorageModifyListen.is() ) { m_pData->m_pStorageModifyListen->dispose(); m_pData->m_pStorageModifyListen = NULL; } if ( m_pData->m_pDocumentUndoManager.is() ) { m_pData->m_pDocumentUndoManager->disposing(); m_pData->m_pDocumentUndoManager = NULL; } lang::EventObject aEvent( (frame::XModel *)this ); m_pData->m_aInterfaceContainer.disposeAndClear( aEvent ); if ( m_pData->m_xDocumentInfo.is() ) { // as long as an SfxObjectShell is assigned to an SfxBaseModel it is still existing here // so we can't dispose the shared DocumentInfoObject here // uno::Reference < lang::XComponent > xComp( m_pData->m_xDocumentInfo, uno::UNO_QUERY ); // xComp->dispose(); m_pData->m_xDocumentInfo = 0; } m_pData->m_xDocumentProperties.clear(); m_pData->m_xDocumentMetadata.clear(); EndListening( *m_pData->m_pObjectShell ); m_pData->m_xCurrent = uno::Reference< frame::XController > (); m_pData->m_seqControllers = uno::Sequence< uno::Reference< frame::XController > > () ; // m_pData member must be set to zero before 0delete is called to // force disposed exception whenever someone tries to access our // instance while in the dtor. IMPL_SfxBaseModel_DataContainer* pData = m_pData; m_pData = 0; delete pData; } //________________________________________________________________________________________________________ // XChild //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::addEventListener( const uno::Reference< XEVENTLISTENER >& aListener ) throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XEVENTLISTENER >*)0), aListener ); } //________________________________________________________________________________________________________ // XChild //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::removeEventListener( const uno::Reference< XEVENTLISTENER >& aListener ) throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XEVENTLISTENER >*)0), aListener ); } //________________________________________________________________________________________________________ // document::XDocumentInfoSupplier //________________________________________________________________________________________________________ uno::Reference< document::XDocumentInfo > SAL_CALL SfxBaseModel::getDocumentInfo() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); if ( !m_pData->m_xDocumentInfo.is() ) { // WARNING: this will only work if (when loading a document) the // document meta-data has already been read and completely written // into the XDocumentProperties at this point // ==> DO NOT call getDocumentInfo before document info has been read! uno::Reference< document::XDocumentInfo > xDocInfo = new SfxDocumentInfoObject; uno::Reference< document::XDocumentProperties > xDocProps = getDocumentProperties(); uno::Sequence< uno::Any > args(1); args[0] <<= xDocProps; uno::Reference< lang::XInitialization > xInit( xDocInfo, uno::UNO_QUERY_THROW); try { xInit->initialize(args); ((SfxBaseModel*)this)->m_pData->m_xDocumentInfo = xDocInfo; } catch (uno::RuntimeException &) { throw; } catch (uno::Exception & e) { throw lang::WrappedTargetRuntimeException(::rtl::OUString::createFromAscii( "SfxBaseModel::getDocumentInfo: cannot initialize"), *this, uno::makeAny(e)); } try { rtl::OUString aName = rtl::OUString::createFromAscii("MediaType"); uno::Reference < beans::XPropertySet > xSet( getDocumentStorage(), uno::UNO_QUERY ); uno::Any aMediaType = xSet->getPropertyValue( aName ); uno::Reference < beans::XPropertySet > xDocSet( m_pData->m_xDocumentInfo, uno::UNO_QUERY ); xDocSet->setPropertyValue( aName, aMediaType ); } catch (uno::Exception &) { //ignore } } return m_pData->m_xDocumentInfo; } // document::XDocumentPropertiesSupplier: uno::Reference< document::XDocumentProperties > SAL_CALL SfxBaseModel::getDocumentProperties() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); if ( !m_pData->m_xDocumentProperties.is() ) { uno::Reference< lang::XInitialization > xDocProps( ::comphelper::getProcessServiceFactory()->createInstance( DEFINE_CONST_UNICODE("com.sun.star.document.DocumentProperties") ), uno::UNO_QUERY_THROW); // xDocProps->initialize(uno::Sequence()); m_pData->m_xDocumentProperties.set(xDocProps, uno::UNO_QUERY_THROW); uno::Reference xMB(m_pData->m_xDocumentProperties, uno::UNO_QUERY_THROW); xMB->addModifyListener(new SfxDocInfoListener_Impl(*m_pData->m_pObjectShell)); } return m_pData->m_xDocumentProperties; } //________________________________________________________________________________________________________ // XEVENTLISTENER //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::disposing( const lang::EventObject& aObject ) throw(::com::sun::star::uno::RuntimeException) { ::vos::OGuard aGuard( Application::GetSolarMutex() ); if ( impl_isDisposed() ) return; uno::Reference< XMODIFYLISTENER > xMod( aObject.Source, uno::UNO_QUERY ); uno::Reference< XEVENTLISTENER > xListener( aObject.Source, uno::UNO_QUERY ); uno::Reference< XDOCEVENTLISTENER > xDocListener( aObject.Source, uno::UNO_QUERY ); if ( xMod.is() ) m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0), xMod ); else if ( xListener.is() ) m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XEVENTLISTENER >*)0), xListener ); else if ( xDocListener.is() ) m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0), xDocListener ); } //________________________________________________________________________________________________________ // frame::XModel //________________________________________________________________________________________________________ sal_Bool SAL_CALL SfxBaseModel::attachResource( const ::rtl::OUString& rURL , const uno::Sequence< beans::PropertyValue >& rArgs ) throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); if ( rURL.getLength() == 0 && rArgs.getLength() == 1 && rArgs[0].Name.equalsAscii( "SetEmbedded" ) ) { // allows to set a windowless document to EMBEDDED state // but _only_ before load() or initNew() methods if ( m_pData->m_pObjectShell.Is() && !m_pData->m_pObjectShell->GetMedium() ) { sal_Bool bEmb = sal_Bool(); if ( ( rArgs[0].Value >>= bEmb ) && bEmb ) m_pData->m_pObjectShell->SetCreateMode_Impl( SFX_CREATE_MODE_EMBEDDED ); } return sal_True; } if ( m_pData->m_pObjectShell.Is() ) { m_pData->m_sURL = rURL; SfxObjectShell* pObjectShell = m_pData->m_pObjectShell; ::comphelper::NamedValueCollection aArgs( rArgs ); Sequence< sal_Int32 > aWinExtent; if ( ( aArgs.get( "WinExtent" ) >>= aWinExtent )&& ( aWinExtent.getLength() == 4 ) ) { Rectangle aVisArea( aWinExtent[0], aWinExtent[1], aWinExtent[2], aWinExtent[3] ); aVisArea = OutputDevice::LogicToLogic( aVisArea, MAP_100TH_MM, pObjectShell->GetMapUnit() ); pObjectShell->SetVisArea( aVisArea ); } sal_Bool bBreakMacroSign = sal_False; if ( aArgs.get( "BreakMacroSignature" ) >>= bBreakMacroSign ) { pObjectShell->BreakMacroSign_Impl( bBreakMacroSign ); } aArgs.remove( "WinExtent" ); aArgs.remove( "BreakMacroSignature" ); aArgs.remove( "Stream" ); aArgs.remove( "InputStream" ); aArgs.remove( "URL" ); aArgs.remove( "Frame" ); aArgs.remove( "Password" ); aArgs.remove( "EncryptionData" ); // TODO/LATER: all the parameters that are accepted by ItemSet of the DocShell must be removed here m_pData->m_seqArguments = aArgs.getPropertyValues(); SfxMedium* pMedium = pObjectShell->GetMedium(); if ( pMedium ) { SfxAllItemSet aSet( pObjectShell->GetPool() ); TransformParameters( SID_OPENDOC, rArgs, aSet ); // the arguments are not allowed to reach the medium aSet.ClearItem( SID_FILE_NAME ); aSet.ClearItem( SID_FILLFRAME ); pMedium->GetItemSet()->Put( aSet ); SFX_ITEMSET_ARG( &aSet, pItem, SfxStringItem, SID_FILTER_NAME, sal_False ); if ( pItem ) pMedium->SetFilter( pObjectShell->GetFactory().GetFilterContainer()->GetFilter4FilterName( pItem->GetValue() ) ); SFX_ITEMSET_ARG( &aSet, pTitleItem, SfxStringItem, SID_DOCINFO_TITLE, sal_False ); if ( pTitleItem ) { SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pObjectShell ); if ( pFrame ) pFrame->UpdateTitle(); } } } return sal_True ; } //________________________________________________________________________________________________________ // frame::XModel //________________________________________________________________________________________________________ ::rtl::OUString SAL_CALL SfxBaseModel::getURL() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); return m_pData->m_sURL ; } //________________________________________________________________________________________________________ // frame::XModel //________________________________________________________________________________________________________ uno::Sequence< beans::PropertyValue > SAL_CALL SfxBaseModel::getArgs() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell.Is() ) { uno::Sequence< beans::PropertyValue > seqArgsNew; uno::Sequence< beans::PropertyValue > seqArgsOld; SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() ); // we need to know which properties are supported by the transformer // hopefully it is a temporary solution, I guess nonconvertable properties // should not be supported so then there will be only ItemSet from medium TransformItems( SID_OPENDOC, *(m_pData->m_pObjectShell->GetMedium()->GetItemSet()), seqArgsNew ); TransformParameters( SID_OPENDOC, m_pData->m_seqArguments, aSet ); TransformItems( SID_OPENDOC, aSet, seqArgsOld ); sal_Int32 nOrgLength = m_pData->m_seqArguments.getLength(); sal_Int32 nOldLength = seqArgsOld.getLength(); sal_Int32 nNewLength = seqArgsNew.getLength(); // "WinExtent" property should be updated always. // We can store it now to overwrite an old value // since it is not from ItemSet Rectangle aTmpRect = m_pData->m_pObjectShell->GetVisArea( ASPECT_CONTENT ); aTmpRect = OutputDevice::LogicToLogic( aTmpRect, m_pData->m_pObjectShell->GetMapUnit(), MAP_100TH_MM ); Sequence< sal_Int32 > aRectSeq(4); aRectSeq[0] = aTmpRect.Left(); aRectSeq[1] = aTmpRect.Top(); aRectSeq[2] = aTmpRect.Right(); aRectSeq[3] = aTmpRect.Bottom(); seqArgsNew.realloc( ++nNewLength ); seqArgsNew[ nNewLength - 1 ].Name = ::rtl::OUString::createFromAscii( "WinExtent" ); seqArgsNew[ nNewLength - 1 ].Value <<= aRectSeq; if ( m_pData->m_aPreusedFilterName.getLength() ) { seqArgsNew.realloc( ++nNewLength ); seqArgsNew[ nNewLength - 1 ].Name = ::rtl::OUString::createFromAscii( "PreusedFilterName" ); seqArgsNew[ nNewLength - 1 ].Value <<= m_pData->m_aPreusedFilterName; } SfxViewFrame* pFrame = SfxViewFrame::GetFirst( m_pData->m_pObjectShell ); if ( pFrame ) { SvBorder aBorder = pFrame->GetBorderPixelImpl( pFrame->GetViewShell() ); Sequence< sal_Int32 > aBorderSeq(4); aBorderSeq[0] = aBorder.Left(); aBorderSeq[1] = aBorder.Top(); aBorderSeq[2] = aBorder.Right(); aBorderSeq[3] = aBorder.Bottom(); seqArgsNew.realloc( ++nNewLength ); seqArgsNew[ nNewLength - 1 ].Name = ::rtl::OUString::createFromAscii( "DocumentBorder" ); seqArgsNew[ nNewLength - 1 ].Value <<= aBorderSeq; } // only the values that are not supported by the ItemSet must be cached here uno::Sequence< beans::PropertyValue > aFinalCache; sal_Int32 nFinalLength = 0; for ( sal_Int32 nOrg = 0; nOrg < nOrgLength; nOrg++ ) { sal_Int32 nOldInd = 0; while ( nOldInd < nOldLength ) { if ( m_pData->m_seqArguments[nOrg].Name.equals( seqArgsOld[nOldInd].Name ) ) break; nOldInd++; } if ( nOldInd == nOldLength ) { // the entity with this name should be new for seqArgsNew // since it is not supported by transformer seqArgsNew.realloc( ++nNewLength ); seqArgsNew[ nNewLength - 1 ] = m_pData->m_seqArguments[nOrg]; aFinalCache.realloc( ++nFinalLength ); aFinalCache[ nFinalLength - 1 ] = m_pData->m_seqArguments[nOrg]; } } m_pData->m_seqArguments = aFinalCache; return seqArgsNew; } return m_pData->m_seqArguments; } //________________________________________________________________________________________________________ // frame::XModel //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::connectController( const uno::Reference< frame::XController >& xController ) throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); OSL_PRECOND( xController.is(), "SfxBaseModel::connectController: invalid controller!" ); if ( !xController.is() ) return; sal_uInt32 nOldCount = m_pData->m_seqControllers.getLength(); uno::Sequence< uno::Reference< frame::XController > > aNewSeq( nOldCount + 1 ); for ( sal_uInt32 n = 0; n < nOldCount; n++ ) aNewSeq.getArray()[n] = m_pData->m_seqControllers.getConstArray()[n]; aNewSeq.getArray()[nOldCount] = xController; m_pData->m_seqControllers = aNewSeq; if ( m_pData->m_seqControllers.getLength() == 1 ) { SfxViewFrame* pViewFrame = SfxViewFrame::Get( xController, GetObjectShell() ); ENSURE_OR_THROW( pViewFrame, "SFX document without SFX view!?" ); pViewFrame->UpdateDocument_Impl(); const String sDocumentURL = GetObjectShell()->GetMedium()->GetName(); if ( sDocumentURL.Len() ) SFX_APP()->Broadcast( SfxStringHint( SID_OPENURL, sDocumentURL ) ); } } //________________________________________________________________________________________________________ // frame::XModel //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::disconnectController( const uno::Reference< frame::XController >& xController ) throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); sal_uInt32 nOldCount = m_pData->m_seqControllers.getLength(); if ( !nOldCount ) return; uno::Sequence< uno::Reference< frame::XController > > aNewSeq( nOldCount - 1 ); for ( sal_uInt32 nOld = 0, nNew = 0; nOld < nOldCount; ++nOld ) { if ( xController != m_pData->m_seqControllers.getConstArray()[nOld] ) { aNewSeq.getArray()[nNew] = m_pData->m_seqControllers.getConstArray()[nOld]; ++nNew; } } m_pData->m_seqControllers = aNewSeq; if ( xController == m_pData->m_xCurrent ) m_pData->m_xCurrent = uno::Reference< frame::XController > (); } namespace { typedef ::cppu::WeakImplHelper1< XUndoAction > ControllerLockUndoAction_Base; class ControllerLockUndoAction : public ControllerLockUndoAction_Base { public: ControllerLockUndoAction( const Reference< XModel >& i_model, const bool i_undoIsUnlock ) :m_xModel( i_model ) ,m_bUndoIsUnlock( i_undoIsUnlock ) { } // XUndoAction virtual ::rtl::OUString SAL_CALL getTitle() throw (RuntimeException); virtual void SAL_CALL undo( ) throw (UndoFailedException, RuntimeException); virtual void SAL_CALL redo( ) throw (UndoFailedException, RuntimeException); private: const Reference< XModel > m_xModel; const bool m_bUndoIsUnlock; }; ::rtl::OUString SAL_CALL ControllerLockUndoAction::getTitle() throw (RuntimeException) { // this action is intended to be used within an UndoContext only, so nobody will ever see this title ... return ::rtl::OUString(); } void SAL_CALL ControllerLockUndoAction::undo( ) throw (UndoFailedException, RuntimeException) { if ( m_bUndoIsUnlock ) m_xModel->unlockControllers(); else m_xModel->lockControllers(); } void SAL_CALL ControllerLockUndoAction::redo( ) throw (UndoFailedException, RuntimeException) { if ( m_bUndoIsUnlock ) m_xModel->lockControllers(); else m_xModel->unlockControllers(); } } //________________________________________________________________________________________________________ // frame::XModel //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::lockControllers() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); ++m_pData->m_nControllerLockCount ; if ( m_pData->m_pDocumentUndoManager.is() && m_pData->m_pDocumentUndoManager->isInContext() && !m_pData->m_pDocumentUndoManager->isLocked() ) { m_pData->m_pDocumentUndoManager->addUndoAction( new ControllerLockUndoAction( this, true ) ); } } //________________________________________________________________________________________________________ // frame::XModel //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::unlockControllers() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); --m_pData->m_nControllerLockCount ; if ( m_pData->m_pDocumentUndoManager.is() && m_pData->m_pDocumentUndoManager->isInContext() && !m_pData->m_pDocumentUndoManager->isLocked() ) { m_pData->m_pDocumentUndoManager->addUndoAction( new ControllerLockUndoAction( this, false ) ); } } //________________________________________________________________________________________________________ // frame::XModel //________________________________________________________________________________________________________ sal_Bool SAL_CALL SfxBaseModel::hasControllersLocked() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); return ( m_pData->m_nControllerLockCount != 0 ) ; } //________________________________________________________________________________________________________ // frame::XModel //________________________________________________________________________________________________________ uno::Reference< frame::XController > SAL_CALL SfxBaseModel::getCurrentController() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); // get the last active controller of this model if ( m_pData->m_xCurrent.is() ) return m_pData->m_xCurrent; // get the first controller of this model return m_pData->m_seqControllers.getLength() ? m_pData->m_seqControllers.getConstArray()[0] : m_pData->m_xCurrent; } //________________________________________________________________________________________________________ // frame::XModel //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::setCurrentController( const uno::Reference< frame::XController >& xCurrentController ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); m_pData->m_xCurrent = xCurrentController; } //________________________________________________________________________________________________________ // frame::XModel //________________________________________________________________________________________________________ uno::Reference< uno::XInterface > SAL_CALL SfxBaseModel::getCurrentSelection() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); uno::Reference< uno::XInterface > xReturn; uno::Reference< frame::XController > xController = getCurrentController() ; if ( xController.is() ) { uno::Reference< view::XSelectionSupplier > xDocView( xController, uno::UNO_QUERY ); if ( xDocView.is() ) { uno::Any xSel = xDocView->getSelection(); xSel >>= xReturn ; } } return xReturn ; } //________________________________________________________________________________________________________ // XModifiable2 //________________________________________________________________________________________________________ sal_Bool SAL_CALL SfxBaseModel::disableSetModified() throw (::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); if ( !m_pData->m_pObjectShell.Is() ) throw uno::RuntimeException(); sal_Bool bResult = m_pData->m_pObjectShell->IsEnableSetModified(); m_pData->m_pObjectShell->EnableSetModified( sal_False ); return bResult; } sal_Bool SAL_CALL SfxBaseModel::enableSetModified() throw (::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); if ( !m_pData->m_pObjectShell.Is() ) throw uno::RuntimeException(); sal_Bool bResult = m_pData->m_pObjectShell->IsEnableSetModified(); m_pData->m_pObjectShell->EnableSetModified( sal_True ); return bResult; } sal_Bool SAL_CALL SfxBaseModel::isSetModifiedEnabled() throw (::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); if ( !m_pData->m_pObjectShell.Is() ) throw uno::RuntimeException(); return m_pData->m_pObjectShell->IsEnableSetModified(); } //________________________________________________________________________________________________________ // XModifiable //________________________________________________________________________________________________________ sal_Bool SAL_CALL SfxBaseModel::isModified() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); return m_pData->m_pObjectShell.Is() ? m_pData->m_pObjectShell->IsModified() : sal_False; } //________________________________________________________________________________________________________ // XModifiable //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::setModified( sal_Bool bModified ) throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell.Is() ) m_pData->m_pObjectShell->SetModified(bModified); } //________________________________________________________________________________________________________ // XModifiable //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::addModifyListener(const uno::Reference< XMODIFYLISTENER >& xListener) throw( uno::RuntimeException ) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0),xListener ); } //________________________________________________________________________________________________________ // XModifiable //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::removeModifyListener(const uno::Reference< XMODIFYLISTENER >& xListener) throw( uno::RuntimeException ) { SfxModelGuard aGuard( *this ); m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0), xListener ); } //____________________________________________________________________________________________________ // XCloseable //____________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::close( sal_Bool bDeliverOwnership ) throw (util::CloseVetoException, uno::RuntimeException) { static ::rtl::OUString MSG_1 = ::rtl::OUString::createFromAscii("Can't close while saving."); ::vos::OGuard aGuard( Application::GetSolarMutex() ); if ( impl_isDisposed() || m_pData->m_bClosed || m_pData->m_bClosing ) return; uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) ); lang::EventObject aSource (static_cast< ::cppu::OWeakObject*>(this)); ::cppu::OInterfaceContainerHelper* pContainer = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) ); if (pContainer!=NULL) { ::cppu::OInterfaceIteratorHelper pIterator(*pContainer); while (pIterator.hasMoreElements()) { try { ((util::XCloseListener*)pIterator.next())->queryClosing( aSource, bDeliverOwnership ); } catch( uno::RuntimeException& ) { pIterator.remove(); } } } if ( m_pData->m_bSaving ) { if (bDeliverOwnership) m_pData->m_bSuicide = sal_True; throw util::CloseVetoException( MSG_1, static_cast< ::com::sun::star::util::XCloseable* >(this)); } // no own objections against closing! m_pData->m_bClosing = sal_True; pContainer = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) ); if (pContainer!=NULL) { ::cppu::OInterfaceIteratorHelper pCloseIterator(*pContainer); while (pCloseIterator.hasMoreElements()) { try { ((util::XCloseListener*)pCloseIterator.next())->notifyClosing( aSource ); } catch( uno::RuntimeException& ) { pCloseIterator.remove(); } } } m_pData->m_bClosed = sal_True; m_pData->m_bClosing = sal_False; dispose(); } //____________________________________________________________________________________________________ // XCloseBroadcaster //____________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::addCloseListener( const uno::Reference< XCLOSELISTENER >& xListener ) throw (uno::RuntimeException) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XCLOSELISTENER >*)0), xListener ); } //____________________________________________________________________________________________________ // XCloseBroadcaster //____________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::removeCloseListener( const uno::Reference< XCLOSELISTENER >& xListener ) throw (uno::RuntimeException) { SfxModelGuard aGuard( *this ); m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XCLOSELISTENER >*)0), xListener ); } //________________________________________________________________________________________________________ // XPrintable //________________________________________________________________________________________________________ uno::Sequence< beans::PropertyValue > SAL_CALL SfxBaseModel::getPrinter() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); if ( impl_getPrintHelper() ) return m_pData->m_xPrintable->getPrinter(); else return uno::Sequence< beans::PropertyValue >(); } void SAL_CALL SfxBaseModel::setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); if ( impl_getPrintHelper() ) m_pData->m_xPrintable->setPrinter( rPrinter ); } void SAL_CALL SfxBaseModel::print(const uno::Sequence< beans::PropertyValue >& rOptions) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); if ( impl_getPrintHelper() ) m_pData->m_xPrintable->print( rOptions ); } //________________________________________________________________________________________________________ // XStorable //________________________________________________________________________________________________________ sal_Bool SAL_CALL SfxBaseModel::hasLocation() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); return m_pData->m_pObjectShell.Is() ? m_pData->m_pObjectShell->HasName() : sal_False; } //________________________________________________________________________________________________________ // XStorable //________________________________________________________________________________________________________ ::rtl::OUString SAL_CALL SfxBaseModel::getLocation() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell.Is() ) { // TODO/LATER: is it correct that the shared document returns shared file location? if ( m_pData->m_pObjectShell->IsDocShared() ) return m_pData->m_pObjectShell->GetSharedFileURL(); else return ::rtl::OUString(m_pData->m_pObjectShell->GetMedium()->GetName()); } return m_pData->m_sURL; } //________________________________________________________________________________________________________ // XStorable //________________________________________________________________________________________________________ sal_Bool SAL_CALL SfxBaseModel::isReadonly() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); return m_pData->m_pObjectShell.Is() ? m_pData->m_pObjectShell->IsReadOnly() : sal_True; } //________________________________________________________________________________________________________ // XStorable2 //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::storeSelf( const uno::Sequence< beans::PropertyValue >& aSeqArgs ) throw ( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException ) { RTL_LOGFILE_PRODUCT_CONTEXT( aPerfLog, "PERFORMANCE - SfxBaseModel::storeSelf" ); SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell.Is() ) { m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "storeSelf" ) ) ); SfxSaveGuard aSaveGuard(this, m_pData, sal_False); for ( sal_Int32 nInd = 0; nInd < aSeqArgs.getLength(); nInd++ ) { // check that only acceptable parameters are provided here if ( !aSeqArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VersionComment" ) ) ) && !aSeqArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Author" ) ) ) && !aSeqArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InteractionHandler" ) ) ) && !aSeqArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StatusIndicator" ) ) ) && !aSeqArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FailOnWarning" ) ) ) ) { m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "unexpected parameter for storeSelf, might be no problem if SaveAs is executed." ) ) ); m_pData->m_pObjectShell->StoreLog(); ::rtl::OUString aMessage( RTL_CONSTASCII_USTRINGPARAM( "Unexpected MediaDescriptor parameter: " ) ); aMessage += aSeqArgs[nInd].Name; throw lang::IllegalArgumentException( aMessage, uno::Reference< uno::XInterface >(), 1 ); } } SfxAllItemSet *pParams = new SfxAllItemSet( SFX_APP()->GetPool() ); TransformParameters( SID_SAVEDOC, aSeqArgs, *pParams ); SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVEDOC, GlobalEventConfig::GetEventName(STR_EVENT_SAVEDOC), m_pData->m_pObjectShell ) ); sal_Bool bRet = sal_False; // TODO/LATER: let the embedded case of saving be handled more careful if ( m_pData->m_pObjectShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ) { // If this is an embedded object that has no URL based location it should be stored to own storage. // An embedded object can have a location based on URL in case it is a link, then it should be // stored in normal way. if ( !hasLocation() || getLocation().compareToAscii( "private:", 8 ) == 0 ) { // actually in this very rare case only UI parameters have sense // TODO/LATER: should be done later, after integration of sb19 bRet = m_pData->m_pObjectShell->DoSave() && m_pData->m_pObjectShell->DoSaveCompleted(); } else { bRet = m_pData->m_pObjectShell->Save_Impl( pParams ); } } else bRet = m_pData->m_pObjectShell->Save_Impl( pParams ); DELETEZ( pParams ); sal_uInt32 nErrCode = m_pData->m_pObjectShell->GetError() ? m_pData->m_pObjectShell->GetError() : ERRCODE_IO_CANTWRITE; m_pData->m_pObjectShell->ResetError(); if ( bRet ) { m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "successful saving." ) ) ); m_pData->m_aPreusedFilterName = GetMediumFilterName_Impl(); SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVEDOCDONE, GlobalEventConfig::GetEventName(STR_EVENT_SAVEDOCDONE), m_pData->m_pObjectShell ) ); } else { m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing failed!" ) ) ); m_pData->m_pObjectShell->StoreLog(); // write the contents of the logger to the file SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVEDOCFAILED, GlobalEventConfig::GetEventName(STR_EVENT_SAVEDOCFAILED), m_pData->m_pObjectShell ) ); throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), nErrCode ); } } } //________________________________________________________________________________________________________ // XStorable //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::store() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) { storeSelf( uno::Sequence< beans::PropertyValue >() ); } //________________________________________________________________________________________________________ // XStorable //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::storeAsURL( const ::rtl::OUString& rURL , const uno::Sequence< beans::PropertyValue >& rArgs ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) { RTL_LOGFILE_PRODUCT_CONTEXT( aPerfLog, "PERFORMANCE - SfxBaseModel::storeAsURL" ); SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell.Is() ) { m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "storeAsURL" ) ) ); SfxSaveGuard aSaveGuard(this, m_pData, sal_False); impl_store( rURL, rArgs, sal_False ); uno::Sequence< beans::PropertyValue > aSequence ; TransformItems( SID_OPENDOC, *m_pData->m_pObjectShell->GetMedium()->GetItemSet(), aSequence ); attachResource( rURL, aSequence ); #if OSL_DEBUG_LEVEL > 0 SFX_ITEMSET_ARG( m_pData->m_pObjectShell->GetMedium()->GetItemSet(), pPasswdItem, SfxStringItem, SID_PASSWORD, sal_False); OSL_ENSURE( !pPasswdItem, "There should be no Password property in the document MediaDescriptor!" ); #endif } } //________________________________________________________________________________________________________ // XUndoManagerSupplier //________________________________________________________________________________________________________ Reference< XUndoManager > SAL_CALL SfxBaseModel::getUndoManager( ) throw (RuntimeException) { SfxModelGuard aGuard( *this ); if ( !m_pData->m_pDocumentUndoManager.is() ) m_pData->m_pDocumentUndoManager.set( new ::sfx2::DocumentUndoManager( *this ) ); return m_pData->m_pDocumentUndoManager.get(); } //________________________________________________________________________________________________________ // XStorable //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::storeToURL( const ::rtl::OUString& rURL , const uno::Sequence< beans::PropertyValue >& rArgs ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell.Is() ) { m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "storeToURL" ) ) ); SfxSaveGuard aSaveGuard(this, m_pData, sal_False); impl_store( rURL, rArgs, sal_True ); } } ::sal_Bool SAL_CALL SfxBaseModel::wasModifiedSinceLastSave() throw ( RuntimeException ) { SfxModelGuard aGuard( *this ); return m_pData->m_bModifiedSinceLastSave; } void SAL_CALL SfxBaseModel::storeToRecoveryFile( const ::rtl::OUString& i_TargetLocation, const Sequence< PropertyValue >& i_MediaDescriptor ) throw ( RuntimeException, IOException, WrappedTargetException ) { SfxModelGuard aGuard( *this ); // delegate SfxSaveGuard aSaveGuard( this, m_pData, sal_False ); impl_store( i_TargetLocation, i_MediaDescriptor, sal_True ); // no need for subsequent calls to storeToRecoveryFile, unless we're modified, again m_pData->m_bModifiedSinceLastSave = sal_False; } void SAL_CALL SfxBaseModel::recoverFromFile( const ::rtl::OUString& i_SourceLocation, const ::rtl::OUString& i_SalvagedFile, const Sequence< PropertyValue >& i_MediaDescriptor ) throw ( RuntimeException, IOException, WrappedTargetException ) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); // delegate to our "load" method ::comphelper::NamedValueCollection aMediaDescriptor( i_MediaDescriptor ); // our load implementation expects the SalvagedFile to be in the media descriptor OSL_ENSURE( !aMediaDescriptor.has( "SalvagedFile" ) || ( aMediaDescriptor.getOrDefault( "SalvagedFile", ::rtl::OUString() ) == i_SalvagedFile ), "SfxBaseModel::recoverFromFile: inconsistent information!" ); aMediaDescriptor.put( "SalvagedFile", i_SalvagedFile ); // similar for the to-be-loaded file OSL_ENSURE( !aMediaDescriptor.has( "URL" ) || ( aMediaDescriptor.getOrDefault( "URL", ::rtl::OUString() ) == i_SourceLocation ), "SfxBaseModel::recoverFromFile: inconsistent information!" ); aMediaDescriptor.put( "URL", i_SourceLocation ); load( aMediaDescriptor.getPropertyValues() ); // Note: The XDocumentRecovery interface specification requires us to do an attachResource after loading. // However, we will not do this here, as we know that our load implementation (respectively some method // called from there) already did so. // In particular, the load process might already have modified some elements of the media // descriptor, for instance the MacroExecMode (in case the user was involved to decide about it), and we do // not want to overwrite it with the "old" elements passed to this method here. } //________________________________________________________________________________________________________ // XLoadable //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::initNew() throw (::com::sun::star::frame::DoubleInitializationException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, ::com::sun::star::uno::Exception) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); if ( IsInitialized() ) throw ::com::sun::star::frame::DoubleInitializationException( ::rtl::OUString(), *this ); // the object shell should exist always DBG_ASSERT( m_pData->m_pObjectShell.Is(), "Model is useless without an ObjectShell" ); if ( m_pData->m_pObjectShell.Is() ) { if( m_pData->m_pObjectShell->GetMedium() ) throw DOUBLEINITIALIZATIONEXCEPTION(); sal_Bool bRes = m_pData->m_pObjectShell->DoInitNew( NULL ); sal_uInt32 nErrCode = m_pData->m_pObjectShell->GetError() ? m_pData->m_pObjectShell->GetError() : ERRCODE_IO_CANTCREATE; m_pData->m_pObjectShell->ResetError(); if ( !bRes ) throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), nErrCode ); } } //________________________________________________________________________________________________________ // XLoadable //________________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::load( const uno::Sequence< beans::PropertyValue >& seqArguments ) throw (::com::sun::star::frame::DoubleInitializationException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, ::com::sun::star::uno::Exception) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); if ( IsInitialized() ) throw ::com::sun::star::frame::DoubleInitializationException( ::rtl::OUString(), *this ); // the object shell should exist always DBG_ASSERT( m_pData->m_pObjectShell.Is(), "Model is useless without an ObjectShell" ); if ( m_pData->m_pObjectShell.Is() ) { if( m_pData->m_pObjectShell->GetMedium() ) // if a Medium is present, the document is already initialized throw DOUBLEINITIALIZATIONEXCEPTION(); SfxMedium* pMedium = new SfxMedium( seqArguments ); String aFilterName; SFX_ITEMSET_ARG( pMedium->GetItemSet(), pFilterNameItem, SfxStringItem, SID_FILTER_NAME, sal_False ); if( pFilterNameItem ) aFilterName = pFilterNameItem->GetValue(); if( !m_pData->m_pObjectShell->GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName ) ) { // filtername is not valid delete pMedium; throw frame::IllegalArgumentIOException(); } // !TODO: currently not working //SFX_ITEMSET_ARG( pParams, pFrameItem, SfxFrameItem, SID_DOCFRAME, sal_False ); //if( pFrameItem && pFrameItem->GetFrame() ) //{ // SfxFrame* pFrame = pFrameItem->GetFrame(); // pMedium->SetLoadTargetFrame( pFrame ); //} SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False ); sal_Bool bSalvage = pSalvageItem ? sal_True : sal_False; // SFX_ITEMSET_ARG( pMedium->GetItemSet(), pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False); // sal_Bool bTemplate = pTemplateItem && pTemplateItem->GetValue(); // // does already happen in DoLoad call //m_pData->m_pObjectShell->SetActivateEvent_Impl( bTemplate ? SFX_EVENT_CREATEDOC : SFX_EVENT_OPENDOC ); // load document sal_uInt32 nError = ERRCODE_NONE; if ( !m_pData->m_pObjectShell->DoLoad(pMedium) ) nError=ERRCODE_IO_GENERAL; // QUESTION: if the following happens outside of DoLoad, something important is missing there! ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > xHandler = pMedium->GetInteractionHandler(); if( m_pData->m_pObjectShell->GetErrorCode() ) { nError = m_pData->m_pObjectShell->GetErrorCode(); if ( nError == ERRCODE_IO_BROKENPACKAGE && xHandler.is() ) { ::rtl::OUString aDocName = pMedium->GetURLObject().getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ); SFX_ITEMSET_ARG( pMedium->GetItemSet(), pRepairItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False ); if ( !pRepairItem || !pRepairItem->GetValue() ) { RequestPackageReparation aRequest( aDocName ); xHandler->handle( aRequest.GetRequest() ); if( aRequest.isApproved() ) { // broken package: try second loading and allow repair pMedium->GetItemSet()->Put( SfxBoolItem( SID_REPAIRPACKAGE, sal_True ) ); pMedium->GetItemSet()->Put( SfxBoolItem( SID_TEMPLATE, sal_True ) ); pMedium->GetItemSet()->Put( SfxStringItem( SID_DOCINFO_TITLE, aDocName ) ); // the error must be reset and the storage must be reopened in new mode pMedium->ResetError(); pMedium->CloseStorage(); m_pData->m_pObjectShell->PrepareSecondTryLoad_Impl(); if ( !m_pData->m_pObjectShell->DoLoad(pMedium) ) nError=ERRCODE_IO_GENERAL; nError = m_pData->m_pObjectShell->GetErrorCode(); } } if ( nError == ERRCODE_IO_BROKENPACKAGE ) { // repair either not allowed or not successful NotifyBrokenPackage aRequest( aDocName ); xHandler->handle( aRequest.GetRequest() ); } } } if( m_pData->m_pObjectShell->IsAbortingImport() ) nError = ERRCODE_ABORT; if( bSalvage ) { // file recovery: restore original filter SFX_ITEMSET_ARG( pMedium->GetItemSet(), pFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False ); SfxFilterMatcher& rMatcher = SFX_APP()->GetFilterMatcher(); const SfxFilter* pSetFilter = rMatcher.GetFilter4FilterName( pFilterItem->GetValue() ); pMedium->SetFilter( pSetFilter ); m_pData->m_pObjectShell->SetModified(sal_True); } // TODO/LATER: may be the mode should be retrieved from outside and the preused filter should not be set if ( m_pData->m_pObjectShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ) { SFX_ITEMSET_ARG( pMedium->GetItemSet(), pFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False ); if ( pFilterItem ) m_pData->m_aPreusedFilterName = pFilterItem->GetValue(); } if ( !nError ) nError = pMedium->GetError(); m_pData->m_pObjectShell->ResetError(); if ( nError ) { sal_Bool bSilent = sal_False; SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSilentItem, SfxBoolItem, SID_SILENT, sal_False); if( pSilentItem ) bSilent = pSilentItem->GetValue(); sal_Bool bWarning = ((nError & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK); if ( nError != ERRCODE_IO_BROKENPACKAGE && !bSilent ) { // broken package was handled already if ( SfxObjectShell::UseInteractionToHandleError( xHandler, nError ) && !bWarning ) { // abort loading (except for warnings) nError = ERRCODE_IO_ABORT; } } if ( m_pData->m_pObjectShell->GetMedium() != pMedium ) { // for whatever reason document now has another medium DBG_ERROR("Document has rejected the medium?!"); delete pMedium; } if ( !bWarning ) // #i30711# don't abort loading if it's only a warning { throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), nError ? nError : ERRCODE_IO_CANTREAD ); } } sal_Bool bHidden = sal_False; SFX_ITEMSET_ARG( pMedium->GetItemSet(), pHidItem, SfxBoolItem, SID_HIDDEN, sal_False); if ( pHidItem ) bHidden = pHidItem->GetValue(); #if OSL_DEBUG_LEVEL > 0 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pPasswdItem, SfxStringItem, SID_PASSWORD, sal_False); OSL_ENSURE( !pPasswdItem, "There should be no Password property in the document MediaDescriptor!" ); #endif // !TODO: will be done by Framework! pMedium->SetUpdatePickList( !bHidden ); } } //________________________________________________________________________________________________________ // XTransferable //________________________________________________________________________________________________________ uno::Any SAL_CALL SfxBaseModel::getTransferData( const DATAFLAVOR& aFlavor ) throw (::com::sun::star::datatransfer::UnsupportedFlavorException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); uno::Any aAny; if ( m_pData->m_pObjectShell.Is() ) { if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) { TransferableObjectDescriptor aDesc; aDesc.maClassName = m_pData->m_pObjectShell->GetClassName(); aDesc.maTypeName = aFlavor.HumanPresentableName; // TODO/LATER: ViewAspect needs to be sal_Int64 aDesc.mnViewAspect = sal::static_int_cast< sal_uInt16 >( embed::Aspects::MSOLE_CONTENT ); //TODO/LATER: status needs to become sal_Int64 aDesc.mnOle2Misc = m_pData->m_pObjectShell->GetMiscStatus(); Size aSize = m_pData->m_pObjectShell->GetVisArea().GetSize(); MapUnit aMapUnit = m_pData->m_pObjectShell->GetMapUnit(); aDesc.maSize = OutputDevice::LogicToLogic( aSize, aMapUnit, MAP_100TH_MM ); aDesc.maDragStartPos = Point(); aDesc.maDisplayName = String(); aDesc.mbCanLink = sal_False; SvMemoryStream aMemStm( 1024, 1024 ); aMemStm << aDesc; aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Tell() ); } else throw datatransfer::UnsupportedFlavorException(); } else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-embed-source;windows_formatname=\"Star EMBS\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) { try { utl::TempFile aTmp; aTmp.EnableKillingFile( sal_True ); storeToURL( aTmp.GetURL(), uno::Sequence < beans::PropertyValue >() ); SvStream* pStream = aTmp.GetStream( STREAM_READ ); const sal_uInt32 nLen = pStream->Seek( STREAM_SEEK_TO_END ); ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( nLen ); pStream->Seek( STREAM_SEEK_TO_BEGIN ); pStream->Read( aSeq.getArray(), nLen ); delete pStream; if( aSeq.getLength() ) aAny <<= aSeq; } catch ( uno::Exception& ) { } } else throw datatransfer::UnsupportedFlavorException(); } else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) { ::boost::shared_ptr pMetaFile = m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True ); if ( pMetaFile ) { SvMemoryStream aMemStm( 65535, 65535 ); aMemStm.SetVersion( SOFFICE_FILEFORMAT_CURRENT ); pMetaFile->Write( aMemStm ); aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) ); } } else throw datatransfer::UnsupportedFlavorException(); } else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) { ::boost::shared_ptr pMetaFile = m_pData->m_pObjectShell->CreatePreviewMetaFile_Impl( sal_True, sal_True ); if ( pMetaFile ) { SvMemoryStream aMemStm( 65535, 65535 ); aMemStm.SetVersion( SOFFICE_FILEFORMAT_CURRENT ); pMetaFile->Write( aMemStm ); aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) ); } } else throw datatransfer::UnsupportedFlavorException(); } else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) { ::boost::shared_ptr pMetaFile = m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True ); if ( pMetaFile ) { ::boost::shared_ptr pStream( GraphicHelper::getFormatStrFromGDI_Impl( pMetaFile.get(), CVT_EMF ) ); if ( pStream ) { pStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT ); aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pStream->GetData() ), pStream->Seek( STREAM_SEEK_TO_END ) ); } } } else if ( GraphicHelper::supportsMetaFileHandle_Impl() && aFlavor.DataType == getCppuType( (const sal_uInt64*) 0 ) ) { ::boost::shared_ptr pMetaFile = m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True ); if ( pMetaFile ) { aAny <<= reinterpret_cast< const sal_uInt64 >( GraphicHelper::getEnhMetaFileFromGDI_Impl( pMetaFile.get() ) ); } } else throw datatransfer::UnsupportedFlavorException(); } else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) { ::boost::shared_ptr pMetaFile = m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True ); if ( pMetaFile ) { ::boost::shared_ptr pStream( GraphicHelper::getFormatStrFromGDI_Impl( pMetaFile.get(), CVT_WMF ) ); if ( pStream ) { pStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT ); aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pStream->GetData() ), pStream->Seek( STREAM_SEEK_TO_END ) ); } } } else if ( GraphicHelper::supportsMetaFileHandle_Impl() && aFlavor.DataType == getCppuType( (const sal_uInt64*) 0 ) ) { // means HGLOBAL handler to memory storage containing METAFILEPICT structure ::boost::shared_ptr pMetaFile = m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True ); if ( pMetaFile ) { Size aMetaSize = pMetaFile->GetPrefSize(); aAny <<= reinterpret_cast< const sal_uInt64 >( GraphicHelper::getWinMetaFileFromGDI_Impl( pMetaFile.get(), aMetaSize ) ); } } else throw datatransfer::UnsupportedFlavorException(); } else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) { ::boost::shared_ptr pMetaFile = m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True ); if ( pMetaFile ) { ::boost::shared_ptr pStream( GraphicHelper::getFormatStrFromGDI_Impl( pMetaFile.get(), CVT_BMP ) ); if ( pStream ) { pStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT ); aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pStream->GetData() ), pStream->Seek( STREAM_SEEK_TO_END ) ); } } } else throw datatransfer::UnsupportedFlavorException(); } else if ( aFlavor.MimeType.equalsAscii( "image/png" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) { ::boost::shared_ptr pMetaFile = m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True ); if ( pMetaFile ) { ::boost::shared_ptr pStream( GraphicHelper::getFormatStrFromGDI_Impl( pMetaFile.get(), CVT_PNG ) ); if ( pStream ) { pStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT ); aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pStream->GetData() ), pStream->Seek( STREAM_SEEK_TO_END ) ); } } } else throw datatransfer::UnsupportedFlavorException(); } else throw datatransfer::UnsupportedFlavorException(); } return aAny; } //________________________________________________________________________________________________________ // XTransferable //________________________________________________________________________________________________________ uno::Sequence< DATAFLAVOR > SAL_CALL SfxBaseModel::getTransferDataFlavors() throw (::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); sal_Int32 nSuppFlavors = GraphicHelper::supportsMetaFileHandle_Impl() ? 10 : 8; uno::Sequence< DATAFLAVOR > aFlavorSeq( nSuppFlavors ); aFlavorSeq[0].MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) ); aFlavorSeq[0].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GDIMetaFile" ) ); aFlavorSeq[0].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 ); aFlavorSeq[1].MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) ); aFlavorSeq[1].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GDIMetaFile" ) ); aFlavorSeq[1].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 ); aFlavorSeq[2].MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) ); aFlavorSeq[2].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enhanced Windows MetaFile" ) ); aFlavorSeq[2].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 ); aFlavorSeq[3].MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) ); aFlavorSeq[3].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Windows MetaFile" ) ); aFlavorSeq[3].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 ); aFlavorSeq[4].MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" ) ); aFlavorSeq[4].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Star Object Descriptor (XML)" ) ); aFlavorSeq[4].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 ); aFlavorSeq[5].MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"" ) ); aFlavorSeq[5].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Star Embed Source (XML)" ) ); aFlavorSeq[5].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 ); aFlavorSeq[6].MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ) ); aFlavorSeq[6].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ) ); aFlavorSeq[6].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 ); aFlavorSeq[7].MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/png" ) ); aFlavorSeq[7].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PNG" ) ); aFlavorSeq[7].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 ); if ( nSuppFlavors == 10 ) { aFlavorSeq[8].MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) ); aFlavorSeq[8].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enhanced Windows MetaFile" ) ); aFlavorSeq[8].DataType = getCppuType( (const sal_uInt64*) 0 ); aFlavorSeq[9].MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) ); aFlavorSeq[9].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Windows MetaFile" ) ); aFlavorSeq[9].DataType = getCppuType( (const sal_uInt64*) 0 ); } return aFlavorSeq; } //________________________________________________________________________________________________________ // XTransferable //________________________________________________________________________________________________________ sal_Bool SAL_CALL SfxBaseModel::isDataFlavorSupported( const DATAFLAVOR& aFlavor ) throw (::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) return sal_True; } else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) return sal_True; } else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) return sal_True; else if ( GraphicHelper::supportsMetaFileHandle_Impl() && aFlavor.DataType == getCppuType( (const sal_uInt64*) 0 ) ) return sal_True; } else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) return sal_True; else if ( GraphicHelper::supportsMetaFileHandle_Impl() && aFlavor.DataType == getCppuType( (const sal_uInt64*) 0 ) ) return sal_True; } else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) return sal_True; } else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-embed-source;windows_formatname=\"Star EMBS\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) return sal_True; } else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) return sal_True; } else if ( aFlavor.MimeType.equalsAscii( "image/png" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) return sal_True; } return sal_False; } //-------------------------------------------------------------------------------------------------------- // XEventsSupplier //-------------------------------------------------------------------------------------------------------- uno::Reference< container::XNameReplace > SAL_CALL SfxBaseModel::getEvents() throw( uno::RuntimeException ) { SfxModelGuard aGuard( *this ); if ( ! m_pData->m_xEvents.is() ) { m_pData->m_xEvents = new SfxEvents_Impl( m_pData->m_pObjectShell, this ); } return m_pData->m_xEvents; } //-------------------------------------------------------------------------------------------------------- // XEmbeddedScripts //-------------------------------------------------------------------------------------------------------- uno::Reference< script::XStorageBasedLibraryContainer > SAL_CALL SfxBaseModel::getBasicLibraries() throw (RuntimeException) { SfxModelGuard aGuard( *this ); uno::Reference< script::XStorageBasedLibraryContainer > xBasicLibraries; if ( m_pData->m_pObjectShell ) xBasicLibraries.set( m_pData->m_pObjectShell->GetBasicContainer(), UNO_QUERY_THROW ); return xBasicLibraries; } uno::Reference< script::XStorageBasedLibraryContainer > SAL_CALL SfxBaseModel::getDialogLibraries() throw (RuntimeException) { SfxModelGuard aGuard( *this ); uno::Reference< script::XStorageBasedLibraryContainer > xDialogLibraries; if ( m_pData->m_pObjectShell ) xDialogLibraries.set( m_pData->m_pObjectShell->GetDialogContainer(), UNO_QUERY_THROW ); return xDialogLibraries; } ::sal_Bool SAL_CALL SfxBaseModel::getAllowMacroExecution() throw (RuntimeException) { SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell ) return m_pData->m_pObjectShell->AdjustMacroMode( String(), false ); return sal_False; } //-------------------------------------------------------------------------------------------------------- // XScriptInvocationContext //-------------------------------------------------------------------------------------------------------- Reference< document::XEmbeddedScripts > SAL_CALL SfxBaseModel::getScriptContainer() throw (RuntimeException) { SfxModelGuard aGuard( *this ); Reference< document::XEmbeddedScripts > xDocumentScripts; try { Reference< frame::XModel > xDocument( this ); xDocumentScripts.set( xDocument, uno::UNO_QUERY ); while ( !xDocumentScripts.is() && xDocument.is() ) { Reference< container::XChild > xDocAsChild( xDocument, uno::UNO_QUERY ); if ( !xDocAsChild.is() ) { xDocument = NULL; break; } xDocument.set( xDocAsChild->getParent(), uno::UNO_QUERY ); xDocumentScripts.set( xDocument, uno::UNO_QUERY ); } } catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); xDocumentScripts = NULL; } return xDocumentScripts; } //-------------------------------------------------------------------------------------------------------- // XEventBroadcaster //-------------------------------------------------------------------------------------------------------- void SAL_CALL SfxBaseModel::addEventListener( const uno::Reference< XDOCEVENTLISTENER >& aListener ) throw( uno::RuntimeException ) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0), aListener ); } //-------------------------------------------------------------------------------------------------------- // XEventBroadcaster //-------------------------------------------------------------------------------------------------------- void SAL_CALL SfxBaseModel::removeEventListener( const uno::Reference< XDOCEVENTLISTENER >& aListener ) throw( uno::RuntimeException ) { SfxModelGuard aGuard( *this ); m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0), aListener ); } //-------------------------------------------------------------------------------------------------------- // XDocumentEventBroadcaster //-------------------------------------------------------------------------------------------------------- // --------------------------------- void SAL_CALL SfxBaseModel::addDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& aListener ) throw ( uno::RuntimeException ) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< document::XDocumentEventListener >*)0), aListener ); } // --------------------------------- void SAL_CALL SfxBaseModel::removeDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& aListener ) throw ( uno::RuntimeException ) { SfxModelGuard aGuard( *this ); m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< document::XDocumentEventListener >*)0), aListener ); } // --------------------------------- void SAL_CALL SfxBaseModel::notifyDocumentEvent( const ::rtl::OUString&, const uno::Reference< frame::XController2 >&, const uno::Any& ) throw ( lang::IllegalArgumentException, lang::NoSupportException, uno::RuntimeException ) { throw lang::NoSupportException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SfxBaseModel controls all the sent notifications itself!" ) ), uno::Reference< uno::XInterface >() ); } //________________________________________________________________________________________________________ // SfxListener //________________________________________________________________________________________________________ void addTitle_Impl( Sequence < ::com::sun::star::beans::PropertyValue >& rSeq, const ::rtl::OUString& rTitle ) { sal_Int32 nCount = rSeq.getLength(); sal_Int32 nArg; for ( nArg = 0; nArg < nCount; nArg++ ) { ::com::sun::star::beans::PropertyValue& rProp = rSeq[nArg]; if ( rProp.Name.equalsAscii("Title") ) { rProp.Value <<= rTitle; break; } } if ( nArg == nCount ) { rSeq.realloc( nCount+1 ); rSeq[nCount].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Title") ); rSeq[nCount].Value <<= rTitle; } } void SfxBaseModel::NotifyStorageListeners_Impl() { uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) ); if ( m_pData->m_pObjectShell ) { ::cppu::OInterfaceContainerHelper* pContainer = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType( ( const uno::Reference< document::XStorageChangeListener >*) NULL ) ); if ( pContainer != NULL ) { uno::Reference< embed::XStorage > xNewStorage = m_pData->m_pObjectShell->GetStorage(); ::cppu::OInterfaceIteratorHelper pIterator(*pContainer); while ( pIterator.hasMoreElements() ) { try { ((document::XStorageChangeListener*)pIterator.next())->notifyStorageChange( xSelfHold, xNewStorage ); } catch( uno::RuntimeException& ) { pIterator.remove(); } } } } } void SfxBaseModel::Notify( SfxBroadcaster& rBC , const SfxHint& rHint ) { if ( !m_pData ) return; if ( &rBC == m_pData->m_pObjectShell ) { SfxSimpleHint* pSimpleHint = PTR_CAST( SfxSimpleHint, &rHint ); if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DOCCHANGED ) changing(); SfxEventHint* pNamedHint = PTR_CAST( SfxEventHint, &rHint ); if ( pNamedHint ) { switch ( pNamedHint->GetEventId() ) { case SFX_EVENT_STORAGECHANGED: { // for now this event is sent only on creation of a new storage for new document // and in case of reload of medium without document reload // other events are used to detect storage change // NotifyStorageListeners_Impl(); if ( m_pData->m_xUIConfigurationManager.is() && m_pData->m_pObjectShell->GetCreateMode() != SFX_CREATE_MODE_EMBEDDED ) { uno::Reference< XSTORAGE > xConfigStorage; rtl::OUString aUIConfigFolderName( RTL_CONSTASCII_USTRINGPARAM( "Configurations2" )); xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, com::sun::star::embed::ElementModes::READWRITE ); if ( !xConfigStorage.is() ) xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, com::sun::star::embed::ElementModes::READ ); if ( xConfigStorage.is() || !m_pData->m_pObjectShell->GetStorage()->hasByName( aUIConfigFolderName ) ) { // the storage is different, since otherwise it could not be opened, so it must be exchanged Reference< ui::XUIConfigurationStorage > xUIConfigStorage( m_pData->m_xUIConfigurationManager, uno::UNO_QUERY ); xUIConfigStorage->setStorage( xConfigStorage ); } else { OSL_ENSURE( sal_False, "Unexpected scenario!\n" ); } } ListenForStorage_Impl( m_pData->m_pObjectShell->GetStorage() ); } break; case SFX_EVENT_LOADFINISHED: { impl_getPrintHelper(); ListenForStorage_Impl( m_pData->m_pObjectShell->GetStorage() ); m_pData->m_bModifiedSinceLastSave = sal_False; } break; case SFX_EVENT_SAVEASDOCDONE: { m_pData->m_sURL = m_pData->m_pObjectShell->GetMedium()->GetName(); SfxItemSet *pSet = m_pData->m_pObjectShell->GetMedium()->GetItemSet(); ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs; ::rtl::OUString aTitle = m_pData->m_pObjectShell->GetTitle(); TransformItems( SID_SAVEASDOC, *pSet, aArgs ); addTitle_Impl( aArgs, aTitle ); attachResource( m_pData->m_pObjectShell->GetMedium()->GetName(), aArgs ); } break; case SFX_EVENT_DOCCREATED: { impl_getPrintHelper(); m_pData->m_bModifiedSinceLastSave = sal_False; } break; case SFX_EVENT_MODIFYCHANGED: { m_pData->m_bModifiedSinceLastSave = isModified(); } break; } SfxViewEventHint* pViewHint = PTR_CAST( SfxViewEventHint, &rHint ); postEvent_Impl( pNamedHint->GetEventName(), pViewHint ? pViewHint->GetController() : uno::Reference< frame::XController2 >() ); } if ( pSimpleHint ) { if ( pSimpleHint->GetId() == SFX_HINT_TITLECHANGED ) { ::rtl::OUString aTitle = m_pData->m_pObjectShell->GetTitle(); addTitle_Impl( m_pData->m_seqArguments, aTitle ); postEvent_Impl( GlobalEventConfig::GetEventName( STR_EVENT_TITLECHANGED ) ); } if ( pSimpleHint->GetId() == SFX_HINT_MODECHANGED ) { postEvent_Impl( GlobalEventConfig::GetEventName( STR_EVENT_MODECHANGED ) ); } /* else if ( pSimpleHint->GetId() == SFX_HINT_DYING || pSimpleHint->GetId() == SFX_HINT_DEINITIALIZING ) { SfxObjectShellLock pShellLock = m_pData->m_pObjectShellLock; m_pData->m_pObjectShellLock = SfxObjectShellLock(); } */ } } } //________________________________________________________________________________________________________ // public impl. //________________________________________________________________________________________________________ void SfxBaseModel::NotifyModifyListeners_Impl() const { ::cppu::OInterfaceContainerHelper* pIC = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0) ); if ( pIC ) { lang::EventObject aEvent( (frame::XModel *)this ); pIC->notifyEach( &util::XModifyListener::modified, aEvent ); } // this notification here is done too generously, we cannot simply assume that we're really modified // now, but we need to check it ... m_pData->m_bModifiedSinceLastSave = const_cast< SfxBaseModel* >( this )->isModified(); } void SfxBaseModel::changing() { SfxModelGuard aGuard( *this ); // the notification should not be sent if the document can not be modified if ( !m_pData->m_pObjectShell.Is() || !m_pData->m_pObjectShell->IsEnableSetModified() ) return; NotifyModifyListeners_Impl(); } void SfxBaseModel::impl_change() { // object already disposed? if ( impl_isDisposed() ) return; NotifyModifyListeners_Impl(); } //________________________________________________________________________________________________________ // public impl. //________________________________________________________________________________________________________ SfxObjectShell* SfxBaseModel::GetObjectShell() const { return m_pData ? (SfxObjectShell*) m_pData->m_pObjectShell : 0; } SfxObjectShell* SfxBaseModel::impl_getObjectShell() const { return m_pData ? (SfxObjectShell*) m_pData->m_pObjectShell : 0; } //________________________________________________________________________________________________________ // public impl. //________________________________________________________________________________________________________ sal_Bool SfxBaseModel::IsInitialized() const { if ( !m_pData || !m_pData->m_pObjectShell ) { OSL_ENSURE( false, "SfxBaseModel::IsInitialized: this should have been caught earlier!" ); return sal_False; } return m_pData->m_pObjectShell->GetMedium() != NULL; } void SfxBaseModel::MethodEntryCheck( const bool i_mustBeInitialized ) const { if ( impl_isDisposed() ) throw ::com::sun::star::lang::DisposedException( ::rtl::OUString(), *const_cast< SfxBaseModel* >( this ) ); if ( i_mustBeInitialized && !IsInitialized() ) throw ::com::sun::star::lang::NotInitializedException( ::rtl::OUString(), *const_cast< SfxBaseModel* >( this ) ); } sal_Bool SfxBaseModel::impl_isDisposed() const { return ( m_pData == NULL ) ; } //________________________________________________________________________________________________________ // private impl. //________________________________________________________________________________________________________ ::rtl::OUString SfxBaseModel::GetMediumFilterName_Impl() { const SfxFilter* pFilter = NULL; SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium(); if ( pMedium ) pFilter = pMedium->GetFilter(); if ( pFilter ) return pFilter->GetName(); return ::rtl::OUString(); } void SfxBaseModel::impl_store( const ::rtl::OUString& sURL , const uno::Sequence< beans::PropertyValue >& seqArguments , sal_Bool bSaveTo ) { if( !sURL.getLength() ) throw frame::IllegalArgumentIOException(); //sal_Bool aSaveAsTemplate = sal_False; sal_Bool bSaved = sal_False; if ( !bSaveTo && m_pData->m_pObjectShell && sURL.getLength() && sURL.compareToAscii( "private:stream", 14 ) != COMPARE_EQUAL && ::utl::UCBContentHelper::EqualURLs( getLocation(), sURL ) ) { // this is the same file URL as the current document location, try to use storeOwn if possible ::comphelper::SequenceAsHashMap aArgHash( seqArguments ); ::rtl::OUString aFilterString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) ); ::rtl::OUString aFilterName = aArgHash.getUnpackedValueOrDefault( aFilterString, ::rtl::OUString() ); if ( aFilterName.getLength() ) { SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium(); if ( pMedium ) { const SfxFilter* pFilter = pMedium->GetFilter(); if ( pFilter && aFilterName.equals( pFilter->GetFilterName() ) ) { // 119366 - If the former file saving with password, do not trying in StoreSelf anyway... bool bFormerPassword = false; { uno::Sequence< beans::NamedValue > aOldEncryptionData; if (GetEncryptionData_Impl( pMedium->GetItemSet(), aOldEncryptionData )) { bFormerPassword = true; } } if ( !bFormerPassword ) { aArgHash.erase( aFilterString ); aArgHash.erase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) ); try { storeSelf( aArgHash.getAsConstPropertyValueList() ); bSaved = sal_True; } catch( const lang::IllegalArgumentException& ) { // some additional arguments do not allow to use saving, SaveAs should be done // but only for normal documents, the shared documents would be overwritten in this case // that would mean an information loss // TODO/LATER: need a new interaction for this case if ( m_pData->m_pObjectShell->IsDocShared() ) { m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't store shared document!" ) ) ); m_pData->m_pObjectShell->StoreLog(); uno::Sequence< beans::NamedValue > aNewEncryptionData = aArgHash.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionData" ) ), uno::Sequence< beans::NamedValue >() ); if ( !aNewEncryptionData.getLength() ) { ::rtl::OUString aNewPassword = aArgHash.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) ), ::rtl::OUString() ); aNewEncryptionData = ::comphelper::OStorageHelper::CreatePackageEncryptionData( aNewPassword ); } uno::Sequence< beans::NamedValue > aOldEncryptionData; GetEncryptionData_Impl( pMedium->GetItemSet(), aOldEncryptionData ); if ( !aOldEncryptionData.getLength() && !aNewEncryptionData.getLength() ) throw; else { // if the password is changed a special error should be used in case of shared document throw task::ErrorCodeIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't change password for shared document." ) ), uno::Reference< uno::XInterface >(), ERRCODE_SFX_SHARED_NOPASSWORDCHANGE ); } } } } } } } } if ( !bSaved && m_pData->m_pObjectShell ) { SFX_APP()->NotifyEvent( SfxEventHint( bSaveTo ? SFX_EVENT_SAVETODOC : SFX_EVENT_SAVEASDOC, GlobalEventConfig::GetEventName( bSaveTo ? STR_EVENT_SAVETODOC : STR_EVENT_SAVEASDOC ), m_pData->m_pObjectShell ) ); SfxAllItemSet *aParams = new SfxAllItemSet( SFX_APP()->GetPool() ); aParams->Put( SfxStringItem( SID_FILE_NAME, String(sURL) ) ); if ( bSaveTo ) aParams->Put( SfxBoolItem( SID_SAVETO, sal_True ) ); TransformParameters( SID_SAVEASDOC, seqArguments, *aParams ); SFX_ITEMSET_ARG( aParams, pCopyStreamItem, SfxBoolItem, SID_COPY_STREAM_IF_POSSIBLE, sal_False ); if ( pCopyStreamItem && pCopyStreamItem->GetValue() && !bSaveTo ) { m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Misuse of CopyStreamIfPossible!" ) ) ); m_pData->m_pObjectShell->StoreLog(); throw frame::IllegalArgumentIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CopyStreamIfPossible parameter is not acceptable for storeAsURL() call!") ), uno::Reference< uno::XInterface >() ); } sal_uInt32 nModifyPasswordHash = 0; uno::Sequence< beans::PropertyValue > aModifyPasswordInfo; SFX_ITEMSET_ARG( aParams, pModifyPasswordInfoItem, SfxUnoAnyItem, SID_MODIFYPASSWORDINFO, sal_False ); if ( pModifyPasswordInfoItem ) { // it contains either a simple hash or a set of PropertyValues // TODO/LATER: the sequence of PropertyValue should replace the hash completely in future sal_Int32 nMPHTmp = 0; pModifyPasswordInfoItem->GetValue() >>= nMPHTmp; nModifyPasswordHash = (sal_uInt32)nMPHTmp; pModifyPasswordInfoItem->GetValue() >>= aModifyPasswordInfo; } aParams->ClearItem( SID_MODIFYPASSWORDINFO ); sal_uInt32 nOldModifyPasswordHash = m_pData->m_pObjectShell->GetModifyPasswordHash(); m_pData->m_pObjectShell->SetModifyPasswordHash( nModifyPasswordHash ); uno::Sequence< beans::PropertyValue > aOldModifyPasswordInfo = m_pData->m_pObjectShell->GetModifyPasswordInfo(); m_pData->m_pObjectShell->SetModifyPasswordInfo( aModifyPasswordInfo ); // since saving a document modifies its DocumentInfo, the current // DocumentInfo must be saved on "SaveTo", so it can be restored // after saving sal_Bool bCopyTo = bSaveTo || m_pData->m_pObjectShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED; uno::Reference xOldDocProps; uno::Reference xOldDocInfo; if ( bCopyTo ) { xOldDocProps = getDocumentProperties(); if (m_pData->m_xDocumentInfo.is()) { xOldDocInfo = getDocumentInfo(); const Reference xCloneable(xOldDocInfo, UNO_QUERY_THROW); const Reference xNewDocInfo( xCloneable->createClone(), UNO_QUERY_THROW); const Reference xDPS( xNewDocInfo, UNO_QUERY_THROW); const Reference xNewDocProps( xDPS->getDocumentProperties()); m_pData->m_xDocumentProperties = xNewDocProps; m_pData->m_xDocumentInfo = xNewDocInfo; } else // try not to create DocumentInfo if it does not exist... { const Reference xCloneable(xOldDocProps, UNO_QUERY_THROW); const Reference xNewDocProps( xCloneable->createClone(), UNO_QUERY_THROW); m_pData->m_xDocumentProperties = xNewDocProps; } } sal_Bool bRet = m_pData->m_pObjectShell->APISaveAs_Impl( sURL, aParams ); if ( bCopyTo ) { // restore DocumentInfo if a copy was created m_pData->m_xDocumentProperties = xOldDocProps; m_pData->m_xDocumentInfo = xOldDocInfo; } uno::Reference < task::XInteractionHandler > xHandler; SFX_ITEMSET_ARG( aParams, pItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False); if ( pItem ) pItem->GetValue() >>= xHandler; DELETEZ( aParams ); sal_uInt32 nErrCode = m_pData->m_pObjectShell->GetErrorCode(); if ( !bRet && !nErrCode ) { m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing has failed, no error is set!" ) ) ); nErrCode = ERRCODE_IO_CANTWRITE; } m_pData->m_pObjectShell->ResetError(); if ( bRet ) { if ( nErrCode ) { // must be a warning - use Interactionhandler if possible or abandone if ( xHandler.is() ) { // TODO/LATER: a general way to set the error context should be available SfxErrorContext aEc( ERRCTX_SFX_SAVEASDOC, m_pData->m_pObjectShell->GetTitle() ); ::com::sun::star::task::ErrorCodeRequest aErrorCode; aErrorCode.ErrCode = nErrCode; SfxMedium::CallApproveHandler( xHandler, uno::makeAny( aErrorCode ), sal_False ); } } m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing succeeded!" ) ) ); if ( !bSaveTo ) { m_pData->m_aPreusedFilterName = GetMediumFilterName_Impl(); m_pData->m_pObjectShell->SetModifyPasswordEntered(); SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVEASDOCDONE, GlobalEventConfig::GetEventName(STR_EVENT_SAVEASDOCDONE), m_pData->m_pObjectShell ) ); } else { m_pData->m_pObjectShell->SetModifyPasswordHash( nOldModifyPasswordHash ); m_pData->m_pObjectShell->SetModifyPasswordInfo( aOldModifyPasswordInfo ); SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVETODOCDONE, GlobalEventConfig::GetEventName(STR_EVENT_SAVETODOCDONE), m_pData->m_pObjectShell ) ); } } else { // let the logring be stored to the related file m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing failed!" ) ) ); m_pData->m_pObjectShell->StoreLog(); m_pData->m_pObjectShell->SetModifyPasswordHash( nOldModifyPasswordHash ); m_pData->m_pObjectShell->SetModifyPasswordInfo( aOldModifyPasswordInfo ); SFX_APP()->NotifyEvent( SfxEventHint( bSaveTo ? SFX_EVENT_SAVETODOCFAILED : SFX_EVENT_SAVEASDOCFAILED, GlobalEventConfig::GetEventName( bSaveTo ? STR_EVENT_SAVETODOCFAILED : STR_EVENT_SAVEASDOCFAILED), m_pData->m_pObjectShell ) ); throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), nErrCode ); } } } //******************************************************************************************************** namespace { template< typename ListenerT, typename EventT > class NotifySingleListenerIgnoreRE { private: typedef void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ); NotificationMethod m_pMethod; const EventT& m_rEvent; public: NotifySingleListenerIgnoreRE( NotificationMethod method, const EventT& event ) : m_pMethod( method ), m_rEvent( event ) { } void operator()( const uno::Reference& listener ) const { try { (listener.get()->*m_pMethod)( m_rEvent ); } catch( uno::RuntimeException& ) { // this exception is ignored to avoid problems with invalid listeners, the listener should be probably thrown away in future } } }; } // anonymous namespace void SfxBaseModel::postEvent_Impl( const ::rtl::OUString& aName, const uno::Reference< frame::XController2 >& xController ) { // object already disposed? if ( impl_isDisposed() ) return; DBG_ASSERT( aName.getLength(), "Empty event name!" ); if (!aName.getLength()) return; ::cppu::OInterfaceContainerHelper* pIC = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType( (const uno::Reference< document::XDocumentEventListener >*)0 ) ); if ( pIC ) { #ifdef DBG_UTIL ByteString aTmp( "SfxDocumentEvent: " ); aTmp += ByteString( String(aName), RTL_TEXTENCODING_UTF8 ); DBG_TRACE( aTmp.GetBuffer() ); #endif document::DocumentEvent aDocumentEvent( (frame::XModel*)this, aName, xController, uno::Any() ); pIC->forEach< document::XDocumentEventListener, NotifySingleListenerIgnoreRE< document::XDocumentEventListener, document::DocumentEvent > >( NotifySingleListenerIgnoreRE< document::XDocumentEventListener, document::DocumentEvent >( &document::XDocumentEventListener::documentEventOccured, aDocumentEvent ) ); } pIC = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType( (const uno::Reference< document::XEventListener >*)0 ) ); if ( pIC ) { #ifdef DBG_UTIL ByteString aTmp( "SfxEvent: " ); aTmp += ByteString( String(aName), RTL_TEXTENCODING_UTF8 ); DBG_TRACE( aTmp.GetBuffer() ); #endif document::EventObject aEvent( (frame::XModel*)this, aName ); pIC->forEach< document::XEventListener, NotifySingleListenerIgnoreRE< document::XEventListener, document::EventObject > >( NotifySingleListenerIgnoreRE< document::XEventListener, document::EventObject >( &document::XEventListener::notifyEvent, aEvent ) ); } } uno::Reference < container::XIndexAccess > SAL_CALL SfxBaseModel::getViewData() throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell.Is() && !m_pData->m_contViewData.is() ) { SfxViewFrame *pActFrame = SfxViewFrame::Current(); if ( !pActFrame || pActFrame->GetObjectShell() != m_pData->m_pObjectShell ) pActFrame = SfxViewFrame::GetFirst( m_pData->m_pObjectShell ); if ( !pActFrame || !pActFrame->GetViewShell() ) // currently no frame for this document at all or View is under construction return uno::Reference < container::XIndexAccess >(); m_pData->m_contViewData = Reference < container::XIndexAccess >( ::comphelper::getProcessServiceFactory()->createInstance( DEFINE_CONST_UNICODE("com.sun.star.document.IndexedPropertyValues") ), uno::UNO_QUERY ); if ( !m_pData->m_contViewData.is() ) { // error: no container class available! return uno::Reference < container::XIndexAccess >(); } uno::Reference < container::XIndexContainer > xCont( m_pData->m_contViewData, uno::UNO_QUERY ); sal_Int32 nCount = 0; uno::Sequence < beans::PropertyValue > aSeq; ::com::sun::star::uno::Any aAny; for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst( m_pData->m_pObjectShell ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, m_pData->m_pObjectShell ) ) { sal_Bool bIsActive = ( pFrame == pActFrame ); pFrame->GetViewShell()->WriteUserDataSequence( aSeq ); aAny <<= aSeq; xCont->insertByIndex( bIsActive ? 0 : nCount, aAny ); nCount++; } } return m_pData->m_contViewData; } void SAL_CALL SfxBaseModel::setViewData( const uno::Reference < container::XIndexAccess >& aData ) throw(::com::sun::star::uno::RuntimeException) { SfxModelGuard aGuard( *this ); m_pData->m_contViewData = aData; } /** calls all XEventListeners */ void SfxBaseModel::notifyEvent( const ::com::sun::star::document::EventObject& aEvent ) const { // object already disposed? if ( impl_isDisposed() ) return; ::cppu::OInterfaceContainerHelper* pIC = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0) ); if( pIC ) { ::cppu::OInterfaceIteratorHelper aIt( *pIC ); while( aIt.hasMoreElements() ) { try { ((XDOCEVENTLISTENER *)aIt.next())->notifyEvent( aEvent ); } catch( uno::RuntimeException& ) { aIt.remove(); } } } } /** returns true if someone added a XEventListener to this XEventBroadcaster */ sal_Bool SfxBaseModel::hasEventListeners() const { return !impl_isDisposed() && (NULL != m_pData->m_aInterfaceContainer.getContainer( ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0) ) ); } void SAL_CALL SfxBaseModel::addPrintJobListener( const uno::Reference< view::XPrintJobListener >& xListener ) throw (uno::RuntimeException) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); if ( impl_getPrintHelper() ) { uno::Reference < view::XPrintJobBroadcaster > xPJB( m_pData->m_xPrintable, uno::UNO_QUERY ); if ( xPJB.is() ) xPJB->addPrintJobListener( xListener ); } // else // m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< view::XPrintJobListener >*)0), xListener ); } void SAL_CALL SfxBaseModel::removePrintJobListener( const uno::Reference< view::XPrintJobListener >& xListener ) throw (uno::RuntimeException) { SfxModelGuard aGuard( *this ); if ( impl_getPrintHelper() ) { uno::Reference < view::XPrintJobBroadcaster > xPJB( m_pData->m_xPrintable, uno::UNO_QUERY ); if ( xPJB.is() ) xPJB->removePrintJobListener( xListener ); } // else // m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< view::XPrintJobListener >*)0), xListener ); } // simple declaration of class SvObject is enough // the corresponding cannon be included because it provides // declaration of class SvBorder that conflicts with ../../inc/viewfrm.hxx class SvObject; sal_Int64 SAL_CALL SfxBaseModel::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException) { ::vos::OGuard aGuard( Application::GetSolarMutex() ); if ( GetObjectShell() ) { SvGlobalName aName( aIdentifier ); if ( aName == SvGlobalName( SO3_GLOBAL_CLASSID ) ) return (sal_Int64)(sal_IntPtr)(SvObject*)GetObjectShell(); else if ( aName == SvGlobalName( SFX_GLOBAL_CLASSID ) ) return (sal_Int64)(sal_IntPtr)(SfxObjectShell*)GetObjectShell(); } return 0; } //____________________________________________________________________________________________________ // XDocumentSubStorageSupplier //____________________________________________________________________________________________________ void SfxBaseModel::ListenForStorage_Impl( const uno::Reference< embed::XStorage >& xStorage ) { uno::Reference< util::XModifiable > xModifiable( xStorage, uno::UNO_QUERY ); if ( xModifiable.is() ) { if ( !m_pData->m_pStorageModifyListen.is() ) { m_pData->m_pStorageModifyListen = new ::sfx2::DocumentStorageModifyListener( *m_pData, Application::GetSolarMutex() ); } // no need to deregister the listening for old storage since it should be disposed automatically xModifiable->addModifyListener( m_pData->m_pStorageModifyListen.get() ); } } uno::Reference< XSTORAGE > SAL_CALL SfxBaseModel::getDocumentSubStorage( const ::rtl::OUString& aStorageName, sal_Int32 nMode ) throw ( uno::RuntimeException) { SfxModelGuard aGuard( *this ); uno::Reference< XSTORAGE > xResult; if ( m_pData->m_pObjectShell.Is() ) { uno::Reference< embed::XStorage > xStorage = m_pData->m_pObjectShell->GetStorage(); if ( xStorage.is() ) { try { xResult = xStorage->openStorageElement( aStorageName, nMode ); } catch ( uno::Exception& ) { } } } return xResult; } Sequence< ::rtl::OUString > SAL_CALL SfxBaseModel::getDocumentSubStoragesNames() throw ( io::IOException, RuntimeException ) { SfxModelGuard aGuard( *this ); Sequence< ::rtl::OUString > aResult; sal_Int32 nResultSize = 0; sal_Bool bSuccess = sal_False; if ( m_pData->m_pObjectShell.Is() ) { uno::Reference < embed::XStorage > xStorage = m_pData->m_pObjectShell->GetStorage(); uno::Reference < container::XNameAccess > xAccess( xStorage, uno::UNO_QUERY ); if ( xAccess.is() ) { Sequence< ::rtl::OUString > aTemp = xAccess->getElementNames(); for ( sal_Int32 n = 0; n < aTemp.getLength(); n++ ) { if ( xStorage->isStorageElement( aTemp[n] ) ) { aResult.realloc( ++nResultSize ); aResult[ nResultSize - 1 ] = aTemp[n]; } } bSuccess = sal_True; } } if ( !bSuccess ) throw io::IOException(); return aResult; } //____________________________________________________________________________________________________ // XScriptProviderSupplier //____________________________________________________________________________________________________ uno::Reference< script::provider::XScriptProvider > SAL_CALL SfxBaseModel::getScriptProvider() throw ( uno::RuntimeException ) { SfxModelGuard aGuard( *this ); uno::Reference< script::provider::XScriptProvider > xScriptProvider; ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); Reference< script::provider::XScriptProviderFactory > xScriptProviderFactory( aContext.getSingleton( "com.sun.star.script.provider.theMasterScriptProviderFactory" ), uno::UNO_QUERY_THROW ); try { Reference< XScriptInvocationContext > xScriptContext( this ); xScriptProvider.set( xScriptProviderFactory->createScriptProvider( makeAny( xScriptContext ) ), uno::UNO_SET_THROW ); } catch( const uno::RuntimeException& ) { throw; } catch( const lang::IllegalArgumentException& ) { throw lang::WrappedTargetRuntimeException( ::rtl::OUString(), *this, ::cppu::getCaughtException() ); } return xScriptProvider; } //____________________________________________________________________________________________________ // XUIConfigurationManagerSupplier //____________________________________________________________________________________________________ rtl::OUString SfxBaseModel::getRuntimeUID() const { OSL_ENSURE( m_pData->m_sRuntimeUID.getLength() > 0, "SfxBaseModel::getRuntimeUID - ID is empty!" ); return m_pData->m_sRuntimeUID; } sal_Bool SfxBaseModel::hasValidSignatures() const { ::vos::OGuard aGuard( Application::GetSolarMutex() ); if ( m_pData->m_pObjectShell.Is() ) return ( m_pData->m_pObjectShell->ImplGetSignatureState( sal_False ) == SIGNATURESTATE_SIGNATURES_OK ); return sal_False; } static void GetCommandFromSequence( rtl::OUString& rCommand, sal_Int32& nIndex, const uno::Sequence< beans::PropertyValue >& rSeqPropValue ) { rtl::OUString aCommand; nIndex = -1; for ( sal_Int32 i = 0; i < rSeqPropValue.getLength(); i++ ) { if ( rSeqPropValue[i].Name.equalsAsciiL( "Command", 7 )) { rSeqPropValue[i].Value >>= rCommand; nIndex = i; return; } } } static void ConvertSlotsToCommands( SfxObjectShell* pDoc, uno::Reference< container::XIndexContainer >& rToolbarDefinition ) { if ( pDoc ) { Any aAny; SfxModule* pModule( pDoc->GetFactory().GetModule() ); rtl::OUString aSlotCmd( RTL_CONSTASCII_USTRINGPARAM( "slot:" )); rtl::OUString aUnoCmd( RTL_CONSTASCII_USTRINGPARAM( ".uno:" )); uno::Sequence< beans::PropertyValue > aSeqPropValue; for ( sal_Int32 i = 0; i < rToolbarDefinition->getCount(); i++ ) { sal_Int32 nIndex( -1 ); rtl::OUString aCommand; if ( rToolbarDefinition->getByIndex( i ) >>= aSeqPropValue ) { GetCommandFromSequence( aCommand, nIndex, aSeqPropValue ); if ( nIndex >= 0 && ( aCommand.indexOf( aSlotCmd ) == 0 )) { rtl::OUString aSlot( aCommand.copy( 5 )); // We have to replace the old "slot-Command" with our new ".uno:-Command" const SfxSlot* pSlot = pModule->GetSlotPool()->GetSlot( sal_uInt16( aSlot.toInt32() )); if ( pSlot ) { rtl::OUStringBuffer aStrBuf( aUnoCmd ); aStrBuf.appendAscii( pSlot->GetUnoName() ); aCommand = aStrBuf.makeStringAndClear(); aSeqPropValue[nIndex].Value <<= aCommand; rToolbarDefinition->replaceByIndex( i, Any( aSeqPropValue )); } } } } } } uno::Reference< ui::XUIConfigurationManager > SAL_CALL SfxBaseModel::getUIConfigurationManager() throw ( uno::RuntimeException ) { SfxModelGuard aGuard( *this ); if ( !m_pData->m_xUIConfigurationManager.is() ) { uno::Reference< ui::XUIConfigurationManager > xNewUIConfMan( ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.ui.UIConfigurationManager" )), uno::UNO_QUERY ); Reference< ui::XUIConfigurationStorage > xUIConfigStorage( xNewUIConfMan, uno::UNO_QUERY ); if ( xUIConfigStorage.is() ) { uno::Reference< XSTORAGE > xConfigStorage; rtl::OUString aUIConfigFolderName( RTL_CONSTASCII_USTRINGPARAM( "Configurations2" )); // First try to open with READWRITE and then READ xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, embed::ElementModes::READWRITE ); if ( xConfigStorage.is() ) { rtl::OUString aMediaTypeProp( RTL_CONSTASCII_USTRINGPARAM( "MediaType" )); rtl::OUString aUIConfigMediaType( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.xml.ui.configuration" ) ); rtl::OUString aMediaType; uno::Reference< beans::XPropertySet > xPropSet( xConfigStorage, uno::UNO_QUERY ); Any a = xPropSet->getPropertyValue( aMediaTypeProp ); if ( !( a >>= aMediaType ) || ( aMediaType.getLength() == 0 )) { a <<= aUIConfigMediaType; xPropSet->setPropertyValue( aMediaTypeProp, a ); } } else xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, embed::ElementModes::READ ); // initialize ui configuration manager with document substorage xUIConfigStorage->setStorage( xConfigStorage ); // embedded objects did not support local configuration data until OOo 3.0, so there's nothing to // migrate if ( m_pData->m_pObjectShell->GetCreateMode() != SFX_CREATE_MODE_EMBEDDED ) { // Import old UI configuration from OOo 1.x uno::Reference< XSTORAGE > xOOo1ConfigStorage; rtl::OUString aOOo1UIConfigFolderName( RTL_CONSTASCII_USTRINGPARAM( "Configurations" )); // Try to open with READ xOOo1ConfigStorage = getDocumentSubStorage( aOOo1UIConfigFolderName, embed::ElementModes::READ ); if ( xOOo1ConfigStorage.is() ) { uno::Reference< lang::XMultiServiceFactory > xServiceMgr( ::comphelper::getProcessServiceFactory() ); uno::Sequence< uno::Reference< container::XIndexContainer > > rToolbars; sal_Bool bImported = framework::UIConfigurationImporterOOo1x::ImportCustomToolbars( xNewUIConfMan, rToolbars, xServiceMgr, xOOo1ConfigStorage ); if ( bImported ) { SfxObjectShell* pObjShell = SfxBaseModel::GetObjectShell(); char aNum[] = "private:resource/toolbar/custom_OOo1x_0"; char aTitle[] = "Toolbar 0"; sal_Int32 nNumIndex = strlen( aNum )-1; sal_Int32 nTitleIndex = strlen( aTitle )-1; for ( sal_Int32 i = 0; i < rToolbars.getLength(); i++ ) { aNum[nNumIndex]++; aTitle[nTitleIndex]++; rtl::OUString aCustomTbxName( RTL_CONSTASCII_USTRINGPARAM( aNum )); rtl::OUString aCustomTbxTitle( RTL_CONSTASCII_USTRINGPARAM( aTitle )); uno::Reference< container::XIndexContainer > xToolbar = rToolbars[i]; ConvertSlotsToCommands( pObjShell, xToolbar ); if ( !xNewUIConfMan->hasSettings( aCustomTbxName )) { // Set UIName for the toolbar with container property uno::Reference< beans::XPropertySet > xPropSet( xToolbar, UNO_QUERY ); if ( xPropSet.is() ) { try { rtl::OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( "UIName" )); Any aAny( aCustomTbxTitle ); xPropSet->setPropertyValue( aPropName, aAny ); } catch ( beans::UnknownPropertyException& ) { } } uno::Reference< container::XIndexAccess > xToolbarData( xToolbar, uno::UNO_QUERY ); xNewUIConfMan->insertSettings( aCustomTbxName, xToolbarData ); uno::Reference< ui::XUIConfigurationPersistence > xPersist( xNewUIConfMan, uno::UNO_QUERY ); xPersist->store(); } } } } } } m_pData->m_xUIConfigurationManager = xNewUIConfMan; } return m_pData->m_xUIConfigurationManager; } //____________________________________________________________________________________________________ // XVisualObject //____________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::setVisualAreaSize( sal_Int64 nAspect, const awt::Size& aSize ) throw ( lang::IllegalArgumentException, embed::WrongStateException, uno::Exception, uno::RuntimeException ) { SfxModelGuard aGuard( *this ); if ( !m_pData->m_pObjectShell.Is() ) throw uno::Exception(); // TODO: error handling SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst( m_pData->m_pObjectShell, sal_False ); if ( pViewFrm && m_pData->m_pObjectShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED && !pViewFrm->GetFrame().IsInPlace() ) { Window* pWindow = VCLUnoHelper::GetWindow( pViewFrm->GetFrame().GetFrameInterface()->getContainerWindow() ); Size aWinSize = pWindow->GetSizePixel(); awt::Size aCurrent = getVisualAreaSize( nAspect ); Size aDiff( aSize.Width-aCurrent.Width, aSize.Height-aCurrent.Height ); Size aWrongDiff = OutputDevice::LogicToLogic( aDiff , m_pData->m_pObjectShell->GetMapUnit(), pWindow->GetMapMode() ); aDiff = pViewFrm->GetViewShell()->GetWindow()->LogicToPixel( aDiff ); aWinSize.Width() += aDiff.Width(); aWinSize.Height() += aDiff.Height(); pWindow->SetSizePixel( aWinSize ); } else { Rectangle aTmpRect = m_pData->m_pObjectShell->GetVisArea( ASPECT_CONTENT ); aTmpRect.SetSize( Size( aSize.Width, aSize.Height ) ); m_pData->m_pObjectShell->SetVisArea( aTmpRect ); } } awt::Size SAL_CALL SfxBaseModel::getVisualAreaSize( sal_Int64 /*nAspect*/ ) throw ( lang::IllegalArgumentException, embed::WrongStateException, uno::Exception, uno::RuntimeException) { SfxModelGuard aGuard( *this ); if ( !m_pData->m_pObjectShell.Is() ) throw uno::Exception(); // TODO: error handling Rectangle aTmpRect = m_pData->m_pObjectShell->GetVisArea( ASPECT_CONTENT ); #if 0 Window* pWindow = NULL; SfxViewFrame* pViewFrm = m_pData->m_pObjectShell.Is() ? SfxViewFrame::GetFirst( m_pData->m_pObjectShell, 0, sal_False ) : 0; if ( pWindow ) { MapMode aInternalMapMode( pViewFrm->GetWindow().GetMapMode() ); MapMode aExternalMapMode( m_pData->m_pObjectShell->GetMapUnit() ); aTmpRect = OutputDevice::LogicToLogic( aTmpRect, aInternalMapMode, aExternalMapMode ); } #endif return awt::Size( aTmpRect.GetWidth(), aTmpRect.GetHeight() ); } sal_Int32 SAL_CALL SfxBaseModel::getMapUnit( sal_Int64 /*nAspect*/ ) throw ( uno::Exception, uno::RuntimeException) { SfxModelGuard aGuard( *this ); if ( !m_pData->m_pObjectShell.Is() ) throw uno::Exception(); // TODO: error handling return VCLUnoHelper::VCL2UnoEmbedMapUnit( m_pData->m_pObjectShell->GetMapUnit() ); } embed::VisualRepresentation SAL_CALL SfxBaseModel::getPreferredVisualRepresentation( ::sal_Int64 /*nAspect*/ ) throw ( lang::IllegalArgumentException, embed::WrongStateException, uno::Exception, uno::RuntimeException ) { SfxModelGuard aGuard( *this ); datatransfer::DataFlavor aDataFlavor( ::rtl::OUString::createFromAscii( "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ), ::rtl::OUString::createFromAscii( "GDIMetaFile" ), ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) ); embed::VisualRepresentation aVisualRepresentation; aVisualRepresentation.Data = getTransferData( aDataFlavor ); aVisualRepresentation.Flavor = aDataFlavor; return aVisualRepresentation; } //____________________________________________________________________________________________________ // XStorageBasedDocument //____________________________________________________________________________________________________ void SAL_CALL SfxBaseModel::loadFromStorage( const uno::Reference< XSTORAGE >& xStorage, const uno::Sequence< beans::PropertyValue >& aMediaDescriptor ) throw ( lang::IllegalArgumentException, DOUBLEINITIALIZATIONEXCEPTION, IOEXCEPTION, EXCEPTION, uno::RuntimeException ) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); if ( IsInitialized() ) throw ::com::sun::star::frame::DoubleInitializationException( ::rtl::OUString(), *this ); // after i36090 is fixed the pool from object shell can be used // SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() ); SfxAllItemSet aSet( SFX_APP()->GetPool() ); // the BaseURL is part of the ItemSet SfxMedium* pMedium = new SfxMedium( xStorage, String() ); TransformParameters( SID_OPENDOC, aMediaDescriptor, aSet ); pMedium->GetItemSet()->Put( aSet ); // allow to use an interactionhandler (if there is one) pMedium->UseInteractionHandler( sal_True ); SFX_ITEMSET_ARG( &aSet, pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False); sal_Bool bTemplate = pTemplateItem && pTemplateItem->GetValue(); m_pData->m_pObjectShell->SetActivateEvent_Impl( bTemplate ? SFX_EVENT_CREATEDOC : SFX_EVENT_OPENDOC ); m_pData->m_pObjectShell->Get_Impl()->bOwnsStorage = sal_False; // load document if ( !m_pData->m_pObjectShell->DoLoad(pMedium) ) { sal_uInt32 nError = m_pData->m_pObjectShell->GetErrorCode(); throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), nError ? nError : ERRCODE_IO_CANTREAD ); } } void SAL_CALL SfxBaseModel::storeToStorage( const uno::Reference< XSTORAGE >& xStorage, const uno::Sequence< beans::PropertyValue >& aMediaDescriptor ) throw ( lang::IllegalArgumentException, IOEXCEPTION, EXCEPTION, uno::RuntimeException ) { SfxModelGuard aGuard( *this ); uno::Reference< XSTORAGE > xResult; if ( !m_pData->m_pObjectShell.Is() ) throw IOEXCEPTION(); // TODO: SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() ); TransformParameters( SID_SAVEASDOC, aMediaDescriptor, aSet ); // TODO/LATER: may be a special URL "private:storage" should be used SFX_ITEMSET_ARG( &aSet, pItem, SfxStringItem, SID_FILTER_NAME, sal_False ); sal_Int32 nVersion = SOFFICE_FILEFORMAT_CURRENT; if( pItem ) { String aFilterName = pItem->GetValue(); const SfxFilter* pFilter = SFX_APP()->GetFilterMatcher().GetFilter4FilterName( aFilterName ); if ( pFilter && pFilter->UsesStorage() ) nVersion = pFilter->GetVersion(); } sal_Bool bSuccess = sal_False; if ( xStorage == m_pData->m_pObjectShell->GetStorage() ) { // storing to the own storage bSuccess = m_pData->m_pObjectShell->DoSave(); } else { // TODO/LATER: if the provided storage has some data inside the storing might fail, probably the storage must be truncated // TODO/LATER: is it possible to have a template here? m_pData->m_pObjectShell->SetupStorage( xStorage, nVersion, sal_False ); // BaseURL is part of the ItemSet SfxMedium aMedium( xStorage, String(), &aSet ); aMedium.CanDisposeStorage_Impl( sal_False ); if ( aMedium.GetFilter() ) { // storing without a valid filter will often crash bSuccess = m_pData->m_pObjectShell->DoSaveObjectAs( aMedium, sal_True ); m_pData->m_pObjectShell->DoSaveCompleted( NULL ); } } sal_uInt32 nError = m_pData->m_pObjectShell->GetErrorCode(); m_pData->m_pObjectShell->ResetError(); // the warnings are currently not transported if ( !bSuccess ) { throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), nError ? nError : ERRCODE_IO_GENERAL ); } } void SAL_CALL SfxBaseModel::switchToStorage( const uno::Reference< XSTORAGE >& xStorage ) throw ( lang::IllegalArgumentException, IOEXCEPTION, EXCEPTION, uno::RuntimeException ) { SfxModelGuard aGuard( *this ); uno::Reference< XSTORAGE > xResult; if ( !m_pData->m_pObjectShell.Is() ) throw IOEXCEPTION(); // TODO: // the persistence should be switched only if the storage is different if ( xStorage != m_pData->m_pObjectShell->GetStorage() && !m_pData->m_pObjectShell->SwitchPersistance( xStorage ) ) { sal_uInt32 nError = m_pData->m_pObjectShell->GetErrorCode(); throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), nError ? nError : ERRCODE_IO_GENERAL ); } m_pData->m_pObjectShell->Get_Impl()->bOwnsStorage = sal_False; } uno::Reference< XSTORAGE > SAL_CALL SfxBaseModel::getDocumentStorage() throw ( IOEXCEPTION, EXCEPTION, uno::RuntimeException ) { SfxModelGuard aGuard( *this ); uno::Reference< XSTORAGE > xResult; if ( !m_pData->m_pObjectShell.Is() ) throw IOEXCEPTION(); // TODO return m_pData->m_pObjectShell->GetStorage(); } void SAL_CALL SfxBaseModel::addStorageChangeListener( const uno::Reference< document::XStorageChangeListener >& xListener ) throw ( uno::RuntimeException ) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< document::XStorageChangeListener >*)0), xListener ); } void SAL_CALL SfxBaseModel::removeStorageChangeListener( const uno::Reference< document::XStorageChangeListener >& xListener ) throw ( uno::RuntimeException ) { SfxModelGuard aGuard( *this ); m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< document::XStorageChangeListener >*)0), xListener ); } #include "printhelper.hxx" bool SfxBaseModel::impl_getPrintHelper() { if ( m_pData->m_xPrintable.is() ) return true; m_pData->m_xPrintable = new SfxPrintHelper(); uno::Reference < lang::XInitialization > xInit( m_pData->m_xPrintable, uno::UNO_QUERY ); uno::Sequence < uno::Any > aValues(1); aValues[0] <<= uno::Reference < frame::XModel > (static_cast< frame::XModel* >(this), uno::UNO_QUERY ); xInit->initialize( aValues ); uno::Reference < view::XPrintJobBroadcaster > xBrd( m_pData->m_xPrintable, uno::UNO_QUERY ); xBrd->addPrintJobListener( new SfxPrintHelperListener_Impl( m_pData ) ); return true; } //============================================================================= // css.frame.XModule void SAL_CALL SfxBaseModel::setIdentifier(const ::rtl::OUString& Identifier) throw (css::uno::RuntimeException) { SfxModelGuard aGuard( *this ); m_pData->m_sModuleIdentifier = Identifier; } //============================================================================= // css.frame.XModule ::rtl::OUString SAL_CALL SfxBaseModel::getIdentifier() throw (css::uno::RuntimeException) { SfxModelGuard aGuard( *this ); if (m_pData->m_sModuleIdentifier.getLength() > 0) return m_pData->m_sModuleIdentifier; if (m_pData->m_pObjectShell) return m_pData->m_pObjectShell->GetFactory().GetDocumentServiceName(); return ::rtl::OUString(); } //============================================================================= css::uno::Reference< css::frame::XTitle > SfxBaseModel::impl_getTitleHelper () { SfxModelGuard aGuard( *this ); if ( ! m_pData->m_xTitleHelper.is ()) { css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory (); css::uno::Reference< css::frame::XUntitledNumbers > xDesktop(xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW); css::uno::Reference< css::frame::XModel > xThis (static_cast< css::frame::XModel* >(this), css::uno::UNO_QUERY_THROW); ::framework::TitleHelper* pHelper = new ::framework::TitleHelper(xSMGR); m_pData->m_xTitleHelper = css::uno::Reference< css::frame::XTitle >(static_cast< ::cppu::OWeakObject* >(pHelper), css::uno::UNO_QUERY_THROW); pHelper->setOwner (xThis ); pHelper->connectWithUntitledNumbers (xDesktop); } return m_pData->m_xTitleHelper; } //============================================================================= css::uno::Reference< css::frame::XUntitledNumbers > SfxBaseModel::impl_getUntitledHelper () { SfxModelGuard aGuard( *this ); if ( ! m_pData->m_xNumberedControllers.is ()) { css::uno::Reference< css::frame::XModel > xThis (static_cast< css::frame::XModel* >(this), css::uno::UNO_QUERY_THROW); ::comphelper::NumberedCollection* pHelper = new ::comphelper::NumberedCollection(); m_pData->m_xNumberedControllers = css::uno::Reference< css::frame::XUntitledNumbers >(static_cast< ::cppu::OWeakObject* >(pHelper), css::uno::UNO_QUERY_THROW); pHelper->setOwner (xThis); pHelper->setUntitledPrefix (::rtl::OUString::createFromAscii(" : ")); } return m_pData->m_xNumberedControllers; } //============================================================================= // css.frame.XTitle ::rtl::OUString SAL_CALL SfxBaseModel::getTitle() throw (css::uno::RuntimeException) { // SYNCHRONIZED -> SfxModelGuard aGuard( *this ); ::rtl::OUString aResult = impl_getTitleHelper()->getTitle (); if ( !m_pData->m_bExternalTitle && m_pData->m_pObjectShell ) { SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium(); if ( pMedium ) { SFX_ITEMSET_ARG( pMedium->GetItemSet(), pRepairedDocItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False ); if ( pRepairedDocItem && pRepairedDocItem->GetValue() ) aResult += String( SfxResId(STR_REPAIREDDOCUMENT) ); } if ( m_pData->m_pObjectShell->IsReadOnlyUI() || (pMedium && pMedium->IsReadOnly()) ) aResult += ::rtl::OUString( String( SfxResId(STR_READONLY) ) ); else if ( m_pData->m_pObjectShell->IsDocShared() ) aResult += ::rtl::OUString( String( SfxResId(STR_SHARED) ) ); if ( m_pData->m_pObjectShell->GetDocumentSignatureState() == SIGNATURESTATE_SIGNATURES_OK ) aResult += String( SfxResId( RID_XMLSEC_DOCUMENTSIGNED ) ); } return aResult; } //============================================================================= // css.frame.XTitle void SAL_CALL SfxBaseModel::setTitle( const ::rtl::OUString& sTitle ) throw (css::uno::RuntimeException) { // SYNCHRONIZED -> SfxModelGuard aGuard( *this ); impl_getTitleHelper()->setTitle (sTitle); m_pData->m_bExternalTitle = sal_True; } //============================================================================= // css.frame.XTitleChangeBroadcaster void SAL_CALL SfxBaseModel::addTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener ) throw (css::uno::RuntimeException) { // SYNCHRONIZED -> SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); css::uno::Reference< css::frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper(), css::uno::UNO_QUERY); if (xBroadcaster.is ()) xBroadcaster->addTitleChangeListener (xListener); } //============================================================================= // css.frame.XTitleChangeBroadcaster void SAL_CALL SfxBaseModel::removeTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener ) throw (css::uno::RuntimeException) { // SYNCHRONIZED -> SfxModelGuard aGuard( *this ); css::uno::Reference< css::frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper(), css::uno::UNO_QUERY); if (xBroadcaster.is ()) xBroadcaster->removeTitleChangeListener (xListener); } //============================================================================= // css.frame.XUntitledNumbers ::sal_Int32 SAL_CALL SfxBaseModel::leaseNumber( const css::uno::Reference< css::uno::XInterface >& xComponent ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException ) { SfxModelGuard aGuard( *this ); return impl_getUntitledHelper ()->leaseNumber (xComponent); } //============================================================================= // css.frame.XUntitledNumbers void SAL_CALL SfxBaseModel::releaseNumber( ::sal_Int32 nNumber ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException ) { SfxModelGuard aGuard( *this ); impl_getUntitledHelper ()->releaseNumber (nNumber); } //============================================================================= // css.frame.XUntitledNumbers void SAL_CALL SfxBaseModel::releaseNumberForComponent( const css::uno::Reference< css::uno::XInterface >& xComponent ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException ) { SfxModelGuard aGuard( *this ); impl_getUntitledHelper ()->releaseNumberForComponent (xComponent); } //============================================================================= // css.frame.XUntitledNumbers ::rtl::OUString SAL_CALL SfxBaseModel::getUntitledPrefix() throw (css::uno::RuntimeException) { SfxModelGuard aGuard( *this ); return impl_getUntitledHelper ()->getUntitledPrefix (); } //============================================================================= // css::frame::XModel2 css::uno::Reference< css::container::XEnumeration > SAL_CALL SfxBaseModel::getControllers() throw (css::uno::RuntimeException) { SfxModelGuard aGuard( *this ); sal_Int32 c = m_pData->m_seqControllers.getLength(); sal_Int32 i = 0; css::uno::Sequence< css::uno::Any > lEnum(c); for (i=0; im_seqControllers[i]; ::comphelper::OAnyEnumeration* pEnum = new ::comphelper::OAnyEnumeration(lEnum); css::uno::Reference< css::container::XEnumeration > xEnum(static_cast< css::container::XEnumeration* >(pEnum), css::uno::UNO_QUERY_THROW); return xEnum; } //============================================================================= // css::frame::XModel2 css::uno::Sequence< ::rtl::OUString > SAL_CALL SfxBaseModel::getAvailableViewControllerNames() throw (css::uno::RuntimeException) { SfxModelGuard aGuard( *this ); const SfxObjectFactory& rDocumentFactory = GetObjectShell()->GetFactory(); const sal_Int32 nViewFactoryCount = rDocumentFactory.GetViewFactoryCount(); Sequence< ::rtl::OUString > aViewNames( nViewFactoryCount ); for ( sal_Int32 nViewNo = 0; nViewNo < nViewFactoryCount; ++nViewNo ) aViewNames[nViewNo] = rDocumentFactory.GetViewFactory( nViewNo ).GetAPIViewName(); return aViewNames; } //============================================================================= // css::frame::XModel2 css::uno::Reference< css::frame::XController2 > SAL_CALL SfxBaseModel::createDefaultViewController( const css::uno::Reference< css::frame::XFrame >& i_rFrame ) throw (css::uno::RuntimeException , css::lang::IllegalArgumentException, css::uno::Exception ) { SfxModelGuard aGuard( *this ); const SfxObjectFactory& rDocumentFactory = GetObjectShell()->GetFactory(); const ::rtl::OUString sDefaultViewName = rDocumentFactory.GetViewFactory( 0 ).GetAPIViewName(); aGuard.clear(); return createViewController( sDefaultViewName, Sequence< PropertyValue >(), i_rFrame ); } //============================================================================= namespace sfx { namespace intern { /** a class which, in its dtor, cleans up variuos objects (well, at the moment only the frame) collected during the creation of a document view, unless the creation was successful. */ class SAL_DLLPRIVATE ViewCreationGuard { public: ViewCreationGuard() :m_bSuccess( false ) { } ~ViewCreationGuard() { if ( !m_bSuccess ) impl_closeAll(); } void takeFrameOwnership( SfxFrame* i_pFrame ) { OSL_PRECOND( !m_aWeakFrame, "ViewCreationGuard::takeFrameOwnership: already have a frame!" ); OSL_PRECOND( i_pFrame != NULL, "ViewCreationGuard::takeFrameOwnership: invalid frame!" ); m_aWeakFrame = i_pFrame; } void releaseAll() { m_bSuccess = true; } private: void impl_closeAll() { if ( m_aWeakFrame && !m_aWeakFrame->GetCurrentDocument() ) { m_aWeakFrame->SetFrameInterface_Impl( NULL ); m_aWeakFrame->DoClose(); } } private: bool m_bSuccess; SfxFrameWeak m_aWeakFrame; }; } } //============================================================================= SfxViewFrame* SfxBaseModel::FindOrCreateViewFrame_Impl( const Reference< XFrame >& i_rFrame, ::sfx::intern::ViewCreationGuard& i_rGuard ) const { SfxViewFrame* pViewFrame = NULL; for ( pViewFrame = SfxViewFrame::GetFirst( GetObjectShell(), sal_False ); pViewFrame; pViewFrame= SfxViewFrame::GetNext( *pViewFrame, GetObjectShell(), sal_False ) ) { if ( pViewFrame->GetFrame().GetFrameInterface() == i_rFrame ) break; } if ( !pViewFrame ) { #if OSL_DEBUG_LEVEL > 0 for ( SfxFrame* pCheckFrame = SfxFrame::GetFirst(); pCheckFrame; pCheckFrame = SfxFrame::GetNext( *pCheckFrame ) ) { if ( pCheckFrame->GetFrameInterface() == i_rFrame ) { if ( ( pCheckFrame->GetCurrentViewFrame() != NULL ) || ( pCheckFrame->GetCurrentDocument() != NULL ) ) // Note that it is perfectly letgitimate that during loading into an XFrame which already contains // a document, there exist two SfxFrame instances bound to this XFrame - the old one, which will be // destroyed later, and the new one, which we're going to create continue; OSL_ENSURE( false, "SfxBaseModel::FindOrCreateViewFrame_Impl: there already is an SfxFrame for the given XFrame, but no view in it!" ); // nowadays, we're the only instance allowed to create an SfxFrame for an XFrame, so this case here should not happen break; } } #endif SfxFrame* pTargetFrame = SfxFrame::Create( i_rFrame ); ENSURE_OR_THROW( pTargetFrame, "could not create an SfxFrame" ); i_rGuard.takeFrameOwnership( pTargetFrame ); // prepare it pTargetFrame->PrepareForDoc_Impl( *GetObjectShell() ); // create view frame pViewFrame = new SfxViewFrame( *pTargetFrame, GetObjectShell() ); } return pViewFrame; } //============================================================================= // css::frame::XModel2 css::uno::Reference< css::frame::XController2 > SAL_CALL SfxBaseModel::createViewController( const ::rtl::OUString& i_rViewName, const Sequence< PropertyValue >& i_rArguments, const Reference< XFrame >& i_rFrame ) throw (css::uno::RuntimeException , css::lang::IllegalArgumentException, css::uno::Exception ) { SfxModelGuard aGuard( *this ); if ( !i_rFrame.is() ) throw css::lang::IllegalArgumentException( ::rtl::OUString(), *this, 3 ); // find the proper SFX view factory SfxViewFactory* pViewFactory = GetObjectShell()->GetFactory().GetViewFactoryByViewName( i_rViewName ); if ( !pViewFactory ) throw IllegalArgumentException( ::rtl::OUString(), *this, 1 ); // determine previous shell (used in some special cases) Reference< XController > xPreviousController( i_rFrame->getController() ); const Reference< XModel > xMe( this ); if ( ( xPreviousController.is() ) && ( xMe != xPreviousController->getModel() ) ) { xPreviousController.clear(); } SfxViewShell* pOldViewShell = SfxViewShell::Get( xPreviousController ); OSL_ENSURE( !xPreviousController.is() || ( pOldViewShell != NULL ), "SfxBaseModel::createViewController: invalid old controller!" ); // a guard which will clean up in case of failure ::sfx::intern::ViewCreationGuard aViewCreationGuard; // determine the ViewFrame belonging to the given XFrame SfxViewFrame* pViewFrame = FindOrCreateViewFrame_Impl( i_rFrame, aViewCreationGuard ); OSL_POSTCOND( pViewFrame, "SfxBaseModel::createViewController: no frame?" ); // delegate to SFX' view factory pViewFrame->GetBindings().ENTERREGISTRATIONS(); SfxViewShell* pViewShell = pViewFactory->CreateInstance( pViewFrame, pOldViewShell ); pViewFrame->GetBindings().LEAVEREGISTRATIONS(); ENSURE_OR_THROW( pViewShell, "invalid view shell provided by factory" ); // by setting the ViewShell it is prevented that disposing the Controller will destroy this ViewFrame also pViewFrame->GetDispatcher()->SetDisableFlags( 0 ); pViewFrame->SetViewShell_Impl( pViewShell ); // remember ViewID pViewFrame->SetCurViewId_Impl( pViewFactory->GetOrdinal() ); // ensure a default controller, if the view shell did not provide an own implementation if ( !pViewShell->GetController().is() ) pViewShell->SetController( new SfxBaseController( pViewShell ) ); // pass the creation arguments to the controller SfxBaseController* pBaseController = pViewShell->GetBaseController_Impl(); ENSURE_OR_THROW( pBaseController, "invalid controller implementation!" ); pBaseController->SetCreationArguments_Impl( i_rArguments ); // some initial view settings, coming from our most recent attachResource call ::comphelper::NamedValueCollection aDocumentLoadArgs( getArgs() ); if ( aDocumentLoadArgs.getOrDefault( "ViewOnly", false ) ) pViewFrame->GetFrame().SetMenuBarOn_Impl( sal_False ); const sal_Int16 nPluginMode = aDocumentLoadArgs.getOrDefault( "PluginMode", sal_Int16( 0 ) ); if ( nPluginMode == 1 ) { pViewFrame->ForceOuterResize_Impl( sal_False ); pViewFrame->GetBindings().HidePopups( sal_True ); SfxFrame& rFrame = pViewFrame->GetFrame(); // MBA: layoutmanager of inplace frame starts locked and invisible rFrame.GetWorkWindow_Impl()->MakeVisible_Impl( sal_False ); rFrame.GetWorkWindow_Impl()->Lock_Impl( sal_True ); rFrame.GetWindow().SetBorderStyle( WINDOW_BORDER_NOBORDER ); pViewFrame->GetWindow().SetBorderStyle( WINDOW_BORDER_NOBORDER ); } // tell the guard we were successful aViewCreationGuard.releaseAll(); // outta gere return pBaseController; } //============================================================================= // RDF DocumentMetadataAccess // ::com::sun::star::rdf::XRepositorySupplier: uno::Reference< rdf::XRepository > SAL_CALL SfxBaseModel::getRDFRepository() throw (uno::RuntimeException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA(m_pData->GetDMA()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } return xDMA->getRDFRepository(); } // ::com::sun::star::rdf::XNode: ::rtl::OUString SAL_CALL SfxBaseModel::getStringValue() throw (uno::RuntimeException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA(m_pData->GetDMA()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } return xDMA->getStringValue(); } // ::com::sun::star::rdf::XURI: ::rtl::OUString SAL_CALL SfxBaseModel::getNamespace() throw (uno::RuntimeException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA(m_pData->GetDMA()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } return xDMA->getNamespace(); } ::rtl::OUString SAL_CALL SfxBaseModel::getLocalName() throw (uno::RuntimeException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA(m_pData->GetDMA()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } return xDMA->getLocalName(); } // ::com::sun::star::rdf::XDocumentMetadataAccess: uno::Reference< rdf::XMetadatable > SAL_CALL SfxBaseModel::getElementByMetadataReference( const ::com::sun::star::beans::StringPair & i_rReference) throw (uno::RuntimeException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA(m_pData->GetDMA()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } return xDMA->getElementByMetadataReference(i_rReference); } uno::Reference< rdf::XMetadatable > SAL_CALL SfxBaseModel::getElementByURI(const uno::Reference< rdf::XURI > & i_xURI) throw (uno::RuntimeException, lang::IllegalArgumentException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA(m_pData->GetDMA()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } return xDMA->getElementByURI(i_xURI); } uno::Sequence< uno::Reference< rdf::XURI > > SAL_CALL SfxBaseModel::getMetadataGraphsWithType( const uno::Reference & i_xType) throw (uno::RuntimeException, lang::IllegalArgumentException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA(m_pData->GetDMA()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } return xDMA->getMetadataGraphsWithType(i_xType); } uno::Reference SAL_CALL SfxBaseModel::addMetadataFile(const ::rtl::OUString & i_rFileName, const uno::Sequence < uno::Reference< rdf::XURI > > & i_rTypes) throw (uno::RuntimeException, lang::IllegalArgumentException, container::ElementExistException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA(m_pData->GetDMA()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } return xDMA->addMetadataFile(i_rFileName, i_rTypes); } uno::Reference SAL_CALL SfxBaseModel::importMetadataFile(::sal_Int16 i_Format, const uno::Reference< io::XInputStream > & i_xInStream, const ::rtl::OUString & i_rFileName, const uno::Reference< rdf::XURI > & i_xBaseURI, const uno::Sequence < uno::Reference< rdf::XURI > > & i_rTypes) throw (uno::RuntimeException, lang::IllegalArgumentException, datatransfer::UnsupportedFlavorException, container::ElementExistException, rdf::ParseException, io::IOException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA(m_pData->GetDMA()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } return xDMA->importMetadataFile(i_Format, i_xInStream, i_rFileName, i_xBaseURI, i_rTypes); } void SAL_CALL SfxBaseModel::removeMetadataFile( const uno::Reference< rdf::XURI > & i_xGraphName) throw (uno::RuntimeException, lang::IllegalArgumentException, container::NoSuchElementException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA(m_pData->GetDMA()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } return xDMA->removeMetadataFile(i_xGraphName); } void SAL_CALL SfxBaseModel::addContentOrStylesFile(const ::rtl::OUString & i_rFileName) throw (uno::RuntimeException, lang::IllegalArgumentException, container::ElementExistException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA(m_pData->GetDMA()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } return xDMA->addContentOrStylesFile(i_rFileName); } void SAL_CALL SfxBaseModel::removeContentOrStylesFile(const ::rtl::OUString & i_rFileName) throw (uno::RuntimeException, lang::IllegalArgumentException, container::NoSuchElementException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA(m_pData->GetDMA()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } return xDMA->removeContentOrStylesFile(i_rFileName); } void SAL_CALL SfxBaseModel::loadMetadataFromStorage( uno::Reference< embed::XStorage > const & i_xStorage, uno::Reference const & i_xBaseURI, uno::Reference const & i_xHandler) throw (uno::RuntimeException, lang::IllegalArgumentException, lang::WrappedTargetException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA( m_pData->CreateDMAUninitialized()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } try { xDMA->loadMetadataFromStorage(i_xStorage, i_xBaseURI, i_xHandler); } catch (lang::IllegalArgumentException &) { throw; // not initialized } catch (uno::Exception &) { // UGLY: if it's a RuntimeException, we can't be sure DMA is initialzed m_pData->m_xDocumentMetadata = xDMA; throw; } m_pData->m_xDocumentMetadata = xDMA; } void SAL_CALL SfxBaseModel::storeMetadataToStorage( uno::Reference< embed::XStorage > const & i_xStorage) throw (uno::RuntimeException, lang::IllegalArgumentException, lang::WrappedTargetException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA(m_pData->GetDMA()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } return xDMA->storeMetadataToStorage(i_xStorage); } void SAL_CALL SfxBaseModel::loadMetadataFromMedium( const uno::Sequence< beans::PropertyValue > & i_rMedium) throw (uno::RuntimeException, lang::IllegalArgumentException, lang::WrappedTargetException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA( m_pData->CreateDMAUninitialized()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } try { xDMA->loadMetadataFromMedium(i_rMedium); } catch (lang::IllegalArgumentException &) { throw; // not initialized } catch (uno::Exception &) { // UGLY: if it's a RuntimeException, we can't be sure DMA is initialzed m_pData->m_xDocumentMetadata = xDMA; throw; } m_pData->m_xDocumentMetadata = xDMA; } void SAL_CALL SfxBaseModel::storeMetadataToMedium( const uno::Sequence< beans::PropertyValue > & i_rMedium) throw (uno::RuntimeException, lang::IllegalArgumentException, lang::WrappedTargetException) { SfxModelGuard aGuard( *this ); const uno::Reference xDMA(m_pData->GetDMA()); if (!xDMA.is()) { throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "model has no document metadata"), *this ); } return xDMA->storeMetadataToMedium(i_rMedium); } // ===================================================================================================================== // = SfxModelSubComponent // ===================================================================================================================== SfxModelSubComponent::~SfxModelSubComponent() { } void SfxModelSubComponent::disposing() { // nothing to do here }