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