bump product version to 4.1.6.2
[LibreOffice.git] / framework / source / loadenv / loadenv.cxx
blob6796fd210e166b7bdb4e8aeb1b5a2c13405f9cf2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <loadenv/loadenv.hxx>
22 #include <loadenv/targethelper.hxx>
23 #include <framework/framelistanalyzer.hxx>
25 #include <constant/containerquery.hxx>
26 #include <interaction/quietinteraction.hxx>
27 #include <threadhelp/writeguard.hxx>
28 #include <threadhelp/readguard.hxx>
29 #include <threadhelp/resetableguard.hxx>
30 #include <properties.h>
31 #include <protocols.h>
32 #include <services.h>
33 #include <comphelper/interaction.hxx>
34 #include <framework/interaction.hxx>
35 #include <comphelper/processfactory.hxx>
36 #include <comphelper/configuration.hxx>
37 #include "officecfg/Office/Common.hxx"
39 #include <com/sun/star/task/ErrorCodeRequest.hpp>
40 #include <com/sun/star/task/InteractionHandler.hpp>
41 #include <com/sun/star/uno/RuntimeException.hpp>
42 #include <com/sun/star/frame/DispatchResultState.hpp>
43 #include <com/sun/star/frame/FrameSearchFlag.hpp>
44 #include <com/sun/star/util/URLTransformer.hpp>
45 #include <com/sun/star/util/XURLTransformer.hpp>
46 #include <com/sun/star/ucb/UniversalContentBroker.hpp>
47 #include <com/sun/star/util/XCloseable.hpp>
48 #include <com/sun/star/lang/XComponent.hpp>
49 #include <com/sun/star/lang/XServiceInfo.hpp>
50 #include <com/sun/star/lang/DisposedException.hpp>
51 #include <com/sun/star/awt/XWindow.hpp>
52 #include <com/sun/star/awt/XWindow2.hpp>
53 #include <com/sun/star/awt/XTopWindow.hpp>
54 #include <com/sun/star/frame/Desktop.hpp>
55 #include <com/sun/star/frame/XModel.hpp>
56 #include <com/sun/star/frame/XFrameLoader.hpp>
57 #include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
58 #include <com/sun/star/frame/XNotifyingDispatch.hpp>
59 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
60 #include <com/sun/star/task/XStatusIndicator.hpp>
61 #include <com/sun/star/util/XModifiable.hpp>
62 #include <com/sun/star/frame/XDispatchProvider.hpp>
63 #include <com/sun/star/document/XTypeDetection.hpp>
64 #include <com/sun/star/document/XActionLockable.hpp>
65 #include <com/sun/star/io/XInputStream.hpp>
66 #include <com/sun/star/task/XInteractionHandler.hpp>
67 #include <com/sun/star/container/XNameAccess.hpp>
68 #include <com/sun/star/container/XContainerQuery.hpp>
69 #include <com/sun/star/container/XEnumeration.hpp>
70 #include <com/sun/star/document/MacroExecMode.hpp>
71 #include <com/sun/star/document/UpdateDocMode.hpp>
73 #include <vcl/window.hxx>
74 #include <vcl/wrkwin.hxx>
75 #include <vcl/syswin.hxx>
77 #include <toolkit/unohlp.hxx>
78 #include <unotools/moduleoptions.hxx>
79 #include <svtools/sfxecode.hxx>
80 #include <unotools/ucbhelper.hxx>
81 #include <comphelper/configurationhelper.hxx>
82 #include <rtl/ustrbuf.hxx>
83 #include "rtl/bootstrap.hxx"
84 #include <vcl/svapp.hxx>
86 const char PROP_TYPES[] = "Types";
87 const char PROP_NAME[] = "Name";
89 namespace framework {
91 using namespace com::sun::star;
94 class LoadEnvListener : private ThreadHelpBase
95 , public ::cppu::WeakImplHelper2< css::frame::XLoadEventListener ,
96 css::frame::XDispatchResultListener >
98 private:
100 bool m_bWaitingResult;
101 LoadEnv* m_pLoadEnv;
103 public:
105 //_______________________________________
106 LoadEnvListener(LoadEnv* pLoadEnv)
107 : m_bWaitingResult(true)
108 , m_pLoadEnv(pLoadEnv)
112 //_______________________________________
113 // frame.XLoadEventListener
114 virtual void SAL_CALL loadFinished(const css::uno::Reference< css::frame::XFrameLoader >& xLoader)
115 throw(css::uno::RuntimeException);
117 virtual void SAL_CALL loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >& xLoader)
118 throw(css::uno::RuntimeException);
120 //_______________________________________
121 // frame.XDispatchResultListener
122 virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& aEvent)
123 throw(css::uno::RuntimeException);
125 //_______________________________________
126 // lang.XEventListener
127 virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
128 throw(css::uno::RuntimeException);
132 LoadEnv::LoadEnv(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
133 throw(LoadEnvException, css::uno::RuntimeException)
134 : ThreadHelpBase( )
135 , m_xSMGR (xSMGR)
136 , m_pQuietInteraction( 0 )
141 LoadEnv::~LoadEnv()
146 css::uno::Reference< css::lang::XComponent > LoadEnv::loadComponentFromURL(const css::uno::Reference< css::frame::XComponentLoader >& xLoader,
147 const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
148 const OUString& sURL ,
149 const OUString& sTarget,
150 sal_Int32 nFlags ,
151 const css::uno::Sequence< css::beans::PropertyValue >& lArgs )
152 throw(css::lang::IllegalArgumentException,
153 css::io::IOException ,
154 css::uno::RuntimeException )
156 css::uno::Reference< css::lang::XComponent > xComponent;
160 LoadEnv aEnv(xSMGR);
162 aEnv.initializeLoading(sURL,
163 lArgs,
164 css::uno::Reference< css::frame::XFrame >(xLoader, css::uno::UNO_QUERY),
165 sTarget,
166 nFlags,
167 LoadEnv::E_NO_FEATURE);
168 aEnv.startLoading();
169 aEnv.waitWhileLoading(); // wait for ever!
171 xComponent = aEnv.getTargetComponent();
173 catch(const LoadEnvException& ex)
175 switch(ex.m_nID)
177 case LoadEnvException::ID_INVALID_MEDIADESCRIPTOR:
178 throw css::lang::IllegalArgumentException(
179 "Optional list of arguments seem to be corrupted.", xLoader, 4);
181 case LoadEnvException::ID_UNSUPPORTED_CONTENT:
183 OUStringBuffer aMsg;
184 aMsg.appendAscii("Unsupported URL <").append(sURL).append('>');
186 if (!ex.m_sMessage.isEmpty())
188 aMsg.appendAscii(": \"").
189 append(OStringToOUString(
190 ex.m_sMessage, RTL_TEXTENCODING_UTF8)).
191 appendAscii("\"");
194 throw css::lang::IllegalArgumentException(aMsg.makeStringAndClear(),
195 xLoader, 1);
198 default:
199 xComponent.clear();
200 break;
204 return xComponent;
207 //-----------------------------------------------
208 ::comphelper::MediaDescriptor impl_mergeMediaDescriptorWithMightExistingModelArgs(const css::uno::Sequence< css::beans::PropertyValue >& lOutsideDescriptor)
210 ::comphelper::MediaDescriptor lDescriptor(lOutsideDescriptor);
211 css::uno::Reference< css::frame::XModel > xModel = lDescriptor.getUnpackedValueOrDefault(
212 ::comphelper::MediaDescriptor::PROP_MODEL (),
213 css::uno::Reference< css::frame::XModel > ());
214 if (xModel.is ())
216 ::comphelper::MediaDescriptor lModelDescriptor(xModel->getArgs());
217 ::comphelper::MediaDescriptor::iterator pIt = lModelDescriptor.find( ::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE() );
218 if ( pIt != lModelDescriptor.end() )
219 lDescriptor[::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()] = pIt->second;
222 return lDescriptor;
226 void LoadEnv::initializeLoading(const OUString& sURL ,
227 const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor,
228 const css::uno::Reference< css::frame::XFrame >& xBaseFrame ,
229 const OUString& sTarget ,
230 sal_Int32 nSearchFlags ,
231 EFeature eFeature , // => use default ...
232 EContentType eContentType ) // => use default ...
234 // SAFE -> ----------------------------------
235 WriteGuard aWriteLock(m_aLock);
237 // Handle still running processes!
238 if (m_xAsynchronousJob.is())
239 throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
241 // take over all new parameters.
242 m_xTargetFrame.clear();
243 m_xBaseFrame = xBaseFrame ;
244 m_lMediaDescriptor = impl_mergeMediaDescriptorWithMightExistingModelArgs(lMediaDescriptor);
245 m_sTarget = sTarget ;
246 m_nSearchFlags = nSearchFlags ;
247 m_eFeature = eFeature ;
248 m_eContentType = eContentType ;
249 m_bCloseFrameOnError = sal_False ;
250 m_bReactivateControllerOnError = sal_False ;
251 m_bLoaded = sal_False ;
253 // try to find out, if its really a content, which can be loaded or must be "handled"
254 // We use a default value for this in-parameter. Then we have to start a complex check method
255 // internally. But if this check was already done outside it can be supressed to perform
256 // the load request. We take over the result then!
257 if (m_eContentType == E_UNSUPPORTED_CONTENT)
259 m_eContentType = LoadEnv::classifyContent(sURL, lMediaDescriptor);
260 if (m_eContentType == E_UNSUPPORTED_CONTENT)
261 throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);
264 // make URL part of the MediaDescriptor
265 // It doesn't mater, if it is already an item of it.
266 // It must be the same value ... so we can overwrite it :-)
267 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_URL()] <<= sURL;
269 // parse it - because some following code require that
270 m_aURL.Complete = sURL;
271 css::uno::Reference< css::util::XURLTransformer > xParser(css::util::URLTransformer::create(::comphelper::getComponentContext(m_xSMGR)));
272 xParser->parseStrict(m_aURL);
274 // BTW: Split URL and JumpMark ...
275 // Because such mark is an explicit value of the media descriptor!
276 if (!m_aURL.Mark.isEmpty())
277 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_JUMPMARK()] <<= m_aURL.Mark;
279 // By the way: remove the old and deprecated value "FileName" from the descriptor!
280 ::comphelper::MediaDescriptor::iterator pIt = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_FILENAME());
281 if (pIt != m_lMediaDescriptor.end())
282 m_lMediaDescriptor.erase(pIt);
284 // patch the MediaDescriptor, so it fullfill the outside requirements
285 // Means especially items like e.g. UI InteractionHandler, Status Indicator,
286 // MacroExecutionMode etcpp.
288 /*TODO progress is bound to a frame ... How can we set it here? */
290 // UI mode
291 const bool bUIMode =
292 ( ( m_eFeature & E_WORK_WITH_UI ) == E_WORK_WITH_UI ) &&
293 ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False ) == sal_False ) &&
294 ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_PREVIEW(), sal_False ) == sal_False );
296 initializeUIDefaults(
297 comphelper::getComponentContext(m_xSMGR),
298 m_lMediaDescriptor,
299 bUIMode,
300 &m_pQuietInteraction
303 aWriteLock.unlock();
304 // <- SAFE ----------------------------------
308 void LoadEnv::initializeUIDefaults( const css::uno::Reference< css::uno::XComponentContext >& i_rxContext,
309 ::comphelper::MediaDescriptor& io_lMediaDescriptor, const bool i_bUIMode,
310 QuietInteraction** o_ppQuietInteraction )
312 css::uno::Reference< css::task::XInteractionHandler > xInteractionHandler;
313 sal_Int16 nMacroMode ;
314 sal_Int16 nUpdateMode ;
316 if ( i_bUIMode )
318 nMacroMode = css::document::MacroExecMode::USE_CONFIG;
319 nUpdateMode = css::document::UpdateDocMode::ACCORDING_TO_CONFIG;
322 xInteractionHandler.set( css::task::InteractionHandler::createWithParent( i_rxContext, 0 ), css::uno::UNO_QUERY_THROW );
324 catch(const css::uno::RuntimeException&) {throw;}
325 catch(const css::uno::Exception& ) { }
327 // hidden mode
328 else
330 nMacroMode = css::document::MacroExecMode::NEVER_EXECUTE;
331 nUpdateMode = css::document::UpdateDocMode::NO_UPDATE;
332 QuietInteraction* pQuietInteraction = new QuietInteraction();
333 xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(static_cast< css::task::XInteractionHandler* >(pQuietInteraction), css::uno::UNO_QUERY);
334 if ( o_ppQuietInteraction != NULL )
336 *o_ppQuietInteraction = pQuietInteraction;
337 (*o_ppQuietInteraction)->acquire();
341 if (
342 (xInteractionHandler.is() ) &&
343 (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()) == io_lMediaDescriptor.end())
346 io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()] <<= xInteractionHandler;
349 if (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()) == io_lMediaDescriptor.end())
350 io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()] <<= nMacroMode;
352 if (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_UPDATEDOCMODE()) == io_lMediaDescriptor.end())
353 io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_UPDATEDOCMODE()] <<= nUpdateMode;
357 void LoadEnv::startLoading()
359 // SAFE ->
360 ReadGuard aReadLock(m_aLock);
362 // Handle still running processes!
363 if (m_xAsynchronousJob.is())
364 throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
366 // content can not be loaded or handled
367 // check "classifyContent()" failed before ...
368 if (m_eContentType == E_UNSUPPORTED_CONTENT)
369 throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);
371 // <- SAFE
372 aReadLock.unlock();
374 // detect its type/filter etcpp.
375 // These information will be available by the
376 // used descriptor member afterwards and is needed
377 // for all following operations!
378 // Note: An exception will be thrown, in case operation was not successfully ...
379 if (m_eContentType != E_CAN_BE_SET)/* Attention: special feature to set existing component on a frame must ignore type detection! */
380 impl_detectTypeAndFilter();
382 // start loading the content ...
383 // Attention: Dont check m_eContentType deeper then UNSUPPORTED/SUPPORTED!
384 // Because it was made in th easiest way ... may a flat detection was made only.
385 // And such simple detection can fail some times .-)
386 // Use another strategy here. Try it and let it run into the case "loading not possible".
387 sal_Bool bStarted = sal_False;
388 if (
389 ((m_eFeature & E_ALLOW_CONTENTHANDLER) == E_ALLOW_CONTENTHANDLER) &&
390 (m_eContentType != E_CAN_BE_SET ) /* Attention: special feature to set existing component on a frame must ignore type detection! */
393 bStarted = impl_handleContent();
396 if (!bStarted)
397 bStarted = impl_loadContent();
399 // not started => general error
400 // We can't say - what was the reason for.
401 if (!bStarted)
402 throw LoadEnvException(LoadEnvException::ID_GENERAL_ERROR);
405 /*-----------------------------------------------
406 TODO
407 First draft does not implement timeout using [ms].
408 Current implementation counts yield calls only ...
409 -----------------------------------------------*/
410 sal_Bool LoadEnv::waitWhileLoading(sal_uInt32 nTimeout)
412 // Because its not a good idea to block the main thread
413 // (and we can't be sure that we are currently not used inside the
414 // main thread!), we can't use conditions here really. We must yield
415 // in an intellegent manner :-)
417 sal_Int32 nTime = nTimeout;
418 while(true)
420 // SAFE -> ------------------------------
421 ReadGuard aReadLock1(m_aLock);
422 if (!m_xAsynchronousJob.is())
423 break;
424 aReadLock1.unlock();
425 // <- SAFE ------------------------------
427 Application::Yield();
429 // forever!
430 if (nTimeout==0)
431 continue;
433 // timed out?
434 --nTime;
435 if (nTime<1)
436 break;
439 // SAFE -> ----------------------------------
440 ReadGuard aReadLock2(m_aLock);
441 return !m_xAsynchronousJob.is();
442 // <- SAFE ----------------------------------
445 css::uno::Reference< css::lang::XComponent > LoadEnv::getTargetComponent() const
447 // SAFE ->
448 ReadGuard aReadLock(m_aLock);
450 if (!m_xTargetFrame.is())
451 return css::uno::Reference< css::lang::XComponent >();
453 css::uno::Reference< css::frame::XController > xController = m_xTargetFrame->getController();
454 if (!xController.is())
455 return css::uno::Reference< css::lang::XComponent >(m_xTargetFrame->getComponentWindow(), css::uno::UNO_QUERY);
457 css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
458 if (!xModel.is())
459 return css::uno::Reference< css::lang::XComponent >(xController, css::uno::UNO_QUERY);
461 return css::uno::Reference< css::lang::XComponent >(xModel, css::uno::UNO_QUERY);
462 // <- SAFE
466 void SAL_CALL LoadEnvListener::loadFinished(const css::uno::Reference< css::frame::XFrameLoader >&)
467 throw(css::uno::RuntimeException)
469 // SAFE -> ----------------------------------
470 WriteGuard aWriteLock(m_aLock);
472 if (m_bWaitingResult)
473 m_pLoadEnv->impl_setResult(sal_True);
474 m_bWaitingResult = false;
476 aWriteLock.unlock();
477 // <- SAFE ----------------------------------
481 void SAL_CALL LoadEnvListener::loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >&)
482 throw(css::uno::RuntimeException)
484 // SAFE -> ----------------------------------
485 WriteGuard aWriteLock(m_aLock);
487 if (m_bWaitingResult)
488 m_pLoadEnv->impl_setResult(sal_False);
489 m_bWaitingResult = false;
491 aWriteLock.unlock();
492 // <- SAFE ----------------------------------
496 void SAL_CALL LoadEnvListener::dispatchFinished(const css::frame::DispatchResultEvent& aEvent)
497 throw(css::uno::RuntimeException)
499 // SAFE -> ----------------------------------
500 WriteGuard aWriteLock(m_aLock);
502 if (!m_bWaitingResult)
503 return;
505 switch(aEvent.State)
507 case css::frame::DispatchResultState::FAILURE :
508 m_pLoadEnv->impl_setResult(sal_False);
509 break;
511 case css::frame::DispatchResultState::SUCCESS :
512 m_pLoadEnv->impl_setResult(sal_False);
513 break;
515 case css::frame::DispatchResultState::DONTKNOW :
516 m_pLoadEnv->impl_setResult(sal_False);
517 break;
519 m_bWaitingResult = false;
521 aWriteLock.unlock();
522 // <- SAFE ----------------------------------
526 void SAL_CALL LoadEnvListener::disposing(const css::lang::EventObject&)
527 throw(css::uno::RuntimeException)
529 // SAFE -> ----------------------------------
530 WriteGuard aWriteLock(m_aLock);
532 if (m_bWaitingResult)
533 m_pLoadEnv->impl_setResult(sal_False);
534 m_bWaitingResult = false;
536 aWriteLock.unlock();
537 // <- SAFE ----------------------------------
541 void LoadEnv::impl_setResult(sal_Bool bResult)
543 // SAFE -> ----------------------------------
544 WriteGuard aWriteLock(m_aLock);
546 m_bLoaded = bResult;
548 impl_reactForLoadingState();
550 // clearing of this reference will unblock waitWhileLoading()!
551 // So we must be sure, that loading process was really finished.
552 // => do it as last operation of this method ...
553 m_xAsynchronousJob.clear();
555 aWriteLock.unlock();
556 // <- SAFE ----------------------------------
559 /*-----------------------------------------------
560 TODO: Is it a good idea to change Sequence<>
561 parameter to stl-adapter?
562 -----------------------------------------------*/
563 LoadEnv::EContentType LoadEnv::classifyContent(const OUString& sURL ,
564 const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor)
566 //-------------------------------------------
567 // (i) Filter some special well known URL protocols,
568 // which can not be handled or loaded in general.
569 // Of course an empty URL must be ignored here too.
570 // Note: These URL schemata are fix and well known ...
571 // But there can be some additional ones, which was not
572 // defined at implementation time of this class :-(
573 // So we have to make sure, that the following code
574 // can detect such protocol schemata too :-)
577 (sURL.isEmpty() ) ||
578 (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_UNO )) ||
579 (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SLOT )) ||
580 (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MACRO )) ||
581 (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SERVICE)) ||
582 (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MAILTO )) ||
583 (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_NEWS ))
586 return E_UNSUPPORTED_CONTENT;
589 //-------------------------------------------
590 // (ii) Some special URLs indicates a given input stream,
591 // a full featured document model directly or
592 // specify a request for opening an empty document.
593 // Such contents are loadable in general.
594 // But we have to check, if the media descriptor contains
595 // all needed resources. If they are missing - the following
596 // load request will fail.
598 /* Attention: The following code can't work on such special URLs!
599 It should not break the office .. but it make no sense
600 to start expensive object creations and complex search
601 algorithm if its clear, that such URLs must be handled
602 in a special way .-)
605 // creation of new documents
606 if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_FACTORY))
607 return E_CAN_BE_LOADED;
609 // using of an existing input stream
610 ::comphelper::MediaDescriptor stlMediaDescriptor(lMediaDescriptor);
611 ::comphelper::MediaDescriptor::const_iterator pIt;
612 if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_STREAM))
614 pIt = stlMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_INPUTSTREAM());
615 css::uno::Reference< css::io::XInputStream > xStream;
616 if (pIt != stlMediaDescriptor.end())
617 pIt->second >>= xStream;
618 if (xStream.is())
619 return E_CAN_BE_LOADED;
620 LOG_WARNING("LoadEnv::classifyContent()", "loading from stream with right URL but invalid stream detected")
621 return E_UNSUPPORTED_CONTENT;
624 // using of a full featured document
625 if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_OBJECT))
627 pIt = stlMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_MODEL());
628 css::uno::Reference< css::frame::XModel > xModel;
629 if (pIt != stlMediaDescriptor.end())
630 pIt->second >>= xModel;
631 if (xModel.is())
632 return E_CAN_BE_SET;
633 LOG_WARNING("LoadEnv::classifyContent()", "loading with object with right URL but invalid object detected")
634 return E_UNSUPPORTED_CONTENT;
637 // following operations can work on an internal type name only :-(
638 css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
639 css::uno::Reference< css::document::XTypeDetection > xDetect(
640 xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_TYPEDETECTION, xContext),
641 css::uno::UNO_QUERY);
643 OUString sType = xDetect->queryTypeByURL(sURL);
645 css::uno::Sequence< css::beans::NamedValue > lQuery(1) ;
646 css::uno::Reference< css::container::XContainerQuery > xContainer ;
647 css::uno::Reference< css::container::XEnumeration > xSet ;
648 css::uno::Sequence< OUString > lTypesReg(1);
651 //-------------------------------------------
652 // (iii) If a FrameLoader service (or at least
653 // a Filter) can be found, which supports
654 // this URL - it must be a loadable content.
655 // Because both items are registered for types
656 // its enough to check for frame loaders only.
657 // Mos of our filters are handled by our global
658 // default loader. But there exist some specialized
659 // loader, which does not work on top of filters!
660 // So its not enough to search on the filter configuration.
661 // Further its not enough to search for types!
662 // Because there exist some types, which are referenced by
663 // other objects ... but not by filters nor frame loaders!
665 OUString sPROP_TYPES(PROP_TYPES);
667 lTypesReg[0] = sType;
668 lQuery[0].Name = sPROP_TYPES;
669 lQuery[0].Value <<= lTypesReg;
671 xContainer = css::uno::Reference< css::container::XContainerQuery >(
672 xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_FRAMELOADERFACTORY, xContext),
673 css::uno::UNO_QUERY);
674 xSet = xContainer->createSubSetEnumerationByProperties(lQuery);
675 // at least one registered frame loader is enough!
676 if (xSet->hasMoreElements())
677 return E_CAN_BE_LOADED;
679 //-------------------------------------------
680 // (iv) Some URL protocols are supported by special services.
681 // E.g. ContentHandler.
682 // Such contents can be handled ... but not loaded.
684 lTypesReg[0] = sType;
685 lQuery[0].Name = sPROP_TYPES;
686 lQuery[0].Value <<= lTypesReg;
688 xContainer = css::uno::Reference< css::container::XContainerQuery >(
689 xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_CONTENTHANDLERFACTORY, xContext),
690 css::uno::UNO_QUERY);
691 xSet = xContainer->createSubSetEnumerationByProperties(lQuery);
692 // at least one registered content handler is enough!
693 if (xSet->hasMoreElements())
694 return E_CAN_BE_HANDLED;
696 //-------------------------------------------
697 // (v) Last but not least the UCB is used inside office to
698 // load contents. He has a special configuration to know
699 // which URL schemata can be used inside office.
700 css::uno::Reference< css::ucb::XUniversalContentBroker > xUCB(css::ucb::UniversalContentBroker::create(xContext));
701 if (xUCB->queryContentProvider(sURL).is())
702 return E_CAN_BE_LOADED;
704 //-------------------------------------------
705 // (TODO) At this point, we have no idea .-)
706 // But it seems to be better, to break all
707 // further requests for this URL. Otherwhise
708 // we can run into some trouble.
709 return E_UNSUPPORTED_CONTENT;
712 namespace {
714 bool queryOrcusTypeAndFilter(const uno::Sequence<beans::PropertyValue>& rDescriptor, OUString& rType, OUString& rFilter)
716 // depending on the experimental mode
717 uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
718 if (!xContext.is() || !officecfg::Office::Common::Misc::ExperimentalMode::get(xContext))
720 return false;
723 OUString aURL;
724 sal_Int32 nSize = rDescriptor.getLength();
725 for (sal_Int32 i = 0; i < nSize; ++i)
727 const beans::PropertyValue& rProp = rDescriptor[i];
728 if (rProp.Name == "URL")
730 rProp.Value >>= aURL;
731 break;
735 if (aURL.isEmpty() || aURL.copy(0,8).equalsIgnoreAsciiCase("private:"))
736 return false;
738 OUString aUseOrcus;
739 rtl::Bootstrap::get("LIBO_USE_ORCUS", aUseOrcus);
740 bool bUseOrcus = (aUseOrcus == "YES");
742 // TODO : Type must be set to be generic_Text (or any other type that
743 // exists) in order to find a usable loader. Exploit it as a temporary
744 // hack.
746 if (aURL.endsWith(".gnumeric"))
748 rType = "generic_Text";
749 rFilter = "gnumeric";
750 return true;
753 if (!bUseOrcus)
754 return false;
756 if (aURL.endsWith(".xlsx"))
758 rType = "generic_Text";
759 rFilter = "xlsx";
760 return true;
762 else if (aURL.endsWith(".ods"))
764 rType = "generic_Text";
765 rFilter = "ods";
766 return true;
768 else if (aURL.endsWith(".csv"))
770 rType = "generic_Text";
771 rFilter = "csv";
772 return true;
775 return false;
780 void LoadEnv::impl_detectTypeAndFilter()
781 throw(LoadEnvException, css::uno::RuntimeException)
783 static OUString TYPEPROP_PREFERREDFILTER("PreferredFilter");
784 static OUString FILTERPROP_FLAGS ("Flags");
785 static sal_Int32 FILTERFLAG_TEMPLATEPATH = 16;
787 // SAFE ->
788 ReadGuard aReadLock(m_aLock);
790 // Attention: Because our stl media descriptor is a copy of an uno sequence
791 // we can't use as an in/out parameter here. Copy it before and dont forget to
792 // update structure afterwards again!
793 css::uno::Sequence< css::beans::PropertyValue > lDescriptor = m_lMediaDescriptor.getAsConstPropertyValueList();
794 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
796 aReadLock.unlock();
797 // <- SAFE
799 OUString sType, sFilter;
801 if (queryOrcusTypeAndFilter(lDescriptor, sType, sFilter) && !sType.isEmpty() && !sFilter.isEmpty())
803 // Orcus type detected. Skip the normal type detection process.
804 m_lMediaDescriptor << lDescriptor;
805 m_lMediaDescriptor[comphelper::MediaDescriptor::PROP_TYPENAME()] <<= sType;
806 m_lMediaDescriptor[comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter;
807 m_lMediaDescriptor[comphelper::MediaDescriptor::PROP_FILTERPROVIDER()] <<= OUString("orcus");
808 return;
811 css::uno::Reference< css::document::XTypeDetection > xDetect(xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY);
812 if (xDetect.is())
813 sType = xDetect->queryTypeByDescriptor(lDescriptor, sal_True); /*TODO should deep detection be able for enable/disable it from outside? */
815 // no valid content -> loading not possible
816 if (sType.isEmpty())
817 throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);
819 // SAFE ->
820 WriteGuard aWriteLock(m_aLock);
822 // detection was successfully => update the descriptor member of this class
823 m_lMediaDescriptor << lDescriptor;
824 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()] <<= sType;
825 // Is there an already detected (may be preselected) filter?
826 // see below ...
827 sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_FILTERNAME(), OUString());
829 aWriteLock.unlock();
830 // <- SAFE
832 // But the type isnt enough. For loading sometimes we need more information.
833 // E.g. for our "_default" feature, where we recylce any frame which contains
834 // and "Untitled" document, we must know if the new document is based on a template!
835 // But this information is available as a filter property only.
836 // => We must try(!) to detect the right filter for this load request.
837 // On the other side ... if no filter is available .. ignore it.
838 // Then the type information must be enough.
839 if (sFilter.isEmpty())
841 // no -> try to find a preferred filter for the detected type.
842 // Dont forget to updatet he media descriptor.
843 css::uno::Reference< css::container::XNameAccess > xTypeCont(xDetect, css::uno::UNO_QUERY_THROW);
846 ::comphelper::SequenceAsHashMap lTypeProps(xTypeCont->getByName(sType));
847 sFilter = lTypeProps.getUnpackedValueOrDefault(TYPEPROP_PREFERREDFILTER, OUString());
848 if (!sFilter.isEmpty())
850 // SAFE ->
851 aWriteLock.lock();
852 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter;
853 aWriteLock.unlock();
854 // <- SAFE
857 catch(const css::container::NoSuchElementException&)
861 // check if the filter (if one exists) points to a template format filter.
862 // Then we have to add the property "AsTemplate".
863 // We need this information to decide afterwards if we can use a "recycle frame"
864 // for target "_default" or has to create a new one everytimes.
865 // On the other side we have to supress that, if this property already exists
866 // and should trigger a special handling. Then the outside calli of this method here,
867 // has to know, what he is doing .-)
869 sal_Bool bIsOwnTemplate = sal_False;
870 if (!sFilter.isEmpty())
872 css::uno::Reference< css::container::XNameAccess > xFilterCont(xSMGR->createInstance(SERVICENAME_FILTERFACTORY), css::uno::UNO_QUERY_THROW);
875 ::comphelper::SequenceAsHashMap lFilterProps(xFilterCont->getByName(sFilter));
876 sal_Int32 nFlags = lFilterProps.getUnpackedValueOrDefault(FILTERPROP_FLAGS, (sal_Int32)0);
877 bIsOwnTemplate = ((nFlags & FILTERFLAG_TEMPLATEPATH) == FILTERFLAG_TEMPLATEPATH);
879 catch(const css::container::NoSuchElementException&)
882 if (bIsOwnTemplate)
884 // SAFE ->
885 aWriteLock.lock();
886 // Dont overwrite external decisions! See comments before ...
887 ::comphelper::MediaDescriptor::const_iterator pAsTemplateItem = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_ASTEMPLATE());
888 if (pAsTemplateItem == m_lMediaDescriptor.end())
889 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_ASTEMPLATE()] <<= sal_True;
890 aWriteLock.unlock();
891 // <- SAFE
896 sal_Bool LoadEnv::impl_handleContent()
897 throw(LoadEnvException, css::uno::RuntimeException)
899 // SAFE -> -----------------------------------
900 ReadGuard aReadLock(m_aLock);
902 // the type must exist inside the descriptor ... otherwise this class is implemented wrong :-)
903 OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), OUString());
904 if (sType.isEmpty())
905 throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR);
907 // convert media descriptor and URL to right format for later interface call!
908 css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
909 m_lMediaDescriptor >> lDescriptor;
910 css::util::URL aURL = m_aURL;
912 // get necessary container to query for a handler object
913 css::uno::Reference< css::lang::XMultiServiceFactory > xFactory(m_xSMGR->createInstance(SERVICENAME_CONTENTHANDLERFACTORY), css::uno::UNO_QUERY);
914 css::uno::Reference< css::container::XContainerQuery > xQuery (xFactory , css::uno::UNO_QUERY);
916 aReadLock.unlock();
917 // <- SAFE -----------------------------------
919 // query
920 css::uno::Sequence< OUString > lTypeReg(1);
921 lTypeReg[0] = sType;
923 css::uno::Sequence< css::beans::NamedValue > lQuery(1);
924 lQuery[0].Name = OUString(PROP_TYPES);
925 lQuery[0].Value <<= lTypeReg;
927 OUString sPROP_NAME(PROP_NAME);
929 css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery);
930 while(xSet->hasMoreElements())
932 ::comphelper::SequenceAsHashMap lProps (xSet->nextElement());
933 OUString sHandler = lProps.getUnpackedValueOrDefault(sPROP_NAME, OUString());
935 css::uno::Reference< css::frame::XNotifyingDispatch > xHandler;
938 xHandler = css::uno::Reference< css::frame::XNotifyingDispatch >(xFactory->createInstance(sHandler), css::uno::UNO_QUERY);
939 if (!xHandler.is())
940 continue;
942 catch(const css::uno::RuntimeException&)
943 { throw; }
944 catch(const css::uno::Exception&)
945 { continue; }
947 // SAFE -> -----------------------------------
948 WriteGuard aWriteLock(m_aLock);
949 m_xAsynchronousJob = xHandler;
950 LoadEnvListener* pListener = new LoadEnvListener(this);
951 aWriteLock.unlock();
952 // <- SAFE -----------------------------------
954 css::uno::Reference< css::frame::XDispatchResultListener > xListener(static_cast< css::frame::XDispatchResultListener* >(pListener), css::uno::UNO_QUERY);
955 xHandler->dispatchWithNotification(aURL, lDescriptor, xListener);
957 return sal_True;
960 return sal_False;
963 //-----------------------------------------------
964 sal_Bool LoadEnv::impl_furtherDocsAllowed()
966 // SAFE ->
967 ReadGuard aReadLock(m_aLock);
968 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
969 aReadLock.unlock();
970 // <- SAFE
972 sal_Bool bAllowed = sal_True;
976 css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
977 comphelper::getComponentContext(xSMGR),
978 OUString("org.openoffice.Office.Common/"),
979 OUString("Misc"),
980 OUString("MaxOpenDocuments"),
981 ::comphelper::ConfigurationHelper::E_READONLY);
983 // NIL means: count of allowed documents = infinite !
984 // => return sal_True
985 if ( ! aVal.hasValue())
986 bAllowed = sal_True;
987 else
989 sal_Int32 nMaxOpenDocuments = 0;
990 aVal >>= nMaxOpenDocuments;
992 css::uno::Reference< css::frame::XFramesSupplier > xDesktop(
993 css::frame::Desktop::create( comphelper::getComponentContext(xSMGR)),
994 css::uno::UNO_QUERY_THROW);
996 FrameListAnalyzer aAnalyzer(xDesktop,
997 css::uno::Reference< css::frame::XFrame >(),
998 FrameListAnalyzer::E_HELP |
999 FrameListAnalyzer::E_BACKINGCOMPONENT |
1000 FrameListAnalyzer::E_HIDDEN);
1002 sal_Int32 nOpenDocuments = aAnalyzer.m_lOtherVisibleFrames.getLength();
1003 bAllowed = (nOpenDocuments < nMaxOpenDocuments);
1006 catch(const css::uno::Exception&)
1007 { bAllowed = sal_True; } // !! internal errors are no reason to disturb the office from opening documents .-)
1009 if ( ! bAllowed )
1011 // SAFE ->
1012 aReadLock.lock();
1013 css::uno::Reference< css::task::XInteractionHandler > xInteraction = m_lMediaDescriptor.getUnpackedValueOrDefault(
1014 ::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER(),
1015 css::uno::Reference< css::task::XInteractionHandler >());
1016 aReadLock.unlock();
1017 // <- SAFE
1019 if (xInteraction.is())
1021 css::uno::Any aInteraction;
1022 css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations(2);
1024 comphelper::OInteractionAbort* pAbort = new comphelper::OInteractionAbort();
1025 comphelper::OInteractionApprove* pApprove = new comphelper::OInteractionApprove();
1027 lContinuations[0] = css::uno::Reference< css::task::XInteractionContinuation >(
1028 static_cast< css::task::XInteractionContinuation* >(pAbort),
1029 css::uno::UNO_QUERY_THROW);
1030 lContinuations[1] = css::uno::Reference< css::task::XInteractionContinuation >(
1031 static_cast< css::task::XInteractionContinuation* >(pApprove),
1032 css::uno::UNO_QUERY_THROW);
1034 css::task::ErrorCodeRequest aErrorCode;
1035 aErrorCode.ErrCode = ERRCODE_SFX_NOMOREDOCUMENTSALLOWED;
1036 aInteraction <<= aErrorCode;
1037 xInteraction->handle( InteractionRequest::CreateRequest(aInteraction, lContinuations) );
1041 return bAllowed;
1044 //-----------------------------------------------
1045 sal_Bool LoadEnv::impl_loadContent()
1046 throw(LoadEnvException, css::uno::RuntimeException)
1048 // SAFE -> -----------------------------------
1049 WriteGuard aWriteLock(m_aLock);
1051 // search or create right target frame
1052 OUString sTarget = m_sTarget;
1053 if (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_DEFAULT))
1055 m_xTargetFrame = impl_searchAlreadyLoaded();
1056 if (m_xTargetFrame.is())
1058 impl_setResult(sal_True);
1059 return sal_True;
1061 m_xTargetFrame = impl_searchRecycleTarget();
1064 if (! m_xTargetFrame.is())
1066 if (
1067 (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_BLANK )) ||
1068 (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_DEFAULT))
1071 if (! impl_furtherDocsAllowed())
1072 return sal_False;
1073 m_xTargetFrame = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0);
1074 m_bCloseFrameOnError = m_xTargetFrame.is();
1076 else
1078 sal_Int32 nFlags = m_nSearchFlags & ~css::frame::FrameSearchFlag::CREATE;
1079 m_xTargetFrame = m_xBaseFrame->findFrame(sTarget, nFlags);
1080 if (! m_xTargetFrame.is())
1082 if (! impl_furtherDocsAllowed())
1083 return sal_False;
1084 m_xTargetFrame = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0);
1085 m_bCloseFrameOnError = m_xTargetFrame.is();
1090 // If we couldn't find a valid frame or the frame has no container window
1091 // we have to throw an exception.
1092 if (
1093 ( ! m_xTargetFrame.is() ) ||
1094 ( ! m_xTargetFrame->getContainerWindow().is() )
1096 throw LoadEnvException(LoadEnvException::ID_NO_TARGET_FOUND);
1098 css::uno::Reference< css::frame::XFrame > xTargetFrame = m_xTargetFrame;
1100 // Now we have a valid frame ... and type detection was already done.
1101 // We should apply the module dependend window position and size to the
1102 // frame window.
1103 impl_applyPersistentWindowState(xTargetFrame->getContainerWindow());
1105 // Don't forget to lock task for following load process. Otherwise it could die
1106 // during this operation runs by terminating the office or closing this task via api.
1107 // If we set this lock "close()" will return false and closing will be broken.
1108 // Attention: Don't forget to reset this lock again after finishing operation.
1109 // Otherwise task AND office couldn't die!!!
1110 // This includes gracefully handling of Exceptions (Runtime!) too ...
1111 // Thats why we use a specialized guard, which will reset the lock
1112 // if it will be run out of scope.
1114 // Note further: ignore if this internal guard already contains a resource.
1115 // Might impl_searchRecylcTarget() set it before. But incase this impl-method wasnt used
1116 // and the target frame was new created ... this lock here must be set!
1117 css::uno::Reference< css::document::XActionLockable > xTargetLock(xTargetFrame, css::uno::UNO_QUERY);
1118 m_aTargetLock.setResource(xTargetLock);
1120 // Add status indicator to descriptor. Loader can show an progresses then.
1121 // But don't do it, if loading should be hidden or preview is used ...!
1122 // So we prevent our code against wrong using. Why?
1123 // It could be, that using of this progress could make trouble. e.g. He make window visible ...
1124 // but shouldn't do that. But if no indicator is available ... nobody has a chance to do that!
1125 sal_Bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False );
1126 sal_Bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_MINIMIZED() , sal_False );
1127 sal_Bool bPreview = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_PREVIEW() , sal_False );
1128 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_STATUSINDICATOR(), css::uno::Reference< css::task::XStatusIndicator >());
1130 if (!bHidden && !bMinimized && !bPreview && !xProgress.is())
1132 // Note: its an optional interface!
1133 css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xTargetFrame, css::uno::UNO_QUERY);
1134 if (xProgressFactory.is())
1136 xProgress = xProgressFactory->createStatusIndicator();
1137 if (xProgress.is())
1138 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_STATUSINDICATOR()] <<= xProgress;
1142 // convert media descriptor and URL to right format for later interface call!
1143 css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
1144 m_lMediaDescriptor >> lDescriptor;
1145 OUString sURL = m_aURL.Complete;
1147 // try to locate any interested frame loader
1148 css::uno::Reference< css::uno::XInterface > xLoader = impl_searchLoader();
1149 css::uno::Reference< css::frame::XFrameLoader > xAsyncLoader(xLoader, css::uno::UNO_QUERY);
1150 css::uno::Reference< css::frame::XSynchronousFrameLoader > xSyncLoader (xLoader, css::uno::UNO_QUERY);
1152 if (xAsyncLoader.is())
1154 // SAFE -> -----------------------------------
1155 aWriteLock.lock();
1156 m_xAsynchronousJob = xAsyncLoader;
1157 LoadEnvListener* pListener = new LoadEnvListener(this);
1158 aWriteLock.unlock();
1159 // <- SAFE -----------------------------------
1161 css::uno::Reference< css::frame::XLoadEventListener > xListener(static_cast< css::frame::XLoadEventListener* >(pListener), css::uno::UNO_QUERY);
1162 xAsyncLoader->load(xTargetFrame, sURL, lDescriptor, xListener);
1164 return sal_True;
1166 else if (xSyncLoader.is())
1168 sal_Bool bResult = xSyncLoader->load(lDescriptor, xTargetFrame);
1169 // react for the result here, so the outside waiting
1170 // code can ask for it later.
1171 impl_setResult(bResult);
1172 // But the return value indicates a valid started(!) operation.
1173 // And thats true everxtimes, we reach this line :-)
1174 return sal_True;
1177 aWriteLock.unlock();
1178 // <- SAFE
1180 return sal_False;
1184 css::uno::Reference< css::uno::XInterface > LoadEnv::impl_searchLoader()
1186 // SAFE -> -----------------------------------
1187 ReadGuard aReadLock(m_aLock);
1189 // special mode to set an existing component on this frame
1190 // In such case the laoder is fix. It must be the SFX based implementation,
1191 // which can create a view on top of such xModel components :-)
1192 if (m_eContentType == E_CAN_BE_SET)
1196 return m_xSMGR->createInstance(IMPLEMENTATIONNAME_GENERICFRAMELOADER);
1198 catch(const css::uno::RuntimeException&)
1199 { throw; }
1200 catch(const css::uno::Exception&)
1202 throw LoadEnvException(LoadEnvException::ID_INVALID_ENVIRONMENT);
1205 // Otherwhise ...
1206 // We need this type information to locate an registered frame loader
1207 // Without such information we can't work!
1208 OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), OUString());
1209 if (sType.isEmpty())
1210 throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR);
1212 // try to locate any interested frame loader
1213 css::uno::Reference< css::lang::XMultiServiceFactory > xLoaderFactory(m_xSMGR->createInstance(SERVICENAME_FRAMELOADERFACTORY), css::uno::UNO_QUERY);
1214 css::uno::Reference< css::container::XContainerQuery > xQuery (xLoaderFactory , css::uno::UNO_QUERY);
1216 aReadLock.unlock();
1217 // <- SAFE -----------------------------------
1219 css::uno::Sequence< OUString > lTypesReg(1);
1220 lTypesReg[0] = sType;
1222 css::uno::Sequence< css::beans::NamedValue > lQuery(1);
1223 lQuery[0].Name = OUString(PROP_TYPES);
1224 lQuery[0].Value <<= lTypesReg;
1226 OUString sPROP_NAME(PROP_NAME);
1228 css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery);
1229 while(xSet->hasMoreElements())
1231 // try everyone ...
1232 // Ignore any loader, which makes trouble :-)
1233 ::comphelper::SequenceAsHashMap lLoaderProps(xSet->nextElement());
1234 OUString sLoader = lLoaderProps.getUnpackedValueOrDefault(sPROP_NAME, OUString());
1235 css::uno::Reference< css::uno::XInterface > xLoader ;
1238 xLoader = xLoaderFactory->createInstance(sLoader);
1239 if (xLoader.is())
1240 return xLoader;
1242 catch(const css::uno::RuntimeException&)
1243 { throw; }
1244 catch(const css::uno::Exception&)
1245 { continue; }
1248 return css::uno::Reference< css::uno::XInterface >();
1252 void LoadEnv::impl_jumpToMark(const css::uno::Reference< css::frame::XFrame >& xFrame,
1253 const css::util::URL& aURL )
1255 if (aURL.Mark.isEmpty())
1256 return;
1258 css::uno::Reference< css::frame::XDispatchProvider > xProvider(xFrame, css::uno::UNO_QUERY);
1259 if (! xProvider.is())
1260 return;
1262 // SAFE ->
1263 ReadGuard aReadLock(m_aLock);
1264 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1265 aReadLock.unlock();
1266 // <- SAFE
1268 css::util::URL aCmd;
1269 aCmd.Complete = OUString(".uno:JumpToMark");
1271 css::uno::Reference< css::util::XURLTransformer > xParser(css::util::URLTransformer::create(::comphelper::getComponentContext(m_xSMGR)));
1272 xParser->parseStrict(aCmd);
1274 css::uno::Reference< css::frame::XDispatch > xDispatcher = xProvider->queryDispatch(aCmd, SPECIALTARGET_SELF, 0);
1275 if (! xDispatcher.is())
1276 return;
1278 ::comphelper::SequenceAsHashMap lArgs;
1279 lArgs[OUString("Bookmark")] <<= aURL.Mark;
1280 xDispatcher->dispatch(aCmd, lArgs.getAsConstPropertyValueList());
1284 css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchAlreadyLoaded()
1285 throw(LoadEnvException, css::uno::RuntimeException)
1287 // SAFE ->
1288 ReadGuard aReadLock(m_aLock);
1290 // such search is allowed for special requests only ...
1291 // or better its not allowed for some requests in general :-)
1292 if (
1293 ( ! TargetHelper::matchSpecialTarget(m_sTarget, TargetHelper::E_DEFAULT) ) ||
1294 (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_ASTEMPLATE() , sal_False) == sal_True) ||
1295 // (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False) == sal_True) ||
1296 (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_OPENNEWVIEW(), sal_False) == sal_True)
1299 return css::uno::Reference< css::frame::XFrame >();
1302 // check URL
1303 // May its not useful to start expensive document search, if it
1304 // can fail only .. because we load from a stream or model directly!
1305 if (
1306 (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM )) ||
1307 (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT ))
1308 /*TODO should be private:factory here tested too? */
1311 return css::uno::Reference< css::frame::XFrame >();
1314 // otherwise - iterate through the tasks of the desktop container
1315 // to find out, which of them might contains the requested document
1316 css::uno::Reference< css::frame::XDesktop2 > xSupplier = css::frame::Desktop::create( comphelper::getComponentContext(m_xSMGR) );
1317 css::uno::Reference< css::container::XIndexAccess > xTaskList(xSupplier->getFrames() , css::uno::UNO_QUERY);
1319 if (!xTaskList.is())
1320 return css::uno::Reference< css::frame::XFrame >(); // task list can be empty!
1322 // Note: To detect if a document was alrady loaded before
1323 // we check URLs here only. But might the existing and the required
1324 // document has different versions! Then its URLs are the same ...
1325 sal_Int16 nNewVersion = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_VERSION(), (sal_Int16)(-1));
1327 // will be used to save the first hidden frame referring the searched model
1328 // Normally we are interested on visible frames ... but if there is no such visible
1329 // frame we referr to any hidden frame also (but as fallback only).
1330 css::uno::Reference< css::frame::XFrame > xHiddenTask;
1331 css::uno::Reference< css::frame::XFrame > xTask;
1333 sal_Int32 count = xTaskList->getCount();
1334 for (sal_Int32 i=0; i<count; ++i)
1338 // locate model of task
1339 // Note: Without a model there is no chance to decide if
1340 // this task contains the searched document or not!
1341 xTaskList->getByIndex(i) >>= xTask;
1342 if (!xTask.is())
1343 continue;
1345 css::uno::Reference< css::frame::XController > xController = xTask->getController();
1346 if (!xController.is())
1348 xTask.clear ();
1349 continue;
1352 css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
1353 if (!xModel.is())
1355 xTask.clear ();
1356 continue;
1359 // don't check the complete URL here.
1360 // use its main part - ignore optional jumpmarks!
1361 const OUString sURL = xModel->getURL();
1362 if (!::utl::UCBContentHelper::EqualURLs( m_aURL.Main, sURL ))
1364 xTask.clear ();
1365 continue;
1368 // get the original load arguments from the current document
1369 // and decide if its really the same then the one will be.
1370 // It must be visible and must use the same file revision ...
1371 // or must not have any file revision set (-1 == -1!)
1372 ::comphelper::MediaDescriptor lOldDocDescriptor(xModel->getArgs());
1374 if (lOldDocDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_VERSION(), (sal_Int32)(-1)) != nNewVersion)
1376 xTask.clear ();
1377 continue;
1380 // Hidden frames are special.
1381 // They will be used as "last chance" if there is no visible frame pointing to the same model.
1382 // Safe the result but continue with current loop might be looking for other visible frames.
1383 ::sal_Bool bIsHidden = lOldDocDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False);
1384 if (
1385 ( bIsHidden ) &&
1386 ( ! xHiddenTask.is())
1389 xHiddenTask = xTask;
1390 xTask.clear ();
1391 continue;
1394 // We found a visible task pointing to the right model ...
1395 // Break search.
1396 break;
1398 catch(const css::uno::RuntimeException&)
1399 { throw; }
1400 catch(const css::uno::Exception&)
1401 { continue; }
1404 css::uno::Reference< css::frame::XFrame > xResult;
1405 if (xTask.is())
1406 xResult = xTask;
1407 else if (xHiddenTask.is())
1408 xResult = xHiddenTask;
1410 if (xResult.is())
1412 // Now we are sure, that this task includes the searched document.
1413 // It's time to activate it. As special feature we try to jump internally
1414 // if an optional jumpmark is given too.
1415 if (!m_aURL.Mark.isEmpty())
1416 impl_jumpToMark(xResult, m_aURL);
1418 // bring it to front and make sure it's visible...
1419 impl_makeFrameWindowVisible(xResult->getContainerWindow(), sal_True);
1422 aReadLock.unlock();
1423 // <- SAFE
1425 return xResult;
1429 sal_Bool LoadEnv::impl_isFrameAlreadyUsedForLoading(const css::uno::Reference< css::frame::XFrame >& xFrame) const
1431 css::uno::Reference< css::document::XActionLockable > xLock(xFrame, css::uno::UNO_QUERY);
1433 // ? no lock interface ?
1434 // Might its an external written frame implementation :-(
1435 // Allowing using of it ... but it can fail if its not synchronized with our processes !
1436 if (!xLock.is())
1437 return sal_False;
1439 // Otherwise we have to look for any other existing lock.
1440 return xLock->isActionLocked();
1444 css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchRecycleTarget()
1445 throw(LoadEnvException, css::uno::RuntimeException)
1447 // SAFE -> ..................................
1448 ReadGuard aReadLock(m_aLock);
1450 // The special backing mode frame will be recycled by definition!
1451 // It doesn't matter if somehwere whish to create a new view
1452 // or open a new untitled document ...
1453 // The only exception form that - hidden frames!
1454 if (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False) == sal_True)
1455 return css::uno::Reference< css::frame::XFrame >();
1457 css::uno::Reference< css::frame::XFramesSupplier > xSupplier( css::frame::Desktop::create( comphelper::getComponentContext(m_xSMGR) ), css::uno::UNO_QUERY);
1458 FrameListAnalyzer aTasksAnalyzer(xSupplier, css::uno::Reference< css::frame::XFrame >(), FrameListAnalyzer::E_BACKINGCOMPONENT);
1459 if (aTasksAnalyzer.m_xBackingComponent.is())
1461 if (!impl_isFrameAlreadyUsedForLoading(aTasksAnalyzer.m_xBackingComponent))
1463 // bring it to front ...
1464 impl_makeFrameWindowVisible(aTasksAnalyzer.m_xBackingComponent->getContainerWindow(), sal_True);
1465 return aTasksAnalyzer.m_xBackingComponent;
1469 // These states indicates a wish for creation of a new view in general.
1470 if (
1471 (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_ASTEMPLATE() , sal_False) == sal_True) ||
1472 (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_OPENNEWVIEW(), sal_False) == sal_True)
1475 return css::uno::Reference< css::frame::XFrame >();
1478 // On the other side some special URLs will open a new frame everytimes (expecting
1479 // they can use the backing-mode frame!)
1480 if (
1481 (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_FACTORY )) ||
1482 (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM )) ||
1483 (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT ))
1486 return css::uno::Reference< css::frame::XFrame >();
1489 // No backing frame! No special URL => recycle active task - if possible.
1490 // Means - if it does not already contains a modified document, or
1491 // use another office module.
1492 css::uno::Reference< css::frame::XFrame > xTask = xSupplier->getActiveFrame();
1494 // not a real error - but might a focus problem!
1495 if (!xTask.is())
1496 return css::uno::Reference< css::frame::XFrame >();
1498 // not a real error - may its a view only
1499 css::uno::Reference< css::frame::XController > xController = xTask->getController();
1500 if (!xController.is())
1501 return css::uno::Reference< css::frame::XFrame >();
1503 // not a real error - may its a db component instead of a full feartured office document
1504 css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
1505 if (!xModel.is())
1506 return css::uno::Reference< css::frame::XFrame >();
1508 // get some more information ...
1510 // A valid set URL means: there is already a location for this document.
1511 // => it was saved there or opened from there. Such Documents can not be used here.
1512 // We search for empty document ... created by a private:factory/ URL!
1513 if (xModel->getURL().getLength()>0)
1514 return css::uno::Reference< css::frame::XFrame >();
1516 // The old document must be unmodified ...
1517 css::uno::Reference< css::util::XModifiable > xModified(xModel, css::uno::UNO_QUERY);
1518 if (xModified->isModified())
1519 return css::uno::Reference< css::frame::XFrame >();
1521 Window* pWindow = VCLUnoHelper::GetWindow(xTask->getContainerWindow());
1522 if (pWindow && pWindow->IsInModalMode())
1523 return css::uno::Reference< css::frame::XFrame >();
1525 // find out the application type of this document
1526 // We can recycle only documents, which uses the same application
1527 // then the new one.
1528 SvtModuleOptions::EFactory eOldApp = SvtModuleOptions::ClassifyFactoryByModel(xModel);
1529 SvtModuleOptions::EFactory eNewApp = SvtModuleOptions::ClassifyFactoryByURL (m_aURL.Complete, m_lMediaDescriptor.getAsConstPropertyValueList());
1531 aReadLock.unlock();
1532 // <- SAFE ..................................
1534 if (eOldApp != eNewApp)
1535 return css::uno::Reference< css::frame::XFrame >();
1537 // OK this task seams to be useable for recycling
1538 // But we should mark it as such - means set an action lock.
1539 // Otherwhise it would be used more then ones or will be destroyed
1540 // by a close() or terminate() request.
1541 // But if such lock already exist ... it means this task is used for
1542 // any other operation already. Don't use it then.
1543 if (impl_isFrameAlreadyUsedForLoading(xTask))
1544 return css::uno::Reference< css::frame::XFrame >();
1546 // OK - there is a valid target frame.
1547 // But may be it contains already a document.
1548 // Then we have to ask it, if it allows recylcing of this frame .-)
1549 sal_Bool bReactivateOldControllerOnError = sal_False;
1550 css::uno::Reference< css::frame::XController > xOldDoc = xTask->getController();
1551 if (xOldDoc.is())
1553 bReactivateOldControllerOnError = xOldDoc->suspend(sal_True);
1554 if (! bReactivateOldControllerOnError)
1555 return css::uno::Reference< css::frame::XFrame >();
1558 // SAFE -> ..................................
1559 WriteGuard aWriteLock(m_aLock);
1561 css::uno::Reference< css::document::XActionLockable > xLock(xTask, css::uno::UNO_QUERY);
1562 if (!m_aTargetLock.setResource(xLock))
1563 return css::uno::Reference< css::frame::XFrame >();
1565 m_bReactivateControllerOnError = bReactivateOldControllerOnError;
1566 aWriteLock.unlock();
1567 // <- SAFE ..................................
1569 // bring it to front ...
1570 impl_makeFrameWindowVisible(xTask->getContainerWindow(), sal_True);
1572 return xTask;
1576 void LoadEnv::impl_reactForLoadingState()
1577 throw(LoadEnvException, css::uno::RuntimeException)
1579 /*TODO reset action locks */
1581 // SAFE -> ----------------------------------
1582 ReadGuard aReadLock(m_aLock);
1584 if (m_bLoaded)
1586 // Bring the new loaded document to front (if allowed!).
1587 // Note: We show new created frames here only.
1588 // We dont hide already visible frames here ...
1589 css::uno::Reference< css::awt::XWindow > xWindow = m_xTargetFrame->getContainerWindow();
1590 sal_Bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False);
1591 sal_Bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_MINIMIZED(), sal_False);
1593 if (bMinimized)
1595 SolarMutexGuard aSolarGuard;
1596 Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
1597 // check for system window is necessary to guarantee correct pointer cast!
1598 if (pWindow && pWindow->IsSystemWindow())
1599 ((WorkWindow*)pWindow)->Minimize();
1601 else if (!bHidden)
1603 // show frame ... if it's not still visible ...
1604 // But do nothing if it's already visible!
1605 impl_makeFrameWindowVisible(xWindow, sal_False);
1608 // Note: Only if an existing property "FrameName" is given by this media descriptor,
1609 // it should be used. Otherwhise we should do nothing. May be the outside code has already
1610 // set a frame name on the target!
1611 ::comphelper::MediaDescriptor::const_iterator pFrameName = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_FRAMENAME());
1612 if (pFrameName != m_lMediaDescriptor.end())
1614 OUString sFrameName;
1615 pFrameName->second >>= sFrameName;
1616 // Check the name again. e.g. "_default" isnt allowed.
1617 // On the other side "_beamer" is a valid name :-)
1618 if (TargetHelper::isValidNameForFrame(sFrameName))
1619 m_xTargetFrame->setName(sFrameName);
1622 else if (m_bReactivateControllerOnError)
1624 // Try to reactivate the old document (if any exists!)
1625 css::uno::Reference< css::frame::XController > xOldDoc = m_xTargetFrame->getController();
1626 // clear does not depend from reactivation state of a might existing old document!
1627 // We must make sure, that a might following getTargetComponent() call does not return
1628 // the old document!
1629 m_xTargetFrame.clear();
1630 if (xOldDoc.is())
1632 sal_Bool bReactivated = xOldDoc->suspend(sal_False);
1633 if (!bReactivated)
1634 throw LoadEnvException(LoadEnvException::ID_COULD_NOT_REACTIVATE_CONTROLLER);
1635 m_bReactivateControllerOnError = sal_False;
1638 else if (m_bCloseFrameOnError)
1640 // close empty frames
1641 css::uno::Reference< css::util::XCloseable > xCloseable (m_xTargetFrame, css::uno::UNO_QUERY);
1642 css::uno::Reference< css::lang::XComponent > xDisposable(m_xTargetFrame, css::uno::UNO_QUERY);
1646 if (xCloseable.is())
1647 xCloseable->close(sal_True);
1648 else
1649 if (xDisposable.is())
1650 xDisposable->dispose();
1652 catch(const css::util::CloseVetoException&)
1654 catch(const css::lang::DisposedException&)
1656 m_xTargetFrame.clear();
1659 // This max force an implicit closing of our target frame ...
1660 // e.g. in case close(sal_True) was called before and the frame
1661 // kill itself if our external use-lock is released here!
1662 // Thats why we releas this lock AFTER ALL OPERATIONS on this frame
1663 // are finished. The frame itslef must handle then
1664 // this situation gracefully.
1665 m_aTargetLock.freeResource();
1667 // Last but not least :-)
1668 // We have to clear the current media descriptor.
1669 // Otherwhise it hold a might existing stream open!
1670 m_lMediaDescriptor.clear();
1672 css::uno::Any aRequest;
1673 bool bThrow = false;
1674 if ( !m_bLoaded && m_pQuietInteraction && m_pQuietInteraction->wasUsed() )
1676 aRequest = m_pQuietInteraction->getRequest();
1677 m_pQuietInteraction->release();
1678 m_pQuietInteraction = 0;
1679 bThrow = true;
1682 aReadLock.unlock();
1684 if (bThrow)
1686 if ( aRequest.isExtractableTo( ::cppu::UnoType< css::uno::Exception >::get() ) )
1687 throw LoadEnvException( LoadEnvException::ID_GENERAL_ERROR, aRequest );
1690 // <- SAFE ----------------------------------
1694 void LoadEnv::impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::XWindow >& xWindow ,
1695 sal_Bool bForceToFront)
1697 // SAFE -> ----------------------------------
1698 ReadGuard aReadLock(m_aLock);
1699 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xSMGR.get(), css::uno::UNO_QUERY );
1700 aReadLock.unlock();
1701 // <- SAFE ----------------------------------
1703 SolarMutexGuard aSolarGuard;
1704 Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
1705 if ( pWindow )
1707 bool const preview( m_lMediaDescriptor.getUnpackedValueOrDefault(
1708 ::comphelper::MediaDescriptor::PROP_PREVIEW(), sal_False) );
1710 bool bForceFrontAndFocus(false);
1711 if ( !preview )
1713 css::uno::Any const a =
1714 ::comphelper::ConfigurationHelper::readDirectKey(
1715 comphelper::getComponentContext(xSMGR),
1716 OUString("org.openoffice.Office.Common/View"),
1717 OUString("NewDocumentHandling"),
1718 OUString("ForceFocusAndToFront"),
1719 ::comphelper::ConfigurationHelper::E_READONLY);
1720 a >>= bForceFrontAndFocus;
1723 if( pWindow->IsVisible() && (bForceFrontAndFocus || bForceToFront) )
1724 pWindow->ToTop();
1725 else
1726 pWindow->Show(sal_True, (bForceFrontAndFocus || bForceToFront) ? SHOW_FOREGROUNDTASK : 0 );
1731 void LoadEnv::impl_applyPersistentWindowState(const css::uno::Reference< css::awt::XWindow >& xWindow)
1733 static OUString PACKAGE_SETUP_MODULES("/org.openoffice.Setup/Office/Factories");
1735 // no window -> action not possible
1736 if (!xWindow.is())
1737 return;
1739 // window already visible -> do nothing! If we use a "recycle frame" for loading ...
1740 // the current position and size must be used.
1741 css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(xWindow, css::uno::UNO_QUERY);
1742 if (
1743 (xVisibleCheck.is() ) &&
1744 (xVisibleCheck->isVisible())
1746 return;
1748 // SOLAR SAFE ->
1749 SolarMutexClearableGuard aSolarGuard1;
1751 Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
1752 if (!pWindow)
1753 return;
1755 sal_Bool bSystemWindow = pWindow->IsSystemWindow();
1756 sal_Bool bWorkWindow = (pWindow->GetType() == WINDOW_WORKWINDOW);
1758 if (!bSystemWindow && !bWorkWindow)
1759 return;
1761 // dont overwrite this special state!
1762 WorkWindow* pWorkWindow = (WorkWindow*)pWindow;
1763 if (pWorkWindow->IsMinimized())
1764 return;
1766 aSolarGuard1.clear();
1767 // <- SOLAR SAFE
1769 // SAFE ->
1770 ReadGuard aReadLock(m_aLock);
1772 // no filter -> no module -> no persistent window state
1773 OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(
1774 ::comphelper::MediaDescriptor::PROP_FILTERNAME(),
1775 OUString());
1776 if (sFilter.isEmpty())
1777 return;
1779 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1781 aReadLock.unlock();
1782 // <- SAFE
1786 // retrieve the module name from the filter configuration
1787 css::uno::Reference< css::container::XNameAccess > xFilterCfg(
1788 xSMGR->createInstance(SERVICENAME_FILTERFACTORY),
1789 css::uno::UNO_QUERY_THROW);
1790 ::comphelper::SequenceAsHashMap lProps (xFilterCfg->getByName(sFilter));
1791 OUString sModule = lProps.getUnpackedValueOrDefault(FILTER_PROPNAME_DOCUMENTSERVICE, OUString());
1793 // get access to the configuration of this office module
1794 css::uno::Reference< css::container::XNameAccess > xModuleCfg(::comphelper::ConfigurationHelper::openConfig(
1795 comphelper::getComponentContext(xSMGR),
1796 PACKAGE_SETUP_MODULES,
1797 ::comphelper::ConfigurationHelper::E_READONLY),
1798 css::uno::UNO_QUERY_THROW);
1800 // read window state from the configuration
1801 // and apply it on the window.
1802 // Do nothing, if no configuration entry exists!
1803 OUString sWindowState ;
1804 ::comphelper::ConfigurationHelper::readRelativeKey(xModuleCfg, sModule, OFFICEFACTORY_PROPNAME_WINDOWATTRIBUTES) >>= sWindowState;
1805 if (!sWindowState.isEmpty())
1807 // SOLAR SAFE ->
1808 SolarMutexGuard aSolarGuard;
1810 // We have to retrieve the window pointer again. Because nobody can guarantee
1811 // that the XWindow was not disposed inbetween .-)
1812 // But if we get a valid pointer we can be sure, that it's the system window pointer
1813 // we already checked and used before. Because nobody recylce the same uno reference for
1814 // a new internal c++ implementation ... hopefully .-))
1815 Window* pWindowCheck = VCLUnoHelper::GetWindow(xWindow);
1816 if (! pWindowCheck)
1817 return;
1819 SystemWindow* pSystemWindow = (SystemWindow*)pWindowCheck;
1820 pSystemWindow->SetWindowState(OUStringToOString(sWindowState,RTL_TEXTENCODING_UTF8));
1821 // <- SOLAR SAFE
1824 catch(const css::uno::RuntimeException&)
1825 { throw; }
1826 catch(const css::uno::Exception&)
1830 } // namespace framework
1832 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */