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 	//IAccessibility2 Implementation 2009-----
191 #ifdef WNT
192 	CEnableAccessInterface e;
193 #endif
194 	//-----IAccessibility2 Implementation 2009
195     css::uno::Reference< css::lang::XComponent > xComponent;
196 
197     try
198     {
199         LoadEnv aEnv(xSMGR);
200 
201         aEnv.initializeLoading(sURL,
202                                lArgs,
203                                css::uno::Reference< css::frame::XFrame >(xLoader, css::uno::UNO_QUERY),
204                                sTarget,
205                                nFlags,
206                                LoadEnv::E_NO_FEATURE);
207         aEnv.startLoading();
208         aEnv.waitWhileLoading(); // wait for ever!
209 
210         xComponent = aEnv.getTargetComponent();
211     }
212     catch(const LoadEnvException& ex)
213     {
214         switch(ex.m_nID)
215         {
216             case LoadEnvException::ID_INVALID_MEDIADESCRIPTOR:
217                     throw css::lang::IllegalArgumentException(
218                             ::rtl::OUString::createFromAscii("Optional list of arguments seem to be corrupted."),
219                             xLoader,
220                             4);
221 
222             case LoadEnvException::ID_UNSUPPORTED_CONTENT:
223                     throw css::lang::IllegalArgumentException(
224                             ::rtl::OUString::createFromAscii("URL seems to be an unsupported one."),
225                             xLoader,
226                             1);
227 
228 			default: xComponent.clear();
229                     break;
230         }
231     }
232 
233     return xComponent;
234 }
235 
236 //-----------------------------------------------
237 ::comphelper::MediaDescriptor impl_mergeMediaDescriptorWithMightExistingModelArgs(const css::uno::Sequence< css::beans::PropertyValue >& lOutsideDescriptor)
238 {
239     ::comphelper::MediaDescriptor lDescriptor(lOutsideDescriptor);
240     css::uno::Reference< css::frame::XModel > xModel     = lDescriptor.getUnpackedValueOrDefault(
241                                                             ::comphelper::MediaDescriptor::PROP_MODEL (),
242                                                             css::uno::Reference< css::frame::XModel > ());
243     if (xModel.is ())
244     {
245         ::comphelper::MediaDescriptor lModelDescriptor(xModel->getArgs());
246         ::comphelper::MediaDescriptor::iterator pIt = lModelDescriptor.find( ::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE() );
247 		if ( pIt != lModelDescriptor.end() )
248 			lDescriptor[::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()] = pIt->second;
249     }
250 
251     return lDescriptor;
252 }
253 
254 /*-----------------------------------------------
255     20.08.2003 09:49
256 -----------------------------------------------*/
257 void LoadEnv::initializeLoading(const ::rtl::OUString&                                           sURL            ,
258                                 const css::uno::Sequence< css::beans::PropertyValue >&           lMediaDescriptor,
259                                 const css::uno::Reference< css::frame::XFrame >&                 xBaseFrame      ,
260                                 const ::rtl::OUString&                                           sTarget         ,
261                                       sal_Int32                                                  nSearchFlags    ,
262                                       EFeature                                                   eFeature        , // => use default ...
263                                       EContentType                                               eContentType    ) // => use default ...
264     throw(LoadEnvException, css::uno::RuntimeException)
265 {
266     // SAFE -> ----------------------------------
267     WriteGuard aWriteLock(m_aLock);
268 
269     // Handle still running processes!
270     if (m_xAsynchronousJob.is())
271         throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
272 
273     // take over all new parameters.
274     m_xTargetFrame.clear();
275     m_xBaseFrame                    = xBaseFrame        ;
276     m_lMediaDescriptor              = impl_mergeMediaDescriptorWithMightExistingModelArgs(lMediaDescriptor);
277     m_sTarget                       = sTarget           ;
278     m_nSearchFlags                  = nSearchFlags      ;
279     m_eFeature                      = eFeature          ;
280     m_eContentType                  = eContentType      ;
281     m_bCloseFrameOnError            = sal_False         ;
282     m_bReactivateControllerOnError  = sal_False         ;
283     m_bLoaded                       = sal_False         ;
284 
285     // try to find out, if its realy a content, which can be loaded or must be "handled"
286     // We use a default value for this in-parameter. Then we have to start a complex check method
287     // internaly. But if this check was already done outside it can be supressed to perform
288     // the load request. We take over the result then!
289     if (m_eContentType == E_UNSUPPORTED_CONTENT)
290     {
291         m_eContentType = LoadEnv::classifyContent(sURL, lMediaDescriptor);
292         if (m_eContentType == E_UNSUPPORTED_CONTENT)
293             throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);
294     }
295 
296     // make URL part of the MediaDescriptor
297     // It doesnt mater, if its already an item of it.
298     // It must be the same value ... so we can overwrite it :-)
299     m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_URL()] <<= sURL;
300 
301     // parse it - because some following code require that
302     m_aURL.Complete = sURL;
303     css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY);
304     xParser->parseStrict(m_aURL);
305 
306     // BTW: Split URL and JumpMark ...
307     // Because such mark is an explicit value of the media descriptor!
308     if (m_aURL.Mark.getLength())
309         m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_JUMPMARK()] <<= m_aURL.Mark;
310 
311     // By the way: remove the old and deprecated value "FileName" from the descriptor!
312     ::comphelper::MediaDescriptor::iterator pIt = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_FILENAME());
313     if (pIt != m_lMediaDescriptor.end())
314         m_lMediaDescriptor.erase(pIt);
315 
316     // patch the MediaDescriptor, so it fullfill the outside requirements
317     // Means especialy items like e.g. UI InteractionHandler, Status Indicator,
318     // MacroExecutionMode etcpp.
319 
320     /*TODO progress is bound to a frame ... How can we set it here? */
321 
322     // UI mode
323     const bool bUIMode =
324         ( ( m_eFeature & E_WORK_WITH_UI )                                                                          == E_WORK_WITH_UI ) &&
325         ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False ) == sal_False      ) &&
326         ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_PREVIEW(), sal_False ) == sal_False      );
327 
328     initializeUIDefaults(
329         m_xSMGR,
330         m_lMediaDescriptor,
331         bUIMode,
332         &m_pQuietInteraction
333     );
334 
335     aWriteLock.unlock();
336     // <- SAFE ----------------------------------
337 }
338 
339 /*-----------------------------------------------
340     22.01.2010
341 -----------------------------------------------*/
342 void LoadEnv::initializeUIDefaults( const css::uno::Reference< css::lang::XMultiServiceFactory >& i_rSMGR,
343                                     ::comphelper::MediaDescriptor& io_lMediaDescriptor, const bool i_bUIMode,
344                                     QuietInteraction** o_ppQuietInteraction )
345 {
346     css::uno::Reference< css::task::XInteractionHandler > xInteractionHandler;
347     sal_Int16                                             nMacroMode         ;
348     sal_Int16                                             nUpdateMode        ;
349 
350     if ( i_bUIMode )
351     {
352         nMacroMode  = css::document::MacroExecMode::USE_CONFIG;
353         nUpdateMode = css::document::UpdateDocMode::ACCORDING_TO_CONFIG;
354         try
355         {
356             xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(i_rSMGR->createInstance(IMPLEMENTATIONNAME_UIINTERACTIONHANDLER), css::uno::UNO_QUERY);
357         }
358         catch(const css::uno::RuntimeException&) {throw;}
359         catch(const css::uno::Exception&       ) {      }
360     }
361     // hidden mode
362     else
363     {
364         nMacroMode  = css::document::MacroExecMode::NEVER_EXECUTE;
365         nUpdateMode = css::document::UpdateDocMode::NO_UPDATE;
366         QuietInteraction* pQuietInteraction = new QuietInteraction();
367         xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(static_cast< css::task::XInteractionHandler* >(pQuietInteraction), css::uno::UNO_QUERY);
368         if ( o_ppQuietInteraction != NULL )
369         {
370             *o_ppQuietInteraction = pQuietInteraction;
371             (*o_ppQuietInteraction)->acquire();
372         }
373     }
374 
375     if (
376         (xInteractionHandler.is()                                                                                       ) &&
377         (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()) == io_lMediaDescriptor.end())
378        )
379     {
380         io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()] <<= xInteractionHandler;
381     }
382 
383     if (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()) == io_lMediaDescriptor.end())
384         io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()] <<= nMacroMode;
385 
386     if (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_UPDATEDOCMODE()) == io_lMediaDescriptor.end())
387         io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_UPDATEDOCMODE()] <<= nUpdateMode;
388 }
389 
390 /*-----------------------------------------------
391     15.08.2003 08:16
392 -----------------------------------------------*/
393 void LoadEnv::startLoading()
394     throw(LoadEnvException, css::uno::RuntimeException)
395 {
396     // SAFE ->
397     ReadGuard aReadLock(m_aLock);
398 
399     // Handle still running processes!
400     if (m_xAsynchronousJob.is())
401         throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
402 
403     // content can not be loaded or handled
404     // check "classifyContent()" failed before ...
405     if (m_eContentType == E_UNSUPPORTED_CONTENT)
406         throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);
407 
408     // <- SAFE
409     aReadLock.unlock();
410 
411     // detect its type/filter etcpp.
412     // These information will be available by the
413     // used descriptor member afterwards and is needed
414     // for all following operations!
415     // Note: An exception will be thrown, in case operation was not successfully ...
416     if (m_eContentType != E_CAN_BE_SET)/* Attention: special feature to set existing component on a frame must ignore type detection! */
417         impl_detectTypeAndFilter();
418 
419     // start loading the content ...
420     // Attention: Dont check m_eContentType deeper then UNSUPPORTED/SUPPORTED!
421     // Because it was made in th easiest way ... may a flat detection was made only.
422     // And such simple detection can fail some times .-)
423     // Use another strategy here. Try it and let it run into the case "loading not possible".
424     sal_Bool bStarted = sal_False;
425     if (
426         ((m_eFeature & E_ALLOW_CONTENTHANDLER) == E_ALLOW_CONTENTHANDLER) &&
427         (m_eContentType                        != E_CAN_BE_SET          )   /* Attention: special feature to set existing component on a frame must ignore type detection! */
428        )
429     {
430         bStarted = impl_handleContent();
431     }
432 
433     if (!bStarted)
434         bStarted = impl_loadContent();
435 
436     // not started => general error
437     // We cant say - what was the reason for.
438     if (!bStarted)
439         throw LoadEnvException(LoadEnvException::ID_GENERAL_ERROR);
440 }
441 
442 /*-----------------------------------------------
443     15.08.2003 09:50
444     TODO
445         First draft does not implement timeout using [ms].
446         Current implementation counts yield calls only ...
447 -----------------------------------------------*/
448 sal_Bool LoadEnv::waitWhileLoading(sal_uInt32 nTimeout)
449     throw(LoadEnvException, css::uno::RuntimeException)
450 {
451     // Because its not a good idea to block the main thread
452     // (and we cant be shure that we are currently not used inside the
453     // main thread!), we cant use conditions here realy. We must yield
454     // in an intellegent manner :-)
455 
456     sal_Int32 nTime = nTimeout;
457     while(true)
458     {
459         // SAFE -> ------------------------------
460         ReadGuard aReadLock1(m_aLock);
461         if (!m_xAsynchronousJob.is())
462             break;
463         aReadLock1.unlock();
464         // <- SAFE ------------------------------
465 
466         Application::Yield();
467 
468         // forever!
469         if (nTimeout==0)
470             continue;
471 
472         // timed out?
473         --nTime;
474         if (nTime<1)
475             break;
476     }
477 
478     // SAFE -> ----------------------------------
479     ReadGuard aReadLock2(m_aLock);
480     return !m_xAsynchronousJob.is();
481     // <- SAFE ----------------------------------
482 }
483 
484 /*-----------------------------------------------
485     20.08.2003 10:00
486 -----------------------------------------------*/
487 void LoadEnv::cancelLoading()
488     throw(LoadEnvException, css::uno::RuntimeException)
489 {
490     // PARTIAL(!) SAFE -> ------------------------------
491     ReadGuard aReadLock(m_aLock);
492 
493     // Still running? Might waitWhileLoading()
494     // runned into the timeout!
495     if (m_xAsynchronousJob.is())
496     {
497         // try to cancel it ... if its an asynchronous frame loader
498         css::uno::Reference< css::frame::XFrameLoader > xAsyncLoader(m_xAsynchronousJob, css::uno::UNO_QUERY);
499         if (xAsyncLoader.is())
500         {
501             aReadLock.unlock();
502             // <- BREAK SAFE ------------------------------
503             xAsyncLoader->cancel();
504             // <- RESTART SAFE ----------------------------
505             aReadLock.lock();
506             /* Attention:
507                 After returning from any cancel/dispose call, neither the frame nor weself
508                 may be called back. Because only we can cancel this job, we already know
509                 the result! => Thats why its not usefull nor neccessary to wait for any
510                 asynchronous listener notification.
511             */
512             m_bLoaded = sal_False;
513             m_xAsynchronousJob.clear();
514         }
515         // or may be its a content handler? Such handler cant be cancelled in its running
516         // operation :-( And we cant deregister us there again :-(
517         // => The only chance is an exception :-)
518         else
519             throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
520     }
521 
522     impl_reactForLoadingState();
523 
524     aReadLock.unlock();
525     // <- PARTIAL(!) SAFE ------------------------------
526 }
527 
528 /*-----------------------------------------------
529     14.08.2003 13:33
530 -----------------------------------------------*/
531 css::uno::Reference< css::frame::XFrame > LoadEnv::getTarget() const
532 {
533     // SAFE ->
534     ReadGuard aReadLock(m_aLock);
535     return m_xTargetFrame;
536     // <- SAFE
537 }
538 
539 /*-----------------------------------------------
540     14.08.2003 13:35
541 -----------------------------------------------*/
542 css::uno::Reference< css::lang::XComponent > LoadEnv::getTargetComponent() const
543 {
544     // SAFE ->
545     ReadGuard aReadLock(m_aLock);
546 
547     if (!m_xTargetFrame.is())
548         return css::uno::Reference< css::lang::XComponent >();
549 
550     css::uno::Reference< css::frame::XController > xController = m_xTargetFrame->getController();
551     if (!xController.is())
552         return css::uno::Reference< css::lang::XComponent >(m_xTargetFrame->getComponentWindow(), css::uno::UNO_QUERY);
553 
554     css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
555     if (!xModel.is())
556         return css::uno::Reference< css::lang::XComponent >(xController, css::uno::UNO_QUERY);
557 
558     return css::uno::Reference< css::lang::XComponent >(xModel, css::uno::UNO_QUERY);
559     // <- SAFE
560 }
561 
562 /*-----------------------------------------------
563     15.08.2003 11:15
564 -----------------------------------------------*/
565 void SAL_CALL LoadEnvListener::loadFinished(const css::uno::Reference< css::frame::XFrameLoader >&)
566     throw(css::uno::RuntimeException)
567 {
568     // SAFE -> ----------------------------------
569     WriteGuard aWriteLock(m_aLock);
570 
571     if (m_ppCheck && *m_ppCheck)
572         m_pLoadEnv->impl_setResult(sal_True);
573     m_ppCheck = NULL;
574 
575     aWriteLock.unlock();
576     // <- SAFE ----------------------------------
577 }
578 
579 /*-----------------------------------------------
580     14.10.2003 12:23
581 -----------------------------------------------*/
582 void SAL_CALL LoadEnvListener::loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >&)
583     throw(css::uno::RuntimeException)
584 {
585     // SAFE -> ----------------------------------
586     WriteGuard aWriteLock(m_aLock);
587 
588     if (m_ppCheck && *m_ppCheck)
589         m_pLoadEnv->impl_setResult(sal_False);
590     m_ppCheck = NULL;
591 
592     aWriteLock.unlock();
593     // <- SAFE ----------------------------------
594 }
595 
596 /*-----------------------------------------------
597     14.10.2003 12:23
598 -----------------------------------------------*/
599 void SAL_CALL LoadEnvListener::dispatchFinished(const css::frame::DispatchResultEvent& aEvent)
600     throw(css::uno::RuntimeException)
601 {
602     // SAFE -> ----------------------------------
603     WriteGuard aWriteLock(m_aLock);
604 
605     if (!m_ppCheck || !*m_ppCheck)
606         return;
607 
608     switch(aEvent.State)
609     {
610         case css::frame::DispatchResultState::FAILURE :
611             m_pLoadEnv->impl_setResult(sal_False);
612             break;
613 
614         case css::frame::DispatchResultState::SUCCESS :
615             m_pLoadEnv->impl_setResult(sal_False);
616             break;
617 
618         case css::frame::DispatchResultState::DONTKNOW :
619             m_pLoadEnv->impl_setResult(sal_False);
620             break;
621     }
622     m_ppCheck = NULL;
623 
624     aWriteLock.unlock();
625     // <- SAFE ----------------------------------
626 }
627 
628 /*-----------------------------------------------
629     14.10.2003 12:24
630 -----------------------------------------------*/
631 void SAL_CALL LoadEnvListener::disposing(const css::lang::EventObject&)
632     throw(css::uno::RuntimeException)
633 {
634     // SAFE -> ----------------------------------
635     WriteGuard aWriteLock(m_aLock);
636 
637     if (m_ppCheck && *m_ppCheck)
638         m_pLoadEnv->impl_setResult(sal_False);
639     m_ppCheck = NULL;
640 
641     aWriteLock.unlock();
642     // <- SAFE ----------------------------------
643 }
644 
645 /*-----------------------------------------------
646     14.10.2003 12:20
647 -----------------------------------------------*/
648 void LoadEnv::impl_setResult(sal_Bool bResult)
649 {
650     // SAFE -> ----------------------------------
651     WriteGuard aWriteLock(m_aLock);
652 
653     m_bLoaded = bResult;
654 
655     impl_reactForLoadingState();
656 
657     // clearing of this reference will unblock waitWhileLoading()!
658     // So we must be shure, that loading process was realy finished.
659     // => do it as last operation of this method ...
660     m_xAsynchronousJob.clear();
661 
662     aWriteLock.unlock();
663     // <- SAFE ----------------------------------
664 }
665 
666 /*-----------------------------------------------
667     06.02.2004 14:03
668     TODO: Is it a good idea to change Sequence<>
669           parameter to stl-adapter?
670 -----------------------------------------------*/
671 LoadEnv::EContentType LoadEnv::classifyContent(const ::rtl::OUString&                                 sURL            ,
672                                                const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor)
673 {
674     //-------------------------------------------
675     // (i) Filter some special well known URL protocols,
676     //     which can not be handled or loaded in general.
677     //     Of course an empty URL must be ignored here too.
678     //     Note: These URL schemata are fix and well known ...
679     //     But there can be some additional ones, which was not
680     //     defined at implementation time of this class :-(
681     //     So we have to make shure, that the following code
682     //     can detect such protocol schemata too :-)
683 
684     if(
685         (!sURL.getLength()                                       ) ||
686         (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_UNO    )) ||
687         (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SLOT   )) ||
688         (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MACRO  )) ||
689         (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SERVICE)) ||
690         (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MAILTO )) ||
691         (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_NEWS   ))
692       )
693     {
694         return E_UNSUPPORTED_CONTENT;
695     }
696 
697     //-------------------------------------------
698     // (ii) Some special URLs indicates a given input stream,
699     //      a full featured document model directly or
700     //      specify a request for opening an empty document.
701     //      Such contents are loadable in general.
702     //      But we have to check, if the media descriptor contains
703     //      all needed resources. If they are missing - the following
704     //      load request will fail.
705 
706     /* Attention: The following code cant work on such special URLs!
707                   It should not break the office .. but it make no sense
708                   to start expensive object creations and complex search
709                   algorithm if its clear, that such URLs must be handled
710                   in a special way .-)
711     */
712 
713     // creation of new documents
714     if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_FACTORY))
715         return E_CAN_BE_LOADED;
716 
717     // using of an existing input stream
718     ::comphelper::MediaDescriptor                 stlMediaDescriptor(lMediaDescriptor);
719     ::comphelper::MediaDescriptor::const_iterator pIt;
720     if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_STREAM))
721     {
722         pIt = stlMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_INPUTSTREAM());
723         css::uno::Reference< css::io::XInputStream > xStream;
724         if (pIt != stlMediaDescriptor.end())
725             pIt->second >>= xStream;
726         if (xStream.is())
727             return E_CAN_BE_LOADED;
728         LOG_WARNING("LoadEnv::classifyContent()", "loading from stream with right URL but invalid stream detected")
729         return E_UNSUPPORTED_CONTENT;
730     }
731 
732     // using of a full featured document
733     if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_OBJECT))
734     {
735         pIt = stlMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_MODEL());
736         css::uno::Reference< css::frame::XModel > xModel;
737         if (pIt != stlMediaDescriptor.end())
738             pIt->second >>= xModel;
739         if (xModel.is())
740             return E_CAN_BE_SET;
741         LOG_WARNING("LoadEnv::classifyContent()", "loading with object with right URL but invalid object detected")
742         return E_UNSUPPORTED_CONTENT;
743     }
744 
745     // following operatons can work on an internal type name only :-(
746     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::utl::getProcessServiceFactory();
747     css::uno::Reference< css::document::XTypeDetection > xDetect(xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY);
748 
749     ::rtl::OUString sType = xDetect->queryTypeByURL(sURL);
750 
751     css::uno::Sequence< css::beans::NamedValue >           lQuery(1)   ;
752     css::uno::Reference< css::container::XContainerQuery > xContainer  ;
753     css::uno::Reference< css::container::XEnumeration >    xSet        ;
754     css::uno::Sequence< ::rtl::OUString >                  lTypesReg(1);
755 
756     /*
757     //-------------------------------------------
758     lQuery[0].Name    = ::framework::constant::Filter::PROP_TYPE;
759     lQuery[0].Value <<= sType;
760 
761     xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_FILTERFACTORY), css::uno::UNO_QUERY);
762     xSet       = xContainer->createSubSetEnumerationByProperties(lQuery);
763     // at least one registered frame loader is enough!
764     if (xSet->hasMoreElements())
765         return E_CAN_BE_LOADED;
766     */
767 
768     //-------------------------------------------
769     // (iii) If a FrameLoader service (or at least
770     //      a Filter) can be found, which supports
771     //      this URL - it must be a loadable content.
772     //      Because both items are registered for types
773     //      its enough to check for frame loaders only.
774     //      Mos of our filters are handled by our global
775     //      default loader. But there exist some specialized
776     //      loader, which does not work on top of filters!
777     //      So its not enough to search on the filter configuration.
778     //      Further its not enough to search for types!
779     //      Because there exist some types, which are referenced by
780     //      other objects ... but not by filters nor frame loaders!
781 
782     lTypesReg[0]      = sType;
783     lQuery[0].Name    = ::framework::constant::FrameLoader::PROP_TYPES;
784     lQuery[0].Value <<= lTypesReg;
785 
786     xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_FRAMELOADERFACTORY), css::uno::UNO_QUERY);
787     xSet       = xContainer->createSubSetEnumerationByProperties(lQuery);
788     // at least one registered frame loader is enough!
789     if (xSet->hasMoreElements())
790         return E_CAN_BE_LOADED;
791 
792     //-------------------------------------------
793     // (iv) Some URL protocols are supported by special services.
794     //      E.g. ContentHandler.
795     //      Such contents can be handled ... but not loaded.
796 
797     lTypesReg[0]      = sType;
798     lQuery[0].Name    = ::framework::constant::ContentHandler::PROP_TYPES;
799     lQuery[0].Value <<= lTypesReg;
800 
801     xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_CONTENTHANDLERFACTORY), css::uno::UNO_QUERY);
802     xSet       = xContainer->createSubSetEnumerationByProperties(lQuery);
803     // at least one registered content handler is enough!
804     if (xSet->hasMoreElements())
805         return E_CAN_BE_HANDLED;
806 
807     //-------------------------------------------
808     // (v) Last but not least the UCB is used inside office to
809     //     load contents. He has a special configuration to know
810     //     which URL schemata can be used inside office.
811     css::uno::Reference< css::ucb::XContentProviderManager > xUCB(xSMGR->createInstance(SERVICENAME_UCBCONTENTBROKER), css::uno::UNO_QUERY);
812     if (xUCB->queryContentProvider(sURL).is())
813         return E_CAN_BE_LOADED;
814 
815     //-------------------------------------------
816     // (TODO) At this point, we have no idea .-)
817     //        But it seems to be better, to break all
818     //        further requests for this URL. Otherwhise
819     //        we can run into some trouble.
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