1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 //_______________________________________________
31 // includes of own project
32 #include <loadenv/loadenv.hxx>
33 
34 #ifndef __FRAMEWORK_LOADENV_TARGETHELPER_HXX_
35 #include <loadenv/targethelper.hxx>
36 #endif
37 #include <framework/framelistanalyzer.hxx>
38 
39 #ifndef __FRAMEWORK_CONSTANT_FRAMELOADER_HXX_
40 #include <constant/frameloader.hxx>
41 #endif
42 
43 #ifndef __FRAMEWORK_CONSTANT_CONTENTHANDLER_HXX_
44 #include <constant/contenthandler.hxx>
45 #endif
46 
47 #ifndef __FRAMEWORK_CONSTANT_CONTAINERQUERY_HXX_
48 #include <constant/containerquery.hxx>
49 #endif
50 #include <interaction/quietinteraction.hxx>
51 #include <threadhelp/writeguard.hxx>
52 #include <threadhelp/readguard.hxx>
53 #include <threadhelp/resetableguard.hxx>
54 #include <properties.h>
55 #include <protocols.h>
56 #include <services.h>
57 #include <comphelper/interaction.hxx>
58 #include <framework/interaction.hxx>
59 
60 //_______________________________________________
61 // includes of uno interface
62 #include <com/sun/star/task/ErrorCodeRequest.hpp>
63 #include <com/sun/star/uno/RuntimeException.hpp>
64 #include <com/sun/star/frame/DispatchResultState.hpp>
65 #include <com/sun/star/frame/FrameSearchFlag.hpp>
66 #include <com/sun/star/util/XURLTransformer.hpp>
67 #include <com/sun/star/ucb/XContentProviderManager.hpp>
68 #include <com/sun/star/util/XCloseable.hpp>
69 #include <com/sun/star/lang/XComponent.hpp>
70 #include <com/sun/star/lang/XServiceInfo.hpp>
71 #include <com/sun/star/lang/DisposedException.hpp>
72 #include <com/sun/star/awt/XWindow.hpp>
73 #include <com/sun/star/awt/XWindow2.hpp>
74 #include <com/sun/star/awt/XTopWindow.hpp>
75 #include <com/sun/star/frame/XModel.hpp>
76 #include <com/sun/star/frame/XFrameLoader.hpp>
77 #include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
78 #include <com/sun/star/frame/XNotifyingDispatch.hpp>
79 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
80 #include <com/sun/star/task/XStatusIndicator.hpp>
81 #include <com/sun/star/util/XModifiable.hpp>
82 #include <com/sun/star/frame/XDispatchProvider.hpp>
83 #include <com/sun/star/document/XTypeDetection.hpp>
84 #include <com/sun/star/document/XActionLockable.hpp>
85 #include <com/sun/star/io/XInputStream.hpp>
86 #include <com/sun/star/task/XInteractionHandler.hpp>
87 #include <com/sun/star/container/XNameAccess.hpp>
88 #include <com/sun/star/container/XContainerQuery.hpp>
89 #include <com/sun/star/container/XEnumeration.hpp>
90 #include <com/sun/star/document/MacroExecMode.hpp>
91 #include <com/sun/star/document/UpdateDocMode.hpp>
92 
93 //_______________________________________________
94 // includes of an other project
95 #include <vcl/window.hxx>
96 #include <vcl/wrkwin.hxx>
97 #include <vcl/syswin.hxx>
98 
99 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
100 #include <toolkit/unohlp.hxx>
101 #endif
102 #include <unotools/moduleoptions.hxx>
103 #include <svtools/sfxecode.hxx>
104 #include <unotools/processfactory.hxx>
105 #include <unotools/ucbhelper.hxx>
106 #include <comphelper/configurationhelper.hxx>
107 #include <rtl/ustrbuf.hxx>
108 #include <vcl/svapp.hxx>
109 
110 //_______________________________________________
111 // namespace
112 
113 namespace framework{
114 
115 // may there exist already a define .-(
116 #ifndef css
117 namespace css = ::com::sun::star;
118 #endif
119 
120 //_______________________________________________
121 // declarations
122 
123 class LoadEnvListener : private ThreadHelpBase
124                       , public ::cppu::WeakImplHelper2< css::frame::XLoadEventListener      ,
125                                                         css::frame::XDispatchResultListener >
126 {
127     private:
128 
129         void**   m_ppCheck ;
130         LoadEnv* m_pLoadEnv;
131 
132     public:
133 
134         //_______________________________________
135         LoadEnvListener(void*    pCheck  ,
136                         LoadEnv* pLoadEnv)
137         {
138             m_ppCheck  = &pCheck ;
139             m_pLoadEnv = pLoadEnv;
140         }
141 
142         //_______________________________________
143         // frame.XLoadEventListener
144         virtual void SAL_CALL loadFinished(const css::uno::Reference< css::frame::XFrameLoader >& xLoader)
145             throw(css::uno::RuntimeException);
146 
147         virtual void SAL_CALL loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >& xLoader)
148             throw(css::uno::RuntimeException);
149 
150         //_______________________________________
151         // frame.XDispatchResultListener
152         virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& aEvent)
153             throw(css::uno::RuntimeException);
154 
155         //_______________________________________
156         // lang.XEventListener
157         virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
158             throw(css::uno::RuntimeException);
159 };
160 
161 /*-----------------------------------------------
162     14.10.2003 13:43
163 -----------------------------------------------*/
164 LoadEnv::LoadEnv(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
165     throw(LoadEnvException, css::uno::RuntimeException)
166     : ThreadHelpBase(     )
167     , m_xSMGR       (xSMGR)
168     , m_pCheck      (this )
169 	, m_pQuietInteraction( 0 )
170 {
171 }
172 
173 /*-----------------------------------------------
174     14.10.2003 13:43
175 -----------------------------------------------*/
176 LoadEnv::~LoadEnv()
177 {
178     m_pCheck = 0;
179 }
180 
181 /*-----------------------------------------------
182     10.09.2003 14:05
183 -----------------------------------------------*/
184 css::uno::Reference< css::lang::XComponent > LoadEnv::loadComponentFromURL(const css::uno::Reference< css::frame::XComponentLoader >&    xLoader,
185                                                                            const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR  ,
186                                                                            const ::rtl::OUString&                                        sURL   ,
187                                                                            const ::rtl::OUString&                                        sTarget,
188                                                                                  sal_Int32                                               nFlags ,
189                                                                            const css::uno::Sequence< css::beans::PropertyValue >&        lArgs  )
190     throw(css::lang::IllegalArgumentException,
191           css::io::IOException               ,
192           css::uno::RuntimeException         )
193 {
194     css::uno::Reference< css::lang::XComponent > xComponent;
195 
196     try
197     {
198         LoadEnv aEnv(xSMGR);
199 
200         aEnv.initializeLoading(sURL,
201                                lArgs,
202                                css::uno::Reference< css::frame::XFrame >(xLoader, css::uno::UNO_QUERY),
203                                sTarget,
204                                nFlags,
205                                LoadEnv::E_NO_FEATURE);
206         aEnv.startLoading();
207         aEnv.waitWhileLoading(); // wait for ever!
208 
209         xComponent = aEnv.getTargetComponent();
210     }
211     catch(const LoadEnvException& ex)
212     {
213         switch(ex.m_nID)
214         {
215             case LoadEnvException::ID_INVALID_MEDIADESCRIPTOR:
216                     throw css::lang::IllegalArgumentException(
217                             ::rtl::OUString::createFromAscii("Optional list of arguments seem to be corrupted."),
218                             xLoader,
219                             4);
220 
221             case LoadEnvException::ID_UNSUPPORTED_CONTENT:
222                     throw css::lang::IllegalArgumentException(
223                             ::rtl::OUString::createFromAscii("URL seems to be an unsupported one."),
224                             xLoader,
225                             1);
226 
227 			default: xComponent.clear();
228                     break;
229         }
230     }
231 
232     return xComponent;
233 }
234 
235 //-----------------------------------------------
236 ::comphelper::MediaDescriptor impl_mergeMediaDescriptorWithMightExistingModelArgs(const css::uno::Sequence< css::beans::PropertyValue >& lOutsideDescriptor)
237 {
238     ::comphelper::MediaDescriptor lDescriptor(lOutsideDescriptor);
239     css::uno::Reference< css::frame::XModel > xModel     = lDescriptor.getUnpackedValueOrDefault(
240                                                             ::comphelper::MediaDescriptor::PROP_MODEL (),
241                                                             css::uno::Reference< css::frame::XModel > ());
242     if (xModel.is ())
243     {
244         ::comphelper::MediaDescriptor lModelDescriptor(xModel->getArgs());
245         ::comphelper::MediaDescriptor::iterator pIt = lModelDescriptor.find( ::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE() );
246 		if ( pIt != lModelDescriptor.end() )
247 			lDescriptor[::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()] = pIt->second;
248     }
249 
250     return lDescriptor;
251 }
252 
253 /*-----------------------------------------------
254     20.08.2003 09:49
255 -----------------------------------------------*/
256 void LoadEnv::initializeLoading(const ::rtl::OUString&                                           sURL            ,
257                                 const css::uno::Sequence< css::beans::PropertyValue >&           lMediaDescriptor,
258                                 const css::uno::Reference< css::frame::XFrame >&                 xBaseFrame      ,
259                                 const ::rtl::OUString&                                           sTarget         ,
260                                       sal_Int32                                                  nSearchFlags    ,
261                                       EFeature                                                   eFeature        , // => use default ...
262                                       EContentType                                               eContentType    ) // => use default ...
263     throw(LoadEnvException, css::uno::RuntimeException)
264 {
265     // SAFE -> ----------------------------------
266     WriteGuard aWriteLock(m_aLock);
267 
268     // Handle still running processes!
269     if (m_xAsynchronousJob.is())
270         throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
271 
272     // take over all new parameters.
273     m_xTargetFrame.clear();
274     m_xBaseFrame                    = xBaseFrame        ;
275     m_lMediaDescriptor              = impl_mergeMediaDescriptorWithMightExistingModelArgs(lMediaDescriptor);
276     m_sTarget                       = sTarget           ;
277     m_nSearchFlags                  = nSearchFlags      ;
278     m_eFeature                      = eFeature          ;
279     m_eContentType                  = eContentType      ;
280     m_bCloseFrameOnError            = sal_False         ;
281     m_bReactivateControllerOnError  = sal_False         ;
282     m_bLoaded                       = sal_False         ;
283 
284     // try to find out, if its realy a content, which can be loaded or must be "handled"
285     // We use a default value for this in-parameter. Then we have to start a complex check method
286     // internaly. But if this check was already done outside it can be supressed to perform
287     // the load request. We take over the result then!
288     if (m_eContentType == E_UNSUPPORTED_CONTENT)
289     {
290         m_eContentType = LoadEnv::classifyContent(sURL, lMediaDescriptor);
291         if (m_eContentType == E_UNSUPPORTED_CONTENT)
292             throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);
293     }
294 
295     // make URL part of the MediaDescriptor
296     // It doesnt mater, if its already an item of it.
297     // It must be the same value ... so we can overwrite it :-)
298     m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_URL()] <<= sURL;
299 
300     // parse it - because some following code require that
301     m_aURL.Complete = sURL;
302     css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY);
303     xParser->parseStrict(m_aURL);
304 
305     // BTW: Split URL and JumpMark ...
306     // Because such mark is an explicit value of the media descriptor!
307     if (m_aURL.Mark.getLength())
308         m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_JUMPMARK()] <<= m_aURL.Mark;
309 
310     // By the way: remove the old and deprecated value "FileName" from the descriptor!
311     ::comphelper::MediaDescriptor::iterator pIt = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_FILENAME());
312     if (pIt != m_lMediaDescriptor.end())
313         m_lMediaDescriptor.erase(pIt);
314 
315     // patch the MediaDescriptor, so it fullfill the outside requirements
316     // Means especialy items like e.g. UI InteractionHandler, Status Indicator,
317     // MacroExecutionMode etcpp.
318 
319     /*TODO progress is bound to a frame ... How can we set it here? */
320 
321     // UI mode
322     const bool bUIMode =
323         ( ( m_eFeature & E_WORK_WITH_UI )                                                                          == E_WORK_WITH_UI ) &&
324         ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False ) == sal_False      ) &&
325         ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_PREVIEW(), sal_False ) == sal_False      );
326 
327     initializeUIDefaults(
328         m_xSMGR,
329         m_lMediaDescriptor,
330         bUIMode,
331         &m_pQuietInteraction
332     );
333 
334     aWriteLock.unlock();
335     // <- SAFE ----------------------------------
336 }
337 
338 /*-----------------------------------------------
339     22.01.2010
340 -----------------------------------------------*/
341 void LoadEnv::initializeUIDefaults( const css::uno::Reference< css::lang::XMultiServiceFactory >& i_rSMGR,
342                                     ::comphelper::MediaDescriptor& io_lMediaDescriptor, const bool i_bUIMode,
343                                     QuietInteraction** o_ppQuietInteraction )
344 {
345     css::uno::Reference< css::task::XInteractionHandler > xInteractionHandler;
346     sal_Int16                                             nMacroMode         ;
347     sal_Int16                                             nUpdateMode        ;
348 
349     if ( i_bUIMode )
350     {
351         nMacroMode  = css::document::MacroExecMode::USE_CONFIG;
352         nUpdateMode = css::document::UpdateDocMode::ACCORDING_TO_CONFIG;
353         try
354         {
355             xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(i_rSMGR->createInstance(IMPLEMENTATIONNAME_UIINTERACTIONHANDLER), css::uno::UNO_QUERY);
356         }
357         catch(const css::uno::RuntimeException&) {throw;}
358         catch(const css::uno::Exception&       ) {      }
359     }
360     // hidden mode
361     else
362     {
363         nMacroMode  = css::document::MacroExecMode::NEVER_EXECUTE;
364         nUpdateMode = css::document::UpdateDocMode::NO_UPDATE;
365         QuietInteraction* pQuietInteraction = new QuietInteraction();
366         xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(static_cast< css::task::XInteractionHandler* >(pQuietInteraction), css::uno::UNO_QUERY);
367         if ( o_ppQuietInteraction != NULL )
368         {
369             *o_ppQuietInteraction = pQuietInteraction;
370             (*o_ppQuietInteraction)->acquire();
371         }
372     }
373 
374     if (
375         (xInteractionHandler.is()                                                                                       ) &&
376         (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()) == io_lMediaDescriptor.end())
377        )
378     {
379         io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()] <<= xInteractionHandler;
380     }
381 
382     if (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()) == io_lMediaDescriptor.end())
383         io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()] <<= nMacroMode;
384 
385     if (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_UPDATEDOCMODE()) == io_lMediaDescriptor.end())
386         io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_UPDATEDOCMODE()] <<= nUpdateMode;
387 }
388 
389 /*-----------------------------------------------
390     15.08.2003 08:16
391 -----------------------------------------------*/
392 void LoadEnv::startLoading()
393     throw(LoadEnvException, css::uno::RuntimeException)
394 {
395     // SAFE ->
396     ReadGuard aReadLock(m_aLock);
397 
398     // Handle still running processes!
399     if (m_xAsynchronousJob.is())
400         throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
401 
402     // content can not be loaded or handled
403     // check "classifyContent()" failed before ...
404     if (m_eContentType == E_UNSUPPORTED_CONTENT)
405         throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);
406 
407     // <- SAFE
408     aReadLock.unlock();
409 
410     // detect its type/filter etcpp.
411     // These information will be available by the
412     // used descriptor member afterwards and is needed
413     // for all following operations!
414     // Note: An exception will be thrown, in case operation was not successfully ...
415     if (m_eContentType != E_CAN_BE_SET)/* Attention: special feature to set existing component on a frame must ignore type detection! */
416         impl_detectTypeAndFilter();
417 
418     // start loading the content ...
419     // Attention: Dont check m_eContentType deeper then UNSUPPORTED/SUPPORTED!
420     // Because it was made in th easiest way ... may a flat detection was made only.
421     // And such simple detection can fail some times .-)
422     // Use another strategy here. Try it and let it run into the case "loading not possible".
423     sal_Bool bStarted = sal_False;
424     if (
425         ((m_eFeature & E_ALLOW_CONTENTHANDLER) == E_ALLOW_CONTENTHANDLER) &&
426         (m_eContentType                        != E_CAN_BE_SET          )   /* Attention: special feature to set existing component on a frame must ignore type detection! */
427        )
428     {
429         bStarted = impl_handleContent();
430     }
431 
432     if (!bStarted)
433         bStarted = impl_loadContent();
434 
435     // not started => general error
436     // We cant say - what was the reason for.
437     if (!bStarted)
438         throw LoadEnvException(LoadEnvException::ID_GENERAL_ERROR);
439 }
440 
441 /*-----------------------------------------------
442     15.08.2003 09:50
443     TODO
444         First draft does not implement timeout using [ms].
445         Current implementation counts yield calls only ...
446 -----------------------------------------------*/
447 sal_Bool LoadEnv::waitWhileLoading(sal_uInt32 nTimeout)
448     throw(LoadEnvException, css::uno::RuntimeException)
449 {
450     // Because its not a good idea to block the main thread
451     // (and we cant be shure that we are currently not used inside the
452     // main thread!), we cant use conditions here realy. We must yield
453     // in an intellegent manner :-)
454 
455     sal_Int32 nTime = nTimeout;
456     while(true)
457     {
458         // SAFE -> ------------------------------
459         ReadGuard aReadLock1(m_aLock);
460         if (!m_xAsynchronousJob.is())
461             break;
462         aReadLock1.unlock();
463         // <- SAFE ------------------------------
464 
465         Application::Yield();
466 
467         // forever!
468         if (nTimeout==0)
469             continue;
470 
471         // timed out?
472         --nTime;
473         if (nTime<1)
474             break;
475     }
476 
477     // SAFE -> ----------------------------------
478     ReadGuard aReadLock2(m_aLock);
479     return !m_xAsynchronousJob.is();
480     // <- SAFE ----------------------------------
481 }
482 
483 /*-----------------------------------------------
484     20.08.2003 10:00
485 -----------------------------------------------*/
486 void LoadEnv::cancelLoading()
487     throw(LoadEnvException, css::uno::RuntimeException)
488 {
489     // PARTIAL(!) SAFE -> ------------------------------
490     ReadGuard aReadLock(m_aLock);
491 
492     // Still running? Might waitWhileLoading()
493     // runned into the timeout!
494     if (m_xAsynchronousJob.is())
495     {
496         // try to cancel it ... if its an asynchronous frame loader
497         css::uno::Reference< css::frame::XFrameLoader > xAsyncLoader(m_xAsynchronousJob, css::uno::UNO_QUERY);
498         if (xAsyncLoader.is())
499         {
500             aReadLock.unlock();
501             // <- BREAK SAFE ------------------------------
502             xAsyncLoader->cancel();
503             // <- RESTART SAFE ----------------------------
504             aReadLock.lock();
505             /* Attention:
506                 After returning from any cancel/dispose call, neither the frame nor weself
507                 may be called back. Because only we can cancel this job, we already know
508                 the result! => Thats why its not usefull nor neccessary to wait for any
509                 asynchronous listener notification.
510             */
511             m_bLoaded = sal_False;
512             m_xAsynchronousJob.clear();
513         }
514         // or may be its a content handler? Such handler cant be cancelled in its running
515         // operation :-( And we cant deregister us there again :-(
516         // => The only chance is an exception :-)
517         else
518             throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
519     }
520 
521     impl_reactForLoadingState();
522 
523     aReadLock.unlock();
524     // <- PARTIAL(!) SAFE ------------------------------
525 }
526 
527 /*-----------------------------------------------
528     14.08.2003 13:33
529 -----------------------------------------------*/
530 css::uno::Reference< css::frame::XFrame > LoadEnv::getTarget() const
531 {
532     // SAFE ->
533     ReadGuard aReadLock(m_aLock);
534     return m_xTargetFrame;
535     // <- SAFE
536 }
537 
538 /*-----------------------------------------------
539     14.08.2003 13:35
540 -----------------------------------------------*/
541 css::uno::Reference< css::lang::XComponent > LoadEnv::getTargetComponent() const
542 {
543     // SAFE ->
544     ReadGuard aReadLock(m_aLock);
545 
546     if (!m_xTargetFrame.is())
547         return css::uno::Reference< css::lang::XComponent >();
548 
549     css::uno::Reference< css::frame::XController > xController = m_xTargetFrame->getController();
550     if (!xController.is())
551         return css::uno::Reference< css::lang::XComponent >(m_xTargetFrame->getComponentWindow(), css::uno::UNO_QUERY);
552 
553     css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
554     if (!xModel.is())
555         return css::uno::Reference< css::lang::XComponent >(xController, css::uno::UNO_QUERY);
556 
557     return css::uno::Reference< css::lang::XComponent >(xModel, css::uno::UNO_QUERY);
558     // <- SAFE
559 }
560 
561 /*-----------------------------------------------
562     15.08.2003 11:15
563 -----------------------------------------------*/
564 void SAL_CALL LoadEnvListener::loadFinished(const css::uno::Reference< css::frame::XFrameLoader >&)
565     throw(css::uno::RuntimeException)
566 {
567     // SAFE -> ----------------------------------
568     WriteGuard aWriteLock(m_aLock);
569 
570     if (m_ppCheck && *m_ppCheck)
571         m_pLoadEnv->impl_setResult(sal_True);
572     m_ppCheck = NULL;
573 
574     aWriteLock.unlock();
575     // <- SAFE ----------------------------------
576 }
577 
578 /*-----------------------------------------------
579     14.10.2003 12:23
580 -----------------------------------------------*/
581 void SAL_CALL LoadEnvListener::loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >&)
582     throw(css::uno::RuntimeException)
583 {
584     // SAFE -> ----------------------------------
585     WriteGuard aWriteLock(m_aLock);
586 
587     if (m_ppCheck && *m_ppCheck)
588         m_pLoadEnv->impl_setResult(sal_False);
589     m_ppCheck = NULL;
590 
591     aWriteLock.unlock();
592     // <- SAFE ----------------------------------
593 }
594 
595 /*-----------------------------------------------
596     14.10.2003 12:23
597 -----------------------------------------------*/
598 void SAL_CALL LoadEnvListener::dispatchFinished(const css::frame::DispatchResultEvent& aEvent)
599     throw(css::uno::RuntimeException)
600 {
601     // SAFE -> ----------------------------------
602     WriteGuard aWriteLock(m_aLock);
603 
604     if (!m_ppCheck || !*m_ppCheck)
605         return;
606 
607     switch(aEvent.State)
608     {
609         case css::frame::DispatchResultState::FAILURE :
610             m_pLoadEnv->impl_setResult(sal_False);
611             break;
612 
613         case css::frame::DispatchResultState::SUCCESS :
614             m_pLoadEnv->impl_setResult(sal_False);
615             break;
616 
617         case css::frame::DispatchResultState::DONTKNOW :
618             m_pLoadEnv->impl_setResult(sal_False);
619             break;
620     }
621     m_ppCheck = NULL;
622 
623     aWriteLock.unlock();
624     // <- SAFE ----------------------------------
625 }
626 
627 /*-----------------------------------------------
628     14.10.2003 12:24
629 -----------------------------------------------*/
630 void SAL_CALL LoadEnvListener::disposing(const css::lang::EventObject&)
631     throw(css::uno::RuntimeException)
632 {
633     // SAFE -> ----------------------------------
634     WriteGuard aWriteLock(m_aLock);
635 
636     if (m_ppCheck && *m_ppCheck)
637         m_pLoadEnv->impl_setResult(sal_False);
638     m_ppCheck = NULL;
639 
640     aWriteLock.unlock();
641     // <- SAFE ----------------------------------
642 }
643 
644 /*-----------------------------------------------
645     14.10.2003 12:20
646 -----------------------------------------------*/
647 void LoadEnv::impl_setResult(sal_Bool bResult)
648 {
649     // SAFE -> ----------------------------------
650     WriteGuard aWriteLock(m_aLock);
651 
652     m_bLoaded = bResult;
653 
654     impl_reactForLoadingState();
655 
656     // clearing of this reference will unblock waitWhileLoading()!
657     // So we must be shure, that loading process was realy finished.
658     // => do it as last operation of this method ...
659     m_xAsynchronousJob.clear();
660 
661     aWriteLock.unlock();
662     // <- SAFE ----------------------------------
663 }
664 
665 /*-----------------------------------------------
666     06.02.2004 14:03
667     TODO: Is it a good idea to change Sequence<>
668           parameter to stl-adapter?
669 -----------------------------------------------*/
670 LoadEnv::EContentType LoadEnv::classifyContent(const ::rtl::OUString&                                 sURL            ,
671                                                const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor)
672 {
673     //-------------------------------------------
674     // (i) Filter some special well known URL protocols,
675     //     which can not be handled or loaded in general.
676     //     Of course an empty URL must be ignored here too.
677     //     Note: These URL schemata are fix and well known ...
678     //     But there can be some additional ones, which was not
679     //     defined at implementation time of this class :-(
680     //     So we have to make shure, that the following code
681     //     can detect such protocol schemata too :-)
682 
683     if(
684         (!sURL.getLength()                                       ) ||
685         (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_UNO    )) ||
686         (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SLOT   )) ||
687         (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MACRO  )) ||
688         (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SERVICE)) ||
689         (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MAILTO )) ||
690         (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_NEWS   ))
691       )
692     {
693         return E_UNSUPPORTED_CONTENT;
694     }
695 
696     //-------------------------------------------
697     // (ii) Some special URLs indicates a given input stream,
698     //      a full featured document model directly or
699     //      specify a request for opening an empty document.
700     //      Such contents are loadable in general.
701     //      But we have to check, if the media descriptor contains
702     //      all needed resources. If they are missing - the following
703     //      load request will fail.
704 
705     /* Attention: The following code cant work on such special URLs!
706                   It should not break the office .. but it make no sense
707                   to start expensive object creations and complex search
708                   algorithm if its clear, that such URLs must be handled
709                   in a special way .-)
710     */
711 
712     // creation of new documents
713     if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_FACTORY))
714         return E_CAN_BE_LOADED;
715 
716     // using of an existing input stream
717     ::comphelper::MediaDescriptor                 stlMediaDescriptor(lMediaDescriptor);
718     ::comphelper::MediaDescriptor::const_iterator pIt;
719     if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_STREAM))
720     {
721         pIt = stlMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_INPUTSTREAM());
722         css::uno::Reference< css::io::XInputStream > xStream;
723         if (pIt != stlMediaDescriptor.end())
724             pIt->second >>= xStream;
725         if (xStream.is())
726             return E_CAN_BE_LOADED;
727         LOG_WARNING("LoadEnv::classifyContent()", "loading from stream with right URL but invalid stream detected")
728         return E_UNSUPPORTED_CONTENT;
729     }
730 
731     // using of a full featured document
732     if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_OBJECT))
733     {
734         pIt = stlMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_MODEL());
735         css::uno::Reference< css::frame::XModel > xModel;
736         if (pIt != stlMediaDescriptor.end())
737             pIt->second >>= xModel;
738         if (xModel.is())
739             return E_CAN_BE_SET;
740         LOG_WARNING("LoadEnv::classifyContent()", "loading with object with right URL but invalid object detected")
741         return E_UNSUPPORTED_CONTENT;
742     }
743 
744     // following operatons can work on an internal type name only :-(
745     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::utl::getProcessServiceFactory();
746     css::uno::Reference< css::document::XTypeDetection > xDetect(xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY);
747 
748     ::rtl::OUString sType = xDetect->queryTypeByURL(sURL);
749 
750     css::uno::Sequence< css::beans::NamedValue >           lQuery(1)   ;
751     css::uno::Reference< css::container::XContainerQuery > xContainer  ;
752     css::uno::Reference< css::container::XEnumeration >    xSet        ;
753     css::uno::Sequence< ::rtl::OUString >                  lTypesReg(1);
754 
755     /*
756     //-------------------------------------------
757     lQuery[0].Name    = ::framework::constant::Filter::PROP_TYPE;
758     lQuery[0].Value <<= sType;
759 
760     xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_FILTERFACTORY), css::uno::UNO_QUERY);
761     xSet       = xContainer->createSubSetEnumerationByProperties(lQuery);
762     // at least one registered frame loader is enough!
763     if (xSet->hasMoreElements())
764         return E_CAN_BE_LOADED;
765     */
766 
767     //-------------------------------------------
768     // (iii) If a FrameLoader service (or at least
769     //      a Filter) can be found, which supports
770     //      this URL - it must be a loadable content.
771     //      Because both items are registered for types
772     //      its enough to check for frame loaders only.
773     //      Mos of our filters are handled by our global
774     //      default loader. But there exist some specialized
775     //      loader, which does not work on top of filters!
776     //      So its not enough to search on the filter configuration.
777     //      Further its not enough to search for types!
778     //      Because there exist some types, which are referenced by
779     //      other objects ... but not by filters nor frame loaders!
780 
781     lTypesReg[0]      = sType;
782     lQuery[0].Name    = ::framework::constant::FrameLoader::PROP_TYPES;
783     lQuery[0].Value <<= lTypesReg;
784 
785     xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_FRAMELOADERFACTORY), css::uno::UNO_QUERY);
786     xSet       = xContainer->createSubSetEnumerationByProperties(lQuery);
787     // at least one registered frame loader is enough!
788     if (xSet->hasMoreElements())
789         return E_CAN_BE_LOADED;
790 
791     //-------------------------------------------
792     // (iv) Some URL protocols are supported by special services.
793     //      E.g. ContentHandler.
794     //      Such contents can be handled ... but not loaded.
795 
796     lTypesReg[0]      = sType;
797     lQuery[0].Name    = ::framework::constant::ContentHandler::PROP_TYPES;
798     lQuery[0].Value <<= lTypesReg;
799 
800     xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_CONTENTHANDLERFACTORY), css::uno::UNO_QUERY);
801     xSet       = xContainer->createSubSetEnumerationByProperties(lQuery);
802     // at least one registered content handler is enough!
803     if (xSet->hasMoreElements())
804         return E_CAN_BE_HANDLED;
805 
806     //-------------------------------------------
807     // (v) Last but not least the UCB is used inside office to
808     //     load contents. He has a special configuration to know
809     //     which URL schemata can be used inside office.
810     css::uno::Reference< css::ucb::XContentProviderManager > xUCB(xSMGR->createInstance(SERVICENAME_UCBCONTENTBROKER), css::uno::UNO_QUERY);
811     if (xUCB->queryContentProvider(sURL).is())
812         return E_CAN_BE_LOADED;
813 
814     //-------------------------------------------
815     // (TODO) At this point, we have no idea .-)
816     //        But it seems to be better, to break all
817     //        further requests for this URL. Otherwhise
818     //        we can run into some trouble.
819     LOG_WARNING("LoadEnv::classifyContent()", "realy an unsupported content?")
820     return E_UNSUPPORTED_CONTENT;
821 }
822 
823 /*-----------------------------------------------
824     03.11.2003 09:31
825 -----------------------------------------------*/
826 void LoadEnv::impl_detectTypeAndFilter()
827     throw(LoadEnvException, css::uno::RuntimeException)
828 {
829     static ::rtl::OUString TYPEPROP_PREFERREDFILTER = ::rtl::OUString::createFromAscii("PreferredFilter");
830     static ::rtl::OUString FILTERPROP_FLAGS         = ::rtl::OUString::createFromAscii("Flags"          );
831     static sal_Int32       FILTERFLAG_TEMPLATEPATH  = 16;
832 
833     // SAFE ->
834     ReadGuard aReadLock(m_aLock);
835 
836     // Attention: Because our stl media descriptor is a copy of an uno sequence
837     // we cant use as an in/out parameter here. Copy it before and dont forget to
838     // update structure afterwards again!
839     css::uno::Sequence< css::beans::PropertyValue >        lDescriptor = m_lMediaDescriptor.getAsConstPropertyValueList();
840     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR       = m_xSMGR;
841 
842     aReadLock.unlock();
843     // <- SAFE
844 
845     ::rtl::OUString sType;
846     css::uno::Reference< css::document::XTypeDetection > xDetect(xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY);
847     if (xDetect.is())
848         sType = xDetect->queryTypeByDescriptor(lDescriptor, sal_True); /*TODO should deep detection be able for enable/disable it from outside? */
849 
850     // no valid content -> loading not possible
851     if (!sType.getLength())
852         throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);
853 
854     // SAFE ->
855     WriteGuard aWriteLock(m_aLock);
856 
857     // detection was successfully => update the descriptor member of this class
858     m_lMediaDescriptor << lDescriptor;
859     m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()] <<= sType;
860     // Is there an already detected (may be preselected) filter?
861     // see below ...
862     ::rtl::OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_FILTERNAME(), ::rtl::OUString());
863 
864     aWriteLock.unlock();
865     // <- SAFE
866 
867     // But the type isnt enough. For loading sometimes we need more informations.
868     // E.g. for our "_default" feature, where we recylce any frame which contains
869     // and "Untitled" document, we must know if the new document is based on a template!
870     // But this information is available as a filter property only.
871     // => We must try(!) to detect the right filter for this load request.
872     // On the other side ... if no filter is available .. ignore it.
873     // Then the type information must be enough.
874     if (!sFilter.getLength())
875     {
876         // no -> try to find a preferred filter for the detected type.
877         // Dont forget to updatet he media descriptor.
878         css::uno::Reference< css::container::XNameAccess > xTypeCont(xDetect, css::uno::UNO_QUERY_THROW);
879         try
880         {
881             ::comphelper::SequenceAsHashMap lTypeProps(xTypeCont->getByName(sType));
882             sFilter = lTypeProps.getUnpackedValueOrDefault(TYPEPROP_PREFERREDFILTER, ::rtl::OUString());
883             if (sFilter.getLength())
884             {
885                 // SAFE ->
886                 aWriteLock.lock();
887                 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter;
888                 aWriteLock.unlock();
889                 // <- SAFE
890             }
891         }
892         catch(const css::container::NoSuchElementException&)
893             {}
894     }
895 
896     // check if the filter (if one exists) points to a template format filter.
897     // Then we have to add the property "AsTemplate".
898     // We need this information to decide afterwards if we can use a "recycle frame"
899     // for target "_default" or has to create a new one everytimes.
900     // On the other side we have to supress that, if this property already exists
901     // and should trigger a special handling. Then the outside calli of this method here,
902     // has to know, what he is doing .-)
903 
904     sal_Bool bIsOwnTemplate = sal_False;
905     if (sFilter.getLength())
906     {
907         css::uno::Reference< css::container::XNameAccess > xFilterCont(xSMGR->createInstance(SERVICENAME_FILTERFACTORY), css::uno::UNO_QUERY_THROW);
908         try
909         {
910             ::comphelper::SequenceAsHashMap lFilterProps(xFilterCont->getByName(sFilter));
911             sal_Int32 nFlags         = lFilterProps.getUnpackedValueOrDefault(FILTERPROP_FLAGS, (sal_Int32)0);
912                       bIsOwnTemplate = ((nFlags & FILTERFLAG_TEMPLATEPATH) == FILTERFLAG_TEMPLATEPATH);
913         }
914         catch(const css::container::NoSuchElementException&)
915             {}
916     }
917     if (bIsOwnTemplate)
918     {
919         // SAFE ->
920         aWriteLock.lock();
921         // Dont overwrite external decisions! See comments before ...
922         ::comphelper::MediaDescriptor::const_iterator pAsTemplateItem = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_ASTEMPLATE());
923         if (pAsTemplateItem == m_lMediaDescriptor.end())
924             m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_ASTEMPLATE()] <<= sal_True;
925         aWriteLock.unlock();
926         // <- SAFE
927     }
928 }
929 
930 /*-----------------------------------------------
931     15.08.2003 09:38
932 -----------------------------------------------*/
933 sal_Bool LoadEnv::impl_handleContent()
934     throw(LoadEnvException, css::uno::RuntimeException)
935 {
936     // SAFE -> -----------------------------------
937     ReadGuard aReadLock(m_aLock);
938 
939     // the type must exist inside the descriptor ... otherwhise this class is implemented wrong :-)
940     ::rtl::OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), ::rtl::OUString());
941     if (!sType.getLength())
942         throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR);
943 
944     // convert media descriptor and URL to right format for later interface call!
945     css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
946     m_lMediaDescriptor >> lDescriptor;
947     css::util::URL aURL = m_aURL;
948 
949     // get neccessary container to query for a handler object
950     css::uno::Reference< css::lang::XMultiServiceFactory > xFactory(m_xSMGR->createInstance(SERVICENAME_CONTENTHANDLERFACTORY), css::uno::UNO_QUERY);
951     css::uno::Reference< css::container::XContainerQuery > xQuery  (xFactory                                                  , css::uno::UNO_QUERY);
952 
953     aReadLock.unlock();
954     // <- SAFE -----------------------------------
955 
956     // query
957     css::uno::Sequence< ::rtl::OUString > lTypeReg(1);
958     lTypeReg[0] = sType;
959 
960     css::uno::Sequence< css::beans::NamedValue > lQuery(1);
961     lQuery[0].Name    = ::framework::constant::ContentHandler::PROP_TYPES;
962     lQuery[0].Value <<= lTypeReg;
963 
964     css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery);
965     while(xSet->hasMoreElements())
966     {
967         ::comphelper::SequenceAsHashMap lProps   (xSet->nextElement());
968         ::rtl::OUString                 sHandler = lProps.getUnpackedValueOrDefault(::framework::constant::ContentHandler::PROP_NAME, ::rtl::OUString());
969 
970         css::uno::Reference< css::frame::XNotifyingDispatch > xHandler;
971         try
972         {
973             xHandler = css::uno::Reference< css::frame::XNotifyingDispatch >(xFactory->createInstance(sHandler), css::uno::UNO_QUERY);
974             if (!xHandler.is())
975                 continue;
976         }
977         catch(const css::uno::RuntimeException&)
978             { throw; }
979         catch(const css::uno::Exception&)
980             { continue; }
981 
982         // SAFE -> -----------------------------------
983         WriteGuard aWriteLock(m_aLock);
984         m_xAsynchronousJob = xHandler;
985         m_pCheck           = this;
986         LoadEnvListener* pListener = new LoadEnvListener(m_pCheck, this);
987         aWriteLock.unlock();
988         // <- SAFE -----------------------------------
989 
990         css::uno::Reference< css::frame::XDispatchResultListener > xListener(static_cast< css::frame::XDispatchResultListener* >(pListener), css::uno::UNO_QUERY);
991         xHandler->dispatchWithNotification(aURL, lDescriptor, xListener);
992 
993         return sal_True;
994     }
995 
996     return sal_False;
997 }
998 
999 //-----------------------------------------------
1000 sal_Bool LoadEnv::impl_furtherDocsAllowed()
1001 {
1002     // SAFE ->
1003     ReadGuard aReadLock(m_aLock);
1004     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1005     aReadLock.unlock();
1006     // <- SAFE
1007 
1008     sal_Bool bAllowed = sal_True;
1009 
1010     try
1011     {
1012         css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
1013                                 xSMGR,
1014                                 ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/"),
1015                                 ::rtl::OUString::createFromAscii("Misc"),
1016                                 ::rtl::OUString::createFromAscii("MaxOpenDocuments"),
1017                                 ::comphelper::ConfigurationHelper::E_READONLY);
1018 
1019         // NIL means: count of allowed documents = infinite !
1020         //     => return sal_True
1021         if ( ! aVal.hasValue())
1022             bAllowed = sal_True;
1023         else
1024         {
1025             sal_Int32 nMaxOpenDocuments = 0;
1026             aVal >>= nMaxOpenDocuments;
1027 
1028             css::uno::Reference< css::frame::XFramesSupplier > xDesktop(
1029                 xSMGR->createInstance(SERVICENAME_DESKTOP),
1030                 css::uno::UNO_QUERY_THROW);
1031 
1032             FrameListAnalyzer aAnalyzer(xDesktop,
1033                                         css::uno::Reference< css::frame::XFrame >(),
1034                                         FrameListAnalyzer::E_HELP |
1035                                         FrameListAnalyzer::E_BACKINGCOMPONENT |
1036                                         FrameListAnalyzer::E_HIDDEN);
1037 
1038             sal_Int32 nOpenDocuments = aAnalyzer.m_lOtherVisibleFrames.getLength();
1039                       bAllowed       = (nOpenDocuments < nMaxOpenDocuments);
1040         }
1041     }
1042     catch(const css::uno::Exception&)
1043         { bAllowed = sal_True; } // !! internal errors are no reason to disturb the office from opening documents .-)
1044 
1045     if ( ! bAllowed )
1046     {
1047         // SAFE ->
1048         aReadLock.lock();
1049         css::uno::Reference< css::task::XInteractionHandler > xInteraction = m_lMediaDescriptor.getUnpackedValueOrDefault(
1050                                                                                 ::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER(),
1051                                                                                 css::uno::Reference< css::task::XInteractionHandler >());
1052         aReadLock.unlock();
1053         // <- SAFE
1054 
1055         if (xInteraction.is())
1056         {
1057             css::uno::Any                                                                    aInteraction;
1058             css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations(2);
1059 
1060             comphelper::OInteractionAbort*   pAbort   = new comphelper::OInteractionAbort();
1061             comphelper::OInteractionApprove* pApprove = new comphelper::OInteractionApprove();
1062 
1063             lContinuations[0] = css::uno::Reference< css::task::XInteractionContinuation >(
1064                                     static_cast< css::task::XInteractionContinuation* >(pAbort),
1065                                     css::uno::UNO_QUERY_THROW);
1066             lContinuations[1] = css::uno::Reference< css::task::XInteractionContinuation >(
1067                                     static_cast< css::task::XInteractionContinuation* >(pApprove),
1068                                     css::uno::UNO_QUERY_THROW);
1069 
1070             css::task::ErrorCodeRequest aErrorCode;
1071             aErrorCode.ErrCode = ERRCODE_SFX_NOMOREDOCUMENTSALLOWED;
1072             aInteraction <<= aErrorCode;
1073             xInteraction->handle( InteractionRequest::CreateRequest(aInteraction, lContinuations) );
1074         }
1075     }
1076 
1077     return bAllowed;
1078 }
1079 
1080 //-----------------------------------------------
1081 sal_Bool LoadEnv::impl_loadContent()
1082     throw(LoadEnvException, css::uno::RuntimeException)
1083 {
1084     // SAFE -> -----------------------------------
1085     WriteGuard aWriteLock(m_aLock);
1086 
1087     // search or create right target frame
1088     ::rtl::OUString sTarget = m_sTarget;
1089     if (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_DEFAULT))
1090     {
1091         m_xTargetFrame = impl_searchAlreadyLoaded();
1092         if (m_xTargetFrame.is())
1093 		{
1094 			impl_setResult(sal_True);
1095 			return sal_True;
1096 		}
1097         m_xTargetFrame = impl_searchRecycleTarget();
1098     }
1099 
1100     if (! m_xTargetFrame.is())
1101     {
1102         if (
1103             (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_BLANK  )) ||
1104             (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_DEFAULT))
1105            )
1106         {
1107             if (! impl_furtherDocsAllowed())
1108                 return sal_False;
1109             m_xTargetFrame       = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0);
1110             m_bCloseFrameOnError = m_xTargetFrame.is();
1111         }
1112         else
1113         {
1114             sal_Int32 nFlags = m_nSearchFlags & ~css::frame::FrameSearchFlag::CREATE;
1115             m_xTargetFrame   = m_xBaseFrame->findFrame(sTarget, nFlags);
1116             if (! m_xTargetFrame.is())
1117             {
1118                 if (! impl_furtherDocsAllowed())
1119                     return sal_False;
1120                 m_xTargetFrame       = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0);
1121                 m_bCloseFrameOnError = m_xTargetFrame.is();
1122             }
1123         }
1124     }
1125 
1126     // If we couldn't find a valid frame or the frame has no container window
1127     // we have to throw an exception.
1128     if (
1129         ( ! m_xTargetFrame.is()                       ) ||
1130         ( ! m_xTargetFrame->getContainerWindow().is() )
1131        )
1132         throw LoadEnvException(LoadEnvException::ID_NO_TARGET_FOUND);
1133 
1134     css::uno::Reference< css::frame::XFrame > xTargetFrame = m_xTargetFrame;
1135 
1136     // Now we have a valid frame ... and type detection was already done.
1137     // We should apply the module dependend window position and size to the
1138     // frame window.
1139     impl_applyPersistentWindowState(xTargetFrame->getContainerWindow());
1140 
1141     // Don't forget to lock task for following load process. Otherwise it could die
1142     // during this operation runs by terminating the office or closing this task via api.
1143     // If we set this lock "close()" will return false and closing will be broken.
1144     // Attention: Don't forget to reset this lock again after finishing operation.
1145     // Otherwise task AND office couldn't die!!!
1146     // This includes gracefully handling of Exceptions (Runtime!) too ...
1147     // Thats why we use a specialized guard, which will reset the lock
1148     // if it will be run out of scope.
1149 
1150     // Note further: ignore if this internal guard already contains a resource.
1151     // Might impl_searchRecylcTarget() set it before. But incase this impl-method wasnt used
1152     // and the target frame was new created ... this lock here must be set!
1153     css::uno::Reference< css::document::XActionLockable > xTargetLock(xTargetFrame, css::uno::UNO_QUERY);
1154     m_aTargetLock.setResource(xTargetLock);
1155 
1156     // Add status indicator to descriptor. Loader can show an progresses then.
1157     // But don't do it, if loading should be hidden or preview is used ...!
1158     // So we prevent our code against wrong using. Why?
1159     // It could be, that using of this progress could make trouble. e.g. He make window visible ...
1160     // but shouldn't do that. But if no indicator is available ... nobody has a chance to do that!
1161     sal_Bool                                           bHidden    = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN()         , sal_False                                           );
1162     sal_Bool                                           bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_MINIMIZED()      , sal_False                                           );
1163     sal_Bool                                           bPreview   = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_PREVIEW()        , sal_False                                           );
1164     css::uno::Reference< css::task::XStatusIndicator > xProgress  = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_STATUSINDICATOR(), css::uno::Reference< css::task::XStatusIndicator >());
1165 
1166     if (!bHidden && !bMinimized && !bPreview && !xProgress.is())
1167     {
1168         // Note: its an optional interface!
1169         css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xTargetFrame, css::uno::UNO_QUERY);
1170         if (xProgressFactory.is())
1171         {
1172             xProgress = xProgressFactory->createStatusIndicator();
1173             if (xProgress.is())
1174                 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_STATUSINDICATOR()] <<= xProgress;
1175         }
1176     }
1177 
1178     // convert media descriptor and URL to right format for later interface call!
1179     css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
1180     m_lMediaDescriptor >> lDescriptor;
1181     ::rtl::OUString sURL = m_aURL.Complete;
1182 
1183     // try to locate any interested frame loader
1184     css::uno::Reference< css::uno::XInterface >                xLoader     = impl_searchLoader();
1185     css::uno::Reference< css::frame::XFrameLoader >            xAsyncLoader(xLoader, css::uno::UNO_QUERY);
1186     css::uno::Reference< css::frame::XSynchronousFrameLoader > xSyncLoader (xLoader, css::uno::UNO_QUERY);
1187 
1188     if (xAsyncLoader.is())
1189     {
1190         // SAFE -> -----------------------------------
1191         aWriteLock.lock();
1192         m_xAsynchronousJob = xAsyncLoader;
1193         m_pCheck           = this;
1194         LoadEnvListener* pListener = new LoadEnvListener(m_pCheck, this);
1195         aWriteLock.unlock();
1196         // <- SAFE -----------------------------------
1197 
1198         css::uno::Reference< css::frame::XLoadEventListener > xListener(static_cast< css::frame::XLoadEventListener* >(pListener), css::uno::UNO_QUERY);
1199         xAsyncLoader->load(xTargetFrame, sURL, lDescriptor, xListener);
1200 
1201         return sal_True;
1202     }
1203     else
1204     if (xSyncLoader.is())
1205     {
1206         sal_Bool bResult = xSyncLoader->load(lDescriptor, xTargetFrame);
1207         // react for the result here, so the outside waiting
1208         // code can ask for it later.
1209         impl_setResult(bResult);
1210         // But the return value indicates a valid started(!) operation.
1211         // And thats true everxtimes, we reach this line :-)
1212         return sal_True;
1213     }
1214 
1215     aWriteLock.unlock();
1216     // <- SAFE
1217 
1218     return sal_False;
1219 }
1220 
1221 /*-----------------------------------------------
1222     06.02.2004 14:40
1223 -----------------------------------------------*/
1224 css::uno::Reference< css::uno::XInterface > LoadEnv::impl_searchLoader()
1225 {
1226     // SAFE -> -----------------------------------
1227     ReadGuard aReadLock(m_aLock);
1228 
1229     // special mode to set an existing component on this frame
1230     // In such case the laoder is fix. It must be the SFX based implementation,
1231     // which can create a view on top of such xModel components :-)
1232     if (m_eContentType == E_CAN_BE_SET)
1233     {
1234         try
1235         {
1236             return m_xSMGR->createInstance(IMPLEMENTATIONNAME_GENERICFRAMELOADER);
1237         }
1238         catch(const css::uno::RuntimeException&)
1239             { throw; }
1240         catch(const css::uno::Exception&)
1241             {}
1242         throw LoadEnvException(LoadEnvException::ID_INVALID_ENVIRONMENT);
1243     }
1244 
1245     // Otherwhise ...
1246     // We need this type information to locate an registered frame loader
1247     // Without such information we cant work!
1248     ::rtl::OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), ::rtl::OUString());
1249     if (!sType.getLength())
1250         throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR);
1251 
1252     // try to locate any interested frame loader
1253     css::uno::Reference< css::lang::XMultiServiceFactory > xLoaderFactory(m_xSMGR->createInstance(SERVICENAME_FRAMELOADERFACTORY), css::uno::UNO_QUERY);
1254     css::uno::Reference< css::container::XContainerQuery > xQuery        (xLoaderFactory                                         , css::uno::UNO_QUERY);
1255 
1256     aReadLock.unlock();
1257     // <- SAFE -----------------------------------
1258 
1259     css::uno::Sequence< ::rtl::OUString > lTypesReg(1);
1260     lTypesReg[0] = sType;
1261 
1262     css::uno::Sequence< css::beans::NamedValue > lQuery(1);
1263     lQuery[0].Name    = ::framework::constant::FrameLoader::PROP_TYPES;
1264     lQuery[0].Value <<= lTypesReg;
1265 
1266     css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery);
1267     while(xSet->hasMoreElements())
1268     {
1269         // try everyone ...
1270         // Ignore any loader, which makes trouble :-)
1271         ::comphelper::SequenceAsHashMap             lLoaderProps(xSet->nextElement());
1272         ::rtl::OUString                             sLoader     = lLoaderProps.getUnpackedValueOrDefault(::framework::constant::FrameLoader::PROP_NAME, ::rtl::OUString());
1273         css::uno::Reference< css::uno::XInterface > xLoader     ;
1274         try
1275         {
1276             xLoader = xLoaderFactory->createInstance(sLoader);
1277             if (xLoader.is())
1278                 return xLoader;
1279         }
1280         catch(const css::uno::RuntimeException&)
1281             { throw; }
1282         catch(const css::uno::Exception&)
1283             { continue; }
1284     }
1285 
1286     return css::uno::Reference< css::uno::XInterface >();
1287 }
1288 
1289 /*-----------------------------------------------
1290     24.01.2006 15:11
1291 -----------------------------------------------*/
1292 void LoadEnv::impl_jumpToMark(const css::uno::Reference< css::frame::XFrame >& xFrame,
1293                               const css::util::URL&                            aURL  )
1294 {
1295     if (! aURL.Mark.getLength())
1296         return;
1297 
1298     css::uno::Reference< css::frame::XDispatchProvider > xProvider(xFrame, css::uno::UNO_QUERY);
1299     if (! xProvider.is())
1300         return;
1301 
1302     // SAFE ->
1303     ReadGuard aReadLock(m_aLock);
1304     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1305     aReadLock.unlock();
1306     // <- SAFE
1307 
1308     css::util::URL aCmd;
1309     aCmd.Complete = ::rtl::OUString::createFromAscii(".uno:JumpToMark");
1310 
1311     css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW);
1312     xParser->parseStrict(aCmd);
1313 
1314     css::uno::Reference< css::frame::XDispatch > xDispatcher = xProvider->queryDispatch(aCmd, SPECIALTARGET_SELF, 0);
1315     if (! xDispatcher.is())
1316         return;
1317 
1318     ::comphelper::SequenceAsHashMap lArgs;
1319     lArgs[::rtl::OUString::createFromAscii("Bookmark")] <<= aURL.Mark;
1320     xDispatcher->dispatch(aCmd, lArgs.getAsConstPropertyValueList());
1321 }
1322 
1323 /*-----------------------------------------------
1324     31.07.2003 09:02
1325 -----------------------------------------------*/
1326 css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchAlreadyLoaded()
1327     throw(LoadEnvException, css::uno::RuntimeException)
1328 {
1329     // SAFE ->
1330     ReadGuard aReadLock(m_aLock);
1331 
1332     // such search is allowed for special requests only ...
1333     // or better its not allowed for some requests in general :-)
1334     if (
1335         ( ! TargetHelper::matchSpecialTarget(m_sTarget, TargetHelper::E_DEFAULT)                                               ) ||
1336         (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_ASTEMPLATE() , sal_False) == sal_True) ||
1337 //      (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN()     , sal_False) == sal_True) ||
1338         (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_OPENNEWVIEW(), sal_False) == sal_True)
1339        )
1340     {
1341         return css::uno::Reference< css::frame::XFrame >();
1342     }
1343 
1344     // check URL
1345     // May its not usefull to start expensive document search, if it
1346     // can fail only .. because we load from a stream or model directly!
1347     if (
1348         (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM )) ||
1349         (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT ))
1350         /*TODO should be private:factory here tested too? */
1351        )
1352     {
1353         return css::uno::Reference< css::frame::XFrame >();
1354     }
1355 
1356     // otherwhise - iterate through the tasks of the desktop container
1357     // to find out, which of them might contains the requested document
1358     css::uno::Reference< css::frame::XFramesSupplier >  xSupplier(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
1359     css::uno::Reference< css::container::XIndexAccess > xTaskList(xSupplier->getFrames()                      , css::uno::UNO_QUERY);
1360 
1361     if (!xTaskList.is())
1362         return css::uno::Reference< css::frame::XFrame >(); // task list can be empty!
1363 
1364     // Note: To detect if a document was alrady loaded before
1365     // we check URLs here only. But might the existing and the requred
1366     // document has different versions! Then its URLs are the same ...
1367     sal_Int16 nNewVersion = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_VERSION(), (sal_Int16)(-1));
1368 
1369     // will be used to save the first hidden frame referring the searched model
1370     // Normaly we are interested on visible frames ... but if there is no such visible
1371     // frame we referr to any hidden frame also (but as fallback only).
1372     css::uno::Reference< css::frame::XFrame > xHiddenTask;
1373     css::uno::Reference< css::frame::XFrame > xTask;
1374 
1375     sal_Int32 count = xTaskList->getCount();
1376     for (sal_Int32 i=0; i<count; ++i)
1377     {
1378         try
1379         {
1380             // locate model of task
1381             // Note: Without a model there is no chance to decide if
1382             // this task contains the searched document or not!
1383             xTaskList->getByIndex(i) >>= xTask;
1384             if (!xTask.is())
1385                 continue;
1386 
1387             css::uno::Reference< css::frame::XController > xController = xTask->getController();
1388             if (!xController.is())
1389 			{
1390 				xTask.clear ();
1391                 continue;
1392 			}
1393 
1394             css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
1395             if (!xModel.is())
1396 			{
1397 				xTask.clear ();
1398                 continue;
1399 			}
1400 
1401             // don't check the complete URL here.
1402             // use its main part - ignore optional jumpmarks!
1403 			const ::rtl::OUString sURL = xModel->getURL();
1404             if (!::utl::UCBContentHelper::EqualURLs( m_aURL.Main, sURL ))
1405 			{
1406 				xTask.clear ();
1407                 continue;
1408 			}
1409 
1410             // get the original load arguments from the current document
1411             // and decide if its realy the same then the one will be.
1412             // It must be visible and must use the same file revision ...
1413             // or must not have any file revision set (-1 == -1!)
1414             ::comphelper::MediaDescriptor lOldDocDescriptor(xModel->getArgs());
1415 
1416             if (lOldDocDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_VERSION(), (sal_Int32)(-1)) != nNewVersion)
1417 			{
1418 				xTask.clear ();
1419                 continue;
1420 			}
1421 
1422             // Hidden frames are special.
1423             // They will be used as "last chance" if there is no visible frame pointing to the same model.
1424             // Safe the result but continue with current loop might be looking for other visible frames.
1425             ::sal_Bool bIsHidden = lOldDocDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False);
1426             if (
1427                 (   bIsHidden       ) &&
1428                 ( ! xHiddenTask.is())
1429                )
1430             {
1431                 xHiddenTask = xTask;
1432                 xTask.clear ();
1433                 continue;
1434             }
1435 
1436             // We found a visible task pointing to the right model ...
1437             // Break search.
1438             break;
1439         }
1440         catch(const css::uno::RuntimeException& exRun)
1441             { throw exRun; }
1442         catch(const css::uno::Exception&)
1443             { continue; }
1444     }
1445 
1446     css::uno::Reference< css::frame::XFrame > xResult;
1447     if (xTask.is())
1448         xResult = xTask;
1449     else
1450     if (xHiddenTask.is())
1451         xResult = xHiddenTask;
1452 
1453     if (xResult.is())
1454     {
1455         // Now we are shure, that this task includes the searched document.
1456         // It's time to activate it. As special feature we try to jump internaly
1457         // if an optional jumpmark is given too.
1458         if (m_aURL.Mark.getLength())
1459             impl_jumpToMark(xResult, m_aURL);
1460 
1461         // bring it to front and make sure it's visible...
1462         impl_makeFrameWindowVisible(xResult->getContainerWindow(), sal_True);
1463     }
1464 
1465     aReadLock.unlock();
1466     // <- SAFE
1467 
1468     return xResult;
1469 }
1470 
1471 /*-----------------------------------------------
1472     30.03.2004 09:12
1473 -----------------------------------------------*/
1474 sal_Bool LoadEnv::impl_isFrameAlreadyUsedForLoading(const css::uno::Reference< css::frame::XFrame >& xFrame) const
1475 {
1476     css::uno::Reference< css::document::XActionLockable > xLock(xFrame, css::uno::UNO_QUERY);
1477 
1478     // ? no lock interface ?
1479     // Might its an external written frame implementation :-(
1480     // Allowing using of it ... but it can fail if its not synchronized with our processes !
1481     if (!xLock.is())
1482         return sal_False;
1483 
1484     // Otherwhise we have to look for any other existing lock.
1485     return xLock->isActionLocked();
1486 }
1487 
1488 /*-----------------------------------------------
1489     30.03.2004 09:12
1490 -----------------------------------------------*/
1491 css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchRecycleTarget()
1492     throw(LoadEnvException, css::uno::RuntimeException)
1493 {
1494     // SAFE -> ..................................
1495     ReadGuard aReadLock(m_aLock);
1496 
1497     // The special backing mode frame will be recycled by definition!
1498     // It does'nt matter if somehwere whish to create a new view
1499     // or open a new untitled document ...
1500     // The only exception form that - hidden frames!
1501     if (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False) == sal_True)
1502         return css::uno::Reference< css::frame::XFrame >();
1503 
1504     css::uno::Reference< css::frame::XFramesSupplier > xSupplier(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
1505     FrameListAnalyzer aTasksAnalyzer(xSupplier, css::uno::Reference< css::frame::XFrame >(), FrameListAnalyzer::E_BACKINGCOMPONENT);
1506     if (aTasksAnalyzer.m_xBackingComponent.is())
1507     {
1508         if (!impl_isFrameAlreadyUsedForLoading(aTasksAnalyzer.m_xBackingComponent))
1509         {
1510             // bring it to front ...
1511             impl_makeFrameWindowVisible(aTasksAnalyzer.m_xBackingComponent->getContainerWindow(), sal_True);
1512             return aTasksAnalyzer.m_xBackingComponent;
1513         }
1514     }
1515 
1516     // These states indicates the wishing for creation of a new view in general.
1517     if (
1518         (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_ASTEMPLATE() , sal_False) == sal_True) ||
1519         (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_OPENNEWVIEW(), sal_False) == sal_True)
1520        )
1521     {
1522         return css::uno::Reference< css::frame::XFrame >();
1523     }
1524 
1525 	// On the other side some special URLs will open a new frame everytimes (expecting
1526 	// they can use the backing-mode frame!)
1527     if (
1528         (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_FACTORY )) ||
1529         (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM  )) ||
1530         (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT  ))
1531        )
1532     {
1533         return css::uno::Reference< css::frame::XFrame >();
1534     }
1535 
1536 	// No backing frame! No special URL => recycle active task - if possible.
1537 	// Means - if it does not already contains a modified document, or
1538 	// use another office module.
1539     css::uno::Reference< css::frame::XFrame > xTask = xSupplier->getActiveFrame();
1540 
1541     // not a real error - but might a focus problem!
1542     if (!xTask.is())
1543         return css::uno::Reference< css::frame::XFrame >();
1544 
1545     // not a real error - may its a view only
1546     css::uno::Reference< css::frame::XController > xController = xTask->getController();
1547     if (!xController.is())
1548         return css::uno::Reference< css::frame::XFrame >();
1549 
1550     // not a real error - may its a db component instead of a full feartured office document
1551     css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
1552     if (!xModel.is())
1553         return css::uno::Reference< css::frame::XFrame >();
1554 
1555     // get some more informations ...
1556 
1557     // A valid set URL means: there is already a location for this document.
1558     // => it was saved there or opened from there. Such Documents can not be used here.
1559     // We search for empty document ... created by a private:factory/ URL!
1560     if (xModel->getURL().getLength()>0)
1561         return css::uno::Reference< css::frame::XFrame >();
1562 
1563     // The old document must be unmodified ...
1564     css::uno::Reference< css::util::XModifiable > xModified(xModel, css::uno::UNO_QUERY);
1565     if (xModified->isModified())
1566         return css::uno::Reference< css::frame::XFrame >();
1567 
1568     Window* pWindow = VCLUnoHelper::GetWindow(xTask->getContainerWindow());
1569     if (pWindow && pWindow->IsInModalMode())
1570         return css::uno::Reference< css::frame::XFrame >();
1571 
1572     // find out the application type of this document
1573     // We can recycle only documents, which uses the same application
1574     // then the new one.
1575     SvtModuleOptions::EFactory eOldApp = SvtModuleOptions::ClassifyFactoryByModel(xModel);
1576     SvtModuleOptions::EFactory eNewApp = SvtModuleOptions::ClassifyFactoryByURL  (m_aURL.Complete, m_lMediaDescriptor.getAsConstPropertyValueList());
1577 
1578     aReadLock.unlock();
1579     // <- SAFE ..................................
1580 
1581     if (eOldApp != eNewApp)
1582         return css::uno::Reference< css::frame::XFrame >();
1583 
1584     // OK this task seams to be useable for recycling
1585     // But we should mark it as such - means set an action lock.
1586     // Otherwhise it would be used more then ones or will be destroyed
1587     // by a close() or terminate() request.
1588     // But if such lock already exist ... it means this task is used for
1589     // any other operation already. Don't use it then.
1590     if (impl_isFrameAlreadyUsedForLoading(xTask))
1591         return css::uno::Reference< css::frame::XFrame >();
1592 
1593     // OK - there is a valid target frame.
1594     // But may be it contains already a document.
1595     // Then we have to ask it, if it allows recylcing of this frame .-)
1596     sal_Bool bReactivateOldControllerOnError = sal_False;
1597     css::uno::Reference< css::frame::XController > xOldDoc = xTask->getController();
1598     if (xOldDoc.is())
1599     {
1600         bReactivateOldControllerOnError = xOldDoc->suspend(sal_True);
1601         if (! bReactivateOldControllerOnError)
1602             return css::uno::Reference< css::frame::XFrame >();
1603     }
1604 
1605     // SAFE -> ..................................
1606     WriteGuard aWriteLock(m_aLock);
1607 
1608     css::uno::Reference< css::document::XActionLockable > xLock(xTask, css::uno::UNO_QUERY);
1609     if (!m_aTargetLock.setResource(xLock))
1610         return css::uno::Reference< css::frame::XFrame >();
1611 
1612     m_bReactivateControllerOnError = bReactivateOldControllerOnError;
1613     aWriteLock.unlock();
1614     // <- SAFE ..................................
1615 
1616     // bring it to front ...
1617     impl_makeFrameWindowVisible(xTask->getContainerWindow(), sal_True);
1618 
1619     return xTask;
1620 }
1621 
1622 /*-----------------------------------------------
1623     15.08.2003 12:39
1624 -----------------------------------------------*/
1625 void LoadEnv::impl_reactForLoadingState()
1626     throw(LoadEnvException, css::uno::RuntimeException)
1627 {
1628     /*TODO reset action locks */
1629 
1630     // SAFE -> ----------------------------------
1631     ReadGuard aReadLock(m_aLock);
1632 
1633     if (m_bLoaded)
1634     {
1635         // Bring the new loaded document to front (if allowed!).
1636         // Note: We show new created frames here only.
1637         // We dont hide already visible frames here ...
1638         css::uno::Reference< css::awt::XWindow > xWindow      = m_xTargetFrame->getContainerWindow();
1639         sal_Bool                                 bHidden      = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False);
1640         sal_Bool                                 bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_MINIMIZED(), sal_False);
1641 
1642         if (bMinimized)
1643         {
1644             ::vos::OClearableGuard aSolarGuard(Application::GetSolarMutex());
1645             Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
1646             // check for system window is neccessary to guarantee correct pointer cast!
1647             if (pWindow && pWindow->IsSystemWindow())
1648                 ((WorkWindow*)pWindow)->Minimize();
1649         }
1650         else
1651         if (!bHidden)
1652         {
1653             // show frame ... if it's not still visible ...
1654             // But do nothing if it's already visible!
1655             impl_makeFrameWindowVisible(xWindow, sal_False);
1656         }
1657 
1658         // Note: Only if an existing property "FrameName" is given by this media descriptor,
1659         // it should be used. Otherwhise we should do nothing. May be the outside code has already
1660         // set a frame name on the target!
1661         ::comphelper::MediaDescriptor::const_iterator pFrameName = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_FRAMENAME());
1662         if (pFrameName != m_lMediaDescriptor.end())
1663         {
1664             ::rtl::OUString sFrameName;
1665             pFrameName->second >>= sFrameName;
1666             // Check the name again. e.g. "_default" isnt allowed.
1667             // On the other side "_beamer" is a valid name :-)
1668             if (TargetHelper::isValidNameForFrame(sFrameName))
1669                 m_xTargetFrame->setName(sFrameName);
1670         }
1671     }
1672     else if (m_bReactivateControllerOnError)
1673 	{
1674 		// Try to reactivate the old document (if any exists!)
1675 		css::uno::Reference< css::frame::XController > xOldDoc = m_xTargetFrame->getController();
1676 		// clear does not depend from reactivation state of a might existing old document!
1677 		// We must make shure, that a might following getTargetComponent() call does not return
1678 		// the old document!
1679 		m_xTargetFrame.clear();
1680 		if (xOldDoc.is())
1681 		{
1682 			sal_Bool bReactivated = xOldDoc->suspend(sal_False);
1683 			if (!bReactivated)
1684 				throw LoadEnvException(LoadEnvException::ID_COULD_NOT_REACTIVATE_CONTROLLER);
1685 			m_bReactivateControllerOnError = sal_False;
1686 		}
1687 	}
1688 	else if (m_bCloseFrameOnError)
1689 	{
1690 		// close empty frames
1691 		css::uno::Reference< css::util::XCloseable > xCloseable (m_xTargetFrame, css::uno::UNO_QUERY);
1692 		css::uno::Reference< css::lang::XComponent > xDisposable(m_xTargetFrame, css::uno::UNO_QUERY);
1693 
1694 		try
1695 		{
1696 			if (xCloseable.is())
1697 				xCloseable->close(sal_True);
1698 			else
1699 			if (xDisposable.is())
1700 				xDisposable->dispose();
1701 		}
1702 		catch(const css::util::CloseVetoException&)
1703 		{}
1704 		catch(const css::lang::DisposedException&)
1705 		{}
1706 		m_xTargetFrame.clear();
1707 	}
1708 
1709     // This max force an implicit closing of our target frame ...
1710     // e.g. in case close(sal_True) was called before and the frame
1711     // kill itself if our external use-lock is released here!
1712     // Thats why we releas this lock AFTER ALL OPERATIONS on this frame
1713     // are finished. The frame itslef must handle then
1714     // this situation gracefully.
1715     m_aTargetLock.freeResource();
1716 
1717     // Last but not least :-)
1718     // We have to clear the current media descriptor.
1719     // Otherwhise it hold a might existing stream open!
1720     m_lMediaDescriptor.clear();
1721 
1722 	css::uno::Any aRequest;
1723 	bool bThrow = false;
1724 	if ( !m_bLoaded && m_pQuietInteraction && m_pQuietInteraction->wasUsed() )
1725 	{
1726 		aRequest = m_pQuietInteraction->getRequest();
1727 		m_pQuietInteraction->release();
1728 		m_pQuietInteraction = 0;
1729 		bThrow = true;
1730 	}
1731 
1732     aReadLock.unlock();
1733 
1734 	if (bThrow)
1735 	{
1736         if  ( aRequest.isExtractableTo( ::cppu::UnoType< css::uno::Exception >::get() ) )
1737 			throw LoadEnvException( LoadEnvException::ID_GENERAL_ERROR, aRequest );
1738 	}
1739 
1740     // <- SAFE ----------------------------------
1741 }
1742 
1743 /*-----------------------------------------------
1744     16.01.2005 13:04
1745 -----------------------------------------------*/
1746 void LoadEnv::impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::XWindow >& xWindow      ,
1747                                                 sal_Bool bForceToFront)
1748 {
1749     // SAFE -> ----------------------------------
1750     ReadGuard aReadLock(m_aLock);
1751     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xSMGR.get(), css::uno::UNO_QUERY );
1752     aReadLock.unlock();
1753     // <- SAFE ----------------------------------
1754 
1755     ::vos::OClearableGuard aSolarGuard(Application::GetSolarMutex());
1756     Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
1757     if ( pWindow )
1758     {
1759         bool bForceFrontAndFocus(false);
1760         css::uno::Any a = ::comphelper::ConfigurationHelper::readDirectKey(
1761             xSMGR,
1762             ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/View"),
1763             ::rtl::OUString::createFromAscii("NewDocumentHandling"),
1764             ::rtl::OUString::createFromAscii("ForceFocusAndToFront"),
1765             ::comphelper::ConfigurationHelper::E_READONLY);
1766         a >>= bForceFrontAndFocus;
1767 
1768         if( pWindow->IsVisible() && (bForceFrontAndFocus || bForceToFront) )
1769             pWindow->ToTop();
1770         else
1771             pWindow->Show(sal_True, (bForceFrontAndFocus || bForceToFront) ? SHOW_FOREGROUNDTASK : 0 );
1772     }
1773 
1774 /* #i19976#
1775     We tried to prevent a toFront() call in case the user putted the
1776     loading document into the background ..
1777     But we had several errors trying that. So we decided to
1778     rollback these changes and bring the new loaded document to front hardly !
1779 
1780     css::uno::Reference< css::awt::XWindow2 > xWindow2(xWindow, css::uno::UNO_QUERY);
1781 
1782     sal_Bool bIsVisible = sal_False;
1783     if (xWindow2.is())
1784         bIsVisible = xWindow2->isVisible(); // TODO is parent visible too ? .-)
1785 
1786     if (!bIsVisible)
1787     {
1788         xWindow->setVisible(sal_True);
1789         bForceToFront = sal_True;
1790     }
1791 
1792     if (
1793         (bForceToFront  ) &&
1794         (xTopWindow.is())
1795        )
1796     {
1797         xTopWindow->toFront();
1798     }
1799 */
1800 }
1801 
1802 /*-----------------------------------------------
1803     15.03.2005 11:12
1804 -----------------------------------------------*/
1805 void LoadEnv::impl_applyPersistentWindowState(const css::uno::Reference< css::awt::XWindow >& xWindow)
1806 {
1807     static ::rtl::OUString PACKAGE_SETUP_MODULES = ::rtl::OUString::createFromAscii("/org.openoffice.Setup/Office/Factories");
1808 
1809     // no window -> action not possible
1810     if (!xWindow.is())
1811         return;
1812 
1813     // window already visible -> do nothing! If we use a "recycle frame" for loading ...
1814     // the current position and size must be used.
1815     css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(xWindow, css::uno::UNO_QUERY);
1816     if (
1817         (xVisibleCheck.is()        ) &&
1818         (xVisibleCheck->isVisible())
1819        )
1820        return;
1821 
1822     // SOLAR SAFE ->
1823     ::vos::OClearableGuard aSolarLock1(Application::GetSolarMutex());
1824 
1825     Window*  pWindow       = VCLUnoHelper::GetWindow(xWindow);
1826     sal_Bool bSystemWindow = pWindow->IsSystemWindow();
1827     sal_Bool bWorkWindow   = (pWindow->GetType() == WINDOW_WORKWINDOW);
1828 
1829     if (!bSystemWindow && !bWorkWindow)
1830         return;
1831 
1832     // dont overwrite this special state!
1833     WorkWindow* pWorkWindow = (WorkWindow*)pWindow;
1834     if (pWorkWindow->IsMinimized())
1835         return;
1836 
1837     aSolarLock1.clear();
1838     // <- SOLAR SAFE
1839 
1840     // SAFE ->
1841     ReadGuard aReadLock(m_aLock);
1842 
1843     // no filter -> no module -> no persistent window state
1844     ::rtl::OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(
1845                                     ::comphelper::MediaDescriptor::PROP_FILTERNAME(),
1846                                     ::rtl::OUString());
1847     if (!sFilter.getLength())
1848         return;
1849 
1850     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1851 
1852     aReadLock.unlock();
1853     // <- SAFE
1854 
1855     try
1856     {
1857         // retrieve the module name from the filter configuration
1858         css::uno::Reference< css::container::XNameAccess > xFilterCfg(
1859             xSMGR->createInstance(SERVICENAME_FILTERFACTORY),
1860             css::uno::UNO_QUERY_THROW);
1861         ::comphelper::SequenceAsHashMap lProps (xFilterCfg->getByName(sFilter));
1862         ::rtl::OUString                 sModule = lProps.getUnpackedValueOrDefault(FILTER_PROPNAME_DOCUMENTSERVICE, ::rtl::OUString());
1863 
1864         // get access to the configuration of this office module
1865         css::uno::Reference< css::container::XNameAccess > xModuleCfg(::comphelper::ConfigurationHelper::openConfig(
1866                                                                         xSMGR,
1867                                                                         PACKAGE_SETUP_MODULES,
1868                                                                         ::comphelper::ConfigurationHelper::E_READONLY),
1869                                                                       css::uno::UNO_QUERY_THROW);
1870 
1871         // read window state from the configuration
1872         // and apply it on the window.
1873         // Do nothing, if no configuration entry exists!
1874         ::rtl::OUString sWindowState ;
1875         ::comphelper::ConfigurationHelper::readRelativeKey(xModuleCfg, sModule, OFFICEFACTORY_PROPNAME_WINDOWATTRIBUTES) >>= sWindowState;
1876         if (sWindowState.getLength())
1877         {
1878             // SOLAR SAFE ->
1879             ::vos::OClearableGuard aSolarLock2(Application::GetSolarMutex());
1880 
1881             // We have to retrieve the window pointer again. Because nobody can guarantee
1882             // that the XWindow was not disposed inbetween .-)
1883             // But if we get a valid pointer we can be sure, that it's the system window pointer
1884             // we already checked and used before. Because nobody recylce the same uno reference for
1885             // a new internal c++ implementation ... hopefully .-))
1886             Window* pWindowCheck  = VCLUnoHelper::GetWindow(xWindow);
1887             if (! pWindowCheck)
1888                 return;
1889 
1890             SystemWindow* pSystemWindow = (SystemWindow*)pWindowCheck;
1891             pSystemWindow->SetWindowState(U2B_ENC(sWindowState,RTL_TEXTENCODING_UTF8));
1892 
1893             aSolarLock2.clear();
1894             // <- SOLAR SAFE
1895         }
1896     }
1897     catch(const css::uno::RuntimeException& exRun)
1898         { throw exRun; }
1899     catch(const css::uno::Exception&)
1900         {}
1901 }
1902 
1903 } // namespace framework
1904 
1905