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