LibreOffice Module framework (master) 1
loadenv.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <loadenv/loadenv.hxx>
21
25
27#include <properties.h>
28#include <protocols.h>
29#include <services.h>
30#include <targets.h>
32#include <comphelper/lok.hxx>
37#include <officecfg/Office/Common.hxx>
38#include <officecfg/Setup.hxx>
39
40#include <com/sun/star/awt/XWindow2.hpp>
41#include <com/sun/star/beans/XPropertySet.hpp>
42#include <com/sun/star/container/XNameAccess.hpp>
43#include <com/sun/star/container/XEnumeration.hpp>
44#include <com/sun/star/document/MacroExecMode.hpp>
45#include <com/sun/star/document/XTypeDetection.hpp>
46#include <com/sun/star/document/XActionLockable.hpp>
47#include <com/sun/star/document/UpdateDocMode.hpp>
48#include <com/sun/star/frame/Desktop.hpp>
49#include <com/sun/star/frame/OfficeFrameLoader.hpp>
50#include <com/sun/star/frame/XModel.hpp>
51#include <com/sun/star/frame/XFrameLoader.hpp>
52#include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
53#include <com/sun/star/frame/XNotifyingDispatch.hpp>
54#include <com/sun/star/frame/FrameLoaderFactory.hpp>
55#include <com/sun/star/frame/ContentHandlerFactory.hpp>
56#include <com/sun/star/frame/DispatchResultState.hpp>
57#include <com/sun/star/frame/FrameSearchFlag.hpp>
58#include <com/sun/star/frame/XDispatchProvider.hpp>
59#include <com/sun/star/lang/IllegalArgumentException.hpp>
60#include <com/sun/star/lang/XInitialization.hpp>
61#include <com/sun/star/lang/DisposedException.hpp>
62#include <com/sun/star/io/XInputStream.hpp>
63#include <com/sun/star/task/XInteractionHandler.hpp>
64#include <com/sun/star/task/ErrorCodeRequest.hpp>
65#include <com/sun/star/task/InteractionHandler.hpp>
66#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
67#include <com/sun/star/task/XStatusIndicator.hpp>
68#include <com/sun/star/uno/RuntimeException.hpp>
69#include <com/sun/star/ucb/UniversalContentBroker.hpp>
70#include <com/sun/star/util/CloseVetoException.hpp>
71#include <com/sun/star/util/URLTransformer.hpp>
72#include <com/sun/star/util/XURLTransformer.hpp>
73#include <com/sun/star/util/XCloseable.hpp>
74#include <com/sun/star/util/XModifiable.hpp>
75
76#include <utility>
77#include <vcl/window.hxx>
78#include <vcl/wrkwin.hxx>
79#include <vcl/syswin.hxx>
80
83#include <svtools/sfxecode.hxx>
86#include <rtl/bootstrap.hxx>
87#include <sal/log.hxx>
89#include <vcl/svapp.hxx>
93#include <tools/fileutil.hxx>
94
95constexpr OUStringLiteral PROP_TYPES = u"Types";
96constexpr OUStringLiteral PROP_NAME = u"Name";
97
98namespace framework {
99
100using namespace com::sun::star;
101
102namespace {
103
104class LoadEnvListener : public ::cppu::WeakImplHelper< css::frame::XLoadEventListener ,
105 css::frame::XDispatchResultListener >
106{
107 private:
108 std::mutex m_mutex;
110 LoadEnv* m_pLoadEnv;
111
112 public:
113
114 explicit LoadEnvListener(LoadEnv* pLoadEnv)
115 : m_bWaitingResult(true)
116 , m_pLoadEnv(pLoadEnv)
117 {
118 }
119
120 // frame.XLoadEventListener
121 virtual void SAL_CALL loadFinished(const css::uno::Reference< css::frame::XFrameLoader >& xLoader) override;
122
123 virtual void SAL_CALL loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >& xLoader) override;
124
125 // frame.XDispatchResultListener
126 virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& aEvent) override;
127
128 // lang.XEventListener
129 virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) override;
130};
131
132}
133
134LoadEnv::LoadEnv(css::uno::Reference< css::uno::XComponentContext > xContext)
135 : m_xContext(std::move(xContext))
136 , m_nSearchFlags(0)
137 , m_eFeature(LoadEnvFeatures::NONE)
138 , m_eContentType(E_UNSUPPORTED_CONTENT)
139 , m_bCloseFrameOnError(false)
140 , m_bReactivateControllerOnError(false)
141 , m_bLoaded( false )
142{
143}
144
146{
147}
148
149css::uno::Reference< css::lang::XComponent > LoadEnv::loadComponentFromURL(const css::uno::Reference< css::frame::XComponentLoader >& xLoader,
150 const css::uno::Reference< css::uno::XComponentContext >& xContext ,
151 const OUString& sURL ,
152 const OUString& sTarget,
153 sal_Int32 nSearchFlags ,
154 const css::uno::Sequence< css::beans::PropertyValue >& lArgs )
155{
156 css::uno::Reference< css::lang::XComponent > xComponent;
157 comphelper::ProfileZone aZone("loadComponentFromURL");
158
159 try
160 {
161 LoadEnv aEnv(xContext);
162
164 // tdf#118238 Only disable UI interaction when loading as hidden
166 loadEnvFeatures = LoadEnvFeatures::NONE;
167
168 aEnv.startLoading(sURL,
169 lArgs,
170 css::uno::Reference< css::frame::XFrame >(xLoader, css::uno::UNO_QUERY),
171 sTarget,
172 nSearchFlags,
173 loadEnvFeatures);
174 aEnv.waitWhileLoading(); // wait for ever!
175
176 xComponent = aEnv.getTargetComponent();
177 }
178 catch(const LoadEnvException& ex)
179 {
180 switch(ex.m_nID)
181 {
183 throw css::lang::IllegalArgumentException(
184 "Optional list of arguments seem to be corrupted.", xLoader, 4);
185
187 throw css::lang::IllegalArgumentException(
188 "Unsupported URL <" + sURL + ">: \"" + ex.m_sMessage + "\"",
189 xLoader, 1);
190
191 default:
192 SAL_WARN(
193 "fwk.loadenv",
194 "caught LoadEnvException " << +ex.m_nID << " \""
195 << ex.m_sMessage << "\""
196 << (ex.m_exOriginal.has<css::uno::Exception>()
197 ? (", " + ex.m_exOriginal.getValueTypeName() + " \""
198 + (ex.m_exOriginal.get<css::uno::Exception>().
199 Message)
200 + "\"")
201 : OUString())
202 << " while loading <" << sURL << ">");
203 xComponent.clear();
204 break;
205 }
206 }
207
208 return xComponent;
209}
210
211namespace {
212
213utl::MediaDescriptor addModelArgs(const uno::Sequence<beans::PropertyValue>& rDescriptor)
214{
215 utl::MediaDescriptor rResult(rDescriptor);
216 uno::Reference<frame::XModel> xModel(rResult.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_MODEL, uno::Reference<frame::XModel>()));
217
218 if (xModel.is())
219 {
220 utl::MediaDescriptor aModelArgs(xModel->getArgs());
221 utl::MediaDescriptor::iterator pIt = aModelArgs.find( utl::MediaDescriptor::PROP_MACROEXECUTIONMODE);
222 if (pIt != aModelArgs.end())
224 }
225
226 return rResult;
227}
228
229}
230
231void LoadEnv::startLoading(const OUString& sURL, const uno::Sequence<beans::PropertyValue>& lMediaDescriptor,
232 const uno::Reference<frame::XFrame>& xBaseFrame, const OUString& sTarget,
233 sal_Int32 nSearchFlags, LoadEnvFeatures eFeature)
234{
235 osl::MutexGuard g(m_mutex);
236
237 // Handle still running processes!
238 if (m_xAsynchronousJob.is())
240
241 // take over all new parameters.
242 m_xTargetFrame.clear();
243 m_xBaseFrame = xBaseFrame;
244 m_lMediaDescriptor = addModelArgs(lMediaDescriptor);
245 m_sTarget = sTarget;
246 m_nSearchFlags = nSearchFlags;
247 m_eFeature = eFeature;
249 m_bCloseFrameOnError = false;
251 m_bLoaded = false;
252
253 OUString aRealURL;
254 if (!officecfg::Office::Common::Load::DetectWebDAVRedirection::get()
255 || !tools::IsMappedWebDAVPath(sURL, &aRealURL))
256 aRealURL = sURL;
257
258 // try to find out, if it's really a content, which can be loaded or must be "handled"
259 // We use a default value for this in-parameter. Then we have to start a complex check method
260 // internally. But if this check was already done outside it can be suppressed to perform
261 // the load request. We take over the result then!
262 m_eContentType = LoadEnv::classifyContent(aRealURL, lMediaDescriptor);
264 throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT, "from LoadEnv::startLoading");
265
266 // make URL part of the MediaDescriptor
267 // It doesn't matter if it is already an item of it.
268 // It must be the same value... so we can overwrite it :-)
270
271 // parse it - because some following code require that
272 m_aURL.Complete = aRealURL;
273 uno::Reference<util::XURLTransformer> xParser(util::URLTransformer::create(m_xContext));
274 xParser->parseStrict(m_aURL);
275
276 // BTW: Split URL and JumpMark ...
277 // Because such mark is an explicit value of the media descriptor!
278 if (!m_aURL.Mark.isEmpty())
280
281 // By the way: remove the old and deprecated value "FileName" from the descriptor!
282 utl::MediaDescriptor::iterator pIt = m_lMediaDescriptor.find(utl::MediaDescriptor::PROP_FILENAME);
283 if (pIt != m_lMediaDescriptor.end())
284 m_lMediaDescriptor.erase(pIt);
285
286 // patch the MediaDescriptor, so it fulfil the outside requirements
287 // Means especially items like e.g. UI InteractionHandler, Status Indicator,
288 // MacroExecutionMode, etc.
289
290 /*TODO progress is bound to a frame ... How can we set it here? */
291
292 // UI mode
293 const bool bUIMode =
295 !m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_HIDDEN, false) &&
296 !m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_PREVIEW, false);
297
299 m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_SILENT, false))
300 {
301 rtl::Reference<QuietInteraction> pQuietInteraction = new QuietInteraction();
302 uno::Reference<task::XInteractionHandler> xInteractionHandler(pQuietInteraction);
304 }
305
307
308 start();
309}
310
311void LoadEnv::initializeUIDefaults( const css::uno::Reference< css::uno::XComponentContext >& i_rxContext,
312 utl::MediaDescriptor& io_lMediaDescriptor, const bool i_bUIMode,
313 rtl::Reference<QuietInteraction>* o_ppQuietInteraction )
314{
315 css::uno::Reference< css::task::XInteractionHandler > xInteractionHandler;
316 sal_Int16 nMacroMode;
317 sal_Int16 nUpdateMode;
318
319 if ( i_bUIMode )
320 {
321 nMacroMode = css::document::MacroExecMode::USE_CONFIG;
322 nUpdateMode = css::document::UpdateDocMode::ACCORDING_TO_CONFIG;
323 try
324 {
325 // tdf#154308 At least for the case the document is launched from the StartCenter, put that StartCenter as the
326 // parent for any dialogs that may appear during typedetection (once load starts a permanent frame will be set
327 // anyway and used as dialog parent, which will be this one if the startcenter was running)
328 css::uno::Reference<css::frame::XFramesSupplier> xSupplier = css::frame::Desktop::create(i_rxContext);
329 FrameListAnalyzer aTasksAnalyzer(xSupplier, css::uno::Reference<css::frame::XFrame>(), FrameAnalyzerFlags::BackingComponent);
330 css::uno::Reference<css::awt::XWindow> xDialogParent(aTasksAnalyzer.m_xBackingComponent ?
331 aTasksAnalyzer.m_xBackingComponent->getContainerWindow() :
332 nullptr);
333
334 xInteractionHandler.set( css::task::InteractionHandler::createWithParent(i_rxContext, xDialogParent), css::uno::UNO_QUERY_THROW );
335 }
336 catch(const css::uno::RuntimeException&) {throw;}
337 catch(const css::uno::Exception& ) { }
338 }
339 // hidden mode
340 else
341 {
342 nMacroMode = css::document::MacroExecMode::NEVER_EXECUTE;
343 nUpdateMode = css::document::UpdateDocMode::NO_UPDATE;
344 rtl::Reference<QuietInteraction> pQuietInteraction = new QuietInteraction();
345 xInteractionHandler = pQuietInteraction.get();
346 if ( o_ppQuietInteraction != nullptr )
347 {
348 *o_ppQuietInteraction = pQuietInteraction;
349 }
350 }
351
352 if ( xInteractionHandler.is() )
353 {
354 if( io_lMediaDescriptor.find(utl::MediaDescriptor::PROP_INTERACTIONHANDLER) == io_lMediaDescriptor.end() )
355 {
356 io_lMediaDescriptor[utl::MediaDescriptor::PROP_INTERACTIONHANDLER] <<= xInteractionHandler;
357 }
358 if( io_lMediaDescriptor.find(utl::MediaDescriptor::PROP_AUTHENTICATIONHANDLER) == io_lMediaDescriptor.end() )
359 {
360 io_lMediaDescriptor[utl::MediaDescriptor::PROP_AUTHENTICATIONHANDLER] <<= xInteractionHandler;
361 }
362 }
363
364 if (io_lMediaDescriptor.find(utl::MediaDescriptor::PROP_MACROEXECUTIONMODE) == io_lMediaDescriptor.end())
365 io_lMediaDescriptor[utl::MediaDescriptor::PROP_MACROEXECUTIONMODE] <<= nMacroMode;
366
367 if (io_lMediaDescriptor.find(utl::MediaDescriptor::PROP_UPDATEDOCMODE) == io_lMediaDescriptor.end())
368 io_lMediaDescriptor[utl::MediaDescriptor::PROP_UPDATEDOCMODE] <<= nUpdateMode;
369}
370
372{
373 // SAFE ->
374 {
375 osl::MutexGuard aReadLock(m_mutex);
376
377 // Handle still running processes!
378 if (m_xAsynchronousJob.is())
380
381 // content can not be loaded or handled
382 // check "classifyContent()" failed before ...
385 "from LoadEnv::start");
386 }
387 // <- SAFE
388
389 // detect its type/filter etc.
390 // This information will be available by the
391 // used descriptor member afterwards and is needed
392 // for all following operations!
393 // Note: An exception will be thrown, in case operation was not successfully ...
394 if (m_eContentType != E_CAN_BE_SET)/* Attention: special feature to set existing component on a frame must ignore type detection! */
396
397 // start loading the content...
398 // Attention: Don't check m_eContentType deeper then UNSUPPORTED/SUPPORTED!
399 // Because it was made in the easiest way... may a flat detection was made only.
400 // And such simple detection can fail sometimes .-)
401 // Use another strategy here. Try it and let it run into the case "loading not possible".
402 bool bStarted = false;
403 if (
405 (m_eContentType != E_CAN_BE_SET ) /* Attention: special feature to set existing component on a frame must ignore type detection! */
406 )
407 {
408 bStarted = impl_handleContent();
409 }
410
411 if (!bStarted)
412 bStarted = impl_loadContent();
413
414 // not started => general error
415 // We can't say - what was the reason for.
416 if (!bStarted)
417 throw LoadEnvException(
419}
420
421/*-----------------------------------------------
422 TODO
423 First draft does not implement timeout using [ms].
424 Current implementation counts yield calls only ...
425-----------------------------------------------*/
426bool LoadEnv::waitWhileLoading(sal_uInt32 nTimeout)
427{
428 // Because it's not a good idea to block the main thread
429 // (and we can't be sure that we are currently not used inside the
430 // main thread!), we can't use conditions here really. We must yield
431 // in an intelligent manner :-)
432
433 sal_Int32 nTime = nTimeout;
434 while(!Application::IsQuit())
435 {
436 // SAFE -> ------------------------------
437 {
438 osl::MutexGuard aReadLock1(m_mutex);
439 if (!m_xAsynchronousJob.is())
440 break;
441 }
442 // <- SAFE ------------------------------
443
445
446 // forever!
447 if (nTimeout==0)
448 continue;
449
450 // timed out?
451 --nTime;
452 if (nTime<1)
453 break;
454 }
455
456 osl::MutexGuard g(m_mutex);
457 return !m_xAsynchronousJob.is();
458}
459
460css::uno::Reference< css::lang::XComponent > LoadEnv::getTargetComponent() const
461{
462 osl::MutexGuard g(m_mutex);
463
464 if (!m_xTargetFrame.is())
465 return css::uno::Reference< css::lang::XComponent >();
466
467 css::uno::Reference< css::frame::XController > xController = m_xTargetFrame->getController();
468 if (!xController.is())
469 return m_xTargetFrame->getComponentWindow();
470
471 css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
472 if (!xModel.is())
473 return xController;
474
475 return xModel;
476}
477
478void SAL_CALL LoadEnvListener::loadFinished(const css::uno::Reference< css::frame::XFrameLoader >&)
479{
480 std::unique_lock g(m_mutex);
483 m_bWaitingResult = false;
484}
485
486void SAL_CALL LoadEnvListener::loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >&)
487{
488 std::unique_lock g(m_mutex);
491 m_bWaitingResult = false;
492}
493
494void SAL_CALL LoadEnvListener::dispatchFinished(const css::frame::DispatchResultEvent& aEvent)
495{
496 std::unique_lock g(m_mutex);
497
498 if (!m_bWaitingResult)
499 return;
500
501 switch(aEvent.State)
502 {
503 case css::frame::DispatchResultState::FAILURE :
505 break;
506
507 case css::frame::DispatchResultState::SUCCESS :
509 break;
510
511 case css::frame::DispatchResultState::DONTKNOW :
513 break;
514 }
515 m_bWaitingResult = false;
516}
517
518void SAL_CALL LoadEnvListener::disposing(const css::lang::EventObject&)
519{
520 std::unique_lock g(m_mutex);
523 m_bWaitingResult = false;
524}
525
526void LoadEnv::impl_setResult(bool bResult)
527{
528 osl::MutexGuard g(m_mutex);
529
530 m_bLoaded = bResult;
531
533
534 // clearing of this reference will unblock waitWhileLoading()!
535 // So we must be sure, that loading process was really finished.
536 // => do it as last operation of this method ...
537 m_xAsynchronousJob.clear();
538}
539
540/*-----------------------------------------------
541 TODO: Is it a good idea to change Sequence<>
542 parameter to stl-adapter?
543-----------------------------------------------*/
545 const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor)
546{
547
548 // (i) Filter some special well known URL protocols,
549 // which can not be handled or loaded in general.
550 // Of course an empty URL must be ignored here too.
551 // Note: These URL schemata are fix and well known ...
552 // But there can be some additional ones, which was not
553 // defined at implementation time of this class :-(
554 // So we have to make sure, that the following code
555 // can detect such protocol schemata too :-)
556
557 if(
558 (sURL.isEmpty() ) ||
565 )
566 {
568 }
569
570 // (ii) Some special URLs indicates a given input stream,
571 // a full featured document model directly or
572 // specify a request for opening an empty document.
573 // Such contents are loadable in general.
574 // But we have to check, if the media descriptor contains
575 // all needed resources. If they are missing - the following
576 // load request will fail.
577
578 /* Attention: The following code can't work on such special URLs!
579 It should not break the office... but it makes no sense
580 to start expensive object creations and complex search
581 algorithm if it's clear, that such URLs must be handled
582 in a special way .-)
583 */
584
585 // creation of new documents
587 return E_CAN_BE_LOADED;
588
589 // using of an existing input stream
590 utl::MediaDescriptor stlMediaDescriptor(lMediaDescriptor);
591 utl::MediaDescriptor::const_iterator pIt;
593 {
594 pIt = stlMediaDescriptor.find(utl::MediaDescriptor::PROP_INPUTSTREAM);
595 css::uno::Reference< css::io::XInputStream > xStream;
596 if (pIt != stlMediaDescriptor.end())
597 pIt->second >>= xStream;
598 if (xStream.is())
599 return E_CAN_BE_LOADED;
600 SAL_INFO("fwk.loadenv", "LoadEnv::classifyContent(): loading from stream with right URL but invalid stream detected");
602 }
603
604 // using of a full featured document
606 {
607 pIt = stlMediaDescriptor.find(utl::MediaDescriptor::PROP_MODEL);
608 css::uno::Reference< css::frame::XModel > xModel;
609 if (pIt != stlMediaDescriptor.end())
610 pIt->second >>= xModel;
611 if (xModel.is())
612 return E_CAN_BE_SET;
613 SAL_INFO("fwk.loadenv", "LoadEnv::classifyContent(): loading with object with right URL but invalid object detected");
615 }
616
617 // following operations can work on an internal type name only :-(
618 css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
619 css::uno::Reference< css::document::XTypeDetection > xDetect(
620 xContext->getServiceManager()->createInstanceWithContext(
621 "com.sun.star.document.TypeDetection", xContext),
622 css::uno::UNO_QUERY_THROW);
623
624 OUString sType = xDetect->queryTypeByURL(sURL);
625
626 css::uno::Reference< css::frame::XLoaderFactory > xLoaderFactory;
627 css::uno::Reference< css::container::XEnumeration > xSet;
628
629 // (iii) If a FrameLoader service (or at least
630 // a Filter) can be found, which supports
631 // this URL - it must be a loadable content.
632 // Because both items are registered for types
633 // it's enough to check for frame loaders only.
634 // Most of our filters are handled by our global
635 // default loader. But there exist some specialized
636 // loader, which does not work on top of filters!
637 // So it's not enough to search on the filter configuration.
638 // Further it's not enough to search for types!
639 // Because there exist some types, which are referenced by
640 // other objects... but neither by filters nor frame loaders!
641 css::uno::Sequence< OUString > lTypesReg { sType };
642 css::uno::Sequence< css::beans::NamedValue > lQuery
643 {
644 css::beans::NamedValue(PROP_TYPES, css::uno::Any(lTypesReg))
645 };
646
647 xLoaderFactory = css::frame::FrameLoaderFactory::create(xContext);
648 xSet = xLoaderFactory->createSubSetEnumerationByProperties(lQuery);
649 // at least one registered frame loader is enough!
650 if (xSet->hasMoreElements())
651 return E_CAN_BE_LOADED;
652
653 // (iv) Some URL protocols are supported by special services.
654 // E.g. ContentHandler.
655 // Such contents can be handled ... but not loaded.
656
657 xLoaderFactory = css::frame::ContentHandlerFactory::create(xContext);
658 xSet = xLoaderFactory->createSubSetEnumerationByProperties(lQuery);
659 // at least one registered content handler is enough!
660 if (xSet->hasMoreElements())
661 return E_CAN_BE_HANDLED;
662
663 // (v) Last but not least the UCB is used inside office to
664 // load contents. He has a special configuration to know
665 // which URL schemata can be used inside office.
666 css::uno::Reference< css::ucb::XUniversalContentBroker > xUCB(css::ucb::UniversalContentBroker::create(xContext));
667 if (xUCB->queryContentProvider(sURL).is())
668 return E_CAN_BE_LOADED;
669
670 // (TODO) At this point, we have no idea .-)
671 // But it seems to be better, to break all
672 // further requests for this URL. Otherwise
673 // we can run into some trouble.
675}
676
677namespace {
678
679bool queryOrcusTypeAndFilter(const uno::Sequence<beans::PropertyValue>& rDescriptor, OUString& rType, OUString& rFilter)
680{
681 OUString aURL;
682 sal_Int32 nSize = rDescriptor.getLength();
683 for (sal_Int32 i = 0; i < nSize; ++i)
684 {
685 const beans::PropertyValue& rProp = rDescriptor[i];
686 if (rProp.Name == "URL")
687 {
688 rProp.Value >>= aURL;
689 break;
690 }
691 }
692
693 if (aURL.isEmpty() || o3tl::equalsIgnoreAsciiCase(aURL.subView(0,8), u"private:"))
694 return false;
695
696 // TODO : Type must be set to be generic_Text (or any other type that
697 // exists) in order to find a usable loader. Exploit it as a temporary
698 // hack.
699
700 // depending on the experimental mode
701 if (!officecfg::Office::Common::Misc::ExperimentalMode::get())
702 {
703 return false;
704 }
705
706 OUString aUseOrcus;
707 rtl::Bootstrap::get("LIBO_USE_ORCUS", aUseOrcus);
708 bool bUseOrcus = (aUseOrcus == "YES");
709
710 if (!bUseOrcus)
711 return false;
712
713 if (aURL.endsWith(".xlsx"))
714 {
715 rType = "generic_Text";
716 rFilter = "xlsx";
717 return true;
718 }
719 else if (aURL.endsWith(".ods"))
720 {
721 rType = "generic_Text";
722 rFilter = "ods";
723 return true;
724 }
725 else if (aURL.endsWith(".csv"))
726 {
727 rType = "generic_Text";
728 rFilter = "csv";
729 return true;
730 }
731
732 return false;
733}
734
735}
736
738{
739 static const sal_Int32 FILTERFLAG_TEMPLATEPATH = 16;
740
741 // SAFE ->
742 osl::ClearableMutexGuard aReadLock(m_mutex);
743
744 // Attention: Because our stl media descriptor is a copy of a uno sequence
745 // we can't use as an in/out parameter here. Copy it before and don't forget to
746 // update structure afterwards again!
747 css::uno::Sequence< css::beans::PropertyValue > lDescriptor = m_lMediaDescriptor.getAsConstPropertyValueList();
748 css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
749
750 aReadLock.clear();
751 // <- SAFE
752
753 OUString sType, sFilter;
754
755 if (queryOrcusTypeAndFilter(lDescriptor, sType, sFilter) && !sType.isEmpty() && !sFilter.isEmpty())
756 {
757 // SAFE ->
758 osl::MutexGuard aWriteLock(m_mutex);
759
760 // Orcus type detected. Skip the normal type detection process.
761 m_lMediaDescriptor << lDescriptor;
765 m_lMediaDescriptor[utl::MediaDescriptor::PROP_DOCUMENTSERVICE] <<= OUString("com.sun.star.sheet.SpreadsheetDocument");
766 return;
767 // <- SAFE
768 }
769
770 css::uno::Reference< css::document::XTypeDetection > xDetect(
771 xContext->getServiceManager()->createInstanceWithContext(
772 "com.sun.star.document.TypeDetection", xContext),
773 css::uno::UNO_QUERY_THROW);
774 sType = xDetect->queryTypeByDescriptor(lDescriptor, true); /*TODO should deep detection be able for enable/disable it from outside? */
775
776 // no valid content -> loading not possible
777 if (sType.isEmpty())
778 throw LoadEnvException(
779 LoadEnvException::ID_UNSUPPORTED_CONTENT, "type detection failed");
780
781 // SAFE ->
782 osl::ResettableMutexGuard aWriteLock(m_mutex);
783
784 // detection was successful => update the descriptor member of this class
785 m_lMediaDescriptor << lDescriptor;
787 // Is there an already detected (may be preselected) filter?
788 // see below ...
789 sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_FILTERNAME, OUString());
790
791 aWriteLock.clear();
792 // <- SAFE
793
794 // We do have potentially correct type, but the detection process was aborted.
795 if (m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_ABORTED, false))
796 throw LoadEnvException(
797 LoadEnvException::ID_UNSUPPORTED_CONTENT, "type detection aborted");
798
799 // But the type isn't enough. For loading sometimes we need more information.
800 // E.g. for our "_default" feature, where we recycle any frame which contains
801 // and "Untitled" document, we must know if the new document is based on a template!
802 // But this information is available as a filter property only.
803 // => We must try(!) to detect the right filter for this load request.
804 // On the other side ... if no filter is available .. ignore it.
805 // Then the type information must be enough.
806 if (sFilter.isEmpty())
807 {
808 // no -> try to find a preferred filter for the detected type.
809 // Don't forget to update the media descriptor.
810 css::uno::Reference< css::container::XNameAccess > xTypeCont(xDetect, css::uno::UNO_QUERY_THROW);
811 try
812 {
813 ::comphelper::SequenceAsHashMap lTypeProps(xTypeCont->getByName(sType));
814 sFilter = lTypeProps.getUnpackedValueOrDefault("PreferredFilter", OUString());
815 if (!sFilter.isEmpty())
816 {
817 // SAFE ->
818 aWriteLock.reset();
820 aWriteLock.clear();
821 // <- SAFE
822 }
823 }
824 catch(const css::container::NoSuchElementException&)
825 {}
826 }
827
828 // check if the filter (if one exists) points to a template format filter.
829 // Then we have to add the property "AsTemplate".
830 // We need this information to decide afterwards if we can use a "recycle frame"
831 // for target "_default" or has to create a new one every time.
832 // On the other side we have to suppress that, if this property already exists
833 // and should trigger a special handling. Then the outside call of this method here,
834 // has to know, what he is doing .-)
835
836 bool bIsOwnTemplate = false;
837 if (!sFilter.isEmpty())
838 {
839 css::uno::Reference< css::container::XNameAccess > xFilterCont(xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_FILTERFACTORY, xContext), css::uno::UNO_QUERY_THROW);
840 try
841 {
842 ::comphelper::SequenceAsHashMap lFilterProps(xFilterCont->getByName(sFilter));
843 sal_Int32 nFlags = lFilterProps.getUnpackedValueOrDefault("Flags", sal_Int32(0));
844 bIsOwnTemplate = ((nFlags & FILTERFLAG_TEMPLATEPATH) == FILTERFLAG_TEMPLATEPATH);
845 }
846 catch(const css::container::NoSuchElementException&)
847 {}
848 }
849 if (bIsOwnTemplate)
850 {
851 // SAFE ->
852 aWriteLock.reset();
853 // Don't overwrite external decisions! See comments before ...
854 utl::MediaDescriptor::const_iterator pAsTemplateItem = m_lMediaDescriptor.find(utl::MediaDescriptor::PROP_ASTEMPLATE);
855 if (pAsTemplateItem == m_lMediaDescriptor.end())
857 aWriteLock.clear();
858 // <- SAFE
859 }
860}
861
863{
864 // SAFE -> -----------------------------------
865 osl::ClearableMutexGuard aReadLock(m_mutex);
866
867 // the type must exist inside the descriptor ... otherwise this class is implemented wrong :-)
868 OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_TYPENAME, OUString());
869 if (sType.isEmpty())
871
872 // convert media descriptor and URL to right format for later interface call!
873 css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
874 m_lMediaDescriptor >> lDescriptor;
875 css::util::URL aURL = m_aURL;
876
877 // get necessary container to query for a handler object
878 css::uno::Reference< css::frame::XLoaderFactory > xLoaderFactory = css::frame::ContentHandlerFactory::create(m_xContext);
879
880 aReadLock.clear();
881 // <- SAFE -----------------------------------
882
883 // query
884 css::uno::Sequence< OUString > lTypeReg { sType };
885
886 css::uno::Sequence< css::beans::NamedValue > lQuery { { PROP_TYPES, css::uno::Any(lTypeReg) } };
887
888 css::uno::Reference< css::container::XEnumeration > xSet = xLoaderFactory->createSubSetEnumerationByProperties(lQuery);
889 while(xSet->hasMoreElements())
890 {
891 ::comphelper::SequenceAsHashMap lProps (xSet->nextElement());
892 OUString sHandler = lProps.getUnpackedValueOrDefault(PROP_NAME, OUString());
893
894 css::uno::Reference< css::frame::XNotifyingDispatch > xHandler;
895 try
896 {
897 xHandler.set(xLoaderFactory->createInstance(sHandler), css::uno::UNO_QUERY);
898 if (!xHandler.is())
899 continue;
900 }
901 catch(const css::uno::RuntimeException&)
902 { throw; }
903 catch(const css::uno::Exception&)
904 { continue; }
905
906 // SAFE -> -----------------------------------
907 osl::ClearableMutexGuard aWriteLock(m_mutex);
908 m_xAsynchronousJob = xHandler;
909 rtl::Reference<LoadEnvListener> xListener = new LoadEnvListener(this);
910 aWriteLock.clear();
911 // <- SAFE -----------------------------------
912
913 xHandler->dispatchWithNotification(aURL, lDescriptor, xListener);
914
915 return true;
916 }
917
918 return false;
919}
920
922{
923 // SAFE ->
924 osl::ResettableMutexGuard aReadLock(m_mutex);
925 css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
926 aReadLock.clear();
927 // <- SAFE
928
929 bool bAllowed = true;
930
931 try
932 {
933 std::optional<sal_Int32> x(officecfg::Office::Common::Misc::MaxOpenDocuments::get());
934
935 // NIL means: count of allowed documents = infinite !
936 // => return true
937 if ( !x)
938 bAllowed = true;
939 else
940 {
941 sal_Int32 nMaxOpenDocuments(*x);
942
943 css::uno::Reference< css::frame::XFramesSupplier > xDesktop(
944 css::frame::Desktop::create(xContext),
945 css::uno::UNO_QUERY_THROW);
946
947 FrameListAnalyzer aAnalyzer(xDesktop,
948 css::uno::Reference< css::frame::XFrame >(),
952
953 sal_Int32 nOpenDocuments = aAnalyzer.m_lOtherVisibleFrames.size();
954 bAllowed = (nOpenDocuments < nMaxOpenDocuments);
955 }
956 }
957 catch(const css::uno::Exception&)
958 { bAllowed = true; } // !! internal errors are no reason to disturb the office from opening documents .-)
959
960 if ( ! bAllowed )
961 {
962 // SAFE ->
963 aReadLock.reset();
964 css::uno::Reference< css::task::XInteractionHandler > xInteraction = m_lMediaDescriptor.getUnpackedValueOrDefault(
966 css::uno::Reference< css::task::XInteractionHandler >());
967 aReadLock.clear();
968 // <- SAFE
969
970 if (xInteraction.is())
971 {
972 css::uno::Any aInteraction;
973
976
977 css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations{
978 pAbort, pApprove
979 };
980
981 css::task::ErrorCodeRequest aErrorCode;
982 aErrorCode.ErrCode = sal_uInt32(ERRCODE_SFX_NOMOREDOCUMENTSALLOWED);
983 aInteraction <<= aErrorCode;
984 xInteraction->handle( InteractionRequest::CreateRequest(aInteraction, lContinuations) );
985 }
986 }
987
988 return bAllowed;
989}
990
992{
993 //show the frame now so it can be the parent for any message dialogs shown during import
994
995 //unless (tdf#114648) an Interactive case such as the new database wizard
996 if (m_aURL.Arguments == "Interactive")
997 return true;
998
999 // unless (tdf#116277) it's the labels/business cards slave frame
1000 if (m_aURL.Arguments.indexOf("slot=") != -1)
1001 return true;
1002
1003 OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_FILTERNAME, OUString());
1004 if (sFilter.isEmpty())
1005 return false;
1006
1007 // unless (tdf#115683) the filter has a UIComponent
1008 OUString sUIComponent;
1009 css::uno::Reference<css::container::XNameAccess> xFilterCont(m_xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_FILTERFACTORY, m_xContext),
1010 css::uno::UNO_QUERY_THROW);
1011 try
1012 {
1013 ::comphelper::SequenceAsHashMap lFilterProps(xFilterCont->getByName(sFilter));
1014 sUIComponent = lFilterProps.getUnpackedValueOrDefault("UIComponent", OUString());
1015 }
1016 catch(const css::container::NoSuchElementException&)
1017 {
1018 }
1019
1020 return !sUIComponent.isEmpty();
1021}
1022
1024{
1025 // SAFE -> -----------------------------------
1026 osl::ClearableMutexGuard aWriteLock(m_mutex);
1027
1028 // search or create right target frame
1029 OUString sTarget = m_sTarget;
1031 {
1033 if (m_xTargetFrame.is())
1034 {
1035 impl_setResult(true);
1036 return true;
1037 }
1039 }
1040
1041 if (! m_xTargetFrame.is())
1042 {
1043 if (
1046 )
1047 {
1049 return false;
1050 TaskCreator aCreator(m_xContext);
1053 }
1054 else
1055 {
1056 sal_Int32 nSearchFlags = m_nSearchFlags & ~css::frame::FrameSearchFlag::CREATE;
1057 m_xTargetFrame = m_xBaseFrame->findFrame(sTarget, nSearchFlags);
1058 if (! m_xTargetFrame.is())
1059 {
1061 return false;
1064 }
1065 }
1066 }
1067
1068 // If we couldn't find a valid frame or the frame has no container window
1069 // we have to throw an exception.
1070 if (
1071 ( ! m_xTargetFrame.is() ) ||
1072 ( ! m_xTargetFrame->getContainerWindow().is() )
1073 )
1075
1076 css::uno::Reference< css::frame::XFrame > xTargetFrame = m_xTargetFrame;
1077
1078 // Now we have a valid frame ... and type detection was already done.
1079 // We should apply the module dependent window position and size to the
1080 // frame window.
1081 impl_applyPersistentWindowState(xTargetFrame->getContainerWindow());
1082
1083 // Don't forget to lock task for following load process. Otherwise it could die
1084 // during this operation runs by terminating the office or closing this task via api.
1085 // If we set this lock "close()" will return false and closing will be broken.
1086 // Attention: Don't forget to reset this lock again after finishing operation.
1087 // Otherwise task AND office couldn't die!!!
1088 // This includes gracefully handling of Exceptions (Runtime!) too ...
1089 // That's why we use a specialized guard, which will reset the lock
1090 // if it will be run out of scope.
1091
1092 // Note further: ignore if this internal guard already contains a resource.
1093 // Might impl_searchRecycleTarget() set it before. But in case this impl-method wasn't used
1094 // and the target frame was new created ... this lock here must be set!
1095 css::uno::Reference< css::document::XActionLockable > xTargetLock(xTargetFrame, css::uno::UNO_QUERY);
1096 m_aTargetLock.setResource(xTargetLock);
1097
1098 // Add status indicator to descriptor. Loader can show a progress then.
1099 // But don't do it, if loading should be hidden or preview is used...!
1100 // So we prevent our code against wrong using. Why?
1101 // It could be, that using of this progress could make trouble. e.g. He makes window visible...
1102 // but shouldn't do that. But if no indicator is available... nobody has a chance to do that!
1103 bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_HIDDEN, false);
1104 bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_MINIMIZED, false);
1105 bool bPreview = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_PREVIEW, false);
1106
1107 if (!bHidden && !bMinimized && !bPreview)
1108 {
1109 css::uno::Reference<css::task::XStatusIndicator> xProgress = m_lMediaDescriptor.getUnpackedValueOrDefault(
1110 utl::MediaDescriptor::PROP_STATUSINDICATOR, css::uno::Reference<css::task::XStatusIndicator>());
1111 if (!xProgress.is())
1112 {
1113 // Note: it's an optional interface!
1114 css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xTargetFrame, css::uno::UNO_QUERY);
1115 if (xProgressFactory.is())
1116 {
1117 xProgress = xProgressFactory->createStatusIndicator();
1118 if (xProgress.is())
1120 }
1121 }
1122
1123 // Now that we have a target window into which we can load, reinit the interaction handler to have this
1124 // window as its parent for modal dialogs and ensure the window is visible
1125 css::uno::Reference< css::task::XInteractionHandler > xInteraction = m_lMediaDescriptor.getUnpackedValueOrDefault(
1127 css::uno::Reference< css::task::XInteractionHandler >());
1128 css::uno::Reference<css::lang::XInitialization> xHandler(xInteraction, css::uno::UNO_QUERY);
1129 if (xHandler.is())
1130 {
1131 css::uno::Reference<css::awt::XWindow> xWindow = xTargetFrame->getContainerWindow();
1132 uno::Sequence<uno::Any> aArguments(comphelper::InitAnyPropertySequence(
1133 {
1134 {"Parent", uno::Any(xWindow)}
1135 }));
1136 xHandler->initialize(aArguments);
1137 //show the frame as early as possible to make it the parent of any message dialogs
1139 {
1141 m_bFocusedAndToFront = true; // no need to ask shouldFocusAndToFront second time
1142 }
1143 }
1144 }
1145
1146 // convert media descriptor and URL to right format for later interface call!
1147 css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
1148 m_lMediaDescriptor >> lDescriptor;
1149 OUString sURL = m_aURL.Complete;
1150
1151 // try to locate any interested frame loader
1152 css::uno::Reference< css::uno::XInterface > xLoader = impl_searchLoader();
1153 css::uno::Reference< css::frame::XFrameLoader > xAsyncLoader(xLoader, css::uno::UNO_QUERY);
1154 css::uno::Reference< css::frame::XSynchronousFrameLoader > xSyncLoader (xLoader, css::uno::UNO_QUERY);
1155
1156 if (xAsyncLoader.is())
1157 {
1158 m_xAsynchronousJob = xAsyncLoader;
1159 rtl::Reference<LoadEnvListener> xListener = new LoadEnvListener(this);
1160 aWriteLock.clear();
1161 // <- SAFE -----------------------------------
1162
1163 xAsyncLoader->load(xTargetFrame, sURL, lDescriptor, xListener);
1164
1165 return true;
1166 }
1167 else if (xSyncLoader.is())
1168 {
1169 uno::Reference<beans::XPropertySet> xTargetFrameProps(xTargetFrame, uno::UNO_QUERY);
1170 if (xTargetFrameProps.is())
1171 {
1172 // Set the URL on the frame itself, for the duration of the load, when it has no
1173 // controller.
1174 xTargetFrameProps->setPropertyValue("URL", uno::Any(sURL));
1175 }
1176 bool bResult = xSyncLoader->load(lDescriptor, xTargetFrame);
1177 // react for the result here, so the outside waiting
1178 // code can ask for it later.
1179 impl_setResult(bResult);
1180 // But the return value indicates a valid started(!) operation.
1181 // And that's true every time we reach this line :-)
1182 return true;
1183 }
1184
1185 aWriteLock.clear();
1186 // <- SAFE
1187
1188 return false;
1189}
1190
1191css::uno::Reference< css::uno::XInterface > LoadEnv::impl_searchLoader()
1192{
1193 // SAFE -> -----------------------------------
1194 osl::ClearableMutexGuard aReadLock(m_mutex);
1195
1196 // special mode to set an existing component on this frame
1197 // In such case the loader is fix. It must be the SFX based implementation,
1198 // which can create a view on top of such xModel components :-)
1200 {
1201 try
1202 {
1203 return css::frame::OfficeFrameLoader::create(m_xContext);
1204 }
1205 catch(const css::uno::RuntimeException&)
1206 { throw; }
1207 catch(const css::uno::Exception&)
1208 {}
1210 }
1211
1212 // Otherwise...
1213 // We need this type information to locate a registered frame loader
1214 // Without such information we can't work!
1215 OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_TYPENAME, OUString());
1216 if (sType.isEmpty())
1218
1219 // try to locate any interested frame loader
1220 css::uno::Reference< css::frame::XLoaderFactory > xLoaderFactory = css::frame::FrameLoaderFactory::create(m_xContext);
1221
1222 aReadLock.clear();
1223 // <- SAFE -----------------------------------
1224
1225 css::uno::Sequence< OUString > lTypesReg { sType };
1226
1227 css::uno::Sequence< css::beans::NamedValue > lQuery { { PROP_TYPES, css::uno::Any(lTypesReg) } };
1228
1229 css::uno::Reference< css::container::XEnumeration > xSet = xLoaderFactory->createSubSetEnumerationByProperties(lQuery);
1230 while(xSet->hasMoreElements())
1231 {
1232 try
1233 {
1234 // try everyone ...
1235 // Ignore any loader, which makes trouble :-)
1236 ::comphelper::SequenceAsHashMap lLoaderProps(xSet->nextElement());
1237 OUString sLoader = lLoaderProps.getUnpackedValueOrDefault(PROP_NAME, OUString());
1238 css::uno::Reference< css::uno::XInterface > xLoader = xLoaderFactory->createInstance(sLoader);
1239 if (xLoader.is())
1240 return xLoader;
1241 }
1242 catch(const css::uno::RuntimeException&)
1243 { throw; }
1244 catch(const css::uno::Exception&)
1245 { continue; }
1246 }
1247
1248 return css::uno::Reference< css::uno::XInterface >();
1249}
1250
1251void LoadEnv::impl_jumpToMark(const css::uno::Reference< css::frame::XFrame >& xFrame,
1252 const css::util::URL& aURL )
1253{
1254 if (aURL.Mark.isEmpty())
1255 return;
1256
1257 css::uno::Reference< css::frame::XDispatchProvider > xProvider(xFrame, css::uno::UNO_QUERY);
1258 if (! xProvider.is())
1259 return;
1260
1261 // SAFE ->
1262 osl::ClearableMutexGuard aReadLock(m_mutex);
1263 css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
1264 aReadLock.clear();
1265 // <- SAFE
1266
1267 css::util::URL aCmd;
1268 aCmd.Complete = ".uno:JumpToMark";
1269
1270 css::uno::Reference< css::util::XURLTransformer > xParser(css::util::URLTransformer::create(xContext));
1271 xParser->parseStrict(aCmd);
1272
1273 css::uno::Reference< css::frame::XDispatch > xDispatcher = xProvider->queryDispatch(aCmd, SPECIALTARGET_SELF, 0);
1274 if (! xDispatcher.is())
1275 return;
1276
1278 lArgs[OUString("Bookmark")] <<= aURL.Mark;
1279 xDispatcher->dispatch(aCmd, lArgs.getAsConstPropertyValueList());
1280}
1281
1282css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchAlreadyLoaded()
1283{
1284 osl::MutexGuard g(m_mutex);
1285
1286 // such search is allowed for special requests only ...
1287 // or better it's not allowed for some requests in general :-)
1288 if (
1290 m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_ASTEMPLATE , false) ||
1291// (m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_HIDDEN() , false) == sal_True) ||
1292 m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_OPENNEWVIEW, false)
1293 )
1294 {
1295 return css::uno::Reference< css::frame::XFrame >();
1296 }
1297
1298 // check URL
1299 // May it's not useful to start expensive document search, if it
1300 // can fail only .. because we load from a stream or model directly!
1301 if (
1304 /*TODO should be private:factory here tested too? */
1305 )
1306 {
1307 return css::uno::Reference< css::frame::XFrame >();
1308 }
1309
1310 // otherwise - iterate through the tasks of the desktop container
1311 // to find out, which of them might contains the requested document
1312 css::uno::Reference< css::frame::XDesktop2 > xSupplier = css::frame::Desktop::create( m_xContext );
1313 css::uno::Reference< css::container::XIndexAccess > xTaskList = xSupplier->getFrames();
1314
1315 if (!xTaskList.is())
1316 return css::uno::Reference< css::frame::XFrame >(); // task list can be empty!
1317
1318 // Note: To detect if a document was already loaded before
1319 // we check URLs here only. But might the existing and the required
1320 // document has different versions! Then its URLs are the same...
1321 sal_Int16 nNewVersion = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_VERSION, sal_Int16(-1));
1322
1323 // will be used to save the first hidden frame referring the searched model
1324 // Normally we are interested on visible frames... but if there is no such visible
1325 // frame we refer to any hidden frame also (but as fallback only).
1326 css::uno::Reference< css::frame::XFrame > xHiddenTask;
1327 css::uno::Reference< css::frame::XFrame > xTask;
1328
1329 sal_Int32 count = xTaskList->getCount();
1330 for (sal_Int32 i=0; i<count; ++i)
1331 {
1332 try
1333 {
1334 // locate model of task
1335 // Note: Without a model there is no chance to decide if
1336 // this task contains the searched document or not!
1337 xTaskList->getByIndex(i) >>= xTask;
1338 if (!xTask.is())
1339 continue;
1340
1341 OUString sURL;
1342 css::uno::Reference< css::frame::XController > xController = xTask->getController();
1343 if (!xController.is())
1344 {
1345 // If we have no controller, then perhaps there is a load in progress. The frame
1346 // itself has the URL in this case.
1347 uno::Reference<beans::XPropertySet> xTaskProps(xTask, uno::UNO_QUERY);
1348 if (xTaskProps.is())
1349 {
1350 xTaskProps->getPropertyValue("URL") >>= sURL;
1351 }
1352 if (sURL.isEmpty())
1353 {
1354 xTask.clear();
1355 continue;
1356 }
1357 }
1358
1359 uno::Reference<frame::XModel> xModel;
1360 if (sURL.isEmpty())
1361 {
1362 xModel = xController->getModel();
1363 if (!xModel.is())
1364 {
1365 xTask.clear();
1366 continue;
1367 }
1368
1369 // don't check the complete URL here.
1370 // use its main part - ignore optional jumpmarks!
1371 sURL = xModel->getURL();
1372 }
1373 if (!::utl::UCBContentHelper::EqualURLs( m_aURL.Main, sURL ))
1374 {
1375 xTask.clear ();
1376 continue;
1377 }
1378
1379 // get the original load arguments from the current document
1380 // and decide if it's really the same then the one will be.
1381 // It must be visible and must use the same file revision ...
1382 // or must not have any file revision set (-1 == -1!)
1383 utl::MediaDescriptor lOldDocDescriptor;
1384 if (xModel.is())
1385 {
1386 lOldDocDescriptor = xModel->getArgs();
1387
1388 if (lOldDocDescriptor.getUnpackedValueOrDefault(
1390 != nNewVersion)
1391 {
1392 xTask.clear();
1393 continue;
1394 }
1395 }
1396
1397 // Hidden frames are special.
1398 // They will be used as "last chance" if there is no visible frame pointing to the same model.
1399 // Safe the result but continue with current loop might be looking for other visible frames.
1400 bool bIsHidden = lOldDocDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_HIDDEN, false);
1401 if ( bIsHidden && ! xHiddenTask.is() )
1402 {
1403 xHiddenTask = xTask;
1404 xTask.clear ();
1405 continue;
1406 }
1407
1408 // We found a visible task pointing to the right model ...
1409 // Break search.
1410 break;
1411 }
1412 catch(const css::uno::RuntimeException&)
1413 { throw; }
1414 catch(const css::uno::Exception&)
1415 { continue; }
1416 }
1417
1418 css::uno::Reference< css::frame::XFrame > xResult;
1419 if (xTask.is())
1420 xResult = xTask;
1421 else if (xHiddenTask.is())
1422 xResult = xHiddenTask;
1423
1424 if (xResult.is())
1425 {
1426 // Now we are sure, that this task includes the searched document.
1427 // It's time to activate it. As special feature we try to jump internally
1428 // if an optional jumpmark is given too.
1429 if (!m_aURL.Mark.isEmpty())
1430 impl_jumpToMark(xResult, m_aURL);
1431 }
1432
1433 return xResult;
1434}
1435
1436bool LoadEnv::impl_isFrameAlreadyUsedForLoading(const css::uno::Reference< css::frame::XFrame >& xFrame) const
1437{
1438 css::uno::Reference< css::document::XActionLockable > xLock(xFrame, css::uno::UNO_QUERY);
1439
1440 // ? no lock interface ?
1441 // Maybe it's an external written frame implementation :-(
1442 // Allowing using of it... but it can fail if it's not synchronized with our processes!
1443 if (!xLock.is())
1444 return false;
1445
1446 // Otherwise we have to look for any other existing lock.
1447 return xLock->isActionLocked();
1448}
1449
1450css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchRecycleTarget()
1451{
1452 // SAFE -> ..................................
1453 osl::ClearableMutexGuard aReadLock(m_mutex);
1454
1455 // The special backing mode frame will be recycled by definition!
1456 // It doesn't matter if somewhere wants to create a new view
1457 // or open a new untitled document...
1458 // The only exception from that - hidden frames!
1459 if (m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_HIDDEN, false))
1460 return css::uno::Reference< css::frame::XFrame >();
1461
1462 css::uno::Reference< css::frame::XFramesSupplier > xSupplier = css::frame::Desktop::create( m_xContext );
1463 FrameListAnalyzer aTasksAnalyzer(xSupplier, css::uno::Reference< css::frame::XFrame >(), FrameAnalyzerFlags::BackingComponent);
1464 if (aTasksAnalyzer.m_xBackingComponent.is())
1465 {
1466 if (!impl_isFrameAlreadyUsedForLoading(aTasksAnalyzer.m_xBackingComponent))
1467 {
1469 return aTasksAnalyzer.m_xBackingComponent;
1470 }
1471 }
1472
1473 // These states indicates a wish for creation of a new view in general.
1474 if (
1475 m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_ASTEMPLATE , false) ||
1476 m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_OPENNEWVIEW, false)
1477 )
1478 {
1479 return css::uno::Reference< css::frame::XFrame >();
1480 }
1481
1482 // On the other side some special URLs will open a new frame every time (expecting
1483 // they can use the backing-mode frame!)
1484 if (
1488 )
1489 {
1490 return css::uno::Reference< css::frame::XFrame >();
1491 }
1492
1493 // No backing frame! No special URL => recycle active task - if possible.
1494 // Means - if it does not already contains a modified document, or
1495 // use another office module.
1496 css::uno::Reference< css::frame::XFrame > xTask = xSupplier->getActiveFrame();
1497
1498 // not a real error - but might a focus problem!
1499 if (!xTask.is())
1500 return css::uno::Reference< css::frame::XFrame >();
1501
1502 // not a real error - may it's a view only
1503 css::uno::Reference< css::frame::XController > xController = xTask->getController();
1504 if (!xController.is())
1505 return css::uno::Reference< css::frame::XFrame >();
1506
1507 // not a real error - may it's a db component instead of a full featured office document
1508 css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
1509 if (!xModel.is())
1510 return css::uno::Reference< css::frame::XFrame >();
1511
1512 // get some more information ...
1513
1514 // A valid set URL means: there is already a location for this document.
1515 // => it was saved there or opened from there. Such Documents can not be used here.
1516 // We search for empty document ... created by a private:factory/ URL!
1517 if (xModel->getURL().getLength()>0)
1518 return css::uno::Reference< css::frame::XFrame >();
1519
1520 // The old document must be unmodified ...
1521 css::uno::Reference< css::util::XModifiable > xModified(xModel, css::uno::UNO_QUERY);
1522 if (xModified->isModified())
1523 return css::uno::Reference< css::frame::XFrame >();
1524
1525 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xTask->getContainerWindow());
1526 if (pWindow && pWindow->IsInModalMode())
1527 return css::uno::Reference< css::frame::XFrame >();
1528
1529 // find out the application type of this document
1530 // We can recycle only documents, which uses the same application
1531 // then the new one.
1533 SvtModuleOptions::EFactory eNewApp = SvtModuleOptions::ClassifyFactoryByURL (m_aURL.Complete, m_lMediaDescriptor.getAsConstPropertyValueList());
1534
1535 aReadLock.clear();
1536 // <- SAFE ..................................
1537
1538 if (eOldApp != eNewApp)
1539 return css::uno::Reference< css::frame::XFrame >();
1540
1541 // OK this task seems to be usable for recycling
1542 // But we should mark it as such - means set an action lock.
1543 // Otherwise it would be used more than ones or will be destroyed
1544 // by a close() or terminate() request.
1545 // But if such lock already exist ... it means this task is used for
1546 // any other operation already. Don't use it then.
1548 return css::uno::Reference< css::frame::XFrame >();
1549
1550 // OK - there is a valid target frame.
1551 // But may be it contains already a document.
1552 // Then we have to ask it, if it allows recycling of this frame .-)
1553 bool bReactivateOldControllerOnError = false;
1554 css::uno::Reference< css::frame::XController > xOldDoc = xTask->getController();
1555 if (xOldDoc.is())
1556 {
1557 utl::MediaDescriptor lOldDocDescriptor(xModel->getArgs());
1558
1559 // replaceable document
1560 if (!lOldDocDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_REPLACEABLE, false))
1561 return css::uno::Reference< css::frame::XFrame >();
1562
1563 bReactivateOldControllerOnError = xOldDoc->suspend(true);
1564 if (! bReactivateOldControllerOnError)
1565 return css::uno::Reference< css::frame::XFrame >();
1566 }
1567
1568 // SAFE -> ..................................
1569 {
1570 osl::MutexGuard aWriteLock(m_mutex);
1571
1572 css::uno::Reference< css::document::XActionLockable > xLock(xTask, css::uno::UNO_QUERY);
1573 if (!m_aTargetLock.setResource(xLock))
1574 return css::uno::Reference< css::frame::XFrame >();
1575
1576 m_bReactivateControllerOnError = bReactivateOldControllerOnError;
1577 }
1578 // <- SAFE ..................................
1579
1580 return xTask;
1581}
1582
1584{
1585 /*TODO reset action locks */
1586
1587 // SAFE -> ----------------------------------
1588 osl::ClearableMutexGuard aReadLock(m_mutex);
1589
1590 if (m_bLoaded)
1591 {
1592 // Bring the new loaded document to front (if allowed!).
1593 // Note: We show new created frames here only.
1594 // We don't hide already visible frames here ...
1595 css::uno::Reference< css::awt::XWindow > xWindow = m_xTargetFrame->getContainerWindow();
1596 bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_HIDDEN, false);
1597 bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_MINIMIZED, false);
1598
1599 if (bMinimized)
1600 {
1601 SolarMutexGuard aSolarGuard;
1603 // check for system window is necessary to guarantee correct pointer cast!
1604 if (pWindow && pWindow->IsSystemWindow())
1605 static_cast<WorkWindow*>(pWindow.get())->Minimize();
1606 }
1607 else if (!bHidden)
1608 {
1609 // show frame ... if it's not still visible ...
1610 // But do nothing if it's already visible!
1612 }
1613
1614 // Note: Only if an existing property "FrameName" is given by this media descriptor,
1615 // it should be used. Otherwise we should do nothing. May be the outside code has already
1616 // set a frame name on the target!
1617 utl::MediaDescriptor::const_iterator pFrameName = m_lMediaDescriptor.find(utl::MediaDescriptor::PROP_FRAMENAME);
1618 if (pFrameName != m_lMediaDescriptor.end())
1619 {
1620 OUString sFrameName;
1621 pFrameName->second >>= sFrameName;
1622 // Check the name again. e.g. "_default" isn't allowed.
1623 // On the other side "_beamer" is a valid name :-)
1625 m_xTargetFrame->setName(sFrameName);
1626 }
1627 }
1629 {
1630 // Try to reactivate the old document (if any exists!)
1631 css::uno::Reference< css::frame::XController > xOldDoc = m_xTargetFrame->getController();
1632 // clear does not depend from reactivation state of a might existing old document!
1633 // We must make sure, that a might following getTargetComponent() call does not return
1634 // the old document!
1635 m_xTargetFrame.clear();
1636 if (xOldDoc.is())
1637 {
1638 bool bReactivated = xOldDoc->suspend(false);
1639 if (!bReactivated)
1642 }
1643 }
1644 else if (m_bCloseFrameOnError)
1645 {
1646 // close empty frames
1647 css::uno::Reference< css::util::XCloseable > xCloseable (m_xTargetFrame, css::uno::UNO_QUERY);
1648
1649 try
1650 {
1651 if (xCloseable.is())
1652 xCloseable->close(true);
1653 else if (m_xTargetFrame.is())
1654 m_xTargetFrame->dispose();
1655 }
1656 catch(const css::util::CloseVetoException&)
1657 {}
1658 catch(const css::lang::DisposedException&)
1659 {}
1660 m_xTargetFrame.clear();
1661 }
1662
1663 // This max force an implicit closing of our target frame ...
1664 // e.g. in case close(sal_True) was called before and the frame
1665 // kill itself if our external use-lock is released here!
1666 // That's why we release this lock AFTER ALL OPERATIONS on this frame
1667 // are finished. The frame itself must handle then
1668 // this situation gracefully.
1670
1671 // Last but not least :-)
1672 // We have to clear the current media descriptor.
1673 // Otherwise it hold a might existing stream open!
1674 m_lMediaDescriptor.clear();
1675
1676 css::uno::Any aRequest;
1677 bool bThrow = false;
1678 if ( !m_bLoaded && m_pQuietInteraction.is() && m_pQuietInteraction->wasUsed() )
1679 {
1680 aRequest = m_pQuietInteraction->getRequest();
1681 m_pQuietInteraction.clear();
1682 bThrow = true;
1683 }
1684
1685 aReadLock.clear();
1686
1687 if (bThrow)
1688 {
1689 if ( aRequest.isExtractableTo( ::cppu::UnoType< css::uno::Exception >::get() ) )
1690 throw LoadEnvException(
1691 LoadEnvException::ID_GENERAL_ERROR, "interaction request",
1692 aRequest);
1693 }
1694
1695 // <- SAFE ----------------------------------
1696}
1697
1699{
1700 bool const preview(
1701 m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_PREVIEW, false));
1702 return !preview
1703 && officecfg::Office::Common::View::NewDocumentHandling::ForceFocusAndToFront::get();
1704}
1705
1706void LoadEnv::impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::XWindow >& xWindow ,
1707 bool bForceToFront)
1708{
1709 SolarMutexGuard aSolarGuard;
1711 if ( !pWindow )
1712 return;
1713
1714 if (pWindow->IsVisible() && bForceToFront)
1715 pWindow->ToTop( ToTopFlags::RestoreWhenMin | ToTopFlags::ForegroundTask );
1716 else
1717 pWindow->Show(true, bForceToFront ? ShowFlags::ForegroundTask : ShowFlags::NONE);
1718}
1719
1720void LoadEnv::impl_applyPersistentWindowState(const css::uno::Reference< css::awt::XWindow >& xWindow)
1721{
1722 // no window -> action not possible
1723 if (!xWindow.is())
1724 return;
1725
1726 // window already visible -> do nothing! If we use a "recycle frame" for loading ...
1727 // the current position and size must be used.
1728 css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(xWindow, css::uno::UNO_QUERY);
1729 if (
1730 (xVisibleCheck.is() ) &&
1731 (xVisibleCheck->isVisible())
1732 )
1733 return;
1734
1735 // SOLAR SAFE ->
1736 {
1737 SolarMutexGuard aSolarGuard1;
1738
1740 if (!pWindow)
1741 return;
1742
1743 bool bSystemWindow = pWindow->IsSystemWindow();
1744 bool bWorkWindow = (pWindow->GetType() == WindowType::WORKWINDOW);
1745
1746 if (!bSystemWindow && !bWorkWindow)
1747 return;
1748
1749 // don't overwrite this special state!
1750 WorkWindow* pWorkWindow = static_cast<WorkWindow*>(pWindow.get());
1751 if (pWorkWindow->IsMinimized())
1752 return;
1753 }
1754 // <- SOLAR SAFE
1755
1756 // SAFE ->
1757 osl::ClearableMutexGuard aReadLock(m_mutex);
1758
1759 // no filter -> no module -> no persistent window state
1760 OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(
1762 OUString());
1763 if (sFilter.isEmpty())
1764 return;
1765
1766 css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
1767
1768 aReadLock.clear();
1769 // <- SAFE
1770
1771 try
1772 {
1773 // retrieve the module name from the filter configuration
1774 css::uno::Reference< css::container::XNameAccess > xFilterCfg(
1775 xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_FILTERFACTORY, xContext),
1776 css::uno::UNO_QUERY_THROW);
1777 ::comphelper::SequenceAsHashMap lProps (xFilterCfg->getByName(sFilter));
1778 OUString sModule = lProps.getUnpackedValueOrDefault(FILTER_PROPNAME_ASCII_DOCUMENTSERVICE, OUString());
1779
1780 // get access to the configuration of this office module
1781 css::uno::Reference< css::container::XNameAccess > xModuleCfg(officecfg::Setup::Office::Factories::get());
1782
1783 // read window state from the configuration
1784 // and apply it on the window.
1785 // Do nothing, if no configuration entry exists!
1786 OUString sWindowState;
1787
1788 // Don't look for persistent window attributes when used through LibreOfficeKit
1790 comphelper::ConfigurationHelper::readRelativeKey(xModuleCfg, sModule, "ooSetupFactoryWindowAttributes") >>= sWindowState;
1791
1792 if (!sWindowState.isEmpty())
1793 {
1794 // SOLAR SAFE ->
1795 SolarMutexGuard aSolarGuard;
1796
1797 // We have to retrieve the window pointer again. Because nobody can guarantee
1798 // that the XWindow was not disposed in between .-)
1799 // But if we get a valid pointer we can be sure, that it's the system window pointer
1800 // we already checked and used before. Because nobody recycle the same uno reference for
1801 // a new internal c++ implementation ... hopefully .-))
1802 VclPtr<vcl::Window> pWindowCheck = VCLUnoHelper::GetWindow(xWindow);
1803 if (! pWindowCheck)
1804 return;
1805
1806 SystemWindow* pSystemWindow = static_cast<SystemWindow*>(pWindowCheck.get());
1807 pSystemWindow->SetWindowState(sWindowState);
1808 // <- SOLAR SAFE
1809 }
1810 }
1811 catch(const css::uno::RuntimeException&)
1812 { throw; }
1813 catch(const css::uno::Exception&)
1814 {}
1815}
1816
1817} // namespace framework
1818
1819/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sType
Reference< XInputStream > xStream
constexpr OUStringLiteral sFrameName
AnyEventRef aEvent
static void Yield()
static bool IsHeadlessModeEnabled()
static bool IsQuit()
static EFactory ClassifyFactoryByURL(const OUString &sURL, const css::uno::Sequence< css::beans::PropertyValue > &lMediaDescriptor)
static EFactory ClassifyFactoryByModel(const css::uno::Reference< css::frame::XModel > &xModel)
void SetWindowState(std::u16string_view rStr)
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
reference_type * get() const
bool IsMinimized() const
static css::uno::Any readRelativeKey(const css::uno::Reference< css::uno::XInterface > &xCFG, const OUString &sRelPath, const OUString &sKey)
const css::uno::Any & get(const OUString &_rValueName) const
TValueType getUnpackedValueOrDefault(const OUString &sKey, const TValueType &aDefault) const
css::uno::Sequence< css::beans::PropertyValue > getAsConstPropertyValueList() const
void freeResource()
set a new resource for locking at this guard.
bool setResource(const css::uno::Reference< css::document::XActionLockable > &xLock)
set a new resource for locking at this guard.
static css::uno::Reference< css::task::XInteractionRequest > CreateRequest(const css::uno::Any &aRequest, const css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > &lContinuations)
specify an exception, which can be used inside the load environment only.
@ ID_INVALID_ENVIRONMENT
Its similar to a uno::RuntimeException... @descr But such runtime exception can break the whole offic...
@ ID_NO_TARGET_FOUND
indicates a failed search for the right target frame.
@ ID_UNSUPPORTED_CONTENT
The specified URL/Stream/etcpp.
@ ID_STILL_RUNNING
indicates an already running load operation.
@ ID_GENERAL_ERROR
sometimes we can't specify the reason for an error, because we was interrupted by a called code in an...
@ ID_INVALID_MEDIADESCRIPTOR
indicates a corrupted media descriptor.
implements general mechanism for loading documents.
Definition: loadenv.hxx:68
bool impl_isFrameAlreadyUsedForLoading(const css::uno::Reference< css::frame::XFrame > &xFrame) const
checks whether a frame is already used for another load request or not.
Definition: loadenv.cxx:1436
bool impl_handleContent()
tries to use ContentHandler objects for loading.
Definition: loadenv.cxx:862
rtl::Reference< QuietInteraction > m_pQuietInteraction
Definition: loadenv.hxx:194
bool m_bCloseFrameOnError
it indicates, that the member m_xTargetFrame was new created for this load request and must be closed...
Definition: loadenv.hxx:159
void impl_setResult(bool bResult)
TODO document me ...
Definition: loadenv.cxx:526
bool m_bLoaded
holds the information about the finished load process.
Definition: loadenv.hxx:180
css::uno::Reference< css::frame::XFrame > impl_searchAlreadyLoaded()
checks if the specified content is already loaded.
Definition: loadenv.cxx:1282
bool shouldFocusAndToFront() const
checks if this should bring to front and get focus on load, according to user settings and to the loa...
Definition: loadenv.cxx:1698
void impl_reactForLoadingState()
it means; show the frame, bring it to front, might set the right icon etcpp.
Definition: loadenv.cxx:1583
bool impl_loadContent()
tries to use FrameLoader objects for loading.
Definition: loadenv.cxx:1023
void startLoading(const OUString &sURL, const css::uno::Sequence< css::beans::PropertyValue > &lMediaDescriptor, const css::uno::Reference< css::frame::XFrame > &xBaseFrame, const OUString &sTarget, sal_Int32 nSearchFlags, LoadEnvFeatures eFeature=LoadEnvFeatures::NONE)
start loading of a resource
Definition: loadenv.cxx:231
css::uno::Reference< css::frame::XFrame > m_xBaseFrame
points to the frame, which uses this LoadEnv object and must be used to start target search there.
Definition: loadenv.hxx:109
css::uno::Reference< css::uno::XInterface > m_xAsynchronousJob
it holds one (!) asynchronous used contenthandler or frameloader alive, till the asynchronous operati...
Definition: loadenv.hxx:172
void impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::XWindow > &xWindow, bool bForceToFront)
because showing of a frame is needed more than once... it's implemented as a separate method .
Definition: loadenv.cxx:1706
static void initializeUIDefaults(const css::uno::Reference< css::uno::XComponentContext > &i_rxContext, utl::MediaDescriptor &io_lMediaDescriptor, const bool _bUIMode, rtl::Reference< QuietInteraction > *o_ppQuiteInteraction)
TODO document me ...
Definition: loadenv.cxx:311
css::uno::Reference< css::frame::XFrame > impl_searchRecycleTarget()
search for any target frame, which seems to be usable for this load request.
Definition: loadenv.cxx:1450
void impl_jumpToMark(const css::uno::Reference< css::frame::XFrame > &xFrame, const css::util::URL &aURL)
jumps to the requested bookmark inside a given document.
Definition: loadenv.cxx:1251
css::uno::Reference< css::uno::XInterface > impl_searchLoader()
TODO document me ...
Definition: loadenv.cxx:1191
void impl_detectTypeAndFilter()
tries to detect the type and the filter of the specified content.
Definition: loadenv.cxx:737
bool impl_filterHasInteractiveDialog() const
determine if this loader has an interactive dialog shown before loading the document.
Definition: loadenv.cxx:991
sal_Int32 m_nSearchFlags
if m_sTarget is not a special one, this flags regulate searching of a suitable one.
Definition: loadenv.hxx:134
EContentType m_eContentType
classify the content, which should be loaded by this instance.
Definition: loadenv.hxx:153
bool waitWhileLoading(sal_uInt32 nTimeout=0)
wait for an already running load request (started by calling startLoading() before).
Definition: loadenv.cxx:426
css::uno::Reference< css::frame::XFrame > m_xTargetFrame
points to the frame, into which the new component was loaded.
Definition: loadenv.hxx:124
bool impl_furtherDocsAllowed()
determine if it's allowed to open new document frames.
Definition: loadenv.cxx:921
LoadEnvFeatures m_eFeature
enable/disable special features of a load request.
Definition: loadenv.hxx:150
~LoadEnv()
deinitialize an instance of this class in the right way.
Definition: loadenv.cxx:145
css::uno::Reference< css::uno::XComponentContext > m_xContext
reference to a uno service manager, which must be used to created on needed services on demand.
Definition: loadenv.hxx:104
static EContentType classifyContent(const OUString &sURL, const css::uno::Sequence< css::beans::PropertyValue > &lMediaDescriptor)
checks if the specified content can be handled by a ContentHandler only and is not related to a targe...
Definition: loadenv.cxx:544
void impl_applyPersistentWindowState(const css::uno::Reference< css::awt::XWindow > &xWindow)
try to determine the used application module of this load request and apply right position and size f...
Definition: loadenv.cxx:1720
osl::Mutex m_mutex
Definition: loadenv.hxx:99
OUString m_sTarget
contains the name of the target, in which the specified resource of this instance must be loaded.
Definition: loadenv.hxx:129
bool m_bReactivateControllerOnError
it indicates, that the old document (which was located inside m_xBaseFrame in combination with the m_...
Definition: loadenv.hxx:167
EContentType
classify a content.
Definition: loadenv.hxx:87
@ E_CAN_BE_SET
special mode for non real loading, In such case the model is given directly!
Definition: loadenv.hxx:95
@ E_CAN_BE_LOADED
identifies a content, which can be loaded into a target frame
Definition: loadenv.hxx:93
@ E_UNSUPPORTED_CONTENT
identifies a content, which seems to be invalid in general
Definition: loadenv.hxx:89
@ E_CAN_BE_HANDLED
identifies a content, which can be used with a ContentHandler and is not related to a target frame
Definition: loadenv.hxx:91
utl::MediaDescriptor m_lMediaDescriptor
contains all needed information about the resource, which should be loaded.
Definition: loadenv.hxx:142
static css::uno::Reference< css::lang::XComponent > loadComponentFromURL(const css::uno::Reference< css::frame::XComponentLoader > &xLoader, const css::uno::Reference< css::uno::XComponentContext > &xContext, const OUString &sURL, const OUString &sTarget, sal_Int32 nFlags, const css::uno::Sequence< css::beans::PropertyValue > &lArgs)
Definition: loadenv.cxx:149
LoadEnv(css::uno::Reference< css::uno::XComponentContext > xContext)
initialize a new instance of this load environment.
Definition: loadenv.cxx:134
ActionLockGuard m_aTargetLock
holds an XActionLock on the internal used task member.
Definition: loadenv.hxx:192
bool m_bFocusedAndToFront
If we already brought it to front; do not do that again (the user could switch elsewhere after the fi...
Definition: loadenv.hxx:186
css::uno::Reference< css::lang::XComponent > getTargetComponent() const
TODO document me ...
Definition: loadenv.cxx:460
css::util::URL m_aURL
because the mediadescriptor contains the complete URL ... but some functionality need the structured ...
Definition: loadenv.hxx:147
static bool isProtocol(std::u16string_view sURL, EProtocol eRequired)
it checks if given URL match the required protocol only It should be used instead of specifyProtocol(...
Definition: protocols.h:82
handle interactions non visible @descr Sometimes it's necessary to use a non visible interaction hand...
static bool matchSpecialTarget(std::u16string_view sCheckTarget, ESpecialTarget eSpecialTarget)
it checks the given unknown target name, if it's the expected special one.
static bool isValidNameForFrame(std::u16string_view sName)
it checks, if the given name can be used to set it at a frame using XFrame.setName() method.
css::uno::Reference< css::frame::XFrame > createTask(const OUString &sName, const utl::MediaDescriptor &rDescriptor)
Definition: taskcreator.cxx:56
static constexpr OUStringLiteral PROP_FRAMENAME
static constexpr OUStringLiteral PROP_PREVIEW
static constexpr OUStringLiteral PROP_INPUTSTREAM
static constexpr OUStringLiteral PROP_ABORTED
static constexpr OUStringLiteral PROP_OPENNEWVIEW
static constexpr OUStringLiteral PROP_JUMPMARK
static constexpr OUStringLiteral PROP_ASTEMPLATE
static constexpr OUStringLiteral PROP_SILENT
static constexpr OUStringLiteral PROP_HIDDEN
static constexpr OUStringLiteral PROP_VERSION
static constexpr OUStringLiteral PROP_MODEL
static constexpr OUStringLiteral PROP_MACROEXECUTIONMODE
static constexpr OUStringLiteral PROP_URL
static constexpr OUStringLiteral PROP_DOCUMENTSERVICE
static constexpr OUStringLiteral PROP_AUTHENTICATIONHANDLER
static constexpr OUStringLiteral PROP_TYPENAME
static constexpr OUStringLiteral PROP_STATUSINDICATOR
static constexpr OUStringLiteral PROP_UPDATEDOCMODE
static constexpr OUStringLiteral PROP_FILENAME
static constexpr OUStringLiteral PROP_FILTERPROVIDER
static constexpr OUStringLiteral PROP_FILTERNAME
static constexpr OUStringLiteral PROP_REPLACEABLE
static constexpr OUStringLiteral PROP_MINIMIZED
static constexpr OUStringLiteral PROP_INTERACTIONHANDLER
URL aURL
float u
float x
css::uno::Reference< css::uno::XComponentContext > m_xContext
Sequence< PropertyValue > aArguments
constexpr OUStringLiteral PROP_TYPES
Definition: loadenv.cxx:95
bool m_bWaitingResult
Definition: loadenv.cxx:109
constexpr OUStringLiteral PROP_NAME
Definition: loadenv.cxx:96
std::mutex m_mutex
Definition: loadenv.cxx:108
LoadEnv * m_pLoadEnv
Definition: loadenv.cxx:110
LoadEnvFeatures
enable/disable special features of a load request.
Definition: loadenv.hxx:44
@ WorkWithUI
enable using of UI elements during loading (means progress, interaction handler etcpp....
@ NONE
we should be informed, if no feature is enabled :-)
@ AllowContentHandler
enable loading of resources, which are not related to a target frame! (see concept of ContentHandler)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
NONE
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
OInteraction< css::task::XInteractionApprove > OInteractionApprove
OInteraction< css::task::XInteractionAbort > OInteractionAbort
constexpr OUStringLiteral SERVICENAME_FILTERFACTORY
Definition: services.h:28
constexpr OUStringLiteral SPECIALTARGET_BLANK
Definition: targets.h:31
constexpr OUStringLiteral SPECIALTARGET_SELF
Definition: targets.h:28
constexpr OUStringLiteral FILTER_PROPNAME_ASCII_DOCUMENTSERVICE
properties for Filter config
Definition: properties.h:88
int i
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
bool IsMappedWebDAVPath(const OUString &rURL, OUString *pRealURL)
#define ERRCODE_SFX_NOMOREDOCUMENTSALLOWED
Reference< XController > xController
Reference< XFrame > xFrame
Reference< XModel > xModel