| /************************************************************** |
| * |
| * 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_framework.hxx" |
| //_______________________________________________ |
| // includes of own project |
| #include <loadenv/loadenv.hxx> |
| |
| #ifndef __FRAMEWORK_LOADENV_TARGETHELPER_HXX_ |
| #include <loadenv/targethelper.hxx> |
| #endif |
| #include <framework/framelistanalyzer.hxx> |
| |
| #ifndef __FRAMEWORK_CONSTANT_FRAMELOADER_HXX_ |
| #include <constant/frameloader.hxx> |
| #endif |
| |
| #ifndef __FRAMEWORK_CONSTANT_CONTENTHANDLER_HXX_ |
| #include <constant/contenthandler.hxx> |
| #endif |
| |
| #ifndef __FRAMEWORK_CONSTANT_CONTAINERQUERY_HXX_ |
| #include <constant/containerquery.hxx> |
| #endif |
| #include <interaction/quietinteraction.hxx> |
| #include <threadhelp/writeguard.hxx> |
| #include <threadhelp/readguard.hxx> |
| #include <threadhelp/resetableguard.hxx> |
| #include <properties.h> |
| #include <protocols.h> |
| #include <services.h> |
| #include <comphelper/interaction.hxx> |
| #include <framework/interaction.hxx> |
| |
| //_______________________________________________ |
| // includes of uno interface |
| #include <com/sun/star/task/ErrorCodeRequest.hpp> |
| #include <com/sun/star/uno/RuntimeException.hpp> |
| #include <com/sun/star/frame/DispatchResultState.hpp> |
| #include <com/sun/star/frame/FrameSearchFlag.hpp> |
| #include <com/sun/star/util/XURLTransformer.hpp> |
| #include <com/sun/star/ucb/XContentProviderManager.hpp> |
| #include <com/sun/star/util/XCloseable.hpp> |
| #include <com/sun/star/lang/XComponent.hpp> |
| #include <com/sun/star/lang/XServiceInfo.hpp> |
| #include <com/sun/star/lang/DisposedException.hpp> |
| #include <com/sun/star/awt/XWindow.hpp> |
| #include <com/sun/star/awt/XWindow2.hpp> |
| #include <com/sun/star/awt/XTopWindow.hpp> |
| #include <com/sun/star/frame/XModel.hpp> |
| #include <com/sun/star/frame/XFrameLoader.hpp> |
| #include <com/sun/star/frame/XSynchronousFrameLoader.hpp> |
| #include <com/sun/star/frame/XNotifyingDispatch.hpp> |
| #include <com/sun/star/task/XStatusIndicatorFactory.hpp> |
| #include <com/sun/star/task/XStatusIndicator.hpp> |
| #include <com/sun/star/util/XModifiable.hpp> |
| #include <com/sun/star/frame/XDispatchProvider.hpp> |
| #include <com/sun/star/document/XTypeDetection.hpp> |
| #include <com/sun/star/document/XActionLockable.hpp> |
| #include <com/sun/star/io/XInputStream.hpp> |
| #include <com/sun/star/task/XInteractionHandler.hpp> |
| #include <com/sun/star/container/XNameAccess.hpp> |
| #include <com/sun/star/container/XContainerQuery.hpp> |
| #include <com/sun/star/container/XEnumeration.hpp> |
| #include <com/sun/star/document/MacroExecMode.hpp> |
| #include <com/sun/star/document/UpdateDocMode.hpp> |
| |
| //_______________________________________________ |
| // includes of an other project |
| #include <vcl/window.hxx> |
| #include <vcl/wrkwin.hxx> |
| #include <vcl/syswin.hxx> |
| |
| #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ |
| #include <toolkit/unohlp.hxx> |
| #endif |
| #include <unotools/moduleoptions.hxx> |
| #include <svtools/sfxecode.hxx> |
| #include <unotools/processfactory.hxx> |
| #include <unotools/ucbhelper.hxx> |
| #include <comphelper/configurationhelper.hxx> |
| #include <rtl/ustrbuf.hxx> |
| #include <vcl/svapp.hxx> |
| |
| //_______________________________________________ |
| // namespace |
| |
| namespace framework{ |
| |
| // may there exist already a define .-( |
| #ifndef css |
| namespace css = ::com::sun::star; |
| #endif |
| |
| //_______________________________________________ |
| // declarations |
| |
| class LoadEnvListener : private ThreadHelpBase |
| , public ::cppu::WeakImplHelper2< css::frame::XLoadEventListener , |
| css::frame::XDispatchResultListener > |
| { |
| private: |
| |
| void** m_ppCheck ; |
| LoadEnv* m_pLoadEnv; |
| |
| public: |
| |
| //_______________________________________ |
| LoadEnvListener(void* pCheck , |
| LoadEnv* pLoadEnv) |
| { |
| m_ppCheck = &pCheck ; |
| m_pLoadEnv = pLoadEnv; |
| } |
| |
| //_______________________________________ |
| // frame.XLoadEventListener |
| virtual void SAL_CALL loadFinished(const css::uno::Reference< css::frame::XFrameLoader >& xLoader) |
| throw(css::uno::RuntimeException); |
| |
| virtual void SAL_CALL loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >& xLoader) |
| throw(css::uno::RuntimeException); |
| |
| //_______________________________________ |
| // frame.XDispatchResultListener |
| virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& aEvent) |
| throw(css::uno::RuntimeException); |
| |
| //_______________________________________ |
| // lang.XEventListener |
| virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) |
| throw(css::uno::RuntimeException); |
| }; |
| |
| /*----------------------------------------------- |
| 14.10.2003 13:43 |
| -----------------------------------------------*/ |
| LoadEnv::LoadEnv(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) |
| throw(LoadEnvException, css::uno::RuntimeException) |
| : ThreadHelpBase( ) |
| , m_xSMGR (xSMGR) |
| , m_pCheck (this ) |
| , m_pQuietInteraction( 0 ) |
| { |
| } |
| |
| /*----------------------------------------------- |
| 14.10.2003 13:43 |
| -----------------------------------------------*/ |
| LoadEnv::~LoadEnv() |
| { |
| m_pCheck = 0; |
| } |
| |
| /*----------------------------------------------- |
| 10.09.2003 14:05 |
| -----------------------------------------------*/ |
| css::uno::Reference< css::lang::XComponent > LoadEnv::loadComponentFromURL(const css::uno::Reference< css::frame::XComponentLoader >& xLoader, |
| const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , |
| const ::rtl::OUString& sURL , |
| const ::rtl::OUString& sTarget, |
| sal_Int32 nFlags , |
| const css::uno::Sequence< css::beans::PropertyValue >& lArgs ) |
| throw(css::lang::IllegalArgumentException, |
| css::io::IOException , |
| css::uno::RuntimeException ) |
| { |
| #ifdef WNT |
| CEnableAccessInterface e; |
| #endif |
| css::uno::Reference< css::lang::XComponent > xComponent; |
| |
| try |
| { |
| LoadEnv aEnv(xSMGR); |
| |
| aEnv.initializeLoading(sURL, |
| lArgs, |
| css::uno::Reference< css::frame::XFrame >(xLoader, css::uno::UNO_QUERY), |
| sTarget, |
| nFlags, |
| LoadEnv::E_NO_FEATURE); |
| aEnv.startLoading(); |
| aEnv.waitWhileLoading(); // wait for ever! |
| |
| xComponent = aEnv.getTargetComponent(); |
| } |
| catch(const LoadEnvException& ex) |
| { |
| switch(ex.m_nID) |
| { |
| case LoadEnvException::ID_INVALID_MEDIADESCRIPTOR: |
| throw css::lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii("Optional list of arguments seem to be corrupted."), |
| xLoader, |
| 4); |
| |
| case LoadEnvException::ID_UNSUPPORTED_CONTENT: |
| throw css::lang::IllegalArgumentException( |
| ::rtl::OUString::createFromAscii("URL seems to be an unsupported one."), |
| xLoader, |
| 1); |
| |
| default: xComponent.clear(); |
| break; |
| } |
| } |
| |
| return xComponent; |
| } |
| |
| //----------------------------------------------- |
| ::comphelper::MediaDescriptor impl_mergeMediaDescriptorWithMightExistingModelArgs(const css::uno::Sequence< css::beans::PropertyValue >& lOutsideDescriptor) |
| { |
| ::comphelper::MediaDescriptor lDescriptor(lOutsideDescriptor); |
| css::uno::Reference< css::frame::XModel > xModel = lDescriptor.getUnpackedValueOrDefault( |
| ::comphelper::MediaDescriptor::PROP_MODEL (), |
| css::uno::Reference< css::frame::XModel > ()); |
| if (xModel.is ()) |
| { |
| ::comphelper::MediaDescriptor lModelDescriptor(xModel->getArgs()); |
| ::comphelper::MediaDescriptor::iterator pIt = lModelDescriptor.find( ::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE() ); |
| if ( pIt != lModelDescriptor.end() ) |
| lDescriptor[::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()] = pIt->second; |
| } |
| |
| return lDescriptor; |
| } |
| |
| /*----------------------------------------------- |
| 20.08.2003 09:49 |
| -----------------------------------------------*/ |
| void LoadEnv::initializeLoading(const ::rtl::OUString& sURL , |
| const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor, |
| const css::uno::Reference< css::frame::XFrame >& xBaseFrame , |
| const ::rtl::OUString& sTarget , |
| sal_Int32 nSearchFlags , |
| EFeature eFeature , // => use default ... |
| EContentType eContentType ) // => use default ... |
| throw(LoadEnvException, css::uno::RuntimeException) |
| { |
| // SAFE -> ---------------------------------- |
| WriteGuard aWriteLock(m_aLock); |
| |
| // Handle still running processes! |
| if (m_xAsynchronousJob.is()) |
| throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING); |
| |
| // take over all new parameters. |
| m_xTargetFrame.clear(); |
| m_xBaseFrame = xBaseFrame ; |
| m_lMediaDescriptor = impl_mergeMediaDescriptorWithMightExistingModelArgs(lMediaDescriptor); |
| m_sTarget = sTarget ; |
| m_nSearchFlags = nSearchFlags ; |
| m_eFeature = eFeature ; |
| m_eContentType = eContentType ; |
| m_bCloseFrameOnError = sal_False ; |
| m_bReactivateControllerOnError = sal_False ; |
| m_bLoaded = sal_False ; |
| |
| // try to find out, if its realy a content, which can be loaded or must be "handled" |
| // We use a default value for this in-parameter. Then we have to start a complex check method |
| // internaly. But if this check was already done outside it can be supressed to perform |
| // the load request. We take over the result then! |
| if (m_eContentType == E_UNSUPPORTED_CONTENT) |
| { |
| m_eContentType = LoadEnv::classifyContent(sURL, lMediaDescriptor); |
| if (m_eContentType == E_UNSUPPORTED_CONTENT) |
| throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT); |
| } |
| |
| // make URL part of the MediaDescriptor |
| // It doesnt mater, if its already an item of it. |
| // It must be the same value ... so we can overwrite it :-) |
| m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_URL()] <<= sURL; |
| |
| // parse it - because some following code require that |
| m_aURL.Complete = sURL; |
| css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY); |
| xParser->parseStrict(m_aURL); |
| |
| // BTW: Split URL and JumpMark ... |
| // Because such mark is an explicit value of the media descriptor! |
| if (m_aURL.Mark.getLength()) |
| m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_JUMPMARK()] <<= m_aURL.Mark; |
| |
| // By the way: remove the old and deprecated value "FileName" from the descriptor! |
| ::comphelper::MediaDescriptor::iterator pIt = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_FILENAME()); |
| if (pIt != m_lMediaDescriptor.end()) |
| m_lMediaDescriptor.erase(pIt); |
| |
| // patch the MediaDescriptor, so it fullfill the outside requirements |
| // Means especialy items like e.g. UI InteractionHandler, Status Indicator, |
| // MacroExecutionMode etcpp. |
| |
| /*TODO progress is bound to a frame ... How can we set it here? */ |
| |
| // UI mode |
| const bool bUIMode = |
| ( ( m_eFeature & E_WORK_WITH_UI ) == E_WORK_WITH_UI ) && |
| ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False ) == sal_False ) && |
| ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_PREVIEW(), sal_False ) == sal_False ); |
| |
| initializeUIDefaults( |
| m_xSMGR, |
| m_lMediaDescriptor, |
| bUIMode, |
| &m_pQuietInteraction |
| ); |
| |
| aWriteLock.unlock(); |
| // <- SAFE ---------------------------------- |
| } |
| |
| /*----------------------------------------------- |
| 22.01.2010 |
| -----------------------------------------------*/ |
| void LoadEnv::initializeUIDefaults( const css::uno::Reference< css::lang::XMultiServiceFactory >& i_rSMGR, |
| ::comphelper::MediaDescriptor& io_lMediaDescriptor, const bool i_bUIMode, |
| QuietInteraction** o_ppQuietInteraction ) |
| { |
| css::uno::Reference< css::task::XInteractionHandler > xInteractionHandler; |
| sal_Int16 nMacroMode ; |
| sal_Int16 nUpdateMode ; |
| |
| if ( i_bUIMode ) |
| { |
| nMacroMode = css::document::MacroExecMode::USE_CONFIG; |
| nUpdateMode = css::document::UpdateDocMode::ACCORDING_TO_CONFIG; |
| try |
| { |
| xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(i_rSMGR->createInstance(IMPLEMENTATIONNAME_UIINTERACTIONHANDLER), css::uno::UNO_QUERY); |
| } |
| catch(const css::uno::RuntimeException&) {throw;} |
| catch(const css::uno::Exception& ) { } |
| } |
| // hidden mode |
| else |
| { |
| nMacroMode = css::document::MacroExecMode::NEVER_EXECUTE; |
| nUpdateMode = css::document::UpdateDocMode::NO_UPDATE; |
| QuietInteraction* pQuietInteraction = new QuietInteraction(); |
| xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(static_cast< css::task::XInteractionHandler* >(pQuietInteraction), css::uno::UNO_QUERY); |
| if ( o_ppQuietInteraction != NULL ) |
| { |
| *o_ppQuietInteraction = pQuietInteraction; |
| (*o_ppQuietInteraction)->acquire(); |
| } |
| } |
| |
| if ( |
| (xInteractionHandler.is() ) && |
| (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()) == io_lMediaDescriptor.end()) |
| ) |
| { |
| io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()] <<= xInteractionHandler; |
| } |
| |
| if (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()) == io_lMediaDescriptor.end()) |
| io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()] <<= nMacroMode; |
| |
| if (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_UPDATEDOCMODE()) == io_lMediaDescriptor.end()) |
| io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_UPDATEDOCMODE()] <<= nUpdateMode; |
| } |
| |
| /*----------------------------------------------- |
| 15.08.2003 08:16 |
| -----------------------------------------------*/ |
| void LoadEnv::startLoading() |
| throw(LoadEnvException, css::uno::RuntimeException) |
| { |
| // SAFE -> |
| ReadGuard aReadLock(m_aLock); |
| |
| // Handle still running processes! |
| if (m_xAsynchronousJob.is()) |
| throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING); |
| |
| // content can not be loaded or handled |
| // check "classifyContent()" failed before ... |
| if (m_eContentType == E_UNSUPPORTED_CONTENT) |
| throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT); |
| |
| // <- SAFE |
| aReadLock.unlock(); |
| |
| // detect its type/filter etcpp. |
| // These information will be available by the |
| // used descriptor member afterwards and is needed |
| // for all following operations! |
| // Note: An exception will be thrown, in case operation was not successfully ... |
| if (m_eContentType != E_CAN_BE_SET)/* Attention: special feature to set existing component on a frame must ignore type detection! */ |
| impl_detectTypeAndFilter(); |
| |
| // start loading the content ... |
| // Attention: Dont check m_eContentType deeper then UNSUPPORTED/SUPPORTED! |
| // Because it was made in th easiest way ... may a flat detection was made only. |
| // And such simple detection can fail some times .-) |
| // Use another strategy here. Try it and let it run into the case "loading not possible". |
| sal_Bool bStarted = sal_False; |
| if ( |
| ((m_eFeature & E_ALLOW_CONTENTHANDLER) == E_ALLOW_CONTENTHANDLER) && |
| (m_eContentType != E_CAN_BE_SET ) /* Attention: special feature to set existing component on a frame must ignore type detection! */ |
| ) |
| { |
| bStarted = impl_handleContent(); |
| } |
| |
| if (!bStarted) |
| bStarted = impl_loadContent(); |
| |
| // not started => general error |
| // We cant say - what was the reason for. |
| if (!bStarted) |
| throw LoadEnvException(LoadEnvException::ID_GENERAL_ERROR); |
| } |
| |
| /*----------------------------------------------- |
| 15.08.2003 09:50 |
| TODO |
| First draft does not implement timeout using [ms]. |
| Current implementation counts yield calls only ... |
| -----------------------------------------------*/ |
| sal_Bool LoadEnv::waitWhileLoading(sal_uInt32 nTimeout) |
| throw(LoadEnvException, css::uno::RuntimeException) |
| { |
| // Because its not a good idea to block the main thread |
| // (and we cant be shure that we are currently not used inside the |
| // main thread!), we cant use conditions here realy. We must yield |
| // in an intellegent manner :-) |
| |
| sal_Int32 nTime = nTimeout; |
| while(true) |
| { |
| // SAFE -> ------------------------------ |
| ReadGuard aReadLock1(m_aLock); |
| if (!m_xAsynchronousJob.is()) |
| break; |
| aReadLock1.unlock(); |
| // <- SAFE ------------------------------ |
| |
| Application::Yield(); |
| |
| // forever! |
| if (nTimeout==0) |
| continue; |
| |
| // timed out? |
| --nTime; |
| if (nTime<1) |
| break; |
| } |
| |
| // SAFE -> ---------------------------------- |
| ReadGuard aReadLock2(m_aLock); |
| return !m_xAsynchronousJob.is(); |
| // <- SAFE ---------------------------------- |
| } |
| |
| /*----------------------------------------------- |
| 20.08.2003 10:00 |
| -----------------------------------------------*/ |
| void LoadEnv::cancelLoading() |
| throw(LoadEnvException, css::uno::RuntimeException) |
| { |
| // PARTIAL(!) SAFE -> ------------------------------ |
| ReadGuard aReadLock(m_aLock); |
| |
| // Still running? Might waitWhileLoading() |
| // runned into the timeout! |
| if (m_xAsynchronousJob.is()) |
| { |
| // try to cancel it ... if its an asynchronous frame loader |
| css::uno::Reference< css::frame::XFrameLoader > xAsyncLoader(m_xAsynchronousJob, css::uno::UNO_QUERY); |
| if (xAsyncLoader.is()) |
| { |
| aReadLock.unlock(); |
| // <- BREAK SAFE ------------------------------ |
| xAsyncLoader->cancel(); |
| // <- RESTART SAFE ---------------------------- |
| aReadLock.lock(); |
| /* Attention: |
| After returning from any cancel/dispose call, neither the frame nor weself |
| may be called back. Because only we can cancel this job, we already know |
| the result! => Thats why its not usefull nor neccessary to wait for any |
| asynchronous listener notification. |
| */ |
| m_bLoaded = sal_False; |
| m_xAsynchronousJob.clear(); |
| } |
| // or may be its a content handler? Such handler cant be cancelled in its running |
| // operation :-( And we cant deregister us there again :-( |
| // => The only chance is an exception :-) |
| else |
| throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING); |
| } |
| |
| impl_reactForLoadingState(); |
| |
| aReadLock.unlock(); |
| // <- PARTIAL(!) SAFE ------------------------------ |
| } |
| |
| /*----------------------------------------------- |
| 14.08.2003 13:33 |
| -----------------------------------------------*/ |
| css::uno::Reference< css::frame::XFrame > LoadEnv::getTarget() const |
| { |
| // SAFE -> |
| ReadGuard aReadLock(m_aLock); |
| return m_xTargetFrame; |
| // <- SAFE |
| } |
| |
| /*----------------------------------------------- |
| 14.08.2003 13:35 |
| -----------------------------------------------*/ |
| css::uno::Reference< css::lang::XComponent > LoadEnv::getTargetComponent() const |
| { |
| // SAFE -> |
| ReadGuard aReadLock(m_aLock); |
| |
| if (!m_xTargetFrame.is()) |
| return css::uno::Reference< css::lang::XComponent >(); |
| |
| css::uno::Reference< css::frame::XController > xController = m_xTargetFrame->getController(); |
| if (!xController.is()) |
| return css::uno::Reference< css::lang::XComponent >(m_xTargetFrame->getComponentWindow(), css::uno::UNO_QUERY); |
| |
| css::uno::Reference< css::frame::XModel > xModel = xController->getModel(); |
| if (!xModel.is()) |
| return css::uno::Reference< css::lang::XComponent >(xController, css::uno::UNO_QUERY); |
| |
| return css::uno::Reference< css::lang::XComponent >(xModel, css::uno::UNO_QUERY); |
| // <- SAFE |
| } |
| |
| /*----------------------------------------------- |
| 15.08.2003 11:15 |
| -----------------------------------------------*/ |
| void SAL_CALL LoadEnvListener::loadFinished(const css::uno::Reference< css::frame::XFrameLoader >&) |
| throw(css::uno::RuntimeException) |
| { |
| // SAFE -> ---------------------------------- |
| WriteGuard aWriteLock(m_aLock); |
| |
| if (m_ppCheck && *m_ppCheck) |
| m_pLoadEnv->impl_setResult(sal_True); |
| m_ppCheck = NULL; |
| |
| aWriteLock.unlock(); |
| // <- SAFE ---------------------------------- |
| } |
| |
| /*----------------------------------------------- |
| 14.10.2003 12:23 |
| -----------------------------------------------*/ |
| void SAL_CALL LoadEnvListener::loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >&) |
| throw(css::uno::RuntimeException) |
| { |
| // SAFE -> ---------------------------------- |
| WriteGuard aWriteLock(m_aLock); |
| |
| if (m_ppCheck && *m_ppCheck) |
| m_pLoadEnv->impl_setResult(sal_False); |
| m_ppCheck = NULL; |
| |
| aWriteLock.unlock(); |
| // <- SAFE ---------------------------------- |
| } |
| |
| /*----------------------------------------------- |
| 14.10.2003 12:23 |
| -----------------------------------------------*/ |
| void SAL_CALL LoadEnvListener::dispatchFinished(const css::frame::DispatchResultEvent& aEvent) |
| throw(css::uno::RuntimeException) |
| { |
| // SAFE -> ---------------------------------- |
| WriteGuard aWriteLock(m_aLock); |
| |
| if (!m_ppCheck || !*m_ppCheck) |
| return; |
| |
| switch(aEvent.State) |
| { |
| case css::frame::DispatchResultState::FAILURE : |
| m_pLoadEnv->impl_setResult(sal_False); |
| break; |
| |
| case css::frame::DispatchResultState::SUCCESS : |
| m_pLoadEnv->impl_setResult(sal_False); |
| break; |
| |
| case css::frame::DispatchResultState::DONTKNOW : |
| m_pLoadEnv->impl_setResult(sal_False); |
| break; |
| } |
| m_ppCheck = NULL; |
| |
| aWriteLock.unlock(); |
| // <- SAFE ---------------------------------- |
| } |
| |
| /*----------------------------------------------- |
| 14.10.2003 12:24 |
| -----------------------------------------------*/ |
| void SAL_CALL LoadEnvListener::disposing(const css::lang::EventObject&) |
| throw(css::uno::RuntimeException) |
| { |
| // SAFE -> ---------------------------------- |
| WriteGuard aWriteLock(m_aLock); |
| |
| if (m_ppCheck && *m_ppCheck) |
| m_pLoadEnv->impl_setResult(sal_False); |
| m_ppCheck = NULL; |
| |
| aWriteLock.unlock(); |
| // <- SAFE ---------------------------------- |
| } |
| |
| /*----------------------------------------------- |
| 14.10.2003 12:20 |
| -----------------------------------------------*/ |
| void LoadEnv::impl_setResult(sal_Bool bResult) |
| { |
| // SAFE -> ---------------------------------- |
| WriteGuard aWriteLock(m_aLock); |
| |
| m_bLoaded = bResult; |
| |
| impl_reactForLoadingState(); |
| |
| // clearing of this reference will unblock waitWhileLoading()! |
| // So we must be shure, that loading process was realy finished. |
| // => do it as last operation of this method ... |
| m_xAsynchronousJob.clear(); |
| |
| aWriteLock.unlock(); |
| // <- SAFE ---------------------------------- |
| } |
| |
| /*----------------------------------------------- |
| 06.02.2004 14:03 |
| TODO: Is it a good idea to change Sequence<> |
| parameter to stl-adapter? |
| -----------------------------------------------*/ |
| LoadEnv::EContentType LoadEnv::classifyContent(const ::rtl::OUString& sURL , |
| const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor) |
| { |
| //------------------------------------------- |
| // (i) Filter some special well known URL protocols, |
| // which can not be handled or loaded in general. |
| // Of course an empty URL must be ignored here too. |
| // Note: These URL schemata are fix and well known ... |
| // But there can be some additional ones, which was not |
| // defined at implementation time of this class :-( |
| // So we have to make shure, that the following code |
| // can detect such protocol schemata too :-) |
| |
| if( |
| (!sURL.getLength() ) || |
| (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_UNO )) || |
| (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SLOT )) || |
| (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MACRO )) || |
| (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SERVICE)) || |
| (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MAILTO )) || |
| (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_NEWS )) |
| ) |
| { |
| return E_UNSUPPORTED_CONTENT; |
| } |
| |
| //------------------------------------------- |
| // (ii) Some special URLs indicates a given input stream, |
| // a full featured document model directly or |
| // specify a request for opening an empty document. |
| // Such contents are loadable in general. |
| // But we have to check, if the media descriptor contains |
| // all needed resources. If they are missing - the following |
| // load request will fail. |
| |
| /* Attention: The following code cant work on such special URLs! |
| It should not break the office .. but it make no sense |
| to start expensive object creations and complex search |
| algorithm if its clear, that such URLs must be handled |
| in a special way .-) |
| */ |
| |
| // creation of new documents |
| if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_FACTORY)) |
| return E_CAN_BE_LOADED; |
| |
| // using of an existing input stream |
| ::comphelper::MediaDescriptor stlMediaDescriptor(lMediaDescriptor); |
| ::comphelper::MediaDescriptor::const_iterator pIt; |
| if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_STREAM)) |
| { |
| pIt = stlMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_INPUTSTREAM()); |
| css::uno::Reference< css::io::XInputStream > xStream; |
| if (pIt != stlMediaDescriptor.end()) |
| pIt->second >>= xStream; |
| if (xStream.is()) |
| return E_CAN_BE_LOADED; |
| LOG_WARNING("LoadEnv::classifyContent()", "loading from stream with right URL but invalid stream detected") |
| return E_UNSUPPORTED_CONTENT; |
| } |
| |
| // using of a full featured document |
| if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_OBJECT)) |
| { |
| pIt = stlMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_MODEL()); |
| css::uno::Reference< css::frame::XModel > xModel; |
| if (pIt != stlMediaDescriptor.end()) |
| pIt->second >>= xModel; |
| if (xModel.is()) |
| return E_CAN_BE_SET; |
| LOG_WARNING("LoadEnv::classifyContent()", "loading with object with right URL but invalid object detected") |
| return E_UNSUPPORTED_CONTENT; |
| } |
| |
| // following operatons can work on an internal type name only :-( |
| css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::utl::getProcessServiceFactory(); |
| css::uno::Reference< css::document::XTypeDetection > xDetect(xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY); |
| |
| ::rtl::OUString sType = xDetect->queryTypeByURL(sURL); |
| |
| css::uno::Sequence< css::beans::NamedValue > lQuery(1) ; |
| css::uno::Reference< css::container::XContainerQuery > xContainer ; |
| css::uno::Reference< css::container::XEnumeration > xSet ; |
| css::uno::Sequence< ::rtl::OUString > lTypesReg(1); |
| |
| /* |
| //------------------------------------------- |
| lQuery[0].Name = ::framework::constant::Filter::PROP_TYPE; |
| lQuery[0].Value <<= sType; |
| |
| xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_FILTERFACTORY), css::uno::UNO_QUERY); |
| xSet = xContainer->createSubSetEnumerationByProperties(lQuery); |
| // at least one registered frame loader is enough! |
| if (xSet->hasMoreElements()) |
| return E_CAN_BE_LOADED; |
| */ |
| |
| //------------------------------------------- |
| // (iii) If a FrameLoader service (or at least |
| // a Filter) can be found, which supports |
| // this URL - it must be a loadable content. |
| // Because both items are registered for types |
| // its enough to check for frame loaders only. |
| // Mos of our filters are handled by our global |
| // default loader. But there exist some specialized |
| // loader, which does not work on top of filters! |
| // So its not enough to search on the filter configuration. |
| // Further its not enough to search for types! |
| // Because there exist some types, which are referenced by |
| // other objects ... but not by filters nor frame loaders! |
| |
| lTypesReg[0] = sType; |
| lQuery[0].Name = ::framework::constant::FrameLoader::PROP_TYPES; |
| lQuery[0].Value <<= lTypesReg; |
| |
| xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_FRAMELOADERFACTORY), css::uno::UNO_QUERY); |
| xSet = xContainer->createSubSetEnumerationByProperties(lQuery); |
| // at least one registered frame loader is enough! |
| if (xSet->hasMoreElements()) |
| return E_CAN_BE_LOADED; |
| |
| //------------------------------------------- |
| // (iv) Some URL protocols are supported by special services. |
| // E.g. ContentHandler. |
| // Such contents can be handled ... but not loaded. |
| |
| lTypesReg[0] = sType; |
| lQuery[0].Name = ::framework::constant::ContentHandler::PROP_TYPES; |
| lQuery[0].Value <<= lTypesReg; |
| |
| xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_CONTENTHANDLERFACTORY), css::uno::UNO_QUERY); |
| xSet = xContainer->createSubSetEnumerationByProperties(lQuery); |
| // at least one registered content handler is enough! |
| if (xSet->hasMoreElements()) |
| return E_CAN_BE_HANDLED; |
| |
| //------------------------------------------- |
| // (v) Last but not least the UCB is used inside office to |
| // load contents. He has a special configuration to know |
| // which URL schemata can be used inside office. |
| css::uno::Reference< css::ucb::XContentProviderManager > xUCB(xSMGR->createInstance(SERVICENAME_UCBCONTENTBROKER), css::uno::UNO_QUERY); |
| if (xUCB->queryContentProvider(sURL).is()) |
| return E_CAN_BE_LOADED; |
| |
| //------------------------------------------- |
| // (TODO) At this point, we have no idea .-) |
| // But it seems to be better, to break all |
| // further requests for this URL. Otherwhise |
| // we can run into some trouble. |
| return E_UNSUPPORTED_CONTENT; |
| } |
| |
| /*----------------------------------------------- |
| 03.11.2003 09:31 |
| -----------------------------------------------*/ |
| void LoadEnv::impl_detectTypeAndFilter() |
| throw(LoadEnvException, css::uno::RuntimeException) |
| { |
| static ::rtl::OUString TYPEPROP_PREFERREDFILTER = ::rtl::OUString::createFromAscii("PreferredFilter"); |
| static ::rtl::OUString FILTERPROP_FLAGS = ::rtl::OUString::createFromAscii("Flags" ); |
| static sal_Int32 FILTERFLAG_TEMPLATEPATH = 16; |
| |
| // SAFE -> |
| ReadGuard aReadLock(m_aLock); |
| |
| // Attention: Because our stl media descriptor is a copy of an uno sequence |
| // we cant use as an in/out parameter here. Copy it before and dont forget to |
| // update structure afterwards again! |
| css::uno::Sequence< css::beans::PropertyValue > lDescriptor = m_lMediaDescriptor.getAsConstPropertyValueList(); |
| css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; |
| |
| aReadLock.unlock(); |
| // <- SAFE |
| |
| ::rtl::OUString sType; |
| css::uno::Reference< css::document::XTypeDetection > xDetect(xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY); |
| if (xDetect.is()) |
| sType = xDetect->queryTypeByDescriptor(lDescriptor, sal_True); /*TODO should deep detection be able for enable/disable it from outside? */ |
| |
| // no valid content -> loading not possible |
| if (!sType.getLength()) |
| throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT); |
| |
| // SAFE -> |
| WriteGuard aWriteLock(m_aLock); |
| |
| // detection was successfully => update the descriptor member of this class |
| m_lMediaDescriptor << lDescriptor; |
| m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()] <<= sType; |
| // Is there an already detected (may be preselected) filter? |
| // see below ... |
| ::rtl::OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_FILTERNAME(), ::rtl::OUString()); |
| |
| aWriteLock.unlock(); |
| // <- SAFE |
| |
| // But the type isnt enough. For loading sometimes we need more informations. |
| // E.g. for our "_default" feature, where we recylce any frame which contains |
| // and "Untitled" document, we must know if the new document is based on a template! |
| // But this information is available as a filter property only. |
| // => We must try(!) to detect the right filter for this load request. |
| // On the other side ... if no filter is available .. ignore it. |
| // Then the type information must be enough. |
| if (!sFilter.getLength()) |
| { |
| // no -> try to find a preferred filter for the detected type. |
| // Dont forget to updatet he media descriptor. |
| css::uno::Reference< css::container::XNameAccess > xTypeCont(xDetect, css::uno::UNO_QUERY_THROW); |
| try |
| { |
| ::comphelper::SequenceAsHashMap lTypeProps(xTypeCont->getByName(sType)); |
| sFilter = lTypeProps.getUnpackedValueOrDefault(TYPEPROP_PREFERREDFILTER, ::rtl::OUString()); |
| if (sFilter.getLength()) |
| { |
| // SAFE -> |
| aWriteLock.lock(); |
| m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter; |
| aWriteLock.unlock(); |
| // <- SAFE |
| } |
| } |
| catch(const css::container::NoSuchElementException&) |
| {} |
| } |
| |
| // check if the filter (if one exists) points to a template format filter. |
| // Then we have to add the property "AsTemplate". |
| // We need this information to decide afterwards if we can use a "recycle frame" |
| // for target "_default" or has to create a new one everytimes. |
| // On the other side we have to supress that, if this property already exists |
| // and should trigger a special handling. Then the outside calli of this method here, |
| // has to know, what he is doing .-) |
| |
| sal_Bool bIsOwnTemplate = sal_False; |
| if (sFilter.getLength()) |
| { |
| css::uno::Reference< css::container::XNameAccess > xFilterCont(xSMGR->createInstance(SERVICENAME_FILTERFACTORY), css::uno::UNO_QUERY_THROW); |
| try |
| { |
| ::comphelper::SequenceAsHashMap lFilterProps(xFilterCont->getByName(sFilter)); |
| sal_Int32 nFlags = lFilterProps.getUnpackedValueOrDefault(FILTERPROP_FLAGS, (sal_Int32)0); |
| bIsOwnTemplate = ((nFlags & FILTERFLAG_TEMPLATEPATH) == FILTERFLAG_TEMPLATEPATH); |
| } |
| catch(const css::container::NoSuchElementException&) |
| {} |
| } |
| if (bIsOwnTemplate) |
| { |
| // SAFE -> |
| aWriteLock.lock(); |
| // Dont overwrite external decisions! See comments before ... |
| ::comphelper::MediaDescriptor::const_iterator pAsTemplateItem = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_ASTEMPLATE()); |
| if (pAsTemplateItem == m_lMediaDescriptor.end()) |
| m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_ASTEMPLATE()] <<= sal_True; |
| aWriteLock.unlock(); |
| // <- SAFE |
| } |
| } |
| |
| /*----------------------------------------------- |
| 15.08.2003 09:38 |
| -----------------------------------------------*/ |
| sal_Bool LoadEnv::impl_handleContent() |
| throw(LoadEnvException, css::uno::RuntimeException) |
| { |
| // SAFE -> ----------------------------------- |
| ReadGuard aReadLock(m_aLock); |
| |
| // the type must exist inside the descriptor ... otherwhise this class is implemented wrong :-) |
| ::rtl::OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), ::rtl::OUString()); |
| if (!sType.getLength()) |
| throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR); |
| |
| // convert media descriptor and URL to right format for later interface call! |
| css::uno::Sequence< css::beans::PropertyValue > lDescriptor; |
| m_lMediaDescriptor >> lDescriptor; |
| css::util::URL aURL = m_aURL; |
| |
| // get neccessary container to query for a handler object |
| css::uno::Reference< css::lang::XMultiServiceFactory > xFactory(m_xSMGR->createInstance(SERVICENAME_CONTENTHANDLERFACTORY), css::uno::UNO_QUERY); |
| css::uno::Reference< css::container::XContainerQuery > xQuery (xFactory , css::uno::UNO_QUERY); |
| |
| aReadLock.unlock(); |
| // <- SAFE ----------------------------------- |
| |
| // query |
| css::uno::Sequence< ::rtl::OUString > lTypeReg(1); |
| lTypeReg[0] = sType; |
| |
| css::uno::Sequence< css::beans::NamedValue > lQuery(1); |
| lQuery[0].Name = ::framework::constant::ContentHandler::PROP_TYPES; |
| lQuery[0].Value <<= lTypeReg; |
| |
| css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery); |
| while(xSet->hasMoreElements()) |
| { |
| ::comphelper::SequenceAsHashMap lProps (xSet->nextElement()); |
| ::rtl::OUString sHandler = lProps.getUnpackedValueOrDefault(::framework::constant::ContentHandler::PROP_NAME, ::rtl::OUString()); |
| |
| css::uno::Reference< css::frame::XNotifyingDispatch > xHandler; |
| try |
| { |
| xHandler = css::uno::Reference< css::frame::XNotifyingDispatch >(xFactory->createInstance(sHandler), css::uno::UNO_QUERY); |
| if (!xHandler.is()) |
| continue; |
| } |
| catch(const css::uno::RuntimeException&) |
| { throw; } |
| catch(const css::uno::Exception&) |
| { continue; } |
| |
| // SAFE -> ----------------------------------- |
| WriteGuard aWriteLock(m_aLock); |
| m_xAsynchronousJob = xHandler; |
| m_pCheck = this; |
| LoadEnvListener* pListener = new LoadEnvListener(m_pCheck, this); |
| aWriteLock.unlock(); |
| // <- SAFE ----------------------------------- |
| |
| css::uno::Reference< css::frame::XDispatchResultListener > xListener(static_cast< css::frame::XDispatchResultListener* >(pListener), css::uno::UNO_QUERY); |
| xHandler->dispatchWithNotification(aURL, lDescriptor, xListener); |
| |
| return sal_True; |
| } |
| |
| return sal_False; |
| } |
| |
| //----------------------------------------------- |
| sal_Bool LoadEnv::impl_furtherDocsAllowed() |
| { |
| // SAFE -> |
| ReadGuard aReadLock(m_aLock); |
| css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; |
| aReadLock.unlock(); |
| // <- SAFE |
| |
| sal_Bool bAllowed = sal_True; |
| |
| try |
| { |
| css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey( |
| xSMGR, |
| ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/"), |
| ::rtl::OUString::createFromAscii("Misc"), |
| ::rtl::OUString::createFromAscii("MaxOpenDocuments"), |
| ::comphelper::ConfigurationHelper::E_READONLY); |
| |
| // NIL means: count of allowed documents = infinite ! |
| // => return sal_True |
| if ( ! aVal.hasValue()) |
| bAllowed = sal_True; |
| else |
| { |
| sal_Int32 nMaxOpenDocuments = 0; |
| aVal >>= nMaxOpenDocuments; |
| |
| css::uno::Reference< css::frame::XFramesSupplier > xDesktop( |
| xSMGR->createInstance(SERVICENAME_DESKTOP), |
| css::uno::UNO_QUERY_THROW); |
| |
| FrameListAnalyzer aAnalyzer(xDesktop, |
| css::uno::Reference< css::frame::XFrame >(), |
| FrameListAnalyzer::E_HELP | |
| FrameListAnalyzer::E_BACKINGCOMPONENT | |
| FrameListAnalyzer::E_HIDDEN); |
| |
| sal_Int32 nOpenDocuments = aAnalyzer.m_lOtherVisibleFrames.getLength(); |
| bAllowed = (nOpenDocuments < nMaxOpenDocuments); |
| } |
| } |
| catch(const css::uno::Exception&) |
| { bAllowed = sal_True; } // !! internal errors are no reason to disturb the office from opening documents .-) |
| |
| if ( ! bAllowed ) |
| { |
| // SAFE -> |
| aReadLock.lock(); |
| css::uno::Reference< css::task::XInteractionHandler > xInteraction = m_lMediaDescriptor.getUnpackedValueOrDefault( |
| ::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER(), |
| css::uno::Reference< css::task::XInteractionHandler >()); |
| aReadLock.unlock(); |
| // <- SAFE |
| |
| if (xInteraction.is()) |
| { |
| css::uno::Any aInteraction; |
| css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations(2); |
| |
| comphelper::OInteractionAbort* pAbort = new comphelper::OInteractionAbort(); |
| comphelper::OInteractionApprove* pApprove = new comphelper::OInteractionApprove(); |
| |
| lContinuations[0] = css::uno::Reference< css::task::XInteractionContinuation >( |
| static_cast< css::task::XInteractionContinuation* >(pAbort), |
| css::uno::UNO_QUERY_THROW); |
| lContinuations[1] = css::uno::Reference< css::task::XInteractionContinuation >( |
| static_cast< css::task::XInteractionContinuation* >(pApprove), |
| css::uno::UNO_QUERY_THROW); |
| |
| css::task::ErrorCodeRequest aErrorCode; |
| aErrorCode.ErrCode = ERRCODE_SFX_NOMOREDOCUMENTSALLOWED; |
| aInteraction <<= aErrorCode; |
| xInteraction->handle( InteractionRequest::CreateRequest(aInteraction, lContinuations) ); |
| } |
| } |
| |
| return bAllowed; |
| } |
| |
| //----------------------------------------------- |
| sal_Bool LoadEnv::impl_loadContent() |
| throw(LoadEnvException, css::uno::RuntimeException) |
| { |
| // SAFE -> ----------------------------------- |
| WriteGuard aWriteLock(m_aLock); |
| |
| // search or create right target frame |
| ::rtl::OUString sTarget = m_sTarget; |
| if (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_DEFAULT)) |
| { |
| m_xTargetFrame = impl_searchAlreadyLoaded(); |
| if (m_xTargetFrame.is()) |
| { |
| impl_setResult(sal_True); |
| return sal_True; |
| } |
| m_xTargetFrame = impl_searchRecycleTarget(); |
| } |
| |
| if (! m_xTargetFrame.is()) |
| { |
| if ( |
| (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_BLANK )) || |
| (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_DEFAULT)) |
| ) |
| { |
| if (! impl_furtherDocsAllowed()) |
| return sal_False; |
| m_xTargetFrame = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0); |
| m_bCloseFrameOnError = m_xTargetFrame.is(); |
| } |
| else |
| { |
| sal_Int32 nFlags = m_nSearchFlags & ~css::frame::FrameSearchFlag::CREATE; |
| m_xTargetFrame = m_xBaseFrame->findFrame(sTarget, nFlags); |
| if (! m_xTargetFrame.is()) |
| { |
| if (! impl_furtherDocsAllowed()) |
| return sal_False; |
| m_xTargetFrame = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0); |
| m_bCloseFrameOnError = m_xTargetFrame.is(); |
| } |
| } |
| } |
| |
| // If we couldn't find a valid frame or the frame has no container window |
| // we have to throw an exception. |
| if ( |
| ( ! m_xTargetFrame.is() ) || |
| ( ! m_xTargetFrame->getContainerWindow().is() ) |
| ) |
| throw LoadEnvException(LoadEnvException::ID_NO_TARGET_FOUND); |
| |
| css::uno::Reference< css::frame::XFrame > xTargetFrame = m_xTargetFrame; |
| |
| // Now we have a valid frame ... and type detection was already done. |
| // We should apply the module dependend window position and size to the |
| // frame window. |
| impl_applyPersistentWindowState(xTargetFrame->getContainerWindow()); |
| |
| // Don't forget to lock task for following load process. Otherwise it could die |
| // during this operation runs by terminating the office or closing this task via api. |
| // If we set this lock "close()" will return false and closing will be broken. |
| // Attention: Don't forget to reset this lock again after finishing operation. |
| // Otherwise task AND office couldn't die!!! |
| // This includes gracefully handling of Exceptions (Runtime!) too ... |
| // Thats why we use a specialized guard, which will reset the lock |
| // if it will be run out of scope. |
| |
| // Note further: ignore if this internal guard already contains a resource. |
| // Might impl_searchRecylcTarget() set it before. But incase this impl-method wasnt used |
| // and the target frame was new created ... this lock here must be set! |
| css::uno::Reference< css::document::XActionLockable > xTargetLock(xTargetFrame, css::uno::UNO_QUERY); |
| m_aTargetLock.setResource(xTargetLock); |
| |
| // Add status indicator to descriptor. Loader can show an progresses then. |
| // But don't do it, if loading should be hidden or preview is used ...! |
| // So we prevent our code against wrong using. Why? |
| // It could be, that using of this progress could make trouble. e.g. He make window visible ... |
| // but shouldn't do that. But if no indicator is available ... nobody has a chance to do that! |
| sal_Bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False ); |
| sal_Bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_MINIMIZED() , sal_False ); |
| sal_Bool bPreview = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_PREVIEW() , sal_False ); |
| css::uno::Reference< css::task::XStatusIndicator > xProgress = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_STATUSINDICATOR(), css::uno::Reference< css::task::XStatusIndicator >()); |
| |
| if (!bHidden && !bMinimized && !bPreview && !xProgress.is()) |
| { |
| // Note: its an optional interface! |
| css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xTargetFrame, css::uno::UNO_QUERY); |
| if (xProgressFactory.is()) |
| { |
| xProgress = xProgressFactory->createStatusIndicator(); |
| if (xProgress.is()) |
| m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_STATUSINDICATOR()] <<= xProgress; |
| } |
| } |
| |
| // convert media descriptor and URL to right format for later interface call! |
| css::uno::Sequence< css::beans::PropertyValue > lDescriptor; |
| m_lMediaDescriptor >> lDescriptor; |
| ::rtl::OUString sURL = m_aURL.Complete; |
| |
| // try to locate any interested frame loader |
| css::uno::Reference< css::uno::XInterface > xLoader = impl_searchLoader(); |
| css::uno::Reference< css::frame::XFrameLoader > xAsyncLoader(xLoader, css::uno::UNO_QUERY); |
| css::uno::Reference< css::frame::XSynchronousFrameLoader > xSyncLoader (xLoader, css::uno::UNO_QUERY); |
| |
| if (xAsyncLoader.is()) |
| { |
| // SAFE -> ----------------------------------- |
| aWriteLock.lock(); |
| m_xAsynchronousJob = xAsyncLoader; |
| m_pCheck = this; |
| LoadEnvListener* pListener = new LoadEnvListener(m_pCheck, this); |
| aWriteLock.unlock(); |
| // <- SAFE ----------------------------------- |
| |
| css::uno::Reference< css::frame::XLoadEventListener > xListener(static_cast< css::frame::XLoadEventListener* >(pListener), css::uno::UNO_QUERY); |
| xAsyncLoader->load(xTargetFrame, sURL, lDescriptor, xListener); |
| |
| return sal_True; |
| } |
| else |
| if (xSyncLoader.is()) |
| { |
| sal_Bool bResult = xSyncLoader->load(lDescriptor, xTargetFrame); |
| // react for the result here, so the outside waiting |
| // code can ask for it later. |
| impl_setResult(bResult); |
| // But the return value indicates a valid started(!) operation. |
| // And thats true everxtimes, we reach this line :-) |
| return sal_True; |
| } |
| |
| aWriteLock.unlock(); |
| // <- SAFE |
| |
| return sal_False; |
| } |
| |
| /*----------------------------------------------- |
| 06.02.2004 14:40 |
| -----------------------------------------------*/ |
| css::uno::Reference< css::uno::XInterface > LoadEnv::impl_searchLoader() |
| { |
| // SAFE -> ----------------------------------- |
| ReadGuard aReadLock(m_aLock); |
| |
| // special mode to set an existing component on this frame |
| // In such case the laoder is fix. It must be the SFX based implementation, |
| // which can create a view on top of such xModel components :-) |
| if (m_eContentType == E_CAN_BE_SET) |
| { |
| try |
| { |
| return m_xSMGR->createInstance(IMPLEMENTATIONNAME_GENERICFRAMELOADER); |
| } |
| catch(const css::uno::RuntimeException&) |
| { throw; } |
| catch(const css::uno::Exception&) |
| {} |
| throw LoadEnvException(LoadEnvException::ID_INVALID_ENVIRONMENT); |
| } |
| |
| // Otherwhise ... |
| // We need this type information to locate an registered frame loader |
| // Without such information we cant work! |
| ::rtl::OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), ::rtl::OUString()); |
| if (!sType.getLength()) |
| throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR); |
| |
| // try to locate any interested frame loader |
| css::uno::Reference< css::lang::XMultiServiceFactory > xLoaderFactory(m_xSMGR->createInstance(SERVICENAME_FRAMELOADERFACTORY), css::uno::UNO_QUERY); |
| css::uno::Reference< css::container::XContainerQuery > xQuery (xLoaderFactory , css::uno::UNO_QUERY); |
| |
| aReadLock.unlock(); |
| // <- SAFE ----------------------------------- |
| |
| css::uno::Sequence< ::rtl::OUString > lTypesReg(1); |
| lTypesReg[0] = sType; |
| |
| css::uno::Sequence< css::beans::NamedValue > lQuery(1); |
| lQuery[0].Name = ::framework::constant::FrameLoader::PROP_TYPES; |
| lQuery[0].Value <<= lTypesReg; |
| |
| css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery); |
| while(xSet->hasMoreElements()) |
| { |
| // try everyone ... |
| // Ignore any loader, which makes trouble :-) |
| ::comphelper::SequenceAsHashMap lLoaderProps(xSet->nextElement()); |
| ::rtl::OUString sLoader = lLoaderProps.getUnpackedValueOrDefault(::framework::constant::FrameLoader::PROP_NAME, ::rtl::OUString()); |
| css::uno::Reference< css::uno::XInterface > xLoader ; |
| try |
| { |
| xLoader = xLoaderFactory->createInstance(sLoader); |
| if (xLoader.is()) |
| return xLoader; |
| } |
| catch(const css::uno::RuntimeException&) |
| { throw; } |
| catch(const css::uno::Exception&) |
| { continue; } |
| } |
| |
| return css::uno::Reference< css::uno::XInterface >(); |
| } |
| |
| /*----------------------------------------------- |
| 24.01.2006 15:11 |
| -----------------------------------------------*/ |
| void LoadEnv::impl_jumpToMark(const css::uno::Reference< css::frame::XFrame >& xFrame, |
| const css::util::URL& aURL ) |
| { |
| if (! aURL.Mark.getLength()) |
| return; |
| |
| css::uno::Reference< css::frame::XDispatchProvider > xProvider(xFrame, css::uno::UNO_QUERY); |
| if (! xProvider.is()) |
| return; |
| |
| // SAFE -> |
| ReadGuard aReadLock(m_aLock); |
| css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; |
| aReadLock.unlock(); |
| // <- SAFE |
| |
| css::util::URL aCmd; |
| aCmd.Complete = ::rtl::OUString::createFromAscii(".uno:JumpToMark"); |
| |
| css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW); |
| xParser->parseStrict(aCmd); |
| |
| css::uno::Reference< css::frame::XDispatch > xDispatcher = xProvider->queryDispatch(aCmd, SPECIALTARGET_SELF, 0); |
| if (! xDispatcher.is()) |
| return; |
| |
| ::comphelper::SequenceAsHashMap lArgs; |
| lArgs[::rtl::OUString::createFromAscii("Bookmark")] <<= aURL.Mark; |
| xDispatcher->dispatch(aCmd, lArgs.getAsConstPropertyValueList()); |
| } |
| |
| /*----------------------------------------------- |
| 31.07.2003 09:02 |
| -----------------------------------------------*/ |
| css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchAlreadyLoaded() |
| throw(LoadEnvException, css::uno::RuntimeException) |
| { |
| // SAFE -> |
| ReadGuard aReadLock(m_aLock); |
| |
| // such search is allowed for special requests only ... |
| // or better its not allowed for some requests in general :-) |
| if ( |
| ( ! TargetHelper::matchSpecialTarget(m_sTarget, TargetHelper::E_DEFAULT) ) || |
| (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_ASTEMPLATE() , sal_False) == sal_True) || |
| // (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False) == sal_True) || |
| (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_OPENNEWVIEW(), sal_False) == sal_True) |
| ) |
| { |
| return css::uno::Reference< css::frame::XFrame >(); |
| } |
| |
| // check URL |
| // May its not usefull to start expensive document search, if it |
| // can fail only .. because we load from a stream or model directly! |
| if ( |
| (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM )) || |
| (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT )) |
| /*TODO should be private:factory here tested too? */ |
| ) |
| { |
| return css::uno::Reference< css::frame::XFrame >(); |
| } |
| |
| // otherwhise - iterate through the tasks of the desktop container |
| // to find out, which of them might contains the requested document |
| css::uno::Reference< css::frame::XFramesSupplier > xSupplier(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY); |
| css::uno::Reference< css::container::XIndexAccess > xTaskList(xSupplier->getFrames() , css::uno::UNO_QUERY); |
| |
| if (!xTaskList.is()) |
| return css::uno::Reference< css::frame::XFrame >(); // task list can be empty! |
| |
| // Note: To detect if a document was alrady loaded before |
| // we check URLs here only. But might the existing and the requred |
| // document has different versions! Then its URLs are the same ... |
| sal_Int16 nNewVersion = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_VERSION(), (sal_Int16)(-1)); |
| |
| // will be used to save the first hidden frame referring the searched model |
| // Normaly we are interested on visible frames ... but if there is no such visible |
| // frame we referr to any hidden frame also (but as fallback only). |
| css::uno::Reference< css::frame::XFrame > xHiddenTask; |
| css::uno::Reference< css::frame::XFrame > xTask; |
| |
| sal_Int32 count = xTaskList->getCount(); |
| for (sal_Int32 i=0; i<count; ++i) |
| { |
| try |
| { |
| // locate model of task |
| // Note: Without a model there is no chance to decide if |
| // this task contains the searched document or not! |
| xTaskList->getByIndex(i) >>= xTask; |
| if (!xTask.is()) |
| continue; |
| |
| css::uno::Reference< css::frame::XController > xController = xTask->getController(); |
| if (!xController.is()) |
| { |
| xTask.clear (); |
| continue; |
| } |
| |
| css::uno::Reference< css::frame::XModel > xModel = xController->getModel(); |
| if (!xModel.is()) |
| { |
| xTask.clear (); |
| continue; |
| } |
| |
| // don't check the complete URL here. |
| // use its main part - ignore optional jumpmarks! |
| const ::rtl::OUString sURL = xModel->getURL(); |
| if (!::utl::UCBContentHelper::EqualURLs( m_aURL.Main, sURL )) |
| { |
| xTask.clear (); |
| continue; |
| } |
| |
| // get the original load arguments from the current document |
| // and decide if its realy the same then the one will be. |
| // It must be visible and must use the same file revision ... |
| // or must not have any file revision set (-1 == -1!) |
| ::comphelper::MediaDescriptor lOldDocDescriptor(xModel->getArgs()); |
| |
| if (lOldDocDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_VERSION(), (sal_Int32)(-1)) != nNewVersion) |
| { |
| xTask.clear (); |
| continue; |
| } |
| |
| // Hidden frames are special. |
| // They will be used as "last chance" if there is no visible frame pointing to the same model. |
| // Safe the result but continue with current loop might be looking for other visible frames. |
| ::sal_Bool bIsHidden = lOldDocDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False); |
| if ( |
| ( bIsHidden ) && |
| ( ! xHiddenTask.is()) |
| ) |
| { |
| xHiddenTask = xTask; |
| xTask.clear (); |
| continue; |
| } |
| |
| // We found a visible task pointing to the right model ... |
| // Break search. |
| break; |
| } |
| catch(const css::uno::RuntimeException& exRun) |
| { throw exRun; } |
| catch(const css::uno::Exception&) |
| { continue; } |
| } |
| |
| css::uno::Reference< css::frame::XFrame > xResult; |
| if (xTask.is()) |
| xResult = xTask; |
| else |
| if (xHiddenTask.is()) |
| xResult = xHiddenTask; |
| |
| if (xResult.is()) |
| { |
| // Now we are shure, that this task includes the searched document. |
| // It's time to activate it. As special feature we try to jump internaly |
| // if an optional jumpmark is given too. |
| if (m_aURL.Mark.getLength()) |
| impl_jumpToMark(xResult, m_aURL); |
| |
| // bring it to front and make sure it's visible... |
| impl_makeFrameWindowVisible(xResult->getContainerWindow(), sal_True); |
| } |
| |
| aReadLock.unlock(); |
| // <- SAFE |
| |
| return xResult; |
| } |
| |
| /*----------------------------------------------- |
| 30.03.2004 09:12 |
| -----------------------------------------------*/ |
| sal_Bool LoadEnv::impl_isFrameAlreadyUsedForLoading(const css::uno::Reference< css::frame::XFrame >& xFrame) const |
| { |
| css::uno::Reference< css::document::XActionLockable > xLock(xFrame, css::uno::UNO_QUERY); |
| |
| // ? no lock interface ? |
| // Might its an external written frame implementation :-( |
| // Allowing using of it ... but it can fail if its not synchronized with our processes ! |
| if (!xLock.is()) |
| return sal_False; |
| |
| // Otherwhise we have to look for any other existing lock. |
| return xLock->isActionLocked(); |
| } |
| |
| /*----------------------------------------------- |
| 30.03.2004 09:12 |
| -----------------------------------------------*/ |
| css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchRecycleTarget() |
| throw(LoadEnvException, css::uno::RuntimeException) |
| { |
| // SAFE -> .................................. |
| ReadGuard aReadLock(m_aLock); |
| |
| // The special backing mode frame will be recycled by definition! |
| // It does'nt matter if somehwere whish to create a new view |
| // or open a new untitled document ... |
| // The only exception form that - hidden frames! |
| if (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False) == sal_True) |
| return css::uno::Reference< css::frame::XFrame >(); |
| |
| css::uno::Reference< css::frame::XFramesSupplier > xSupplier(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY); |
| FrameListAnalyzer aTasksAnalyzer(xSupplier, css::uno::Reference< css::frame::XFrame >(), FrameListAnalyzer::E_BACKINGCOMPONENT); |
| if (aTasksAnalyzer.m_xBackingComponent.is()) |
| { |
| if (!impl_isFrameAlreadyUsedForLoading(aTasksAnalyzer.m_xBackingComponent)) |
| { |
| // bring it to front ... |
| impl_makeFrameWindowVisible(aTasksAnalyzer.m_xBackingComponent->getContainerWindow(), sal_True); |
| return aTasksAnalyzer.m_xBackingComponent; |
| } |
| } |
| |
| // These states indicates the wishing for creation of a new view in general. |
| if ( |
| (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_ASTEMPLATE() , sal_False) == sal_True) || |
| (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_OPENNEWVIEW(), sal_False) == sal_True) |
| ) |
| { |
| return css::uno::Reference< css::frame::XFrame >(); |
| } |
| |
| // On the other side some special URLs will open a new frame everytimes (expecting |
| // they can use the backing-mode frame!) |
| if ( |
| (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_FACTORY )) || |
| (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM )) || |
| (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT )) |
| ) |
| { |
| return css::uno::Reference< css::frame::XFrame >(); |
| } |
| |
| // No backing frame! No special URL => recycle active task - if possible. |
| // Means - if it does not already contains a modified document, or |
| // use another office module. |
| css::uno::Reference< css::frame::XFrame > xTask = xSupplier->getActiveFrame(); |
| |
| // not a real error - but might a focus problem! |
| if (!xTask.is()) |
| return css::uno::Reference< css::frame::XFrame >(); |
| |
| // not a real error - may its a view only |
| css::uno::Reference< css::frame::XController > xController = xTask->getController(); |
| if (!xController.is()) |
| return css::uno::Reference< css::frame::XFrame >(); |
| |
| // not a real error - may its a db component instead of a full feartured office document |
| css::uno::Reference< css::frame::XModel > xModel = xController->getModel(); |
| if (!xModel.is()) |
| return css::uno::Reference< css::frame::XFrame >(); |
| |
| // get some more informations ... |
| |
| // A valid set URL means: there is already a location for this document. |
| // => it was saved there or opened from there. Such Documents can not be used here. |
| // We search for empty document ... created by a private:factory/ URL! |
| if (xModel->getURL().getLength()>0) |
| return css::uno::Reference< css::frame::XFrame >(); |
| |
| // The old document must be unmodified ... |
| css::uno::Reference< css::util::XModifiable > xModified(xModel, css::uno::UNO_QUERY); |
| if (xModified->isModified()) |
| return css::uno::Reference< css::frame::XFrame >(); |
| |
| Window* pWindow = VCLUnoHelper::GetWindow(xTask->getContainerWindow()); |
| if (pWindow && pWindow->IsInModalMode()) |
| return css::uno::Reference< css::frame::XFrame >(); |
| |
| // find out the application type of this document |
| // We can recycle only documents, which uses the same application |
| // then the new one. |
| SvtModuleOptions::EFactory eOldApp = SvtModuleOptions::ClassifyFactoryByModel(xModel); |
| SvtModuleOptions::EFactory eNewApp = SvtModuleOptions::ClassifyFactoryByURL (m_aURL.Complete, m_lMediaDescriptor.getAsConstPropertyValueList()); |
| |
| aReadLock.unlock(); |
| // <- SAFE .................................. |
| |
| if (eOldApp != eNewApp) |
| return css::uno::Reference< css::frame::XFrame >(); |
| |
| // OK this task seams to be useable for recycling |
| // But we should mark it as such - means set an action lock. |
| // Otherwhise it would be used more then ones or will be destroyed |
| // by a close() or terminate() request. |
| // But if such lock already exist ... it means this task is used for |
| // any other operation already. Don't use it then. |
| if (impl_isFrameAlreadyUsedForLoading(xTask)) |
| return css::uno::Reference< css::frame::XFrame >(); |
| |
| // OK - there is a valid target frame. |
| // But may be it contains already a document. |
| // Then we have to ask it, if it allows recylcing of this frame .-) |
| sal_Bool bReactivateOldControllerOnError = sal_False; |
| css::uno::Reference< css::frame::XController > xOldDoc = xTask->getController(); |
| if (xOldDoc.is()) |
| { |
| bReactivateOldControllerOnError = xOldDoc->suspend(sal_True); |
| if (! bReactivateOldControllerOnError) |
| return css::uno::Reference< css::frame::XFrame >(); |
| } |
| |
| // SAFE -> .................................. |
| WriteGuard aWriteLock(m_aLock); |
| |
| css::uno::Reference< css::document::XActionLockable > xLock(xTask, css::uno::UNO_QUERY); |
| if (!m_aTargetLock.setResource(xLock)) |
| return css::uno::Reference< css::frame::XFrame >(); |
| |
| m_bReactivateControllerOnError = bReactivateOldControllerOnError; |
| aWriteLock.unlock(); |
| // <- SAFE .................................. |
| |
| // bring it to front ... |
| impl_makeFrameWindowVisible(xTask->getContainerWindow(), sal_True); |
| |
| return xTask; |
| } |
| |
| /*----------------------------------------------- |
| 15.08.2003 12:39 |
| -----------------------------------------------*/ |
| void LoadEnv::impl_reactForLoadingState() |
| throw(LoadEnvException, css::uno::RuntimeException) |
| { |
| /*TODO reset action locks */ |
| |
| // SAFE -> ---------------------------------- |
| ReadGuard aReadLock(m_aLock); |
| |
| if (m_bLoaded) |
| { |
| // Bring the new loaded document to front (if allowed!). |
| // Note: We show new created frames here only. |
| // We dont hide already visible frames here ... |
| css::uno::Reference< css::awt::XWindow > xWindow = m_xTargetFrame->getContainerWindow(); |
| sal_Bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False); |
| sal_Bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_MINIMIZED(), sal_False); |
| |
| if (bMinimized) |
| { |
| ::vos::OClearableGuard aSolarGuard(Application::GetSolarMutex()); |
| Window* pWindow = VCLUnoHelper::GetWindow(xWindow); |
| // check for system window is neccessary to guarantee correct pointer cast! |
| if (pWindow && pWindow->IsSystemWindow()) |
| ((WorkWindow*)pWindow)->Minimize(); |
| } |
| else |
| if (!bHidden) |
| { |
| // show frame ... if it's not still visible ... |
| // But do nothing if it's already visible! |
| impl_makeFrameWindowVisible(xWindow, sal_False); |
| } |
| |
| // Note: Only if an existing property "FrameName" is given by this media descriptor, |
| // it should be used. Otherwhise we should do nothing. May be the outside code has already |
| // set a frame name on the target! |
| ::comphelper::MediaDescriptor::const_iterator pFrameName = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_FRAMENAME()); |
| if (pFrameName != m_lMediaDescriptor.end()) |
| { |
| ::rtl::OUString sFrameName; |
| pFrameName->second >>= sFrameName; |
| // Check the name again. e.g. "_default" isnt allowed. |
| // On the other side "_beamer" is a valid name :-) |
| if (TargetHelper::isValidNameForFrame(sFrameName)) |
| m_xTargetFrame->setName(sFrameName); |
| } |
| } |
| else if (m_bReactivateControllerOnError) |
| { |
| // Try to reactivate the old document (if any exists!) |
| css::uno::Reference< css::frame::XController > xOldDoc = m_xTargetFrame->getController(); |
| // clear does not depend from reactivation state of a might existing old document! |
| // We must make shure, that a might following getTargetComponent() call does not return |
| // the old document! |
| m_xTargetFrame.clear(); |
| if (xOldDoc.is()) |
| { |
| sal_Bool bReactivated = xOldDoc->suspend(sal_False); |
| if (!bReactivated) |
| throw LoadEnvException(LoadEnvException::ID_COULD_NOT_REACTIVATE_CONTROLLER); |
| m_bReactivateControllerOnError = sal_False; |
| } |
| } |
| else if (m_bCloseFrameOnError) |
| { |
| // close empty frames |
| css::uno::Reference< css::util::XCloseable > xCloseable (m_xTargetFrame, css::uno::UNO_QUERY); |
| css::uno::Reference< css::lang::XComponent > xDisposable(m_xTargetFrame, css::uno::UNO_QUERY); |
| |
| try |
| { |
| if (xCloseable.is()) |
| xCloseable->close(sal_True); |
| else |
| if (xDisposable.is()) |
| xDisposable->dispose(); |
| } |
| catch(const css::util::CloseVetoException&) |
| {} |
| catch(const css::lang::DisposedException&) |
| {} |
| m_xTargetFrame.clear(); |
| } |
| |
| // This max force an implicit closing of our target frame ... |
| // e.g. in case close(sal_True) was called before and the frame |
| // kill itself if our external use-lock is released here! |
| // Thats why we releas this lock AFTER ALL OPERATIONS on this frame |
| // are finished. The frame itslef must handle then |
| // this situation gracefully. |
| m_aTargetLock.freeResource(); |
| |
| // Last but not least :-) |
| // We have to clear the current media descriptor. |
| // Otherwhise it hold a might existing stream open! |
| m_lMediaDescriptor.clear(); |
| |
| css::uno::Any aRequest; |
| bool bThrow = false; |
| if ( !m_bLoaded && m_pQuietInteraction && m_pQuietInteraction->wasUsed() ) |
| { |
| aRequest = m_pQuietInteraction->getRequest(); |
| m_pQuietInteraction->release(); |
| m_pQuietInteraction = 0; |
| bThrow = true; |
| } |
| |
| aReadLock.unlock(); |
| |
| if (bThrow) |
| { |
| if ( aRequest.isExtractableTo( ::cppu::UnoType< css::uno::Exception >::get() ) ) |
| throw LoadEnvException( LoadEnvException::ID_GENERAL_ERROR, aRequest ); |
| } |
| |
| // <- SAFE ---------------------------------- |
| } |
| |
| /*----------------------------------------------- |
| 16.01.2005 13:04 |
| -----------------------------------------------*/ |
| void LoadEnv::impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::XWindow >& xWindow , |
| sal_Bool bForceToFront) |
| { |
| // SAFE -> ---------------------------------- |
| ReadGuard aReadLock(m_aLock); |
| css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xSMGR.get(), css::uno::UNO_QUERY ); |
| aReadLock.unlock(); |
| // <- SAFE ---------------------------------- |
| |
| ::vos::OClearableGuard aSolarGuard(Application::GetSolarMutex()); |
| Window* pWindow = VCLUnoHelper::GetWindow(xWindow); |
| if ( pWindow ) |
| { |
| bool bForceFrontAndFocus(false); |
| css::uno::Any a = ::comphelper::ConfigurationHelper::readDirectKey( |
| xSMGR, |
| ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/View"), |
| ::rtl::OUString::createFromAscii("NewDocumentHandling"), |
| ::rtl::OUString::createFromAscii("ForceFocusAndToFront"), |
| ::comphelper::ConfigurationHelper::E_READONLY); |
| a >>= bForceFrontAndFocus; |
| |
| if( pWindow->IsVisible() && (bForceFrontAndFocus || bForceToFront) ) |
| pWindow->ToTop(); |
| else |
| pWindow->Show(sal_True, (bForceFrontAndFocus || bForceToFront) ? SHOW_FOREGROUNDTASK : 0 ); |
| } |
| |
| /* #i19976# |
| We tried to prevent a toFront() call in case the user putted the |
| loading document into the background .. |
| But we had several errors trying that. So we decided to |
| rollback these changes and bring the new loaded document to front hardly ! |
| |
| css::uno::Reference< css::awt::XWindow2 > xWindow2(xWindow, css::uno::UNO_QUERY); |
| |
| sal_Bool bIsVisible = sal_False; |
| if (xWindow2.is()) |
| bIsVisible = xWindow2->isVisible(); // TODO is parent visible too ? .-) |
| |
| if (!bIsVisible) |
| { |
| xWindow->setVisible(sal_True); |
| bForceToFront = sal_True; |
| } |
| |
| if ( |
| (bForceToFront ) && |
| (xTopWindow.is()) |
| ) |
| { |
| xTopWindow->toFront(); |
| } |
| */ |
| } |
| |
| /*----------------------------------------------- |
| 15.03.2005 11:12 |
| -----------------------------------------------*/ |
| void LoadEnv::impl_applyPersistentWindowState(const css::uno::Reference< css::awt::XWindow >& xWindow) |
| { |
| static ::rtl::OUString PACKAGE_SETUP_MODULES = ::rtl::OUString::createFromAscii("/org.openoffice.Setup/Office/Factories"); |
| |
| // no window -> action not possible |
| if (!xWindow.is()) |
| return; |
| |
| // window already visible -> do nothing! If we use a "recycle frame" for loading ... |
| // the current position and size must be used. |
| css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(xWindow, css::uno::UNO_QUERY); |
| if ( |
| (xVisibleCheck.is() ) && |
| (xVisibleCheck->isVisible()) |
| ) |
| return; |
| |
| // SOLAR SAFE -> |
| ::vos::OClearableGuard aSolarLock1(Application::GetSolarMutex()); |
| |
| Window* pWindow = VCLUnoHelper::GetWindow(xWindow); |
| sal_Bool bSystemWindow = pWindow->IsSystemWindow(); |
| sal_Bool bWorkWindow = (pWindow->GetType() == WINDOW_WORKWINDOW); |
| |
| if (!bSystemWindow && !bWorkWindow) |
| return; |
| |
| // dont overwrite this special state! |
| WorkWindow* pWorkWindow = (WorkWindow*)pWindow; |
| if (pWorkWindow->IsMinimized()) |
| return; |
| |
| aSolarLock1.clear(); |
| // <- SOLAR SAFE |
| |
| // SAFE -> |
| ReadGuard aReadLock(m_aLock); |
| |
| // no filter -> no module -> no persistent window state |
| ::rtl::OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault( |
| ::comphelper::MediaDescriptor::PROP_FILTERNAME(), |
| ::rtl::OUString()); |
| if (!sFilter.getLength()) |
| return; |
| |
| css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; |
| |
| aReadLock.unlock(); |
| // <- SAFE |
| |
| try |
| { |
| // retrieve the module name from the filter configuration |
| css::uno::Reference< css::container::XNameAccess > xFilterCfg( |
| xSMGR->createInstance(SERVICENAME_FILTERFACTORY), |
| css::uno::UNO_QUERY_THROW); |
| ::comphelper::SequenceAsHashMap lProps (xFilterCfg->getByName(sFilter)); |
| ::rtl::OUString sModule = lProps.getUnpackedValueOrDefault(FILTER_PROPNAME_DOCUMENTSERVICE, ::rtl::OUString()); |
| |
| // get access to the configuration of this office module |
| css::uno::Reference< css::container::XNameAccess > xModuleCfg(::comphelper::ConfigurationHelper::openConfig( |
| xSMGR, |
| PACKAGE_SETUP_MODULES, |
| ::comphelper::ConfigurationHelper::E_READONLY), |
| css::uno::UNO_QUERY_THROW); |
| |
| // read window state from the configuration |
| // and apply it on the window. |
| // Do nothing, if no configuration entry exists! |
| ::rtl::OUString sWindowState ; |
| ::comphelper::ConfigurationHelper::readRelativeKey(xModuleCfg, sModule, OFFICEFACTORY_PROPNAME_WINDOWATTRIBUTES) >>= sWindowState; |
| if (sWindowState.getLength()) |
| { |
| // SOLAR SAFE -> |
| ::vos::OClearableGuard aSolarLock2(Application::GetSolarMutex()); |
| |
| // We have to retrieve the window pointer again. Because nobody can guarantee |
| // that the XWindow was not disposed inbetween .-) |
| // But if we get a valid pointer we can be sure, that it's the system window pointer |
| // we already checked and used before. Because nobody recylce the same uno reference for |
| // a new internal c++ implementation ... hopefully .-)) |
| Window* pWindowCheck = VCLUnoHelper::GetWindow(xWindow); |
| if (! pWindowCheck) |
| return; |
| |
| SystemWindow* pSystemWindow = (SystemWindow*)pWindowCheck; |
| pSystemWindow->SetWindowState(U2B_ENC(sWindowState,RTL_TEXTENCODING_UTF8)); |
| |
| aSolarLock2.clear(); |
| // <- SOLAR SAFE |
| } |
| } |
| catch(const css::uno::RuntimeException& exRun) |
| { throw exRun; } |
| catch(const css::uno::Exception&) |
| {} |
| } |
| |
| } // namespace framework |
| |