summaryrefslogtreecommitdiffstats
path: root/desktop/source/app/appinit.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/source/app/appinit.cxx')
-rw-r--r--desktop/source/app/appinit.cxx274
1 files changed, 274 insertions, 0 deletions
diff --git a/desktop/source/app/appinit.cxx b/desktop/source/app/appinit.cxx
new file mode 100644
index 000000000..cff0a684c
--- /dev/null
+++ b/desktop/source/app/appinit.cxx
@@ -0,0 +1,274 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <algorithm>
+
+#include <app.hxx>
+#include <dp_shared.hxx>
+#include "cmdlineargs.hxx"
+#include <strings.hrc>
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/ucb/UniversalContentBroker.hpp>
+#include <cppuhelper/bootstrap.hxx>
+#include <officecfg/Setup.hxx>
+#include <osl/file.hxx>
+#include <rtl/bootstrap.hxx>
+#include <sal/log.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <rtl/instance.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <unotools/tempfile.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/pathoptions.hxx>
+#include <map>
+
+using namespace desktop;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::ucb;
+
+namespace desktop
+{
+
+
+static void configureUcb()
+{
+ // For backwards compatibility, in case some code still uses plain
+ // createInstance w/o args directly to obtain an instance:
+ UniversalContentBroker::create(comphelper::getProcessComponentContext());
+}
+
+void Desktop::InitApplicationServiceManager()
+{
+ Reference<XMultiServiceFactory> sm;
+#ifdef ANDROID
+ OUString aUnoRc( "file:///assets/program/unorc" );
+ sm.set(
+ cppu::defaultBootstrap_InitialComponentContext( aUnoRc )->getServiceManager(),
+ UNO_QUERY_THROW);
+#elif defined(IOS)
+ OUString uri( "$APP_DATA_DIR" );
+ rtl_bootstrap_expandMacros( &uri.pData );
+ OUString aUnoRc("file://" + uri + "/unorc");
+ sm.set(
+ cppu::defaultBootstrap_InitialComponentContext( aUnoRc )->getServiceManager(),
+ UNO_QUERY_THROW);
+#else
+ sm.set(
+ cppu::defaultBootstrap_InitialComponentContext()->getServiceManager(),
+ UNO_QUERY_THROW);
+#endif
+ comphelper::setProcessServiceFactory(sm);
+}
+
+void Desktop::RegisterServices(Reference< XComponentContext > const & context)
+{
+ if( m_bServicesRegistered )
+ return;
+
+ // interpret command line arguments
+ CommandLineArgs& rCmdLine = GetCommandLineArgs();
+
+ // Headless mode for FAT Office, auto cancels any dialogs that popup
+ if (rCmdLine.IsEventTesting())
+ Application::EnableEventTestingMode();
+ else if (rCmdLine.IsHeadless())
+ Application::EnableHeadlessMode(false);
+
+ // read accept string from configuration
+ OUString conDcpCfg(
+ officecfg::Setup::Office::ooSetupConnectionURL::get(context));
+ if (!conDcpCfg.isEmpty()) {
+ createAcceptor(conDcpCfg);
+ }
+
+ std::vector< OUString > const & conDcp = rCmdLine.GetAccept();
+ for (auto const& elem : conDcp)
+ {
+ createAcceptor(elem);
+ }
+
+ configureUcb();
+
+ CreateTemporaryDirectory();
+ m_bServicesRegistered = true;
+}
+
+typedef std::map< OUString, css::uno::Reference<css::lang::XInitialization> > AcceptorMap;
+
+namespace
+{
+ struct acceptorMap : public rtl::Static< AcceptorMap, acceptorMap > {};
+ struct CurrentTempURL : public rtl::Static< OUString, CurrentTempURL > {};
+}
+
+static bool bAccept = false;
+
+void Desktop::createAcceptor(const OUString& aAcceptString)
+{
+ // check whether the requested acceptor already exists
+ AcceptorMap &rMap = acceptorMap::get();
+ AcceptorMap::const_iterator pIter = rMap.find(aAcceptString);
+ if (pIter != rMap.end() )
+ return;
+
+ Sequence< Any > aSeq( 2 );
+ aSeq[0] <<= aAcceptString;
+ aSeq[1] <<= bAccept;
+ Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ Reference<XInitialization> rAcceptor(
+ xContext->getServiceManager()->createInstanceWithContext("com.sun.star.office.Acceptor", xContext),
+ UNO_QUERY );
+ if ( rAcceptor.is() )
+ {
+ try
+ {
+ rAcceptor->initialize( aSeq );
+ rMap.emplace(aAcceptString, rAcceptor);
+ }
+ catch (const css::uno::Exception&)
+ {
+ // no error handling needed...
+ // acceptor just won't come up
+ TOOLS_WARN_EXCEPTION( "desktop.app", "Acceptor could not be created");
+ }
+ }
+ else
+ {
+ // there is already an acceptor with this description
+ SAL_WARN( "desktop.app", "Acceptor already exists.");
+ }
+}
+
+namespace {
+
+class enable
+{
+ private:
+ Sequence<Any> m_aSeq;
+ public:
+ enable() : m_aSeq(1) {
+ m_aSeq[0] <<= true;
+ }
+ void operator() (const AcceptorMap::value_type& val) {
+ if (val.second.is()) {
+ val.second->initialize(m_aSeq);
+ }
+ }
+};
+
+}
+
+// enable acceptors
+IMPL_STATIC_LINK_NOARG(Desktop, EnableAcceptors_Impl, void*, void)
+{
+ if (!bAccept)
+ {
+ // from now on, all new acceptors are enabled
+ bAccept = true;
+ // enable existing acceptors by calling initialize(true)
+ // on all existing acceptors
+ AcceptorMap &rMap = acceptorMap::get();
+ std::for_each(rMap.begin(), rMap.end(), enable());
+ }
+}
+
+void Desktop::destroyAcceptor(const OUString& aAcceptString)
+{
+ // special case stop all acceptors
+ AcceptorMap &rMap = acceptorMap::get();
+ if (aAcceptString == "all") {
+ rMap.clear();
+
+ } else {
+ // try to remove acceptor from map
+ AcceptorMap::const_iterator pIter = rMap.find(aAcceptString);
+ if (pIter != rMap.end() ) {
+ // remove reference from map
+ // this is the last reference and the acceptor will be destructed
+ rMap.erase(aAcceptString);
+ } else {
+ SAL_WARN( "desktop.app", "Found no acceptor to remove");
+ }
+ }
+}
+
+
+void Desktop::DeregisterServices()
+{
+ // stop all acceptors by clearing the map
+ acceptorMap::get().clear();
+}
+
+void Desktop::CreateTemporaryDirectory()
+{
+ OUString aTempBaseURL;
+ try
+ {
+ SvtPathOptions aOpt;
+ aTempBaseURL = aOpt.GetTempPath();
+ }
+ catch (RuntimeException& e)
+ {
+ // Catch runtime exception here: We have to add language dependent info
+ // to the exception message. Fallback solution uses hard coded string.
+ OUString aMsg = DpResId(STR_BOOTSTRAP_ERR_NO_PATHSET_SERVICE);
+ e.Message = aMsg + e.Message;
+ throw;
+ }
+
+ // create new current temporary directory
+ OUString aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempBaseURL );
+ if ( aTempPath.isEmpty()
+ && ::osl::File::getTempDirURL( aTempBaseURL ) == osl::FileBase::E_None )
+ {
+ aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempBaseURL );
+ }
+
+ // set new current temporary directory
+ OUString aRet;
+ if (osl::FileBase::getFileURLFromSystemPath( aTempPath, aRet )
+ != osl::FileBase::E_None)
+ {
+ aRet.clear();
+ }
+ CurrentTempURL::get() = aRet;
+}
+
+void Desktop::RemoveTemporaryDirectory()
+{
+ // remove current temporary directory
+ OUString &rCurrentTempURL = CurrentTempURL::get();
+ if ( !rCurrentTempURL.isEmpty() )
+ {
+ ::utl::UCBContentHelper::Kill( rCurrentTempURL );
+ }
+}
+
+} // namespace desktop
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */