166a17583SThorsten Behrens /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
217ff7b41SMichael Meeks /*
317ff7b41SMichael Meeks * This file is part of the LibreOffice project.
477f6149cSKurt Zenker *
517ff7b41SMichael Meeks * This Source Code Form is subject to the terms of the Mozilla Public
617ff7b41SMichael Meeks * License, v. 2.0. If a copy of the MPL was not distributed with this
717ff7b41SMichael Meeks * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8e8914d14SRüdiger Timm *
917ff7b41SMichael Meeks * This file incorporates work covered by the following license notice:
10e8914d14SRüdiger Timm *
1117ff7b41SMichael Meeks * Licensed to the Apache Software Foundation (ASF) under one or more
1217ff7b41SMichael Meeks * contributor license agreements. See the NOTICE file distributed
1317ff7b41SMichael Meeks * with this work for additional information regarding copyright
1417ff7b41SMichael Meeks * ownership. The ASF licenses this file to you under the Apache
1517ff7b41SMichael Meeks * License, Version 2.0 (the "License"); you may not use this file
1617ff7b41SMichael Meeks * except in compliance with the License. You may obtain a copy of
1717ff7b41SMichael Meeks * the License at http://www.apache.org/licenses/LICENSE-2.0 .
1817ff7b41SMichael Meeks */
19c24c1a18SOliver Bolte
2077f6149cSKurt Zenker #include <loadenv/loadenv.hxx>
2177f6149cSKurt Zenker
22e4bf92aeSGabor Kelemen #include <loadenv/loadenvexception.hxx>
2377f6149cSKurt Zenker #include <loadenv/targethelper.hxx>
244f40fd27SMathias Bauer #include <framework/framelistanalyzer.hxx>
25ffa0c246SRüdiger Timm
26c7e172b2SJens-Heiner Rechtien #include <interaction/quietinteraction.hxx>
274543350eSVladimir Glazounov #include <properties.h>
2877f6149cSKurt Zenker #include <protocols.h>
2977f6149cSKurt Zenker #include <services.h>
30e4bf92aeSGabor Kelemen #include <targets.h>
31fd90f23fSBjoern Michaelsen #include <comphelper/interaction.hxx>
3257448212STor Lillqvist #include <comphelper/lok.hxx>
331115a60eSSamuel Mehrbrodt #include <comphelper/namedvaluecollection.hxx>
346f316707SCaolán McNamara #include <comphelper/propertysequence.hxx>
3536ea4fb1SMathias Bauer #include <framework/interaction.hxx>
369c2dfa9bSMarkus Mohrhard #include <comphelper/processfactory.hxx>
37a457c7c6SStephan Bergmann #include <officecfg/Office/Common.hxx>
38f3e0595fSJulien Nabet #include <officecfg/Setup.hxx>
397c80942cSRüdiger Timm
402a993534SKurt Zenker #include <com/sun/star/awt/XWindow2.hpp>
41f3e0595fSJulien Nabet #include <com/sun/star/beans/XPropertySet.hpp>
42d7fa9ca7SNoel Grandin #include <com/sun/star/container/XNameAccess.hpp>
43d7fa9ca7SNoel Grandin #include <com/sun/star/container/XEnumeration.hpp>
44d7fa9ca7SNoel Grandin #include <com/sun/star/document/MacroExecMode.hpp>
45d7fa9ca7SNoel Grandin #include <com/sun/star/document/XTypeDetection.hpp>
46d7fa9ca7SNoel Grandin #include <com/sun/star/document/XActionLockable.hpp>
47d7fa9ca7SNoel Grandin #include <com/sun/star/document/UpdateDocMode.hpp>
48bb121c86SNoel Grandin #include <com/sun/star/frame/Desktop.hpp>
4930dd9b2fSNoel Grandin #include <com/sun/star/frame/OfficeFrameLoader.hpp>
5077f6149cSKurt Zenker #include <com/sun/star/frame/XModel.hpp>
5177f6149cSKurt Zenker #include <com/sun/star/frame/XFrameLoader.hpp>
5277f6149cSKurt Zenker #include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
5377f6149cSKurt Zenker #include <com/sun/star/frame/XNotifyingDispatch.hpp>
54d7fa9ca7SNoel Grandin #include <com/sun/star/frame/FrameLoaderFactory.hpp>
55d7fa9ca7SNoel Grandin #include <com/sun/star/frame/ContentHandlerFactory.hpp>
56d7fa9ca7SNoel Grandin #include <com/sun/star/frame/DispatchResultState.hpp>
57d7fa9ca7SNoel Grandin #include <com/sun/star/frame/FrameSearchFlag.hpp>
5877f6149cSKurt Zenker #include <com/sun/star/frame/XDispatchProvider.hpp>
59e4bf92aeSGabor Kelemen #include <com/sun/star/lang/IllegalArgumentException.hpp>
606f316707SCaolán McNamara #include <com/sun/star/lang/XInitialization.hpp>
61d7fa9ca7SNoel Grandin #include <com/sun/star/lang/DisposedException.hpp>
6277f6149cSKurt Zenker #include <com/sun/star/io/XInputStream.hpp>
6377f6149cSKurt Zenker #include <com/sun/star/task/XInteractionHandler.hpp>
64d7fa9ca7SNoel Grandin #include <com/sun/star/task/ErrorCodeRequest.hpp>
65d7fa9ca7SNoel Grandin #include <com/sun/star/task/InteractionHandler.hpp>
66d7fa9ca7SNoel Grandin #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
67d7fa9ca7SNoel Grandin #include <com/sun/star/task/XStatusIndicator.hpp>
68d7fa9ca7SNoel Grandin #include <com/sun/star/uno/RuntimeException.hpp>
69d7fa9ca7SNoel Grandin #include <com/sun/star/ucb/UniversalContentBroker.hpp>
706dce9c67SStephan Bergmann #include <com/sun/star/util/CloseVetoException.hpp>
71d7fa9ca7SNoel Grandin #include <com/sun/star/util/URLTransformer.hpp>
72d7fa9ca7SNoel Grandin #include <com/sun/star/util/XURLTransformer.hpp>
73d7fa9ca7SNoel Grandin #include <com/sun/star/util/XCloseable.hpp>
74d7fa9ca7SNoel Grandin #include <com/sun/star/util/XModifiable.hpp>
7577f6149cSKurt Zenker
76c60ad041SNoel Grandin #include <utility>
77965cc9c2SJens-Heiner Rechtien #include <vcl/window.hxx>
78965cc9c2SJens-Heiner Rechtien #include <vcl/wrkwin.hxx>
79965cc9c2SJens-Heiner Rechtien #include <vcl/syswin.hxx>
80965cc9c2SJens-Heiner Rechtien
815cb2e310SThomas Arnhold #include <toolkit/helper/vclunohelper.hxx>
82bff284e2SMathias Bauer #include <unotools/moduleoptions.hxx>
837c80942cSRüdiger Timm #include <svtools/sfxecode.hxx>
8408e2fc04SMikhail Voytenko #include <unotools/ucbhelper.hxx>
854543350eSVladimir Glazounov #include <comphelper/configurationhelper.hxx>
862ce779cdSThomas Arnhold #include <rtl/bootstrap.hxx>
87bdb0775aSGabor Kelemen #include <sal/log.hxx>
88fd3888c6SNoel Grandin #include <comphelper/errcode.hxx>
8977f6149cSKurt Zenker #include <vcl/svapp.hxx>
90431f2ce8STakeshi Abe #include <cppuhelper/implbase.hxx>
9108f6f9ddSLászló Németh #include <comphelper/profilezone.hxx>
924a0f506fSMiklos Vajna #include <classes/taskcreator.hxx>
9320b1e644SMike Kaganski #include <tools/fileutil.hxx>
9477f6149cSKurt Zenker
9564c47c92SStephan Bergmann constexpr OUString PROP_TYPES = u"Types"_ustr;
9664c47c92SStephan Bergmann constexpr OUString PROP_NAME = u"Name"_ustr;
97ae921976SCaolán McNamara
9877f6149cSKurt Zenker namespace framework {
9977f6149cSKurt Zenker
100a6639312SKohei Yoshida using namespace com::sun::star;
10177f6149cSKurt Zenker
102f853ec31SStephan Bergmann namespace {
103f853ec31SStephan Bergmann
104431f2ce8STakeshi Abe class LoadEnvListener : public ::cppu::WeakImplHelper< css::frame::XLoadEventListener ,
10577f6149cSKurt Zenker css::frame::XDispatchResultListener >
10677f6149cSKurt Zenker {
10777f6149cSKurt Zenker private:
10889fa0a42SNoel Grandin std::mutex m_mutex;
1098cd21316SCaolán McNamara bool m_bWaitingResult;
11077f6149cSKurt Zenker LoadEnv* m_pLoadEnv;
11177f6149cSKurt Zenker
11277f6149cSKurt Zenker public:
11377f6149cSKurt Zenker
LoadEnvListener(LoadEnv * pLoadEnv)114bea8a7adSCaolán McNamara explicit LoadEnvListener(LoadEnv* pLoadEnv)
1158cd21316SCaolán McNamara : m_bWaitingResult(true)
1168cd21316SCaolán McNamara , m_pLoadEnv(pLoadEnv)
11777f6149cSKurt Zenker {
11877f6149cSKurt Zenker }
11977f6149cSKurt Zenker
12077f6149cSKurt Zenker // frame.XLoadEventListener
121e57ca028SStephan Bergmann virtual void SAL_CALL loadFinished(const css::uno::Reference< css::frame::XFrameLoader >& xLoader) override;
12277f6149cSKurt Zenker
123e57ca028SStephan Bergmann virtual void SAL_CALL loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >& xLoader) override;
12477f6149cSKurt Zenker
12577f6149cSKurt Zenker // frame.XDispatchResultListener
126e57ca028SStephan Bergmann virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& aEvent) override;
12777f6149cSKurt Zenker
12877f6149cSKurt Zenker // lang.XEventListener
129e57ca028SStephan Bergmann virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) override;
13077f6149cSKurt Zenker };
13177f6149cSKurt Zenker
132f853ec31SStephan Bergmann }
133f853ec31SStephan Bergmann
LoadEnv(css::uno::Reference<css::uno::XComponentContext> xContext)134c60ad041SNoel Grandin LoadEnv::LoadEnv(css::uno::Reference< css::uno::XComponentContext > xContext)
135c60ad041SNoel Grandin : m_xContext(std::move(xContext))
136cffe7a15SCaolán McNamara , m_nSearchFlags(0)
137344957aaSNoel Grandin , m_eFeature(LoadEnvFeatures::NONE)
138cffe7a15SCaolán McNamara , m_eContentType(E_UNSUPPORTED_CONTENT)
139cffe7a15SCaolán McNamara , m_bCloseFrameOnError(false)
140cffe7a15SCaolán McNamara , m_bReactivateControllerOnError(false)
1419a57fe1aSTor Lillqvist , m_bLoaded( false )
14277f6149cSKurt Zenker {
14377f6149cSKurt Zenker }
14477f6149cSKurt Zenker
~LoadEnv()14577f6149cSKurt Zenker LoadEnv::~LoadEnv()
14677f6149cSKurt Zenker {
14777f6149cSKurt Zenker }
14877f6149cSKurt Zenker
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 nSearchFlags,const css::uno::Sequence<css::beans::PropertyValue> & lArgs)14977f6149cSKurt Zenker css::uno::Reference< css::lang::XComponent > LoadEnv::loadComponentFromURL(const css::uno::Reference< css::frame::XComponentLoader >& xLoader,
150fe1ac1bfSNoel Grandin const css::uno::Reference< css::uno::XComponentContext >& xContext ,
1511946794aSLuboš Luňák const OUString& sURL ,
1521946794aSLuboš Luňák const OUString& sTarget,
153c5e1c410SSamuel Mehrbrodt sal_Int32 nSearchFlags ,
15477f6149cSKurt Zenker const css::uno::Sequence< css::beans::PropertyValue >& lArgs )
15577f6149cSKurt Zenker {
15677f6149cSKurt Zenker css::uno::Reference< css::lang::XComponent > xComponent;
15727bde9a6STor Lillqvist comphelper::ProfileZone aZone("loadComponentFromURL");
15877f6149cSKurt Zenker
15977f6149cSKurt Zenker try
16077f6149cSKurt Zenker {
161fe1ac1bfSNoel Grandin LoadEnv aEnv(xContext);
1621115a60eSSamuel Mehrbrodt LoadEnvFeatures loadEnvFeatures = LoadEnvFeatures::WorkWithUI;
1631115a60eSSamuel Mehrbrodt // tdf#118238 Only disable UI interaction when loading as hidden
164d03e7a8fSNoel Grandin if (comphelper::NamedValueCollection::get(lArgs, u"Hidden") == uno::Any(true) || Application::IsHeadlessModeEnabled())
1651115a60eSSamuel Mehrbrodt loadEnvFeatures = LoadEnvFeatures::NONE;
1661115a60eSSamuel Mehrbrodt
1673b16dfd8SStephan Bergmann aEnv.startLoading(sURL,
16877f6149cSKurt Zenker lArgs,
16977f6149cSKurt Zenker css::uno::Reference< css::frame::XFrame >(xLoader, css::uno::UNO_QUERY),
17077f6149cSKurt Zenker sTarget,
171c5e1c410SSamuel Mehrbrodt nSearchFlags,
1721115a60eSSamuel Mehrbrodt loadEnvFeatures);
17377f6149cSKurt Zenker aEnv.waitWhileLoading(); // wait for ever!
17477f6149cSKurt Zenker
17577f6149cSKurt Zenker xComponent = aEnv.getTargetComponent();
17677f6149cSKurt Zenker }
17777f6149cSKurt Zenker catch(const LoadEnvException& ex)
17877f6149cSKurt Zenker {
17977f6149cSKurt Zenker switch(ex.m_nID)
18077f6149cSKurt Zenker {
18177f6149cSKurt Zenker case LoadEnvException::ID_INVALID_MEDIADESCRIPTOR:
18277f6149cSKurt Zenker throw css::lang::IllegalArgumentException(
1834f5f24a4SNoel Grandin u"Optional list of arguments seem to be corrupted."_ustr, xLoader, 4);
18477f6149cSKurt Zenker
1853a54f45cSSander Vesik case LoadEnvException::ID_UNSUPPORTED_CONTENT:
1862d2337ebSStephan Bergmann throw css::lang::IllegalArgumentException(
187e50ef195SStephan Bergmann "Unsupported URL <" + sURL + ">: \"" + ex.m_sMessage + "\"",
18880cc7728SCaolán McNamara xLoader, 1);
18980cc7728SCaolán McNamara
19080cc7728SCaolán McNamara default:
1912d2337ebSStephan Bergmann SAL_WARN(
1922d2337ebSStephan Bergmann "fwk.loadenv",
1932d2337ebSStephan Bergmann "caught LoadEnvException " << +ex.m_nID << " \""
1942d2337ebSStephan Bergmann << ex.m_sMessage << "\""
1952d2337ebSStephan Bergmann << (ex.m_exOriginal.has<css::uno::Exception>()
1962d2337ebSStephan Bergmann ? (", " + ex.m_exOriginal.getValueTypeName() + " \""
1972d2337ebSStephan Bergmann + (ex.m_exOriginal.get<css::uno::Exception>().
1982d2337ebSStephan Bergmann Message)
1992d2337ebSStephan Bergmann + "\"")
2002d2337ebSStephan Bergmann : OUString())
2012d2337ebSStephan Bergmann << " while loading <" << sURL << ">");
20280cc7728SCaolán McNamara xComponent.clear();
20377f6149cSKurt Zenker break;
20477f6149cSKurt Zenker }
20577f6149cSKurt Zenker }
20677f6149cSKurt Zenker
2078c6972a4SCaolán McNamara // if AbortOnLoadFailure is set and we couldn't load the document, assert, intended for use with crashtesting to
2088c6972a4SCaolán McNamara // detect when we export something we can't import
2098c6972a4SCaolán McNamara assert(xComponent.is() || comphelper::NamedValueCollection::get(lArgs, u"AbortOnLoadFailure") != uno::Any(true));
2108c6972a4SCaolán McNamara
21177f6149cSKurt Zenker return xComponent;
21277f6149cSKurt Zenker }
21377f6149cSKurt Zenker
214b34f0327SJan Holesovsky namespace {
215b34f0327SJan Holesovsky
addModelArgs(const uno::Sequence<beans::PropertyValue> & rDescriptor)216b34f0327SJan Holesovsky utl::MediaDescriptor addModelArgs(const uno::Sequence<beans::PropertyValue>& rDescriptor)
217c57e8e70SVladimir Glazounov {
218b34f0327SJan Holesovsky utl::MediaDescriptor rResult(rDescriptor);
2192ab40e9eSNoel Grandin uno::Reference<frame::XModel> xModel(rResult.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_MODEL, uno::Reference<frame::XModel>()));
220b34f0327SJan Holesovsky
221c57e8e70SVladimir Glazounov if (xModel.is())
222c57e8e70SVladimir Glazounov {
223b34f0327SJan Holesovsky utl::MediaDescriptor aModelArgs(xModel->getArgs());
2242ab40e9eSNoel Grandin utl::MediaDescriptor::iterator pIt = aModelArgs.find( utl::MediaDescriptor::PROP_MACROEXECUTIONMODE);
225b34f0327SJan Holesovsky if (pIt != aModelArgs.end())
2262ab40e9eSNoel Grandin rResult[utl::MediaDescriptor::PROP_MACROEXECUTIONMODE] = pIt->second;
227c57e8e70SVladimir Glazounov }
228c57e8e70SVladimir Glazounov
229b34f0327SJan Holesovsky return rResult;
230c57e8e70SVladimir Glazounov }
231c57e8e70SVladimir Glazounov
232b34f0327SJan Holesovsky }
233b34f0327SJan Holesovsky
startLoading(const OUString & sURL,const uno::Sequence<beans::PropertyValue> & lMediaDescriptor,const uno::Reference<frame::XFrame> & xBaseFrame,const OUString & sTarget,sal_Int32 nSearchFlags,LoadEnvFeatures eFeature)2343b16dfd8SStephan Bergmann void LoadEnv::startLoading(const OUString& sURL, const uno::Sequence<beans::PropertyValue>& lMediaDescriptor,
235b34f0327SJan Holesovsky const uno::Reference<frame::XFrame>& xBaseFrame, const OUString& sTarget,
236344957aaSNoel Grandin sal_Int32 nSearchFlags, LoadEnvFeatures eFeature)
23777f6149cSKurt Zenker {
23885f7ed1cSStephan Bergmann osl::MutexGuard g(m_mutex);
23977f6149cSKurt Zenker
24077f6149cSKurt Zenker // Handle still running processes!
24177f6149cSKurt Zenker if (m_xAsynchronousJob.is())
24277f6149cSKurt Zenker throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
24377f6149cSKurt Zenker
24477f6149cSKurt Zenker // take over all new parameters.
24577f6149cSKurt Zenker m_xTargetFrame.clear();
24677f6149cSKurt Zenker m_xBaseFrame = xBaseFrame;
247b34f0327SJan Holesovsky m_lMediaDescriptor = addModelArgs(lMediaDescriptor);
24877f6149cSKurt Zenker m_sTarget = sTarget;
24977f6149cSKurt Zenker m_nSearchFlags = nSearchFlags;
25077f6149cSKurt Zenker m_eFeature = eFeature;
2519866efe3SNoel Grandin m_eContentType = E_UNSUPPORTED_CONTENT;
252a6287e21SNoel Grandin m_bCloseFrameOnError = false;
253a6287e21SNoel Grandin m_bReactivateControllerOnError = false;
254a6287e21SNoel Grandin m_bLoaded = false;
25577f6149cSKurt Zenker
25620b1e644SMike Kaganski OUString aRealURL;
257a3843f1cSMike Kaganski if (!officecfg::Office::Common::Load::DetectWebDAVRedirection::get()
258a3843f1cSMike Kaganski || !tools::IsMappedWebDAVPath(sURL, &aRealURL))
25920b1e644SMike Kaganski aRealURL = sURL;
26020b1e644SMike Kaganski
26142cfb5d0SAndrea Gelmini // try to find out, if it's really a content, which can be loaded or must be "handled"
26277f6149cSKurt Zenker // We use a default value for this in-parameter. Then we have to start a complex check method
263a1bc5756SJesús Corrius // internally. But if this check was already done outside it can be suppressed to perform
26477f6149cSKurt Zenker // the load request. We take over the result then!
26520b1e644SMike Kaganski m_eContentType = LoadEnv::classifyContent(aRealURL, lMediaDescriptor);
26677f6149cSKurt Zenker if (m_eContentType == E_UNSUPPORTED_CONTENT)
2674f5f24a4SNoel Grandin throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT, u"from LoadEnv::startLoading"_ustr);
26877f6149cSKurt Zenker
26977f6149cSKurt Zenker // make URL part of the MediaDescriptor
270465489d9SAndrea Gelmini // It doesn't matter if it is already an item of it.
27177f6149cSKurt Zenker // It must be the same value... so we can overwrite it :-)
2722ab40e9eSNoel Grandin m_lMediaDescriptor[utl::MediaDescriptor::PROP_URL] <<= aRealURL;
27377f6149cSKurt Zenker
27477f6149cSKurt Zenker // parse it - because some following code require that
27520b1e644SMike Kaganski m_aURL.Complete = aRealURL;
276b34f0327SJan Holesovsky uno::Reference<util::XURLTransformer> xParser(util::URLTransformer::create(m_xContext));
27777f6149cSKurt Zenker xParser->parseStrict(m_aURL);
27877f6149cSKurt Zenker
279e2a4aa0eSKurt Zenker // BTW: Split URL and JumpMark ...
280e2a4aa0eSKurt Zenker // Because such mark is an explicit value of the media descriptor!
28118692cc1SOlivier Hallot if (!m_aURL.Mark.isEmpty())
2822ab40e9eSNoel Grandin m_lMediaDescriptor[utl::MediaDescriptor::PROP_JUMPMARK] <<= m_aURL.Mark;
283e2a4aa0eSKurt Zenker
28477f6149cSKurt Zenker // By the way: remove the old and deprecated value "FileName" from the descriptor!
2852ab40e9eSNoel Grandin utl::MediaDescriptor::iterator pIt = m_lMediaDescriptor.find(utl::MediaDescriptor::PROP_FILENAME);
28677f6149cSKurt Zenker if (pIt != m_lMediaDescriptor.end())
28777f6149cSKurt Zenker m_lMediaDescriptor.erase(pIt);
28877f6149cSKurt Zenker
289a1bc5756SJesús Corrius // patch the MediaDescriptor, so it fulfil the outside requirements
2909a2d1b9cSLionel Elie Mamane // Means especially items like e.g. UI InteractionHandler, Status Indicator,
291a1bc5756SJesús Corrius // MacroExecutionMode, etc.
29277f6149cSKurt Zenker
29377f6149cSKurt Zenker /*TODO progress is bound to a frame ... How can we set it here? */
29477f6149cSKurt Zenker
295c0899590SFrank Schoenheit [fs] // UI mode
296c0899590SFrank Schoenheit [fs] const bool bUIMode =
297344957aaSNoel Grandin (m_eFeature & LoadEnvFeatures::WorkWithUI) &&
2982ab40e9eSNoel Grandin !m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_HIDDEN, false) &&
2992ab40e9eSNoel Grandin !m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_PREVIEW, false);
300c0899590SFrank Schoenheit [fs]
301f43a5ec2SHenry Castro if( comphelper::LibreOfficeKit::isActive() &&
302f43a5ec2SHenry Castro m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_SILENT, false))
303f43a5ec2SHenry Castro {
304f43a5ec2SHenry Castro rtl::Reference<QuietInteraction> pQuietInteraction = new QuietInteraction();
305*09e2627aSNoel Grandin m_lMediaDescriptor[utl::MediaDescriptor::PROP_INTERACTIONHANDLER] <<=
306*09e2627aSNoel Grandin uno::Reference<task::XInteractionHandler>(pQuietInteraction);
307f43a5ec2SHenry Castro }
308f43a5ec2SHenry Castro
309b34f0327SJan Holesovsky initializeUIDefaults(m_xContext, m_lMediaDescriptor, bUIMode, &m_pQuietInteraction);
3103b16dfd8SStephan Bergmann
3113b16dfd8SStephan Bergmann start();
312c0899590SFrank Schoenheit [fs] }
313c0899590SFrank Schoenheit [fs]
initializeUIDefaults(const css::uno::Reference<css::uno::XComponentContext> & i_rxContext,utl::MediaDescriptor & io_lMediaDescriptor,const bool i_bUIMode,rtl::Reference<QuietInteraction> * o_ppQuietInteraction)314dc00ad1eSNoel Grandin void LoadEnv::initializeUIDefaults( const css::uno::Reference< css::uno::XComponentContext >& i_rxContext,
31524cad6a6SStephan Bergmann utl::MediaDescriptor& io_lMediaDescriptor, const bool i_bUIMode,
316da8bfce2SStephan Bergmann rtl::Reference<QuietInteraction>* o_ppQuietInteraction )
317c0899590SFrank Schoenheit [fs] {
31877f6149cSKurt Zenker css::uno::Reference< css::task::XInteractionHandler > xInteractionHandler;
31977f6149cSKurt Zenker sal_Int16 nMacroMode;
32077f6149cSKurt Zenker sal_Int16 nUpdateMode;
32177f6149cSKurt Zenker
322c0899590SFrank Schoenheit [fs] if ( i_bUIMode )
32377f6149cSKurt Zenker {
32477f6149cSKurt Zenker nMacroMode = css::document::MacroExecMode::USE_CONFIG;
32577f6149cSKurt Zenker nUpdateMode = css::document::UpdateDocMode::ACCORDING_TO_CONFIG;
32677f6149cSKurt Zenker try
32777f6149cSKurt Zenker {
3287f9b3a02SCaolán McNamara // tdf#154308 At least for the case the document is launched from the StartCenter, put that StartCenter as the
3297f9b3a02SCaolán McNamara // parent for any dialogs that may appear during typedetection (once load starts a permanent frame will be set
3307f9b3a02SCaolán McNamara // anyway and used as dialog parent, which will be this one if the startcenter was running)
3317f9b3a02SCaolán McNamara css::uno::Reference<css::frame::XFramesSupplier> xSupplier = css::frame::Desktop::create(i_rxContext);
3327f9b3a02SCaolán McNamara FrameListAnalyzer aTasksAnalyzer(xSupplier, css::uno::Reference<css::frame::XFrame>(), FrameAnalyzerFlags::BackingComponent);
3337f9b3a02SCaolán McNamara css::uno::Reference<css::awt::XWindow> xDialogParent(aTasksAnalyzer.m_xBackingComponent ?
3347f9b3a02SCaolán McNamara aTasksAnalyzer.m_xBackingComponent->getContainerWindow() :
3357f9b3a02SCaolán McNamara nullptr);
3367f9b3a02SCaolán McNamara
3377f9b3a02SCaolán McNamara xInteractionHandler.set( css::task::InteractionHandler::createWithParent(i_rxContext, xDialogParent), css::uno::UNO_QUERY_THROW );
33877f6149cSKurt Zenker }
33977f6149cSKurt Zenker catch(const css::uno::RuntimeException&) {throw;}
34077f6149cSKurt Zenker catch(const css::uno::Exception& ) { }
34177f6149cSKurt Zenker }
34277f6149cSKurt Zenker // hidden mode
34377f6149cSKurt Zenker else
34477f6149cSKurt Zenker {
34577f6149cSKurt Zenker nMacroMode = css::document::MacroExecMode::NEVER_EXECUTE;
34677f6149cSKurt Zenker nUpdateMode = css::document::UpdateDocMode::NO_UPDATE;
347da8bfce2SStephan Bergmann rtl::Reference<QuietInteraction> pQuietInteraction = new QuietInteraction();
348da8bfce2SStephan Bergmann xInteractionHandler = pQuietInteraction.get();
34906c5c630SStephan Bergmann if ( o_ppQuietInteraction != nullptr )
350c0899590SFrank Schoenheit [fs] {
35123d7910cSCaolán McNamara *o_ppQuietInteraction = std::move(pQuietInteraction);
352c0899590SFrank Schoenheit [fs] }
35377f6149cSKurt Zenker }
35477f6149cSKurt Zenker
355bc9a8ddbSGiuseppe Castagno if ( xInteractionHandler.is() )
356bc9a8ddbSGiuseppe Castagno {
3572ab40e9eSNoel Grandin if( io_lMediaDescriptor.find(utl::MediaDescriptor::PROP_INTERACTIONHANDLER) == io_lMediaDescriptor.end() )
35877f6149cSKurt Zenker {
3592ab40e9eSNoel Grandin io_lMediaDescriptor[utl::MediaDescriptor::PROP_INTERACTIONHANDLER] <<= xInteractionHandler;
36077f6149cSKurt Zenker }
3612ab40e9eSNoel Grandin if( io_lMediaDescriptor.find(utl::MediaDescriptor::PROP_AUTHENTICATIONHANDLER) == io_lMediaDescriptor.end() )
362bc9a8ddbSGiuseppe Castagno {
3632ab40e9eSNoel Grandin io_lMediaDescriptor[utl::MediaDescriptor::PROP_AUTHENTICATIONHANDLER] <<= xInteractionHandler;
364bc9a8ddbSGiuseppe Castagno }
365bc9a8ddbSGiuseppe Castagno }
36677f6149cSKurt Zenker
3672ab40e9eSNoel Grandin if (io_lMediaDescriptor.find(utl::MediaDescriptor::PROP_MACROEXECUTIONMODE) == io_lMediaDescriptor.end())
3682ab40e9eSNoel Grandin io_lMediaDescriptor[utl::MediaDescriptor::PROP_MACROEXECUTIONMODE] <<= nMacroMode;
36977f6149cSKurt Zenker
3702ab40e9eSNoel Grandin if (io_lMediaDescriptor.find(utl::MediaDescriptor::PROP_UPDATEDOCMODE) == io_lMediaDescriptor.end())
3712ab40e9eSNoel Grandin io_lMediaDescriptor[utl::MediaDescriptor::PROP_UPDATEDOCMODE] <<= nUpdateMode;
37277f6149cSKurt Zenker }
37377f6149cSKurt Zenker
start()3743b16dfd8SStephan Bergmann void LoadEnv::start()
37577f6149cSKurt Zenker {
37677f6149cSKurt Zenker // SAFE ->
3775a824268SMike Kaganski {
3785a824268SMike Kaganski osl::MutexGuard aReadLock(m_mutex);
37977f6149cSKurt Zenker
38077f6149cSKurt Zenker // Handle still running processes!
38177f6149cSKurt Zenker if (m_xAsynchronousJob.is())
38277f6149cSKurt Zenker throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
38377f6149cSKurt Zenker
38477f6149cSKurt Zenker // content can not be loaded or handled
38577f6149cSKurt Zenker // check "classifyContent()" failed before ...
38677f6149cSKurt Zenker if (m_eContentType == E_UNSUPPORTED_CONTENT)
3875a824268SMike Kaganski throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT,
3884f5f24a4SNoel Grandin u"from LoadEnv::start"_ustr);
3895a824268SMike Kaganski }
39077f6149cSKurt Zenker // <- SAFE
39177f6149cSKurt Zenker
392a1bc5756SJesús Corrius // detect its type/filter etc.
393a179305cSAndrea Gelmini // This information will be available by the
39477f6149cSKurt Zenker // used descriptor member afterwards and is needed
39577f6149cSKurt Zenker // for all following operations!
39677f6149cSKurt Zenker // Note: An exception will be thrown, in case operation was not successfully ...
397bd32f48aSKurt Zenker if (m_eContentType != E_CAN_BE_SET)/* Attention: special feature to set existing component on a frame must ignore type detection! */
39877f6149cSKurt Zenker impl_detectTypeAndFilter();
39977f6149cSKurt Zenker
40077f6149cSKurt Zenker // start loading the content...
401a1bc5756SJesús Corrius // Attention: Don't check m_eContentType deeper then UNSUPPORTED/SUPPORTED!
402a1bc5756SJesús Corrius // Because it was made in the easiest way... may a flat detection was made only.
40377f6149cSKurt Zenker // And such simple detection can fail sometimes .-)
40477f6149cSKurt Zenker // Use another strategy here. Try it and let it run into the case "loading not possible".
405a6287e21SNoel Grandin bool bStarted = false;
406bd32f48aSKurt Zenker if (
407344957aaSNoel Grandin (m_eFeature & LoadEnvFeatures::AllowContentHandler) &&
408bd32f48aSKurt Zenker (m_eContentType != E_CAN_BE_SET ) /* Attention: special feature to set existing component on a frame must ignore type detection! */
409bd32f48aSKurt Zenker )
410bd32f48aSKurt Zenker {
41177f6149cSKurt Zenker bStarted = impl_handleContent();
412bd32f48aSKurt Zenker }
41377f6149cSKurt Zenker
41477f6149cSKurt Zenker if (!bStarted)
41577f6149cSKurt Zenker bStarted = impl_loadContent();
41677f6149cSKurt Zenker
41777f6149cSKurt Zenker // not started => general error
4189a2d1b9cSLionel Elie Mamane // We can't say - what was the reason for.
41977f6149cSKurt Zenker if (!bStarted)
4205a10e33fSStephan Bergmann throw LoadEnvException(
4214f5f24a4SNoel Grandin LoadEnvException::ID_GENERAL_ERROR, u"not started"_ustr);
42277f6149cSKurt Zenker }
42377f6149cSKurt Zenker
42477f6149cSKurt Zenker /*-----------------------------------------------
42577f6149cSKurt Zenker TODO
42677f6149cSKurt Zenker First draft does not implement timeout using [ms].
42777f6149cSKurt Zenker Current implementation counts yield calls only ...
42877f6149cSKurt Zenker -----------------------------------------------*/
waitWhileLoading(sal_uInt32 nTimeout)429a6287e21SNoel Grandin bool LoadEnv::waitWhileLoading(sal_uInt32 nTimeout)
43077f6149cSKurt Zenker {
431c7114b66SAndrea Gelmini // Because it's not a good idea to block the main thread
4329a2d1b9cSLionel Elie Mamane // (and we can't be sure that we are currently not used inside the
4339a2d1b9cSLionel Elie Mamane // main thread!), we can't use conditions here really. We must yield
434a1bc5756SJesús Corrius // in an intelligent manner :-)
43577f6149cSKurt Zenker
43677f6149cSKurt Zenker sal_Int32 nTime = nTimeout;
437c880d3e3SNoel Grandin while(!Application::IsQuit())
43877f6149cSKurt Zenker {
43977f6149cSKurt Zenker // SAFE -> ------------------------------
4405a824268SMike Kaganski {
4415a824268SMike Kaganski osl::MutexGuard aReadLock1(m_mutex);
44277f6149cSKurt Zenker if (!m_xAsynchronousJob.is())
44377f6149cSKurt Zenker break;
4445a824268SMike Kaganski }
44577f6149cSKurt Zenker // <- SAFE ------------------------------
44677f6149cSKurt Zenker
44777f6149cSKurt Zenker Application::Yield();
44877f6149cSKurt Zenker
44977f6149cSKurt Zenker // forever!
45077f6149cSKurt Zenker if (nTimeout==0)
45177f6149cSKurt Zenker continue;
45277f6149cSKurt Zenker
45377f6149cSKurt Zenker // timed out?
45477f6149cSKurt Zenker --nTime;
45577f6149cSKurt Zenker if (nTime<1)
45677f6149cSKurt Zenker break;
45777f6149cSKurt Zenker }
45877f6149cSKurt Zenker
45985f7ed1cSStephan Bergmann osl::MutexGuard g(m_mutex);
46077f6149cSKurt Zenker return !m_xAsynchronousJob.is();
46177f6149cSKurt Zenker }
46277f6149cSKurt Zenker
getTargetComponent() const46377f6149cSKurt Zenker css::uno::Reference< css::lang::XComponent > LoadEnv::getTargetComponent() const
46477f6149cSKurt Zenker {
46585f7ed1cSStephan Bergmann osl::MutexGuard g(m_mutex);
46677f6149cSKurt Zenker
46777f6149cSKurt Zenker if (!m_xTargetFrame.is())
46877f6149cSKurt Zenker return css::uno::Reference< css::lang::XComponent >();
46977f6149cSKurt Zenker
47077f6149cSKurt Zenker css::uno::Reference< css::frame::XController > xController = m_xTargetFrame->getController();
47177f6149cSKurt Zenker if (!xController.is())
472952b806cSNoel Grandin return m_xTargetFrame->getComponentWindow();
47377f6149cSKurt Zenker
47477f6149cSKurt Zenker css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
47577f6149cSKurt Zenker if (!xModel.is())
476952b806cSNoel Grandin return xController;
47777f6149cSKurt Zenker
478952b806cSNoel Grandin return xModel;
47977f6149cSKurt Zenker }
48077f6149cSKurt Zenker
loadFinished(const css::uno::Reference<css::frame::XFrameLoader> &)4817d144987SJens-Heiner Rechtien void SAL_CALL LoadEnvListener::loadFinished(const css::uno::Reference< css::frame::XFrameLoader >&)
48277f6149cSKurt Zenker {
48389fa0a42SNoel Grandin std::unique_lock g(m_mutex);
4848cd21316SCaolán McNamara if (m_bWaitingResult)
485a6287e21SNoel Grandin m_pLoadEnv->impl_setResult(true);
4868cd21316SCaolán McNamara m_bWaitingResult = false;
48777f6149cSKurt Zenker }
48877f6149cSKurt Zenker
loadCancelled(const css::uno::Reference<css::frame::XFrameLoader> &)4897d144987SJens-Heiner Rechtien void SAL_CALL LoadEnvListener::loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >&)
49077f6149cSKurt Zenker {
49189fa0a42SNoel Grandin std::unique_lock g(m_mutex);
4928cd21316SCaolán McNamara if (m_bWaitingResult)
493a6287e21SNoel Grandin m_pLoadEnv->impl_setResult(false);
4948cd21316SCaolán McNamara m_bWaitingResult = false;
49577f6149cSKurt Zenker }
49677f6149cSKurt Zenker
dispatchFinished(const css::frame::DispatchResultEvent & aEvent)49777f6149cSKurt Zenker void SAL_CALL LoadEnvListener::dispatchFinished(const css::frame::DispatchResultEvent& aEvent)
49877f6149cSKurt Zenker {
49989fa0a42SNoel Grandin std::unique_lock g(m_mutex);
50077f6149cSKurt Zenker
5018cd21316SCaolán McNamara if (!m_bWaitingResult)
50277f6149cSKurt Zenker return;
50377f6149cSKurt Zenker
50477f6149cSKurt Zenker switch(aEvent.State)
50577f6149cSKurt Zenker {
50677f6149cSKurt Zenker case css::frame::DispatchResultState::FAILURE :
507a6287e21SNoel Grandin m_pLoadEnv->impl_setResult(false);
50877f6149cSKurt Zenker break;
50977f6149cSKurt Zenker
51077f6149cSKurt Zenker case css::frame::DispatchResultState::SUCCESS :
511a6287e21SNoel Grandin m_pLoadEnv->impl_setResult(false);
51277f6149cSKurt Zenker break;
51377f6149cSKurt Zenker
51477f6149cSKurt Zenker case css::frame::DispatchResultState::DONTKNOW :
515a6287e21SNoel Grandin m_pLoadEnv->impl_setResult(false);
51677f6149cSKurt Zenker break;
51777f6149cSKurt Zenker }
5188cd21316SCaolán McNamara m_bWaitingResult = false;
51977f6149cSKurt Zenker }
52077f6149cSKurt Zenker
disposing(const css::lang::EventObject &)5217d144987SJens-Heiner Rechtien void SAL_CALL LoadEnvListener::disposing(const css::lang::EventObject&)
52277f6149cSKurt Zenker {
52389fa0a42SNoel Grandin std::unique_lock g(m_mutex);
5248cd21316SCaolán McNamara if (m_bWaitingResult)
525a6287e21SNoel Grandin m_pLoadEnv->impl_setResult(false);
5268cd21316SCaolán McNamara m_bWaitingResult = false;
52777f6149cSKurt Zenker }
52877f6149cSKurt Zenker
impl_setResult(bool bResult)529a6287e21SNoel Grandin void LoadEnv::impl_setResult(bool bResult)
53077f6149cSKurt Zenker {
53185f7ed1cSStephan Bergmann osl::MutexGuard g(m_mutex);
53277f6149cSKurt Zenker
53377f6149cSKurt Zenker m_bLoaded = bResult;
53477f6149cSKurt Zenker
53577f6149cSKurt Zenker impl_reactForLoadingState();
53677f6149cSKurt Zenker
53777f6149cSKurt Zenker // clearing of this reference will unblock waitWhileLoading()!
5389a2d1b9cSLionel Elie Mamane // So we must be sure, that loading process was really finished.
53977f6149cSKurt Zenker // => do it as last operation of this method ...
54077f6149cSKurt Zenker m_xAsynchronousJob.clear();
54177f6149cSKurt Zenker }
54277f6149cSKurt Zenker
54377f6149cSKurt Zenker /*-----------------------------------------------
54477f6149cSKurt Zenker TODO: Is it a good idea to change Sequence<>
54577f6149cSKurt Zenker parameter to stl-adapter?
54677f6149cSKurt Zenker -----------------------------------------------*/
classifyContent(const OUString & sURL,const css::uno::Sequence<css::beans::PropertyValue> & lMediaDescriptor)5471946794aSLuboš Luňák LoadEnv::EContentType LoadEnv::classifyContent(const OUString& sURL ,
54877f6149cSKurt Zenker const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor)
54977f6149cSKurt Zenker {
5500ce0c369SAlexander Wilms
55177f6149cSKurt Zenker // (i) Filter some special well known URL protocols,
55277f6149cSKurt Zenker // which can not be handled or loaded in general.
55377f6149cSKurt Zenker // Of course an empty URL must be ignored here too.
55477f6149cSKurt Zenker // Note: These URL schemata are fix and well known ...
55577f6149cSKurt Zenker // But there can be some additional ones, which was not
55677f6149cSKurt Zenker // defined at implementation time of this class :-(
5579a2d1b9cSLionel Elie Mamane // So we have to make sure, that the following code
55877f6149cSKurt Zenker // can detect such protocol schemata too :-)
55977f6149cSKurt Zenker
56077f6149cSKurt Zenker if(
56118692cc1SOlivier Hallot (sURL.isEmpty() ) ||
562bac9a5d6SNoel Grandin (ProtocolCheck::isProtocol(sURL,EProtocol::Uno )) ||
563bac9a5d6SNoel Grandin (ProtocolCheck::isProtocol(sURL,EProtocol::Slot )) ||
564bac9a5d6SNoel Grandin (ProtocolCheck::isProtocol(sURL,EProtocol::Macro )) ||
565bac9a5d6SNoel Grandin (ProtocolCheck::isProtocol(sURL,EProtocol::Service)) ||
566bac9a5d6SNoel Grandin (ProtocolCheck::isProtocol(sURL,EProtocol::MailTo )) ||
567bac9a5d6SNoel Grandin (ProtocolCheck::isProtocol(sURL,EProtocol::News ))
56877f6149cSKurt Zenker )
56977f6149cSKurt Zenker {
57077f6149cSKurt Zenker return E_UNSUPPORTED_CONTENT;
57177f6149cSKurt Zenker }
57277f6149cSKurt Zenker
57377f6149cSKurt Zenker // (ii) Some special URLs indicates a given input stream,
57477f6149cSKurt Zenker // a full featured document model directly or
57577f6149cSKurt Zenker // specify a request for opening an empty document.
57677f6149cSKurt Zenker // Such contents are loadable in general.
57777f6149cSKurt Zenker // But we have to check, if the media descriptor contains
57877f6149cSKurt Zenker // all needed resources. If they are missing - the following
57977f6149cSKurt Zenker // load request will fail.
58077f6149cSKurt Zenker
5819a2d1b9cSLionel Elie Mamane /* Attention: The following code can't work on such special URLs!
582c64c4ad0SAndrea Gelmini It should not break the office... but it makes no sense
58377f6149cSKurt Zenker to start expensive object creations and complex search
584c64c4ad0SAndrea Gelmini algorithm if it's clear, that such URLs must be handled
58577f6149cSKurt Zenker in a special way .-)
58677f6149cSKurt Zenker */
58777f6149cSKurt Zenker
5885334ff28SAkash Jain // creation of new documents
589bac9a5d6SNoel Grandin if (ProtocolCheck::isProtocol(sURL,EProtocol::PrivateFactory))
5905334ff28SAkash Jain return E_CAN_BE_LOADED;
5915334ff28SAkash Jain
5925334ff28SAkash Jain // using of an existing input stream
59338a3743eSTor Lillqvist utl::MediaDescriptor stlMediaDescriptor(lMediaDescriptor);
59438a3743eSTor Lillqvist utl::MediaDescriptor::const_iterator pIt;
595bac9a5d6SNoel Grandin if (ProtocolCheck::isProtocol(sURL,EProtocol::PrivateStream))
59677f6149cSKurt Zenker {
5972ab40e9eSNoel Grandin pIt = stlMediaDescriptor.find(utl::MediaDescriptor::PROP_INPUTSTREAM);
59877f6149cSKurt Zenker css::uno::Reference< css::io::XInputStream > xStream;
599965cc9c2SJens-Heiner Rechtien if (pIt != stlMediaDescriptor.end())
60077f6149cSKurt Zenker pIt->second >>= xStream;
60177f6149cSKurt Zenker if (xStream.is())
60277f6149cSKurt Zenker return E_CAN_BE_LOADED;
603d15b4e20SNoel Grandin SAL_INFO("fwk.loadenv", "LoadEnv::classifyContent(): loading from stream with right URL but invalid stream detected");
60477f6149cSKurt Zenker return E_UNSUPPORTED_CONTENT;
60577f6149cSKurt Zenker }
60677f6149cSKurt Zenker
60777f6149cSKurt Zenker // using of a full featured document
608bac9a5d6SNoel Grandin if (ProtocolCheck::isProtocol(sURL,EProtocol::PrivateObject))
60977f6149cSKurt Zenker {
6102ab40e9eSNoel Grandin pIt = stlMediaDescriptor.find(utl::MediaDescriptor::PROP_MODEL);
61177f6149cSKurt Zenker css::uno::Reference< css::frame::XModel > xModel;
612bd32f48aSKurt Zenker if (pIt != stlMediaDescriptor.end())
61377f6149cSKurt Zenker pIt->second >>= xModel;
61477f6149cSKurt Zenker if (xModel.is())
615bd32f48aSKurt Zenker return E_CAN_BE_SET;
616d15b4e20SNoel Grandin SAL_INFO("fwk.loadenv", "LoadEnv::classifyContent(): loading with object with right URL but invalid object detected");
61777f6149cSKurt Zenker return E_UNSUPPORTED_CONTENT;
61877f6149cSKurt Zenker }
61977f6149cSKurt Zenker
62089fed427SNoel Grandin // following operations can work on an internal type name only :-(
621ed0b12f4SNoel Grandin const css::uno::Reference< css::uno::XComponentContext >& xContext = ::comphelper::getProcessComponentContext();
62289fed427SNoel Grandin css::uno::Reference< css::document::XTypeDetection > xDetect(
6232d2337ebSStephan Bergmann xContext->getServiceManager()->createInstanceWithContext(
6244f5f24a4SNoel Grandin u"com.sun.star.document.TypeDetection"_ustr, xContext),
6252d2337ebSStephan Bergmann css::uno::UNO_QUERY_THROW);
62677f6149cSKurt Zenker
6271946794aSLuboš Luňák OUString sType = xDetect->queryTypeByURL(sURL);
62877f6149cSKurt Zenker
629d7fa9ca7SNoel Grandin css::uno::Reference< css::frame::XLoaderFactory > xLoaderFactory;
63077f6149cSKurt Zenker css::uno::Reference< css::container::XEnumeration > xSet;
63177f6149cSKurt Zenker
63277f6149cSKurt Zenker // (iii) If a FrameLoader service (or at least
63377f6149cSKurt Zenker // a Filter) can be found, which supports
63477f6149cSKurt Zenker // this URL - it must be a loadable content.
63577f6149cSKurt Zenker // Because both items are registered for types
6363c28c44aSAndrea Gelmini // it's enough to check for frame loaders only.
637bb73961eSJulien Nabet // Most of our filters are handled by our global
63877f6149cSKurt Zenker // default loader. But there exist some specialized
63977f6149cSKurt Zenker // loader, which does not work on top of filters!
640c7114b66SAndrea Gelmini // So it's not enough to search on the filter configuration.
641c7114b66SAndrea Gelmini // Further it's not enough to search for types!
64277f6149cSKurt Zenker // Because there exist some types, which are referenced by
643bb73961eSJulien Nabet // other objects... but neither by filters nor frame loaders!
644bb73961eSJulien Nabet css::uno::Sequence< OUString > lTypesReg { sType };
645bb73961eSJulien Nabet css::uno::Sequence< css::beans::NamedValue > lQuery
646bb73961eSJulien Nabet {
6476b6df07dSStephan Bergmann css::beans::NamedValue(PROP_TYPES, css::uno::Any(lTypesReg))
648bb73961eSJulien Nabet };
64977f6149cSKurt Zenker
650d7fa9ca7SNoel Grandin xLoaderFactory = css::frame::FrameLoaderFactory::create(xContext);
651d7fa9ca7SNoel Grandin xSet = xLoaderFactory->createSubSetEnumerationByProperties(lQuery);
65277f6149cSKurt Zenker // at least one registered frame loader is enough!
65377f6149cSKurt Zenker if (xSet->hasMoreElements())
65477f6149cSKurt Zenker return E_CAN_BE_LOADED;
65577f6149cSKurt Zenker
65677f6149cSKurt Zenker // (iv) Some URL protocols are supported by special services.
65777f6149cSKurt Zenker // E.g. ContentHandler.
65877f6149cSKurt Zenker // Such contents can be handled ... but not loaded.
65977f6149cSKurt Zenker
660d7fa9ca7SNoel Grandin xLoaderFactory = css::frame::ContentHandlerFactory::create(xContext);
661d7fa9ca7SNoel Grandin xSet = xLoaderFactory->createSubSetEnumerationByProperties(lQuery);
66277f6149cSKurt Zenker // at least one registered content handler is enough!
66377f6149cSKurt Zenker if (xSet->hasMoreElements())
66477f6149cSKurt Zenker return E_CAN_BE_HANDLED;
66577f6149cSKurt Zenker
66677f6149cSKurt Zenker // (v) Last but not least the UCB is used inside office to
66777f6149cSKurt Zenker // load contents. He has a special configuration to know
66877f6149cSKurt Zenker // which URL schemata can be used inside office.
66989fed427SNoel Grandin css::uno::Reference< css::ucb::XUniversalContentBroker > xUCB(css::ucb::UniversalContentBroker::create(xContext));
67077f6149cSKurt Zenker if (xUCB->queryContentProvider(sURL).is())
67177f6149cSKurt Zenker return E_CAN_BE_LOADED;
67277f6149cSKurt Zenker
67377f6149cSKurt Zenker // (TODO) At this point, we have no idea .-)
67477f6149cSKurt Zenker // But it seems to be better, to break all
675a1bc5756SJesús Corrius // further requests for this URL. Otherwise
67677f6149cSKurt Zenker // we can run into some trouble.
67777f6149cSKurt Zenker return E_UNSUPPORTED_CONTENT;
67877f6149cSKurt Zenker }
67977f6149cSKurt Zenker
680a6639312SKohei Yoshida namespace {
681a6639312SKohei Yoshida
queryOrcusTypeAndFilter(const uno::Sequence<beans::PropertyValue> & rDescriptor,OUString & rType,OUString & rFilter)682a6639312SKohei Yoshida bool queryOrcusTypeAndFilter(const uno::Sequence<beans::PropertyValue>& rDescriptor, OUString& rType, OUString& rFilter)
683a6639312SKohei Yoshida {
684a6639312SKohei Yoshida OUString aURL;
685a6639312SKohei Yoshida sal_Int32 nSize = rDescriptor.getLength();
686a6639312SKohei Yoshida for (sal_Int32 i = 0; i < nSize; ++i)
687a6639312SKohei Yoshida {
688a6639312SKohei Yoshida const beans::PropertyValue& rProp = rDescriptor[i];
689a6639312SKohei Yoshida if (rProp.Name == "URL")
690a6639312SKohei Yoshida {
691a6639312SKohei Yoshida rProp.Value >>= aURL;
692a6639312SKohei Yoshida break;
693a6639312SKohei Yoshida }
694a6639312SKohei Yoshida }
695a6639312SKohei Yoshida
696cbaf1fbaSNoel Grandin if (aURL.isEmpty() || o3tl::equalsIgnoreAsciiCase(aURL.subView(0,8), u"private:"))
697a6639312SKohei Yoshida return false;
698a6639312SKohei Yoshida
699868ce95aSKohei Yoshida // TODO : Type must be set to be generic_Text (or any other type that
700868ce95aSKohei Yoshida // exists) in order to find a usable loader. Exploit it as a temporary
701868ce95aSKohei Yoshida // hack.
702868ce95aSKohei Yoshida
7036ae1b105SMarkus Mohrhard // depending on the experimental mode
7044256c764SLuboš Luňák if (!officecfg::Office::Common::Misc::ExperimentalMode::get())
7056ae1b105SMarkus Mohrhard {
7066ae1b105SMarkus Mohrhard return false;
7076ae1b105SMarkus Mohrhard }
7086ae1b105SMarkus Mohrhard
7096ae1b105SMarkus Mohrhard OUString aUseOrcus;
7104f5f24a4SNoel Grandin rtl::Bootstrap::get(u"LIBO_USE_ORCUS"_ustr, aUseOrcus);
7116ae1b105SMarkus Mohrhard bool bUseOrcus = (aUseOrcus == "YES");
7126ae1b105SMarkus Mohrhard
713644f122aSKohei Yoshida if (!bUseOrcus)
714644f122aSKohei Yoshida return false;
715644f122aSKohei Yoshida
716644f122aSKohei Yoshida if (aURL.endsWith(".xlsx"))
717a6639312SKohei Yoshida {
718a6639312SKohei Yoshida rType = "generic_Text";
719868ce95aSKohei Yoshida rFilter = "xlsx";
720a6639312SKohei Yoshida return true;
721a6639312SKohei Yoshida }
722868ce95aSKohei Yoshida else if (aURL.endsWith(".ods"))
723868ce95aSKohei Yoshida {
724868ce95aSKohei Yoshida rType = "generic_Text";
725868ce95aSKohei Yoshida rFilter = "ods";
726868ce95aSKohei Yoshida return true;
727868ce95aSKohei Yoshida }
7280552a09bSKohei Yoshida else if (aURL.endsWith(".csv"))
7290552a09bSKohei Yoshida {
7300552a09bSKohei Yoshida rType = "generic_Text";
7310552a09bSKohei Yoshida rFilter = "csv";
7320552a09bSKohei Yoshida return true;
7330552a09bSKohei Yoshida }
734a6639312SKohei Yoshida
735a6639312SKohei Yoshida return false;
736a6639312SKohei Yoshida }
737a6639312SKohei Yoshida
738a6639312SKohei Yoshida }
7391c9e7d47SXisco Fauli
impl_detectTypeAndFilter()74077f6149cSKurt Zenker void LoadEnv::impl_detectTypeAndFilter()
74177f6149cSKurt Zenker {
74238187ec1SNoel Grandin static const sal_Int32 FILTERFLAG_TEMPLATEPATH = 16;
7430c917a22SKurt Zenker
74477f6149cSKurt Zenker // SAFE ->
74585f7ed1cSStephan Bergmann osl::ClearableMutexGuard aReadLock(m_mutex);
746ffa0c246SRüdiger Timm
747fbc038ccSCaolán McNamara // Attention: Because our stl media descriptor is a copy of a uno sequence
748a1bc5756SJesús Corrius // we can't use as an in/out parameter here. Copy it before and don't forget to
7493b2321d5SFrank Schoenheit [fs] // update structure afterwards again!
7500c917a22SKurt Zenker css::uno::Sequence< css::beans::PropertyValue > lDescriptor = m_lMediaDescriptor.getAsConstPropertyValueList();
751fe1ac1bfSNoel Grandin css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
752ffa0c246SRüdiger Timm
75385f7ed1cSStephan Bergmann aReadLock.clear();
754ffa0c246SRüdiger Timm // <- SAFE
75577f6149cSKurt Zenker
7561946794aSLuboš Luňák OUString sType, sFilter;
757a6639312SKohei Yoshida
758a6639312SKohei Yoshida if (queryOrcusTypeAndFilter(lDescriptor, sType, sFilter) && !sType.isEmpty() && !sFilter.isEmpty())
759a6639312SKohei Yoshida {
760e662e835SMike Kaganski // SAFE ->
761e662e835SMike Kaganski osl::MutexGuard aWriteLock(m_mutex);
762e662e835SMike Kaganski
763a6639312SKohei Yoshida // Orcus type detected. Skip the normal type detection process.
764a6639312SKohei Yoshida m_lMediaDescriptor << lDescriptor;
7652ab40e9eSNoel Grandin m_lMediaDescriptor[utl::MediaDescriptor::PROP_TYPENAME] <<= sType;
7662ab40e9eSNoel Grandin m_lMediaDescriptor[utl::MediaDescriptor::PROP_FILTERNAME] <<= sFilter;
7674f5f24a4SNoel Grandin m_lMediaDescriptor[utl::MediaDescriptor::PROP_FILTERPROVIDER] <<= u"orcus"_ustr;
7684f5f24a4SNoel Grandin m_lMediaDescriptor[utl::MediaDescriptor::PROP_DOCUMENTSERVICE] <<= u"com.sun.star.sheet.SpreadsheetDocument"_ustr;
769a6639312SKohei Yoshida return;
770e662e835SMike Kaganski // <- SAFE
771a6639312SKohei Yoshida }
772a6639312SKohei Yoshida
7732d2337ebSStephan Bergmann css::uno::Reference< css::document::XTypeDetection > xDetect(
7742d2337ebSStephan Bergmann xContext->getServiceManager()->createInstanceWithContext(
7754f5f24a4SNoel Grandin u"com.sun.star.document.TypeDetection"_ustr, xContext),
7762d2337ebSStephan Bergmann css::uno::UNO_QUERY_THROW);
777ed467869SStephan Bergmann sType = xDetect->queryTypeByDescriptor(lDescriptor, true); /*TODO should deep detection be able for enable/disable it from outside? */
77877f6149cSKurt Zenker
779ffa0c246SRüdiger Timm // no valid content -> loading not possible
78018692cc1SOlivier Hallot if (sType.isEmpty())
7812d2337ebSStephan Bergmann throw LoadEnvException(
7824f5f24a4SNoel Grandin LoadEnvException::ID_UNSUPPORTED_CONTENT, u"type detection failed"_ustr);
78377f6149cSKurt Zenker
784ffa0c246SRüdiger Timm // SAFE ->
78585f7ed1cSStephan Bergmann osl::ResettableMutexGuard aWriteLock(m_mutex);
7860c917a22SKurt Zenker
7873fce6ae2SNoel Grandin // detection was successful => update the descriptor member of this class
788ffa0c246SRüdiger Timm m_lMediaDescriptor << lDescriptor;
7892ab40e9eSNoel Grandin m_lMediaDescriptor[utl::MediaDescriptor::PROP_TYPENAME] <<= sType;
7900c917a22SKurt Zenker // Is there an already detected (may be preselected) filter?
7910c917a22SKurt Zenker // see below ...
7922ab40e9eSNoel Grandin sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_FILTERNAME, OUString());
7930c917a22SKurt Zenker
79485f7ed1cSStephan Bergmann aWriteLock.clear();
79577f6149cSKurt Zenker // <- SAFE
7960c917a22SKurt Zenker
797579c2de3SMaxim Monastirsky // We do have potentially correct type, but the detection process was aborted.
7982ab40e9eSNoel Grandin if (m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_ABORTED, false))
799579c2de3SMaxim Monastirsky throw LoadEnvException(
8004f5f24a4SNoel Grandin LoadEnvException::ID_UNSUPPORTED_CONTENT, u"type detection aborted"_ustr);
801579c2de3SMaxim Monastirsky
802a1bc5756SJesús Corrius // But the type isn't enough. For loading sometimes we need more information.
803a1bc5756SJesús Corrius // E.g. for our "_default" feature, where we recycle any frame which contains
8040c917a22SKurt Zenker // and "Untitled" document, we must know if the new document is based on a template!
8050c917a22SKurt Zenker // But this information is available as a filter property only.
8060c917a22SKurt Zenker // => We must try(!) to detect the right filter for this load request.
8070c917a22SKurt Zenker // On the other side ... if no filter is available .. ignore it.
8080c917a22SKurt Zenker // Then the type information must be enough.
80918692cc1SOlivier Hallot if (sFilter.isEmpty())
8100c917a22SKurt Zenker {
8110c917a22SKurt Zenker // no -> try to find a preferred filter for the detected type.
812a1bc5756SJesús Corrius // Don't forget to update the media descriptor.
8130c917a22SKurt Zenker css::uno::Reference< css::container::XNameAccess > xTypeCont(xDetect, css::uno::UNO_QUERY_THROW);
8140c917a22SKurt Zenker try
8150c917a22SKurt Zenker {
8160c917a22SKurt Zenker ::comphelper::SequenceAsHashMap lTypeProps(xTypeCont->getByName(sType));
8174f5f24a4SNoel Grandin sFilter = lTypeProps.getUnpackedValueOrDefault(u"PreferredFilter"_ustr, OUString());
81818692cc1SOlivier Hallot if (!sFilter.isEmpty())
8190c917a22SKurt Zenker {
8200c917a22SKurt Zenker // SAFE ->
82185f7ed1cSStephan Bergmann aWriteLock.reset();
8222ab40e9eSNoel Grandin m_lMediaDescriptor[utl::MediaDescriptor::PROP_FILTERNAME] <<= sFilter;
82385f7ed1cSStephan Bergmann aWriteLock.clear();
8240c917a22SKurt Zenker // <- SAFE
8250c917a22SKurt Zenker }
8260c917a22SKurt Zenker }
8270c917a22SKurt Zenker catch(const css::container::NoSuchElementException&)
8280c917a22SKurt Zenker {}
8290c917a22SKurt Zenker }
830f6275a04SOliver Bolte
8310c917a22SKurt Zenker // check if the filter (if one exists) points to a template format filter.
832f6275a04SOliver Bolte // Then we have to add the property "AsTemplate".
833f6275a04SOliver Bolte // We need this information to decide afterwards if we can use a "recycle frame"
834a1bc5756SJesús Corrius // for target "_default" or has to create a new one every time.
835a1bc5756SJesús Corrius // On the other side we have to suppress that, if this property already exists
836a1bc5756SJesús Corrius // and should trigger a special handling. Then the outside call of this method here,
837f6275a04SOliver Bolte // has to know, what he is doing .-)
838f6275a04SOliver Bolte
839a6287e21SNoel Grandin bool bIsOwnTemplate = false;
84018692cc1SOlivier Hallot if (!sFilter.isEmpty())
8410c917a22SKurt Zenker {
842fe1ac1bfSNoel Grandin css::uno::Reference< css::container::XNameAccess > xFilterCont(xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_FILTERFACTORY, xContext), css::uno::UNO_QUERY_THROW);
8430c917a22SKurt Zenker try
8440c917a22SKurt Zenker {
8450c917a22SKurt Zenker ::comphelper::SequenceAsHashMap lFilterProps(xFilterCont->getByName(sFilter));
8464f5f24a4SNoel Grandin sal_Int32 nFlags = lFilterProps.getUnpackedValueOrDefault(u"Flags"_ustr, sal_Int32(0));
8470c917a22SKurt Zenker bIsOwnTemplate = ((nFlags & FILTERFLAG_TEMPLATEPATH) == FILTERFLAG_TEMPLATEPATH);
8480c917a22SKurt Zenker }
8490c917a22SKurt Zenker catch(const css::container::NoSuchElementException&)
8500c917a22SKurt Zenker {}
8510c917a22SKurt Zenker }
8520c917a22SKurt Zenker if (bIsOwnTemplate)
8530c917a22SKurt Zenker {
8540c917a22SKurt Zenker // SAFE ->
85585f7ed1cSStephan Bergmann aWriteLock.reset();
856a1bc5756SJesús Corrius // Don't overwrite external decisions! See comments before ...
8572ab40e9eSNoel Grandin utl::MediaDescriptor::const_iterator pAsTemplateItem = m_lMediaDescriptor.find(utl::MediaDescriptor::PROP_ASTEMPLATE);
8585ba4567aSOliver Bolte if (pAsTemplateItem == m_lMediaDescriptor.end())
8592ab40e9eSNoel Grandin m_lMediaDescriptor[utl::MediaDescriptor::PROP_ASTEMPLATE] <<= true;
86085f7ed1cSStephan Bergmann aWriteLock.clear();
8610c917a22SKurt Zenker // <- SAFE
8620c917a22SKurt Zenker }
86377f6149cSKurt Zenker }
86477f6149cSKurt Zenker
impl_handleContent()865a6287e21SNoel Grandin bool LoadEnv::impl_handleContent()
86677f6149cSKurt Zenker {
86777f6149cSKurt Zenker // SAFE -> -----------------------------------
86885f7ed1cSStephan Bergmann osl::ClearableMutexGuard aReadLock(m_mutex);
86977f6149cSKurt Zenker
870e2f97dccSIvan Timofeev // the type must exist inside the descriptor ... otherwise this class is implemented wrong :-)
8712ab40e9eSNoel Grandin OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_TYPENAME, OUString());
87218692cc1SOlivier Hallot if (sType.isEmpty())
87377f6149cSKurt Zenker throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR);
87477f6149cSKurt Zenker
87577f6149cSKurt Zenker // convert media descriptor and URL to right format for later interface call!
87677f6149cSKurt Zenker css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
87777f6149cSKurt Zenker m_lMediaDescriptor >> lDescriptor;
87877f6149cSKurt Zenker css::util::URL aURL = m_aURL;
87977f6149cSKurt Zenker
880f5ca04caSThomas Arnhold // get necessary container to query for a handler object
881d7fa9ca7SNoel Grandin css::uno::Reference< css::frame::XLoaderFactory > xLoaderFactory = css::frame::ContentHandlerFactory::create(m_xContext);
88277f6149cSKurt Zenker
88385f7ed1cSStephan Bergmann aReadLock.clear();
88477f6149cSKurt Zenker // <- SAFE -----------------------------------
88577f6149cSKurt Zenker
88677f6149cSKurt Zenker // query
8878e234c5bSNoel Grandin css::uno::Sequence< OUString > lTypeReg { sType };
88877f6149cSKurt Zenker
8896b6df07dSStephan Bergmann css::uno::Sequence< css::beans::NamedValue > lQuery { { PROP_TYPES, css::uno::Any(lTypeReg) } };
890ae921976SCaolán McNamara
891d7fa9ca7SNoel Grandin css::uno::Reference< css::container::XEnumeration > xSet = xLoaderFactory->createSubSetEnumerationByProperties(lQuery);
89277f6149cSKurt Zenker while(xSet->hasMoreElements())
89377f6149cSKurt Zenker {
89477f6149cSKurt Zenker ::comphelper::SequenceAsHashMap lProps (xSet->nextElement());
89569ef5d40SStephan Bergmann OUString sHandler = lProps.getUnpackedValueOrDefault(PROP_NAME, OUString());
89677f6149cSKurt Zenker
89777f6149cSKurt Zenker css::uno::Reference< css::frame::XNotifyingDispatch > xHandler;
89877f6149cSKurt Zenker try
89977f6149cSKurt Zenker {
9005797d29eSNoel Grandin xHandler.set(xLoaderFactory->createInstance(sHandler), css::uno::UNO_QUERY);
90177f6149cSKurt Zenker if (!xHandler.is())
90277f6149cSKurt Zenker continue;
90377f6149cSKurt Zenker }
90477f6149cSKurt Zenker catch(const css::uno::RuntimeException&)
90577f6149cSKurt Zenker { throw; }
90677f6149cSKurt Zenker catch(const css::uno::Exception&)
90777f6149cSKurt Zenker { continue; }
90877f6149cSKurt Zenker
90977f6149cSKurt Zenker // SAFE -> -----------------------------------
91085f7ed1cSStephan Bergmann osl::ClearableMutexGuard aWriteLock(m_mutex);
91177f6149cSKurt Zenker m_xAsynchronousJob = xHandler;
912897970cdSNoel rtl::Reference<LoadEnvListener> xListener = new LoadEnvListener(this);
91385f7ed1cSStephan Bergmann aWriteLock.clear();
91477f6149cSKurt Zenker // <- SAFE -----------------------------------
91577f6149cSKurt Zenker
91677f6149cSKurt Zenker xHandler->dispatchWithNotification(aURL, lDescriptor, xListener);
91777f6149cSKurt Zenker
918a6287e21SNoel Grandin return true;
91977f6149cSKurt Zenker }
92077f6149cSKurt Zenker
921a6287e21SNoel Grandin return false;
92277f6149cSKurt Zenker }
92377f6149cSKurt Zenker
impl_furtherDocsAllowed()924a6287e21SNoel Grandin bool LoadEnv::impl_furtherDocsAllowed()
9257c80942cSRüdiger Timm {
9267c80942cSRüdiger Timm // SAFE ->
92785f7ed1cSStephan Bergmann osl::ResettableMutexGuard aReadLock(m_mutex);
928fe1ac1bfSNoel Grandin css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
92985f7ed1cSStephan Bergmann aReadLock.clear();
9307c80942cSRüdiger Timm // <- SAFE
9317c80942cSRüdiger Timm
932a6287e21SNoel Grandin bool bAllowed = true;
9337c80942cSRüdiger Timm
9347c80942cSRüdiger Timm try
9357c80942cSRüdiger Timm {
9364256c764SLuboš Luňák std::optional<sal_Int32> x(officecfg::Office::Common::Misc::MaxOpenDocuments::get());
9377c80942cSRüdiger Timm
9387c80942cSRüdiger Timm // NIL means: count of allowed documents = infinite !
939f3e0595fSJulien Nabet // => return true
940f3e0595fSJulien Nabet if ( !x)
941a6287e21SNoel Grandin bAllowed = true;
9427c80942cSRüdiger Timm else
9437c80942cSRüdiger Timm {
944f3e0595fSJulien Nabet sal_Int32 nMaxOpenDocuments(*x);
9457c80942cSRüdiger Timm
9467c80942cSRüdiger Timm css::uno::Reference< css::frame::XFramesSupplier > xDesktop(
947fe1ac1bfSNoel Grandin css::frame::Desktop::create(xContext),
9487c80942cSRüdiger Timm css::uno::UNO_QUERY_THROW);
9497c80942cSRüdiger Timm
9507c80942cSRüdiger Timm FrameListAnalyzer aAnalyzer(xDesktop,
9517c80942cSRüdiger Timm css::uno::Reference< css::frame::XFrame >(),
952d76d1555SNoel Grandin FrameAnalyzerFlags::Help |
953d76d1555SNoel Grandin FrameAnalyzerFlags::BackingComponent |
954d76d1555SNoel Grandin FrameAnalyzerFlags::Hidden);
9557c80942cSRüdiger Timm
9563f7f4971SNoel Grandin sal_Int32 nOpenDocuments = aAnalyzer.m_lOtherVisibleFrames.size();
9577c80942cSRüdiger Timm bAllowed = (nOpenDocuments < nMaxOpenDocuments);
9587c80942cSRüdiger Timm }
9597c80942cSRüdiger Timm }
9607c80942cSRüdiger Timm catch(const css::uno::Exception&)
961a6287e21SNoel Grandin { bAllowed = true; } // !! internal errors are no reason to disturb the office from opening documents .-)
9627c80942cSRüdiger Timm
9637c80942cSRüdiger Timm if ( ! bAllowed )
9647c80942cSRüdiger Timm {
9657c80942cSRüdiger Timm // SAFE ->
96685f7ed1cSStephan Bergmann aReadLock.reset();
9677c80942cSRüdiger Timm css::uno::Reference< css::task::XInteractionHandler > xInteraction = m_lMediaDescriptor.getUnpackedValueOrDefault(
9682ab40e9eSNoel Grandin utl::MediaDescriptor::PROP_INTERACTIONHANDLER,
9697c80942cSRüdiger Timm css::uno::Reference< css::task::XInteractionHandler >());
97085f7ed1cSStephan Bergmann aReadLock.clear();
9717c80942cSRüdiger Timm // <- SAFE
9727c80942cSRüdiger Timm
9737c80942cSRüdiger Timm if (xInteraction.is())
9747c80942cSRüdiger Timm {
9757c80942cSRüdiger Timm css::uno::Any aInteraction;
9767c80942cSRüdiger Timm
977897970cdSNoel rtl::Reference<comphelper::OInteractionAbort> pAbort = new comphelper::OInteractionAbort();
978897970cdSNoel rtl::Reference<comphelper::OInteractionApprove> pApprove = new comphelper::OInteractionApprove();
9797c80942cSRüdiger Timm
980f662ba95SMike Kaganski css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations{
981f662ba95SMike Kaganski pAbort, pApprove
982f662ba95SMike Kaganski };
9837c80942cSRüdiger Timm
9847c80942cSRüdiger Timm css::task::ErrorCodeRequest aErrorCode;
98552863266SNoel Grandin aErrorCode.ErrCode = sal_uInt32(ERRCODE_SFX_NOMOREDOCUMENTSALLOWED);
9867c80942cSRüdiger Timm aInteraction <<= aErrorCode;
987661e2cc1SMathias Bauer xInteraction->handle( InteractionRequest::CreateRequest(aInteraction, lContinuations) );
9887c80942cSRüdiger Timm }
9897c80942cSRüdiger Timm }
9907c80942cSRüdiger Timm
9917c80942cSRüdiger Timm return bAllowed;
9927c80942cSRüdiger Timm }
9937c80942cSRüdiger Timm
impl_filterHasInteractiveDialog() const994754f6e2fSCaolán McNamara bool LoadEnv::impl_filterHasInteractiveDialog() const
995754f6e2fSCaolán McNamara {
996754f6e2fSCaolán McNamara //show the frame now so it can be the parent for any message dialogs shown during import
997754f6e2fSCaolán McNamara
998754f6e2fSCaolán McNamara //unless (tdf#114648) an Interactive case such as the new database wizard
999754f6e2fSCaolán McNamara if (m_aURL.Arguments == "Interactive")
1000754f6e2fSCaolán McNamara return true;
1001754f6e2fSCaolán McNamara
10020040076aSAndrea Gelmini // unless (tdf#116277) it's the labels/business cards slave frame
1003754f6e2fSCaolán McNamara if (m_aURL.Arguments.indexOf("slot=") != -1)
1004754f6e2fSCaolán McNamara return true;
1005754f6e2fSCaolán McNamara
10062ab40e9eSNoel Grandin OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_FILTERNAME, OUString());
1007754f6e2fSCaolán McNamara if (sFilter.isEmpty())
1008754f6e2fSCaolán McNamara return false;
1009754f6e2fSCaolán McNamara
1010754f6e2fSCaolán McNamara // unless (tdf#115683) the filter has a UIComponent
1011754f6e2fSCaolán McNamara OUString sUIComponent;
1012754f6e2fSCaolán McNamara css::uno::Reference<css::container::XNameAccess> xFilterCont(m_xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_FILTERFACTORY, m_xContext),
1013754f6e2fSCaolán McNamara css::uno::UNO_QUERY_THROW);
1014754f6e2fSCaolán McNamara try
1015754f6e2fSCaolán McNamara {
1016754f6e2fSCaolán McNamara ::comphelper::SequenceAsHashMap lFilterProps(xFilterCont->getByName(sFilter));
10174f5f24a4SNoel Grandin sUIComponent = lFilterProps.getUnpackedValueOrDefault(u"UIComponent"_ustr, OUString());
1018754f6e2fSCaolán McNamara }
1019754f6e2fSCaolán McNamara catch(const css::container::NoSuchElementException&)
1020754f6e2fSCaolán McNamara {
1021754f6e2fSCaolán McNamara }
1022754f6e2fSCaolán McNamara
1023754f6e2fSCaolán McNamara return !sUIComponent.isEmpty();
1024754f6e2fSCaolán McNamara }
1025754f6e2fSCaolán McNamara
impl_loadContent()1026a6287e21SNoel Grandin bool LoadEnv::impl_loadContent()
102777f6149cSKurt Zenker {
102877f6149cSKurt Zenker // SAFE -> -----------------------------------
102985f7ed1cSStephan Bergmann osl::ClearableMutexGuard aWriteLock(m_mutex);
103077f6149cSKurt Zenker
103177f6149cSKurt Zenker // search or create right target frame
10321946794aSLuboš Luňák OUString sTarget = m_sTarget;
1033bac9a5d6SNoel Grandin if (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::ESpecialTarget::Default))
103477f6149cSKurt Zenker {
103577f6149cSKurt Zenker m_xTargetFrame = impl_searchAlreadyLoaded();
10363a54f45cSSander Vesik if (m_xTargetFrame.is())
10373a54f45cSSander Vesik {
1038a6287e21SNoel Grandin impl_setResult(true);
1039a6287e21SNoel Grandin return true;
10403a54f45cSSander Vesik }
104177f6149cSKurt Zenker m_xTargetFrame = impl_searchRecycleTarget();
10427c80942cSRüdiger Timm }
10437c80942cSRüdiger Timm
104477f6149cSKurt Zenker if (! m_xTargetFrame.is())
104577f6149cSKurt Zenker {
10467c80942cSRüdiger Timm if (
1047bac9a5d6SNoel Grandin (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::ESpecialTarget::Blank )) ||
1048bac9a5d6SNoel Grandin (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::ESpecialTarget::Default))
10497c80942cSRüdiger Timm )
10507c80942cSRüdiger Timm {
10517c80942cSRüdiger Timm if (! impl_furtherDocsAllowed())
1052a6287e21SNoel Grandin return false;
10534a0f506fSMiklos Vajna TaskCreator aCreator(m_xContext);
10544a0f506fSMiklos Vajna m_xTargetFrame = aCreator.createTask(SPECIALTARGET_BLANK, m_lMediaDescriptor);
10557c80942cSRüdiger Timm m_bCloseFrameOnError = m_xTargetFrame.is();
10567c80942cSRüdiger Timm }
10577c80942cSRüdiger Timm else
10587c80942cSRüdiger Timm {
1059c5e1c410SSamuel Mehrbrodt sal_Int32 nSearchFlags = m_nSearchFlags & ~css::frame::FrameSearchFlag::CREATE;
1060c5e1c410SSamuel Mehrbrodt m_xTargetFrame = m_xBaseFrame->findFrame(sTarget, nSearchFlags);
10617c80942cSRüdiger Timm if (! m_xTargetFrame.is())
10627c80942cSRüdiger Timm {
10637c80942cSRüdiger Timm if (! impl_furtherDocsAllowed())
1064a6287e21SNoel Grandin return false;
10657c80942cSRüdiger Timm m_xTargetFrame = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0);
106677f6149cSKurt Zenker m_bCloseFrameOnError = m_xTargetFrame.is();
106777f6149cSKurt Zenker }
106877f6149cSKurt Zenker }
10697c80942cSRüdiger Timm }
107077f6149cSKurt Zenker
1071b6ca1e97SRüdiger Timm // If we couldn't find a valid frame or the frame has no container window
1072b6ca1e97SRüdiger Timm // we have to throw an exception.
1073ce32bfbfSRüdiger Timm if (
1074ce32bfbfSRüdiger Timm ( ! m_xTargetFrame.is() ) ||
1075ce32bfbfSRüdiger Timm ( ! m_xTargetFrame->getContainerWindow().is() )
1076ce32bfbfSRüdiger Timm )
107777f6149cSKurt Zenker throw LoadEnvException(LoadEnvException::ID_NO_TARGET_FOUND);
107877f6149cSKurt Zenker
1079ce32bfbfSRüdiger Timm css::uno::Reference< css::frame::XFrame > xTargetFrame = m_xTargetFrame;
108077f6149cSKurt Zenker
10814543350eSVladimir Glazounov // Now we have a valid frame ... and type detection was already done.
1082a1bc5756SJesús Corrius // We should apply the module dependent window position and size to the
10834543350eSVladimir Glazounov // frame window.
10844543350eSVladimir Glazounov impl_applyPersistentWindowState(xTargetFrame->getContainerWindow());
10854543350eSVladimir Glazounov
108677f6149cSKurt Zenker // Don't forget to lock task for following load process. Otherwise it could die
108777f6149cSKurt Zenker // during this operation runs by terminating the office or closing this task via api.
108877f6149cSKurt Zenker // If we set this lock "close()" will return false and closing will be broken.
108977f6149cSKurt Zenker // Attention: Don't forget to reset this lock again after finishing operation.
109077f6149cSKurt Zenker // Otherwise task AND office couldn't die!!!
109177f6149cSKurt Zenker // This includes gracefully handling of Exceptions (Runtime!) too ...
1092a1bc5756SJesús Corrius // That's why we use a specialized guard, which will reset the lock
109377f6149cSKurt Zenker // if it will be run out of scope.
109477f6149cSKurt Zenker
109577f6149cSKurt Zenker // Note further: ignore if this internal guard already contains a resource.
1096acd820fdSKatarina Behrens // Might impl_searchRecycleTarget() set it before. But in case this impl-method wasn't used
109777f6149cSKurt Zenker // and the target frame was new created ... this lock here must be set!
109877f6149cSKurt Zenker css::uno::Reference< css::document::XActionLockable > xTargetLock(xTargetFrame, css::uno::UNO_QUERY);
109977f6149cSKurt Zenker m_aTargetLock.setResource(xTargetLock);
110077f6149cSKurt Zenker
11019771ab4bSAndrea Gelmini // Add status indicator to descriptor. Loader can show a progress then.
110277f6149cSKurt Zenker // But don't do it, if loading should be hidden or preview is used...!
110377f6149cSKurt Zenker // So we prevent our code against wrong using. Why?
110447d9af04SAndrea Gelmini // It could be, that using of this progress could make trouble. e.g. He makes window visible...
110577f6149cSKurt Zenker // but shouldn't do that. But if no indicator is available... nobody has a chance to do that!
11062ab40e9eSNoel Grandin bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_HIDDEN, false);
11072ab40e9eSNoel Grandin bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_MINIMIZED, false);
11082ab40e9eSNoel Grandin bool bPreview = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_PREVIEW, false);
1109d239ac79STibor Nagy bool bStartPres = m_lMediaDescriptor.contains("StartPresentation");
1110c46f0c9fSCaolán McNamara
1111d239ac79STibor Nagy if (!bHidden && !bMinimized && !bPreview && !bStartPres)
11126f316707SCaolán McNamara {
111361e1e041SJan-Marek Glogowski css::uno::Reference<css::task::XStatusIndicator> xProgress = m_lMediaDescriptor.getUnpackedValueOrDefault(
11142ab40e9eSNoel Grandin utl::MediaDescriptor::PROP_STATUSINDICATOR, css::uno::Reference<css::task::XStatusIndicator>());
11156f316707SCaolán McNamara if (!xProgress.is())
111677f6149cSKurt Zenker {
1117c7114b66SAndrea Gelmini // Note: it's an optional interface!
111877f6149cSKurt Zenker css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xTargetFrame, css::uno::UNO_QUERY);
111977f6149cSKurt Zenker if (xProgressFactory.is())
112077f6149cSKurt Zenker {
112177f6149cSKurt Zenker xProgress = xProgressFactory->createStatusIndicator();
112277f6149cSKurt Zenker if (xProgress.is())
11232ab40e9eSNoel Grandin m_lMediaDescriptor[utl::MediaDescriptor::PROP_STATUSINDICATOR] <<= xProgress;
112477f6149cSKurt Zenker }
112577f6149cSKurt Zenker }
112677f6149cSKurt Zenker
11276f316707SCaolán McNamara // Now that we have a target window into which we can load, reinit the interaction handler to have this
11286f316707SCaolán McNamara // window as its parent for modal dialogs and ensure the window is visible
11296f316707SCaolán McNamara css::uno::Reference< css::task::XInteractionHandler > xInteraction = m_lMediaDescriptor.getUnpackedValueOrDefault(
11302ab40e9eSNoel Grandin utl::MediaDescriptor::PROP_INTERACTIONHANDLER,
11316f316707SCaolán McNamara css::uno::Reference< css::task::XInteractionHandler >());
11326f316707SCaolán McNamara css::uno::Reference<css::lang::XInitialization> xHandler(xInteraction, css::uno::UNO_QUERY);
11336f316707SCaolán McNamara if (xHandler.is())
11346f316707SCaolán McNamara {
11356f316707SCaolán McNamara css::uno::Reference<css::awt::XWindow> xWindow = xTargetFrame->getContainerWindow();
11366f316707SCaolán McNamara uno::Sequence<uno::Any> aArguments(comphelper::InitAnyPropertySequence(
11376f316707SCaolán McNamara {
11386f316707SCaolán McNamara {"Parent", uno::Any(xWindow)}
11396f316707SCaolán McNamara }));
11406f316707SCaolán McNamara xHandler->initialize(aArguments);
1141754f6e2fSCaolán McNamara //show the frame as early as possible to make it the parent of any message dialogs
1142754f6e2fSCaolán McNamara if (!impl_filterHasInteractiveDialog())
114342d197efSMike Kaganski {
114442d197efSMike Kaganski impl_makeFrameWindowVisible(xWindow, shouldFocusAndToFront());
114542d197efSMike Kaganski m_bFocusedAndToFront = true; // no need to ask shouldFocusAndToFront second time
114642d197efSMike Kaganski }
11476f316707SCaolán McNamara }
11486f316707SCaolán McNamara }
11496f316707SCaolán McNamara
115077f6149cSKurt Zenker // convert media descriptor and URL to right format for later interface call!
115177f6149cSKurt Zenker css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
115277f6149cSKurt Zenker m_lMediaDescriptor >> lDescriptor;
11531946794aSLuboš Luňák OUString sURL = m_aURL.Complete;
115477f6149cSKurt Zenker
115577f6149cSKurt Zenker // try to locate any interested frame loader
1156bd32f48aSKurt Zenker css::uno::Reference< css::uno::XInterface > xLoader = impl_searchLoader();
115777f6149cSKurt Zenker css::uno::Reference< css::frame::XFrameLoader > xAsyncLoader(xLoader, css::uno::UNO_QUERY);
115877f6149cSKurt Zenker css::uno::Reference< css::frame::XSynchronousFrameLoader > xSyncLoader (xLoader, css::uno::UNO_QUERY);
115977f6149cSKurt Zenker
116077f6149cSKurt Zenker if (xAsyncLoader.is())
116177f6149cSKurt Zenker {
116277f6149cSKurt Zenker m_xAsynchronousJob = xAsyncLoader;
1163897970cdSNoel rtl::Reference<LoadEnvListener> xListener = new LoadEnvListener(this);
116485f7ed1cSStephan Bergmann aWriteLock.clear();
116577f6149cSKurt Zenker // <- SAFE -----------------------------------
116677f6149cSKurt Zenker
116777f6149cSKurt Zenker xAsyncLoader->load(xTargetFrame, sURL, lDescriptor, xListener);
116877f6149cSKurt Zenker
1169a6287e21SNoel Grandin return true;
117077f6149cSKurt Zenker }
1171586895f8SCaolán McNamara else if (xSyncLoader.is())
117277f6149cSKurt Zenker {
117385467e7cSMiklos Vajna uno::Reference<beans::XPropertySet> xTargetFrameProps(xTargetFrame, uno::UNO_QUERY);
117485467e7cSMiklos Vajna if (xTargetFrameProps.is())
117585467e7cSMiklos Vajna {
117685467e7cSMiklos Vajna // Set the URL on the frame itself, for the duration of the load, when it has no
117785467e7cSMiklos Vajna // controller.
11784f5f24a4SNoel Grandin xTargetFrameProps->setPropertyValue(u"URL"_ustr, uno::Any(sURL));
117985467e7cSMiklos Vajna }
1180a6287e21SNoel Grandin bool bResult = xSyncLoader->load(lDescriptor, xTargetFrame);
118177f6149cSKurt Zenker // react for the result here, so the outside waiting
118277f6149cSKurt Zenker // code can ask for it later.
118377f6149cSKurt Zenker impl_setResult(bResult);
118477f6149cSKurt Zenker // But the return value indicates a valid started(!) operation.
1185a1bc5756SJesús Corrius // And that's true every time we reach this line :-)
1186a6287e21SNoel Grandin return true;
118777f6149cSKurt Zenker }
118877f6149cSKurt Zenker
118985f7ed1cSStephan Bergmann aWriteLock.clear();
119077f6149cSKurt Zenker // <- SAFE
119177f6149cSKurt Zenker
1192a6287e21SNoel Grandin return false;
119377f6149cSKurt Zenker }
119477f6149cSKurt Zenker
impl_searchLoader()1195bd32f48aSKurt Zenker css::uno::Reference< css::uno::XInterface > LoadEnv::impl_searchLoader()
1196bd32f48aSKurt Zenker {
1197bd32f48aSKurt Zenker // SAFE -> -----------------------------------
119885f7ed1cSStephan Bergmann osl::ClearableMutexGuard aReadLock(m_mutex);
1199bd32f48aSKurt Zenker
1200bd32f48aSKurt Zenker // special mode to set an existing component on this frame
1201a1bc5756SJesús Corrius // In such case the loader is fix. It must be the SFX based implementation,
1202bd32f48aSKurt Zenker // which can create a view on top of such xModel components :-)
1203bd32f48aSKurt Zenker if (m_eContentType == E_CAN_BE_SET)
1204bd32f48aSKurt Zenker {
1205bd32f48aSKurt Zenker try
1206bd32f48aSKurt Zenker {
120730dd9b2fSNoel Grandin return css::frame::OfficeFrameLoader::create(m_xContext);
1208bd32f48aSKurt Zenker }
1209bd32f48aSKurt Zenker catch(const css::uno::RuntimeException&)
1210bd32f48aSKurt Zenker { throw; }
1211bd32f48aSKurt Zenker catch(const css::uno::Exception&)
1212bd32f48aSKurt Zenker {}
1213bd32f48aSKurt Zenker throw LoadEnvException(LoadEnvException::ID_INVALID_ENVIRONMENT);
1214bd32f48aSKurt Zenker }
1215bd32f48aSKurt Zenker
1216a1bc5756SJesús Corrius // Otherwise...
1217fdf032c3SAndrea Gelmini // We need this type information to locate a registered frame loader
12189a2d1b9cSLionel Elie Mamane // Without such information we can't work!
12192ab40e9eSNoel Grandin OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_TYPENAME, OUString());
122018692cc1SOlivier Hallot if (sType.isEmpty())
1221bd32f48aSKurt Zenker throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR);
1222bd32f48aSKurt Zenker
1223bd32f48aSKurt Zenker // try to locate any interested frame loader
1224d7fa9ca7SNoel Grandin css::uno::Reference< css::frame::XLoaderFactory > xLoaderFactory = css::frame::FrameLoaderFactory::create(m_xContext);
1225bd32f48aSKurt Zenker
122685f7ed1cSStephan Bergmann aReadLock.clear();
1227bd32f48aSKurt Zenker // <- SAFE -----------------------------------
1228bd32f48aSKurt Zenker
12298e234c5bSNoel Grandin css::uno::Sequence< OUString > lTypesReg { sType };
1230bd32f48aSKurt Zenker
12316b6df07dSStephan Bergmann css::uno::Sequence< css::beans::NamedValue > lQuery { { PROP_TYPES, css::uno::Any(lTypesReg) } };
1232ae921976SCaolán McNamara
1233d7fa9ca7SNoel Grandin css::uno::Reference< css::container::XEnumeration > xSet = xLoaderFactory->createSubSetEnumerationByProperties(lQuery);
1234bd32f48aSKurt Zenker while(xSet->hasMoreElements())
1235bd32f48aSKurt Zenker {
123649572624SCaolán McNamara try
123749572624SCaolán McNamara {
1238bd32f48aSKurt Zenker // try everyone ...
1239bd32f48aSKurt Zenker // Ignore any loader, which makes trouble :-)
1240bd32f48aSKurt Zenker ::comphelper::SequenceAsHashMap lLoaderProps(xSet->nextElement());
124169ef5d40SStephan Bergmann OUString sLoader = lLoaderProps.getUnpackedValueOrDefault(PROP_NAME, OUString());
1242bf9f0b29SNoel Grandin css::uno::Reference< css::uno::XInterface > xLoader = xLoaderFactory->createInstance(sLoader);
1243bd32f48aSKurt Zenker if (xLoader.is())
1244bd32f48aSKurt Zenker return xLoader;
1245bd32f48aSKurt Zenker }
1246bd32f48aSKurt Zenker catch(const css::uno::RuntimeException&)
1247bd32f48aSKurt Zenker { throw; }
1248bd32f48aSKurt Zenker catch(const css::uno::Exception&)
1249bd32f48aSKurt Zenker { continue; }
1250bd32f48aSKurt Zenker }
1251bd32f48aSKurt Zenker
1252bd32f48aSKurt Zenker return css::uno::Reference< css::uno::XInterface >();
1253bd32f48aSKurt Zenker }
1254bd32f48aSKurt Zenker
impl_jumpToMark(const css::uno::Reference<css::frame::XFrame> & xFrame,const css::util::URL & aURL)1255e1b5a6d0SRüdiger Timm void LoadEnv::impl_jumpToMark(const css::uno::Reference< css::frame::XFrame >& xFrame,
1256e1b5a6d0SRüdiger Timm const css::util::URL& aURL )
1257e1b5a6d0SRüdiger Timm {
125818692cc1SOlivier Hallot if (aURL.Mark.isEmpty())
1259e1b5a6d0SRüdiger Timm return;
1260e1b5a6d0SRüdiger Timm
1261e1b5a6d0SRüdiger Timm css::uno::Reference< css::frame::XDispatchProvider > xProvider(xFrame, css::uno::UNO_QUERY);
1262e1b5a6d0SRüdiger Timm if (! xProvider.is())
1263e1b5a6d0SRüdiger Timm return;
1264e1b5a6d0SRüdiger Timm
1265e1b5a6d0SRüdiger Timm // SAFE ->
126685f7ed1cSStephan Bergmann osl::ClearableMutexGuard aReadLock(m_mutex);
1267fe1ac1bfSNoel Grandin css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
126885f7ed1cSStephan Bergmann aReadLock.clear();
1269e1b5a6d0SRüdiger Timm // <- SAFE
1270e1b5a6d0SRüdiger Timm
1271e1b5a6d0SRüdiger Timm css::util::URL aCmd;
1272e52779d2SNoel Grandin aCmd.Complete = ".uno:JumpToMark";
1273e1b5a6d0SRüdiger Timm
1274fe1ac1bfSNoel Grandin css::uno::Reference< css::util::XURLTransformer > xParser(css::util::URLTransformer::create(xContext));
1275e1b5a6d0SRüdiger Timm xParser->parseStrict(aCmd);
1276e1b5a6d0SRüdiger Timm
1277e1b5a6d0SRüdiger Timm css::uno::Reference< css::frame::XDispatch > xDispatcher = xProvider->queryDispatch(aCmd, SPECIALTARGET_SELF, 0);
1278e1b5a6d0SRüdiger Timm if (! xDispatcher.is())
1279e1b5a6d0SRüdiger Timm return;
1280e1b5a6d0SRüdiger Timm
1281e1b5a6d0SRüdiger Timm ::comphelper::SequenceAsHashMap lArgs;
12824f5f24a4SNoel Grandin lArgs[u"Bookmark"_ustr] <<= aURL.Mark;
1283e1b5a6d0SRüdiger Timm xDispatcher->dispatch(aCmd, lArgs.getAsConstPropertyValueList());
1284e1b5a6d0SRüdiger Timm }
1285e1b5a6d0SRüdiger Timm
impl_searchAlreadyLoaded()128677f6149cSKurt Zenker css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchAlreadyLoaded()
128777f6149cSKurt Zenker {
128885f7ed1cSStephan Bergmann osl::MutexGuard g(m_mutex);
128977f6149cSKurt Zenker
129077f6149cSKurt Zenker // such search is allowed for special requests only ...
1291c7114b66SAndrea Gelmini // or better it's not allowed for some requests in general :-)
129277f6149cSKurt Zenker if (
1293bac9a5d6SNoel Grandin ( ! TargetHelper::matchSpecialTarget(m_sTarget, TargetHelper::ESpecialTarget::Default) ) ||
12942ab40e9eSNoel Grandin m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_ASTEMPLATE , false) ||
1295ac113013SStephan Bergmann // (m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_HIDDEN() , false) == sal_True) ||
12962ab40e9eSNoel Grandin m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_OPENNEWVIEW, false)
129777f6149cSKurt Zenker )
129877f6149cSKurt Zenker {
129977f6149cSKurt Zenker return css::uno::Reference< css::frame::XFrame >();
130077f6149cSKurt Zenker }
130177f6149cSKurt Zenker
130277f6149cSKurt Zenker // check URL
1303c7114b66SAndrea Gelmini // May it's not useful to start expensive document search, if it
130477f6149cSKurt Zenker // can fail only .. because we load from a stream or model directly!
130577f6149cSKurt Zenker if (
1306bac9a5d6SNoel Grandin (ProtocolCheck::isProtocol(m_aURL.Complete, EProtocol::PrivateStream )) ||
1307bac9a5d6SNoel Grandin (ProtocolCheck::isProtocol(m_aURL.Complete, EProtocol::PrivateObject ))
130877f6149cSKurt Zenker /*TODO should be private:factory here tested too? */
130977f6149cSKurt Zenker )
131077f6149cSKurt Zenker {
131177f6149cSKurt Zenker return css::uno::Reference< css::frame::XFrame >();
131277f6149cSKurt Zenker }
131377f6149cSKurt Zenker
1314e2f97dccSIvan Timofeev // otherwise - iterate through the tasks of the desktop container
131577f6149cSKurt Zenker // to find out, which of them might contains the requested document
1316fe1ac1bfSNoel Grandin css::uno::Reference< css::frame::XDesktop2 > xSupplier = css::frame::Desktop::create( m_xContext );
1317952b806cSNoel Grandin css::uno::Reference< css::container::XIndexAccess > xTaskList = xSupplier->getFrames();
131877f6149cSKurt Zenker
131977f6149cSKurt Zenker if (!xTaskList.is())
132077f6149cSKurt Zenker return css::uno::Reference< css::frame::XFrame >(); // task list can be empty!
132177f6149cSKurt Zenker
1322a1bc5756SJesús Corrius // Note: To detect if a document was already loaded before
13239a2d1b9cSLionel Elie Mamane // we check URLs here only. But might the existing and the required
132477f6149cSKurt Zenker // document has different versions! Then its URLs are the same...
13252ab40e9eSNoel Grandin sal_Int16 nNewVersion = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_VERSION, sal_Int16(-1));
132677f6149cSKurt Zenker
1327ed2a2ab2SIvo Hinkelmann // will be used to save the first hidden frame referring the searched model
13289a2d1b9cSLionel Elie Mamane // Normally we are interested on visible frames... but if there is no such visible
1329a1bc5756SJesús Corrius // frame we refer to any hidden frame also (but as fallback only).
1330ed2a2ab2SIvo Hinkelmann css::uno::Reference< css::frame::XFrame > xHiddenTask;
1331ed2a2ab2SIvo Hinkelmann css::uno::Reference< css::frame::XFrame > xTask;
1332ed2a2ab2SIvo Hinkelmann
133377f6149cSKurt Zenker sal_Int32 count = xTaskList->getCount();
133477f6149cSKurt Zenker for (sal_Int32 i=0; i<count; ++i)
133577f6149cSKurt Zenker {
133677f6149cSKurt Zenker try
133777f6149cSKurt Zenker {
133877f6149cSKurt Zenker // locate model of task
133977f6149cSKurt Zenker // Note: Without a model there is no chance to decide if
134077f6149cSKurt Zenker // this task contains the searched document or not!
134177f6149cSKurt Zenker xTaskList->getByIndex(i) >>= xTask;
134277f6149cSKurt Zenker if (!xTask.is())
134377f6149cSKurt Zenker continue;
134477f6149cSKurt Zenker
134585467e7cSMiklos Vajna OUString sURL;
134677f6149cSKurt Zenker css::uno::Reference< css::frame::XController > xController = xTask->getController();
134777f6149cSKurt Zenker if (!xController.is())
1348ed2a2ab2SIvo Hinkelmann {
134985467e7cSMiklos Vajna // If we have no controller, then perhaps there is a load in progress. The frame
135085467e7cSMiklos Vajna // itself has the URL in this case.
135185467e7cSMiklos Vajna uno::Reference<beans::XPropertySet> xTaskProps(xTask, uno::UNO_QUERY);
135285467e7cSMiklos Vajna if (xTaskProps.is())
135385467e7cSMiklos Vajna {
13544f5f24a4SNoel Grandin xTaskProps->getPropertyValue(u"URL"_ustr) >>= sURL;
135585467e7cSMiklos Vajna }
135685467e7cSMiklos Vajna if (sURL.isEmpty())
135785467e7cSMiklos Vajna {
1358ed2a2ab2SIvo Hinkelmann xTask.clear();
135977f6149cSKurt Zenker continue;
1360ed2a2ab2SIvo Hinkelmann }
136185467e7cSMiklos Vajna }
136277f6149cSKurt Zenker
136385467e7cSMiklos Vajna uno::Reference<frame::XModel> xModel;
136485467e7cSMiklos Vajna if (sURL.isEmpty())
136585467e7cSMiklos Vajna {
136685467e7cSMiklos Vajna xModel = xController->getModel();
136777f6149cSKurt Zenker if (!xModel.is())
1368ed2a2ab2SIvo Hinkelmann {
1369ed2a2ab2SIvo Hinkelmann xTask.clear();
137077f6149cSKurt Zenker continue;
1371ed2a2ab2SIvo Hinkelmann }
137277f6149cSKurt Zenker
137377f6149cSKurt Zenker // don't check the complete URL here.
137477f6149cSKurt Zenker // use its main part - ignore optional jumpmarks!
137585467e7cSMiklos Vajna sURL = xModel->getURL();
137685467e7cSMiklos Vajna }
137708e2fc04SMikhail Voytenko if (!::utl::UCBContentHelper::EqualURLs( m_aURL.Main, sURL ))
1378ed2a2ab2SIvo Hinkelmann {
1379ed2a2ab2SIvo Hinkelmann xTask.clear ();
138077f6149cSKurt Zenker continue;
1381ed2a2ab2SIvo Hinkelmann }
138277f6149cSKurt Zenker
138377f6149cSKurt Zenker // get the original load arguments from the current document
138442cfb5d0SAndrea Gelmini // and decide if it's really the same then the one will be.
138577f6149cSKurt Zenker // It must be visible and must use the same file revision ...
138677f6149cSKurt Zenker // or must not have any file revision set (-1 == -1!)
138785467e7cSMiklos Vajna utl::MediaDescriptor lOldDocDescriptor;
138885467e7cSMiklos Vajna if (xModel.is())
138985467e7cSMiklos Vajna {
139085467e7cSMiklos Vajna lOldDocDescriptor = xModel->getArgs();
139177f6149cSKurt Zenker
139285467e7cSMiklos Vajna if (lOldDocDescriptor.getUnpackedValueOrDefault(
13932ab40e9eSNoel Grandin utl::MediaDescriptor::PROP_VERSION, sal_Int32(-1))
139485467e7cSMiklos Vajna != nNewVersion)
1395ed2a2ab2SIvo Hinkelmann {
1396ed2a2ab2SIvo Hinkelmann xTask.clear();
139777f6149cSKurt Zenker continue;
1398ed2a2ab2SIvo Hinkelmann }
139985467e7cSMiklos Vajna }
140077f6149cSKurt Zenker
1401ed2a2ab2SIvo Hinkelmann // Hidden frames are special.
1402ed2a2ab2SIvo Hinkelmann // They will be used as "last chance" if there is no visible frame pointing to the same model.
1403ed2a2ab2SIvo Hinkelmann // Safe the result but continue with current loop might be looking for other visible frames.
14042ab40e9eSNoel Grandin bool bIsHidden = lOldDocDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_HIDDEN, false);
14054250b25cSNoel Grandin if ( bIsHidden && ! xHiddenTask.is() )
1406ed2a2ab2SIvo Hinkelmann {
1407ed2a2ab2SIvo Hinkelmann xHiddenTask = xTask;
1408ed2a2ab2SIvo Hinkelmann xTask.clear ();
140977f6149cSKurt Zenker continue;
1410ed2a2ab2SIvo Hinkelmann }
141177f6149cSKurt Zenker
1412ed2a2ab2SIvo Hinkelmann // We found a visible task pointing to the right model ...
1413ed2a2ab2SIvo Hinkelmann // Break search.
1414ed2a2ab2SIvo Hinkelmann break;
1415ed2a2ab2SIvo Hinkelmann }
1416ba5a460bSPKEuS catch(const css::uno::RuntimeException&)
1417ba5a460bSPKEuS { throw; }
1418ed2a2ab2SIvo Hinkelmann catch(const css::uno::Exception&)
1419ed2a2ab2SIvo Hinkelmann { continue; }
1420ed2a2ab2SIvo Hinkelmann }
1421ed2a2ab2SIvo Hinkelmann
1422ed2a2ab2SIvo Hinkelmann css::uno::Reference< css::frame::XFrame > xResult;
1423ed2a2ab2SIvo Hinkelmann if (xTask.is())
1424ee4554b0SCaolán McNamara xResult = std::move(xTask);
14257d044841SCaolán McNamara else if (xHiddenTask.is())
1426ee4554b0SCaolán McNamara xResult = std::move(xHiddenTask);
1427ed2a2ab2SIvo Hinkelmann
1428ed2a2ab2SIvo Hinkelmann if (xResult.is())
1429ed2a2ab2SIvo Hinkelmann {
14309a2d1b9cSLionel Elie Mamane // Now we are sure, that this task includes the searched document.
14319a2d1b9cSLionel Elie Mamane // It's time to activate it. As special feature we try to jump internally
143277f6149cSKurt Zenker // if an optional jumpmark is given too.
143318692cc1SOlivier Hallot if (!m_aURL.Mark.isEmpty())
1434ed2a2ab2SIvo Hinkelmann impl_jumpToMark(xResult, m_aURL);
143577f6149cSKurt Zenker }
143677f6149cSKurt Zenker
1437ed2a2ab2SIvo Hinkelmann return xResult;
143877f6149cSKurt Zenker }
143977f6149cSKurt Zenker
14408ef4dc07SNoel Grandin // static
impl_isFrameAlreadyUsedForLoading(const css::uno::Reference<css::frame::XFrame> & xFrame)14418ef4dc07SNoel Grandin bool LoadEnv::impl_isFrameAlreadyUsedForLoading(const css::uno::Reference< css::frame::XFrame >& xFrame)
14420c917a22SKurt Zenker {
14430c917a22SKurt Zenker css::uno::Reference< css::document::XActionLockable > xLock(xFrame, css::uno::UNO_QUERY);
14440c917a22SKurt Zenker
14450c917a22SKurt Zenker // ? no lock interface ?
1446ad1fb1c3SAndrea Gelmini // Maybe it's an external written frame implementation :-(
1447c7114b66SAndrea Gelmini // Allowing using of it... but it can fail if it's not synchronized with our processes!
14480c917a22SKurt Zenker if (!xLock.is())
1449a6287e21SNoel Grandin return false;
14500c917a22SKurt Zenker
14519a2d1b9cSLionel Elie Mamane // Otherwise we have to look for any other existing lock.
14520c917a22SKurt Zenker return xLock->isActionLocked();
14530c917a22SKurt Zenker }
14540c917a22SKurt Zenker
impl_searchRecycleTarget()145577f6149cSKurt Zenker css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchRecycleTarget()
145677f6149cSKurt Zenker {
145777f6149cSKurt Zenker // SAFE -> ..................................
145885f7ed1cSStephan Bergmann osl::ClearableMutexGuard aReadLock(m_mutex);
145977f6149cSKurt Zenker
1460ffa0c246SRüdiger Timm // The special backing mode frame will be recycled by definition!
1461a1bc5756SJesús Corrius // It doesn't matter if somewhere wants to create a new view
1462ffa0c246SRüdiger Timm // or open a new untitled document...
14639771ab4bSAndrea Gelmini // The only exception from that - hidden frames!
14642ab40e9eSNoel Grandin if (m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_HIDDEN, false))
1465ffa0c246SRüdiger Timm return css::uno::Reference< css::frame::XFrame >();
1466ffa0c246SRüdiger Timm
1467952b806cSNoel Grandin css::uno::Reference< css::frame::XFramesSupplier > xSupplier = css::frame::Desktop::create( m_xContext );
1468d76d1555SNoel Grandin FrameListAnalyzer aTasksAnalyzer(xSupplier, css::uno::Reference< css::frame::XFrame >(), FrameAnalyzerFlags::BackingComponent);
1469ffa0c246SRüdiger Timm if (aTasksAnalyzer.m_xBackingComponent.is())
14700c917a22SKurt Zenker {
14710c917a22SKurt Zenker if (!impl_isFrameAlreadyUsedForLoading(aTasksAnalyzer.m_xBackingComponent))
1472b3e80e19SRüdiger Timm {
1473cc679439SMaxim Monastirsky m_bReactivateControllerOnError = true;
1474ffa0c246SRüdiger Timm return aTasksAnalyzer.m_xBackingComponent;
14750c917a22SKurt Zenker }
1476b3e80e19SRüdiger Timm }
1477ffa0c246SRüdiger Timm
14789a2d1b9cSLionel Elie Mamane // These states indicates a wish for creation of a new view in general.
147977f6149cSKurt Zenker if (
14802ab40e9eSNoel Grandin m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_ASTEMPLATE , false) ||
14812ab40e9eSNoel Grandin m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_OPENNEWVIEW, false)
148277f6149cSKurt Zenker )
148377f6149cSKurt Zenker {
148477f6149cSKurt Zenker return css::uno::Reference< css::frame::XFrame >();
148577f6149cSKurt Zenker }
148677f6149cSKurt Zenker
1487a1bc5756SJesús Corrius // On the other side some special URLs will open a new frame every time (expecting
14882ae6c2a5SRüdiger Timm // they can use the backing-mode frame!)
14892ae6c2a5SRüdiger Timm if (
1490bac9a5d6SNoel Grandin (ProtocolCheck::isProtocol(m_aURL.Complete, EProtocol::PrivateFactory )) ||
1491bac9a5d6SNoel Grandin (ProtocolCheck::isProtocol(m_aURL.Complete, EProtocol::PrivateStream )) ||
1492bac9a5d6SNoel Grandin (ProtocolCheck::isProtocol(m_aURL.Complete, EProtocol::PrivateObject ))
14932ae6c2a5SRüdiger Timm )
14942ae6c2a5SRüdiger Timm {
14952ae6c2a5SRüdiger Timm return css::uno::Reference< css::frame::XFrame >();
14962ae6c2a5SRüdiger Timm }
14972ae6c2a5SRüdiger Timm
14982ae6c2a5SRüdiger Timm // No backing frame! No special URL => recycle active task - if possible.
14992ae6c2a5SRüdiger Timm // Means - if it does not already contains a modified document, or
15002ae6c2a5SRüdiger Timm // use another office module.
150177f6149cSKurt Zenker css::uno::Reference< css::frame::XFrame > xTask = xSupplier->getActiveFrame();
150277f6149cSKurt Zenker
150377f6149cSKurt Zenker // not a real error - but might a focus problem!
150477f6149cSKurt Zenker if (!xTask.is())
150577f6149cSKurt Zenker return css::uno::Reference< css::frame::XFrame >();
150677f6149cSKurt Zenker
15077f436c1fSAndras Timar // not a real error - may it's a view only
150877f6149cSKurt Zenker css::uno::Reference< css::frame::XController > xController = xTask->getController();
150977f6149cSKurt Zenker if (!xController.is())
151077f6149cSKurt Zenker return css::uno::Reference< css::frame::XFrame >();
151177f6149cSKurt Zenker
15127f436c1fSAndras Timar // not a real error - may it's a db component instead of a full featured office document
151377f6149cSKurt Zenker css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
151477f6149cSKurt Zenker if (!xModel.is())
151577f6149cSKurt Zenker return css::uno::Reference< css::frame::XFrame >();
151677f6149cSKurt Zenker
1517db7a4413SGregg King // get some more information ...
151877f6149cSKurt Zenker
151977f6149cSKurt Zenker // A valid set URL means: there is already a location for this document.
152077f6149cSKurt Zenker // => it was saved there or opened from there. Such Documents can not be used here.
152177f6149cSKurt Zenker // We search for empty document ... created by a private:factory/ URL!
152277f6149cSKurt Zenker if (xModel->getURL().getLength()>0)
152377f6149cSKurt Zenker return css::uno::Reference< css::frame::XFrame >();
152477f6149cSKurt Zenker
152577f6149cSKurt Zenker // The old document must be unmodified ...
152677f6149cSKurt Zenker css::uno::Reference< css::util::XModifiable > xModified(xModel, css::uno::UNO_QUERY);
152777f6149cSKurt Zenker if (xModified->isModified())
152877f6149cSKurt Zenker return css::uno::Reference< css::frame::XFrame >();
152977f6149cSKurt Zenker
153078b4a1fbSNoel Grandin VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xTask->getContainerWindow());
1531ce32bfbfSRüdiger Timm if (pWindow && pWindow->IsInModalMode())
1532ce32bfbfSRüdiger Timm return css::uno::Reference< css::frame::XFrame >();
1533ce32bfbfSRüdiger Timm
153477f6149cSKurt Zenker // find out the application type of this document
153577f6149cSKurt Zenker // We can recycle only documents, which uses the same application
153677f6149cSKurt Zenker // then the new one.
153777f6149cSKurt Zenker SvtModuleOptions::EFactory eOldApp = SvtModuleOptions::ClassifyFactoryByModel(xModel);
153877f6149cSKurt Zenker SvtModuleOptions::EFactory eNewApp = SvtModuleOptions::ClassifyFactoryByURL (m_aURL.Complete, m_lMediaDescriptor.getAsConstPropertyValueList());
153977f6149cSKurt Zenker
154085f7ed1cSStephan Bergmann aReadLock.clear();
154177f6149cSKurt Zenker // <- SAFE ..................................
154277f6149cSKurt Zenker
154377f6149cSKurt Zenker if (eOldApp != eNewApp)
154477f6149cSKurt Zenker return css::uno::Reference< css::frame::XFrame >();
154577f6149cSKurt Zenker
15466f0e7c36SJulien Nabet // OK this task seems to be usable for recycling
154777f6149cSKurt Zenker // But we should mark it as such - means set an action lock.
15489bac4d41STakeshi Abe // Otherwise it would be used more than ones or will be destroyed
154977f6149cSKurt Zenker // by a close() or terminate() request.
155077f6149cSKurt Zenker // But if such lock already exist ... it means this task is used for
155177f6149cSKurt Zenker // any other operation already. Don't use it then.
15520c917a22SKurt Zenker if (impl_isFrameAlreadyUsedForLoading(xTask))
155377f6149cSKurt Zenker return css::uno::Reference< css::frame::XFrame >();
155477f6149cSKurt Zenker
1555ce32bfbfSRüdiger Timm // OK - there is a valid target frame.
1556ce32bfbfSRüdiger Timm // But may be it contains already a document.
1557a1bc5756SJesús Corrius // Then we have to ask it, if it allows recycling of this frame .-)
1558a6287e21SNoel Grandin bool bReactivateOldControllerOnError = false;
1559ce32bfbfSRüdiger Timm css::uno::Reference< css::frame::XController > xOldDoc = xTask->getController();
1560ce32bfbfSRüdiger Timm if (xOldDoc.is())
1561ce32bfbfSRüdiger Timm {
1562acd820fdSKatarina Behrens utl::MediaDescriptor lOldDocDescriptor(xModel->getArgs());
1563acd820fdSKatarina Behrens
156461e1e041SJan-Marek Glogowski // replaceable document
15652ab40e9eSNoel Grandin if (!lOldDocDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_REPLACEABLE, false))
1566acd820fdSKatarina Behrens return css::uno::Reference< css::frame::XFrame >();
1567acd820fdSKatarina Behrens
1568ed467869SStephan Bergmann bReactivateOldControllerOnError = xOldDoc->suspend(true);
1569ce32bfbfSRüdiger Timm if (! bReactivateOldControllerOnError)
1570ce32bfbfSRüdiger Timm return css::uno::Reference< css::frame::XFrame >();
1571ce32bfbfSRüdiger Timm }
1572ce32bfbfSRüdiger Timm
157377f6149cSKurt Zenker // SAFE -> ..................................
15745a824268SMike Kaganski {
15755a824268SMike Kaganski osl::MutexGuard aWriteLock(m_mutex);
1576ce32bfbfSRüdiger Timm
15770c917a22SKurt Zenker css::uno::Reference< css::document::XActionLockable > xLock(xTask, css::uno::UNO_QUERY);
157877f6149cSKurt Zenker if (!m_aTargetLock.setResource(xLock))
157977f6149cSKurt Zenker return css::uno::Reference< css::frame::XFrame >();
1580ce32bfbfSRüdiger Timm
1581ce32bfbfSRüdiger Timm m_bReactivateControllerOnError = bReactivateOldControllerOnError;
15825a824268SMike Kaganski }
158377f6149cSKurt Zenker // <- SAFE ..................................
158477f6149cSKurt Zenker
158577f6149cSKurt Zenker return xTask;
158677f6149cSKurt Zenker }
158777f6149cSKurt Zenker
impl_reactForLoadingState()158877f6149cSKurt Zenker void LoadEnv::impl_reactForLoadingState()
158977f6149cSKurt Zenker {
159077f6149cSKurt Zenker /*TODO reset action locks */
159177f6149cSKurt Zenker
159277f6149cSKurt Zenker // SAFE -> ----------------------------------
159385f7ed1cSStephan Bergmann osl::ClearableMutexGuard aReadLock(m_mutex);
159477f6149cSKurt Zenker
159577f6149cSKurt Zenker if (m_bLoaded)
159677f6149cSKurt Zenker {
159777f6149cSKurt Zenker // Bring the new loaded document to front (if allowed!).
159877f6149cSKurt Zenker // Note: We show new created frames here only.
1599eab0904fSAndrea Gelmini // We don't hide already visible frames here ...
160077f6149cSKurt Zenker css::uno::Reference< css::awt::XWindow > xWindow = m_xTargetFrame->getContainerWindow();
16012ab40e9eSNoel Grandin bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_HIDDEN, false);
16022ab40e9eSNoel Grandin bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_MINIMIZED, false);
1603d239ac79STibor Nagy bool bStartPres = m_lMediaDescriptor.contains("StartPresentation");
1604d239ac79STibor Nagy
1605e0b930e1SVasily Melenchuk VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xWindow);
160677f6149cSKurt Zenker
1607965cc9c2SJens-Heiner Rechtien if (bMinimized)
1608965cc9c2SJens-Heiner Rechtien {
16094bd2ed6aSNorbert Thiebaud SolarMutexGuard aSolarGuard;
1610f5ca04caSThomas Arnhold // check for system window is necessary to guarantee correct pointer cast!
1611965cc9c2SJens-Heiner Rechtien if (pWindow && pWindow->IsSystemWindow())
161278b4a1fbSNoel Grandin static_cast<WorkWindow*>(pWindow.get())->Minimize();
1613965cc9c2SJens-Heiner Rechtien }
1614d239ac79STibor Nagy else if (!bHidden && !bStartPres)
161577f6149cSKurt Zenker {
16162a993534SKurt Zenker // show frame ... if it's not still visible ...
16172a993534SKurt Zenker // But do nothing if it's already visible!
161842d197efSMike Kaganski impl_makeFrameWindowVisible(xWindow, !m_bFocusedAndToFront && shouldFocusAndToFront());
161977f6149cSKurt Zenker }
162077f6149cSKurt Zenker
1621e0b930e1SVasily Melenchuk if (pWindow)
1622e0b930e1SVasily Melenchuk pWindow->FlashWindow();
1623e0b930e1SVasily Melenchuk
1624bd32f48aSKurt Zenker // Note: Only if an existing property "FrameName" is given by this media descriptor,
1625a1bc5756SJesús Corrius // it should be used. Otherwise we should do nothing. May be the outside code has already
1626bd32f48aSKurt Zenker // set a frame name on the target!
16272ab40e9eSNoel Grandin utl::MediaDescriptor::const_iterator pFrameName = m_lMediaDescriptor.find(utl::MediaDescriptor::PROP_FRAMENAME);
1628bd32f48aSKurt Zenker if (pFrameName != m_lMediaDescriptor.end())
1629bd32f48aSKurt Zenker {
16301946794aSLuboš Luňák OUString sFrameName;
1631bd32f48aSKurt Zenker pFrameName->second >>= sFrameName;
1632a1bc5756SJesús Corrius // Check the name again. e.g. "_default" isn't allowed.
1633bd32f48aSKurt Zenker // On the other side "_beamer" is a valid name :-)
163477f6149cSKurt Zenker if (TargetHelper::isValidNameForFrame(sFrameName))
163577f6149cSKurt Zenker m_xTargetFrame->setName(sFrameName);
163677f6149cSKurt Zenker }
1637bd32f48aSKurt Zenker }
1638c7e172b2SJens-Heiner Rechtien else if (m_bReactivateControllerOnError)
163977f6149cSKurt Zenker {
164077f6149cSKurt Zenker // Try to reactivate the old document (if any exists!)
164177f6149cSKurt Zenker css::uno::Reference< css::frame::XController > xOldDoc = m_xTargetFrame->getController();
164277f6149cSKurt Zenker // clear does not depend from reactivation state of a might existing old document!
16439a2d1b9cSLionel Elie Mamane // We must make sure, that a might following getTargetComponent() call does not return
164477f6149cSKurt Zenker // the old document!
164577f6149cSKurt Zenker m_xTargetFrame.clear();
164677f6149cSKurt Zenker if (xOldDoc.is())
164777f6149cSKurt Zenker {
1648ed467869SStephan Bergmann bool bReactivated = xOldDoc->suspend(false);
164977f6149cSKurt Zenker if (!bReactivated)
165077f6149cSKurt Zenker throw LoadEnvException(LoadEnvException::ID_COULD_NOT_REACTIVATE_CONTROLLER);
1651a6287e21SNoel Grandin m_bReactivateControllerOnError = false;
165277f6149cSKurt Zenker }
165377f6149cSKurt Zenker }
1654c7e172b2SJens-Heiner Rechtien else if (m_bCloseFrameOnError)
165577f6149cSKurt Zenker {
165677f6149cSKurt Zenker // close empty frames
165777f6149cSKurt Zenker css::uno::Reference< css::util::XCloseable > xCloseable (m_xTargetFrame, css::uno::UNO_QUERY);
165877f6149cSKurt Zenker
165977f6149cSKurt Zenker try
166077f6149cSKurt Zenker {
166177f6149cSKurt Zenker if (xCloseable.is())
1662ed467869SStephan Bergmann xCloseable->close(true);
1663952b806cSNoel Grandin else if (m_xTargetFrame.is())
1664952b806cSNoel Grandin m_xTargetFrame->dispose();
166577f6149cSKurt Zenker }
166677f6149cSKurt Zenker catch(const css::util::CloseVetoException&)
166777f6149cSKurt Zenker {}
166877f6149cSKurt Zenker catch(const css::lang::DisposedException&)
166977f6149cSKurt Zenker {}
167077f6149cSKurt Zenker m_xTargetFrame.clear();
167177f6149cSKurt Zenker }
167277f6149cSKurt Zenker
1673e2a4aa0eSKurt Zenker // This max force an implicit closing of our target frame ...
16747799914bSXiaofei Zhang // e.g. in case close(sal_True) was called before and the frame
1675e2a4aa0eSKurt Zenker // kill itself if our external use-lock is released here!
1676a1bc5756SJesús Corrius // That's why we release this lock AFTER ALL OPERATIONS on this frame
1677a1bc5756SJesús Corrius // are finished. The frame itself must handle then
1678e2a4aa0eSKurt Zenker // this situation gracefully.
1679e2a4aa0eSKurt Zenker m_aTargetLock.freeResource();
1680e2a4aa0eSKurt Zenker
1681e2a4aa0eSKurt Zenker // Last but not least :-)
1682e2a4aa0eSKurt Zenker // We have to clear the current media descriptor.
1683a1bc5756SJesús Corrius // Otherwise it hold a might existing stream open!
1684e2a4aa0eSKurt Zenker m_lMediaDescriptor.clear();
1685e2a4aa0eSKurt Zenker
1686c7e172b2SJens-Heiner Rechtien css::uno::Any aRequest;
1687c7e172b2SJens-Heiner Rechtien bool bThrow = false;
1688da8bfce2SStephan Bergmann if ( !m_bLoaded && m_pQuietInteraction.is() && m_pQuietInteraction->wasUsed() )
1689c7e172b2SJens-Heiner Rechtien {
1690c7e172b2SJens-Heiner Rechtien aRequest = m_pQuietInteraction->getRequest();
1691da8bfce2SStephan Bergmann m_pQuietInteraction.clear();
1692c7e172b2SJens-Heiner Rechtien bThrow = true;
1693c7e172b2SJens-Heiner Rechtien }
1694c7e172b2SJens-Heiner Rechtien
169585f7ed1cSStephan Bergmann aReadLock.clear();
1696c7e172b2SJens-Heiner Rechtien
1697c7e172b2SJens-Heiner Rechtien if (bThrow)
1698c7e172b2SJens-Heiner Rechtien {
1699d69335c9SFrank Schoenheit [fs] if ( aRequest.isExtractableTo( ::cppu::UnoType< css::uno::Exception >::get() ) )
17005a10e33fSStephan Bergmann throw LoadEnvException(
17014f5f24a4SNoel Grandin LoadEnvException::ID_GENERAL_ERROR, u"interaction request"_ustr,
17025a10e33fSStephan Bergmann aRequest);
1703c7e172b2SJens-Heiner Rechtien }
1704c7e172b2SJens-Heiner Rechtien
170577f6149cSKurt Zenker // <- SAFE ----------------------------------
170677f6149cSKurt Zenker }
170777f6149cSKurt Zenker
shouldFocusAndToFront() const170842d197efSMike Kaganski bool LoadEnv::shouldFocusAndToFront() const
170942d197efSMike Kaganski {
171042d197efSMike Kaganski bool const preview(
171142d197efSMike Kaganski m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_PREVIEW, false));
1712e0b930e1SVasily Melenchuk return !preview;
171342d197efSMike Kaganski }
171442d197efSMike Kaganski
17158ef4dc07SNoel Grandin // static
impl_makeFrameWindowVisible(const css::uno::Reference<css::awt::XWindow> & xWindow,bool bForceToFront)17162a993534SKurt Zenker void LoadEnv::impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::XWindow >& xWindow ,
1717a6287e21SNoel Grandin bool bForceToFront)
17182a993534SKurt Zenker {
17194bd2ed6aSNorbert Thiebaud SolarMutexGuard aSolarGuard;
172078b4a1fbSNoel Grandin VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xWindow);
1721ff25a4a6SNoel Grandin if ( !pWindow )
1722ff25a4a6SNoel Grandin return;
1723ff25a4a6SNoel Grandin
1724f0fbf30aSMike Kaganski if (pWindow->IsVisible() && bForceToFront)
1725e9230b2bSMark Hung pWindow->ToTop( ToTopFlags::RestoreWhenMin | ToTopFlags::ForegroundTask );
1726cfdbe09cSPhilipp Lohmann [pl] else
1727f0fbf30aSMike Kaganski pWindow->Show(true, bForceToFront ? ShowFlags::ForegroundTask : ShowFlags::NONE);
172823740dc4SVladimir Glazounov }
17292a993534SKurt Zenker
impl_applyPersistentWindowState(const css::uno::Reference<css::awt::XWindow> & xWindow)17304543350eSVladimir Glazounov void LoadEnv::impl_applyPersistentWindowState(const css::uno::Reference< css::awt::XWindow >& xWindow)
17314543350eSVladimir Glazounov {
17324543350eSVladimir Glazounov // no window -> action not possible
17334543350eSVladimir Glazounov if (!xWindow.is())
17344543350eSVladimir Glazounov return;
17354543350eSVladimir Glazounov
17364543350eSVladimir Glazounov // window already visible -> do nothing! If we use a "recycle frame" for loading ...
17374543350eSVladimir Glazounov // the current position and size must be used.
17384543350eSVladimir Glazounov css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(xWindow, css::uno::UNO_QUERY);
17394543350eSVladimir Glazounov if (
17404543350eSVladimir Glazounov (xVisibleCheck.is() ) &&
17414543350eSVladimir Glazounov (xVisibleCheck->isVisible())
17424543350eSVladimir Glazounov )
17434543350eSVladimir Glazounov return;
17444543350eSVladimir Glazounov
17457487c382SOliver Bolte // SOLAR SAFE ->
17465a824268SMike Kaganski {
17475a824268SMike Kaganski SolarMutexGuard aSolarGuard1;
17487487c382SOliver Bolte
174978b4a1fbSNoel Grandin VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xWindow);
175047cda279SCaolán McNamara if (!pWindow)
175147cda279SCaolán McNamara return;
175247cda279SCaolán McNamara
1753a6287e21SNoel Grandin bool bSystemWindow = pWindow->IsSystemWindow();
17548c00536dSNoel Grandin bool bWorkWindow = (pWindow->GetType() == WindowType::WORKWINDOW);
17554543350eSVladimir Glazounov
17564543350eSVladimir Glazounov if (!bSystemWindow && !bWorkWindow)
17574543350eSVladimir Glazounov return;
17584543350eSVladimir Glazounov
1759eab0904fSAndrea Gelmini // don't overwrite this special state!
176078b4a1fbSNoel Grandin WorkWindow* pWorkWindow = static_cast<WorkWindow*>(pWindow.get());
17614543350eSVladimir Glazounov if (pWorkWindow->IsMinimized())
17624543350eSVladimir Glazounov return;
17635a824268SMike Kaganski }
17647487c382SOliver Bolte // <- SOLAR SAFE
17657487c382SOliver Bolte
17664543350eSVladimir Glazounov // SAFE ->
176785f7ed1cSStephan Bergmann osl::ClearableMutexGuard aReadLock(m_mutex);
17684543350eSVladimir Glazounov
17694543350eSVladimir Glazounov // no filter -> no module -> no persistent window state
17701946794aSLuboš Luňák OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(
17712ab40e9eSNoel Grandin utl::MediaDescriptor::PROP_FILTERNAME,
17721946794aSLuboš Luňák OUString());
177318692cc1SOlivier Hallot if (sFilter.isEmpty())
17744543350eSVladimir Glazounov return;
17754543350eSVladimir Glazounov
1776fe1ac1bfSNoel Grandin css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
17774543350eSVladimir Glazounov
177885f7ed1cSStephan Bergmann aReadLock.clear();
17794543350eSVladimir Glazounov // <- SAFE
17804543350eSVladimir Glazounov
17814543350eSVladimir Glazounov try
17824543350eSVladimir Glazounov {
17834543350eSVladimir Glazounov // retrieve the module name from the filter configuration
17844543350eSVladimir Glazounov css::uno::Reference< css::container::XNameAccess > xFilterCfg(
1785fe1ac1bfSNoel Grandin xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_FILTERFACTORY, xContext),
17864543350eSVladimir Glazounov css::uno::UNO_QUERY_THROW);
17874543350eSVladimir Glazounov ::comphelper::SequenceAsHashMap lProps (xFilterCfg->getByName(sFilter));
1788c5376ef6SStephan Bergmann OUString sModule = lProps.getUnpackedValueOrDefault(FILTER_PROPNAME_ASCII_DOCUMENTSERVICE, OUString());
17894543350eSVladimir Glazounov
17904543350eSVladimir Glazounov // get access to the configuration of this office module
17914256c764SLuboš Luňák css::uno::Reference< css::container::XNameAccess > xModuleCfg(officecfg::Setup::Office::Factories::get());
17924543350eSVladimir Glazounov
17934543350eSVladimir Glazounov // read window state from the configuration
17944543350eSVladimir Glazounov // and apply it on the window.
17954543350eSVladimir Glazounov // Do nothing, if no configuration entry exists!
17961946794aSLuboš Luňák OUString sWindowState;
179757448212STor Lillqvist
179857448212STor Lillqvist // Don't look for persistent window attributes when used through LibreOfficeKit
179957448212STor Lillqvist if( !comphelper::LibreOfficeKit::isActive() )
18004f5f24a4SNoel Grandin comphelper::ConfigurationHelper::readRelativeKey(xModuleCfg, sModule, u"ooSetupFactoryWindowAttributes"_ustr) >>= sWindowState;
180157448212STor Lillqvist
180218692cc1SOlivier Hallot if (!sWindowState.isEmpty())
18037487c382SOliver Bolte {
18047487c382SOliver Bolte // SOLAR SAFE ->
18054bd2ed6aSNorbert Thiebaud SolarMutexGuard aSolarGuard;
18067487c382SOliver Bolte
18077487c382SOliver Bolte // We have to retrieve the window pointer again. Because nobody can guarantee
18087487c382SOliver Bolte // that the XWindow was not disposed in between .-)
18097487c382SOliver Bolte // But if we get a valid pointer we can be sure, that it's the system window pointer
1810a1bc5756SJesús Corrius // we already checked and used before. Because nobody recycle the same uno reference for
18117487c382SOliver Bolte // a new internal c++ implementation ... hopefully .-))
181278b4a1fbSNoel Grandin VclPtr<vcl::Window> pWindowCheck = VCLUnoHelper::GetWindow(xWindow);
18137487c382SOliver Bolte if (! pWindowCheck)
18147487c382SOliver Bolte return;
18157487c382SOliver Bolte
181678b4a1fbSNoel Grandin SystemWindow* pSystemWindow = static_cast<SystemWindow*>(pWindowCheck.get());
1817116b9d6dSMike Kaganski pSystemWindow->SetWindowState(sWindowState);
18187487c382SOliver Bolte // <- SOLAR SAFE
18197487c382SOliver Bolte }
18204543350eSVladimir Glazounov }
1821ba5a460bSPKEuS catch(const css::uno::RuntimeException&)
1822ba5a460bSPKEuS { throw; }
18234543350eSVladimir Glazounov catch(const css::uno::Exception&)
18244543350eSVladimir Glazounov {}
18254543350eSVladimir Glazounov }
18264543350eSVladimir Glazounov
182777f6149cSKurt Zenker } // namespace framework
18283d698bcaSJens-Heiner Rechtien
18298694d2bcSSebastian Spaeth /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1830