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