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