LibreOffice Module desktop (master)  1
app.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <memory>
21 #include <config_features.h>
22 #include <config_java.h>
23 #include <config_folders.h>
24 #include <config_extensions.h>
25 
26 #include <sal/config.h>
27 
28 #include <iostream>
29 #include <mutex>
30 #if defined UNX
31 #include <signal.h>
32 #endif
33 
34 #include <app.hxx>
35 #include <dp_shared.hxx>
36 #include <strings.hrc>
37 #include "cmdlineargs.hxx"
38 #include "cmdlinehelp.hxx"
39 #include "dispatchwatcher.hxx"
40 #include <lockfile.hxx>
41 #include "userinstall.hxx"
42 #include "desktopcontext.hxx"
43 #include <migration.hxx>
44 #if HAVE_FEATURE_UPDATE_MAR
45 #include "updater.hxx"
46 #endif
47 
50 #include <svl/languageoptions.hxx>
51 #include <svtools/javacontext.hxx>
52 #include <com/sun/star/beans/XPropertySet.hpp>
53 #include <com/sun/star/frame/theAutoRecovery.hpp>
54 #include <com/sun/star/frame/theGlobalEventBroadcaster.hpp>
55 #include <com/sun/star/frame/SessionListener.hpp>
56 #include <com/sun/star/frame/XSynchronousDispatch.hpp>
57 #include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
58 #include <com/sun/star/configuration/CorruptedConfigurationException.hpp>
59 #include <com/sun/star/configuration/theDefaultProvider.hpp>
60 #include <com/sun/star/util/XFlushable.hpp>
61 #include <com/sun/star/util/XModifiable.hpp>
62 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
63 #include <com/sun/star/frame/Desktop.hpp>
64 #include <com/sun/star/frame/StartModule.hpp>
65 #include <com/sun/star/view/XPrintable.hpp>
66 #include <com/sun/star/awt/XTopWindow.hpp>
67 #include <com/sun/star/util/URLTransformer.hpp>
68 #include <com/sun/star/util/XURLTransformer.hpp>
69 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
70 #include <com/sun/star/configuration/MissingBootstrapFileException.hpp>
71 #include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
72 #include <com/sun/star/configuration/InstallationIncompleteException.hpp>
73 #include <com/sun/star/configuration/backend/BackendSetupException.hpp>
74 #include <com/sun/star/configuration/backend/BackendAccessException.hpp>
75 #include <com/sun/star/task/theJobExecutor.hpp>
76 #include <com/sun/star/task/OfficeRestartManager.hpp>
77 #include <com/sun/star/task/XRestartManager.hpp>
78 #include <com/sun/star/document/XDocumentEventListener.hpp>
79 #include <com/sun/star/ui/theUIElementFactoryManager.hpp>
80 #include <com/sun/star/ui/theWindowStateConfiguration.hpp>
81 #include <com/sun/star/office/Quickstart.hpp>
82 #include <com/sun/star/system/XSystemShellExecute.hpp>
83 #include <com/sun/star/system/SystemShellExecute.hpp>
84 
85 #include <desktop/exithelper.h>
86 #include <sal/log.hxx>
89 #include <comphelper/fileurl.hxx>
93 #include <unotools/bootstrap.hxx>
94 #include <unotools/configmgr.hxx>
97 #include <officecfg/Office/Common.hxx>
98 #include <officecfg/Office/Recovery.hxx>
99 #include <officecfg/Office/Update.hxx>
100 #include <officecfg/Setup.hxx>
101 #include <osl/file.hxx>
102 #include <osl/process.h>
103 #include <rtl/byteseq.hxx>
104 #include <rtl/uri.hxx>
105 #include <unotools/pathoptions.hxx>
106 #include <svtools/miscopt.hxx>
107 #include <svtools/menuoptions.hxx>
108 #include <rtl/bootstrap.hxx>
109 #include <vcl/glxtestprocess.hxx>
110 #include <vcl/help.hxx>
111 #include <vcl/weld.hxx>
112 #include <vcl/settings.hxx>
113 #include <sfx2/flatpak.hxx>
114 #include <sfx2/sfxsids.hrc>
115 #include <sfx2/app.hxx>
116 #include <sfx2/safemode.hxx>
117 #include <svl/itemset.hxx>
118 #include <svl/eitem.hxx>
119 #include <basic/sbstar.hxx>
120 #include <desktop/crashreport.hxx>
121 #include <tools/urlobj.hxx>
122 #include <tools/diagnose_ex.h>
125 #include <svtools/apearcfg.hxx>
126 #include <vcl/graphicfilter.hxx>
127 #include <vcl/window.hxx>
128 #include "langselect.hxx"
129 
130 #if HAVE_FEATURE_BREAKPAD
131 #include <fstream>
132 #endif
133 
134 #if defined MACOSX
135 #include <errno.h>
136 #include <sys/wait.h>
137 #endif
138 
139 #ifdef _WIN32
140 #define WIN32_LEAN_AND_MEAN
141 #include <windows.h>
142 #endif
143 
144 #if defined(_WIN32)
145 #include <process.h>
146 #define GETPID _getpid
147 #else
148 #include <unistd.h>
149 #define GETPID getpid
150 #endif
151 
152 #include <strings.hxx>
153 
154 using namespace ::com::sun::star::awt;
155 using namespace ::com::sun::star::uno;
156 using namespace ::com::sun::star::util;
157 using namespace ::com::sun::star::lang;
158 using namespace ::com::sun::star::beans;
159 using namespace ::com::sun::star::frame;
160 using namespace ::com::sun::star::document;
161 using namespace ::com::sun::star::view;
162 using namespace ::com::sun::star::task;
163 using namespace ::com::sun::star::system;
164 using namespace ::com::sun::star::ui;
165 using namespace ::com::sun::star::ui::dialogs;
166 using namespace ::com::sun::star::container;
167 
168 namespace desktop
169 {
170 
171 static oslSignalHandler pSignalHandler = nullptr;
172 
173 namespace {
174 
175 #if HAVE_FEATURE_EXTENSIONS
176 
177 // Remove any existing UserInstallation's extensions cache data remaining from
178 // old installations. This addresses at least two problems:
179 //
180 // For one, apparently due to the old share/prereg/bundled mechanism (disabled
181 // since 5c47e5f63a79a9e72ec4a100786b1bbf65137ed4 "fdo#51252 Disable copying
182 // share/prereg/bundled to avoid startup crashes"), the user/extensions/bundled
183 // cache could contain corrupted information (like a UNO component registered
184 // twice, which got changed from active to passive registration in one LO
185 // version, but the version of the corresponding bundled extension only
186 // incremented in a later LO version).
187 //
188 // For another, UserInstallations have been seen in the wild where no extensions
189 // were installed per-user (any longer), but user/uno_packages/cache/registry/
190 // com.sun.star.comp.deployment.component.PackageRegistryBackend/*.rdb files
191 // contained data nevertheless.
192 //
193 // When a LO upgrade is detected (i.e., no user/extensions/buildid or one
194 // containing an old build ID), then user/extensions and
195 // user/uno_packages/cache/registry/
196 // com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc are
197 // removed. That should prevent any problems starting the service manager due
198 // to old junk. Later on in Desktop::SynchronizeExtensionRepositories, the
199 // removed cache data is recreated.
200 //
201 // Multiple instances of soffice.bin can execute this code in parallel for a
202 // single UserInstallation, as it is called before RequestHandler is set up.
203 // Therefore, any errors here only lead to SAL_WARNs.
204 //
205 // At least in theory, this function could be removed again once no
206 // UserInstallation can be poisoned by old junk any more.
207 bool cleanExtensionCache() {
208  OUString buildId(
209  "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("version") ":buildid}");
210  rtl::Bootstrap::expandMacros(buildId); //TODO: detect failure
211  OUString extDir(
212  "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap")
213  ":UserInstallation}/user/extensions");
214  rtl::Bootstrap::expandMacros(extDir); //TODO: detect failure
215  OUString buildIdFile(extDir + "/buildid");
216  osl::File fr(buildIdFile);
217  osl::FileBase::RC rc = fr.open(osl_File_OpenFlag_Read);
218  switch (rc) {
219  case osl::FileBase::E_None:
220  {
221  rtl::ByteSequence s1;
222  rc = fr.readLine(s1);
223  osl::FileBase::RC rc2 = fr.close();
224  SAL_WARN_IF(
225  rc2 != osl::FileBase::E_None, "desktop.app",
226  "cannot close " << fr.getURL() << " after reading: " << +rc2);
227  // readLine returns E_AGAIN for a zero-size file:
228  if (rc != osl::FileBase::E_None && rc != osl::FileBase::E_AGAIN) {
229  SAL_WARN( "desktop.app", "cannot read from " << fr.getURL() << ": " << +rc);
230  break;
231  }
232  OUString s2(
233  reinterpret_cast< char const * >(s1.getConstArray()),
234  s1.getLength(), RTL_TEXTENCODING_ISO_8859_1);
235  // using ISO 8859-1 avoids any and all conversion errors; the
236  // content should only be a subset of ASCII, anyway
237  if (s2 == buildId) {
238  return false;
239  }
240  break;
241  }
242  case osl::FileBase::E_NOENT:
243  break;
244  default:
245  SAL_WARN( "desktop.app", "cannot open " << fr.getURL() << " for reading: " << +rc);
246  break;
247  }
248  utl::removeTree(extDir);
249  OUString userRcFile(
250  "$UNO_USER_PACKAGES_CACHE/registry/"
251  "com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
252  rtl::Bootstrap::expandMacros(userRcFile); //TODO: detect failure
253  rc = osl::File::remove(userRcFile);
254  SAL_WARN_IF(
255  rc != osl::FileBase::E_None && rc != osl::FileBase::E_NOENT, "desktop.app",
256  "cannot remove file " << userRcFile << ": " << +rc);
257  rc = osl::Directory::createPath(extDir);
258  SAL_WARN_IF(
259  rc != osl::FileBase::E_None && rc != osl::FileBase::E_EXIST, "desktop.app",
260  "cannot create path " << extDir << ": " << +rc);
261  osl::File fw(buildIdFile);
262  rc = fw.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
263  if (rc != osl::FileBase::E_None) {
264  SAL_WARN( "desktop.app", "cannot open " << fw.getURL() << " for writing: " << +rc);
265  return true;
266  }
267  OString buf(OUStringToOString(buildId, RTL_TEXTENCODING_UTF8));
268  // using UTF-8 avoids almost all conversion errors (and buildid
269  // containing single surrogate halves should never happen, anyway); the
270  // content should only be a subset of ASCII, anyway
271  sal_uInt64 n = 0;
272  rc = fw.write(buf.getStr(), buf.getLength(), n);
273  SAL_WARN_IF(
274  (rc != osl::FileBase::E_None
275  || n != static_cast< sal_uInt32 >(buf.getLength())),
276  "desktop.app",
277  "cannot write to " << fw.getURL() << ": " << +rc << ", " << n);
278  rc = fw.close();
279  SAL_WARN_IF(
280  rc != osl::FileBase::E_None, "desktop.app",
281  "cannot close " << fw.getURL() << " after writing: " << +rc);
282  return true;
283 }
284 
285 #endif
286 
287 bool shouldLaunchQuickstart()
288 {
289  bool bQuickstart = Desktop::GetCommandLineArgs().IsQuickstart();
290  if (!bQuickstart)
291  {
292  const SfxPoolItem* pItem=nullptr;
294  SfxGetpApp()->GetOptions(aQLSet);
295  SfxItemState eState = aQLSet.GetItemState(SID_ATTR_QUICKLAUNCHER, false, &pItem);
296  if (SfxItemState::SET == eState)
297  bQuickstart = static_cast<const SfxBoolItem*>(pItem)->GetValue();
298  }
299  return bQuickstart;
300 }
301 
302 void SetRestartState() {
303  try {
304  std::shared_ptr< comphelper::ConfigurationChanges > batch(
306  officecfg::Setup::Office::OfficeRestartInProgress::set(true, batch);
307  batch->commit();
308  } catch (css::uno::Exception & e) {
309  SAL_WARN("desktop.app", "ignoring " << e);
310  }
311 }
312 
313 void DoRestartActionsIfNecessary(bool quickstart) {
314  if (quickstart) {
315  try {
316  if (officecfg::Setup::Office::OfficeRestartInProgress::get()) {
317  std::shared_ptr< comphelper::ConfigurationChanges > batch(
319  officecfg::Setup::Office::OfficeRestartInProgress::set(
320  false, batch);
321  batch->commit();
322  css::office::Quickstart::createStart(
324  shouldLaunchQuickstart());
325  }
326  } catch (css::uno::Exception & e) {
327  SAL_WARN(
328  "desktop.app", "ignoring " << e);
329  }
330  }
331 }
332 
333 }
334 
335 namespace {
336 
337 
338 OUString MakeStartupErrorMessage(OUString const & aErrorMessage)
339 {
340  return DpResId(STR_BOOTSTRAP_ERR_CANNOT_START) + "\n" + aErrorMessage;
341 }
342 
343 OUString MakeStartupConfigAccessErrorMessage( OUString const & aInternalErrMsg )
344 {
345  OUString aDiagnosticMessage = DpResId(STR_BOOTSTRAP_ERR_CFG_DATAACCESS);
346  if ( !aInternalErrMsg.isEmpty() )
347  {
348  aDiagnosticMessage += "\n\n"
349  + DpResId(STR_INTERNAL_ERRMSG)
350  + aInternalErrMsg;
351  }
352  return aDiagnosticMessage;
353 }
354 
355 
356 // shows a simple error box with the given message ... but exits from these process !
357 // Fatal errors can't be solved by the process ... nor any recovery can help.
358 // Mostly the installation was damaged and must be repaired manually .. or by calling
359 // setup again.
360 // On the other side we must make sure that no further actions will be possible within
361 // the current office process ! No pipe requests, no menu/toolbar/shortcut actions
362 // are allowed. Otherwise we will force a "crash inside a crash".
363 // That's why we have to use a special native message box here which does not use yield :-)
364 
365 void FatalError(const OUString& sMessage)
366 {
367  OUString sProductKey = ::utl::Bootstrap::getProductKey();
368  if ( sProductKey.isEmpty())
369  {
370  osl_getExecutableFile( &sProductKey.pData );
371 
372  ::sal_uInt32 nLastIndex = sProductKey.lastIndexOf('/');
373  if ( nLastIndex > 0 )
374  sProductKey = sProductKey.copy( nLastIndex+1 );
375  }
376 
377  OUString sTitle = sProductKey + " - Fatal Error";
378  Application::ShowNativeErrorBox (sTitle, sMessage);
379  std::cerr << sTitle << ": " << sMessage << std::endl;
380  _exit(EXITHELPER_FATAL_ERROR);
381 }
382 
383 struct theCommandLineArgs : public rtl::Static< CommandLineArgs, theCommandLineArgs > {};
384 
385 }
386 
388 {
389  return theCommandLineArgs::get();
390 }
391 
392 namespace
393 {
394  struct OOOVendor
395  : public rtl::Static< OUString, OOOVendor > {};
396 }
397 
398 OUString ReplaceStringHookProc( const OUString& rStr )
399 {
400  const static OUString sBuildId(utl::Bootstrap::getBuildIdData("development"));
401  static OUString sBrandName, sVersion, sAboutBoxVersion, sAboutBoxVersionSuffix, sExtension;
402 
403  static std::once_flag aInitOnce;
404  std::call_once(aInitOnce, []
405  {
406  sBrandName = utl::ConfigManager::getProductName();
409  sAboutBoxVersionSuffix = utl::ConfigManager::getAboutBoxProductVersionSuffix();
411  } );
412 
413  OUString sRet(rStr);
414  if (sRet.indexOf("%PRODUCT") != -1 || sRet.indexOf("%ABOUTBOX") != -1)
415  {
416  sRet = sRet.replaceAll( "%PRODUCTNAME", sBrandName );
417  sRet = sRet.replaceAll( "%PRODUCTVERSION", sVersion );
418  sRet = sRet.replaceAll( "%BUILDID", sBuildId );
419  sRet = sRet.replaceAll( "%ABOUTBOXPRODUCTVERSIONSUFFIX", sAboutBoxVersionSuffix );
420  sRet = sRet.replaceAll( "%ABOUTBOXPRODUCTVERSION", sAboutBoxVersion );
421  sRet = sRet.replaceAll( "%PRODUCTEXTENSION", sExtension );
422  }
423 
424  if ( sRet.indexOf( "%OOOVENDOR" ) != -1 )
425  {
426  OUString sOOOVendor = OOOVendor::get();
427 
428  if ( sOOOVendor.isEmpty() )
429  {
430  sOOOVendor = utl::ConfigManager::getVendor();
431  }
432 
433  sRet = sRet.replaceAll( "%OOOVENDOR", sOOOVendor );
434  }
435 
436  return sRet;
437 }
438 
440  : m_bCleanedExtensionCache(false)
441  , m_bServicesRegistered(false)
442  , m_aBootstrapError(BE_OK)
443  , m_aBootstrapStatus(BS_OK)
444 {
445  m_firstRunTimer.SetTimeout(3000); // 3 sec.
446  m_firstRunTimer.SetInvokeHandler(LINK(this, Desktop, AsyncInitFirstRun));
447  m_firstRunTimer.SetDebugName( "desktop::Desktop m_firstRunTimer" );
448 }
449 
451 {
452 }
453 
455 {
457 
458 #if HAVE_FEATURE_EXTENSIONS
459  m_bCleanedExtensionCache = cleanExtensionCache();
460 #endif
461 
462  // We need to have service factory before going further, but see fdo#37195.
463  // Doing this will mmap common.rdb, making it not overwritable on windows,
464  // so this can't happen before the synchronization above. Lets rework this
465  // so that the above is called *from* CreateApplicationServiceManager or
466  // something to enforce this gotcha
467  try
468  {
470  }
471  catch (css::uno::Exception & e)
472  {
474  }
475 
476  // Check whether safe mode is enabled
477  const CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
478  // Check if we are restarting from safe mode - in that case we don't want to enter it again
481  else if (rCmdLineArgs.IsSafeMode() || sfx2::SafeMode::hasFlag())
483 
484  // When we are in SafeMode we need to do changes before the configuration
485  // gets read (langselect::prepareLocale() by UNO API -> Components::Components)
486  // This may prepare SafeMode or restore from it by moving data in
487  // the UserConfiguration directory
489 
490  if ( m_aBootstrapError == BE_OK )
491  {
492  try
493  {
495  {
496  SetBootstrapError( BE_LANGUAGE_MISSING, OUString() );
497  }
498  }
499  catch (css::uno::Exception & e)
500  {
502  }
503 
504  // test code for ProfileSafeMode to allow testing the fail
505  // of loading the office configuration initially. To use,
506  // either set to true and compile, or set a breakpoint
507  // in debugger and change the local bool
508  static bool bTryHardOfficeconfigBroken(false); // loplugin:constvars:ignore
509 
510  if (bTryHardOfficeconfigBroken)
511  {
513  }
514  }
515 
516  if ( true )
517  {
518  // start ipc thread only for non-remote offices
520  if ( aStatus == RequestHandler::IPC_STATUS_PIPE_ERROR )
521  {
522 #if defined ANDROID
523  // Ignore crack pipe errors on Android
524 #else
525  // Keep using this oddly named BE_PATHINFO_MISSING value
526  // for pipe-related errors on other platforms. Of course
527  // this crack with two (if not more) levels of our own
528  // error codes hiding the actual system error code is
529  // broken, but that is done all over the code, let's leave
530  // reengineering that to another year.
531  SetBootstrapError( BE_PATHINFO_MISSING, OUString() );
532 #endif
533  }
534  else if ( aStatus == RequestHandler::IPC_STATUS_BOOTSTRAP_ERROR )
535  {
536  SetBootstrapError( BE_PATHINFO_MISSING, OUString() );
537  }
538  else if ( aStatus == RequestHandler::IPC_STATUS_2ND_OFFICE )
539  {
540  // 2nd office startup should terminate after sending cmdlineargs through pipe
542  }
543  else if ( !rCmdLineArgs.GetUnknown().isEmpty()
544  || rCmdLineArgs.IsHelp() || rCmdLineArgs.IsVersion() )
545  {
546  // disable IPC thread in an instance that is just showing a help message
548  }
549  pSignalHandler = osl_addSignalHandler(SalMainPipeExchangeSignal_impl, nullptr);
550  }
551 }
552 
554 {
556 }
557 
559 {
560  try {
561  // instead of removing of the configManager just let it commit all the changes
564 
565  // close splashscreen if it's still open
567  Reference< XComponent >(
568  comphelper::getProcessComponentContext(), UNO_QUERY_THROW )->
569  dispose();
570  // nobody should get a destroyed service factory...
571  ::comphelper::setProcessServiceFactory( nullptr );
572 
573  // clear lockfile
574  m_xLockfile.reset();
575 
577  if( pSignalHandler )
578  osl_removeSignalHandler( pSignalHandler );
579  } catch (const RuntimeException&) {
580  // someone threw an exception during shutdown
581  // this will leave some garbage behind..
582  }
583 }
584 
586 {
587  try
588  {
590  }
591  catch ( const RuntimeException& )
592  {
593  }
594 
595  const sal_Char SUSPEND_QUICKSTARTVETO[] = "SuspendQuickstartVeto";
596 
597  Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
598  Reference< XPropertySet > xPropertySet(xDesktop, UNO_QUERY_THROW);
599  xPropertySet->setPropertyValue( SUSPEND_QUICKSTARTVETO, Any(true) );
600 
601  bool bExit = xDesktop->terminate();
602 
603  if ( !bExit )
604  {
605  xPropertySet->setPropertyValue( SUSPEND_QUICKSTARTVETO, Any(false) );
606  }
608  {
610  try
611  {
612  // it is no problem to call RequestHandler::Disable() more than once
613  // it also looks to be threadsafe
615  }
616  catch ( const RuntimeException& )
617  {
618  }
619 
620  m_xLockfile.reset();
621 
622  }
623 
624  return bExit;
625 }
626 
627 void Desktop::HandleBootstrapPathErrors( ::utl::Bootstrap::Status aBootstrapStatus, const OUString& aDiagnosticMessage )
628 {
629  if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
630  {
631  OUString aProductKey;
632  OUString aTemp;
633 
634  osl_getExecutableFile( &aProductKey.pData );
635  sal_uInt32 lastIndex = aProductKey.lastIndexOf('/');
636  if ( lastIndex > 0 )
637  aProductKey = aProductKey.copy( lastIndex+1 );
638 
639  aTemp = ::utl::Bootstrap::getProductKey( aProductKey );
640  if ( !aTemp.isEmpty() )
641  aProductKey = aTemp;
642 
643  OUString const aMessage(aDiagnosticMessage + "\n");
644 
645  std::unique_ptr<weld::MessageDialog> xBootstrapFailedBox(Application::CreateMessageDialog(nullptr,
646  VclMessageType::Warning, VclButtonsType::Ok, aMessage));
647  xBootstrapFailedBox->set_title(aProductKey);
648  xBootstrapFailedBox->run();
649  }
650 }
651 
652 // Create an error message depending on bootstrap failure code and an optional file url
654  utl::Bootstrap::FailureCode nFailureCode,
655  const OUString& aFileURL )
656 {
657  OUString aMsg;
658  OUString aFilePath;
659  bool bFileInfo = true;
660 
661  switch ( nFailureCode )
662  {
664  case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
665  {
666  aMsg = DpResId(STR_BOOTSTRAP_ERR_PATH_INVALID);
667  bFileInfo = false;
668  }
669  break;
670 
672  case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
673  {
674  aMsg = DpResId(STR_BOOTSTRAP_ERR_FILE_MISSING);
675  }
676  break;
677 
680  case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
681  case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
682  {
683  aMsg = DpResId(STR_BOOTSTRAP_ERR_FILE_CORRUPT);
684  }
685  break;
686 
688  case ::utl::Bootstrap::MISSING_VERSION_FILE:
689  {
690  aMsg = DpResId(STR_BOOTSTRAP_ERR_FILE_MISSING);
691  }
692  break;
693 
695  case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
696  {
697  aMsg = DpResId(STR_BOOTSTRAP_ERR_NO_SUPPORT);
698  }
699  break;
700 
702  case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
703  {
704  aMsg = DpResId(STR_BOOTSTRAP_ERR_DIR_MISSING);
705  }
706  break;
707 
709  case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
710  {
711  aMsg = DpResId(STR_BOOTSTRAP_ERR_INTERNAL);
712  bFileInfo = false;
713  }
714  break;
715 
716  case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
717  {
718  // This needs to be improved, see #i67575#:
719  aMsg = "Invalid version file entry";
720  bFileInfo = false;
721  }
722  break;
723 
724  case ::utl::Bootstrap::NO_FAILURE:
725  {
726  OSL_ASSERT(false);
727  }
728  break;
729  }
730 
731  if ( bFileInfo )
732  {
733  OUString aMsgString( aMsg );
734 
735  osl::File::getSystemPathFromFileURL( aFileURL, aFilePath );
736 
737  aMsgString = aMsgString.replaceFirst( "$1", aFilePath );
738  aMsg = aMsgString;
739  }
740 
741  return MakeStartupErrorMessage( aMsg );
742 }
743 
745  BootstrapError aBootstrapError, OUString const & aErrorMessage )
746 {
747  if ( aBootstrapError == BE_PATHINFO_MISSING )
748  {
749  OUString aErrorMsg;
750  OUString aBuffer;
751  utl::Bootstrap::Status aBootstrapStatus;
752  utl::Bootstrap::FailureCode nFailureCode;
753 
754  aBootstrapStatus = ::utl::Bootstrap::checkBootstrapStatus( aBuffer, nFailureCode );
755  if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
756  {
757  switch ( nFailureCode )
758  {
759  case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
760  case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
761  {
762  aErrorMsg = CreateErrorMsgString( nFailureCode, OUString() );
763  }
764  break;
765 
769  case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
770  case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
771  case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
772  {
773  OUString aBootstrapFileURL;
774 
775  utl::Bootstrap::locateBootstrapFile( aBootstrapFileURL );
776  aErrorMsg = CreateErrorMsgString( nFailureCode, aBootstrapFileURL );
777  }
778  break;
779 
783  case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
784  case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
785  case ::utl::Bootstrap::MISSING_VERSION_FILE:
786  {
787  OUString aVersionFileURL;
788 
789  utl::Bootstrap::locateVersionFile( aVersionFileURL );
790  aErrorMsg = CreateErrorMsgString( nFailureCode, aVersionFileURL );
791  }
792  break;
793 
795  case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
796  {
797  OUString aUserInstallationURL;
798 
799  utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
800  aErrorMsg = CreateErrorMsgString( nFailureCode, aUserInstallationURL );
801  }
802  break;
803 
804  case ::utl::Bootstrap::NO_FAILURE:
805  {
806  OSL_ASSERT(false);
807  }
808  break;
809  }
810 
811  HandleBootstrapPathErrors( aBootstrapStatus, aErrorMsg );
812  }
813  }
814  else if ( aBootstrapError == BE_UNO_SERVICEMANAGER || aBootstrapError == BE_UNO_SERVICE_CONFIG_MISSING )
815  {
816  // Uno service manager is not available. VCL needs a uno service manager to display a message box!!!
817  // Currently we are not able to display a message box with a service manager due to this limitations inside VCL.
818 
819  // When UNO is not properly initialized, all kinds of things can fail
820  // and cause the process to crash. To give the user a hint even if
821  // generating and displaying a message box below crashes, print a
822  // hard-coded message on stderr first:
823  std::cerr
824  << "The application cannot be started.\n"
825  // STR_BOOTSTRAP_ERR_CANNOT_START
826  << (aBootstrapError == BE_UNO_SERVICEMANAGER
827  ? "The component manager is not available.\n"
828  // STR_BOOTSTRAP_ERR_NO_SERVICE
829  : "The configuration service is not available.\n");
830  // STR_BOOTSTRAP_ERR_NO_CFG_SERVICE
831  if ( !aErrorMessage.isEmpty() )
832  {
833  std::cerr << "(\"" << aErrorMessage << "\")\n";
834  }
835 
836  // First sentence. We cannot bootstrap office further!
837  OUString aDiagnosticMessage = DpResId(STR_BOOTSTRAP_ERR_NO_CFG_SERVICE) + "\n";
838  if ( !aErrorMessage.isEmpty() )
839  {
840  aDiagnosticMessage += "(\"" + aErrorMessage + "\")\n";
841  }
842 
843  // Due to the fact the we haven't a backup applicat.rdb file anymore it is not possible to
844  // repair the installation with the setup executable besides the office executable. Now
845  // we have to ask the user to start the setup on CD/installation directory manually!!
846  aDiagnosticMessage += DpResId(STR_ASK_START_SETUP_MANUALLY);
847 
848  FatalError(MakeStartupErrorMessage(aDiagnosticMessage));
849  }
850  else if ( aBootstrapError == BE_OFFICECONFIG_BROKEN )
851  {
852  // set flag at BackupFileHelper to be able to know if _exit was called and
853  // actions are executed after this. This method we are in will not return,
854  // but end up in a _exit() call
856 
857  // enter safe mode, too
859 
860  OUString msg(DpResId(STR_CONFIG_ERR_ACCESS_GENERAL));
861  if (!aErrorMessage.isEmpty()) {
862  msg += "\n(\"" + aErrorMessage + "\")";
863  }
864  FatalError(MakeStartupErrorMessage(msg));
865  }
866  else if ( aBootstrapError == BE_USERINSTALL_FAILED )
867  {
868  OUString aDiagnosticMessage = DpResId(STR_BOOTSTRAP_ERR_USERINSTALL_FAILED);
869  FatalError(MakeStartupErrorMessage(aDiagnosticMessage));
870  }
871  else if ( aBootstrapError == BE_LANGUAGE_MISSING )
872  {
873  OUString aDiagnosticMessage = DpResId(STR_BOOTSTRAP_ERR_LANGUAGE_MISSING);
874  FatalError(MakeStartupErrorMessage(aDiagnosticMessage));
875  }
876  else if (( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE ) ||
877  ( aBootstrapError == BE_USERINSTALL_NOWRITEACCESS ))
878  {
879  OUString aUserInstallationURL;
880  OUString aUserInstallationPath;
881  utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
882  osl::File::getSystemPathFromFileURL( aUserInstallationURL, aUserInstallationPath );
883 
884  OUString aDiagnosticMessage;
885  if ( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE )
886  aDiagnosticMessage = DpResId(STR_BOOTSTRAP_ERR_NOTENOUGHDISKSPACE);
887  else
888  aDiagnosticMessage = DpResId(STR_BOOTSTRAP_ERR_NOACCESSRIGHTS);
889  aDiagnosticMessage += aUserInstallationPath;
890 
891  FatalError(MakeStartupErrorMessage(aDiagnosticMessage));
892  }
893 }
894 
895 
896 namespace {
897 
898 bool crashReportInfoExists()
899 {
900 #if HAVE_FEATURE_BREAKPAD
901  std::string path = CrashReporter::getIniFileName();
902  std::ifstream aFile(path);
903  while (aFile.good())
904  {
905  std::string line;
906  std::getline(aFile, line);
907  int sep = line.find('=');
908  if (sep >= 0)
909  {
910  std::string key = line.substr(0, sep);
911  if (key == "DumpFile")
912  return true;
913  }
914  }
915 #endif
916  return false;
917 }
918 
919 #if HAVE_FEATURE_BREAKPAD
920 void handleCrashReport()
921 {
922  static const char SERVICENAME_CRASHREPORT[] = "com.sun.star.comp.svx.CrashReportUI";
923 
924  css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
925 
926  Reference< css::frame::XSynchronousDispatch > xRecoveryUI(
927  xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_CRASHREPORT, xContext),
928  css::uno::UNO_QUERY_THROW);
929 
930  Reference< css::util::XURLTransformer > xURLParser =
932 
933  css::util::URL aURL;
934  css::uno::Any aRet = xRecoveryUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
935  bool bRet = false;
936  aRet >>= bRet;
937 }
938 #endif
939 
940 #if !defined ANDROID
941 void handleSafeMode()
942 {
943  css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
944 
945  Reference< css::frame::XSynchronousDispatch > xSafeModeUI(
946  xContext->getServiceManager()->createInstanceWithContext("com.sun.star.comp.svx.SafeModeUI", xContext),
947  css::uno::UNO_QUERY_THROW);
948 
949  css::util::URL aURL;
950  css::uno::Any aRet = xSafeModeUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
951  bool bRet = false;
952  aRet >>= bRet;
953 }
954 #endif
955 
972 void impl_checkRecoveryState(bool& bCrashed ,
973  bool& bRecoveryDataExists,
974  bool& bSessionDataExists )
975 {
976  bCrashed = officecfg::Office::Recovery::RecoveryInfo::Crashed::get() || crashReportInfoExists();
977  bool elements = officecfg::Office::Recovery::RecoveryList::get()->
978  hasElements();
979  bool session
980  = officecfg::Office::Recovery::RecoveryInfo::SessionData::get();
981  bRecoveryDataExists = elements && !session;
982  bSessionDataExists = elements && session;
983 }
984 
985 Reference< css::frame::XSynchronousDispatch > g_xRecoveryUI;
986 
987 template <class Ref>
988 struct RefClearGuard
989 {
991  RefClearGuard(Ref& ref) : m_Ref(ref) {}
992  ~RefClearGuard() { m_Ref.clear(); }
993 };
994 
995 /* @short start the recovery wizard.
996 
997  @param bEmergencySave
998  differs between EMERGENCY_SAVE and RECOVERY
999 */
1000 bool impl_callRecoveryUI(bool bEmergencySave ,
1001  bool bExistsRecoveryData)
1002 {
1003  static const char COMMAND_EMERGENCYSAVE[] = "vnd.sun.star.autorecovery:/doEmergencySave";
1004  static const char COMMAND_RECOVERY[] = "vnd.sun.star.autorecovery:/doAutoRecovery";
1005 
1006  css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1007 
1008  g_xRecoveryUI.set(
1009  xContext->getServiceManager()->createInstanceWithContext("com.sun.star.comp.svx.RecoveryUI", xContext),
1010  css::uno::UNO_QUERY_THROW);
1011  RefClearGuard<Reference< css::frame::XSynchronousDispatch >> refClearGuard(g_xRecoveryUI);
1012 
1013  Reference< css::util::XURLTransformer > xURLParser =
1015 
1016  css::util::URL aURL;
1017  if (bEmergencySave)
1018  aURL.Complete = COMMAND_EMERGENCYSAVE;
1019  else if (bExistsRecoveryData)
1020  aURL.Complete = COMMAND_RECOVERY;
1021  else
1022  return false;
1023 
1024  xURLParser->parseStrict(aURL);
1025 
1026  css::uno::Any aRet = g_xRecoveryUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
1027  bool bRet = false;
1028  aRet >>= bRet;
1029  return bRet;
1030 }
1031 
1032 bool impl_bringToFrontRecoveryUI()
1033 {
1034  Reference< css::frame::XSynchronousDispatch > xRecoveryUI(g_xRecoveryUI);
1035  if (!xRecoveryUI.is())
1036  return false;
1037 
1038  css::util::URL aURL;
1039  aURL.Complete = "vnd.sun.star.autorecovery:/doBringToFront";
1040  Reference< css::util::XURLTransformer > xURLParser =
1042  xURLParser->parseStrict(aURL);
1043 
1044  css::uno::Any aRet = xRecoveryUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
1045  bool bRet = false;
1046  aRet >>= bRet;
1047  return bRet;
1048 }
1049 
1050 }
1051 
1052 namespace {
1053 
1054 void restartOnMac(bool passArguments) {
1055 #if defined MACOSX
1057 #if HAVE_FEATURE_MACOSX_SANDBOX
1058  (void) passArguments; // avoid warnings
1059  OUString aMessage = DpResId(STR_LO_MUST_BE_RESTARTED);
1060 
1061  std::unique_ptr<weld::MessageDialog> xRestartBox(Application::CreateMessageDialog(nullptr,
1062  VclMessageType::Warning, VclButtonsType::Ok, aMessage));
1063  xRestartBox->run();
1064 #else
1065  OUString execUrl;
1066  OSL_VERIFY(osl_getExecutableFile(&execUrl.pData) == osl_Process_E_None);
1067  OUString execPath;
1068  OString execPath8;
1069  if ((osl::FileBase::getSystemPathFromFileURL(execUrl, execPath)
1070  != osl::FileBase::E_None) ||
1071  !execPath.convertToString(
1072  &execPath8, osl_getThreadTextEncoding(),
1073  (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
1074  RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
1075  {
1076  std::abort();
1077  }
1078  std::vector< OString > args;
1079  args.push_back(execPath8);
1080  bool wait = false;
1081  if (passArguments) {
1082  sal_uInt32 n = osl_getCommandArgCount();
1083  for (sal_uInt32 i = 0; i < n; ++i) {
1084  OUString arg;
1085  osl_getCommandArg(i, &arg.pData);
1086  if (arg.match("--accept=")) {
1087  wait = true;
1088  }
1089  OString arg8;
1090  if (!arg.convertToString(
1091  &arg8, osl_getThreadTextEncoding(),
1092  (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
1093  RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
1094  {
1095  std::abort();
1096  }
1097  args.push_back(arg8);
1098  }
1099  }
1100  std::vector< char const * > argPtrs;
1101  for (auto const& elem : args)
1102  {
1103  argPtrs.push_back(elem.getStr());
1104  }
1105  argPtrs.push_back(nullptr);
1106  execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
1107  if (errno == ENOTSUP) { // happens when multithreaded on macOS < 10.6
1108  pid_t pid = fork();
1109  if (pid == 0) {
1110  execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
1111  } else if (pid > 0) {
1112  // Two simultaneously running soffice processes lead to two dock
1113  // icons, so avoid waiting here unless it must be assumed that the
1114  // process invoking soffice itself wants to wait for soffice to
1115  // finish:
1116  if (!wait) {
1117  return;
1118  }
1119  int stat;
1120  if (waitpid(pid, &stat, 0) == pid && WIFEXITED(stat)) {
1121  _exit(WEXITSTATUS(stat));
1122  }
1123  }
1124  }
1125  std::abort();
1126 #endif
1127 #else
1128  (void) passArguments; // avoid warnings
1129 #endif
1130 }
1131 
1132 #if HAVE_FEATURE_UPDATE_MAR
1133 bool isTimeForUpdateCheck()
1134 {
1135  sal_uInt64 nLastUpdate = officecfg::Office::Update::Update::LastUpdateTime::get();
1136  sal_uInt64 nNow = tools::Time::GetSystemTicks();
1137 
1138  sal_uInt64 n7DayInMS = 1000 * 60 * 60 * 12 * 1; // 12 hours in ms
1139  if (nNow - n7DayInMS >= nLastUpdate)
1140  return true;
1141 
1142  return false;
1143 }
1144 #endif
1145 
1146 }
1147 
1149 {
1150  // protect against recursive calls
1151  static bool bInException = false;
1152 
1154  Application::SetSystemWindowMode( nOldMode & ~SystemWindowFlags::NOAUTOMODE );
1155  if ( bInException )
1156  {
1157  Application::Abort( OUString() );
1158  }
1159 
1160  bInException = true;
1161  const CommandLineArgs& rArgs = GetCommandLineArgs();
1162 
1163  // save all modified documents ... if it's allowed doing so.
1164  bool bRestart = false;
1165  bool bAllowRecoveryAndSessionManagement = (
1166  ( !rArgs.IsNoRestore() ) && // some use cases of office must work without recovery
1167  ( !rArgs.IsHeadless() ) &&
1168  ( nCategory != ExceptionCategory::UserInterface ) && // recovery can't work without UI ... but UI layer seems to be the reason for this crash
1169  ( Application::IsInExecute() ) // crashes during startup and shutdown should be ignored (they indicates a corrupt installation ...)
1170  );
1171  if ( bAllowRecoveryAndSessionManagement )
1172  {
1173  // Save all open documents so they will be reopened
1174  // the next time the application is started
1175  // returns true if at least one document could be saved...
1176  bRestart = impl_callRecoveryUI(
1177  true , // force emergency save
1178  false);
1179  }
1180 
1182 
1183  switch( nCategory )
1184  {
1185  case ExceptionCategory::ResourceNotLoaded:
1186  {
1187  Application::Abort( OUString() );
1188  break;
1189  }
1190 
1191  default:
1192  {
1193  m_xLockfile.reset();
1194 
1195  if( bRestart )
1196  {
1198  if( pSignalHandler )
1199  osl_removeSignalHandler( pSignalHandler );
1200 
1201  restartOnMac(false);
1202  if ( m_rSplashScreen.is() )
1203  m_rSplashScreen->reset();
1204 
1206  }
1207  else
1208  {
1209  Application::Abort( OUString() );
1210  }
1211 
1212  break;
1213  }
1214  }
1215 
1216  OSL_ASSERT(false); // unreachable
1217 }
1218 
1219 void Desktop::AppEvent( const ApplicationEvent& rAppEvent )
1220 {
1221  HandleAppEvent( rAppEvent );
1222 }
1223 
1225 {
1226  Reference < css::document::XDocumentEventListener > xGlobalBroadcaster;
1229  std::unique_ptr<SvtLanguageOptions> pLanguageOptions;
1230  std::unique_ptr<SvtPathOptions> pPathOptions;
1231 
1233  : bRestartRequested( false )
1234  , bUseSystemFileDialog( true )
1235  {}
1236 };
1237 
1238 static ExecuteGlobals* pExecGlobals = nullptr;
1239 
1241 {
1242  pExecGlobals = new ExecuteGlobals();
1243 
1244  // Remember current context object
1245  css::uno::ContextLayer layer( css::uno::getCurrentContext() );
1246 
1247  if ( m_aBootstrapError != BE_OK )
1248  {
1250  return EXIT_FAILURE;
1251  }
1252 
1253  BootstrapStatus eStatus = GetBootstrapStatus();
1254  if (eStatus == BS_TERMINATE) {
1255  return EXIT_SUCCESS;
1256  }
1257 
1258  // Detect desktop environment - need to do this as early as possible
1259  css::uno::setCurrentContext( new DesktopContext( css::uno::getCurrentContext() ) );
1260 
1261  CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
1262 
1264 
1265  // Startup screen
1266  OpenSplashScreen();
1267 
1269 
1271  if (inst_fin != userinstall::EXISTED && inst_fin != userinstall::CREATED)
1272  {
1273  SAL_WARN( "desktop.app", "userinstall failed");
1274  if ( inst_fin == userinstall::ERROR_NO_SPACE )
1276  BE_USERINSTALL_NOTENOUGHDISKSPACE, OUString() );
1277  else if ( inst_fin == userinstall::ERROR_CANT_WRITE )
1279  else
1281  return EXIT_FAILURE;
1282  }
1283  // refresh path information
1286 
1287  Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1288 
1289  Reference< XRestartManager > xRestartManager( OfficeRestartManager::get(xContext) );
1290 
1291  Reference< XDesktop2 > xDesktop;
1292  try
1293  {
1294  RegisterServices(xContext);
1295 
1297 
1298 #if HAVE_FEATURE_DESKTOP
1299  // check user installation directory for lockfile so we can be sure
1300  // there is no other instance using our data files from a remote host
1301 
1302  bool bMustLockProfile = ( getenv( "SAL_NOLOCK_PROFILE" ) == nullptr );
1303  if ( bMustLockProfile )
1304  {
1305  m_xLockfile.reset(new Lockfile);
1306 
1307  if ( !rCmdLineArgs.IsHeadless() && !rCmdLineArgs.IsInvisible() &&
1308  !rCmdLineArgs.IsNoLockcheck() && !m_xLockfile->check( Lockfile_execWarning ))
1309  {
1310  // Lockfile exists, and user clicked 'no'
1311  return EXIT_FAILURE;
1312  }
1313  }
1314 
1315  // check if accessibility is enabled but not working and allow to quit
1317  {
1318  if( !InitAccessBridge() )
1319  return EXIT_FAILURE;
1320  }
1321 #endif
1322 
1323  // terminate if requested...
1324  if( rCmdLineArgs.IsTerminateAfterInit() )
1325  return EXIT_SUCCESS;
1326 
1327  // Read the common configuration items for optimization purpose
1328  if ( !InitializeConfiguration() )
1329  return EXIT_FAILURE;
1330 
1331 #if HAVE_FEATURE_UPDATE_MAR
1332  const char* pUpdaterTestEnable = std::getenv("LIBO_UPDATER_TEST_ENABLE");
1333  if (pUpdaterTestEnable || officecfg::Office::Update::Update::Enabled::get())
1334  {
1335  // check if we just updated
1336  const char* pUpdaterRunning = std::getenv("LIBO_UPDATER_TEST_RUNNING");
1337  bool bUpdateRunning = officecfg::Office::Update::Update::UpdateRunning::get() || pUpdaterRunning;
1338  if (bUpdateRunning)
1339  {
1340  OUString aSeeAlso = officecfg::Office::Update::Update::SeeAlso::get();
1341  OUString aOldBuildID = officecfg::Office::Update::Update::OldBuildID::get();
1342 
1343  OUString aBuildID = Updater::getBuildID();
1344  if (aOldBuildID == aBuildID)
1345  {
1346  Updater::log("Old and new Build ID are the same. No Updating took place.");
1347  }
1348  else
1349  {
1350  if (!aSeeAlso.isEmpty())
1351  {
1352  SAL_INFO("desktop.updater", "See also: " << aSeeAlso);
1353  Reference< css::system::XSystemShellExecute > xSystemShell(
1355 
1356  xSystemShell->execute( aSeeAlso, OUString(), SystemShellExecuteFlags::URIS_ONLY );
1357  }
1358  }
1359 
1360  // reset all the configuration values,
1361  // all values need to be read before this code
1362  std::shared_ptr< comphelper::ConfigurationChanges > batch(
1364  officecfg::Office::Update::Update::UpdateRunning::set(false, batch);
1365  officecfg::Office::Update::Update::SeeAlso::set(OUString(), batch);
1366  officecfg::Office::Update::Update::OldBuildID::set(OUString(), batch);
1367  batch->commit();
1368 
1370  }
1371 
1372  osl::DirectoryItem aUpdateFile;
1373  osl::DirectoryItem::get(Updater::getUpdateFileURL(), aUpdateFile);
1374 
1375  const char* pUpdaterTestUpdate = std::getenv("LIBO_UPDATER_TEST_UPDATE");
1376  const char* pForcedUpdateCheck = std::getenv("LIBO_UPDATER_TEST_UPDATE_CHECK");
1377  if (pUpdaterTestUpdate || aUpdateFile.is())
1378  {
1379  OUString aBuildID("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("version") ":buildid}");
1380  rtl::Bootstrap::expandMacros(aBuildID);
1381  std::shared_ptr< comphelper::ConfigurationChanges > batch(
1383  officecfg::Office::Update::Update::OldBuildID::set(aBuildID, batch);
1384  officecfg::Office::Update::Update::UpdateRunning::set(true, batch);
1385  batch->commit();
1386 
1387  // make sure the change is written to the configuration before we start the update
1388  css::uno::Reference<css::util::XFlushable> xFlushable(css::configuration::theDefaultProvider::get(xContext), UNO_QUERY);
1389  xFlushable->flush();
1390  // avoid the old oosplash staying around
1392  bool bSuccess = update();
1393  if (bSuccess)
1394  return EXIT_SUCCESS;
1395  }
1396  else if (isTimeForUpdateCheck() || pForcedUpdateCheck)
1397  {
1398  sal_uInt64 nNow = tools::Time::GetSystemTicks();
1399  Updater::log("Update Check Time: " + OUString::number(nNow));
1400  std::shared_ptr< comphelper::ConfigurationChanges > batch(
1402  officecfg::Office::Update::Update::LastUpdateTime::set(nNow, batch);
1403  batch->commit();
1404  m_aUpdateThread = std::thread(update_checker);
1405  }
1406  }
1407 #endif
1408 
1410 
1411  // create title string
1412  OUString aTitle(ReplaceStringHookProc(RID_APPTITLE));
1413 
1414 #ifdef DBG_UTIL
1415  //include buildid in non product builds
1416  aTitle += " [";
1417  aTitle += utl::Bootstrap::getBuildIdData("development");
1418  aTitle += "]";
1419 #endif
1420 
1421  SetDisplayName( aTitle );
1423  pExecGlobals->pPathOptions.reset( new SvtPathOptions);
1425 
1426  xDesktop = css::frame::Desktop::create( xContext );
1427 
1428  // create service for loading SFX (still needed in startup)
1429  pExecGlobals->xGlobalBroadcaster = Reference < css::document::XDocumentEventListener >
1430  ( css::frame::theGlobalEventBroadcaster::get(xContext), UNO_SET_THROW );
1431 
1432  /* ensure existence of a default window that messages can be dispatched to
1433  This is for the benefit of testtool which uses PostUserEvent extensively
1434  and else can deadlock while creating this window from another thread while
1435  the main thread is not yet in the event loop.
1436  */
1438 
1439 #if HAVE_FEATURE_EXTENSIONS
1440  // Check if bundled or shared extensions were added /removed
1441  // and process those extensions (has to be done before checking
1442  // the extension dependencies!
1444  bool bAbort = CheckExtensionDependencies();
1445  if ( bAbort )
1446  return EXIT_FAILURE;
1447 
1448  if (inst_fin == userinstall::CREATED)
1449  {
1451  }
1452 #endif
1453 
1454  // keep a language options instance...
1455  pExecGlobals->pLanguageOptions.reset( new SvtLanguageOptions(true));
1456 
1457  css::document::DocumentEvent aEvent;
1458  aEvent.EventName = "OnStartApp";
1459  pExecGlobals->xGlobalBroadcaster->documentEventOccured(aEvent);
1460 
1462 
1463  // Backing Component
1464  bool bCrashed = false;
1465  bool bExistsRecoveryData = false;
1466  bool bExistsSessionData = false;
1467 
1468  impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
1469 
1470  OUString pidfileName = rCmdLineArgs.GetPidfileName();
1471  if ( !pidfileName.isEmpty() )
1472  {
1473  OUString pidfileURL;
1474 
1475  if ( osl_getFileURLFromSystemPath(pidfileName.pData, &pidfileURL.pData) == osl_File_E_None )
1476  {
1477  osl::File pidfile( pidfileURL );
1478  osl::FileBase::RC rc;
1479 
1480  osl::File::remove( pidfileURL );
1481  if ( (rc = pidfile.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create ) ) == osl::File::E_None )
1482  {
1483  OString pid( OString::number( GETPID() ) );
1484  sal_uInt64 written = 0;
1485  if ( pidfile.write(pid.getStr(), pid.getLength(), written) != osl::File::E_None )
1486  {
1487  SAL_WARN("desktop.app", "cannot write pidfile " << pidfile.getURL());
1488  }
1489  pidfile.close();
1490  }
1491  else
1492  {
1493  SAL_WARN("desktop.app", "cannot open pidfile " << pidfile.getURL() << rc);
1494  }
1495  }
1496  else
1497  {
1498  SAL_WARN("desktop.app", "cannot get pidfile URL from path" << pidfileName);
1499  }
1500  }
1501 
1502  if ( rCmdLineArgs.IsHeadless() || rCmdLineArgs.IsEventTesting() )
1503  {
1504  // Ensure that we use not the system file dialogs as
1505  // headless mode relies on Application::EnableHeadlessMode()
1506  // which does only work for VCL dialogs!!
1507  SvtMiscOptions aMiscOptions;
1508  pExecGlobals->bUseSystemFileDialog = aMiscOptions.UseSystemFileDialog();
1509  aMiscOptions.SetUseSystemFileDialog( false );
1510  }
1511 
1512  pExecGlobals->bRestartRequested = xRestartManager->isRestartRequested(
1513  true);
1514  if ( !pExecGlobals->bRestartRequested )
1515  {
1516  if ((!rCmdLineArgs.WantsToLoadDocument() && !rCmdLineArgs.IsInvisible() && !rCmdLineArgs.IsHeadless() && !rCmdLineArgs.IsQuickstart()) &&
1518  (!bExistsRecoveryData ) &&
1519  (!bExistsSessionData ) &&
1520  (!Application::AnyInput( VclInputFlags::APPEVENT ) ))
1521  {
1522  ShowBackingComponent(this);
1523  }
1524  }
1525  }
1526  catch ( const css::lang::WrappedTargetException& wte )
1527  {
1528  css::uno::Exception te;
1529  wte.TargetException >>= te;
1530  FatalError( MakeStartupConfigAccessErrorMessage(wte.Message + te.Message) );
1531  }
1532  catch ( const css::uno::Exception& e )
1533  {
1534  FatalError( MakeStartupErrorMessage(e.Message) );
1535  }
1537 
1539 
1540  SvtTabAppearanceCfg aAppearanceCfg;
1542  aAppearanceCfg.SetApplicationDefaults( this );
1543  SvtAccessibilityOptions aOptions;
1544  aOptions.SetVCLSettings();
1546 
1547  if ( !pExecGlobals->bRestartRequested )
1548  {
1549  Application::SetFilterHdl( LINK( this, Desktop, ImplInitFilterHdl ) );
1550 
1551  // Preload function depends on an initialized sfx application!
1553 
1554  // use system window dialogs
1555  Application::SetSystemWindowMode( SystemWindowFlags::DIALOG );
1556 
1558 
1559  if ( !rCmdLineArgs.IsInvisible() &&
1560  !rCmdLineArgs.IsNoQuickstart() )
1561  InitializeQuickstartMode( xContext );
1562 
1563  try
1564  {
1565  if ( xDesktop.is() )
1566  xDesktop->addTerminateListener( new RequestHandlerController );
1568  }
1569  catch ( const css::uno::Exception& e )
1570  {
1571  FatalError( MakeStartupErrorMessage(e.Message) );
1572  }
1573 
1574  // FIXME: move this somewhere sensible.
1575 #if HAVE_FEATURE_OPENCL
1576  CheckOpenCLCompute(xDesktop);
1577 #endif
1578 
1579  // In headless mode, reap the process started by fire_glxtest_process() early in soffice_main
1580  // (desktop/source/app/sofficemain.cxx), in a code block that needs to be covered by the same
1581  // #if condition as this code block:
1582 #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID && !defined(LIBO_HEADLESS) && HAVE_FEATURE_OPENGL
1583  if (rCmdLineArgs.IsHeadless()) {
1585  }
1586 #endif
1587 
1588  // Release solar mutex just before we wait for our client to connect
1589  {
1590  SolarMutexReleaser aReleaser;
1591 
1592  // Post user event to startup first application component window
1593  // We have to send this OpenClients message short before execute() to
1594  // minimize the risk that this message overtakes type detection construction!!
1595  Application::PostUserEvent( LINK( this, Desktop, OpenClients_Impl ) );
1596 
1597  // Post event to enable acceptors
1598  Application::PostUserEvent( LINK( this, Desktop, EnableAcceptors_Impl) );
1599 
1600  // Acquire solar mutex just before we enter our message loop
1601  }
1602 
1603  // call Application::Execute to process messages in vcl message loop
1604  try
1605  {
1606 #if HAVE_FEATURE_JAVA
1607  // The JavaContext contains an interaction handler which is used when
1608  // the creation of a Java Virtual Machine fails
1609  css::uno::ContextLayer layer2(
1610  new svt::JavaContext( css::uno::getCurrentContext() ) );
1611 #endif
1612  // check whether the shutdown is caused by restart just before entering the Execute
1613  pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested ||
1614  xRestartManager->isRestartRequested(true);
1615 
1616  if ( !pExecGlobals->bRestartRequested )
1617  {
1618  // if this run of the office is triggered by restart, some additional actions should be done
1619  DoRestartActionsIfNecessary( !rCmdLineArgs.IsInvisible() && !rCmdLineArgs.IsNoQuickstart() );
1620 
1621  Execute();
1622  }
1623  }
1624  catch(const css::document::CorruptedFilterConfigurationException& exFilterCfg)
1625  {
1627  FatalError( MakeStartupErrorMessage(exFilterCfg.Message) );
1628  }
1629  catch(const css::configuration::CorruptedConfigurationException& exAnyCfg)
1630  {
1632  FatalError( MakeStartupErrorMessage(exAnyCfg.Message) );
1633  }
1634  catch( const css::uno::Exception& exUNO)
1635  {
1637  FatalError( exUNO.Message);
1638  }
1639  catch( const std::exception& exSTD)
1640  {
1642  FatalError(o3tl::runtimeToOUString(exSTD.what()));
1643  }
1644  catch( ...)
1645  {
1647  FatalError( "Caught Unknown Exception: Aborting!");
1648  }
1649  }
1650  else
1651  {
1652  if (xDesktop.is())
1653  xDesktop->terminate();
1654  }
1655  // CAUTION: you do not necessarily get here e.g. on the Mac.
1656  // please put all deinitialization code into doShutdown
1657  return doShutdown();
1658 }
1659 
1661 {
1662  if( ! pExecGlobals )
1663  return EXIT_SUCCESS;
1664 
1665  if (m_aUpdateThread.joinable())
1666  m_aUpdateThread.join();
1667 
1668  pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested ||
1669  OfficeRestartManager::get(comphelper::getProcessComponentContext())->
1670  isRestartRequested(true);
1671  if ( pExecGlobals->bRestartRequested )
1672  SetRestartState();
1673 
1674  // Restore old value
1675  const CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
1676  if ( rCmdLineArgs.IsHeadless() || rCmdLineArgs.IsEventTesting() )
1678 
1679  OUString pidfileName = rCmdLineArgs.GetPidfileName();
1680  if ( !pidfileName.isEmpty() )
1681  {
1682  OUString pidfileURL;
1683 
1684  if ( osl_getFileURLFromSystemPath(pidfileName.pData, &pidfileURL.pData) == osl_File_E_None )
1685  {
1686  if ( osl::File::remove( pidfileURL ) != osl::FileBase::E_None )
1687  {
1688  SAL_WARN("desktop.app", "shutdown: cannot remove pidfile " << pidfileURL);
1689  }
1690  }
1691  else
1692  {
1693  SAL_WARN("desktop.app", "shutdown: cannot get pidfile URL from path" << pidfileName);
1694  }
1695  }
1696 
1697  // remove temp directory
1700 
1701  // flush evtl. configuration changes so that all config files in user
1702  // dir are written
1704 
1705  if (pExecGlobals->bRestartRequested)
1706  {
1707  // a restart is already requested, usually due to a configuration change
1708  // that needs a restart to get active. If this is the case, do not try
1709  // to use SecureUserConfig to safe this still untested new configuration
1710  }
1711  else
1712  {
1713  // Test if SecureUserConfig is active. If yes and we are at this point, regular shutdown
1714  // is in progress and the currently used configuration was working. Try to secure this
1715  // working configuration for later eventually necessary restores
1716  comphelper::BackupFileHelper aBackupFileHelper;
1717 
1718  aBackupFileHelper.tryPush();
1719  aBackupFileHelper.tryPushExtensionInfo();
1720  }
1721 
1722  // The acceptors in the AcceptorMap must be released (in DeregisterServices)
1723  // with the solar mutex unlocked, to avoid deadlock:
1724  {
1725  SolarMutexReleaser aReleaser;
1727 #if HAVE_FEATURE_SCRIPTING
1729 #endif
1730  }
1731 
1732  // be sure that path/language options gets destroyed before
1733  // UCB is deinitialized
1734  pExecGlobals->pLanguageOptions.reset();
1735  pExecGlobals->pPathOptions.reset();
1736 
1738 
1739  bool bRR = pExecGlobals->bRestartRequested;
1740  delete pExecGlobals;
1741  pExecGlobals = nullptr;
1742 
1743  if ( bRR )
1744  {
1745  restartOnMac(true);
1746  if ( m_rSplashScreen.is() )
1747  m_rSplashScreen->reset();
1748 
1750  }
1751  return EXIT_SUCCESS;
1752 }
1753 
1754 IMPL_STATIC_LINK( Desktop, ImplInitFilterHdl, ::ConvertData&, rData, bool )
1755 {
1756  return GraphicFilter::GetGraphicFilter().GetFilterCallback().Call( rData );
1757 }
1758 
1760 {
1761  try
1762  {
1763  css::configuration::theDefaultProvider::get(
1765  return true;
1766  }
1767  catch( css::lang::ServiceNotRegisteredException & e )
1768  {
1771  }
1772  catch( const css::configuration::MissingBootstrapFileException& e )
1773  {
1775  e.BootstrapFileURL ));
1777  }
1778  catch( const css::configuration::InvalidBootstrapFileException& e )
1779  {
1781  e.BootstrapFileURL ));
1783  }
1784  catch( const css::configuration::InstallationIncompleteException& )
1785  {
1786  OUString aVersionFileURL;
1787  OUString aMsg;
1788  utl::Bootstrap::PathStatus aPathStatus = utl::Bootstrap::locateVersionFile( aVersionFileURL );
1789  if ( aPathStatus == utl::Bootstrap::PATH_EXISTS )
1791  else
1793 
1795  }
1796  catch ( const css::configuration::backend::BackendAccessException& exception)
1797  {
1798  // [cm122549] It is assumed in this case that the message
1799  // coming from InitConfiguration (in fact CreateApplicationConf...)
1800  // is suitable for display directly.
1801  FatalError( MakeStartupErrorMessage( exception.Message ) );
1802  }
1803  catch ( const css::configuration::backend::BackendSetupException& exception)
1804  {
1805  // [cm122549] It is assumed in this case that the message
1806  // coming from InitConfiguration (in fact CreateApplicationConf...)
1807  // is suitable for display directly.
1808  FatalError( MakeStartupErrorMessage( exception.Message ) );
1809  }
1810  catch ( const css::configuration::CannotLoadConfigurationException& )
1811  {
1813  OUString() ));
1815  }
1816  catch( const css::uno::Exception& )
1817  {
1819  OUString() ));
1821  }
1822  return false;
1823 }
1824 
1826 {
1827  css::uno::Reference< css::util::XFlushable >(
1828  css::configuration::theDefaultProvider::get(
1830  css::uno::UNO_QUERY_THROW)->flush();
1831 }
1832 
1834 {
1835  try
1836  {
1837  // the shutdown icon sits in the systray and allows the user to keep
1838  // the office instance running for quicker restart
1839  // this will only be activated if --quickstart was specified on cmdline
1840 
1841  bool bQuickstart = shouldLaunchQuickstart();
1842 
1843  // Try to instantiate quickstart service. This service is not mandatory, so
1844  // do nothing if service is not available
1845 
1846  // #i105753# the following if was invented for performance
1847  // unfortunately this broke the Mac behavior which is to always run
1848  // in quickstart mode since Mac applications do not usually quit
1849  // when the last document closes.
1850  // Note that this claim that on macOS we "always run in quickstart mode"
1851  // has nothing to do with (quick) *starting* (i.e. starting automatically
1852  // when the user logs in), though, but with not quitting when no documents
1853  // are open.
1854  #ifndef MACOSX
1855  if ( bQuickstart )
1856  #endif
1857  {
1858  css::office::Quickstart::createStart(rxContext, bQuickstart);
1859  }
1860  return true;
1861  }
1862  catch( const css::uno::Exception& )
1863  {
1864  return false;
1865  }
1866 }
1867 
1869 {
1871  return;
1872 
1873  StyleSettings hStyleSettings = rSettings.GetStyleSettings();
1874  MouseSettings hMouseSettings = rSettings.GetMouseSettings();
1875 
1876  DragFullOptions nDragFullOptions = hStyleSettings.GetDragFullOptions();
1877 
1878  SvtTabAppearanceCfg aAppearanceCfg;
1879  DragMode nDragMode = aAppearanceCfg.GetDragMode();
1880  switch ( nDragMode )
1881  {
1882  case DragMode::FullWindow:
1883  nDragFullOptions |= DragFullOptions::All;
1884  break;
1885  case DragMode::Frame:
1886  nDragFullOptions &= ~DragFullOptions::All;
1887  break;
1888  case DragMode::SystemDep:
1889  default:
1890  break;
1891  }
1892 
1893  MouseFollowFlags nFollow = hMouseSettings.GetFollow();
1894  hMouseSettings.SetFollow( aAppearanceCfg.IsMenuMouseFollow() ? (nFollow|MouseFollowFlags::Menu) : (nFollow&~MouseFollowFlags::Menu));
1895  rSettings.SetMouseSettings(hMouseSettings);
1896 
1897  SvtMenuOptions aMenuOpt;
1898  hStyleSettings.SetUseImagesInMenus(aMenuOpt.GetMenuIconsState());
1899  hStyleSettings.SetContextMenuShortcuts(aMenuOpt.GetContextMenuShortcuts());
1900  hStyleSettings.SetDragFullOptions( nDragFullOptions );
1901  rSettings.SetStyleSettings ( hStyleSettings );
1902 }
1903 
1904 
1905 class ExitTimer : public Timer
1906 {
1907  public:
1909  {
1910  SetTimeout(500);
1911  Start();
1912  }
1913  virtual void Invoke() override
1914  {
1915  exit(42);
1916  }
1917 };
1918 
1919 IMPL_LINK_NOARG(Desktop, OpenClients_Impl, void*, void)
1920 {
1921  try {
1922  // #i114963#
1923  // Enable IPC thread before OpenClients
1924  //
1925  // This is because it is possible for another client to connect during the OpenClients() call.
1926  // This can happen on Windows when document is printed (not opened) and another client wants to print (when printing multiple documents).
1927  // If the IPC thread is enabled after OpenClients, then the client will not be processed because the application will exit after printing. i.e RequestHandler::AreRequestsPending() will always return false
1928  //
1929  // ALSO:
1930  //
1931  // Multiple clients may request simultaneous connections.
1932  // When this server closes down it attempts to recreate the pipe (in RequestHandler::Disable()).
1933  // It's possible that the client has a pending connection request.
1934  // When the IPC thread is not running, this connection locks (because maPipe.accept()) is never called
1936  OpenClients();
1937 
1938  CloseSplashScreen();
1939  CheckFirstRun( );
1940 #ifdef _WIN32
1941  // Registers a COM class factory of the service manager with the windows operating system.
1943  xSMgr->createInstance("com.sun.star.bridge.OleApplicationRegistration");
1944  xSMgr->createInstance("com.sun.star.comp.ole.EmbedServer");
1945 #endif
1946  const char *pExitPostStartup = getenv ("OOO_EXIT_POST_STARTUP");
1947  if (pExitPostStartup && *pExitPostStartup)
1948  new ExitTimer();
1949  } catch (const css::uno::Exception &e) {
1950  Application::Abort( "UNO exception during client open: " + e.Message );
1951  }
1952 }
1953 
1955 {
1956 
1957  const CommandLineArgs& rArgs = GetCommandLineArgs();
1958 
1959  if (!rArgs.IsQuickstart())
1960  {
1961  OUString aHelpModule;
1962  if (rArgs.IsHelpWriter()) {
1963  aHelpModule = "swriter";
1964  } else if (rArgs.IsHelpCalc()) {
1965  aHelpModule = "scalc";
1966  } else if (rArgs.IsHelpDraw()) {
1967  aHelpModule = "sdraw";
1968  } else if (rArgs.IsHelpImpress()) {
1969  aHelpModule = "simpress";
1970  } else if (rArgs.IsHelpBase()) {
1971  aHelpModule = "sdatabase";
1972  } else if (rArgs.IsHelpBasic()) {
1973  aHelpModule = "sbasic";
1974  } else if (rArgs.IsHelpMath()) {
1975  aHelpModule = "smath";
1976  }
1977  if (!aHelpModule.isEmpty()) {
1978  OUString aHelpURL = "vnd.sun.star.help://"
1979  + aHelpModule
1980  + "/start?Language="
1982 #if defined UNX
1983  aHelpURL += "&System=UNX";
1984 #elif defined WNT
1985  aHelpURL += "&System=WIN";
1986 #endif
1987  Application::GetHelp()->Start(aHelpURL, static_cast<const vcl::Window*>(nullptr));
1988  return;
1989  }
1990  }
1991 
1992  // Disable AutoSave feature in case "--norestore" or a similar command line switch is set on the command line.
1993  // The reason behind: AutoSave/EmergencySave/AutoRecovery share the same data.
1994  // But the require that all documents, which are saved as backup should exists inside
1995  // memory. May be this mechanism will be inconsistent if the configuration exists...
1996  // but no document inside memory corresponds to this data.
1997  // Further it's not acceptable to recover such documents without any UI. It can
1998  // need some time, where the user won't see any results and wait for finishing the office startup...
1999  bool bAllowRecoveryAndSessionManagement = ( !rArgs.IsNoRestore() ) && ( !rArgs.IsHeadless() );
2000 
2001 #if !defined ANDROID
2002  // Enter safe mode if requested
2004  handleSafeMode();
2005  }
2006 #endif
2007 
2008 #if HAVE_FEATURE_BREAKPAD
2009  if (crashReportInfoExists())
2010  handleCrashReport();
2011 #endif
2012 
2013  if ( ! bAllowRecoveryAndSessionManagement )
2014  {
2015  try
2016  {
2017  Reference< XDispatch > xRecovery = css::frame::theAutoRecovery::get( ::comphelper::getProcessComponentContext() );
2018  Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create( ::comphelper::getProcessComponentContext() );
2019 
2020  css::util::URL aCmd;
2021  aCmd.Complete = "vnd.sun.star.autorecovery:/disableRecovery";
2022  xParser->parseStrict(aCmd);
2023 
2024  xRecovery->dispatch(aCmd, css::uno::Sequence< css::beans::PropertyValue >());
2025  }
2026  catch(const css::uno::Exception& e)
2027  {
2028  SAL_WARN( "desktop.app", "Could not disable AutoRecovery." << e);
2029  }
2030  }
2031  else
2032  {
2033  bool bCrashed = false;
2034  bool bExistsRecoveryData = false;
2035  bool bExistsSessionData = false;
2036  bool const bDisableRecovery
2037  = getenv("OOO_DISABLE_RECOVERY") != nullptr
2038  || !officecfg::Office::Recovery::RecoveryInfo::Enabled::get();
2039 
2040  impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
2041 
2042  if ( !bDisableRecovery &&
2043  (
2044  bExistsRecoveryData || // => crash with files => recovery
2045  bCrashed // => crash without files => error report
2046  )
2047  )
2048  {
2049  try
2050  {
2051  impl_callRecoveryUI(
2052  false , // false => force recovery instead of emergency save
2053  bExistsRecoveryData);
2054  }
2055  catch(const css::uno::Exception& e)
2056  {
2057  SAL_WARN( "desktop.app", "Error during recovery" << e);
2058  }
2059  }
2060 
2061  Reference< XSessionManagerListener2 > xSessionListener;
2062  try
2063  {
2064  // specifies whether the UI-interaction on Session shutdown is allowed
2065  bool bUIOnSessionShutdownAllowed = officecfg::Office::Recovery::SessionShutdown::DocumentStoreUIEnabled::get();
2066  xSessionListener = SessionListener::createWithOnQuitFlag(
2067  ::comphelper::getProcessComponentContext(), bUIOnSessionShutdownAllowed);
2068  }
2069  catch(const css::uno::Exception& e)
2070  {
2071  SAL_WARN( "desktop.app", "Registration of session listener failed" << e);
2072  }
2073 
2074  if ( !bExistsRecoveryData && xSessionListener.is() )
2075  {
2076  // session management
2077  try
2078  {
2079  xSessionListener->doRestore();
2080  }
2081  catch(const css::uno::Exception& e)
2082  {
2083  SAL_WARN( "desktop.app", "Error in session management" << e);
2084  }
2085  }
2086  }
2087 #if HAVE_FEATURE_BREAKPAD
2089  // write this information here to avoid depending on vcl in the crash reporter lib
2090  CrashReporter::AddKeyValue("Language", Application::GetSettings().GetLanguageTag().getBcp47());
2091 #endif
2092 
2094 
2095  ProcessDocumentsRequest aRequest(rArgs.getCwdUrl());
2096  aRequest.aOpenList = rArgs.GetOpenList();
2097  aRequest.aViewList = rArgs.GetViewList();
2098  aRequest.aStartList = rArgs.GetStartList();
2099  aRequest.aPrintList = rArgs.GetPrintList();
2100  aRequest.aPrintToList = rArgs.GetPrintToList();
2101  aRequest.aPrinterName = rArgs.GetPrinterName();
2102  aRequest.aForceOpenList = rArgs.GetForceOpenList();
2103  aRequest.aForceNewList = rArgs.GetForceNewList();
2104  aRequest.aConversionList = rArgs.GetConversionList();
2105  aRequest.aConversionParams = rArgs.GetConversionParams();
2106  aRequest.aConversionOut = rArgs.GetConversionOut();
2107  aRequest.aImageConversionType = rArgs.GetImageConversionType();
2108  aRequest.aInFilter = rArgs.GetInFilter();
2109  aRequest.bTextCat = rArgs.IsTextCat();
2110  aRequest.bScriptCat = rArgs.IsScriptCat();
2111 
2112  if ( !aRequest.aOpenList.empty() ||
2113  !aRequest.aViewList.empty() ||
2114  !aRequest.aStartList.empty() ||
2115  !aRequest.aPrintList.empty() ||
2116  !aRequest.aForceOpenList.empty() ||
2117  !aRequest.aForceNewList.empty() ||
2118  ( !aRequest.aPrintToList.empty() && !aRequest.aPrinterName.isEmpty() ) ||
2119  !aRequest.aConversionList.empty() )
2120  {
2121  if ( rArgs.HasModuleParam() )
2122  {
2123  SvtModuleOptions aOpt;
2124 
2125  // Support command line parameters to start a module (as preselection)
2127  aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::EFactory::WRITER );
2128  else if ( rArgs.IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
2129  aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::EFactory::CALC );
2130  else if ( rArgs.IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
2131  aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::EFactory::IMPRESS );
2132  else if ( rArgs.IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
2133  aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::EFactory::DRAW );
2134  }
2135 
2136  // check for printing disabled
2137  if( ( !(aRequest.aPrintList.empty() && aRequest.aPrintToList.empty()) )
2139  {
2140  aRequest.aPrintList.clear();
2141  aRequest.aPrintToList.clear();
2142  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
2143  VclMessageType::Warning, VclButtonsType::Ok,
2144  DpResId(STR_ERR_PRINTDISABLED)));
2145  xBox->run();
2146  }
2147 
2148  // Process request
2149  if ( RequestHandler::ExecuteCmdLineRequests(aRequest, false) )
2150  {
2151  // Don't do anything if we have successfully called terminate at desktop:
2152  return;
2153  }
2154  }
2155 
2156  // no default document if a document was loaded by recovery or by command line or if soffice is used as server
2157  Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
2158  Reference< XElementAccess > xList( xDesktop->getFrames(), UNO_QUERY_THROW );
2159  if ( xList->hasElements() )
2160  return;
2161 
2162  if ( rArgs.IsQuickstart() || rArgs.IsInvisible() || Application::AnyInput( VclInputFlags::APPEVENT ) )
2163  // soffice was started as tray icon ...
2164  return;
2165 
2166  OpenDefault();
2167 }
2168 
2170 {
2171  OUString aName;
2172  SvtModuleOptions aOpt;
2173 
2174  const CommandLineArgs& rArgs = GetCommandLineArgs();
2175  if ( rArgs.IsNoDefault() ) return;
2176  if ( rArgs.HasModuleParam() )
2177  {
2178  // Support new command line parameters to start a module
2181  else if ( rArgs.IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
2183  else if ( rArgs.IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
2185  else if ( rArgs.IsBase() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) )
2187  else if ( rArgs.IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
2189  else if ( rArgs.IsMath() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH ) )
2191  else if ( rArgs.IsGlobal() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
2193  else if ( rArgs.IsWeb() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
2195  }
2196 
2197  if ( aName.isEmpty() )
2198  {
2200  {
2201  ShowBackingComponent(nullptr);
2202  return;
2203  }
2204 
2205  // Old way to create a default document
2216  else
2217  return;
2218  }
2219 
2220  ProcessDocumentsRequest aRequest(rArgs.getCwdUrl());
2221  aRequest.aOpenList.push_back(aName);
2222  RequestHandler::ExecuteCmdLineRequests(aRequest, false);
2223 }
2224 
2225 
2226 OUString GetURL_Impl(
2227  const OUString& rName, boost::optional< OUString > const & cwdUrl )
2228 {
2229  // if rName is a vnd.sun.star.script URL do not attempt to parse it
2230  // as INetURLObj does not handle URLs there
2231  if (rName.startsWith("vnd.sun.star.script"))
2232  {
2233  return rName;
2234  }
2235 
2236  // don't touch file urls, those should already be in internal form
2237  // they won't get better here (#112849#)
2238  if (comphelper::isFileUrl(rName))
2239  {
2240  return rName;
2241  }
2242 
2243  if ( rName.startsWith("service:"))
2244  {
2245  return rName;
2246  }
2247 
2248  // Add path separator to these directory and make given URL (rName) absolute by using of current working directory
2249  // Attention: "setFinalSlash()" is necessary for calling "smartRel2Abs()"!!!
2250  // Otherwise last part will be ignored and wrong result will be returned!!!
2251  // "smartRel2Abs()" interpret given URL as file not as path. So he truncate last element to get the base path ...
2252  // But if we add a separator - he doesn't do it anymore.
2253  INetURLObject aObj;
2254  if (cwdUrl) {
2255  aObj.SetURL(*cwdUrl);
2256  aObj.setFinalSlash();
2257  }
2258 
2259  // Use the provided parameters for smartRel2Abs to support the usage of '%' in system paths.
2260  // Otherwise this char won't get encoded and we are not able to load such files later,
2261  bool bWasAbsolute;
2262  INetURLObject aURL = aObj.smartRel2Abs( rName, bWasAbsolute, false, INetURLObject::EncodeMechanism::WasEncoded,
2263  RTL_TEXTENCODING_UTF8, true );
2264  OUString aFileURL = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
2265 
2266  ::osl::FileStatus aStatus( osl_FileStatus_Mask_FileURL );
2267  ::osl::DirectoryItem aItem;
2268  if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
2269  ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
2270  aFileURL = aStatus.getFileURL();
2271 
2272  return aFileURL;
2273 }
2274 
2276 {
2277  switch ( rAppEvent.GetEvent() )
2278  {
2280  // every time an accept parameter is used we create an acceptor
2281  // with the corresponding accept-string
2282  createAcceptor(rAppEvent.GetStringData());
2283  break;
2285  if ( !GetCommandLineArgs().IsInvisible() && !impl_bringToFrontRecoveryUI() )
2286  {
2287  Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2288 
2289  // find active task - the active task is always a visible task
2290  Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext );
2291  Reference< css::frame::XFrame > xTask = xDesktop->getActiveFrame();
2292  if ( !xTask.is() )
2293  {
2294  // get any task if there is no active one
2295  Reference< css::container::XIndexAccess > xList( xDesktop->getFrames(), css::uno::UNO_QUERY );
2296  if ( xList->getCount() > 0 )
2297  xList->getByIndex(0) >>= xTask;
2298  }
2299 
2300  if ( xTask.is() )
2301  {
2302  Reference< css::awt::XTopWindow > xTop( xTask->getContainerWindow(), UNO_QUERY );
2303  xTop->toFront();
2304  }
2305  else
2306  {
2307  // no visible task that could be activated found
2308  Reference< css::awt::XWindow > xContainerWindow;
2309  Reference< XFrame > xBackingFrame = xDesktop->findFrame( "_blank", 0);
2310  if (xBackingFrame.is())
2311  xContainerWindow = xBackingFrame->getContainerWindow();
2312  if (xContainerWindow.is())
2313  {
2314  Reference< XController > xStartModule = StartModule::createWithParentWindow(xContext, xContainerWindow);
2315  Reference< css::awt::XWindow > xBackingWin(xStartModule, UNO_QUERY);
2316  // Attention: You MUST(!) call setComponent() before you call attachFrame().
2317  // Because the backing component set the property "IsBackingMode" of the frame
2318  // to true inside attachFrame(). But setComponent() reset this state every time ...
2319  xBackingFrame->setComponent(xBackingWin, xStartModule);
2320  xStartModule->attachFrame(xBackingFrame);
2321  xContainerWindow->setVisible(true);
2322 
2323  VclPtr<vcl::Window> pCompWindow = VCLUnoHelper::GetWindow(xBackingFrame->getComponentWindow());
2324  if (pCompWindow)
2325  pCompWindow->Update();
2326  }
2327  }
2328  }
2329  break;
2331  {
2332  const CommandLineArgs& rCmdLine = GetCommandLineArgs();
2333  if ( !rCmdLine.IsInvisible() && !rCmdLine.IsTerminateAfterInit() )
2334  {
2335  ProcessDocumentsRequest docsRequest(rCmdLine.getCwdUrl());
2336  std::vector<OUString> const & data(rAppEvent.GetStringsData());
2337  docsRequest.aOpenList.insert(
2338  docsRequest.aOpenList.end(), data.begin(), data.end());
2339  RequestHandler::ExecuteCmdLineRequests(docsRequest, false);
2340  }
2341  }
2342  break;
2344  // start help for a specific URL
2345  Application::GetHelp()->Start(rAppEvent.GetStringData(), static_cast<vcl::Window*>(nullptr));
2346  break;
2348  {
2349  const CommandLineArgs& rCmdLine = GetCommandLineArgs();
2350  if ( !rCmdLine.IsInvisible() && !rCmdLine.IsTerminateAfterInit() )
2351  {
2352  ProcessDocumentsRequest docsRequest(rCmdLine.getCwdUrl());
2353  std::vector<OUString> const & data(rAppEvent.GetStringsData());
2354  docsRequest.aPrintList.insert(
2355  docsRequest.aPrintList.end(), data.begin(), data.end());
2356  RequestHandler::ExecuteCmdLineRequests(docsRequest, false);
2357  }
2358  }
2359  break;
2361  {
2362  Desktop* pD = dynamic_cast<Desktop*>(GetpApp());
2363  OSL_ENSURE( pD, "no desktop ?!?" );
2364  if( pD )
2365  pD->doShutdown();
2366  }
2367  break;
2369  if ( !GetCommandLineArgs().IsInvisible() )
2370  {
2371  // If the office has been started the second time its command line arguments are sent through a pipe
2372  // connection to the first office. We want to reuse the quickstart option for the first office.
2373  // NOTICE: The quickstart service must be initialized inside the "main thread", so we use the
2374  // application events to do this (they are executed inside main thread)!!!
2375  // Don't start quickstart service if the user specified "--invisible" on the command line!
2376  Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2377  css::office::Quickstart::createStart(xContext, true/*Quickstart*/);
2378  }
2379  break;
2381  // ignore all errors here. It's clicking a menu entry only ...
2382  // The user will try it again, in case nothing happens .-)
2383  try
2384  {
2385  Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2386 
2387  Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext );
2388 
2389  Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create(xContext);
2390  css::util::URL aCommand;
2391  if( rAppEvent.GetStringData() == "PREFERENCES" )
2392  aCommand.Complete = ".uno:OptionsTreeDialog";
2393  else if( rAppEvent.GetStringData() == "ABOUT" )
2394  aCommand.Complete = ".uno:About";
2395  if( !aCommand.Complete.isEmpty() )
2396  {
2397  xParser->parseStrict(aCommand);
2398 
2399  css::uno::Reference< css::frame::XDispatch > xDispatch = xDesktop->queryDispatch(aCommand, OUString(), 0);
2400  if (xDispatch.is())
2401  xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >());
2402  }
2403  }
2404  catch(const css::uno::Exception&)
2405  {}
2406  break;
2408  // try to remove corresponding acceptor
2409  destroyAcceptor(rAppEvent.GetStringData());
2410  break;
2411  default:
2412  SAL_WARN( "desktop.app", "this cannot happen");
2413  break;
2414  }
2415 }
2416 
2418 {
2419  const CommandLineArgs &rCmdLine = GetCommandLineArgs();
2420  // Show intro only if this is normal start (e.g. no server, no quickstart, no printing )
2421  if ( !rCmdLine.IsInvisible() &&
2422  !rCmdLine.IsHeadless() &&
2423  !rCmdLine.IsQuickstart() &&
2424  !rCmdLine.IsMinimized() &&
2425  !rCmdLine.IsNoLogo() &&
2426  !rCmdLine.IsTerminateAfterInit() &&
2427  rCmdLine.GetPrintList().empty() &&
2428  rCmdLine.GetPrintToList().empty() &&
2429  rCmdLine.GetConversionList().empty() )
2430  {
2431  // Determine application name from command line parameters
2432  OUString aAppName;
2433  if ( rCmdLine.IsWriter() )
2434  aAppName = "writer";
2435  else if ( rCmdLine.IsCalc() )
2436  aAppName = "calc";
2437  else if ( rCmdLine.IsDraw() )
2438  aAppName = "draw";
2439  else if ( rCmdLine.IsImpress() )
2440  aAppName = "impress";
2441  else if ( rCmdLine.IsBase() )
2442  aAppName = "base";
2443  else if ( rCmdLine.IsGlobal() )
2444  aAppName = "global";
2445  else if ( rCmdLine.IsMath() )
2446  aAppName = "math";
2447  else if ( rCmdLine.IsWeb() )
2448  aAppName = "web";
2449 
2450  // Which splash to use
2451  OUString aSplashService( "com.sun.star.office.SplashScreen" );
2452  if ( rCmdLine.HasSplashPipe() )
2453  aSplashService = "com.sun.star.office.PipeSplashScreen";
2454 
2455  Sequence< Any > aSeq( 2 );
2456  aSeq[0] <<= true; // bVisible
2457  aSeq[1] <<= aAppName;
2458  css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2459  m_rSplashScreen.set(
2460  xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aSplashService, aSeq, xContext),
2461  UNO_QUERY);
2462 
2463  if(m_rSplashScreen.is())
2464  m_rSplashScreen->start("SplashScreen", 100);
2465  }
2466 
2467 }
2468 
2469 void Desktop::SetSplashScreenProgress(sal_Int32 iProgress)
2470 {
2471  if(m_rSplashScreen.is())
2472  {
2473  m_rSplashScreen->setValue(iProgress);
2474  }
2475 }
2476 
2477 void Desktop::SetSplashScreenText( const OUString& rText )
2478 {
2479  if( m_rSplashScreen.is() )
2480  {
2481  m_rSplashScreen->setText( rText );
2482  }
2483 }
2484 
2486 {
2487  if(m_rSplashScreen.is())
2488  {
2489  m_rSplashScreen->end();
2490  m_rSplashScreen = nullptr;
2491  }
2492 }
2493 
2494 
2495 IMPL_STATIC_LINK_NOARG(Desktop, AsyncInitFirstRun, Timer *, void)
2496 {
2497  // does initializations which are necessary for the first run of the office
2498  try
2499  {
2500  Reference< XJobExecutor > xExecutor = theJobExecutor::get( ::comphelper::getProcessComponentContext() );
2501  xExecutor->trigger( "onFirstRunInitialization" );
2502  }
2503  catch(const css::uno::Exception&)
2504  {
2505  css::uno::Any ex( cppu::getCaughtException() );
2506  SAL_WARN( "desktop.app", "Desktop::DoFirstRunInitializations: caught an exception while trigger job executor ... " << exceptionToString(ex) );
2507  }
2508 }
2509 
2511 {
2512  if (GetCommandLineArgs().IsNoDefault())
2513  {
2514  return;
2515  }
2517  Reference< XDesktop2 > xDesktop = css::frame::Desktop::create(xContext);
2518  if (progress != nullptr)
2519  {
2520  progress->SetSplashScreenProgress(60);
2521  }
2522  Reference< XFrame > xBackingFrame = xDesktop->findFrame( "_blank", 0);
2523  Reference< css::awt::XWindow > xContainerWindow;
2524 
2525  if (xBackingFrame.is())
2526  xContainerWindow = xBackingFrame->getContainerWindow();
2527  if (xContainerWindow.is())
2528  {
2529  // set the WindowExtendedStyle::Document style. Normally, this is done by the TaskCreator service when a "_blank"
2530  // frame/window is created. Since we do not use the TaskCreator here, we need to mimic its behavior,
2531  // otherwise documents loaded into this frame will later on miss functionality depending on the style.
2532  VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
2533  SAL_WARN_IF( !pContainerWindow, "desktop.app", "Desktop::Main: no implementation access to the frame's container window!" );
2534  pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WindowExtendedStyle::Document );
2535  if (progress != nullptr)
2536  {
2537  progress->SetSplashScreenProgress(75);
2538  }
2539 
2540  Reference< XController > xStartModule = StartModule::createWithParentWindow( xContext, xContainerWindow);
2541  // Attention: You MUST(!) call setComponent() before you call attachFrame().
2542  // Because the backing component set the property "IsBackingMode" of the frame
2543  // to true inside attachFrame(). But setComponent() reset this state everytimes ...
2544  xBackingFrame->setComponent(Reference< XWindow >(xStartModule, UNO_QUERY), xStartModule);
2545  if (progress != nullptr)
2546  {
2547  progress->SetSplashScreenProgress(100);
2548  }
2549  xStartModule->attachFrame(xBackingFrame);
2550  if (progress != nullptr)
2551  {
2552  progress->CloseSplashScreen();
2553  }
2554  xContainerWindow->setVisible(true);
2555  }
2556 }
2557 
2558 
2560 {
2561  if (officecfg::Office::Common::Misc::FirstRun::get())
2562  {
2563  // use VCL timer, which won't trigger during shutdown if the
2564  // application exits before timeout
2566 
2567 #ifdef _WIN32
2568  // Check if Quickstarter should be started (on Windows only)
2569  WCHAR szValue[8192];
2570  DWORD nValueSize = sizeof(szValue);
2571  HKEY hKey;
2572  if ( ERROR_SUCCESS == RegOpenKeyW( HKEY_LOCAL_MACHINE, L"Software\\LibreOffice", &hKey ) )
2573  {
2574  if ( ERROR_SUCCESS == RegQueryValueExW( hKey, L"RunQuickstartAtFirstStart", nullptr, nullptr, reinterpret_cast<LPBYTE>(szValue), &nValueSize ) )
2575  {
2576  css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2577  css::office::Quickstart::createAutoStart(xContext, true/*Quickstart*/, true/*bAutostart*/);
2578  RegCloseKey( hKey );
2579  }
2580  }
2581 #endif
2582 
2583  std::shared_ptr< comphelper::ConfigurationChanges > batch(
2585  officecfg::Office::Common::Misc::FirstRun::set(false, batch);
2586  batch->commit();
2587  }
2588 }
2589 
2590 }
2591 
2592 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::vector< OUString > const & GetStringsData() const
static ExecuteGlobals * pExecGlobals
Definition: app.cxx:1238
std::unique_ptr< SvtPathOptions > pPathOptions
Definition: app.cxx:1230
Type GetEvent() const
std::vector< OUString > aOpenList
#define GETPID
Definition: app.cxx:149
static void destroyAcceptor(const OUString &aDescription)
Definition: appinit.cxx:206
static bool IsInitialized()
static PathStatus locateUserInstallation(OUString &_rURL)
static void DetachAllDocBasicItems()
std::vector< OUString > GetViewList() const
static void storeConfigItems()
css::uno::Reference< css::task::XStatusIndicator > m_rSplashScreen
Definition: app.hxx:148
static bool ExecuteCmdLineRequests(ProcessDocumentsRequest &, bool noTerminate)
static bool IsInExecute()
static bool InitializeConfiguration()
Definition: app.cxx:1759
void OpenSplashScreen()
Definition: app.cxx:2417
void SetDragFullOptions(DragFullOptions nOptions)
virtual void AppEvent(const ApplicationEvent &rAppEvent) override
Definition: app.cxx:1219
std::string GetValue
bool update()
Definition: updater.cxx:284
void SetStyleSettings(const StyleSettings &rSet)
static void HandleBootstrapPathErrors(::utl::Bootstrap::Status, const OUString &aMsg)
Definition: app.cxx:627
static Help * GetHelp()
void CheckFirstRun()
checks if the office is run the first time
Definition: app.cxx:2559
SFX2_DLLPUBLIC void removeTemporaryHtmlDirectory()
bool HasModuleParam() const
bool IsModuleInstalled(EModule eModule) const
bool IsScriptCat() const
Definition: cmdlineargs.hxx:96
const StyleSettings & GetStyleSettings() const
virtual void DeInit() override
Definition: app.cxx:558
static const AllSettings & GetSettings()
static OUString getAboutBoxProductVersionSuffix()
static VclPtr< vcl::Window > GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
std::vector< OUString > GetStartList() const
const Link< ConvertData &, bool > GetFilterCallback() const
OUString ReplaceStringHookProc(const OUString &rStr)
Definition: app.cxx:398
std::unique_ptr< Lockfile > m_xLockfile
Definition: app.hxx:172
static PathStatus locateBootstrapFile(OUString &_rURL)
void SetBootstrapStatus(BootstrapStatus nStatus)
Definition: app.hxx:108
int doShutdown()
Definition: app.cxx:1660
static OUString CreateErrorMsgString(utl::Bootstrap::FailureCode nFailureCode, const OUString &aFileURL)
Definition: app.cxx:653
tuple args
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
std::vector< OUString > GetPrintToList() const
bool IsHelpImpress() const
Definition: cmdlineargs.hxx:80
static void EnableSafeMode()
std::vector< OUString > const & GetInFilter() const
bool InitAccessBridge()
bool IsHelpMath() const
Definition: cmdlineargs.hxx:82
const OUString & GetConversionParams() const
static oslSignalHandler pSignalHandler
Definition: app.cxx:171
css::uno::Reference< css::deployment::XPackageRegistry > create(css::uno::Reference< css::deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, css::uno::Reference< css::uno::XComponentContext > const &xComponentContext)
Definition: app.cxx:168
void SetSplashScreenProgress(sal_Int32)
Definition: app.cxx:2469
void SetApplicationDefaults(Application *pApp)
bool IsHeadless() const
Definition: cmdlineargs.hxx:69
MouseFollowFlags GetFollow() const
BootstrapError m_aBootstrapError
Definition: app.hxx:168
bool IsMenuMouseFollow() const
bool IsNoDefault() const
Definition: cmdlineargs.hxx:68
static bool IsSafeModeEnabled()
SfxApplication * SfxGetpApp()
IMPL_STATIC_LINK(Desktop, ImplInitFilterHdl,::ConvertData &, rData, bool)
Definition: app.cxx:1754
static OutputDevice * GetDefaultDevice()
bool IsSafeMode() const
Definition: cmdlineargs.hxx:97
const boost::optional< OUString > & getCwdUrl() const
Definition: cmdlineargs.hxx:59
void SetUseSystemFileDialog(bool bSet)
static void ShowBackingComponent(Desktop *progress)
Definition: app.cxx:2510
static OUString getUpdateFileURL()
Definition: updater.cxx:783
std::unique_ptr< SvtLanguageOptions > pLanguageOptions
Definition: app.cxx:1229
void SetReadStringHook(ResHookProc pProc)
bool setFinalSlash()
void GetOptions(SfxItemSet &)
static void SetFilterHdl(const Link< ConvertData &, bool > &rLink)
std::vector< OUString > GetForceNewList() const
Any SAL_CALL getCaughtException()
virtual void OverrideSystemSettings(AllSettings &rSettings) override
Definition: app.cxx:1868
static void FlushConfiguration()
Definition: app.cxx:1825
static void log(const OUString &rMessage)
Definition: updater.cxx:804
char sal_Char
#define RID_APPTITLE
Definition: strings.hxx:13
static std::shared_ptr< ConfigurationChanges > create(css::uno::Reference< css::uno::XComponentContext > const &context=comphelper::getProcessComponentContext())
DragFullOptions GetDragFullOptions() const
TriState GetContextMenuShortcuts() const
static SystemWindowFlags GetSystemWindowMode()
Application * GetpApp()
static void InitApplicationServiceManager()
Definition: appinit.cxx:75
bool WantsToLoadDocument() const
Definition: cmdlineargs.hxx:94
ExceptionCategory
virtual ~Desktop() override
Definition: app.cxx:450
static OUString getProductVersion()
OUString GetConversionOut() const
static void removeUpdateFiles()
Definition: updater.cxx:847
virtual void Init() override
Definition: app.cxx:454
static void DeregisterServices()
Definition: appinit.cxx:227
void Update()
static ThreadPool & getSharedOptimalPool()
MouseFollowFlags
static bool IsEventTestingModeEnabled()
Ref & m_Ref
Definition: app.cxx:990
#define SAL_CONFIGFILE(name)
const OUString & GetUnknown() const
Definition: cmdlineargs.hxx:99
WindowExtendedStyle GetExtendedStyle() const
bool IsHelpBase() const
Definition: cmdlineargs.hxx:81
static PathStatus locateVersionFile(OUString &_rURL)
void RegisterServices(css::uno::Reference< css::uno::XComponentContext > const &context)
Definition: appinit.cxx:98
static void migrateSettingsIfNecessary()
Definition: migration.cxx:198
Timer m_firstRunTimer
Definition: app.hxx:173
bool IsHelpDraw() const
Definition: cmdlineargs.hxx:79
static void ShowNativeErrorBox(const OUString &sTitle, const OUString &sMessage)
static OUString getProductName()
bool IsHelpCalc() const
Definition: cmdlineargs.hxx:78
static void RemoveTemporaryDirectory()
Definition: appinit.cxx:268
std::vector< OUString > GetPrintList() const
static bool AnyInput(VclInputFlags nType=VCL_INPUT_ANY)
static void SetSystemWindowMode(SystemWindowFlags nMode)
static void AddKeyValue(const OUString &rKey, const OUString &rValue)
Definition: crashreport.hxx:72
static void reactOnSafeMode(bool bSafeMode)
static void SetReady(bool bIsReady)
static void reloadData()
static void HandleBootstrapErrors(BootstrapError nError, OUString const &aMessage)
Definition: app.cxx:744
SystemWindowFlags
void SetMouseSettings(const MouseSettings &rSet)
int i
void SetBootstrapError(BootstrapError nError, OUString const &aMessage)
Definition: app.hxx:97
const OUString & GetPrinterName() const
void reap_glxtest_process()
virtual bool Start(const OUString &rHelpId, const vcl::Window *pWindow)
bool IsHelpBasic() const
Definition: cmdlineargs.hxx:83
bool IsTerminateAfterInit() const
Definition: cmdlineargs.hxx:73
static bool hasFlag()
void SetContextMenuShortcuts(TriState eContextMenuShortcuts)
virtual void Start() override
bool HasSplashPipe() const
bool m_bCleanedExtensionCache
Definition: app.hxx:166
static CommandLineArgs & GetCommandLineArgs()
Definition: app.cxx:387
void SetSplashScreenText(const OUString &rText)
Definition: app.cxx:2477
bool IsEventTesting() const
Definition: cmdlineargs.hxx:70
OUString GetFactoryName(EFactory eFactory) const
OUString GetFactoryEmptyDocumentURL(EFactory eFactory) const
void removeTree(OUString const &url)
const OUString & GetPidfileName() const
static OUString getAboutBoxProductVersion()
void SetTimeout(sal_uInt64 nTimeoutMs)
static OUString getUILocale()
static void OpenDefault()
Definition: app.cxx:2169
void SetUseImagesInMenus(TriState eUseImagesInMenus)
IMPL_LINK_NOARG(Desktop, OpenClients_Impl, void *, void)
Definition: app.cxx:1919
static void SetInitialized()
static void createAcceptor(const OUString &aDescription)
Definition: appinit.cxx:141
bool IsInvisible() const
Definition: cmdlineargs.hxx:63
static std::string getIniFileName()
OString exceptionToString(const css::uno::Any &caught)
std::vector< OUString > GetConversionList() const
IMPL_STATIC_LINK_NOARG(Desktop, AsyncInitFirstRun, Timer *, void)
Definition: app.cxx:2495
OUString m_aBootstrapErrorMessage
Definition: app.hxx:169
static OUString getProductKey()
OString OUStringToOString(const OUString &str, ConnectionSettings const *settings)
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
static uno::Reference< css::uno::XComponentContext > xContext
Definition: init.cxx:1604
OUString runtimeToOUString(char const *runtimeString)
std::thread m_aUpdateThread
Definition: app.hxx:174
static void HandleAppEvent(const ApplicationEvent &rAppEvent)
Definition: app.cxx:2275
static Status Enable(bool ipc)
Reference< XMultiServiceFactory > getProcessServiceFactory()
static void CheckOpenCLCompute(const css::uno::Reference< css::frame::XDesktop2 > &)
SfxItemState
static bool putFlag()
static void Abort(const OUString &rErrorText)
#define SAL_WARN_IF(condition, area, stream)
std::vector< OUString > aPrintList
static OUString getVendor()
COMPHELPER_DLLPUBLIC bool isFileUrl(OUString const &url)
void update_checker()
Definition: updater.cxx:662
static void SynchronizeExtensionRepositories(bool bCleanedExtensionCache, Desktop *pDesktop=nullptr)
#define SAL_INFO(area, stream)
bool IsHelpWriter() const
Definition: cmdlineargs.hxx:77
std::vector< OUString > GetOpenList() const
virtual void InitFinished() override
Definition: app.cxx:553
bool IsNoQuickstart() const
Definition: cmdlineargs.hxx:72
static OUString getBuildID()
Definition: updater.cxx:831
void SetFollow(MouseFollowFlags nFollow)
Reference< XComponentContext > getProcessComponentContext()
const MouseSettings & GetMouseSettings() const
void SetInvokeHandler(const Link< Timer *, void > &rLink)
static sal_uInt64 GetSystemTicks()
OUString const & GetImageConversionType() const
static bool InitializeQuickstartMode(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
Definition: app.cxx:1833
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage)
bool IsNoLockcheck() const
Definition: cmdlineargs.hxx:75
bool IsQuickstart() const
Definition: cmdlineargs.hxx:71
OString const aName
TriState GetMenuIconsState() const
static GraphicFilter & GetGraphicFilter()
virtual void Exception(ExceptionCategory nCategory) override
Definition: app.cxx:1148
const MiscSettings & GetMiscSettings() const
Reference< css::document::XDocumentEventListener > xGlobalBroadcaster
Definition: app.cxx:1226
OUString DpResId(const char *pId)
Definition: dp_shared.hxx:38
static bool hasRestartFlag()
oslSignalAction SalMainPipeExchangeSignal_impl(SAL_UNUSED_PARAMETER void *, oslSignalInfo *pInfo)
#define SAL_WARN(area, stream)
bool SetURL(OUString const &rTheAbsURIRef, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
static void OpenClients()
Definition: app.cxx:1954
bool IsMinimized() const
Definition: cmdlineargs.hxx:62
virtual int Main() override
Definition: app.cxx:1240
virtual void Invoke() override
Definition: app.cxx:1913
virtual bool QueryExit() override
Definition: app.cxx:585
bool GetEnableATToolSupport() const
void CloseSplashScreen()
Definition: app.cxx:2485
DragFullOptions
OUString const & GetStringData() const
bool GetDisablePrinting() const
void dispose()
DragMode GetDragMode() const
static bool CheckExtensionDependencies()
bool Lockfile_execWarning(Lockfile const *that)
Definition: lockfile2.cxx:29
BootstrapStatus GetBootstrapStatus() const
Definition: app.hxx:112
static void writeCommonInfo()
Definition: crashreport.cxx:72
static Status checkBootstrapStatus(OUString &_rDiagnosticMessage, FailureCode &_rErrCode)
INetURLObject smartRel2Abs(OUString const &rTheRelURIRef, bool &rWasAbsolute, bool bIgnoreFragment=false, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8, bool bRelativeNonURIs=false, FSysStyle eStyle=FSysStyle::Detect) const
void SetExtendedStyle(WindowExtendedStyle nExtendedStyle)
static OUString getProductExtension()
DragMode
OUString GetURL_Impl(const OUString &rName, boost::optional< OUString > const &cwdUrl)
Definition: app.cxx:2226
static bool removeRestartFlag()
bool UseSystemFileDialog() const
static OUString getBuildIdData(OUString const &_sDefault)
void SetDebugName(const sal_Char *pDebugName)
static void SetDisplayName(const OUString &rDisplayName)
std::vector< OUString > GetForceOpenList() const
static void Execute()
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo
bool IsNoRestore() const
Definition: cmdlineargs.hxx:67