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