LCOV - code coverage report
Current view: top level - desktop/source/app - app.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 404 1174 34.4 %
Date: 2015-06-13 12:38:46 Functions: 39 64 60.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <config_features.h>
      21             : #include <config_folders.h>
      22             : 
      23             : #include <sal/config.h>
      24             : 
      25             : #include <iostream>
      26             : 
      27             : #include "app.hxx"
      28             : #include "desktop.hrc"
      29             : #include "cmdlineargs.hxx"
      30             : #include "cmdlinehelp.hxx"
      31             : #include "dispatchwatcher.hxx"
      32             : #include "configinit.hxx"
      33             : #include "lockfile.hxx"
      34             : #include "userinstall.hxx"
      35             : #include "desktopcontext.hxx"
      36             : #include "exithelper.h"
      37             : #include "migration.hxx"
      38             : 
      39             : #include <svl/languageoptions.hxx>
      40             : #include <svtools/javacontext.hxx>
      41             : #include <com/sun/star/beans/XPropertySet.hpp>
      42             : #include <com/sun/star/frame/theAutoRecovery.hpp>
      43             : #include <com/sun/star/frame/theGlobalEventBroadcaster.hpp>
      44             : #include <com/sun/star/frame/SessionListener.hpp>
      45             : #include <com/sun/star/frame/XSessionManagerListener.hpp>
      46             : #include <com/sun/star/frame/XSynchronousDispatch.hpp>
      47             : #include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
      48             : #include <com/sun/star/configuration/CorruptedConfigurationException.hpp>
      49             : #include <com/sun/star/configuration/theDefaultProvider.hpp>
      50             : #include <com/sun/star/util/XFlushable.hpp>
      51             : #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
      52             : #include <com/sun/star/frame/Desktop.hpp>
      53             : #include <com/sun/star/frame/StartModule.hpp>
      54             : #include <com/sun/star/frame/XComponentLoader.hpp>
      55             : #include <com/sun/star/view/XPrintable.hpp>
      56             : #include <com/sun/star/awt/XTopWindow.hpp>
      57             : #include <com/sun/star/util/URLTransformer.hpp>
      58             : #include <com/sun/star/util/XURLTransformer.hpp>
      59             : #include <com/sun/star/util/XCloseable.hpp>
      60             : #include <com/sun/star/frame/XDispatchProvider.hpp>
      61             : #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
      62             : #include <com/sun/star/configuration/MissingBootstrapFileException.hpp>
      63             : #include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
      64             : #include <com/sun/star/configuration/InstallationIncompleteException.hpp>
      65             : #include <com/sun/star/configuration/backend/BackendSetupException.hpp>
      66             : #include <com/sun/star/configuration/backend/BackendAccessException.hpp>
      67             : #include <com/sun/star/task/theJobExecutor.hpp>
      68             : #include <com/sun/star/task/OfficeRestartManager.hpp>
      69             : #include <com/sun/star/task/XRestartManager.hpp>
      70             : #include <com/sun/star/document/XDocumentEventListener.hpp>
      71             : #include <com/sun/star/frame/theUICommandDescription.hpp>
      72             : #include <com/sun/star/ui/theUIElementFactoryManager.hpp>
      73             : #include <com/sun/star/ui/theWindowStateConfiguration.hpp>
      74             : #include <com/sun/star/frame/XUIControllerRegistration.hpp>
      75             : #include <com/sun/star/frame/thePopupMenuControllerFactory.hpp>
      76             : #include <com/sun/star/office/Quickstart.hpp>
      77             : 
      78             : #include <sal/log.hxx>
      79             : #include <toolkit/helper/vclunohelper.hxx>
      80             : #include <comphelper/configuration.hxx>
      81             : #include <comphelper/processfactory.hxx>
      82             : #include <unotools/bootstrap.hxx>
      83             : #include <unotools/configmgr.hxx>
      84             : #include <unotools/moduleoptions.hxx>
      85             : #include <unotools/localfilehelper.hxx>
      86             : #include <officecfg/Office/Common.hxx>
      87             : #include <officecfg/Office/Recovery.hxx>
      88             : #include <officecfg/Setup.hxx>
      89             : #include <osl/file.hxx>
      90             : #include <osl/process.h>
      91             : #include <rtl/uri.hxx>
      92             : #include <unotools/pathoptions.hxx>
      93             : #include <svtools/miscopt.hxx>
      94             : #include <svtools/menuoptions.hxx>
      95             : #include <rtl/bootstrap.hxx>
      96             : #include <vcl/help.hxx>
      97             : #include <vcl/layout.hxx>
      98             : #include <vcl/settings.hxx>
      99             : #include <sfx2/sfx.hrc>
     100             : #include <sfx2/app.hxx>
     101             : #include <svl/itemset.hxx>
     102             : #include <svl/eitem.hxx>
     103             : #include <basic/sbstar.hxx>
     104             : 
     105             : #include <svtools/fontsubstconfig.hxx>
     106             : #include <svtools/accessibilityoptions.hxx>
     107             : #include <svtools/apearcfg.hxx>
     108             : #include <vcl/graphicfilter.hxx>
     109             : 
     110             : #include "langselect.hxx"
     111             : 
     112             : #include <config_telepathy.h>
     113             : 
     114             : #if ENABLE_TELEPATHY
     115             : #include <tubes/manager.hxx>
     116             : #endif
     117             : 
     118             : #if defined MACOSX
     119             : #include <errno.h>
     120             : #include <sys/wait.h>
     121             : #endif
     122             : 
     123             : #ifdef WNT
     124             : #ifdef _MSC_VER
     125             : #pragma warning(push, 1) /* disable warnings within system headers */
     126             : #pragma warning (disable: 4005)
     127             : #endif
     128             : #define WIN32_LEAN_AND_MEAN
     129             : #include <windows.h>
     130             : #ifdef _MSC_VER
     131             : #pragma warning(pop)
     132             : #endif
     133             : #endif //WNT
     134             : 
     135             : #if defined WNT
     136             : #include <process.h>
     137             : #define GETPID _getpid
     138             : #else
     139             : #include <unistd.h>
     140             : #define GETPID getpid
     141             : #endif
     142             : 
     143             : using namespace ::com::sun::star::awt;
     144             : using namespace ::com::sun::star::uno;
     145             : using namespace ::com::sun::star::util;
     146             : using namespace ::com::sun::star::lang;
     147             : using namespace ::com::sun::star::beans;
     148             : using namespace ::com::sun::star::frame;
     149             : using namespace ::com::sun::star::document;
     150             : using namespace ::com::sun::star::view;
     151             : using namespace ::com::sun::star::task;
     152             : using namespace ::com::sun::star::system;
     153             : using namespace ::com::sun::star::ui;
     154             : using namespace ::com::sun::star::ui::dialogs;
     155             : using namespace ::com::sun::star::container;
     156             : 
     157             : ResMgr* desktop::Desktop::pResMgr = 0;
     158             : 
     159             : namespace desktop
     160             : {
     161             : 
     162             : static oslSignalHandler pSignalHandler = 0;
     163             : 
     164             : namespace {
     165             : 
     166             : #if HAVE_FEATURE_EXTENSIONS
     167             : 
     168             : // Remove any existing UserInstallation's extensions cache data remaining from
     169             : // old installations.  This addresses at least two problems:
     170             : //
     171             : // For one, apparently due to the old share/prereg/bundled mechanism (disabled
     172             : // since 5c47e5f63a79a9e72ec4a100786b1bbf65137ed4 "fdo#51252 Disable copying
     173             : // share/prereg/bundled to avoid startup crashes"), the user/extensions/bundled
     174             : // cache could contain corrupted information (like a UNO component registered
     175             : // twice, which got changed from active to passive registration in one LO
     176             : // version, but the version of the corresponding bundled extension only
     177             : // incremented in a later LO version).
     178             : //
     179             : // For another, UserInstallations have been seen in the wild where no extensions
     180             : // were installed per-user (any longer), but user/uno_packages/cache/registry/
     181             : // com.sun.star.comp.deployment.component.PackageRegistryBackend/*.rdb files
     182             : // contained data nevertheless.
     183             : //
     184             : // When a LO upgrade is detected (i.e., no user/extensions/buildid or one
     185             : // containing an old build ID), then user/extensions and
     186             : // user/uno_packages/cache/registry/
     187             : // com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc are
     188             : // removed.  That should prevent any problems starting the service manager due
     189             : // to old junk.  Later on in Desktop::SynchronizeExtensionRepositories, the
     190             : // removed cache data is recreated.
     191             : //
     192             : // Multiple instances of soffice.bin can execute this code in parallel for a
     193             : // single UserInstallation, as it is called before OfficeIPCThread is set up.
     194             : // Therefore, any errors here only lead to SAL_WARNs.
     195             : //
     196             : // At least in theory, this function could be removed again once no
     197             : // UserInstallation can be poisoned by old junk any more.
     198         116 : bool cleanExtensionCache() {
     199             :     OUString buildId(
     200         116 :         "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("version") ":buildid}");
     201         116 :     rtl::Bootstrap::expandMacros(buildId); //TODO: detect failure
     202             :     OUString extDir(
     203             :         "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap")
     204         232 :         ":UserInstallation}/user/extensions");
     205         116 :     rtl::Bootstrap::expandMacros(extDir); //TODO: detect failure
     206         232 :     OUString buildIdFile(extDir + "/buildid");
     207         232 :     osl::File fr(buildIdFile);
     208         116 :     osl::FileBase::RC rc = fr.open(osl_File_OpenFlag_Read);
     209         116 :     switch (rc) {
     210             :     case osl::FileBase::E_None:
     211             :         {
     212          63 :             rtl::ByteSequence s1;
     213          63 :             rc = fr.readLine(s1);
     214          63 :             osl::FileBase::RC rc2 = fr.close();
     215             :             SAL_WARN_IF(
     216             :                 rc2 != osl::FileBase::E_None, "desktop.app",
     217             :                 "cannot close " << fr.getURL() << " after reading: " << +rc2);
     218             :             // readLine returns E_AGAIN for a zero-size file:
     219          63 :             if (rc != osl::FileBase::E_None && rc != osl::FileBase::E_AGAIN) {
     220             :                 SAL_WARN( "desktop.app", "cannot read from " << fr.getURL() << ": " << +rc);
     221           0 :                 break;
     222             :             }
     223             :             OUString s2(
     224          63 :                 reinterpret_cast< char const * >(s1.getConstArray()),
     225         126 :                 s1.getLength(), RTL_TEXTENCODING_ISO_8859_1);
     226             :                 // using ISO 8859-1 avoids any and all conversion errors; the
     227             :                 // content should only be a subset of ASCII, anyway
     228          63 :             if (s2 == buildId) {
     229          63 :                 return false;
     230             :             }
     231           0 :             break;
     232             :         }
     233             :     case osl::FileBase::E_NOENT:
     234          53 :         break;
     235             :     default:
     236             :         SAL_WARN( "desktop.app", "cannot open " << fr.getURL() << " for reading: " << +rc);
     237           0 :         break;
     238             :     }
     239          53 :     utl::removeTree(extDir);
     240             :     OUString userRcFile(
     241             :         "$UNO_USER_PACKAGES_CACHE/registry/"
     242          53 :         "com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
     243          53 :     rtl::Bootstrap::expandMacros(userRcFile); //TODO: detect failure
     244          53 :     rc = osl::File::remove(userRcFile);
     245             :     SAL_WARN_IF(
     246             :         rc != osl::FileBase::E_None && rc != osl::FileBase::E_NOENT, "desktop.app",
     247             :         "cannot remove file " << userRcFile << ": " << +rc);
     248          53 :     rc = osl::Directory::createPath(extDir);
     249             :     SAL_WARN_IF(
     250             :         rc != osl::FileBase::E_None && rc != osl::FileBase::E_EXIST, "desktop.app",
     251             :         "cannot create path " << extDir << ": " << +rc);
     252         106 :     osl::File fw(buildIdFile);
     253          53 :     rc = fw.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
     254          53 :     if (rc != osl::FileBase::E_None) {
     255             :         SAL_WARN( "desktop.app", "cannot open " << fw.getURL() << " for writing: " << +rc);
     256           0 :         return true;
     257             :     }
     258         106 :     OString buf(OUStringToOString(buildId, RTL_TEXTENCODING_UTF8));
     259             :         // using UTF-8 avoids almost all conversion errors (and buildid
     260             :         // containing single surrogate halves should never happen, anyway); the
     261             :         // content should only be a subset of ASCII, anyway
     262          53 :     sal_uInt64 n = 0;
     263          53 :     rc = fw.write(buf.getStr(), buf.getLength(), n);
     264             :     SAL_WARN_IF(
     265             :         (rc != osl::FileBase::E_None
     266             :          || n != static_cast< sal_uInt32 >(buf.getLength())),
     267             :         "desktop.app",
     268             :         "cannot write to " << fw.getURL() << ": " << +rc << ", " << n);
     269          53 :     rc = fw.close();
     270             :     SAL_WARN_IF(
     271             :         rc != osl::FileBase::E_None, "desktop.app",
     272             :         "cannot close " << fw.getURL() << " after writing: " << +rc);
     273         222 :     return true;
     274             : }
     275             : 
     276             : #endif
     277             : 
     278           0 : bool shouldLaunchQuickstart()
     279             : {
     280           0 :     bool bQuickstart = Desktop::GetCommandLineArgs().IsQuickstart();
     281           0 :     if (!bQuickstart)
     282             :     {
     283           0 :         const SfxPoolItem* pItem=0;
     284           0 :         SfxItemSet aQLSet(SfxGetpApp()->GetPool(), SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER);
     285           0 :         SfxGetpApp()->GetOptions(aQLSet);
     286           0 :         SfxItemState eState = aQLSet.GetItemState(SID_ATTR_QUICKLAUNCHER, false, &pItem);
     287           0 :         if (SfxItemState::SET == eState)
     288           0 :             bQuickstart = static_cast<const SfxBoolItem*>(pItem)->GetValue();
     289             :     }
     290           0 :     return bQuickstart;
     291             : }
     292             : 
     293          52 : void SetRestartState() {
     294             :     try {
     295             :         std::shared_ptr< comphelper::ConfigurationChanges > batch(
     296          52 :             comphelper::ConfigurationChanges::create());
     297          52 :         officecfg::Setup::Office::OfficeRestartInProgress::set(true, batch);
     298          52 :         batch->commit();
     299           0 :     } catch (css::uno::Exception & e) {
     300             :         SAL_WARN("desktop.app", "ignoring Exception \"" << e.Message << "\"");
     301             :     }
     302          52 : }
     303             : 
     304          64 : void DoRestartActionsIfNecessary(bool quickstart) {
     305          64 :     if (quickstart) {
     306             :         try {
     307           0 :             if (officecfg::Setup::Office::OfficeRestartInProgress::get()) {
     308             :                 std::shared_ptr< comphelper::ConfigurationChanges > batch(
     309           0 :                     comphelper::ConfigurationChanges::create());
     310             :                 officecfg::Setup::Office::OfficeRestartInProgress::set(
     311           0 :                     false, batch);
     312           0 :                 batch->commit();
     313             :                 css::office::Quickstart::createStart(
     314             :                     comphelper::getProcessComponentContext(),
     315           0 :                     shouldLaunchQuickstart());
     316             :             }
     317           0 :         } catch (css::uno::Exception & e) {
     318             :             SAL_WARN(
     319             :                 "desktop.app", "ignoring Exception \"" << e.Message << "\"");
     320             :         }
     321             :     }
     322          64 : }
     323             : 
     324             : }
     325             : 
     326             : 
     327             : 
     328         116 : ResMgr* Desktop::GetDesktopResManager()
     329             : {
     330         116 :     if ( !Desktop::pResMgr )
     331             :     {
     332             :         // Create desktop resource manager and bootstrap process
     333             :         // was successful. Use default way to get language specific message.
     334         116 :         if ( Application::IsInExecute() )
     335           0 :             Desktop::pResMgr = ResMgr::CreateResMgr("dkt");
     336             : 
     337         116 :         if ( !Desktop::pResMgr )
     338             :         {
     339             :             // Use VCL to get the correct language specific message as we
     340             :             // are in the bootstrap process and not able to get the installed
     341             :             // language!!
     342         116 :             OUString aUILocaleString = langselect::getEmergencyLocale();
     343         232 :             LanguageTag aLanguageTag( aUILocaleString);
     344             :             //! ResMgr may modify the Locale for fallback!
     345         232 :             Desktop::pResMgr = ResMgr::SearchCreateResMgr( "dkt", aLanguageTag);
     346             :         }
     347             :     }
     348             : 
     349         116 :     return Desktop::pResMgr;
     350             : }
     351             : 
     352             : namespace {
     353             : 
     354             : 
     355             : // Get a message string securely. There is a fallback string if the resource
     356             : // is not available.
     357             : 
     358           0 : OUString GetMsgString(
     359             :     sal_uInt16 nId, const OUString& aFallbackMsg,
     360             :     bool bAlwaysUseFallbackMsg = false )
     361             : {
     362           0 :     if ( !bAlwaysUseFallbackMsg )
     363             :     {
     364           0 :         ResMgr* resMgr = Desktop::GetDesktopResManager();
     365           0 :         if ( resMgr )
     366           0 :             return ResId(nId, *resMgr).toString();
     367             :     }
     368           0 :     return aFallbackMsg;
     369             : }
     370             : 
     371           0 : OUString MakeStartupErrorMessage(
     372             :     OUString const & aErrorMessage, bool bAlwaysUseFallbackMsg = false )
     373             : {
     374           0 :     OUStringBuffer    aDiagnosticMessage( 100 );
     375             : 
     376             :     aDiagnosticMessage.append(
     377             :         GetMsgString(
     378             :             STR_BOOTSTRAP_ERR_CANNOT_START, "The program cannot be started.",
     379           0 :             bAlwaysUseFallbackMsg ) );
     380             : 
     381           0 :     aDiagnosticMessage.appendAscii( "\n" );
     382             : 
     383           0 :     aDiagnosticMessage.append( aErrorMessage );
     384             : 
     385           0 :     return aDiagnosticMessage.makeStringAndClear();
     386             : }
     387             : 
     388           0 : OUString MakeStartupConfigAccessErrorMessage( OUString const & aInternalErrMsg )
     389             : {
     390           0 :     OUStringBuffer aDiagnosticMessage( 200 );
     391             : 
     392           0 :     ResMgr* pResMgr = Desktop::GetDesktopResManager();
     393           0 :     if ( pResMgr )
     394           0 :         aDiagnosticMessage.append( ResId(STR_BOOTSTRAP_ERR_CFG_DATAACCESS, *pResMgr).toString() );
     395             :     else
     396           0 :         aDiagnosticMessage.appendAscii( "The program cannot be started." );
     397             : 
     398           0 :     if ( !aInternalErrMsg.isEmpty() )
     399             :     {
     400           0 :         aDiagnosticMessage.appendAscii( "\n\n" );
     401           0 :         if ( pResMgr )
     402           0 :             aDiagnosticMessage.append( ResId(STR_INTERNAL_ERRMSG, *pResMgr).toString() );
     403             :         else
     404           0 :             aDiagnosticMessage.appendAscii( "The following internal error has occurred:\n\n" );
     405           0 :         aDiagnosticMessage.append( aInternalErrMsg );
     406             :     }
     407             : 
     408           0 :     return aDiagnosticMessage.makeStringAndClear();
     409             : }
     410             : 
     411             : 
     412             : // shows a simple error box with the given message ... but exits from these process !
     413             : // Fatal errors can't be solved by the process ... nor any recovery can help.
     414             : // Mostly the installation was damaged and must be repaired manually .. or by calling
     415             : // setup again.
     416             : // On the other side we must make sure that no further actions will be possible within
     417             : // the current office process ! No pipe requests, no menu/toolbar/shortuct actions
     418             : // are allowed. Otherwise we will force a "crash inside a crash".
     419             : // Thats why we have to use a special native message box here which does not use yield :-)
     420             : 
     421           0 : void FatalError(const OUString& sMessage)
     422             : {
     423           0 :     OUString sProductKey = ::utl::Bootstrap::getProductKey();
     424           0 :     if ( sProductKey.isEmpty())
     425             :     {
     426           0 :         osl_getExecutableFile( &sProductKey.pData );
     427             : 
     428           0 :         ::sal_uInt32 nLastIndex = sProductKey.lastIndexOf('/');
     429           0 :         if ( nLastIndex > 0 )
     430           0 :             sProductKey = sProductKey.copy( nLastIndex+1 );
     431             :     }
     432             : 
     433           0 :     OUStringBuffer sTitle (128);
     434           0 :     sTitle.append      (sProductKey     );
     435           0 :     sTitle.appendAscii (" - Fatal Error");
     436             : 
     437           0 :     Application::ShowNativeErrorBox (sTitle.makeStringAndClear (), sMessage);
     438           0 :     _exit(EXITHELPER_FATAL_ERROR);
     439             : }
     440             : 
     441         116 : static bool ShouldSuppressUI(const CommandLineArgs& rCmdLine)
     442             : {
     443         116 :     return  rCmdLine.IsInvisible() ||
     444         116 :             rCmdLine.IsHeadless() ||
     445         116 :             rCmdLine.IsQuickstart();
     446             : }
     447             : 
     448             : struct theCommandLineArgs : public rtl::Static< CommandLineArgs, theCommandLineArgs > {};
     449             : 
     450             : }
     451             : 
     452         877 : CommandLineArgs& Desktop::GetCommandLineArgs()
     453             : {
     454         877 :     return theCommandLineArgs::get();
     455             : }
     456             : 
     457             : namespace
     458             : {
     459             :     struct BrandName
     460             :         : public rtl::Static< OUString, BrandName > {};
     461             :     struct Version
     462             :         : public rtl::Static< OUString, Version > {};
     463             :     struct AboutBoxVersion
     464             :         : public rtl::Static< OUString, AboutBoxVersion > {};
     465             :     struct AboutBoxVersionSuffix
     466             :         : public rtl::Static< OUString, AboutBoxVersionSuffix > {};
     467             :     struct OOOVendor
     468             :         : public rtl::Static< OUString, OOOVendor > {};
     469             :     struct Extension
     470             :         : public rtl::Static< OUString, Extension > {};
     471             : }
     472             : 
     473      680630 : OUString ReplaceStringHookProc( const OUString& rStr )
     474             : {
     475      680630 :     OUString sRet(rStr);
     476             : 
     477      680630 :     if (sRet.indexOf("%PRODUCT") != -1 || sRet.indexOf("%ABOUTBOX") != -1)
     478             :     {
     479         941 :         OUString sBrandName = BrandName::get();
     480        1882 :         OUString sVersion = Version::get();
     481        1882 :         OUString sBuildId = utl::Bootstrap::getBuildIdData("development");
     482        1882 :         OUString sAboutBoxVersion = AboutBoxVersion::get();
     483        1882 :         OUString sAboutBoxVersionSuffix = AboutBoxVersionSuffix::get();
     484        1882 :         OUString sExtension = Extension::get();
     485             : 
     486         941 :         if ( sBrandName.isEmpty() )
     487             :         {
     488         941 :             sBrandName = utl::ConfigManager::getProductName();
     489         941 :             sVersion = utl::ConfigManager::getProductVersion();
     490         941 :             sAboutBoxVersion = utl::ConfigManager::getAboutBoxProductVersion();
     491         941 :             sAboutBoxVersionSuffix = utl::ConfigManager::getAboutBoxProductVersionSuffix();
     492         941 :             if ( sExtension.isEmpty() )
     493             :             {
     494         941 :                 sExtension = utl::ConfigManager::getProductExtension();
     495             :             }
     496             :         }
     497             : 
     498         941 :         sRet = sRet.replaceAll( "%PRODUCTNAME", sBrandName );
     499         941 :         sRet = sRet.replaceAll( "%PRODUCTVERSION", sVersion );
     500         941 :         sRet = sRet.replaceAll( "%BUILDID", sBuildId );
     501         941 :         sRet = sRet.replaceAll( "%ABOUTBOXPRODUCTVERSIONSUFFIX", sAboutBoxVersionSuffix );
     502         941 :         sRet = sRet.replaceAll( "%ABOUTBOXPRODUCTVERSION", sAboutBoxVersion );
     503        1882 :         sRet = sRet.replaceAll( "%PRODUCTEXTENSION", sExtension );
     504             :     }
     505             : 
     506      680630 :     if ( sRet.indexOf( "%OOOVENDOR" ) != -1 )
     507             :     {
     508           0 :         OUString sOOOVendor = OOOVendor::get();
     509             : 
     510           0 :         if ( sOOOVendor.isEmpty() )
     511             :         {
     512           0 :             sOOOVendor = utl::ConfigManager::getVendor();
     513             :         }
     514             : 
     515           0 :         sRet = sRet.replaceAll( "%OOOVENDOR", sOOOVendor );
     516             :     }
     517             : 
     518      680630 :     return sRet;
     519             : }
     520             : 
     521         116 : Desktop::Desktop()
     522             :     : m_bCleanedExtensionCache(false)
     523             :     , m_bServicesRegistered(false)
     524             :     , m_aBootstrapError(BE_OK)
     525         116 :     , m_aBootstrapStatus(BS_OK)
     526             : {
     527         116 : }
     528             : 
     529         116 : Desktop::~Desktop()
     530             : {
     531             : #if ENABLE_TELEPATHY
     532             :     TeleManager::finalize();
     533             : #endif
     534         116 : }
     535             : 
     536         116 : void Desktop::Init()
     537             : {
     538         116 :     SetBootstrapStatus(BS_OK);
     539             : 
     540             : #if HAVE_FEATURE_EXTENSIONS
     541         116 :     m_bCleanedExtensionCache = cleanExtensionCache();
     542             : #endif
     543             : 
     544             :     // We need to have service factory before going further, but see fdo#37195.
     545             :     // Doing this will mmap common.rdb, making it not overwritable on windows,
     546             :     // so this can't happen before the synchronization above. Lets rework this
     547             :     // so that the above is called *from* CreateApplicationServiceManager or
     548             :     // something to enforce this gotcha
     549             :     try
     550             :     {
     551         116 :         InitApplicationServiceManager();
     552             :     }
     553           0 :     catch (css::uno::Exception & e)
     554             :     {
     555           0 :         SetBootstrapError( BE_UNO_SERVICEMANAGER, e.Message );
     556             :     }
     557             : 
     558         116 :     if ( m_aBootstrapError == BE_OK )
     559             :     {
     560             :         try
     561             :         {
     562         116 :             if (!langselect::prepareLocale())
     563             :             {
     564           0 :                 SetBootstrapError( BE_LANGUAGE_MISSING, OUString() );
     565             :             }
     566             :         }
     567           0 :         catch (css::uno::Exception & e)
     568             :         {
     569           0 :             SetBootstrapError( BE_OFFICECONFIG_BROKEN, e.Message );
     570             :         }
     571             :     }
     572             : 
     573             :     if ( true )
     574             :     {
     575         116 :         const CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
     576             : 
     577             :         // start ipc thread only for non-remote offices
     578         116 :         OfficeIPCThread::Status aStatus = OfficeIPCThread::EnableOfficeIPCThread();
     579         116 :         if ( aStatus == OfficeIPCThread::IPC_STATUS_PIPE_ERROR )
     580             :         {
     581             : #if HAVE_FEATURE_MACOSX_SANDBOX
     582             :             // In a sandboxed LO, on 10.8.2 at least, creating the
     583             :             // Unix domain socket fails. Ignore that as hopefully
     584             :             // people running a sandboxed LO won't attempt starting it
     585             :             // from the command-line or otherwise in tricky ways, so
     586             :             // the normal OS X mechanism that prevents multiple
     587             :             // instances of an app from being started should work
     588             :             // fine. I hope.
     589             : #elif defined ANDROID
     590             :             // Ignore crack pipe errors on Android, too
     591             : #else
     592             :             // Keep using this oddly named BE_PATHINFO_MISSING value
     593             :             // for pipe-related errors on other platforms. Of course
     594             :             // this crack with two (if not more) levels of our own
     595             :             // error codes hiding the actual system error code is
     596             :             // broken, but that is done all over the code, let's leave
     597             :             // re-enginering that to another year.
     598           0 :             SetBootstrapError( BE_PATHINFO_MISSING, OUString() );
     599             : #endif
     600             :         }
     601         116 :         else if ( aStatus == OfficeIPCThread::IPC_STATUS_BOOTSTRAP_ERROR )
     602             :         {
     603           0 :             SetBootstrapError( BE_PATHINFO_MISSING, OUString() );
     604             :         }
     605         116 :         else if ( aStatus == OfficeIPCThread::IPC_STATUS_2ND_OFFICE )
     606             :         {
     607             :             // 2nd office startup should terminate after sending cmdlineargs through pipe
     608           0 :             SetBootstrapStatus(BS_TERMINATE);
     609             :         }
     610         348 :         else if ( !rCmdLineArgs.GetUnknown().isEmpty()
     611         348 :                   || rCmdLineArgs.IsHelp() || rCmdLineArgs.IsVersion() )
     612             :         {
     613             :             // disable IPC thread in an instance that is just showing a help message
     614           0 :             OfficeIPCThread::DisableOfficeIPCThread();
     615             :         }
     616         116 :         pSignalHandler = osl_addSignalHandler(SalMainPipeExchangeSignal_impl, NULL);
     617             :     }
     618         116 : }
     619             : 
     620         611 : void Desktop::InitFinished()
     621             : {
     622         611 :     CloseSplashScreen();
     623         611 : }
     624             : 
     625         116 : void Desktop::DeInit()
     626             : {
     627             :     try {
     628             :         // instead of removing of the configManager just let it commit all the changes
     629         116 :         utl::ConfigManager::storeConfigItems();
     630         116 :         FlushConfiguration();
     631             : 
     632             :         // close splashscreen if it's still open
     633         116 :         CloseSplashScreen();
     634             :         Reference< XComponent >(
     635         232 :             comphelper::getProcessComponentContext(), UNO_QUERY_THROW )->
     636         116 :             dispose();
     637             :         // nobody should get a destroyed service factory...
     638         116 :         ::comphelper::setProcessServiceFactory( NULL );
     639             : 
     640             :         // clear lockfile
     641         116 :         m_xLockfile.reset();
     642             : 
     643         116 :         OfficeIPCThread::DisableOfficeIPCThread();
     644         116 :         if( pSignalHandler )
     645         116 :             osl_removeSignalHandler( pSignalHandler );
     646           0 :     } catch (const RuntimeException&) {
     647             :         // someone threw an exception during shutdown
     648             :         // this will leave some garbage behind..
     649             :     }
     650         116 : }
     651             : 
     652           0 : bool Desktop::QueryExit()
     653             : {
     654             :     try
     655             :     {
     656           0 :         utl::ConfigManager::storeConfigItems();
     657             :     }
     658           0 :     catch ( const RuntimeException& )
     659             :     {
     660             :     }
     661             : 
     662           0 :     const sal_Char SUSPEND_QUICKSTARTVETO[] = "SuspendQuickstartVeto";
     663             : 
     664           0 :     Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
     665           0 :     Reference< XPropertySet > xPropertySet(xDesktop, UNO_QUERY_THROW);
     666           0 :     xPropertySet->setPropertyValue( OUString(SUSPEND_QUICKSTARTVETO ), Any(true) );
     667             : 
     668           0 :     bool bExit = xDesktop->terminate();
     669             : 
     670           0 :     if ( !bExit )
     671             :     {
     672           0 :         xPropertySet->setPropertyValue( OUString(SUSPEND_QUICKSTARTVETO ), Any(false) );
     673             :     }
     674             :     else
     675             :     {
     676           0 :         FlushConfiguration();
     677             :         try
     678             :         {
     679             :             // it is no problem to call DisableOfficeIPCThread() more than once
     680             :             // it also looks to be threadsafe
     681           0 :             OfficeIPCThread::DisableOfficeIPCThread();
     682             :         }
     683           0 :         catch ( const RuntimeException& )
     684             :         {
     685             :         }
     686             : 
     687           0 :         m_xLockfile.reset();
     688             : 
     689             :     }
     690             : 
     691           0 :     return bExit;
     692             : }
     693             : 
     694           0 : void Desktop::HandleBootstrapPathErrors( ::utl::Bootstrap::Status aBootstrapStatus, const OUString& aDiagnosticMessage )
     695             : {
     696           0 :     if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
     697             :     {
     698           0 :         OUString        aProductKey;
     699           0 :         OUString        aTemp;
     700             : 
     701           0 :         osl_getExecutableFile( &aProductKey.pData );
     702           0 :         sal_uInt32     lastIndex = aProductKey.lastIndexOf('/');
     703           0 :         if ( lastIndex > 0 )
     704           0 :             aProductKey = aProductKey.copy( lastIndex+1 );
     705             : 
     706           0 :         aTemp = ::utl::Bootstrap::getProductKey( aProductKey );
     707           0 :         if ( !aTemp.isEmpty() )
     708           0 :             aProductKey = aTemp;
     709             : 
     710           0 :         OUString const aMessage(aDiagnosticMessage + "\n");
     711             : 
     712           0 :         ScopedVclPtrInstance< MessageDialog > aBootstrapFailedBox(nullptr, aMessage);
     713           0 :         aBootstrapFailedBox->SetText( aProductKey );
     714           0 :         aBootstrapFailedBox->Execute();
     715             :     }
     716           0 : }
     717             : 
     718             : // Create a error message depending on bootstrap failure code and an optional file url
     719           0 : OUString    Desktop::CreateErrorMsgString(
     720             :     utl::Bootstrap::FailureCode nFailureCode,
     721             :     const OUString& aFileURL )
     722             : {
     723           0 :     OUString        aMsg;
     724           0 :     OUString        aFilePath;
     725           0 :     bool            bFileInfo = true;
     726             : 
     727           0 :     switch ( nFailureCode )
     728             :     {
     729             :         /// the shared installation directory could not be located
     730             :         case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
     731             :         {
     732           0 :             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_PATH_INVALID,
     733           0 :                         OUString( "The installation path is not available." ) );
     734           0 :             bFileInfo = false;
     735             :         }
     736           0 :         break;
     737             : 
     738             :         /// the bootstrap INI file could not be found or read
     739             :         case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
     740             :         {
     741           0 :             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
     742           0 :                         OUString( "The configuration file \"$1\" is missing." ) );
     743             :         }
     744           0 :         break;
     745             : 
     746             :         /// the bootstrap INI is missing a required entry
     747             :         /// the bootstrap INI contains invalid data
     748             :          case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
     749             :          case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
     750             :         {
     751           0 :             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_CORRUPT,
     752           0 :                         OUString( "The configuration file \"$1\" is corrupt." ) );
     753             :         }
     754           0 :         break;
     755             : 
     756             :         /// the version locator INI file could not be found or read
     757             :         case ::utl::Bootstrap::MISSING_VERSION_FILE:
     758             :         {
     759           0 :             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
     760           0 :                         OUString( "The configuration file \"$1\" is missing." ) );
     761             :         }
     762           0 :         break;
     763             : 
     764             :         /// the version locator INI has no entry for this version
     765             :          case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
     766             :         {
     767           0 :             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SUPPORT,
     768           0 :                         OUString( "The main configuration file \"$1\" does not support the current version." ) );
     769             :         }
     770           0 :         break;
     771             : 
     772             :         /// the user installation directory does not exist
     773             :            case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
     774             :         {
     775           0 :             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_DIR_MISSING,
     776           0 :                         OUString( "The configuration directory \"$1\" is missing." ) );
     777             :         }
     778           0 :         break;
     779             : 
     780             :         /// some bootstrap data was invalid in unexpected ways
     781             :         case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
     782             :         {
     783           0 :             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_INTERNAL,
     784           0 :                         OUString( "An internal failure occurred." ) );
     785           0 :             bFileInfo = false;
     786             :         }
     787           0 :         break;
     788             : 
     789             :         case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
     790             :         {
     791             :             // This needs to be improved, see #i67575#:
     792           0 :             aMsg = "Invalid version file entry";
     793           0 :             bFileInfo = false;
     794             :         }
     795           0 :         break;
     796             : 
     797             :         case ::utl::Bootstrap::NO_FAILURE:
     798             :         {
     799             :             OSL_ASSERT(false);
     800             :         }
     801           0 :         break;
     802             :     }
     803             : 
     804           0 :     if ( bFileInfo )
     805             :     {
     806           0 :         OUString aMsgString( aMsg );
     807             : 
     808           0 :         osl::File::getSystemPathFromFileURL( aFileURL, aFilePath );
     809             : 
     810           0 :         aMsgString = aMsgString.replaceFirst( "$1", aFilePath );
     811           0 :         aMsg = aMsgString;
     812             :     }
     813             : 
     814           0 :     return MakeStartupErrorMessage( aMsg );
     815             : }
     816             : 
     817           0 : void Desktop::HandleBootstrapErrors(
     818             :     BootstrapError aBootstrapError, OUString const & aErrorMessage )
     819             : {
     820           0 :     if ( aBootstrapError == BE_PATHINFO_MISSING )
     821             :     {
     822           0 :         OUString                    aErrorMsg;
     823           0 :         OUString                    aBuffer;
     824             :         utl::Bootstrap::Status        aBootstrapStatus;
     825             :         utl::Bootstrap::FailureCode    nFailureCode;
     826             : 
     827           0 :         aBootstrapStatus = ::utl::Bootstrap::checkBootstrapStatus( aBuffer, nFailureCode );
     828           0 :         if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
     829             :         {
     830           0 :             switch ( nFailureCode )
     831             :             {
     832             :                 case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
     833             :                 case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
     834             :                 {
     835           0 :                     aErrorMsg = CreateErrorMsgString( nFailureCode, OUString() );
     836             :                 }
     837           0 :                 break;
     838             : 
     839             :                 /// the bootstrap INI file could not be found or read
     840             :                 /// the bootstrap INI is missing a required entry
     841             :                 /// the bootstrap INI contains invalid data
     842             :                 case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
     843             :                 case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
     844             :                 case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
     845             :                 {
     846           0 :                     OUString aBootstrapFileURL;
     847             : 
     848           0 :                     utl::Bootstrap::locateBootstrapFile( aBootstrapFileURL );
     849           0 :                     aErrorMsg = CreateErrorMsgString( nFailureCode, aBootstrapFileURL );
     850             :                 }
     851           0 :                 break;
     852             : 
     853             :                 /// the version locator INI file could not be found or read
     854             :                 /// the version locator INI has no entry for this version
     855             :                 /// the version locator INI entry is not a valid directory URL
     856             :                  case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
     857             :                  case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
     858             :                  case ::utl::Bootstrap::MISSING_VERSION_FILE:
     859             :                 {
     860           0 :                     OUString aVersionFileURL;
     861             : 
     862           0 :                     utl::Bootstrap::locateVersionFile( aVersionFileURL );
     863           0 :                     aErrorMsg = CreateErrorMsgString( nFailureCode, aVersionFileURL );
     864             :                 }
     865           0 :                 break;
     866             : 
     867             :                 /// the user installation directory does not exist
     868             :                  case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
     869             :                 {
     870           0 :                     OUString aUserInstallationURL;
     871             : 
     872           0 :                     utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
     873           0 :                     aErrorMsg = CreateErrorMsgString( nFailureCode, aUserInstallationURL );
     874             :                 }
     875           0 :                 break;
     876             : 
     877             :                 case ::utl::Bootstrap::NO_FAILURE:
     878             :                 {
     879             :                     OSL_ASSERT(false);
     880             :                 }
     881           0 :                 break;
     882             :             }
     883             : 
     884           0 :             HandleBootstrapPathErrors( aBootstrapStatus, aErrorMsg );
     885           0 :         }
     886             :     }
     887           0 :     else if ( aBootstrapError == BE_UNO_SERVICEMANAGER || aBootstrapError == BE_UNO_SERVICE_CONFIG_MISSING )
     888             :     {
     889             :         // Uno service manager is not available. VCL needs a uno service manager to display a message box!!!
     890             :         // Currently we are not able to display a message box with a service manager due to this limitations inside VCL.
     891             : 
     892             :         // When UNO is not properly initialized, all kinds of things can fail
     893             :         // and cause the process to crash (e.g., a call to GetMsgString may
     894             :         // crash when somewhere deep within that call Any::operator <= is used
     895             :         // with a PropertyValue, and no binary UNO type description for
     896             :         // PropertyValue is available).  To give the user a hint even if
     897             :         // generating and displaying a message box below crashes, print a
     898             :         // hard-coded message on stderr first:
     899             :         std::cerr
     900           0 :             << "The application cannot be started.\n"
     901             :                 // STR_BOOTSTRAP_ERR_CANNOT_START
     902             :             << (aBootstrapError == BE_UNO_SERVICEMANAGER
     903             :                 ? "The component manager is not available.\n"
     904             :                     // STR_BOOTSTRAP_ERR_NO_SERVICE
     905           0 :                 : "The configuration service is not available.\n");
     906             :                     // STR_BOOTSTRAP_ERR_NO_CFG_SERVICE
     907           0 :         if ( !aErrorMessage.isEmpty() )
     908             :         {
     909           0 :             std::cerr << "(\"" << aErrorMessage << "\")\n";
     910             :         }
     911             : 
     912             :         // First sentence. We cannot bootstrap office further!
     913           0 :         OUString            aMessage;
     914           0 :         OUStringBuffer        aDiagnosticMessage( 100 );
     915             : 
     916           0 :         OUString aErrorMsg;
     917             : 
     918           0 :         if ( aBootstrapError == BE_UNO_SERVICEMANAGER )
     919           0 :             aErrorMsg = "The service manager is not available.";
     920             :         else
     921           0 :             aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_CFG_SERVICE,
     922           0 :                             OUString( "The configuration service is not available." ) );
     923             : 
     924           0 :         aDiagnosticMessage.append( aErrorMsg );
     925           0 :         aDiagnosticMessage.appendAscii( "\n" );
     926           0 :         if ( !aErrorMessage.isEmpty() )
     927             :         {
     928           0 :             aDiagnosticMessage.appendAscii( "(\"" );
     929           0 :             aDiagnosticMessage.append( aErrorMessage );
     930           0 :             aDiagnosticMessage.appendAscii( "\")\n" );
     931             :         }
     932             : 
     933             :         // Due to the fact the we haven't a backup applicat.rdb file anymore it is not possible to
     934             :         // repair the installation with the setup executable besides the office executable. Now
     935             :         // we have to ask the user to start the setup on CD/installation directory manually!!
     936             :         OUString aStartSetupManually( GetMsgString(
     937             :             STR_ASK_START_SETUP_MANUALLY,
     938             :             OUString( "Start setup application to repair the installation from CD, or the folder containing the installation packages." ),
     939           0 :             aBootstrapError == BE_UNO_SERVICEMANAGER ) );
     940             : 
     941           0 :         aDiagnosticMessage.append( aStartSetupManually );
     942           0 :         aMessage = MakeStartupErrorMessage(
     943             :             aDiagnosticMessage.makeStringAndClear(),
     944           0 :             aBootstrapError == BE_UNO_SERVICEMANAGER );
     945             : 
     946           0 :         FatalError( aMessage);
     947             :     }
     948           0 :     else if ( aBootstrapError == BE_OFFICECONFIG_BROKEN )
     949             :     {
     950             :         OUString msg(
     951             :             GetMsgString(
     952             :                 STR_CONFIG_ERR_ACCESS_GENERAL,
     953             :                 ("A general error occurred while accessing your central"
     954           0 :                  " configuration.")));
     955           0 :         if (!aErrorMessage.isEmpty()) {
     956           0 :             msg += "\n(\"" + aErrorMessage + "\")";
     957             :         }
     958           0 :         FatalError(MakeStartupErrorMessage(msg));
     959             :     }
     960           0 :     else if ( aBootstrapError == BE_USERINSTALL_FAILED )
     961             :     {
     962           0 :         OUString aMessage;
     963           0 :         OUStringBuffer aDiagnosticMessage( 100 );
     964           0 :         OUString aErrorMsg;
     965           0 :         aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_USERINSTALL_FAILED,
     966           0 :             OUString( "User installation could not be completed" ) );
     967           0 :         aDiagnosticMessage.append( aErrorMsg );
     968           0 :         aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
     969           0 :         FatalError(aMessage);
     970             :     }
     971           0 :     else if ( aBootstrapError == BE_LANGUAGE_MISSING )
     972             :     {
     973           0 :         OUString aMessage;
     974           0 :         OUStringBuffer aDiagnosticMessage( 100 );
     975           0 :         OUString aErrorMsg;
     976           0 :         aErrorMsg = GetMsgString(
     977             :             //@@@ FIXME: should use an own resource string => #i36213#
     978             :             STR_BOOTSTRAP_ERR_LANGUAGE_MISSING,
     979           0 :             OUString( "Language could not be determined." ) );
     980           0 :         aDiagnosticMessage.append( aErrorMsg );
     981           0 :         aMessage = MakeStartupErrorMessage(
     982           0 :             aDiagnosticMessage.makeStringAndClear() );
     983           0 :         FatalError(aMessage);
     984             :     }
     985           0 :     else if (( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE ) ||
     986             :              ( aBootstrapError == BE_USERINSTALL_NOWRITEACCESS      ))
     987             :     {
     988           0 :         OUString       aUserInstallationURL;
     989           0 :         OUString       aUserInstallationPath;
     990           0 :         OUString       aMessage;
     991           0 :         OUString       aErrorMsg;
     992           0 :         OUStringBuffer aDiagnosticMessage( 100 );
     993             : 
     994           0 :         utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
     995             : 
     996           0 :         if ( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE )
     997           0 :             aErrorMsg = GetMsgString(
     998             :                 STR_BOOSTRAP_ERR_NOTENOUGHDISKSPACE,
     999           0 :                 OUString( "User installation could not be completed due to insufficient free disk space." ) );
    1000             :         else
    1001           0 :             aErrorMsg = GetMsgString(
    1002             :                 STR_BOOSTRAP_ERR_NOACCESSRIGHTS,
    1003           0 :                 OUString( "User installation could not be processed due to missing access rights." ) );
    1004             : 
    1005           0 :         osl::File::getSystemPathFromFileURL( aUserInstallationURL, aUserInstallationPath );
    1006             : 
    1007           0 :         aDiagnosticMessage.append( aErrorMsg );
    1008           0 :         aDiagnosticMessage.append( aUserInstallationPath );
    1009           0 :         aMessage = MakeStartupErrorMessage(
    1010           0 :             aDiagnosticMessage.makeStringAndClear() );
    1011           0 :         FatalError(aMessage);
    1012             :     }
    1013             : 
    1014           0 :     return;
    1015             : }
    1016             : 
    1017             : 
    1018           0 : bool Desktop::isUIOnSessionShutdownAllowed()
    1019             : {
    1020             :     return officecfg::Office::Recovery::SessionShutdown::DocumentStoreUIEnabled
    1021           0 :         ::get();
    1022             : }
    1023             : 
    1024             : 
    1025             : /** @short  check if recovery must be started or not.
    1026             : 
    1027             :     @param  bCrashed [boolean ... out!]
    1028             :             the office crashed last times.
    1029             :             But may be there are no recovery data.
    1030             :             Useful to trigger the error report tool without
    1031             :             showing the recovery UI.
    1032             : 
    1033             :     @param  bRecoveryDataExists [boolean ... out!]
    1034             :             there exists some recovery data.
    1035             : 
    1036             :     @param  bSessionDataExists [boolean ... out!]
    1037             :             there exists some session data.
    1038             :             Because the user may be logged out last time from it's
    1039             :             unix session...
    1040             : */
    1041         116 : void impl_checkRecoveryState(bool& bCrashed           ,
    1042             :                              bool& bRecoveryDataExists,
    1043             :                              bool& bSessionDataExists )
    1044             : {
    1045         116 :     bCrashed = officecfg::Office::Recovery::RecoveryInfo::Crashed::get();
    1046         232 :     bool elements = officecfg::Office::Recovery::RecoveryList::get()->
    1047         116 :         hasElements();
    1048             :     bool session
    1049         116 :         = officecfg::Office::Recovery::RecoveryInfo::SessionData::get();
    1050         116 :     bRecoveryDataExists = elements && !session;
    1051         116 :     bSessionDataExists = elements && session;
    1052         116 : }
    1053             : 
    1054             : 
    1055             : /*  @short  start the recovery wizard.
    1056             : 
    1057             :     @param  bEmergencySave
    1058             :             differs between EMERGENCY_SAVE and RECOVERY
    1059             : */
    1060           0 : bool impl_callRecoveryUI(bool bEmergencySave     ,
    1061             :                          bool bExistsRecoveryData)
    1062             : {
    1063             :     static const char SERVICENAME_RECOVERYUI[] = "com.sun.star.comp.svx.RecoveryUI";
    1064             :     static const char COMMAND_EMERGENCYSAVE[] = "vnd.sun.star.autorecovery:/doEmergencySave";
    1065             :     static const char COMMAND_RECOVERY[] = "vnd.sun.star.autorecovery:/doAutoRecovery";
    1066             : 
    1067           0 :     css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
    1068             : 
    1069             :     Reference< css::frame::XSynchronousDispatch > xRecoveryUI(
    1070           0 :         xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_RECOVERYUI, xContext),
    1071           0 :         css::uno::UNO_QUERY_THROW);
    1072             : 
    1073             :     Reference< css::util::XURLTransformer > xURLParser =
    1074           0 :         css::util::URLTransformer::create(::comphelper::getProcessComponentContext());
    1075             : 
    1076           0 :     css::util::URL aURL;
    1077           0 :     if (bEmergencySave)
    1078           0 :         aURL.Complete = COMMAND_EMERGENCYSAVE;
    1079           0 :     else if (bExistsRecoveryData)
    1080           0 :         aURL.Complete = COMMAND_RECOVERY;
    1081             :     else
    1082           0 :         return false;
    1083             : 
    1084           0 :     xURLParser->parseStrict(aURL);
    1085             : 
    1086           0 :     css::uno::Any aRet = xRecoveryUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
    1087           0 :     bool bRet = false;
    1088           0 :     aRet >>= bRet;
    1089           0 :     return !bEmergencySave || bRet;
    1090             : }
    1091             : 
    1092             : /*
    1093             :  * Save all open documents so they will be reopened
    1094             :  * the next time the application is started
    1095             :  *
    1096             :  * returns sal_True if at least one document could be saved...
    1097             :  *
    1098             :  */
    1099             : 
    1100           0 : bool Desktop::SaveTasks()
    1101             : {
    1102             :     return impl_callRecoveryUI(
    1103             :         true , // sal_True => force emergency save
    1104           0 :         false);
    1105             : }
    1106             : 
    1107             : namespace {
    1108             : 
    1109          52 : void restartOnMac(bool passArguments) {
    1110             : #if defined MACOSX
    1111             :     OfficeIPCThread::DisableOfficeIPCThread();
    1112             : #if HAVE_FEATURE_MACOSX_SANDBOX
    1113             :     (void) passArguments; // avoid warnings
    1114             :     ResMgr *resMgr = Desktop::GetDesktopResManager();
    1115             :     OUString aMessage = ResId(STR_LO_MUST_BE_RESTARTED, *resMgr).toString();
    1116             : 
    1117             :     MessageDialog aRestartBox(NULL, aMessage);
    1118             :     aRestartBox.Execute();
    1119             : #else
    1120             :     OUString execUrl;
    1121             :     OSL_VERIFY(osl_getExecutableFile(&execUrl.pData) == osl_Process_E_None);
    1122             :     OUString execPath;
    1123             :     OString execPath8;
    1124             :     if ((osl::FileBase::getSystemPathFromFileURL(execUrl, execPath)
    1125             :          != osl::FileBase::E_None) ||
    1126             :         !execPath.convertToString(
    1127             :             &execPath8, osl_getThreadTextEncoding(),
    1128             :             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
    1129             :              RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
    1130             :     {
    1131             :         std::abort();
    1132             :     }
    1133             :     std::vector< OString > args;
    1134             :     args.push_back(execPath8);
    1135             :     bool wait = false;
    1136             :     if (passArguments) {
    1137             :         sal_uInt32 n = osl_getCommandArgCount();
    1138             :         for (sal_uInt32 i = 0; i < n; ++i) {
    1139             :             OUString arg;
    1140             :             osl_getCommandArg(i, &arg.pData);
    1141             :             if (arg.match("--accept=")) {
    1142             :                 wait = true;
    1143             :             }
    1144             :             OString arg8;
    1145             :             if (!arg.convertToString(
    1146             :                     &arg8, osl_getThreadTextEncoding(),
    1147             :                     (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
    1148             :                      RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
    1149             :             {
    1150             :                 std::abort();
    1151             :             }
    1152             :             args.push_back(arg8);
    1153             :         }
    1154             :     }
    1155             :     std::vector< char const * > argPtrs;
    1156             :     for (std::vector< OString >::iterator i(args.begin()); i != args.end();
    1157             :          ++i)
    1158             :     {
    1159             :         argPtrs.push_back(i->getStr());
    1160             :     }
    1161             :     argPtrs.push_back(0);
    1162             :     execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
    1163             :     if (errno == ENOTSUP) { // happens when multithreaded on OS X < 10.6
    1164             :         pid_t pid = fork();
    1165             :         if (pid == 0) {
    1166             :             execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
    1167             :         } else if (pid > 0) {
    1168             :             // Two simultaneously running soffice processes lead to two dock
    1169             :             // icons, so avoid waiting here unless it must be assumed that the
    1170             :             // process invoking soffice itself wants to wait for soffice to
    1171             :             // finish:
    1172             :             if (!wait) {
    1173             :                 return;
    1174             :             }
    1175             :             int stat;
    1176             :             if (waitpid(pid, &stat, 0) == pid && WIFEXITED(stat)) {
    1177             :                 _exit(WEXITSTATUS(stat));
    1178             :             }
    1179             :         }
    1180             :     }
    1181             :     std::abort();
    1182             : #endif
    1183             : #else
    1184             :     (void) passArguments; // avoid warnings
    1185             : #endif
    1186          52 : }
    1187             : 
    1188             : }
    1189             : 
    1190           0 : sal_uInt16 Desktop::Exception(sal_uInt16 nError)
    1191             : {
    1192             :     // protect against recursive calls
    1193             :     static bool bInException = false;
    1194             : 
    1195           0 :     SystemWindowFlags nOldMode = Application::GetSystemWindowMode();
    1196           0 :     Application::SetSystemWindowMode( nOldMode & ~SystemWindowFlags::NOAUTOMODE );
    1197           0 :     Application::SetDefDialogParent( NULL );
    1198             : 
    1199           0 :     if ( bInException )
    1200             :     {
    1201           0 :         OUString aDoubleExceptionString;
    1202           0 :         Application::Abort( aDoubleExceptionString );
    1203             :     }
    1204             : 
    1205           0 :     bInException = true;
    1206           0 :     const CommandLineArgs& rArgs = GetCommandLineArgs();
    1207             : 
    1208             :     // save all modified documents ... if it's allowed doing so.
    1209           0 :     bool bRestart                           = false;
    1210             :     bool bAllowRecoveryAndSessionManagement = (
    1211           0 :                                                     ( !rArgs.IsNoRestore()                    ) && // some use cases of office must work without recovery
    1212           0 :                                                     ( !rArgs.IsHeadless()                     ) &&
    1213           0 :                                                     (( nError & EXC_MAJORTYPE ) != EXC_DISPLAY ) && // recovery can't work without UI ... but UI layer seems to be the reason for this crash
    1214           0 :                                                     ( Application::IsInExecute()               )    // crashes during startup and shutdown should be ignored (they indicates a corrupt installation ...)
    1215           0 :                                                   );
    1216           0 :     if ( bAllowRecoveryAndSessionManagement )
    1217           0 :         bRestart = SaveTasks();
    1218             : 
    1219           0 :     FlushConfiguration();
    1220             : 
    1221           0 :     switch( nError & EXC_MAJORTYPE )
    1222             :     {
    1223             :         case EXC_RSCNOTLOADED:
    1224             :         {
    1225           0 :             OUString aResExceptionString;
    1226           0 :             Application::Abort( aResExceptionString );
    1227           0 :             break;
    1228             :         }
    1229             : 
    1230             :         default:
    1231             :         {
    1232           0 :             m_xLockfile.reset();
    1233             : 
    1234           0 :             if( bRestart )
    1235             :             {
    1236           0 :                 OfficeIPCThread::DisableOfficeIPCThread();
    1237           0 :                 if( pSignalHandler )
    1238           0 :                     osl_removeSignalHandler( pSignalHandler );
    1239             : 
    1240           0 :                 restartOnMac(false);
    1241           0 :                 if ( m_rSplashScreen.is() )
    1242           0 :                     m_rSplashScreen->reset();
    1243             : 
    1244           0 :                 _exit( EXITHELPER_CRASH_WITH_RESTART );
    1245             :             }
    1246             :             else
    1247             :             {
    1248           0 :                 Application::Abort( OUString() );
    1249             :             }
    1250             : 
    1251           0 :             break;
    1252             :         }
    1253             :     }
    1254             : 
    1255             :     OSL_ASSERT(false); // unreachable
    1256           0 :     return 0;
    1257             : }
    1258             : 
    1259           0 : void Desktop::AppEvent( const ApplicationEvent& rAppEvent )
    1260             : {
    1261           0 :     HandleAppEvent( rAppEvent );
    1262           0 : }
    1263             : 
    1264             : 
    1265         116 : struct ExecuteGlobals
    1266             : {
    1267             :     Reference < css::document::XDocumentEventListener > xGlobalBroadcaster;
    1268             :     bool bRestartRequested;
    1269             :     bool bUseSystemFileDialog;
    1270             :     std::unique_ptr<SvtLanguageOptions> pLanguageOptions;
    1271             :     std::unique_ptr<SvtPathOptions> pPathOptions;
    1272             : 
    1273         116 :     ExecuteGlobals()
    1274             :     : bRestartRequested( false )
    1275         116 :     , bUseSystemFileDialog( true )
    1276         116 :     {}
    1277             : };
    1278             : 
    1279             : static ExecuteGlobals* pExecGlobals = NULL;
    1280             : 
    1281         116 : int Desktop::Main()
    1282             : {
    1283         116 :     pExecGlobals = new ExecuteGlobals();
    1284             : 
    1285             :     // Remember current context object
    1286             :     com::sun::star::uno::ContextLayer layer(
    1287         116 :         com::sun::star::uno::getCurrentContext() );
    1288             : 
    1289         116 :     if ( m_aBootstrapError != BE_OK )
    1290             :     {
    1291           0 :         HandleBootstrapErrors( m_aBootstrapError, m_aBootstrapErrorMessage );
    1292           0 :         return EXIT_FAILURE;
    1293             :     }
    1294             : 
    1295         116 :     BootstrapStatus eStatus = GetBootstrapStatus();
    1296         116 :     if (eStatus == BS_TERMINATE) {
    1297           0 :         return EXIT_SUCCESS;
    1298             :     }
    1299             : 
    1300             :     // Detect desktop environment - need to do this as early as possible
    1301             :     com::sun::star::uno::setCurrentContext(
    1302         116 :         new DesktopContext( com::sun::star::uno::getCurrentContext() ) );
    1303             : 
    1304         116 :     CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
    1305             : 
    1306             : #if HAVE_FEATURE_DESKTOP
    1307         232 :     OUString aUnknown( rCmdLineArgs.GetUnknown() );
    1308         116 :     if ( !aUnknown.isEmpty() )
    1309             :     {
    1310           0 :         displayCmdlineHelp( aUnknown );
    1311           0 :         return EXIT_FAILURE;
    1312             :     }
    1313         116 :     if ( rCmdLineArgs.IsHelp() )
    1314             :     {
    1315           0 :         displayCmdlineHelp( OUString() );
    1316           0 :         return EXIT_SUCCESS;
    1317             :     }
    1318         116 :     if ( rCmdLineArgs.IsVersion() )
    1319             :     {
    1320           0 :         displayVersion();
    1321           0 :         return EXIT_SUCCESS;
    1322             :     }
    1323             : #endif
    1324             :     // setup configuration error handling
    1325         232 :     ConfigurationErrorHandler aConfigErrHandler;
    1326         116 :     if (!ShouldSuppressUI(rCmdLineArgs))
    1327           0 :         aConfigErrHandler.activate();
    1328             : 
    1329         116 :     ResMgr::SetReadStringHook( ReplaceStringHookProc );
    1330             : 
    1331             :     // Startup screen
    1332         116 :     OpenSplashScreen();
    1333             : 
    1334         116 :     SetSplashScreenProgress(10);
    1335             : 
    1336         116 :     userinstall::Status inst_fin = userinstall::finalize();
    1337         116 :     if (inst_fin != userinstall::EXISTED && inst_fin != userinstall::CREATED)
    1338             :     {
    1339             :         SAL_WARN( "desktop.app", "userinstall failed");
    1340           0 :         if ( inst_fin == userinstall::ERROR_NO_SPACE )
    1341             :             HandleBootstrapErrors(
    1342           0 :                 BE_USERINSTALL_NOTENOUGHDISKSPACE, OUString() );
    1343           0 :         else if ( inst_fin == userinstall::ERROR_CANT_WRITE )
    1344           0 :             HandleBootstrapErrors( BE_USERINSTALL_NOWRITEACCESS, OUString() );
    1345             :         else
    1346           0 :             HandleBootstrapErrors( BE_USERINSTALL_FAILED, OUString() );
    1347           0 :         return EXIT_FAILURE;
    1348             :     }
    1349             :     // refresh path information
    1350         116 :     utl::Bootstrap::reloadData();
    1351         116 :     SetSplashScreenProgress(20);
    1352             : 
    1353         232 :     Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
    1354             : 
    1355         232 :     Reference< XRestartManager > xRestartManager( OfficeRestartManager::get(xContext) );
    1356             : 
    1357         232 :     Reference< XDesktop2 > xDesktop;
    1358             :     try
    1359             :     {
    1360         116 :         RegisterServices(xContext);
    1361             : 
    1362         116 :         SetSplashScreenProgress(25);
    1363             : 
    1364             : #if HAVE_FEATURE_DESKTOP
    1365             :         // check user installation directory for lockfile so we can be sure
    1366             :         // there is no other instance using our data files from a remote host
    1367         116 :         m_xLockfile.reset(new Lockfile);
    1368             : 
    1369         232 :         if ( !rCmdLineArgs.IsHeadless() && !rCmdLineArgs.IsInvisible() &&
    1370         116 :              !rCmdLineArgs.IsNoLockcheck() && !m_xLockfile->check( Lockfile_execWarning ))
    1371             :         {
    1372             :             // Lockfile exists, and user clicked 'no'
    1373           0 :             return EXIT_FAILURE;
    1374             :         }
    1375             : 
    1376             :         // check if accessibility is enabled but not working and allow to quit
    1377         116 :         if( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() )
    1378             :         {
    1379           0 :             if( !InitAccessBridge() )
    1380           0 :                 return EXIT_FAILURE;
    1381             :         }
    1382             : #endif
    1383             : 
    1384             :         // terminate if requested...
    1385         116 :         if( rCmdLineArgs.IsTerminateAfterInit() )
    1386           0 :             return EXIT_SUCCESS;
    1387             : 
    1388             :         //  Read the common configuration items for optimization purpose
    1389         116 :         if ( !InitializeConfiguration() )
    1390           0 :             return EXIT_FAILURE;
    1391             : 
    1392         116 :         SetSplashScreenProgress(30);
    1393             : 
    1394             :         // set static variable to disable crash reporting
    1395         116 :         osl_setErrorReporting( false );
    1396             : 
    1397             :         // create title string
    1398         116 :         LanguageTag aLocale( LANGUAGE_SYSTEM);
    1399         116 :         ResMgr* pLabelResMgr = GetDesktopResManager();
    1400         232 :         OUString aTitle = pLabelResMgr ? ResId(RID_APPTITLE, *pLabelResMgr).toString() : OUString();
    1401             : 
    1402             : #ifdef DBG_UTIL
    1403             :         //include buildid in non product builds
    1404             :         OUString aDefault("development");
    1405             :         aTitle += " [";
    1406             :         aTitle += utl::Bootstrap::getBuildIdData(aDefault);
    1407             :         aTitle += "]";
    1408             : #endif
    1409             : 
    1410         116 :         SetDisplayName( aTitle );
    1411         116 :         SetSplashScreenProgress(35);
    1412         116 :         pExecGlobals->pPathOptions.reset( new SvtPathOptions);
    1413         116 :         SetSplashScreenProgress(40);
    1414             : 
    1415         116 :         xDesktop = css::frame::Desktop::create( xContext );
    1416             : 
    1417             :         // create service for loadin SFX (still needed in startup)
    1418         232 :         pExecGlobals->xGlobalBroadcaster = Reference < css::document::XDocumentEventListener >
    1419         116 :             ( css::frame::theGlobalEventBroadcaster::get(xContext), UNO_SET_THROW );
    1420             : 
    1421             :         /* ensure existence of a default window that messages can be dispatched to
    1422             :            This is for the benefit of testtool which uses PostUserEvent extensively
    1423             :            and else can deadlock while creating this window from another tread while
    1424             :            the main thread is not yet in the event loop.
    1425             :         */
    1426         116 :         Application::GetDefaultDevice();
    1427             : 
    1428             : #if HAVE_FEATURE_EXTENSIONS
    1429             :         // Check if bundled or shared extensions were added /removed
    1430             :         // and process those extensions (has to be done before checking
    1431             :         // the extension dependencies!
    1432         116 :         SynchronizeExtensionRepositories();
    1433         116 :         bool bAbort = CheckExtensionDependencies();
    1434         116 :         if ( bAbort )
    1435           0 :             return EXIT_FAILURE;
    1436             : 
    1437         116 :         if (inst_fin == userinstall::CREATED)
    1438             :         {
    1439          53 :             Migration::migrateSettingsIfNecessary();
    1440             :         }
    1441             : #endif
    1442             : 
    1443             :         // keep a language options instance...
    1444         116 :         pExecGlobals->pLanguageOptions.reset( new SvtLanguageOptions(true));
    1445             : 
    1446         232 :         css::document::DocumentEvent aEvent;
    1447         116 :         aEvent.EventName = "OnStartApp";
    1448         116 :         pExecGlobals->xGlobalBroadcaster->documentEventOccured(aEvent);
    1449             : 
    1450         116 :         SetSplashScreenProgress(50);
    1451             : 
    1452             :         // Backing Component
    1453         116 :         bool bCrashed            = false;
    1454         116 :         bool bExistsRecoveryData = false;
    1455         116 :         bool bExistsSessionData  = false;
    1456             : 
    1457         116 :         impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
    1458             : 
    1459         232 :         OUString pidfileName = rCmdLineArgs.GetPidfileName();
    1460         116 :         if ( !pidfileName.isEmpty() )
    1461             :         {
    1462           0 :             OUString pidfileURL;
    1463             : 
    1464           0 :             if ( osl_getFileURLFromSystemPath(pidfileName.pData, &pidfileURL.pData) == osl_File_E_None )
    1465             :             {
    1466           0 :                 osl::File pidfile( pidfileURL );
    1467             :                 osl::FileBase::RC rc;
    1468             : 
    1469           0 :                 osl::File::remove( pidfileURL );
    1470           0 :                 if ( (rc = pidfile.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create ) ) == osl::File::E_None )
    1471             :                 {
    1472           0 :                     OString pid( OString::number( GETPID() ) );
    1473           0 :                     sal_uInt64 written = 0;
    1474           0 :                     if ( pidfile.write(pid.getStr(), pid.getLength(), written) != osl::File::E_None )
    1475             :                     {
    1476             :                         SAL_WARN("desktop.app", "cannot write pidfile " << pidfile.getURL());
    1477             :                     }
    1478           0 :                     pidfile.close();
    1479             :                 }
    1480             :                 else
    1481             :                 {
    1482             :                     SAL_WARN("desktop.app", "cannot open pidfile " << pidfile.getURL() << osl::FileBase::RC(rc));
    1483           0 :                 }
    1484             :             }
    1485             :             else
    1486             :             {
    1487             :                 SAL_WARN("desktop.app", "cannot get pidfile URL from path" << pidfileName);
    1488           0 :             }
    1489             :         }
    1490             : 
    1491         116 :         if ( rCmdLineArgs.IsHeadless() )
    1492             :         {
    1493             :             // Ensure that we use not the system file dialogs as
    1494             :             // headless mode relies on Application::EnableHeadlessMode()
    1495             :             // which does only work for VCL dialogs!!
    1496         116 :             SvtMiscOptions aMiscOptions;
    1497         116 :             pExecGlobals->bUseSystemFileDialog = aMiscOptions.UseSystemFileDialog();
    1498         116 :             aMiscOptions.SetUseSystemFileDialog( false );
    1499             :         }
    1500             : 
    1501         116 :         pExecGlobals->bRestartRequested = xRestartManager->isRestartRequested(
    1502         232 :             true);
    1503         116 :         if ( !pExecGlobals->bRestartRequested )
    1504             :         {
    1505         319 :             if ((!rCmdLineArgs.WantsToLoadDocument() && !rCmdLineArgs.IsInvisible() && !rCmdLineArgs.IsHeadless() && !rCmdLineArgs.IsQuickstart()) &&
    1506          64 :                 (SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::STARTMODULE)) &&
    1507           0 :                 (!bExistsRecoveryData                                                  ) &&
    1508         128 :                 (!bExistsSessionData                                                   ) &&
    1509           0 :                 (!Application::AnyInput( VclInputFlags::APPEVENT )                          ))
    1510             :             {
    1511           0 :                  ShowBackingComponent(this);
    1512             :             }
    1513         116 :         }
    1514             :     }
    1515           0 :     catch ( const com::sun::star::lang::WrappedTargetException& wte )
    1516             :     {
    1517           0 :         com::sun::star::uno::Exception te;
    1518           0 :         wte.TargetException >>= te;
    1519           0 :         FatalError( MakeStartupConfigAccessErrorMessage(wte.Message + te.Message) );
    1520             :     }
    1521           0 :     catch ( const com::sun::star::uno::Exception& e )
    1522             :     {
    1523           0 :         FatalError( MakeStartupErrorMessage(e.Message) );
    1524             :     }
    1525         116 :     SetSplashScreenProgress(55);
    1526             : 
    1527         116 :     SvtFontSubstConfig().Apply();
    1528             : 
    1529         232 :     SvtTabAppearanceCfg aAppearanceCfg;
    1530         116 :     SvtTabAppearanceCfg::SetInitialized();
    1531         116 :     aAppearanceCfg.SetApplicationDefaults( this );
    1532         232 :     SvtAccessibilityOptions aOptions;
    1533         116 :     aOptions.SetVCLSettings();
    1534         116 :     SetSplashScreenProgress(60);
    1535             : 
    1536             : #if ENABLE_TELEPATHY
    1537             :     bool bListen = rCmdLineArgs.IsInvisible();
    1538             :     TeleManager::init( bListen );
    1539             : #endif
    1540             : 
    1541         116 :     if ( !pExecGlobals->bRestartRequested )
    1542             :     {
    1543          64 :         Application::SetFilterHdl( LINK( this, Desktop, ImplInitFilterHdl ) );
    1544          64 :         bool bTerminateRequested = false;
    1545             : 
    1546             :         // Preload function depends on an initialized sfx application!
    1547          64 :         SetSplashScreenProgress(75);
    1548             : 
    1549             :         // use system window dialogs
    1550          64 :         Application::SetSystemWindowMode( SystemWindowFlags::DIALOG );
    1551             : 
    1552          64 :         SetSplashScreenProgress(80);
    1553             : 
    1554          64 :         if ( !bTerminateRequested && !rCmdLineArgs.IsInvisible() &&
    1555           0 :              !rCmdLineArgs.IsNoQuickstart() )
    1556           0 :             InitializeQuickstartMode( xContext );
    1557             : 
    1558             :         try
    1559             :         {
    1560          64 :             if ( xDesktop.is() )
    1561          64 :                 xDesktop->addTerminateListener( new OfficeIPCThreadController );
    1562          64 :             SetSplashScreenProgress(100);
    1563             :         }
    1564           0 :         catch ( const com::sun::star::uno::Exception& e )
    1565             :         {
    1566           0 :             FatalError( MakeStartupErrorMessage(e.Message) );
    1567             :         }
    1568             : 
    1569             :         // Release solar mutex just before we wait for our client to connect
    1570             :         {
    1571          64 :             SolarMutexReleaser aReleaser;
    1572             : 
    1573             :             // Post user event to startup first application component window
    1574             :             // We have to send this OpenClients message short before execute() to
    1575             :             // minimize the risk that this message overtakes type detection construction!!
    1576          64 :             Application::PostUserEvent( LINK( this, Desktop, OpenClients_Impl ) );
    1577             : 
    1578             :             // Post event to enable acceptors
    1579          64 :             Application::PostUserEvent( LINK( this, Desktop, EnableAcceptors_Impl) );
    1580             : 
    1581             :             // The configuration error handler currently is only for startup
    1582          64 :             aConfigErrHandler.deactivate();
    1583             : 
    1584             :             // Acquire solar mutex just before we enter our message loop
    1585             :         }
    1586             : 
    1587             :         // call Application::Execute to process messages in vcl message loop
    1588             :         try
    1589             :         {
    1590             : #if HAVE_FEATURE_JAVA
    1591             :             // The JavaContext contains an interaction handler which is used when
    1592             :             // the creation of a Java Virtual Machine fails
    1593             :             com::sun::star::uno::ContextLayer layer2(
    1594          64 :                 new svt::JavaContext( com::sun::star::uno::getCurrentContext() ) );
    1595             : #endif
    1596             :             // check whether the shutdown is caused by restart just before entering the Execute
    1597         128 :             pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested ||
    1598         192 :                 xRestartManager->isRestartRequested(true);
    1599             : 
    1600          64 :             if ( !pExecGlobals->bRestartRequested )
    1601             :             {
    1602             :                 // if this run of the office is triggered by restart, some additional actions should be done
    1603          64 :                 DoRestartActionsIfNecessary( !rCmdLineArgs.IsInvisible() && !rCmdLineArgs.IsNoQuickstart() );
    1604             : 
    1605          64 :                 Execute();
    1606          64 :             }
    1607             :         }
    1608           0 :         catch(const com::sun::star::document::CorruptedFilterConfigurationException& exFilterCfg)
    1609             :         {
    1610           0 :             OfficeIPCThread::SetDowning();
    1611           0 :             FatalError( MakeStartupErrorMessage(exFilterCfg.Message) );
    1612             :         }
    1613           0 :         catch(const com::sun::star::configuration::CorruptedConfigurationException& exAnyCfg)
    1614             :         {
    1615           0 :             OfficeIPCThread::SetDowning();
    1616           0 :             FatalError( MakeStartupErrorMessage(exAnyCfg.Message) );
    1617             :         }
    1618           0 :         catch( const ::com::sun::star::uno::Exception& exUNO)
    1619             :         {
    1620           0 :             OfficeIPCThread::SetDowning();
    1621           0 :             FatalError( exUNO.Message);
    1622             :         }
    1623           0 :         catch( const std::exception& exSTD)
    1624             :         {
    1625           0 :             OfficeIPCThread::SetDowning();
    1626           0 :             FatalError( OUString::createFromAscii( exSTD.what()));
    1627             :         }
    1628           0 :         catch( ...)
    1629             :         {
    1630           0 :             OfficeIPCThread::SetDowning();
    1631           0 :             FatalError( OUString( "Caught Unknown Exception: Aborting!"));
    1632             :         }
    1633             :     }
    1634             :     else
    1635             :     {
    1636          52 :         if (xDesktop.is())
    1637          52 :             xDesktop->terminate();
    1638             :     }
    1639             :     // CAUTION: you do not necessarily get here e.g. on the Mac.
    1640             :     // please put all deinitialization code into doShutdown
    1641         232 :     return doShutdown();
    1642             : }
    1643             : 
    1644         116 : int Desktop::doShutdown()
    1645             : {
    1646         116 :     if( ! pExecGlobals )
    1647           0 :         return EXIT_SUCCESS;
    1648             : 
    1649         244 :     pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested ||
    1650         308 :         OfficeRestartManager::get(comphelper::getProcessComponentContext())->
    1651         348 :         isRestartRequested(true);
    1652         116 :     if ( pExecGlobals->bRestartRequested )
    1653          52 :         SetRestartState();
    1654             : 
    1655         116 :     if (pExecGlobals->xGlobalBroadcaster.is())
    1656             :     {
    1657         116 :         css::document::DocumentEvent aEvent;
    1658         116 :         aEvent.EventName = "OnCloseApp";
    1659         116 :         pExecGlobals->xGlobalBroadcaster->documentEventOccured(aEvent);
    1660             :     }
    1661             : 
    1662         116 :     delete pResMgr, pResMgr = NULL;
    1663             :     // Restore old value
    1664         116 :     const CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
    1665         116 :     if ( rCmdLineArgs.IsHeadless() )
    1666         116 :         SvtMiscOptions().SetUseSystemFileDialog( pExecGlobals->bUseSystemFileDialog );
    1667             : 
    1668         116 :     OUString pidfileName = rCmdLineArgs.GetPidfileName();
    1669         116 :     if ( !pidfileName.isEmpty() )
    1670             :     {
    1671           0 :         OUString pidfileURL;
    1672             : 
    1673           0 :         if ( osl_getFileURLFromSystemPath(pidfileName.pData, &pidfileURL.pData) == osl_File_E_None )
    1674             :         {
    1675           0 :             if ( osl::File::remove( pidfileURL ) != osl::FileBase::E_None )
    1676             :             {
    1677             :                 SAL_WARN("desktop.app", "shutdown: cannot remove pidfile " << pidfileURL);
    1678             :             }
    1679             :         }
    1680             :         else
    1681             :         {
    1682             :             SAL_WARN("desktop.app", "shutdown: cannot get pidfile URL from path" << pidfileName);
    1683           0 :         }
    1684             :     }
    1685             : 
    1686             :     // remove temp directory
    1687         116 :     RemoveTemporaryDirectory();
    1688         116 :     FlushConfiguration();
    1689             :     // The acceptors in the AcceptorMap must be released (in DeregisterServices)
    1690             :     // with the solar mutex unlocked, to avoid deadlock:
    1691             :     {
    1692         116 :         SolarMutexReleaser aReleaser;
    1693         116 :         DeregisterServices();
    1694             : #if HAVE_FEATURE_SCRIPTING
    1695         116 :         StarBASIC::DetachAllDocBasicItems();
    1696             : #endif
    1697             :     }
    1698             :     // be sure that path/language options gets destroyed before
    1699             :     // UCB is deinitialized
    1700         116 :     pExecGlobals->pLanguageOptions.reset( 0 );
    1701         116 :     pExecGlobals->pPathOptions.reset( 0 );
    1702             : 
    1703         116 :     bool bRR = pExecGlobals->bRestartRequested;
    1704         116 :     delete pExecGlobals, pExecGlobals = NULL;
    1705             : 
    1706         116 :     if ( bRR )
    1707             :     {
    1708          52 :         restartOnMac(true);
    1709          52 :         if ( m_rSplashScreen.is() )
    1710           0 :             m_rSplashScreen->reset();
    1711             : 
    1712          52 :         return EXITHELPER_NORMAL_RESTART;
    1713             :     }
    1714          64 :     return EXIT_SUCCESS;
    1715             : }
    1716             : 
    1717          14 : IMPL_STATIC_LINK( Desktop, ImplInitFilterHdl, ConvertData*, pData )
    1718             : {
    1719           7 :     return GraphicFilter::GetGraphicFilter().GetFilterCallback().Call( pData );
    1720             : }
    1721             : 
    1722         116 : bool Desktop::InitializeConfiguration()
    1723             : {
    1724             :     try
    1725             :     {
    1726             :         css::configuration::theDefaultProvider::get(
    1727         116 :             comphelper::getProcessComponentContext() );
    1728         116 :         return true;
    1729             :     }
    1730           0 :     catch( ::com::sun::star::lang::ServiceNotRegisteredException & e )
    1731             :     {
    1732             :         HandleBootstrapErrors(
    1733           0 :             Desktop::BE_UNO_SERVICE_CONFIG_MISSING, e.Message );
    1734             :     }
    1735           0 :     catch( const ::com::sun::star::configuration::MissingBootstrapFileException& e )
    1736             :     {
    1737             :         OUString aMsg( CreateErrorMsgString( utl::Bootstrap::MISSING_BOOTSTRAP_FILE,
    1738           0 :                                                 e.BootstrapFileURL ));
    1739           0 :         HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_USER_INSTALL, aMsg );
    1740             :     }
    1741           0 :     catch( const ::com::sun::star::configuration::InvalidBootstrapFileException& e )
    1742             :     {
    1743             :         OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY,
    1744           0 :                                                 e.BootstrapFileURL ));
    1745           0 :         HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
    1746             :     }
    1747           0 :     catch( const ::com::sun::star::configuration::InstallationIncompleteException& )
    1748             :     {
    1749           0 :         OUString aVersionFileURL;
    1750           0 :         OUString aMsg;
    1751           0 :         utl::Bootstrap::PathStatus aPathStatus = utl::Bootstrap::locateVersionFile( aVersionFileURL );
    1752           0 :         if ( aPathStatus == utl::Bootstrap::PATH_EXISTS )
    1753           0 :             aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE_ENTRY, aVersionFileURL );
    1754             :         else
    1755           0 :             aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE, aVersionFileURL );
    1756             : 
    1757           0 :         HandleBootstrapPathErrors( ::utl::Bootstrap::MISSING_USER_INSTALL, aMsg );
    1758             :     }
    1759           0 :     catch ( const com::sun::star::configuration::backend::BackendAccessException& exception)
    1760             :     {
    1761             :         // [cm122549] It is assumed in this case that the message
    1762             :         // coming from InitConfiguration (in fact CreateApplicationConf...)
    1763             :         // is suitable for display directly.
    1764           0 :         FatalError( MakeStartupErrorMessage( exception.Message ) );
    1765             :     }
    1766           0 :     catch ( const com::sun::star::configuration::backend::BackendSetupException& exception)
    1767             :     {
    1768             :         // [cm122549] It is assumed in this case that the message
    1769             :         // coming from InitConfiguration (in fact CreateApplicationConf...)
    1770             :         // is suitable for display directly.
    1771           0 :         FatalError( MakeStartupErrorMessage( exception.Message ) );
    1772             :     }
    1773           0 :     catch ( const ::com::sun::star::configuration::CannotLoadConfigurationException& )
    1774             :     {
    1775             :         OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
    1776           0 :                                                 OUString() ));
    1777           0 :         HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
    1778             :     }
    1779           0 :     catch( const ::com::sun::star::uno::Exception& )
    1780             :     {
    1781             :         OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
    1782           0 :                                                 OUString() ));
    1783           0 :         HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
    1784             :     }
    1785           0 :     return false;
    1786             : }
    1787             : 
    1788         232 : void Desktop::FlushConfiguration()
    1789             : {
    1790             :     css::uno::Reference< css::util::XFlushable >(
    1791             :         css::configuration::theDefaultProvider::get(
    1792             :             comphelper::getProcessComponentContext()),
    1793         232 :         css::uno::UNO_QUERY_THROW)->flush();
    1794         232 : }
    1795             : 
    1796           0 : bool Desktop::InitializeQuickstartMode( const Reference< XComponentContext >& rxContext )
    1797             : {
    1798             :     try
    1799             :     {
    1800             :         // the shutdown icon sits in the systray and allows the user to keep
    1801             :         // the office instance running for quicker restart
    1802             :         // this will only be activated if --quickstart was specified on cmdline
    1803             : 
    1804           0 :         bool bQuickstart = shouldLaunchQuickstart();
    1805             : 
    1806             :         // Try to instantiate quickstart service. This service is not mandatory, so
    1807             :         // do nothing if service is not available
    1808             : 
    1809             :         // #i105753# the following if was invented for performance
    1810             :         // unfortunately this broke the Mac behavior which is to always run
    1811             :         // in quickstart mode since Mac applications do not usually quit
    1812             :         // when the last document closes.
    1813             :         // Note that this claim that on OS X we "always run in quickstart mode"
    1814             :         // has nothing to do with (quick) *starting* (i.e. starting automatically
    1815             :         // when the user logs in), though, but with not quitting when no documents
    1816             :         // are open.
    1817             :         #ifndef MACOSX
    1818           0 :         if ( bQuickstart )
    1819             :         #endif
    1820             :         {
    1821           0 :             css::office::Quickstart::createStart(rxContext, bQuickstart);
    1822             :         }
    1823           0 :         return true;
    1824             :     }
    1825           0 :     catch( const ::com::sun::star::uno::Exception& )
    1826             :     {
    1827           0 :         return false;
    1828             :     }
    1829             : }
    1830             : 
    1831         232 : void Desktop::OverrideSystemSettings( AllSettings& rSettings )
    1832             : {
    1833         232 :     if ( !SvtTabAppearanceCfg::IsInitialized () )
    1834         348 :         return;
    1835             : 
    1836         116 :     StyleSettings hStyleSettings   = rSettings.GetStyleSettings();
    1837         232 :     MouseSettings hMouseSettings = rSettings.GetMouseSettings();
    1838             : 
    1839         116 :     DragFullOptions nDragFullOptions = hStyleSettings.GetDragFullOptions();
    1840             : 
    1841         232 :     SvtTabAppearanceCfg aAppearanceCfg;
    1842         116 :     sal_uInt16 nDragMode = aAppearanceCfg.GetDragMode();
    1843         116 :     switch ( nDragMode )
    1844             :     {
    1845             :     case DragFullWindow:
    1846           0 :         nDragFullOptions |= DragFullOptions::All;
    1847           0 :         break;
    1848             :     case DragFrame:
    1849           0 :         nDragFullOptions &= ~DragFullOptions::All;
    1850           0 :         break;
    1851             :     case DragSystemDep:
    1852             :     default:
    1853         116 :         break;
    1854             :     }
    1855             : 
    1856         116 :     MouseFollowFlags nFollow = hMouseSettings.GetFollow();
    1857         116 :     hMouseSettings.SetFollow( aAppearanceCfg.IsMenuMouseFollow() ? (nFollow|MouseFollowFlags::Menu) : (nFollow&~MouseFollowFlags::Menu));
    1858         116 :     rSettings.SetMouseSettings(hMouseSettings);
    1859             : 
    1860         116 :     SvtMenuOptions aMenuOpt;
    1861         116 :     hStyleSettings.SetUseImagesInMenus(aMenuOpt.GetMenuIconsState());
    1862         116 :     hStyleSettings.SetDragFullOptions( nDragFullOptions );
    1863         232 :     rSettings.SetStyleSettings ( hStyleSettings );
    1864             : }
    1865             : 
    1866             : 
    1867          76 : IMPL_STATIC_LINK_TYPED(Desktop, AsyncInitFirstRun, Timer *, /*unused*/, void)
    1868             : {
    1869          38 :     DoFirstRunInitializations();
    1870          38 : }
    1871             : 
    1872             : 
    1873             : 
    1874           0 : class ExitTimer : public Timer
    1875             : {
    1876             :   public:
    1877           0 :     ExitTimer()
    1878           0 :     {
    1879           0 :         SetTimeout(500);
    1880           0 :         Start();
    1881           0 :     }
    1882           0 :     virtual void Invoke() SAL_OVERRIDE
    1883             :     {
    1884           0 :         exit(42);
    1885             :     }
    1886             : };
    1887             : 
    1888         128 : IMPL_LINK_NOARG(Desktop, OpenClients_Impl)
    1889             : {
    1890             :     try {
    1891          64 :         OpenClients();
    1892             : 
    1893          64 :         OfficeIPCThread::SetReady();
    1894             : 
    1895          64 :         CloseSplashScreen();
    1896          64 :         CheckFirstRun( );
    1897             : #ifdef WNT
    1898             :         // Registers a COM class factory of the service manager with the windows operating system.
    1899             :         Reference< XMultiServiceFactory > xSMgr=  comphelper::getProcessServiceFactory();
    1900             :         xSMgr->createInstance("com.sun.star.bridge.OleApplicationRegistration");
    1901             :         xSMgr->createInstance("com.sun.star.comp.ole.EmbedServer");
    1902             : #endif
    1903          64 :         const char *pExitPostStartup = getenv ("OOO_EXIT_POST_STARTUP");
    1904          64 :         if (pExitPostStartup && *pExitPostStartup)
    1905           0 :             new ExitTimer();
    1906           0 :     } catch (const ::com::sun::star::uno::Exception &e) {
    1907           0 :         OUString a( "UNO exception during client open:\n"  );
    1908           0 :         Application::Abort( a + e.Message );
    1909             :     }
    1910          64 :     return 0;
    1911             : }
    1912             : 
    1913             : // enable acceptos
    1914         128 : IMPL_STATIC_LINK_NOARG(Desktop, EnableAcceptors_Impl)
    1915             : {
    1916          64 :     enableAcceptors();
    1917          64 :     return 0;
    1918             : }
    1919             : 
    1920             : 
    1921           0 : void Desktop::PreloadModuleData( const CommandLineArgs& rArgs )
    1922             : {
    1923           0 :     Sequence < com::sun::star::beans::PropertyValue > args(1);
    1924           0 :     args[0].Name = "Hidden";
    1925           0 :     args[0].Value <<= sal_True;
    1926           0 :     Reference < XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
    1927             : 
    1928           0 :     if ( rArgs.IsWriter() )
    1929             :     {
    1930             :         try
    1931             :         {
    1932           0 :             Reference < ::com::sun::star::util::XCloseable > xDoc( xDesktop->loadComponentFromURL( OUString("private:factory/swriter"),
    1933           0 :                 OUString("_blank"), 0, args ), UNO_QUERY_THROW );
    1934           0 :             xDoc->close( sal_False );
    1935             :         }
    1936           0 :         catch ( const com::sun::star::uno::Exception& )
    1937             :         {
    1938             :         }
    1939             :     }
    1940           0 :     if ( rArgs.IsCalc() )
    1941             :     {
    1942             :         try
    1943             :         {
    1944           0 :             Reference < ::com::sun::star::util::XCloseable > xDoc( xDesktop->loadComponentFromURL( OUString("private:factory/scalc"),
    1945           0 :                 OUString("_blank"), 0, args ), UNO_QUERY_THROW );
    1946           0 :             xDoc->close( sal_False );
    1947             :         }
    1948           0 :         catch ( const com::sun::star::uno::Exception& )
    1949             :         {
    1950             :         }
    1951             :     }
    1952           0 :     if ( rArgs.IsDraw() )
    1953             :     {
    1954             :         try
    1955             :         {
    1956           0 :             Reference < ::com::sun::star::util::XCloseable > xDoc( xDesktop->loadComponentFromURL( OUString("private:factory/sdraw"),
    1957           0 :                 OUString("_blank"), 0, args ), UNO_QUERY_THROW );
    1958           0 :             xDoc->close( sal_False );
    1959             :         }
    1960           0 :         catch ( const com::sun::star::uno::Exception& )
    1961             :         {
    1962             :         }
    1963             :     }
    1964           0 :     if ( rArgs.IsImpress() )
    1965             :     {
    1966             :         try
    1967             :         {
    1968           0 :             Reference < ::com::sun::star::util::XCloseable > xDoc( xDesktop->loadComponentFromURL( OUString("private:factory/simpress"),
    1969           0 :                 OUString("_blank"), 0, args ), UNO_QUERY_THROW );
    1970           0 :             xDoc->close( sal_False );
    1971             :         }
    1972           0 :         catch ( const com::sun::star::uno::Exception& )
    1973             :         {
    1974             :         }
    1975           0 :     }
    1976           0 : }
    1977             : 
    1978           0 : void Desktop::PreloadConfigurationData()
    1979             : {
    1980           0 :     Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
    1981           0 :     Reference< XNameAccess > xNameAccess = css::frame::theUICommandDescription::get(xContext);
    1982             : 
    1983           0 :     OUString aWriterDoc( "com.sun.star.text.TextDocument" );
    1984           0 :     OUString aCalcDoc( "com.sun.star.sheet.SpreadsheetDocument" );
    1985           0 :     OUString aDrawDoc( "com.sun.star.drawing.DrawingDocument" );
    1986           0 :     OUString aImpressDoc( "com.sun.star.presentation.PresentationDocument" );
    1987             : 
    1988             :     // preload commands configuration
    1989           0 :     Any a;
    1990           0 :     Reference< XNameAccess > xCmdAccess;
    1991             : 
    1992             :     try
    1993             :     {
    1994           0 :         a = xNameAccess->getByName( aWriterDoc );
    1995           0 :         a >>= xCmdAccess;
    1996           0 :         if ( xCmdAccess.is() )
    1997             :         {
    1998           0 :             xCmdAccess->getByName(".uno:BasicShapes");
    1999           0 :             xCmdAccess->getByName(".uno:EditGlossary");
    2000             :         }
    2001             :     }
    2002           0 :     catch ( const ::com::sun::star::uno::Exception& )
    2003             :     {
    2004             :     }
    2005             : 
    2006             :     try
    2007             :     {
    2008           0 :         a = xNameAccess->getByName( aCalcDoc );
    2009           0 :         a >>= xCmdAccess;
    2010           0 :         if ( xCmdAccess.is() )
    2011           0 :             xCmdAccess->getByName(".uno:InsertObjectStarMath");
    2012             :     }
    2013           0 :     catch ( const ::com::sun::star::uno::Exception& )
    2014             :     {
    2015             :     }
    2016             : 
    2017             :     try
    2018             :     {
    2019             :         // draw and impress share the same configuration file (DrawImpressCommands.xcu)
    2020           0 :         a = xNameAccess->getByName( aDrawDoc );
    2021           0 :         a >>= xCmdAccess;
    2022           0 :         if ( xCmdAccess.is() )
    2023           0 :             xCmdAccess->getByName(".uno:Polygon");
    2024             :     }
    2025           0 :     catch ( const ::com::sun::star::uno::Exception& )
    2026             :     {
    2027             :     }
    2028             : 
    2029             :     // preload window state configuration
    2030           0 :     xNameAccess = theWindowStateConfiguration::get( xContext );
    2031           0 :     Reference< XNameAccess > xWindowAccess;
    2032             :     try
    2033             :     {
    2034           0 :         a = xNameAccess->getByName( aWriterDoc );
    2035           0 :         a >>= xWindowAccess;
    2036           0 :         if ( xWindowAccess.is() )
    2037           0 :             xWindowAccess->getByName("private:resource/toolbar/standardbar");
    2038             :     }
    2039           0 :     catch ( const ::com::sun::star::uno::Exception& )
    2040             :     {
    2041             :     }
    2042             :     try
    2043             :     {
    2044           0 :         a = xNameAccess->getByName( aCalcDoc );
    2045           0 :         a >>= xWindowAccess;
    2046           0 :         if ( xWindowAccess.is() )
    2047           0 :             xWindowAccess->getByName("private:resource/toolbar/standardbar");
    2048             :     }
    2049           0 :     catch ( const ::com::sun::star::uno::Exception& )
    2050             :     {
    2051             :     }
    2052             :     try
    2053             :     {
    2054           0 :         a = xNameAccess->getByName( aDrawDoc );
    2055           0 :         a >>= xWindowAccess;
    2056           0 :         if ( xWindowAccess.is() )
    2057           0 :             xWindowAccess->getByName("private:resource/toolbar/standardbar");
    2058             :     }
    2059           0 :     catch ( const ::com::sun::star::uno::Exception& )
    2060             :     {
    2061             :     }
    2062             :     try
    2063             :     {
    2064           0 :         a = xNameAccess->getByName( aImpressDoc );
    2065           0 :         a >>= xWindowAccess;
    2066           0 :         if ( xWindowAccess.is() )
    2067           0 :             xWindowAccess->getByName("private:resource/toolbar/standardbar");
    2068             :     }
    2069           0 :     catch ( const ::com::sun::star::uno::Exception& )
    2070             :     {
    2071             :     }
    2072             : 
    2073             :     // preload user interface element factories
    2074           0 :     Reference< XUIElementFactoryManager > xUIElementFactory = theUIElementFactoryManager::get( xContext );
    2075             :     try
    2076             :     {
    2077           0 :         xUIElementFactory->getRegisteredFactories();
    2078             :     }
    2079           0 :     catch ( const ::com::sun::star::uno::Exception& )
    2080             :     {
    2081             :     }
    2082             : 
    2083             :     // preload popup menu controller factories. As all controllers are in the same
    2084             :     // configuration file they also get preloaded!
    2085             : 
    2086             :     Reference< css::frame::XUIControllerRegistration > xPopupMenuControllerFactory =
    2087           0 :     css::frame::thePopupMenuControllerFactory::get( xContext );
    2088             :     try
    2089             :     {
    2090           0 :         (void)xPopupMenuControllerFactory->hasController(
    2091             :                     OUString( ".uno:CharFontName" ),
    2092           0 :                     OUString() );
    2093             :     }
    2094           0 :     catch ( const ::com::sun::star::uno::Exception& )
    2095             :     {
    2096             :     }
    2097             : 
    2098             :     // preload filter configuration
    2099           0 :     xNameAccess = Reference< XNameAccess >(
    2100           0 :                     xContext->getServiceManager()->createInstanceWithContext("com.sun.star.document.FilterFactory", xContext),
    2101           0 :                     UNO_QUERY );
    2102           0 :     if ( xNameAccess.is() )
    2103             :     {
    2104             :         try
    2105             :         {
    2106           0 :              xNameAccess->getElementNames();
    2107             :         }
    2108           0 :         catch ( const ::com::sun::star::uno::Exception& )
    2109             :         {
    2110             :         }
    2111             :     }
    2112             : 
    2113             :     // preload type detection configuration
    2114           0 :     xNameAccess = Reference< XNameAccess >(
    2115           0 :                     xContext->getServiceManager()->createInstanceWithContext("com.sun.star.document.TypeDetection", xContext),
    2116           0 :                     UNO_QUERY );
    2117           0 :     if ( xNameAccess.is() )
    2118             :     {
    2119             :         try
    2120             :         {
    2121           0 :              xNameAccess->getElementNames();
    2122             :         }
    2123           0 :         catch ( const ::com::sun::star::uno::Exception& )
    2124             :         {
    2125             :         }
    2126           0 :     }
    2127           0 : }
    2128             : 
    2129          64 : void Desktop::OpenClients()
    2130             : {
    2131             : 
    2132             :     // check if a document has been recovered - if there is one of if a document was loaded by cmdline, no default document
    2133             :     // should be created
    2134          64 :     Reference < XComponent > xFirst;
    2135          64 :     bool bRecovery = false;
    2136             : 
    2137          64 :     const CommandLineArgs& rArgs = GetCommandLineArgs();
    2138             : 
    2139          64 :     if (!rArgs.IsQuickstart())
    2140             :     {
    2141          64 :         bool bShowHelp = false;
    2142          64 :         OUStringBuffer aHelpURLBuffer;
    2143          64 :         if (rArgs.IsHelpWriter()) {
    2144           0 :             bShowHelp = true;
    2145           0 :             aHelpURLBuffer.appendAscii("vnd.sun.star.help://swriter/start");
    2146          64 :         } else if (rArgs.IsHelpCalc()) {
    2147           0 :             bShowHelp = true;
    2148           0 :             aHelpURLBuffer.appendAscii("vnd.sun.star.help://scalc/start");
    2149          64 :         } else if (rArgs.IsHelpDraw()) {
    2150           0 :             bShowHelp = true;
    2151           0 :             aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdraw/start");
    2152          64 :         } else if (rArgs.IsHelpImpress()) {
    2153           0 :             bShowHelp = true;
    2154           0 :             aHelpURLBuffer.appendAscii("vnd.sun.star.help://simpress/start");
    2155          64 :         } else if (rArgs.IsHelpBase()) {
    2156           0 :             bShowHelp = true;
    2157           0 :             aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdatabase/start");
    2158          64 :         } else if (rArgs.IsHelpBasic()) {
    2159           0 :             bShowHelp = true;
    2160           0 :             aHelpURLBuffer.appendAscii("vnd.sun.star.help://sbasic/start");
    2161          64 :         } else if (rArgs.IsHelpMath()) {
    2162           0 :             bShowHelp = true;
    2163           0 :             aHelpURLBuffer.appendAscii("vnd.sun.star.help://smath/start");
    2164             :         }
    2165          64 :         if (bShowHelp) {
    2166           0 :             aHelpURLBuffer.appendAscii("?Language=");
    2167           0 :             aHelpURLBuffer.append(utl::ConfigManager::getLocale());
    2168             : #if defined UNX
    2169           0 :             aHelpURLBuffer.appendAscii("&System=UNX");
    2170             : #elif defined WNT
    2171             :             aHelpURLBuffer.appendAscii("&System=WIN");
    2172             : #endif
    2173           0 :             Application::GetHelp()->Start(
    2174           0 :                 aHelpURLBuffer.makeStringAndClear(), NULL);
    2175           0 :             return;
    2176          64 :         }
    2177             :     }
    2178             :     else
    2179             :     {
    2180           0 :         OUString            aIniName;
    2181             : 
    2182           0 :         osl_getExecutableFile( &aIniName.pData );
    2183           0 :         sal_uInt32     lastIndex = aIniName.lastIndexOf('/');
    2184           0 :         if ( lastIndex > 0 )
    2185             :         {
    2186           0 :             aIniName    = aIniName.copy( 0, lastIndex+1 );
    2187           0 :             aIniName    += "perftune";
    2188             : #if defined(WNT)
    2189             :             aIniName    += ".ini";
    2190             : #else
    2191           0 :             aIniName    += "rc";
    2192             : #endif
    2193             :         }
    2194             : 
    2195           0 :         rtl::Bootstrap aPerfTuneIniFile( aIniName );
    2196             : 
    2197           0 :         OUString aDefault( "0" );
    2198           0 :         OUString aPreloadData;
    2199             : 
    2200           0 :         aPerfTuneIniFile.getFrom( OUString( "QuickstartPreloadConfiguration" ), aPreloadData, aDefault );
    2201           0 :         if ( aPreloadData == "1" )
    2202             :         {
    2203           0 :             if ( rArgs.IsWriter()  ||
    2204           0 :                  rArgs.IsCalc()    ||
    2205           0 :                  rArgs.IsDraw()    ||
    2206           0 :                  rArgs.IsImpress()    )
    2207             :             {
    2208           0 :                 PreloadModuleData( rArgs );
    2209             :             }
    2210             : 
    2211           0 :             PreloadConfigurationData();
    2212           0 :         }
    2213             :     }
    2214             : 
    2215             :     // Disable AutoSave feature in case "--norestore" or a similar command line switch is set on the command line.
    2216             :     // The reason behind: AutoSave/EmergencySave/AutoRecovery share the same data.
    2217             :     // But the require that all documents, which are saved as backup should exists inside
    2218             :     // memory. May be this mechanism will be inconsistent if the configuration exists ...
    2219             :     // but no document inside memory corrspond to this data.
    2220             :     // Furter it's not acceptable to recover such documents without any UI. It can
    2221             :     // need some time, where the user wont see any results and wait for finishing the office startup ...
    2222          64 :     bool bAllowRecoveryAndSessionManagement = ( !rArgs.IsNoRestore() ) && ( !rArgs.IsHeadless()  );
    2223             : 
    2224          64 :     if ( ! bAllowRecoveryAndSessionManagement )
    2225             :     {
    2226             :         try
    2227             :         {
    2228          64 :             Reference< XDispatch > xRecovery = css::frame::theAutoRecovery::get( ::comphelper::getProcessComponentContext() );
    2229         128 :             Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create( ::comphelper::getProcessComponentContext() );
    2230             : 
    2231         128 :             css::util::URL aCmd;
    2232          64 :             aCmd.Complete = "vnd.sun.star.autorecovery:/disableRecovery";
    2233          64 :             xParser->parseStrict(aCmd);
    2234             : 
    2235         128 :             xRecovery->dispatch(aCmd, css::uno::Sequence< css::beans::PropertyValue >());
    2236             :         }
    2237           0 :         catch(const css::uno::Exception& e)
    2238             :         {
    2239             :             SAL_WARN( "desktop.app", "Could not disable AutoRecovery." << e.Message);
    2240             :         }
    2241             :     }
    2242             :     else
    2243             :     {
    2244           0 :         bool bCrashed            = false;
    2245           0 :         bool bExistsRecoveryData = false;
    2246           0 :         bool bExistsSessionData  = false;
    2247           0 :         bool const bDisableRecovery = getenv("OOO_DISABLE_RECOVERY") != nullptr;
    2248             : 
    2249           0 :         impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
    2250             : 
    2251           0 :         if ( !bDisableRecovery &&
    2252             :             (
    2253           0 :                 ( bExistsRecoveryData ) || // => crash with files    => recovery
    2254             :                 ( bCrashed            )    // => crash without files => error report
    2255             :             )
    2256             :            )
    2257             :         {
    2258             :             try
    2259             :             {
    2260             :                 bRecovery = impl_callRecoveryUI(
    2261             :                     false          , // false => force recovery instead of emergency save
    2262           0 :                     bExistsRecoveryData);
    2263             :             }
    2264           0 :             catch(const css::uno::Exception& e)
    2265             :             {
    2266             :                 SAL_WARN( "desktop.app", "Error during recovery" << e.Message);
    2267           0 :             }
    2268             :         }
    2269           0 :         else if (bExistsRecoveryData && bDisableRecovery)
    2270             :             // prevent new Writer doc
    2271           0 :             bRecovery = true;
    2272             : 
    2273           0 :         Reference< XSessionManagerListener2 > xSessionListener;
    2274             :         try
    2275             :         {
    2276             :             // specifies whether the UI-interaction on Session shutdown is allowed
    2277           0 :             xSessionListener = SessionListener::createWithOnQuitFlag(
    2278           0 :                     ::comphelper::getProcessComponentContext(), isUIOnSessionShutdownAllowed());
    2279             :         }
    2280           0 :         catch(const com::sun::star::uno::Exception& e)
    2281             :         {
    2282             :             SAL_WARN( "desktop.app", "Registration of session listener failed" << e.Message);
    2283             :         }
    2284             : 
    2285           0 :         if ( !bExistsRecoveryData && xSessionListener.is() )
    2286             :         {
    2287             :             // session management
    2288             :             try
    2289             :             {
    2290           0 :                 xSessionListener->doRestore();
    2291             :             }
    2292           0 :             catch(const com::sun::star::uno::Exception& e)
    2293             :             {
    2294             :                 SAL_WARN( "desktop.app", "Error in session management" << e.Message);
    2295             :             }
    2296           0 :         }
    2297             :     }
    2298             : 
    2299          64 :     OfficeIPCThread::EnableRequests();
    2300             : 
    2301          64 :     ProcessDocumentsRequest aRequest(rArgs.getCwdUrl());
    2302          64 :     aRequest.pcProcessed = NULL;
    2303             : 
    2304          64 :     aRequest.aOpenList = rArgs.GetOpenList();
    2305          64 :     aRequest.aViewList = rArgs.GetViewList();
    2306          64 :     aRequest.aStartList = rArgs.GetStartList();
    2307          64 :     aRequest.aPrintList = rArgs.GetPrintList();
    2308          64 :     aRequest.aPrintToList = rArgs.GetPrintToList();
    2309          64 :     aRequest.aPrinterName = rArgs.GetPrinterName();
    2310          64 :     aRequest.aForceOpenList = rArgs.GetForceOpenList();
    2311          64 :     aRequest.aForceNewList = rArgs.GetForceNewList();
    2312          64 :     aRequest.aConversionList = rArgs.GetConversionList();
    2313          64 :     aRequest.aConversionParams = rArgs.GetConversionParams();
    2314          64 :     aRequest.aConversionOut = rArgs.GetConversionOut();
    2315          64 :     aRequest.aInFilter = rArgs.GetInFilter();
    2316          64 :     aRequest.bTextCat = rArgs.IsTextCat();
    2317             : 
    2318         191 :     if ( !aRequest.aOpenList.empty() ||
    2319         126 :          !aRequest.aViewList.empty() ||
    2320         126 :          !aRequest.aStartList.empty() ||
    2321         126 :          !aRequest.aPrintList.empty() ||
    2322         126 :          !aRequest.aForceOpenList.empty() ||
    2323         126 :          !aRequest.aForceNewList.empty() ||
    2324         190 :          ( !aRequest.aPrintToList.empty() && !aRequest.aPrinterName.isEmpty() ) ||
    2325          63 :          !aRequest.aConversionList.empty() )
    2326             :     {
    2327           1 :         if ( rArgs.HasModuleParam() )
    2328             :         {
    2329           0 :             SvtModuleOptions    aOpt;
    2330             : 
    2331             :             // Support command line parameters to start a module (as preselection)
    2332           0 :             if ( rArgs.IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
    2333           0 :                 aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::EFactory::WRITER );
    2334           0 :             else if ( rArgs.IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
    2335           0 :                 aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::EFactory::CALC );
    2336           0 :             else if ( rArgs.IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
    2337           0 :                 aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::EFactory::IMPRESS );
    2338           0 :             else if ( rArgs.IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
    2339           0 :                 aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::EFactory::DRAW );
    2340             :         }
    2341             : 
    2342             :         // check for printing disabled
    2343           3 :         if( ( !(aRequest.aPrintList.empty() && aRequest.aPrintToList.empty()) )
    2344           1 :             && Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
    2345             :         {
    2346           0 :             aRequest.aPrintList.clear();
    2347           0 :             aRequest.aPrintToList.clear();
    2348           0 :             ResMgr* pDtResMgr = GetDesktopResManager();
    2349           0 :             if( pDtResMgr )
    2350             :             {
    2351           0 :                 ScopedVclPtrInstance< MessageDialog > aBox(nullptr, ResId(STR_ERR_PRINTDISABLED, *pDtResMgr));
    2352           0 :                 aBox->Execute();
    2353             :             }
    2354             :         }
    2355             : 
    2356             :         // Process request
    2357           1 :         if ( OfficeIPCThread::ExecuteCmdLineRequests( aRequest ) )
    2358             :         {
    2359             :             // Don't do anything if we have successfully called terminate at desktop:
    2360           0 :             return;
    2361             :         }
    2362             :     }
    2363             : 
    2364             :     // no default document if a document was loaded by recovery or by command line or if soffice is used as server
    2365          64 :     Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
    2366          64 :     Reference< XElementAccess > xList( xDesktop->getFrames(), UNO_QUERY_THROW );
    2367          64 :     if ( xList->hasElements() )
    2368           1 :         return;
    2369             : 
    2370          63 :     if ( rArgs.IsQuickstart() || rArgs.IsInvisible() || Application::AnyInput( VclInputFlags::APPEVENT ) )
    2371             :         // soffice was started as tray icon ...
    2372          63 :         return;
    2373             : 
    2374           0 :     if ( bRecovery )
    2375             :     {
    2376           0 :         ShowBackingComponent(0);
    2377             :     }
    2378             :     else
    2379             :     {
    2380           0 :         OpenDefault();
    2381           0 :     }
    2382             : }
    2383             : 
    2384           0 : void Desktop::OpenDefault()
    2385             : {
    2386           0 :     OUString        aName;
    2387           0 :     SvtModuleOptions    aOpt;
    2388             : 
    2389           0 :     const CommandLineArgs& rArgs = GetCommandLineArgs();
    2390           0 :     if ( rArgs.IsNoDefault() ) return;
    2391           0 :     if ( rArgs.HasModuleParam() )
    2392             :     {
    2393             :         // Support new command line parameters to start a module
    2394           0 :         if ( rArgs.IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
    2395           0 :             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::WRITER );
    2396           0 :         else if ( rArgs.IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
    2397           0 :             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::CALC );
    2398           0 :         else if ( rArgs.IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
    2399           0 :             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::IMPRESS );
    2400           0 :         else if ( rArgs.IsBase() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) )
    2401           0 :             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::DATABASE );
    2402           0 :         else if ( rArgs.IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
    2403           0 :             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::DRAW );
    2404           0 :         else if ( rArgs.IsMath() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH ) )
    2405           0 :             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::MATH );
    2406           0 :         else if ( rArgs.IsGlobal() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
    2407           0 :             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::WRITERGLOBAL );
    2408           0 :         else if ( rArgs.IsWeb() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
    2409           0 :             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::WRITERWEB );
    2410             :     }
    2411             : 
    2412           0 :     if ( aName.isEmpty() )
    2413             :     {
    2414             :         // Old way to create a default document
    2415           0 :         if ( aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
    2416           0 :             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::WRITER );
    2417           0 :         else if ( aOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
    2418           0 :             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::CALC );
    2419           0 :         else if ( aOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
    2420           0 :             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::IMPRESS );
    2421           0 :         else if ( aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) )
    2422           0 :             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::DATABASE );
    2423           0 :         else if ( aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
    2424           0 :             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory::DRAW );
    2425             :         else
    2426           0 :             return;
    2427             :     }
    2428             : 
    2429           0 :     ProcessDocumentsRequest aRequest(rArgs.getCwdUrl());
    2430           0 :     aRequest.pcProcessed = NULL;
    2431           0 :     aRequest.aOpenList.push_back(aName);
    2432           0 :     OfficeIPCThread::ExecuteCmdLineRequests( aRequest );
    2433             : }
    2434             : 
    2435             : 
    2436           1 : OUString GetURL_Impl(
    2437             :     const OUString& rName, boost::optional< OUString > const & cwdUrl )
    2438             : {
    2439             :     // if rName is a vnd.sun.star.script URL do not attempt to parse it
    2440             :     // as INetURLObj does not handle handle there URLs
    2441           1 :     if (rName.startsWith("vnd.sun.star.script"))
    2442             :     {
    2443           0 :         return rName;
    2444             :     }
    2445             : 
    2446             :     // dont touch file urls, those should already be in internal form
    2447             :     // they won't get better here (#112849#)
    2448           1 :     if (rName.startsWith("file:"))
    2449             :     {
    2450           0 :         return rName;
    2451             :     }
    2452             : 
    2453           1 :     if ( rName.startsWith("service:"))
    2454             :     {
    2455           0 :         return rName;
    2456             :     }
    2457             : 
    2458             :     // Add path separator to these directory and make given URL (rName) absolute by using of current working directory
    2459             :     // Attention: "setFinalSlash()" is necessary for calling "smartRel2Abs()"!!!
    2460             :     // Otherwhise last part will be ignored and wrong result will be returned!!!
    2461             :     // "smartRel2Abs()" interpret given URL as file not as path. So he truncate last element to get the base path ...
    2462             :     // But if we add a separator - he doesn't do it anymore.
    2463           1 :     INetURLObject aObj;
    2464           1 :     if (cwdUrl) {
    2465           1 :         aObj.SetURL(*cwdUrl);
    2466           1 :         aObj.setFinalSlash();
    2467             :     }
    2468             : 
    2469             :     // Use the provided parameters for smartRel2Abs to support the usage of '%' in system paths.
    2470             :     // Otherwise this char won't get encoded and we are not able to load such files later,
    2471             :     bool bWasAbsolute;
    2472             :     INetURLObject aURL     = aObj.smartRel2Abs( rName, bWasAbsolute, false, INetURLObject::WAS_ENCODED,
    2473           2 :                                                 RTL_TEXTENCODING_UTF8, true );
    2474           2 :     OUString      aFileURL = aURL.GetMainURL(INetURLObject::NO_DECODE);
    2475             : 
    2476           2 :     ::osl::FileStatus aStatus( osl_FileStatus_Mask_FileURL );
    2477           2 :     ::osl::DirectoryItem aItem;
    2478           2 :     if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
    2479           1 :         ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
    2480           1 :             aFileURL = aStatus.getFileURL();
    2481             : 
    2482           2 :     return aFileURL;
    2483             : }
    2484             : 
    2485           0 : void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
    2486             : {
    2487           0 :     switch ( rAppEvent.GetEvent() )
    2488             :     {
    2489             :     case ApplicationEvent::TYPE_ACCEPT:
    2490             :         // every time an accept parameter is used we create an acceptor
    2491             :         // with the corresponding accept-string
    2492           0 :         createAcceptor(rAppEvent.GetStringData());
    2493           0 :         break;
    2494             :     case ApplicationEvent::TYPE_APPEAR:
    2495           0 :         if ( !GetCommandLineArgs().IsInvisible() )
    2496             :         {
    2497           0 :             Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
    2498             : 
    2499             :             // find active task - the active task is always a visible task
    2500           0 :             Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext );
    2501           0 :             Reference< css::frame::XFrame > xTask = xDesktop->getActiveFrame();
    2502           0 :             if ( !xTask.is() )
    2503             :             {
    2504             :                 // get any task if there is no active one
    2505           0 :                 Reference< css::container::XIndexAccess > xList( xDesktop->getFrames(), ::com::sun::star::uno::UNO_QUERY );
    2506           0 :                 if ( xList->getCount() > 0 )
    2507           0 :                     xList->getByIndex(0) >>= xTask;
    2508             :             }
    2509             : 
    2510           0 :             if ( xTask.is() )
    2511             :             {
    2512           0 :                 Reference< com::sun::star::awt::XTopWindow > xTop( xTask->getContainerWindow(), UNO_QUERY );
    2513           0 :                 xTop->toFront();
    2514             :             }
    2515             :             else
    2516             :             {
    2517             :                 // no visible task that could be activated found
    2518           0 :                 Reference< ::com::sun::star::awt::XWindow > xContainerWindow;
    2519           0 :                 Reference< XFrame > xBackingFrame = xDesktop->findFrame(OUString( "_blank" ), 0);
    2520           0 :                 if (xBackingFrame.is())
    2521           0 :                     xContainerWindow = xBackingFrame->getContainerWindow();
    2522           0 :                 if (xContainerWindow.is())
    2523             :                 {
    2524           0 :                     Reference< XController > xStartModule = StartModule::createWithParentWindow(xContext, xContainerWindow);
    2525           0 :                     Reference< ::com::sun::star::awt::XWindow > xBackingWin(xStartModule, UNO_QUERY);
    2526             :                     // Attention: You MUST(!) call setComponent() before you call attachFrame().
    2527             :                     // Because the backing component set the property "IsBackingMode" of the frame
    2528             :                     // to true inside attachFrame(). But setComponent() reset this state every time ...
    2529           0 :                     xBackingFrame->setComponent(xBackingWin, xStartModule);
    2530           0 :                     xStartModule->attachFrame(xBackingFrame);
    2531           0 :                     xContainerWindow->setVisible(sal_True);
    2532             : 
    2533           0 :                     vcl::Window* pCompWindow = VCLUnoHelper::GetWindow(xBackingFrame->getComponentWindow());
    2534           0 :                     if (pCompWindow)
    2535           0 :                         pCompWindow->Update();
    2536           0 :                 }
    2537           0 :             }
    2538             :         }
    2539           0 :         break;
    2540             :     case ApplicationEvent::TYPE_HELP:
    2541           0 :         displayCmdlineHelp(rAppEvent.GetStringData());
    2542           0 :         break;
    2543             :     case ApplicationEvent::TYPE_VERSION:
    2544           0 :         displayVersion();
    2545           0 :         break;
    2546             :     case ApplicationEvent::TYPE_OPEN:
    2547             :         {
    2548           0 :             const CommandLineArgs& rCmdLine = GetCommandLineArgs();
    2549           0 :             if ( !rCmdLine.IsInvisible() && !rCmdLine.IsTerminateAfterInit() )
    2550             :             {
    2551             :                 ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
    2552           0 :                     rCmdLine.getCwdUrl());
    2553           0 :                 std::vector<OUString> const & data(rAppEvent.GetStringsData());
    2554             :                 pDocsRequest->aOpenList.insert(
    2555           0 :                     pDocsRequest->aOpenList.end(), data.begin(), data.end());
    2556           0 :                 pDocsRequest->pcProcessed = NULL;
    2557             : 
    2558           0 :                 OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
    2559           0 :                 delete pDocsRequest;
    2560             :             }
    2561             :         }
    2562           0 :         break;
    2563             :     case ApplicationEvent::TYPE_OPENHELPURL:
    2564             :         // start help for a specific URL
    2565           0 :         Application::GetHelp()->Start(rAppEvent.GetStringData(), NULL);
    2566           0 :         break;
    2567             :     case ApplicationEvent::TYPE_PRINT:
    2568             :         {
    2569           0 :             const CommandLineArgs& rCmdLine = GetCommandLineArgs();
    2570           0 :             if ( !rCmdLine.IsInvisible() && !rCmdLine.IsTerminateAfterInit() )
    2571             :             {
    2572             :                 ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
    2573           0 :                     rCmdLine.getCwdUrl());
    2574           0 :                 std::vector<OUString> const & data(rAppEvent.GetStringsData());
    2575             :                 pDocsRequest->aPrintList.insert(
    2576           0 :                     pDocsRequest->aPrintList.end(), data.begin(), data.end());
    2577           0 :                 pDocsRequest->pcProcessed = NULL;
    2578             : 
    2579           0 :                 OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
    2580           0 :                 delete pDocsRequest;
    2581             :             }
    2582             :         }
    2583           0 :         break;
    2584             :     case ApplicationEvent::TYPE_PRIVATE_DOSHUTDOWN:
    2585             :         {
    2586           0 :             Desktop* pD = dynamic_cast<Desktop*>(GetpApp());
    2587             :             OSL_ENSURE( pD, "no desktop ?!?" );
    2588           0 :             if( pD )
    2589           0 :                 pD->doShutdown();
    2590             :         }
    2591           0 :         break;
    2592             :     case ApplicationEvent::TYPE_QUICKSTART:
    2593           0 :         if ( !GetCommandLineArgs().IsInvisible()  )
    2594             :         {
    2595             :             // If the office has been started the second time its command line arguments are sent through a pipe
    2596             :             // connection to the first office. We want to reuse the quickstart option for the first office.
    2597             :             // NOTICE: The quickstart service must be initialized inside the "main thread", so we use the
    2598             :             // application events to do this (they are executed inside main thread)!!!
    2599             :             // Don't start quickstart service if the user specified "--invisible" on the command line!
    2600           0 :             Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
    2601           0 :             css::office::Quickstart::createStart(xContext, true/*Quickstart*/);
    2602             :         }
    2603           0 :         break;
    2604             :     case ApplicationEvent::TYPE_SHOWDIALOG:
    2605             :         // ignore all errors here. It's clicking a menu entry only ...
    2606             :         // The user will try it again, in case nothing happens .-)
    2607             :         try
    2608             :         {
    2609           0 :             Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
    2610             : 
    2611           0 :             Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext );
    2612             : 
    2613           0 :             Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create(xContext);
    2614           0 :             css::util::URL aCommand;
    2615           0 :             if( rAppEvent.GetStringData() == "PREFERENCES" )
    2616           0 :                 aCommand.Complete = ".uno:OptionsTreeDialog";
    2617           0 :             else if( rAppEvent.GetStringData() == "ABOUT" )
    2618           0 :                 aCommand.Complete = ".uno:About";
    2619           0 :             if( !aCommand.Complete.isEmpty() )
    2620             :             {
    2621           0 :                 xParser->parseStrict(aCommand);
    2622             : 
    2623           0 :                 css::uno::Reference< css::frame::XDispatch > xDispatch = xDesktop->queryDispatch(aCommand, OUString(), 0);
    2624           0 :                 if (xDispatch.is())
    2625           0 :                     xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >());
    2626           0 :             }
    2627             :         }
    2628           0 :         catch(const css::uno::Exception&)
    2629             :         {}
    2630           0 :         break;
    2631             :     case ApplicationEvent::TYPE_UNACCEPT:
    2632             :         // try to remove corresponding acceptor
    2633           0 :         destroyAcceptor(rAppEvent.GetStringData());
    2634           0 :         break;
    2635             :     default:
    2636             :         SAL_WARN( "desktop.app", "this cannot happen");
    2637           0 :         break;
    2638             :     }
    2639           0 : }
    2640             : 
    2641         116 : void Desktop::OpenSplashScreen()
    2642             : {
    2643         116 :     const CommandLineArgs &rCmdLine = GetCommandLineArgs();
    2644             :     // Show intro only if this is normal start (e.g. no server, no quickstart, no printing )
    2645         464 :     if ( !rCmdLine.IsInvisible() &&
    2646           0 :          !rCmdLine.IsHeadless() &&
    2647           0 :          !rCmdLine.IsQuickstart() &&
    2648           0 :          !rCmdLine.IsMinimized() &&
    2649           0 :          !rCmdLine.IsNoLogo() &&
    2650           0 :          !rCmdLine.IsTerminateAfterInit() &&
    2651         116 :          rCmdLine.GetPrintList().empty() &&
    2652         348 :          rCmdLine.GetPrintToList().empty() &&
    2653         116 :          rCmdLine.GetConversionList().empty() )
    2654             :     {
    2655             :         // Determine application name from command line parameters
    2656           0 :         OUString aAppName;
    2657           0 :         if ( rCmdLine.IsWriter() )
    2658           0 :             aAppName = "writer";
    2659           0 :         else if ( rCmdLine.IsCalc() )
    2660           0 :             aAppName = "calc";
    2661           0 :         else if ( rCmdLine.IsDraw() )
    2662           0 :             aAppName = "draw";
    2663           0 :         else if ( rCmdLine.IsImpress() )
    2664           0 :             aAppName = "impress";
    2665           0 :         else if ( rCmdLine.IsBase() )
    2666           0 :             aAppName = "base";
    2667           0 :         else if ( rCmdLine.IsGlobal() )
    2668           0 :             aAppName = "global";
    2669           0 :         else if ( rCmdLine.IsMath() )
    2670           0 :             aAppName = "math";
    2671           0 :         else if ( rCmdLine.IsWeb() )
    2672           0 :             aAppName = "web";
    2673             : 
    2674             :         // Which splash to use
    2675           0 :         OUString aSplashService( "com.sun.star.office.SplashScreen" );
    2676           0 :         if ( rCmdLine.HasSplashPipe() )
    2677           0 :             aSplashService = "com.sun.star.office.PipeSplashScreen";
    2678             : 
    2679           0 :         bool bVisible = true;
    2680           0 :         Sequence< Any > aSeq( 2 );
    2681           0 :         aSeq[0] <<= bVisible;
    2682           0 :         aSeq[1] <<= aAppName;
    2683           0 :         css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
    2684           0 :         m_rSplashScreen = Reference<XStatusIndicator>(
    2685           0 :             xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aSplashService, aSeq, xContext),
    2686           0 :             UNO_QUERY);
    2687             : 
    2688           0 :         if(m_rSplashScreen.is())
    2689           0 :                 m_rSplashScreen->start(OUString("SplashScreen"), 100);
    2690             :     }
    2691             : 
    2692         116 : }
    2693             : 
    2694        1236 : void Desktop::SetSplashScreenProgress(sal_Int32 iProgress)
    2695             : {
    2696        1236 :     if(m_rSplashScreen.is())
    2697             :     {
    2698           0 :         m_rSplashScreen->setValue(iProgress);
    2699             :     }
    2700        1236 : }
    2701             : 
    2702         381 : void Desktop::SetSplashScreenText( const OUString& rText )
    2703             : {
    2704         381 :     if( m_rSplashScreen.is() )
    2705             :     {
    2706           0 :         m_rSplashScreen->setText( rText );
    2707             :     }
    2708         381 : }
    2709             : 
    2710         791 : void Desktop::CloseSplashScreen()
    2711             : {
    2712         791 :     if(m_rSplashScreen.is())
    2713             :     {
    2714           0 :         m_rSplashScreen->end();
    2715           0 :         m_rSplashScreen = NULL;
    2716             :     }
    2717         791 : }
    2718             : 
    2719             : 
    2720          38 : void Desktop::DoFirstRunInitializations()
    2721             : {
    2722             :     try
    2723             :     {
    2724          38 :         Reference< XJobExecutor > xExecutor = theJobExecutor::get( ::comphelper::getProcessComponentContext() );
    2725          38 :         xExecutor->trigger( OUString("onFirstRunInitialization") );
    2726             :     }
    2727           0 :     catch(const ::com::sun::star::uno::Exception&)
    2728             :     {
    2729             :         SAL_WARN( "desktop.app", "Desktop::DoFirstRunInitializations: caught an exception while trigger job executor ..." );
    2730             :     }
    2731          38 : }
    2732             : 
    2733           0 : void Desktop::ShowBackingComponent(Desktop * progress)
    2734             : {
    2735           0 :     if (GetCommandLineArgs().IsNoDefault())
    2736             :     {
    2737           0 :         return;
    2738             :     }
    2739           0 :     Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
    2740           0 :     Reference< XDesktop2 > xDesktop = css::frame::Desktop::create(xContext);
    2741           0 :     if (progress != 0)
    2742             :     {
    2743           0 :         progress->SetSplashScreenProgress(60);
    2744             :     }
    2745           0 :     Reference< XFrame > xBackingFrame = xDesktop->findFrame(OUString( "_blank" ), 0);
    2746           0 :     Reference< ::com::sun::star::awt::XWindow > xContainerWindow;
    2747             : 
    2748           0 :     if (xBackingFrame.is())
    2749           0 :         xContainerWindow = xBackingFrame->getContainerWindow();
    2750           0 :     if (xContainerWindow.is())
    2751             :     {
    2752             :         // set the WB_EXT_DOCUMENT style. Normally, this is done by the TaskCreator service when a "_blank"
    2753             :         // frame/window is created. Since we do not use the TaskCreator here, we need to mimic its behavior,
    2754             :         // otherwise documents loaded into this frame will later on miss functionality depending on the style.
    2755           0 :         vcl::Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
    2756             :         SAL_WARN_IF( !pContainerWindow, "desktop.app", "Desktop::Main: no implementation access to the frame's container window!" );
    2757           0 :         pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WB_EXT_DOCUMENT );
    2758           0 :         if (progress != 0)
    2759             :         {
    2760           0 :             progress->SetSplashScreenProgress(75);
    2761             :         }
    2762             : 
    2763           0 :         Reference< XController > xStartModule = StartModule::createWithParentWindow( xContext, xContainerWindow);
    2764             :         // Attention: You MUST(!) call setComponent() before you call attachFrame().
    2765             :         // Because the backing component set the property "IsBackingMode" of the frame
    2766             :         // to true inside attachFrame(). But setComponent() reset this state everytimes ...
    2767           0 :         xBackingFrame->setComponent(Reference< XWindow >(xStartModule, UNO_QUERY), xStartModule);
    2768           0 :         if (progress != 0)
    2769             :         {
    2770           0 :             progress->SetSplashScreenProgress(100);
    2771             :         }
    2772           0 :         xStartModule->attachFrame(xBackingFrame);
    2773           0 :         if (progress != 0)
    2774             :         {
    2775           0 :             progress->CloseSplashScreen();
    2776             :         }
    2777           0 :         xContainerWindow->setVisible(sal_True);
    2778           0 :     }
    2779             : }
    2780             : 
    2781             : 
    2782          64 : void Desktop::CheckFirstRun( )
    2783             : {
    2784          64 :     if (officecfg::Office::Common::Misc::FirstRun::get())
    2785             :     {
    2786             :         // use VCL timer, which won't trigger during shutdown if the
    2787             :         // application exits before timeout
    2788          47 :         m_firstRunTimer.SetTimeout(3000); // 3 sec.
    2789          47 :         m_firstRunTimer.SetTimeoutHdl(LINK(this, Desktop, AsyncInitFirstRun));
    2790          47 :         m_firstRunTimer.Start();
    2791             : 
    2792             : #ifdef WNT
    2793             :         // Check if Quckstarter should be started (on Windows only)
    2794             :         TCHAR szValue[8192];
    2795             :         DWORD nValueSize = sizeof(szValue);
    2796             :         HKEY hKey;
    2797             :         if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE,  "Software\\LibreOffice", &hKey ) )
    2798             :         {
    2799             :             if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("RunQuickstartAtFirstStart"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
    2800             :             {
    2801             :                 css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
    2802             :                 css::office::Quickstart::createAutoStart(xContext, true/*Quickstart*/, true/*bAutostart*/);
    2803             :                 RegCloseKey( hKey );
    2804             :             }
    2805             :         }
    2806             : #endif
    2807             : 
    2808             :         std::shared_ptr< comphelper::ConfigurationChanges > batch(
    2809          47 :             comphelper::ConfigurationChanges::create());
    2810          47 :         officecfg::Office::Common::Misc::FirstRun::set(false, batch);
    2811          47 :         batch->commit();
    2812             :     }
    2813          64 : }
    2814             : 
    2815         348 : }
    2816             : 
    2817             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11