summaryrefslogtreecommitdiffstats
path: root/desktop/source/app
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2016-10-12 16:27:22 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2016-10-12 16:31:13 +0200
commitd79ac386cd959eacd25a0e0afbc0e995b08eec18 (patch)
tree52d4c70380840a699035c2849a51e427ee912f87 /desktop/source/app
parentAvoid one more crash on switching to pattern tab (diff)
downloadcore-d79ac386cd959eacd25a0e0afbc0e995b08eec18.tar.gz
core-d79ac386cd959eacd25a0e0afbc0e995b08eec18.zip
Removed by-error-pushed desktop/source/app/app.cxx.orig
Change-Id: I87a25028b82f7f6d107b2b234e20a9af6382d113
Diffstat (limited to 'desktop/source/app')
-rw-r--r--desktop/source/app/app.cxx.orig2735
1 files changed, 0 insertions, 2735 deletions
diff --git a/desktop/source/app/app.cxx.orig b/desktop/source/app/app.cxx.orig
deleted file mode 100644
index a9d10c3a99ba..000000000000
--- a/desktop/source/app/app.cxx.orig
+++ /dev/null
@@ -1,2735 +0,0 @@
-/* -*- 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 <config_features.h>
-#include <config_folders.h>
-
-#include <sal/config.h>
-
-#include <iostream>
-#if defined UNX
-#include <signal.h>
-#endif
-
-#include "app.hxx"
-#include "desktop.hrc"
-#include "cmdlineargs.hxx"
-#include "cmdlinehelp.hxx"
-#include "dispatchwatcher.hxx"
-#include "lockfile.hxx"
-#include "userinstall.hxx"
-#include "desktopcontext.hxx"
-#include "migration.hxx"
-
-#include <svl/languageoptions.hxx>
-#include <svtools/javacontext.hxx>
-#include <com/sun/star/beans/XPropertySet.hpp>
-#include <com/sun/star/frame/theAutoRecovery.hpp>
-#include <com/sun/star/frame/theGlobalEventBroadcaster.hpp>
-#include <com/sun/star/frame/SessionListener.hpp>
-#include <com/sun/star/frame/XSessionManagerListener.hpp>
-#include <com/sun/star/frame/XSynchronousDispatch.hpp>
-#include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
-#include <com/sun/star/configuration/CorruptedConfigurationException.hpp>
-#include <com/sun/star/configuration/theDefaultProvider.hpp>
-#include <com/sun/star/util/XFlushable.hpp>
-#include <com/sun/star/util/XModifiable.hpp>
-#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
-#include <com/sun/star/frame/Desktop.hpp>
-#include <com/sun/star/frame/StartModule.hpp>
-#include <com/sun/star/frame/XComponentLoader.hpp>
-#include <com/sun/star/view/XPrintable.hpp>
-#include <com/sun/star/awt/XTopWindow.hpp>
-#include <com/sun/star/util/URLTransformer.hpp>
-#include <com/sun/star/util/XURLTransformer.hpp>
-#include <com/sun/star/frame/XDispatchProvider.hpp>
-#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
-#include <com/sun/star/configuration/MissingBootstrapFileException.hpp>
-#include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
-#include <com/sun/star/configuration/InstallationIncompleteException.hpp>
-#include <com/sun/star/configuration/backend/BackendSetupException.hpp>
-#include <com/sun/star/configuration/backend/BackendAccessException.hpp>
-#include <com/sun/star/task/theJobExecutor.hpp>
-#include <com/sun/star/task/OfficeRestartManager.hpp>
-#include <com/sun/star/task/XRestartManager.hpp>
-#include <com/sun/star/document/XDocumentEventListener.hpp>
-#include <com/sun/star/frame/theUICommandDescription.hpp>
-#include <com/sun/star/ui/theUIElementFactoryManager.hpp>
-#include <com/sun/star/ui/theWindowStateConfiguration.hpp>
-#include <com/sun/star/frame/thePopupMenuControllerFactory.hpp>
-#include <com/sun/star/office/Quickstart.hpp>
-
-#include <desktop/exithelper.h>
-#include <sal/log.hxx>
-#include <toolkit/helper/vclunohelper.hxx>
-#include <comphelper/configuration.hxx>
-#include <comphelper/fileurl.hxx>
-#include <comphelper/processfactory.hxx>
-#include <comphelper/backupfilehelper.hxx>
-#include <unotools/bootstrap.hxx>
-#include <unotools/configmgr.hxx>
-#include <unotools/moduleoptions.hxx>
-#include <unotools/localfilehelper.hxx>
-#include <officecfg/Office/Common.hxx>
-#include <officecfg/Office/Recovery.hxx>
-#include <officecfg/Setup.hxx>
-#include <osl/file.hxx>
-#include <osl/process.h>
-#include <rtl/uri.hxx>
-#include <unotools/pathoptions.hxx>
-#include <svtools/miscopt.hxx>
-#include <svtools/menuoptions.hxx>
-#include <rtl/bootstrap.hxx>
-#include <vcl/help.hxx>
-#include <vcl/layout.hxx>
-#include <vcl/settings.hxx>
-#include <sfx2/sfx.hrc>
-#include <sfx2/app.hxx>
-#include <svl/itemset.hxx>
-#include <svl/eitem.hxx>
-#include <basic/sbstar.hxx>
-#include <desktop/crashreport.hxx>
-
-#include <svtools/fontsubstconfig.hxx>
-#include <svtools/accessibilityoptions.hxx>
-#include <svtools/apearcfg.hxx>
-#include <vcl/graphicfilter.hxx>
-
-#include "langselect.hxx"
-
-#include <config_telepathy.h>
-
-#if ENABLE_TELEPATHY
-#include <tubes/manager.hxx>
-#endif
-
-#if HAVE_FEATURE_BREAKPAD
-#include <fstream>
-#endif
-
-#if defined MACOSX
-#include <errno.h>
-#include <sys/wait.h>
-#endif
-
-#ifdef _WIN32
-#ifdef _MSC_VER
-#pragma warning(push, 1) /* disable warnings within system headers */
-#pragma warning (disable: 4005)
-#endif
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-#endif //WNT
-
-#if defined(_WIN32)
-#include <process.h>
-#define GETPID _getpid
-#else
-#include <unistd.h>
-#define GETPID getpid
-#endif
-
-using namespace ::com::sun::star::awt;
-using namespace ::com::sun::star::uno;
-using namespace ::com::sun::star::util;
-using namespace ::com::sun::star::lang;
-using namespace ::com::sun::star::beans;
-using namespace ::com::sun::star::frame;
-using namespace ::com::sun::star::document;
-using namespace ::com::sun::star::view;
-using namespace ::com::sun::star::task;
-using namespace ::com::sun::star::system;
-using namespace ::com::sun::star::ui;
-using namespace ::com::sun::star::ui::dialogs;
-using namespace ::com::sun::star::container;
-
-ResMgr* desktop::Desktop::pResMgr = nullptr;
-
-namespace desktop
-{
-
-static oslSignalHandler pSignalHandler = nullptr;
-
-namespace {
-
-#if HAVE_FEATURE_EXTENSIONS
-
-// Remove any existing UserInstallation's extensions cache data remaining from
-// old installations. This addresses at least two problems:
-//
-// For one, apparently due to the old share/prereg/bundled mechanism (disabled
-// since 5c47e5f63a79a9e72ec4a100786b1bbf65137ed4 "fdo#51252 Disable copying
-// share/prereg/bundled to avoid startup crashes"), the user/extensions/bundled
-// cache could contain corrupted information (like a UNO component registered
-// twice, which got changed from active to passive registration in one LO
-// version, but the version of the corresponding bundled extension only
-// incremented in a later LO version).
-//
-// For another, UserInstallations have been seen in the wild where no extensions
-// were installed per-user (any longer), but user/uno_packages/cache/registry/
-// com.sun.star.comp.deployment.component.PackageRegistryBackend/*.rdb files
-// contained data nevertheless.
-//
-// When a LO upgrade is detected (i.e., no user/extensions/buildid or one
-// containing an old build ID), then user/extensions and
-// user/uno_packages/cache/registry/
-// com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc are
-// removed. That should prevent any problems starting the service manager due
-// to old junk. Later on in Desktop::SynchronizeExtensionRepositories, the
-// removed cache data is recreated.
-//
-// Multiple instances of soffice.bin can execute this code in parallel for a
-// single UserInstallation, as it is called before RequestHandler is set up.
-// Therefore, any errors here only lead to SAL_WARNs.
-//
-// At least in theory, this function could be removed again once no
-// UserInstallation can be poisoned by old junk any more.
-bool cleanExtensionCache() {
- OUString buildId(
- "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("version") ":buildid}");
- rtl::Bootstrap::expandMacros(buildId); //TODO: detect failure
- OUString extDir(
- "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap")
- ":UserInstallation}/user/extensions");
- rtl::Bootstrap::expandMacros(extDir); //TODO: detect failure
- OUString buildIdFile(extDir + "/buildid");
- osl::File fr(buildIdFile);
- osl::FileBase::RC rc = fr.open(osl_File_OpenFlag_Read);
- switch (rc) {
- case osl::FileBase::E_None:
- {
- rtl::ByteSequence s1;
- rc = fr.readLine(s1);
- osl::FileBase::RC rc2 = fr.close();
- SAL_WARN_IF(
- rc2 != osl::FileBase::E_None, "desktop.app",
- "cannot close " << fr.getURL() << " after reading: " << +rc2);
- // readLine returns E_AGAIN for a zero-size file:
- if (rc != osl::FileBase::E_None && rc != osl::FileBase::E_AGAIN) {
- SAL_WARN( "desktop.app", "cannot read from " << fr.getURL() << ": " << +rc);
- break;
- }
- OUString s2(
- reinterpret_cast< char const * >(s1.getConstArray()),
- s1.getLength(), RTL_TEXTENCODING_ISO_8859_1);
- // using ISO 8859-1 avoids any and all conversion errors; the
- // content should only be a subset of ASCII, anyway
- if (s2 == buildId) {
- return false;
- }
- break;
- }
- case osl::FileBase::E_NOENT:
- break;
- default:
- SAL_WARN( "desktop.app", "cannot open " << fr.getURL() << " for reading: " << +rc);
- break;
- }
- utl::removeTree(extDir);
- OUString userRcFile(
- "$UNO_USER_PACKAGES_CACHE/registry/"
- "com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
- rtl::Bootstrap::expandMacros(userRcFile); //TODO: detect failure
- rc = osl::File::remove(userRcFile);
- SAL_WARN_IF(
- rc != osl::FileBase::E_None && rc != osl::FileBase::E_NOENT, "desktop.app",
- "cannot remove file " << userRcFile << ": " << +rc);
- rc = osl::Directory::createPath(extDir);
- SAL_WARN_IF(
- rc != osl::FileBase::E_None && rc != osl::FileBase::E_EXIST, "desktop.app",
- "cannot create path " << extDir << ": " << +rc);
- osl::File fw(buildIdFile);
- rc = fw.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
- if (rc != osl::FileBase::E_None) {
- SAL_WARN( "desktop.app", "cannot open " << fw.getURL() << " for writing: " << +rc);
- return true;
- }
- OString buf(OUStringToOString(buildId, RTL_TEXTENCODING_UTF8));
- // using UTF-8 avoids almost all conversion errors (and buildid
- // containing single surrogate halves should never happen, anyway); the
- // content should only be a subset of ASCII, anyway
- sal_uInt64 n = 0;
- rc = fw.write(buf.getStr(), buf.getLength(), n);
- SAL_WARN_IF(
- (rc != osl::FileBase::E_None
- || n != static_cast< sal_uInt32 >(buf.getLength())),
- "desktop.app",
- "cannot write to " << fw.getURL() << ": " << +rc << ", " << n);
- rc = fw.close();
- SAL_WARN_IF(
- rc != osl::FileBase::E_None, "desktop.app",
- "cannot close " << fw.getURL() << " after writing: " << +rc);
- return true;
-}
-
-#endif
-
-bool shouldLaunchQuickstart()
-{
- bool bQuickstart = Desktop::GetCommandLineArgs().IsQuickstart();
- if (!bQuickstart)
- {
- const SfxPoolItem* pItem=nullptr;
- SfxItemSet aQLSet(SfxGetpApp()->GetPool(), SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER);
- SfxGetpApp()->GetOptions(aQLSet);
- SfxItemState eState = aQLSet.GetItemState(SID_ATTR_QUICKLAUNCHER, false, &pItem);
- if (SfxItemState::SET == eState)
- bQuickstart = static_cast<const SfxBoolItem*>(pItem)->GetValue();
- }
- return bQuickstart;
-}
-
-void SetRestartState() {
- try {
- std::shared_ptr< comphelper::ConfigurationChanges > batch(
- comphelper::ConfigurationChanges::create());
- officecfg::Setup::Office::OfficeRestartInProgress::set(true, batch);
- batch->commit();
- } catch (css::uno::Exception & e) {
- SAL_WARN("desktop.app", "ignoring Exception \"" << e.Message << "\"");
- }
-}
-
-void DoRestartActionsIfNecessary(bool quickstart) {
- if (quickstart) {
- try {
- if (officecfg::Setup::Office::OfficeRestartInProgress::get()) {
- std::shared_ptr< comphelper::ConfigurationChanges > batch(
- comphelper::ConfigurationChanges::create());
- officecfg::Setup::Office::OfficeRestartInProgress::set(
- false, batch);
- batch->commit();
- css::office::Quickstart::createStart(
- comphelper::getProcessComponentContext(),
- shouldLaunchQuickstart());
- }
- } catch (css::uno::Exception & e) {
- SAL_WARN(
- "desktop.app", "ignoring Exception \"" << e.Message << "\"");
- }
- }
-}
-
-}
-
-
-ResMgr* Desktop::GetDesktopResManager()
-{
- if ( !Desktop::pResMgr )
- {
- // Create desktop resource manager and bootstrap process
- // was successful. Use default way to get language specific message.
- if ( Application::IsInExecute() )
- Desktop::pResMgr = ResMgr::CreateResMgr("dkt");
-
- if ( !Desktop::pResMgr )
- {
- // Use VCL to get the correct language specific message as we
- // are in the bootstrap process and not able to get the installed
- // language!!
- OUString aUILocaleString = langselect::getEmergencyLocale();
- LanguageTag aLanguageTag( aUILocaleString);
- //! ResMgr may modify the Locale for fallback!
- Desktop::pResMgr = ResMgr::SearchCreateResMgr( "dkt", aLanguageTag);
- }
- }
-
- return Desktop::pResMgr;
-}
-
-namespace {
-
-
-// Get a message string securely. There is a fallback string if the resource
-// is not available.
-
-OUString GetMsgString(
- sal_uInt16 nId, const OUString& aFallbackMsg,
- bool bAlwaysUseFallbackMsg = false )
-{
- if ( !bAlwaysUseFallbackMsg )
- {
- ResMgr* resMgr = Desktop::GetDesktopResManager();
- if ( resMgr )
- return ResId(nId, *resMgr).toString();
- }
- return aFallbackMsg;
-}
-
-OUString MakeStartupErrorMessage(
- OUString const & aErrorMessage, bool bAlwaysUseFallbackMsg = false )
-{
- OUStringBuffer aDiagnosticMessage( 100 );
-
- aDiagnosticMessage.append(
- GetMsgString(
- STR_BOOTSTRAP_ERR_CANNOT_START, "The program cannot be started.",
- bAlwaysUseFallbackMsg ) );
-
- aDiagnosticMessage.append( "\n" );
-
- aDiagnosticMessage.append( aErrorMessage );
-
- return aDiagnosticMessage.makeStringAndClear();
-}
-
-OUString MakeStartupConfigAccessErrorMessage( OUString const & aInternalErrMsg )
-{
- OUStringBuffer aDiagnosticMessage( 200 );
-
- ResMgr* pResMgr = Desktop::GetDesktopResManager();
- if ( pResMgr )
- aDiagnosticMessage.append( ResId(STR_BOOTSTRAP_ERR_CFG_DATAACCESS, *pResMgr).toString() );
- else
- aDiagnosticMessage.append( "The program cannot be started." );
-
- if ( !aInternalErrMsg.isEmpty() )
- {
- aDiagnosticMessage.append( "\n\n" );
- if ( pResMgr )
- aDiagnosticMessage.append( ResId(STR_INTERNAL_ERRMSG, *pResMgr).toString() );
- else
- aDiagnosticMessage.append( "The following internal error has occurred:\n\n" );
- aDiagnosticMessage.append( aInternalErrMsg );
- }
-
- return aDiagnosticMessage.makeStringAndClear();
-}
-
-
-// shows a simple error box with the given message ... but exits from these process !
-// Fatal errors can't be solved by the process ... nor any recovery can help.
-// Mostly the installation was damaged and must be repaired manually .. or by calling
-// setup again.
-// On the other side we must make sure that no further actions will be possible within
-// the current office process ! No pipe requests, no menu/toolbar/shortcut actions
-// are allowed. Otherwise we will force a "crash inside a crash".
-// Thats why we have to use a special native message box here which does not use yield :-)
-
-void FatalError(const OUString& sMessage)
-{
- OUString sProductKey = ::utl::Bootstrap::getProductKey();
- if ( sProductKey.isEmpty())
- {
- osl_getExecutableFile( &sProductKey.pData );
-
- ::sal_uInt32 nLastIndex = sProductKey.lastIndexOf('/');
- if ( nLastIndex > 0 )
- sProductKey = sProductKey.copy( nLastIndex+1 );
- }
-
- OUStringBuffer sTitle (128);
- sTitle.append (sProductKey );
- sTitle.append (" - Fatal Error");
-
- Application::ShowNativeErrorBox (sTitle.makeStringAndClear (), sMessage);
- _exit(EXITHELPER_FATAL_ERROR);
-}
-
-struct theCommandLineArgs : public rtl::Static< CommandLineArgs, theCommandLineArgs > {};
-
-}
-
-CommandLineArgs& Desktop::GetCommandLineArgs()
-{
- return theCommandLineArgs::get();
-}
-
-namespace
-{
- struct BrandName
- : public rtl::Static< OUString, BrandName > {};
- struct Version
- : public rtl::Static< OUString, Version > {};
- struct AboutBoxVersion
- : public rtl::Static< OUString, AboutBoxVersion > {};
- struct AboutBoxVersionSuffix
- : public rtl::Static< OUString, AboutBoxVersionSuffix > {};
- struct OOOVendor
- : public rtl::Static< OUString, OOOVendor > {};
- struct Extension
- : public rtl::Static< OUString, Extension > {};
-}
-
-OUString ReplaceStringHookProc( const OUString& rStr )
-{
- OUString sRet(rStr);
-
- if (sRet.indexOf("%PRODUCT") != -1 || sRet.indexOf("%ABOUTBOX") != -1)
- {
- OUString sBrandName = BrandName::get();
- OUString sVersion = Version::get();
- OUString sBuildId = utl::Bootstrap::getBuildIdData("development");
- OUString sAboutBoxVersion = AboutBoxVersion::get();
- OUString sAboutBoxVersionSuffix = AboutBoxVersionSuffix::get();
- OUString sExtension = Extension::get();
-
- if ( sBrandName.isEmpty() )
- {
- sBrandName = utl::ConfigManager::getProductName();
- sVersion = utl::ConfigManager::getProductVersion();
- sAboutBoxVersion = utl::ConfigManager::getAboutBoxProductVersion();
- sAboutBoxVersionSuffix = utl::ConfigManager::getAboutBoxProductVersionSuffix();
- if ( sExtension.isEmpty() )
- {
- sExtension = utl::ConfigManager::getProductExtension();
- }
- }
-
- sRet = sRet.replaceAll( "%PRODUCTNAME", sBrandName );
- sRet = sRet.replaceAll( "%PRODUCTVERSION", sVersion );
- sRet = sRet.replaceAll( "%BUILDID", sBuildId );
- sRet = sRet.replaceAll( "%ABOUTBOXPRODUCTVERSIONSUFFIX", sAboutBoxVersionSuffix );
- sRet = sRet.replaceAll( "%ABOUTBOXPRODUCTVERSION", sAboutBoxVersion );
- sRet = sRet.replaceAll( "%PRODUCTEXTENSION", sExtension );
- }
-
- if ( sRet.indexOf( "%OOOVENDOR" ) != -1 )
- {
- OUString sOOOVendor = OOOVendor::get();
-
- if ( sOOOVendor.isEmpty() )
- {
- sOOOVendor = utl::ConfigManager::getVendor();
- }
-
- sRet = sRet.replaceAll( "%OOOVENDOR", sOOOVendor );
- }
-
- return sRet;
-}
-
-Desktop::Desktop()
- : m_bCleanedExtensionCache(false)
- , m_bServicesRegistered(false)
- , m_aBootstrapError(BE_OK)
- , m_aBootstrapStatus(BS_OK)
-{
-}
-
-Desktop::~Desktop()
-{
-#if ENABLE_TELEPATHY
- TeleManager::finalize();
-#endif
-}
-
-void Desktop::Init()
-{
- SetBootstrapStatus(BS_OK);
-
-#if HAVE_FEATURE_EXTENSIONS
- m_bCleanedExtensionCache = cleanExtensionCache();
-#endif
-
- // We need to have service factory before going further, but see fdo#37195.
- // Doing this will mmap common.rdb, making it not overwritable on windows,
- // so this can't happen before the synchronization above. Lets rework this
- // so that the above is called *from* CreateApplicationServiceManager or
- // something to enforce this gotcha
- try
- {
- InitApplicationServiceManager();
- }
- catch (css::uno::Exception & e)
- {
- SetBootstrapError( BE_UNO_SERVICEMANAGER, e.Message );
- }
-
- if ( m_aBootstrapError == BE_OK )
- {
- try
- {
- if (!langselect::prepareLocale())
- {
- SetBootstrapError( BE_LANGUAGE_MISSING, OUString() );
- }
- }
- catch (css::uno::Exception & e)
- {
- SetBootstrapError( BE_OFFICECONFIG_BROKEN, e.Message );
- }
-
- // test code for ProfileSafeMode to allow testing the fail
- // of loading the office configuration initially. To use,
- // either set to true and compile, or set a breakpoint
- // in debugger and change the local bool
- static bool bTryHardOfficeconfigBroken(false);
-
- if (bTryHardOfficeconfigBroken)
- {
- SetBootstrapError(BE_OFFICECONFIG_BROKEN, OUString());
- }
- }
-
- if ( true )
- {
- const CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
-
- // start ipc thread only for non-remote offices
- RequestHandler::Status aStatus = RequestHandler::Enable(true);
- if ( aStatus == RequestHandler::IPC_STATUS_PIPE_ERROR )
- {
-#if defined ANDROID
- // Ignore crack pipe errors on Android
-#else
- // Keep using this oddly named BE_PATHINFO_MISSING value
- // for pipe-related errors on other platforms. Of course
- // this crack with two (if not more) levels of our own
- // error codes hiding the actual system error code is
- // broken, but that is done all over the code, let's leave
- // reengineering that to another year.
- SetBootstrapError( BE_PATHINFO_MISSING, OUString() );
-#endif
- }
- else if ( aStatus == RequestHandler::IPC_STATUS_BOOTSTRAP_ERROR )
- {
- SetBootstrapError( BE_PATHINFO_MISSING, OUString() );
- }
- else if ( aStatus == RequestHandler::IPC_STATUS_2ND_OFFICE )
- {
- // 2nd office startup should terminate after sending cmdlineargs through pipe
- SetBootstrapStatus(BS_TERMINATE);
- }
- else if ( !rCmdLineArgs.GetUnknown().isEmpty()
- || rCmdLineArgs.IsHelp() || rCmdLineArgs.IsVersion() )
- {
- // disable IPC thread in an instance that is just showing a help message
- RequestHandler::Disable();
- }
- pSignalHandler = osl_addSignalHandler(SalMainPipeExchangeSignal_impl, nullptr);
- }
-}
-
-void Desktop::InitFinished()
-{
- CloseSplashScreen();
-}
-
-void Desktop::DeInit()
-{
- try {
- // instead of removing of the configManager just let it commit all the changes
- utl::ConfigManager::storeConfigItems();
- FlushConfiguration();
-
- // close splashscreen if it's still open
- CloseSplashScreen();
- Reference< XComponent >(
- comphelper::getProcessComponentContext(), UNO_QUERY_THROW )->
- dispose();
- // nobody should get a destroyed service factory...
- ::comphelper::setProcessServiceFactory( nullptr );
-
- // clear lockfile
- m_xLockfile.reset();
-
- RequestHandler::Disable();
- if( pSignalHandler )
- osl_removeSignalHandler( pSignalHandler );
- } catch (const RuntimeException&) {
- // someone threw an exception during shutdown
- // this will leave some garbage behind..
- }
-}
-
-bool Desktop::QueryExit()
-{
- try
- {
- utl::ConfigManager::storeConfigItems();
- }
- catch ( const RuntimeException& )
- {
- }
-
- const sal_Char SUSPEND_QUICKSTARTVETO[] = "SuspendQuickstartVeto";
-
- Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
- Reference< XPropertySet > xPropertySet(xDesktop, UNO_QUERY_THROW);
- xPropertySet->setPropertyValue( SUSPEND_QUICKSTARTVETO, Any(true) );
-
- bool bExit = xDesktop->terminate();
-
- if ( !bExit )
- {
- xPropertySet->setPropertyValue( SUSPEND_QUICKSTARTVETO, Any(false) );
- }
- else if (!Application::IsEventTestingModeEnabled())
- {
- FlushConfiguration();
- try
- {
- // it is no problem to call RequestHandler::Disable() more than once
- // it also looks to be threadsafe
- RequestHandler::Disable();
- }
- catch ( const RuntimeException& )
- {
- }
-
- m_xLockfile.reset();
-
- }
-
- return bExit;
-}
-
-void Desktop::HandleBootstrapPathErrors( ::utl::Bootstrap::Status aBootstrapStatus, const OUString& aDiagnosticMessage )
-{
- if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
- {
- OUString aProductKey;
- OUString aTemp;
-
- osl_getExecutableFile( &aProductKey.pData );
- sal_uInt32 lastIndex = aProductKey.lastIndexOf('/');
- if ( lastIndex > 0 )
- aProductKey = aProductKey.copy( lastIndex+1 );
-
- aTemp = ::utl::Bootstrap::getProductKey( aProductKey );
- if ( !aTemp.isEmpty() )
- aProductKey = aTemp;
-
- OUString const aMessage(aDiagnosticMessage + "\n");
-
- ScopedVclPtrInstance< MessageDialog > aBootstrapFailedBox(nullptr, aMessage);
- aBootstrapFailedBox->SetText( aProductKey );
- aBootstrapFailedBox->Execute();
- }
-}
-
-// Create a error message depending on bootstrap failure code and an optional file url
-OUString Desktop::CreateErrorMsgString(
- utl::Bootstrap::FailureCode nFailureCode,
- const OUString& aFileURL )
-{
- OUString aMsg;
- OUString aFilePath;
- bool bFileInfo = true;
-
- switch ( nFailureCode )
- {
- /// the shared installation directory could not be located
- case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
- {
- aMsg = GetMsgString( STR_BOOTSTRAP_ERR_PATH_INVALID,
- "The installation path is not available." );
- bFileInfo = false;
- }
- break;
-
- /// the bootstrap INI file could not be found or read
- case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
- {
- aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
- "The configuration file \"$1\" is missing." );
- }
- break;
-
- /// the bootstrap INI is missing a required entry
- /// the bootstrap INI contains invalid data
- case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
- case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
- {
- aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_CORRUPT,
- "The configuration file \"$1\" is corrupt." );
- }
- break;
-
- /// the version locator INI file could not be found or read
- case ::utl::Bootstrap::MISSING_VERSION_FILE:
- {
- aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
- "The configuration file \"$1\" is missing." );
- }
- break;
-
- /// the version locator INI has no entry for this version
- case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
- {
- aMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SUPPORT,
- "The main configuration file \"$1\" does not support the current version." );
- }
- break;
-
- /// the user installation directory does not exist
- case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
- {
- aMsg = GetMsgString( STR_BOOTSTRAP_ERR_DIR_MISSING,
- "The configuration directory \"$1\" is missing." );
- }
- break;
-
- /// some bootstrap data was invalid in unexpected ways
- case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
- {
- aMsg = GetMsgString( STR_BOOTSTRAP_ERR_INTERNAL,
- "An internal failure occurred." );
- bFileInfo = false;
- }
- break;
-
- case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
- {
- // This needs to be improved, see #i67575#:
- aMsg = "Invalid version file entry";
- bFileInfo = false;
- }
- break;
-
- case ::utl::Bootstrap::NO_FAILURE:
- {
- OSL_ASSERT(false);
- }
- break;
- }
-
- if ( bFileInfo )
- {
- OUString aMsgString( aMsg );
-
- osl::File::getSystemPathFromFileURL( aFileURL, aFilePath );
-
- aMsgString = aMsgString.replaceFirst( "$1", aFilePath );
- aMsg = aMsgString;
- }
-
- return MakeStartupErrorMessage( aMsg );
-}
-
-void Desktop::HandleBootstrapErrors(
- BootstrapError aBootstrapError, OUString const & aErrorMessage )
-{
- if ( aBootstrapError == BE_PATHINFO_MISSING )
- {
- OUString aErrorMsg;
- OUString aBuffer;
- utl::Bootstrap::Status aBootstrapStatus;
- utl::Bootstrap::FailureCode nFailureCode;
-
- aBootstrapStatus = ::utl::Bootstrap::checkBootstrapStatus( aBuffer, nFailureCode );
- if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
- {
- switch ( nFailureCode )
- {
- case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
- case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
- {
- aErrorMsg = CreateErrorMsgString( nFailureCode, OUString() );
- }
- break;
-
- /// the bootstrap INI file could not be found or read
- /// the bootstrap INI is missing a required entry
- /// the bootstrap INI contains invalid data
- case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
- case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
- case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
- {
- OUString aBootstrapFileURL;
-
- utl::Bootstrap::locateBootstrapFile( aBootstrapFileURL );
- aErrorMsg = CreateErrorMsgString( nFailureCode, aBootstrapFileURL );
- }
- break;
-
- /// the version locator INI file could not be found or read
- /// the version locator INI has no entry for this version
- /// the version locator INI entry is not a valid directory URL
- case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
- case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
- case ::utl::Bootstrap::MISSING_VERSION_FILE:
- {
- OUString aVersionFileURL;
-
- utl::Bootstrap::locateVersionFile( aVersionFileURL );
- aErrorMsg = CreateErrorMsgString( nFailureCode, aVersionFileURL );
- }
- break;
-
- /// the user installation directory does not exist
- case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
- {
- OUString aUserInstallationURL;
-
- utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
- aErrorMsg = CreateErrorMsgString( nFailureCode, aUserInstallationURL );
- }
- break;
-
- case ::utl::Bootstrap::NO_FAILURE:
- {
- OSL_ASSERT(false);
- }
- break;
- }
-
- HandleBootstrapPathErrors( aBootstrapStatus, aErrorMsg );
- }
- }
- else if ( aBootstrapError == BE_UNO_SERVICEMANAGER || aBootstrapError == BE_UNO_SERVICE_CONFIG_MISSING )
- {
- // Uno service manager is not available. VCL needs a uno service manager to display a message box!!!
- // Currently we are not able to display a message box with a service manager due to this limitations inside VCL.
-
- // When UNO is not properly initialized, all kinds of things can fail
- // and cause the process to crash (e.g., a call to GetMsgString may
- // crash when somewhere deep within that call Any::operator <= is used
- // with a PropertyValue, and no binary UNO type description for
- // PropertyValue is available). To give the user a hint even if
- // generating and displaying a message box below crashes, print a
- // hard-coded message on stderr first:
- std::cerr
- << "The application cannot be started.\n"
- // STR_BOOTSTRAP_ERR_CANNOT_START
- << (aBootstrapError == BE_UNO_SERVICEMANAGER
- ? "The component manager is not available.\n"
- // STR_BOOTSTRAP_ERR_NO_SERVICE
- : "The configuration service is not available.\n");
- // STR_BOOTSTRAP_ERR_NO_CFG_SERVICE
- if ( !aErrorMessage.isEmpty() )
- {
- std::cerr << "(\"" << aErrorMessage << "\")\n";
- }
-
- // First sentence. We cannot bootstrap office further!
- OUString aMessage;
- OUStringBuffer aDiagnosticMessage( 100 );
-
- OUString aErrorMsg;
-
- if ( aBootstrapError == BE_UNO_SERVICEMANAGER )
- aErrorMsg = "The service manager is not available.";
- else
- aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_CFG_SERVICE,
- "The configuration service is not available." );
-
- aDiagnosticMessage.append( aErrorMsg );
- aDiagnosticMessage.append( "\n" );
- if ( !aErrorMessage.isEmpty() )
- {
- aDiagnosticMessage.append( "(\"" );
- aDiagnosticMessage.append( aErrorMessage );
- aDiagnosticMessage.append( "\")\n" );
- }
-
- // Due to the fact the we haven't a backup applicat.rdb file anymore it is not possible to
- // repair the installation with the setup executable besides the office executable. Now
- // we have to ask the user to start the setup on CD/installation directory manually!!
- OUString aStartSetupManually( GetMsgString(
- STR_ASK_START_SETUP_MANUALLY,
- "Start setup application to repair the installation from CD, or the folder containing the installation packages.",
- aBootstrapError == BE_UNO_SERVICEMANAGER ) );
-
- aDiagnosticMessage.append( aStartSetupManually );
- aMessage = MakeStartupErrorMessage(
- aDiagnosticMessage.makeStringAndClear(),
- aBootstrapError == BE_UNO_SERVICEMANAGER );
-
- FatalError( aMessage);
- }
- else if ( aBootstrapError == BE_OFFICECONFIG_BROKEN )
- {
- // test restore of registrymodifications
- sal_uInt16 nSecureUserConfigNumCopies(0);
- bool bFireOriginalError(true);
-
- // read configuration from soffice.ini
- const bool bSecureUserConfig(comphelper::BackupFileHelper::getSecureUserConfig(nSecureUserConfigNumCopies));
-
- if (bSecureUserConfig)
- {
- // try to asccess user layer configuration file
- OUString conf("${CONFIGURATION_LAYERS}");
- rtl::Bootstrap::expandMacros(conf);
- const OUString aTokenUser("user:");
- sal_Int32 nStart(conf.indexOf(aTokenUser));
- OUString aUser;
-
- if (-1 != nStart)
- {
- nStart += aTokenUser.getLength();
- sal_Int32 nEnd(conf.indexOf(' ', nStart));
-
- if (-1 == nEnd)
- {
- nEnd = conf.getLength();
- }
-
- aUser = conf.copy(nStart, nEnd - nStart);
- aUser.startsWith("!", &aUser);
- }
-
- if (!aUser.isEmpty())
- {
- comphelper::BackupFileHelper aBackupFileHelper(aUser, nSecureUserConfigNumCopies);
-
- if (aBackupFileHelper.isPopPossible())
- {
- // for linux (and probably others?) we need to instantiate XDesktop2
- // to be able to open a *.ui-file based dialog, so do this here locally.
- // does no harm on win, so better always do this (in error case only anyways)
- Reference< XComponentContext > xLocalContext = ::comphelper::getProcessComponentContext();
- Reference< XDesktop2 > xDesktop = css::frame::Desktop::create(xLocalContext);
-
- ScopedVclPtrInstance< MessageDialog > aQueryShouldRestore(
- Application::GetDefDialogParent(),
- "QueryTryToRestoreConfigurationDialog",
- "desktop/ui/querytrytorestoreconfigurationdialog.ui");
-
- if (aQueryShouldRestore.get())
- {
- if (!aErrorMessage.isEmpty())
- {
- OUString aPrimaryText(aQueryShouldRestore->get_primary_text());
-
- aPrimaryText += "\n(\"" + aErrorMessage + "\")";
- aQueryShouldRestore->set_primary_text(aPrimaryText);
- }
-
- if (RET_YES == aQueryShouldRestore->Execute())
- {
- aBackupFileHelper.tryPop();
- bFireOriginalError = false;
- }
- }
- }
- }
- }
-
- // set flag at BackupFileHelper to be able to know if _exit was called and
- // actions are executed after this
- comphelper::BackupFileHelper::setExitWasCalled();
-
- if (bFireOriginalError)
- {
- OUString msg(
- GetMsgString(
- STR_CONFIG_ERR_ACCESS_GENERAL,
- ("A general error occurred while accessing your central"
- " configuration.")));
- if (!aErrorMessage.isEmpty()) {
- msg += "\n(\"" + aErrorMessage + "\")";
- }
- FatalError(MakeStartupErrorMessage(msg));
- }
- else
- {
- // Already presented all information to the user.
- // just do what FatalError does at it's end
- _exit(EXITHELPER_FATAL_ERROR);
- }
- }
- else if ( aBootstrapError == BE_USERINSTALL_FAILED )
- {
- OUString aMessage;
- OUStringBuffer aDiagnosticMessage( 100 );
- OUString aErrorMsg;
- aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_USERINSTALL_FAILED,
- "User installation could not be completed" );
- aDiagnosticMessage.append( aErrorMsg );
- aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
- FatalError(aMessage);
- }
- else if ( aBootstrapError == BE_LANGUAGE_MISSING )
- {
- OUString aMessage;
- OUStringBuffer aDiagnosticMessage( 100 );
- OUString aErrorMsg;
- aErrorMsg = GetMsgString(
- //@@@ FIXME: should use an own resource string => #i36213#
- STR_BOOTSTRAP_ERR_LANGUAGE_MISSING,
- "Language could not be determined." );
- aDiagnosticMessage.append( aErrorMsg );
- aMessage = MakeStartupErrorMessage(
- aDiagnosticMessage.makeStringAndClear() );
- FatalError(aMessage);
- }
- else if (( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE ) ||
- ( aBootstrapError == BE_USERINSTALL_NOWRITEACCESS ))
- {
- OUString aUserInstallationURL;
- OUString aUserInstallationPath;
- OUString aMessage;
- OUString aErrorMsg;
- OUStringBuffer aDiagnosticMessage( 100 );
-
- utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
-
- if ( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE )
- aErrorMsg = GetMsgString(
- STR_BOOSTRAP_ERR_NOTENOUGHDISKSPACE,
- "User installation could not be completed due to insufficient free disk space." );
- else
- aErrorMsg = GetMsgString(
- STR_BOOSTRAP_ERR_NOACCESSRIGHTS,
- "User installation could not be processed due to missing access rights." );
-
- osl::File::getSystemPathFromFileURL( aUserInstallationURL, aUserInstallationPath );
-
- aDiagnosticMessage.append( aErrorMsg );
- aDiagnosticMessage.append( aUserInstallationPath );
- aMessage = MakeStartupErrorMessage(
- aDiagnosticMessage.makeStringAndClear() );
- FatalError(aMessage);
- }
-
- return;
-}
-
-
-bool Desktop::isUIOnSessionShutdownAllowed()
-{
- return officecfg::Office::Recovery::SessionShutdown::DocumentStoreUIEnabled
- ::get();
-}
-
-namespace {
-
-bool crashReportInfoExists()
-{
-#if HAVE_FEATURE_BREAKPAD
- std::string path = CrashReporter::getIniFileName();
- std::ifstream aFile(path);
- while (aFile.good())
- {
- std::string line;
- std::getline(aFile, line);
- int sep = line.find('=');
- if (sep >= 0)
- {
- std::string key = line.substr(0, sep);
- if (key == "DumpFile")
- return true;
- }
- }
-#endif
- return false;
-}
-
-#if HAVE_FEATURE_BREAKPAD
-void handleCrashReport()
-{
- static const char SERVICENAME_CRASHREPORT[] = "com.sun.star.comp.svx.CrashReportUI";
-
- css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
-
- Reference< css::frame::XSynchronousDispatch > xRecoveryUI(
- xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_CRASHREPORT, xContext),
- css::uno::UNO_QUERY_THROW);
-
- Reference< css::util::XURLTransformer > xURLParser =
- css::util::URLTransformer::create(::comphelper::getProcessComponentContext());
-
- css::util::URL aURL;
- css::uno::Any aRet = xRecoveryUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
- bool bRet = false;
- aRet >>= bRet;
-}
-#endif
-
-void handleSafeMode()
-{
- static const char SERVICENAME_SAFEMODE[] = "com.sun.star.comp.svx.SafeModeUI";
-
- css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
-
- Reference< css::frame::XSynchronousDispatch > xSafeModeUI(
- xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_SAFEMODE, xContext),
- css::uno::UNO_QUERY_THROW);
-
- css::util::URL aURL;
- css::uno::Any aRet = xSafeModeUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
- bool bRet = false;
- aRet >>= bRet;
-}
-
-/** @short check if recovery must be started or not.
-
- @param bCrashed [boolean ... out!]
- the office crashed last times.
- But may be there are no recovery data.
- Useful to trigger the error report tool without
- showing the recovery UI.
-
- @param bRecoveryDataExists [boolean ... out!]
- there exists some recovery data.
-
- @param bSessionDataExists [boolean ... out!]
- there exists some session data.
- Because the user may be logged out last time from its
- unix session...
-*/
-void impl_checkRecoveryState(bool& bCrashed ,
- bool& bRecoveryDataExists,
- bool& bSessionDataExists )
-{
- bCrashed = officecfg::Office::Recovery::RecoveryInfo::Crashed::get() || crashReportInfoExists();
- bool elements = officecfg::Office::Recovery::RecoveryList::get()->
- hasElements();
- bool session
- = officecfg::Office::Recovery::RecoveryInfo::SessionData::get();
- bRecoveryDataExists = elements && !session;
- bSessionDataExists = elements && session;
-}
-
-
-/* @short start the recovery wizard.
-
- @param bEmergencySave
- differs between EMERGENCY_SAVE and RECOVERY
-*/
-bool impl_callRecoveryUI(bool bEmergencySave ,
- bool bExistsRecoveryData)
-{
- static const char SERVICENAME_RECOVERYUI[] = "com.sun.star.comp.svx.RecoveryUI";
- static const char COMMAND_EMERGENCYSAVE[] = "vnd.sun.star.autorecovery:/doEmergencySave";
- static const char COMMAND_RECOVERY[] = "vnd.sun.star.autorecovery:/doAutoRecovery";
-
- css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
-
- Reference< css::frame::XSynchronousDispatch > xRecoveryUI(
- xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_RECOVERYUI, xContext),
- css::uno::UNO_QUERY_THROW);
-
- Reference< css::util::XURLTransformer > xURLParser =
- css::util::URLTransformer::create(::comphelper::getProcessComponentContext());
-
- css::util::URL aURL;
- if (bEmergencySave)
- aURL.Complete = COMMAND_EMERGENCYSAVE;
- else if (bExistsRecoveryData)
- aURL.Complete = COMMAND_RECOVERY;
- else
- return false;
-
- xURLParser->parseStrict(aURL);
-
- css::uno::Any aRet = xRecoveryUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
- bool bRet = false;
- aRet >>= bRet;
- return bRet;
-}
-
-}
-
-/*
- * Save all open documents so they will be reopened
- * the next time the application is started
- *
- * returns sal_True if at least one document could be saved...
- *
- */
-bool Desktop::SaveTasks()
-{
- return impl_callRecoveryUI(
- true , // sal_True => force emergency save
- false);
-}
-
-namespace {
-
-void restartOnMac(bool passArguments) {
-#if defined MACOSX
- RequestHandler::Disable();
-#if HAVE_FEATURE_MACOSX_SANDBOX
- (void) passArguments; // avoid warnings
- ResMgr *resMgr = Desktop::GetDesktopResManager();
- OUString aMessage = ResId(STR_LO_MUST_BE_RESTARTED, *resMgr).toString();
-
- MessageDialog aRestartBox(NULL, aMessage);
- aRestartBox.Execute();
-#else
- OUString execUrl;
- OSL_VERIFY(osl_getExecutableFile(&execUrl.pData) == osl_Process_E_None);
- OUString execPath;
- OString execPath8;
- if ((osl::FileBase::getSystemPathFromFileURL(execUrl, execPath)
- != osl::FileBase::E_None) ||
- !execPath.convertToString(
- &execPath8, osl_getThreadTextEncoding(),
- (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
- RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
- {
- std::abort();
- }
- std::vector< OString > args;
- args.push_back(execPath8);
- bool wait = false;
- if (passArguments) {
- sal_uInt32 n = osl_getCommandArgCount();
- for (sal_uInt32 i = 0; i < n; ++i) {
- OUString arg;
- osl_getCommandArg(i, &arg.pData);
- if (arg.match("--accept=")) {
- wait = true;
- }
- OString arg8;
- if (!arg.convertToString(
- &arg8, osl_getThreadTextEncoding(),
- (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
- RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
- {
- std::abort();
- }
- args.push_back(arg8);
- }
- }
- std::vector< char const * > argPtrs;
- for (std::vector< OString >::iterator i(args.begin()); i != args.end();
- ++i)
- {
- argPtrs.push_back(i->getStr());
- }
- argPtrs.push_back(nullptr);
- execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
- if (errno == ENOTSUP) { // happens when multithreaded on OS X < 10.6
- pid_t pid = fork();
- if (pid == 0) {
- execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
- } else if (pid > 0) {
- // Two simultaneously running soffice processes lead to two dock
- // icons, so avoid waiting here unless it must be assumed that the
- // process invoking soffice itself wants to wait for soffice to
- // finish:
- if (!wait) {
- return;
- }
- int stat;
- if (waitpid(pid, &stat, 0) == pid && WIFEXITED(stat)) {
- _exit(WEXITSTATUS(stat));
- }
- }
- }
- std::abort();
-#endif
-#else
- (void) passArguments; // avoid warnings
-#endif
-}
-
-}
-
-void Desktop::Exception(ExceptionCategory nCategory)
-{
- // protect against recursive calls
- static bool bInException = false;
-
- SystemWindowFlags nOldMode = Application::GetSystemWindowMode();
- Application::SetSystemWindowMode( nOldMode & ~SystemWindowFlags::NOAUTOMODE );
- if ( bInException )
- {
- OUString aDoubleExceptionString;
- Application::Abort( aDoubleExceptionString );
- }
-
- bInException = true;
- const CommandLineArgs& rArgs = GetCommandLineArgs();
-
- // save all modified documents ... if it's allowed doing so.
- bool bRestart = false;
- bool bAllowRecoveryAndSessionManagement = (
- ( !rArgs.IsNoRestore() ) && // some use cases of office must work without recovery
- ( !rArgs.IsHeadless() ) &&
- ( nCategory != ExceptionCategory::UserInterface ) && // recovery can't work without UI ... but UI layer seems to be the reason for this crash
- ( Application::IsInExecute() ) // crashes during startup and shutdown should be ignored (they indicates a corrupt installation ...)
- );
- if ( bAllowRecoveryAndSessionManagement )
- bRestart = SaveTasks();
-
- FlushConfiguration();
-
- switch( nCategory )
- {
- case ExceptionCategory::ResourceNotLoaded:
- {
- OUString aResExceptionString;
- Application::Abort( aResExceptionString );
- break;
- }
-
- default:
- {
- m_xLockfile.reset();
-
- if( bRestart )
- {
- RequestHandler::Disable();
- if( pSignalHandler )
- osl_removeSignalHandler( pSignalHandler );
-
- restartOnMac(false);
- if ( m_rSplashScreen.is() )
- m_rSplashScreen->reset();
-
- _exit( EXITHELPER_CRASH_WITH_RESTART );
- }
- else
- {
- Application::Abort( OUString() );
- }
-
- break;
- }
- }
-
- OSL_ASSERT(false); // unreachable
-}
-
-void Desktop::AppEvent( const ApplicationEvent& rAppEvent )
-{
- HandleAppEvent( rAppEvent );
-}
-
-struct ExecuteGlobals
-{
- Reference < css::document::XDocumentEventListener > xGlobalBroadcaster;
- bool bRestartRequested;
- bool bUseSystemFileDialog;
- std::unique_ptr<SvtLanguageOptions> pLanguageOptions;
- std::unique_ptr<SvtPathOptions> pPathOptions;
-
- ExecuteGlobals()
- : bRestartRequested( false )
- , bUseSystemFileDialog( true )
- {}
-};
-
-static ExecuteGlobals* pExecGlobals = nullptr;
-
-
-//This just calls Execute() for all normal uses of LibreOffice, but for
-//ui-testing if built with afl-clang-fast++ then on exit it will pseudo-restart
-//(up to 100 times)
-void Desktop::DoExecute()
-{
-#if !defined(__AFL_HAVE_MANUAL_CONTROL)
- Execute();
-#else
- while (__AFL_LOOP(1000))
- {
- Execute();
- OpenDefault();
- }
-#endif
-}
-
-int Desktop::Main()
-{
- pExecGlobals = new ExecuteGlobals();
-
- // Remember current context object
- css::uno::ContextLayer layer( css::uno::getCurrentContext() );
-
- if ( m_aBootstrapError != BE_OK )
- {
- HandleBootstrapErrors( m_aBootstrapError, m_aBootstrapErrorMessage );
- return EXIT_FAILURE;
- }
-
- BootstrapStatus eStatus = GetBootstrapStatus();
- if (eStatus == BS_TERMINATE) {
- return EXIT_SUCCESS;
- }
-
- // Detect desktop environment - need to do this as early as possible
- css::uno::setCurrentContext( new DesktopContext( css::uno::getCurrentContext() ) );
-
- CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
-
-#if HAVE_FEATURE_DESKTOP
- OUString aUnknown( rCmdLineArgs.GetUnknown() );
- if ( !aUnknown.isEmpty() )
- {
- displayCmdlineHelp( aUnknown );
- return EXIT_FAILURE;
- }
- if ( rCmdLineArgs.IsHelp() )
- {
- displayCmdlineHelp( OUString() );
- return EXIT_SUCCESS;
- }
- if ( rCmdLineArgs.IsVersion() )
- {
- displayVersion();
- return EXIT_SUCCESS;
- }
-#endif
-
- ResMgr::SetReadStringHook( ReplaceStringHookProc );
-
- // Startup screen
- OpenSplashScreen();
-
- SetSplashScreenProgress(10);
-
- userinstall::Status inst_fin = userinstall::finalize();
- if (inst_fin != userinstall::EXISTED && inst_fin != userinstall::CREATED)
- {
- SAL_WARN( "desktop.app", "userinstall failed");
- if ( inst_fin == userinstall::ERROR_NO_SPACE )
- HandleBootstrapErrors(
- BE_USERINSTALL_NOTENOUGHDISKSPACE, OUString() );
- else if ( inst_fin == userinstall::ERROR_CANT_WRITE )
- HandleBootstrapErrors( BE_USERINSTALL_NOWRITEACCESS, OUString() );
- else
- HandleBootstrapErrors( BE_USERINSTALL_FAILED, OUString() );
- return EXIT_FAILURE;
- }
- // refresh path information
- utl::Bootstrap::reloadData();
- SetSplashScreenProgress(20);
-
- Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
-
- Reference< XRestartManager > xRestartManager( OfficeRestartManager::get(xContext) );
-
- Reference< XDesktop2 > xDesktop;
- try
- {
- RegisterServices(xContext);
-
- SetSplashScreenProgress(25);
-
-#if HAVE_FEATURE_DESKTOP
- // check user installation directory for lockfile so we can be sure
- // there is no other instance using our data files from a remote host
- m_xLockfile.reset(new Lockfile);
-
- if ( !rCmdLineArgs.IsHeadless() && !rCmdLineArgs.IsInvisible() &&
- !rCmdLineArgs.IsNoLockcheck() && !m_xLockfile->check( Lockfile_execWarning ))
- {
- // Lockfile exists, and user clicked 'no'
- return EXIT_FAILURE;
- }
-
- // check if accessibility is enabled but not working and allow to quit
- if( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() )
- {
- if( !InitAccessBridge() )
- return EXIT_FAILURE;
- }
-#endif
-
- // terminate if requested...
- if( rCmdLineArgs.IsTerminateAfterInit() )
- return EXIT_SUCCESS;
-
- // Read the common configuration items for optimization purpose
- if ( !InitializeConfiguration() )
- return EXIT_FAILURE;
-
- SetSplashScreenProgress(30);
-
- // create title string
- LanguageTag aLocale( LANGUAGE_SYSTEM);
- ResMgr* pLabelResMgr = GetDesktopResManager();
- OUString aTitle = pLabelResMgr ? ResId(RID_APPTITLE, *pLabelResMgr).toString() : OUString();
-
-#ifdef DBG_UTIL
- //include buildid in non product builds
- OUString aDefault("development");
- aTitle += " [";
- aTitle += utl::Bootstrap::getBuildIdData(aDefault);
- aTitle += "]";
-#endif
-
- SetDisplayName( aTitle );
- SetSplashScreenProgress(35);
- pExecGlobals->pPathOptions.reset( new SvtPathOptions);
- SetSplashScreenProgress(40);
-
- xDesktop = css::frame::Desktop::create( xContext );
-
- // create service for loading SFX (still needed in startup)
- pExecGlobals->xGlobalBroadcaster = Reference < css::document::XDocumentEventListener >
- ( css::frame::theGlobalEventBroadcaster::get(xContext), UNO_SET_THROW );
-
- /* ensure existence of a default window that messages can be dispatched to
- This is for the benefit of testtool which uses PostUserEvent extensively
- and else can deadlock while creating this window from another thread while
- the main thread is not yet in the event loop.
- */
- Application::GetDefaultDevice();
-
-#if HAVE_FEATURE_EXTENSIONS
- // Check if bundled or shared extensions were added /removed
- // and process those extensions (has to be done before checking
- // the extension dependencies!
- SynchronizeExtensionRepositories();
- bool bAbort = CheckExtensionDependencies();
- if ( bAbort )
- return EXIT_FAILURE;
-
- if (inst_fin == userinstall::CREATED)
- {
- Migration::migrateSettingsIfNecessary();
- }
-#endif
-
- // keep a language options instance...
- pExecGlobals->pLanguageOptions.reset( new SvtLanguageOptions(true));
-
- css::document::DocumentEvent aEvent;
- aEvent.EventName = "OnStartApp";
- pExecGlobals->xGlobalBroadcaster->documentEventOccured(aEvent);
-
- SetSplashScreenProgress(50);
-
- // Backing Component
- bool bCrashed = false;
- bool bExistsRecoveryData = false;
- bool bExistsSessionData = false;
-
- impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
-
- OUString pidfileName = rCmdLineArgs.GetPidfileName();
- if ( !pidfileName.isEmpty() )
- {
- OUString pidfileURL;
-
- if ( osl_getFileURLFromSystemPath(pidfileName.pData, &pidfileURL.pData) == osl_File_E_None )
- {
- osl::File pidfile( pidfileURL );
- osl::FileBase::RC rc;
-
- osl::File::remove( pidfileURL );
- if ( (rc = pidfile.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create ) ) == osl::File::E_None )
- {
- OString pid( OString::number( GETPID() ) );
- sal_uInt64 written = 0;
- if ( pidfile.write(pid.getStr(), pid.getLength(), written) != osl::File::E_None )
- {
- SAL_WARN("desktop.app", "cannot write pidfile " << pidfile.getURL());
- }
- pidfile.close();
- }
- else
- {
- SAL_WARN("desktop.app", "cannot open pidfile " << pidfile.getURL() << osl::FileBase::RC(rc));
- }
- }
- else
- {
- SAL_WARN("desktop.app", "cannot get pidfile URL from path" << pidfileName);
- }
- }
-
- if ( rCmdLineArgs.IsHeadless() || rCmdLineArgs.IsEventTesting() )
- {
- // Ensure that we use not the system file dialogs as
- // headless mode relies on Application::EnableHeadlessMode()
- // which does only work for VCL dialogs!!
- SvtMiscOptions aMiscOptions;
- pExecGlobals->bUseSystemFileDialog = aMiscOptions.UseSystemFileDialog();
- aMiscOptions.SetUseSystemFileDialog( false );
- }
-
- pExecGlobals->bRestartRequested = xRestartManager->isRestartRequested(
- true);
- if ( !pExecGlobals->bRestartRequested )
- {
- if ((!rCmdLineArgs.WantsToLoadDocument() && !rCmdLineArgs.IsInvisible() && !rCmdLineArgs.IsHeadless() && !rCmdLineArgs.IsQuickstart()) &&
- (SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::STARTMODULE)) &&
- (!bExistsRecoveryData ) &&
- (!bExistsSessionData ) &&
- (!Application::AnyInput( VclInputFlags::APPEVENT ) ))
- {
- ShowBackingComponent(this);
- }
- }
- }
- catch ( const css::lang::WrappedTargetException& wte )
- {
- css::uno::Exception te;
- wte.TargetException >>= te;
- FatalError( MakeStartupConfigAccessErrorMessage(wte.Message + te.Message) );
- }
- catch ( const css::uno::Exception& e )
- {
- FatalError( MakeStartupErrorMessage(e.Message) );
- }
- SetSplashScreenProgress(55);
-
- SvtFontSubstConfig().Apply();
-
- SvtTabAppearanceCfg aAppearanceCfg;
- SvtTabAppearanceCfg::SetInitialized();
- aAppearanceCfg.SetApplicationDefaults( this );
- SvtAccessibilityOptions aOptions;
- aOptions.SetVCLSettings();
- SetSplashScreenProgress(60);
-
-#if ENABLE_TELEPATHY
- bool bListen = rCmdLineArgs.IsInvisible();
- TeleManager::init( bListen );
-#endif
-
- if ( !pExecGlobals->bRestartRequested )
- {
- Application::SetFilterHdl( LINK( this, Desktop, ImplInitFilterHdl ) );
- bool bTerminateRequested = false;
-
- // Preload function depends on an initialized sfx application!
- SetSplashScreenProgress(75);
-
- // use system window dialogs
- Application::SetSystemWindowMode( SystemWindowFlags::DIALOG );
-
- SetSplashScreenProgress(80);
-
- if ( !bTerminateRequested && !rCmdLineArgs.IsInvisible() &&
- !rCmdLineArgs.IsNoQuickstart() )
- InitializeQuickstartMode( xContext );
-
- try
- {
- if ( xDesktop.is() )
- xDesktop->addTerminateListener( new RequestHandlerController );
- SetSplashScreenProgress(100);
- }
- catch ( const css::uno::Exception& e )
- {
- FatalError( MakeStartupErrorMessage(e.Message) );
- }
-
- // FIXME: move this somewhere sensible.
-#if HAVE_FEATURE_OPENCL
- CheckOpenCLCompute(xDesktop);
-#endif
-
- // Release solar mutex just before we wait for our client to connect
- {
- SolarMutexReleaser aReleaser;
-
- // Post user event to startup first application component window
- // We have to send this OpenClients message short before execute() to
- // minimize the risk that this message overtakes type detection construction!!
- Application::PostUserEvent( LINK( this, Desktop, OpenClients_Impl ) );
-
- // Post event to enable acceptors
- Application::PostUserEvent( LINK( this, Desktop, EnableAcceptors_Impl) );
-
- // Acquire solar mutex just before we enter our message loop
- }
-
- // call Application::Execute to process messages in vcl message loop
- try
- {
-#if HAVE_FEATURE_JAVA
- // The JavaContext contains an interaction handler which is used when
- // the creation of a Java Virtual Machine fails
- css::uno::ContextLayer layer2(
- new svt::JavaContext( css::uno::getCurrentContext() ) );
-#endif
- // check whether the shutdown is caused by restart just before entering the Execute
- pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested ||
- xRestartManager->isRestartRequested(true);
-
- if ( !pExecGlobals->bRestartRequested )
- {
- // if this run of the office is triggered by restart, some additional actions should be done
- DoRestartActionsIfNecessary( !rCmdLineArgs.IsInvisible() && !rCmdLineArgs.IsNoQuickstart() );
-
- DoExecute();
- }
- }
- catch(const css::document::CorruptedFilterConfigurationException& exFilterCfg)
- {
- RequestHandler::SetDowning();
- FatalError( MakeStartupErrorMessage(exFilterCfg.Message) );
- }
- catch(const css::configuration::CorruptedConfigurationException& exAnyCfg)
- {
- RequestHandler::SetDowning();
- FatalError( MakeStartupErrorMessage(exAnyCfg.Message) );
- }
- catch( const css::uno::Exception& exUNO)
- {
- RequestHandler::SetDowning();
- FatalError( exUNO.Message);
- }
- catch( const std::exception& exSTD)
- {
- RequestHandler::SetDowning();
- FatalError( OUString::createFromAscii( exSTD.what()));
- }
- catch( ...)
- {
- RequestHandler::SetDowning();
- FatalError( "Caught Unknown Exception: Aborting!");
- }
- }
- else
- {
- if (xDesktop.is())
- xDesktop->terminate();
- }
- // CAUTION: you do not necessarily get here e.g. on the Mac.
- // please put all deinitialization code into doShutdown
- return doShutdown();
-}
-
-int Desktop::doShutdown()
-{
- if( ! pExecGlobals )
- return EXIT_SUCCESS;
-
- pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested ||
- OfficeRestartManager::get(comphelper::getProcessComponentContext())->
- isRestartRequested(true);
- if ( pExecGlobals->bRestartRequested )
- SetRestartState();
-
- if (pExecGlobals->xGlobalBroadcaster.is())
- {
- css::document::DocumentEvent aEvent;
- aEvent.EventName = "OnCloseApp";
- pExecGlobals->xGlobalBroadcaster->documentEventOccured(aEvent);
- }
-
- delete pResMgr;
- pResMgr = nullptr;
- // Restore old value
- const CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
- if ( rCmdLineArgs.IsHeadless() || rCmdLineArgs.IsEventTesting() )
- SvtMiscOptions().SetUseSystemFileDialog( pExecGlobals->bUseSystemFileDialog );
-
- OUString pidfileName = rCmdLineArgs.GetPidfileName();
- if ( !pidfileName.isEmpty() )
- {
- OUString pidfileURL;
-
- if ( osl_getFileURLFromSystemPath(pidfileName.pData, &pidfileURL.pData) == osl_File_E_None )
- {
- if ( osl::File::remove( pidfileURL ) != osl::FileBase::E_None )
- {
- SAL_WARN("desktop.app", "shutdown: cannot remove pidfile " << pidfileURL);
- }
- }
- else
- {
- SAL_WARN("desktop.app", "shutdown: cannot get pidfile URL from path" << pidfileName);
- }
- }
-
- // remove temp directory
- RemoveTemporaryDirectory();
- FlushConfiguration();
- // The acceptors in the AcceptorMap must be released (in DeregisterServices)
- // with the solar mutex unlocked, to avoid deadlock:
- {
- SolarMutexReleaser aReleaser;
- DeregisterServices();
-#if HAVE_FEATURE_SCRIPTING
- StarBASIC::DetachAllDocBasicItems();
-#endif
- }
- // be sure that path/language options gets destroyed before
- // UCB is deinitialized
- pExecGlobals->pLanguageOptions.reset( nullptr );
- pExecGlobals->pPathOptions.reset( nullptr );
-
- bool bRR = pExecGlobals->bRestartRequested;
- delete pExecGlobals;
- pExecGlobals = nullptr;
-
- if ( bRR )
- {
- restartOnMac(true);
- if ( m_rSplashScreen.is() )
- m_rSplashScreen->reset();
-
- return EXITHELPER_NORMAL_RESTART;
- }
- return EXIT_SUCCESS;
-}
-
-IMPL_STATIC_LINK( Desktop, ImplInitFilterHdl, ::ConvertData&, rData, bool )
-{
- return GraphicFilter::GetGraphicFilter().GetFilterCallback().Call( rData );
-}
-
-bool Desktop::InitializeConfiguration()
-{
- try
- {
- css::configuration::theDefaultProvider::get(
- comphelper::getProcessComponentContext() );
- return true;
- }
- catch( css::lang::ServiceNotRegisteredException & e )
- {
- HandleBootstrapErrors(
- Desktop::BE_UNO_SERVICE_CONFIG_MISSING, e.Message );
- }
- catch( const css::configuration::MissingBootstrapFileException& e )
- {
- OUString aMsg( CreateErrorMsgString( utl::Bootstrap::MISSING_BOOTSTRAP_FILE,
- e.BootstrapFileURL ));
- HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_USER_INSTALL, aMsg );
- }
- catch( const css::configuration::InvalidBootstrapFileException& e )
- {
- OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY,
- e.BootstrapFileURL ));
- HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
- }
- catch( const css::configuration::InstallationIncompleteException& )
- {
- OUString aVersionFileURL;
- OUString aMsg;
- utl::Bootstrap::PathStatus aPathStatus = utl::Bootstrap::locateVersionFile( aVersionFileURL );
- if ( aPathStatus == utl::Bootstrap::PATH_EXISTS )
- aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE_ENTRY, aVersionFileURL );
- else
- aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE, aVersionFileURL );
-
- HandleBootstrapPathErrors( ::utl::Bootstrap::MISSING_USER_INSTALL, aMsg );
- }
- catch ( const css::configuration::backend::BackendAccessException& exception)
- {
- // [cm122549] It is assumed in this case that the message
- // coming from InitConfiguration (in fact CreateApplicationConf...)
- // is suitable for display directly.
- FatalError( MakeStartupErrorMessage( exception.Message ) );
- }
- catch ( const css::configuration::backend::BackendSetupException& exception)
- {
- // [cm122549] It is assumed in this case that the message
- // coming from InitConfiguration (in fact CreateApplicationConf...)
- // is suitable for display directly.
- FatalError( MakeStartupErrorMessage( exception.Message ) );
- }
- catch ( const css::configuration::CannotLoadConfigurationException& )
- {
- OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
- OUString() ));
- HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
- }
- catch( const css::uno::Exception& )
- {
- OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
- OUString() ));
- HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
- }
- return false;
-}
-
-void Desktop::FlushConfiguration()
-{
- css::uno::Reference< css::util::XFlushable >(
- css::configuration::theDefaultProvider::get(
- comphelper::getProcessComponentContext()),
- css::uno::UNO_QUERY_THROW)->flush();
-}
-
-bool Desktop::InitializeQuickstartMode( const Reference< XComponentContext >& rxContext )
-{
- try
- {
- // the shutdown icon sits in the systray and allows the user to keep
- // the office instance running for quicker restart
- // this will only be activated if --quickstart was specified on cmdline
-
- bool bQuickstart = shouldLaunchQuickstart();
-
- // Try to instantiate quickstart service. This service is not mandatory, so
- // do nothing if service is not available
-
- // #i105753# the following if was invented for performance
- // unfortunately this broke the Mac behavior which is to always run
- // in quickstart mode since Mac applications do not usually quit
- // when the last document closes.
- // Note that this claim that on OS X we "always run in quickstart mode"
- // has nothing to do with (quick) *starting* (i.e. starting automatically
- // when the user logs in), though, but with not quitting when no documents
- // are open.
- #ifndef MACOSX
- if ( bQuickstart )
- #endif
- {
- css::office::Quickstart::createStart(rxContext, bQuickstart);
- }
- return true;
- }
- catch( const css::uno::Exception& )
- {
- return false;
- }
-}
-
-void Desktop::OverrideSystemSettings( AllSettings& rSettings )
-{
- if ( !SvtTabAppearanceCfg::IsInitialized () )
- return;
-
- StyleSettings hStyleSettings = rSettings.GetStyleSettings();
- MouseSettings hMouseSettings = rSettings.GetMouseSettings();
-
- DragFullOptions nDragFullOptions = hStyleSettings.GetDragFullOptions();
-
- SvtTabAppearanceCfg aAppearanceCfg;
- DragMode nDragMode = aAppearanceCfg.GetDragMode();
- switch ( nDragMode )
- {
- case DragMode::FullWindow:
- nDragFullOptions |= DragFullOptions::All;
- break;
- case DragMode::Frame:
- nDragFullOptions &= ~DragFullOptions::All;
- break;
- case DragMode::SystemDep:
- default:
- break;
- }
-
- MouseFollowFlags nFollow = hMouseSettings.GetFollow();
- hMouseSettings.SetFollow( aAppearanceCfg.IsMenuMouseFollow() ? (nFollow|MouseFollowFlags::Menu) : (nFollow&~MouseFollowFlags::Menu));
- rSettings.SetMouseSettings(hMouseSettings);
-
- SvtMenuOptions aMenuOpt;
- hStyleSettings.SetUseImagesInMenus(aMenuOpt.GetMenuIconsState());
- hStyleSettings.SetContextMenuShortcuts(aMenuOpt.GetContextMenuShortcuts());
- hStyleSettings.SetDragFullOptions( nDragFullOptions );
- rSettings.SetStyleSettings ( hStyleSettings );
-}
-
-
-IMPL_STATIC_LINK(Desktop, AsyncInitFirstRun, Timer *, /*unused*/, void)
-{
- DoFirstRunInitializations();
-}
-
-
-class ExitTimer : public Timer
-{
- public:
- ExitTimer()
- {
- SetTimeout(500);
- Start();
- }
- virtual void Invoke() override
- {
- exit(42);
- }
-};
-
-IMPL_LINK_NOARG(Desktop, OpenClients_Impl, void*, void)
-{
- try {
- // #i114963#
- // Enable IPC thread before OpenClients
- //
- // This is because it is possible for another client to connect during the OpenClients() call.
- // This can happen on Windows when document is printed (not opened) and another client wants to print (when printing multiple documents).
- // If the IPC thread is enabled after OpenClients, then the client will not be processed because the application will exit after printing. i.e RequestHandler::AreRequestsPending() will always return false
- //
- // ALSO:
- //
- // Multiple clients may request simultaneous connections.
- // When this server closes down it attempts to recreate the pipe (in RequestHandler::Disable()).
- // It's possible that the client has a pending connection request.
- // When the IPC thread is not running, this connection locks (because maPipe.accept()) is never called
- RequestHandler::SetReady();
- OpenClients();
-
- CloseSplashScreen();
- CheckFirstRun( );
-#ifdef _WIN32
- // Registers a COM class factory of the service manager with the windows operating system.
- Reference< XMultiServiceFactory > xSMgr= comphelper::getProcessServiceFactory();
- xSMgr->createInstance("com.sun.star.bridge.OleApplicationRegistration");
- xSMgr->createInstance("com.sun.star.comp.ole.EmbedServer");
-#endif
- const char *pExitPostStartup = getenv ("OOO_EXIT_POST_STARTUP");
- if (pExitPostStartup && *pExitPostStartup)
- new ExitTimer();
- } catch (const css::uno::Exception &e) {
- OUString a( "UNO exception during client open:\n" );
- Application::Abort( a + e.Message );
- }
-}
-
-// enable acceptors
-IMPL_STATIC_LINK_NOARG(Desktop, EnableAcceptors_Impl, void*, void)
-{
- enableAcceptors();
-}
-
-void Desktop::OpenClients()
-{
-
- // check if a document has been recovered - if there is one of if a document was loaded by cmdline, no default document
- // should be created
- Reference < XComponent > xFirst;
- bool bRecovery = false;
-
- const CommandLineArgs& rArgs = GetCommandLineArgs();
-
- if (!rArgs.IsQuickstart())
- {
- bool bShowHelp = false;
- OUStringBuffer aHelpURLBuffer;
- if (rArgs.IsHelpWriter()) {
- bShowHelp = true;
- aHelpURLBuffer.append("vnd.sun.star.help://swriter/start");
- } else if (rArgs.IsHelpCalc()) {
- bShowHelp = true;
- aHelpURLBuffer.append("vnd.sun.star.help://scalc/start");
- } else if (rArgs.IsHelpDraw()) {
- bShowHelp = true;
- aHelpURLBuffer.append("vnd.sun.star.help://sdraw/start");
- } else if (rArgs.IsHelpImpress()) {
- bShowHelp = true;
- aHelpURLBuffer.append("vnd.sun.star.help://simpress/start");
- } else if (rArgs.IsHelpBase()) {
- bShowHelp = true;
- aHelpURLBuffer.append("vnd.sun.star.help://sdatabase/start");
- } else if (rArgs.IsHelpBasic()) {
- bShowHelp = true;
- aHelpURLBuffer.append("vnd.sun.star.help://sbasic/start");
- } else if (rArgs.IsHelpMath()) {
- bShowHelp = true;
- aHelpURLBuffer.append("vnd.sun.star.help://smath/start");
- }
- if (bShowHelp) {
- aHelpURLBuffer.append("?Language=");
- aHelpURLBuffer.append(utl::ConfigManager::getLocale());
-#if defined UNX
- aHelpURLBuffer.append("&System=UNX");
-#elif defined WNT
- aHelpURLBuffer.appendAscii("&System=WIN");
-#endif
- Application::GetHelp()->Start(
- aHelpURLBuffer.makeStringAndClear(), nullptr);
- return;
- }
- }
-
- // Disable AutoSave feature in case "--norestore" or a similar command line switch is set on the command line.
- // The reason behind: AutoSave/EmergencySave/AutoRecovery share the same data.
- // But the require that all documents, which are saved as backup should exists inside
- // memory. May be this mechanism will be inconsistent if the configuration exists...
- // but no document inside memory corresponds to this data.
- // Further it's not acceptable to recover such documents without any UI. It can
- // need some time, where the user won't see any results and wait for finishing the office startup...
- bool bAllowRecoveryAndSessionManagement = ( !rArgs.IsNoRestore() ) && ( !rArgs.IsHeadless() );
-
- // Enter safe mode if requested
- if (rArgs.IsSafeMode())
- handleSafeMode();
-
-
-#if HAVE_FEATURE_BREAKPAD
- if (crashReportInfoExists())
- handleCrashReport();
-#endif
-
- if ( ! bAllowRecoveryAndSessionManagement )
- {
- try
- {
- Reference< XDispatch > xRecovery = css::frame::theAutoRecovery::get( ::comphelper::getProcessComponentContext() );
- Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create( ::comphelper::getProcessComponentContext() );
-
- css::util::URL aCmd;
- aCmd.Complete = "vnd.sun.star.autorecovery:/disableRecovery";
- xParser->parseStrict(aCmd);
-
- xRecovery->dispatch(aCmd, css::uno::Sequence< css::beans::PropertyValue >());
- }
- catch(const css::uno::Exception& e)
- {
- SAL_WARN( "desktop.app", "Could not disable AutoRecovery." << e.Message);
- }
- }
- else
- {
- bool bCrashed = false;
- bool bExistsRecoveryData = false;
- bool bExistsSessionData = false;
- bool const bDisableRecovery = getenv("OOO_DISABLE_RECOVERY") != nullptr;
-
- impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
-
- if ( !bDisableRecovery &&
- (
- ( bExistsRecoveryData ) || // => crash with files => recovery
- ( bCrashed ) // => crash without files => error report
- )
- )
- {
- try
- {
- bRecovery = impl_callRecoveryUI(
- false , // false => force recovery instead of emergency save
- bExistsRecoveryData);
- }
- catch(const css::uno::Exception& e)
- {
- SAL_WARN( "desktop.app", "Error during recovery" << e.Message);
- }
- }
- else if (bExistsRecoveryData && bDisableRecovery && !rArgs.HasModuleParam())
- // prevent new Writer doc
- bRecovery = true;
-
- Reference< XSessionManagerListener2 > xSessionListener;
- try
- {
- // specifies whether the UI-interaction on Session shutdown is allowed
- xSessionListener = SessionListener::createWithOnQuitFlag(
- ::comphelper::getProcessComponentContext(), isUIOnSessionShutdownAllowed());
- }
- catch(const css::uno::Exception& e)
- {
- SAL_WARN( "desktop.app", "Registration of session listener failed" << e.Message);
- }
-
- if ( !bExistsRecoveryData && xSessionListener.is() )
- {
- // session management
- try
- {
- xSessionListener->doRestore();
- }
- catch(const css::uno::Exception& e)
- {
- SAL_WARN( "desktop.app", "Error in session management" << e.Message);
- }
- }
- }
-#if HAVE_FEATURE_BREAKPAD
- CrashReporter::writeCommonInfo();
-#endif
-
- RequestHandler::EnableRequests();
-
- ProcessDocumentsRequest aRequest(rArgs.getCwdUrl());
- aRequest.aOpenList = rArgs.GetOpenList();
- aRequest.aViewList = rArgs.GetViewList();
- aRequest.aStartList = rArgs.GetStartList();
- aRequest.aPrintList = rArgs.GetPrintList();
- aRequest.aPrintToList = rArgs.GetPrintToList();
- aRequest.aPrinterName = rArgs.GetPrinterName();
- aRequest.aForceOpenList = rArgs.GetForceOpenList();
- aRequest.aForceNewList = rArgs.GetForceNewList();
- aRequest.aConversionList = rArgs.GetConversionList();
- aRequest.aConversionParams = rArgs.GetConversionParams();
- aRequest.aConversionOut = rArgs.GetConversionOut();
- aRequest.aInFilter = rArgs.GetInFilter();
- aRequest.bTextCat = rArgs.IsTextCat();
-
- if ( !aRequest.aOpenList.empty() ||
- !aRequest.aViewList.empty() ||
- !aRequest.aStartList.empty() ||
- !aRequest.aPrintList.empty() ||
- !aRequest.aForceOpenList.empty() ||
- !aRequest.aForceNewList.empty() ||
- ( !aRequest.aPrintToList.empty() && !aRequest.aPrinterName.isEmpty() ) ||
- !aRequest.aConversionList.empty() )
- {
- if ( rArgs.HasModuleParam() )
- {
- SvtModuleOptions aOpt;
-
- // Support command line parameters to start a module (as preselection)
- if ( rArgs.IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
- aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::EFactory::WRITER );
- else if ( rArgs.IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
- aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::EFactory::CALC );
- else if ( rArgs.IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
- aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::EFactory::IMPRESS );
- else if ( rArgs.IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
- aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::EFactory::DRAW );
- }
-
- // check for printing disabled
- if( ( !(aRequest.aPrintList.empty() && aRequest.aPrintToList.empty()) )
- && Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
- {
- aRequest.aPrintList.clear();
- aRequest.aPrintToList.clear();
- ResMgr* pDtResMgr = GetDesktopResManager();
- if( pDtResMgr )
- {
- ScopedVclPtrInstance< MessageDialog > aBox(nullptr, ResId(STR_ERR_PRINTDISABLED, *pDtResMgr));
- aBox->Execute();
- }
- }
-
- // Process request
- if ( RequestHandler::ExecuteCmdLineRequests(aRequest, false) )
- {
- // Don't do anything if we have successfully called terminate at desktop:
- return;
- }
- }
-
- // no default document if a document was loaded by recovery or by command line or if soffice is used as server
- Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
- Reference< XElementAccess > xList( xDesktop->getFrames(), UNO_QUERY_THROW );
- if ( xList->hasElements() )
- return;
-
- if ( rArgs.IsQuickstart() || rArgs.IsInvisible() || Application::AnyInput( VclInputFlags::APPEVENT ) )
- // soffice was started as tray icon ...
- return;
-
- if ( bRecovery )
- {
- ShowBackingComponent(nullptr);
- }
- else
- {
- OpenDefault();
- }
-}
-
-void Desktop::OpenDefault()
-{
- OUString aName;
- SvtModuleOptions aOpt;
-
- const CommandLineArgs& rArgs = GetCommandLineArgs();
- if ( rArgs.IsNoDefault() ) return;
- if ( rArgs.HasModuleParam() )
- {
- // Support new command line parameters to start a module
- if ( rArgs.IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
- aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::WRITER );
- else if ( rArgs.IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
- aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::CALC );
- else if ( rArgs.IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
- aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::IMPRESS );
- else if ( rArgs.IsBase() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) )
- aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::DATABASE );
- else if ( rArgs.IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
- aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::DRAW );
- else if ( rArgs.IsMath() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH ) )
- aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::MATH );
- else if ( rArgs.IsGlobal() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
- aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::WRITERGLOBAL );
- else if ( rArgs.IsWeb() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
- aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::WRITERWEB );
- }
-
- if ( aName.isEmpty() )
- {
- // Old way to create a default document
- if ( aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
- aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::WRITER );
- else if ( aOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
- aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::CALC );
- else if ( aOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
- aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::IMPRESS );
- else if ( aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) )
- aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::DATABASE );
- else if ( aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
- aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::DRAW );
- else
- return;
- }
-
- ProcessDocumentsRequest aRequest(rArgs.getCwdUrl());
- aRequest.aOpenList.push_back(aName);
- RequestHandler::ExecuteCmdLineRequests(aRequest, false);
-}
-
-
-OUString GetURL_Impl(
- const OUString& rName, boost::optional< OUString > const & cwdUrl )
-{
- // if rName is a vnd.sun.star.script URL do not attempt to parse it
- // as INetURLObj does not handle handle there URLs
- if (rName.startsWith("vnd.sun.star.script"))
- {
- return rName;
- }
-
- // don't touch file urls, those should already be in internal form
- // they won't get better here (#112849#)
- if (comphelper::isFileUrl(rName))
- {
- return rName;
- }
-
- if ( rName.startsWith("service:"))
- {
- return rName;
- }
-
- // Add path separator to these directory and make given URL (rName) absolute by using of current working directory
- // Attention: "setFinalSlash()" is necessary for calling "smartRel2Abs()"!!!
- // Otherwhise last part will be ignored and wrong result will be returned!!!
- // "smartRel2Abs()" interpret given URL as file not as path. So he truncate last element to get the base path ...
- // But if we add a separator - he doesn't do it anymore.
- INetURLObject aObj;
- if (cwdUrl) {
- aObj.SetURL(*cwdUrl);
- aObj.setFinalSlash();
- }
-
- // Use the provided parameters for smartRel2Abs to support the usage of '%' in system paths.
- // Otherwise this char won't get encoded and we are not able to load such files later,
- bool bWasAbsolute;
- INetURLObject aURL = aObj.smartRel2Abs( rName, bWasAbsolute, false, INetURLObject::WAS_ENCODED,
- RTL_TEXTENCODING_UTF8, true );
- OUString aFileURL = aURL.GetMainURL(INetURLObject::NO_DECODE);
-
- ::osl::FileStatus aStatus( osl_FileStatus_Mask_FileURL );
- ::osl::DirectoryItem aItem;
- if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
- ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
- aFileURL = aStatus.getFileURL();
-
- return aFileURL;
-}
-
-void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
-{
- switch ( rAppEvent.GetEvent() )
- {
- case ApplicationEvent::Type::Accept:
- // every time an accept parameter is used we create an acceptor
- // with the corresponding accept-string
- createAcceptor(rAppEvent.GetStringData());
- break;
- case ApplicationEvent::Type::Appear:
- if ( !GetCommandLineArgs().IsInvisible() )
- {
- Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
-
- // find active task - the active task is always a visible task
- Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext );
- Reference< css::frame::XFrame > xTask = xDesktop->getActiveFrame();
- if ( !xTask.is() )
- {
- // get any task if there is no active one
- Reference< css::container::XIndexAccess > xList( xDesktop->getFrames(), css::uno::UNO_QUERY );
- if ( xList->getCount() > 0 )
- xList->getByIndex(0) >>= xTask;
- }
-
- if ( xTask.is() )
- {
- Reference< css::awt::XTopWindow > xTop( xTask->getContainerWindow(), UNO_QUERY );
- xTop->toFront();
- }
- else
- {
- // no visible task that could be activated found
- Reference< css::awt::XWindow > xContainerWindow;
- Reference< XFrame > xBackingFrame = xDesktop->findFrame( "_blank", 0);
- if (xBackingFrame.is())
- xContainerWindow = xBackingFrame->getContainerWindow();
- if (xContainerWindow.is())
- {
- Reference< XController > xStartModule = StartModule::createWithParentWindow(xContext, xContainerWindow);
- Reference< css::awt::XWindow > xBackingWin(xStartModule, UNO_QUERY);
- // Attention: You MUST(!) call setComponent() before you call attachFrame().
- // Because the backing component set the property "IsBackingMode" of the frame
- // to true inside attachFrame(). But setComponent() reset this state every time ...
- xBackingFrame->setComponent(xBackingWin, xStartModule);
- xStartModule->attachFrame(xBackingFrame);
- xContainerWindow->setVisible(true);
-
- vcl::Window* pCompWindow = VCLUnoHelper::GetWindow(xBackingFrame->getComponentWindow());
- if (pCompWindow)
- pCompWindow->Update();
- }
- }
- }
- break;
- case ApplicationEvent::Type::Help:
- displayCmdlineHelp(rAppEvent.GetStringData());
- break;
- case ApplicationEvent::Type::Version:
- displayVersion();
- break;
- case ApplicationEvent::Type::Open:
- {
- const CommandLineArgs& rCmdLine = GetCommandLineArgs();
- if ( !rCmdLine.IsInvisible() && !rCmdLine.IsTerminateAfterInit() )
- {
- ProcessDocumentsRequest docsRequest(rCmdLine.getCwdUrl());
- std::vector<OUString> const & data(rAppEvent.GetStringsData());
- docsRequest.aOpenList.insert(
- docsRequest.aOpenList.end(), data.begin(), data.end());
- RequestHandler::ExecuteCmdLineRequests(docsRequest, false);
- }
- }
- break;
- case ApplicationEvent::Type::OpenHelpUrl:
- // start help for a specific URL
- Application::GetHelp()->Start(rAppEvent.GetStringData(), nullptr);
- break;
- case ApplicationEvent::Type::Print:
- {
- const CommandLineArgs& rCmdLine = GetCommandLineArgs();
- if ( !rCmdLine.IsInvisible() && !rCmdLine.IsTerminateAfterInit() )
- {
- ProcessDocumentsRequest docsRequest(rCmdLine.getCwdUrl());
- std::vector<OUString> const & data(rAppEvent.GetStringsData());
- docsRequest.aPrintList.insert(
- docsRequest.aPrintList.end(), data.begin(), data.end());
- RequestHandler::ExecuteCmdLineRequests(docsRequest, false);
- }
- }
- break;
- case ApplicationEvent::Type::PrivateDoShutdown:
- {
- Desktop* pD = dynamic_cast<Desktop*>(GetpApp());
- OSL_ENSURE( pD, "no desktop ?!?" );
- if( pD )
- pD->doShutdown();
- }
- break;
- case ApplicationEvent::Type::QuickStart:
- if ( !GetCommandLineArgs().IsInvisible() )
- {
- // If the office has been started the second time its command line arguments are sent through a pipe
- // connection to the first office. We want to reuse the quickstart option for the first office.
- // NOTICE: The quickstart service must be initialized inside the "main thread", so we use the
- // application events to do this (they are executed inside main thread)!!!
- // Don't start quickstart service if the user specified "--invisible" on the command line!
- Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
- css::office::Quickstart::createStart(xContext, true/*Quickstart*/);
- }
- break;
- case ApplicationEvent::Type::ShowDialog:
- // ignore all errors here. It's clicking a menu entry only ...
- // The user will try it again, in case nothing happens .-)
- try
- {
- Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
-
- Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext );
-
- Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create(xContext);
- css::util::URL aCommand;
- if( rAppEvent.GetStringData() == "PREFERENCES" )
- aCommand.Complete = ".uno:OptionsTreeDialog";
- else if( rAppEvent.GetStringData() == "ABOUT" )
- aCommand.Complete = ".uno:About";
- if( !aCommand.Complete.isEmpty() )
- {
- xParser->parseStrict(aCommand);
-
- css::uno::Reference< css::frame::XDispatch > xDispatch = xDesktop->queryDispatch(aCommand, OUString(), 0);
- if (xDispatch.is())
- xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >());
- }
- }
- catch(const css::uno::Exception&)
- {}
- break;
- case ApplicationEvent::Type::Unaccept:
- // try to remove corresponding acceptor
- destroyAcceptor(rAppEvent.GetStringData());
- break;
- default:
- SAL_WARN( "desktop.app", "this cannot happen");
- break;
- }
-}
-
-void Desktop::OpenSplashScreen()
-{
- const CommandLineArgs &rCmdLine = GetCommandLineArgs();
- // Show intro only if this is normal start (e.g. no server, no quickstart, no printing )
- if ( !rCmdLine.IsInvisible() &&
- !rCmdLine.IsHeadless() &&
- !rCmdLine.IsQuickstart() &&
- !rCmdLine.IsMinimized() &&
- !rCmdLine.IsNoLogo() &&
- !rCmdLine.IsTerminateAfterInit() &&
- rCmdLine.GetPrintList().empty() &&
- rCmdLine.GetPrintToList().empty() &&
- rCmdLine.GetConversionList().empty() )
- {
- // Determine application name from command line parameters
- OUString aAppName;
- if ( rCmdLine.IsWriter() )
- aAppName = "writer";
- else if ( rCmdLine.IsCalc() )
- aAppName = "calc";
- else if ( rCmdLine.IsDraw() )
- aAppName = "draw";
- else if ( rCmdLine.IsImpress() )
- aAppName = "impress";
- else if ( rCmdLine.IsBase() )
- aAppName = "base";
- else if ( rCmdLine.IsGlobal() )
- aAppName = "global";
- else if ( rCmdLine.IsMath() )
- aAppName = "math";
- else if ( rCmdLine.IsWeb() )
- aAppName = "web";
-
- // Which splash to use
- OUString aSplashService( "com.sun.star.office.SplashScreen" );
- if ( rCmdLine.HasSplashPipe() )
- aSplashService = "com.sun.star.office.PipeSplashScreen";
-
- bool bVisible = true;
- Sequence< Any > aSeq( 2 );
- aSeq[0] <<= bVisible;
- aSeq[1] <<= aAppName;
- css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
- m_rSplashScreen.set(
- xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aSplashService, aSeq, xContext),
- UNO_QUERY);
-
- if(m_rSplashScreen.is())
- m_rSplashScreen->start("SplashScreen", 100);
- }
-
-}
-
-void Desktop::SetSplashScreenProgress(sal_Int32 iProgress)
-{
- if(m_rSplashScreen.is())
- {
- m_rSplashScreen->setValue(iProgress);
- }
-}
-
-void Desktop::SetSplashScreenText( const OUString& rText )
-{
- if( m_rSplashScreen.is() )
- {
- m_rSplashScreen->setText( rText );
- }
-}
-
-void Desktop::CloseSplashScreen()
-{
- if(m_rSplashScreen.is())
- {
- m_rSplashScreen->end();
- m_rSplashScreen = nullptr;
- }
-}
-
-
-void Desktop::DoFirstRunInitializations()
-{
- try
- {
- Reference< XJobExecutor > xExecutor = theJobExecutor::get( ::comphelper::getProcessComponentContext() );
- xExecutor->trigger( "onFirstRunInitialization" );
- }
- catch(const css::uno::Exception&)
- {
- SAL_WARN( "desktop.app", "Desktop::DoFirstRunInitializations: caught an exception while trigger job executor ..." );
- }
-}
-
-void Desktop::ShowBackingComponent(Desktop * progress)
-{
- if (GetCommandLineArgs().IsNoDefault())
- {
- return;
- }
- Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
- Reference< XDesktop2 > xDesktop = css::frame::Desktop::create(xContext);
- if (progress != nullptr)
- {
- progress->SetSplashScreenProgress(60);
- }
- Reference< XFrame > xBackingFrame = xDesktop->findFrame( "_blank", 0);
- Reference< css::awt::XWindow > xContainerWindow;
-
- if (xBackingFrame.is())
- xContainerWindow = xBackingFrame->getContainerWindow();
- if (xContainerWindow.is())
- {
- // set the WB_EXT_DOCUMENT style. Normally, this is done by the TaskCreator service when a "_blank"
- // frame/window is created. Since we do not use the TaskCreator here, we need to mimic its behavior,
- // otherwise documents loaded into this frame will later on miss functionality depending on the style.
- vcl::Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
- SAL_WARN_IF( !pContainerWindow, "desktop.app", "Desktop::Main: no implementation access to the frame's container window!" );
- pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WB_EXT_DOCUMENT );
- if (progress != nullptr)
- {
- progress->SetSplashScreenProgress(75);
- }
-
- Reference< XController > xStartModule = StartModule::createWithParentWindow( xContext, xContainerWindow);
- // Attention: You MUST(!) call setComponent() before you call attachFrame().
- // Because the backing component set the property "IsBackingMode" of the frame
- // to true inside attachFrame(). But setComponent() reset this state everytimes ...
- xBackingFrame->setComponent(Reference< XWindow >(xStartModule, UNO_QUERY), xStartModule);
- if (progress != nullptr)
- {
- progress->SetSplashScreenProgress(100);
- }
- xStartModule->attachFrame(xBackingFrame);
- if (progress != nullptr)
- {
- progress->CloseSplashScreen();
- }
- xContainerWindow->setVisible(true);
- }
-}
-
-
-void Desktop::CheckFirstRun( )
-{
- if (officecfg::Office::Common::Misc::FirstRun::get())
- {
- // use VCL timer, which won't trigger during shutdown if the
- // application exits before timeout
- m_firstRunTimer.SetTimeout(3000); // 3 sec.
- m_firstRunTimer.SetTimeoutHdl(LINK(this, Desktop, AsyncInitFirstRun));
- m_firstRunTimer.Start();
-
-#ifdef _WIN32
- // Check if Quickstarter should be started (on Windows only)
- TCHAR szValue[8192];
- DWORD nValueSize = sizeof(szValue);
- HKEY hKey;
- if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, "Software\\LibreOffice", &hKey ) )
- {
- if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("RunQuickstartAtFirstStart"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
- {
- css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
- css::office::Quickstart::createAutoStart(xContext, true/*Quickstart*/, true/*bAutostart*/);
- RegCloseKey( hKey );
- }
- }
-#endif
-
- std::shared_ptr< comphelper::ConfigurationChanges > batch(
- comphelper::ConfigurationChanges::create());
- officecfg::Office::Common::Misc::FirstRun::set(false, batch);
- batch->commit();
- }
-}
-
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */