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 #include <string_view>
32 
33 #include <app.hxx>
34 #include <dp_shared.hxx>
35 #include <strings.hrc>
36 #include "cmdlineargs.hxx"
37 #include <lockfile.hxx>
38 #include "userinstall.hxx"
39 #include "desktopcontext.hxx"
40 #include <migration.hxx>
41 #include "officeipcthread.hxx"
42 #if HAVE_FEATURE_UPDATE_MAR
43 #include "updater.hxx"
44 #endif
45 
46 #include <framework/desktop.hxx>
49 #include <svl/languageoptions.hxx>
50 #include <svtools/javacontext.hxx>
51 #include <com/sun/star/beans/XPropertySet.hpp>
52 #include <com/sun/star/frame/theAutoRecovery.hpp>
53 #include <com/sun/star/frame/theGlobalEventBroadcaster.hpp>
54 #include <com/sun/star/frame/SessionListener.hpp>
55 #include <com/sun/star/frame/XSynchronousDispatch.hpp>
56 #include <com/sun/star/configuration/theDefaultProvider.hpp>
57 #include <com/sun/star/util/XFlushable.hpp>
58 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
59 #include <com/sun/star/frame/Desktop.hpp>
60 #include <com/sun/star/frame/StartModule.hpp>
61 #include <com/sun/star/view/XPrintable.hpp>
62 #include <com/sun/star/awt/XTopWindow.hpp>
63 #include <com/sun/star/util/URLTransformer.hpp>
64 #include <com/sun/star/util/XURLTransformer.hpp>
65 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
66 #include <com/sun/star/configuration/MissingBootstrapFileException.hpp>
67 #include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
68 #include <com/sun/star/configuration/InstallationIncompleteException.hpp>
69 #include <com/sun/star/configuration/backend/BackendSetupException.hpp>
70 #include <com/sun/star/configuration/backend/BackendAccessException.hpp>
71 #include <com/sun/star/task/theJobExecutor.hpp>
72 #include <com/sun/star/task/OfficeRestartManager.hpp>
73 #include <com/sun/star/task/XRestartManager.hpp>
74 #include <com/sun/star/document/XDocumentEventListener.hpp>
75 #include <com/sun/star/office/Quickstart.hpp>
76 #include <com/sun/star/system/XSystemShellExecute.hpp>
77 #include <com/sun/star/system/SystemShellExecute.hpp>
78 #include <com/sun/star/loader/XImplementationLoader.hpp>
79 
80 #include <desktop/exithelper.h>
81 #include <sal/log.hxx>
84 #include <comphelper/fileurl.hxx>
88 #include <uno/current_context.hxx>
89 #include <unotools/bootstrap.hxx>
90 #include <unotools/configmgr.hxx>
93 #include <unotools/ucbhelper.hxx>
94 #include <officecfg/Office/Common.hxx>
95 #include <officecfg/Office/Recovery.hxx>
96 #include <officecfg/Office/Update.hxx>
97 #include <officecfg/Setup.hxx>
98 #include <osl/file.hxx>
99 #include <osl/process.h>
100 #include <rtl/byteseq.hxx>
101 #include <unotools/pathoptions.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(std::u16string_view 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  static constexpr OUStringLiteral SUSPEND_QUICKSTARTVETO = u"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, std::u16string_view 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(OUString::Concat(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 constexpr OUStringLiteral SERVICENAME_CRASHREPORT = u"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  pExecGlobals->bUseSystemFileDialog = officecfg::Office::Common::Misc::UseSystemFileDialog::get();
1497  std::shared_ptr< comphelper::ConfigurationChanges > xChanges(
1499  officecfg::Office::Common::Misc::UseSystemFileDialog::set( false, xChanges );
1500  xChanges->commit();
1501  }
1502 
1503  pExecGlobals->bRestartRequested = xRestartManager->isRestartRequested(true);
1504  if ( !pExecGlobals->bRestartRequested )
1505  {
1506  if ((!rCmdLineArgs.WantsToLoadDocument() && !rCmdLineArgs.IsInvisible() && !rCmdLineArgs.IsHeadless() && !rCmdLineArgs.IsQuickstart()) &&
1508  (!bExistsRecoveryData ) &&
1509  (!bExistsSessionData ) &&
1510  (!Application::AnyInput( VclInputFlags::APPEVENT ) ))
1511  {
1512  ShowBackingComponent(this);
1513  }
1514  }
1515 
1517 
1519 
1520  SvtTabAppearanceCfg aAppearanceCfg;
1522  aAppearanceCfg.SetApplicationDefaults( this );
1523  SvtAccessibilityOptions aOptions;
1524  aOptions.SetVCLSettings();
1526 
1527  if ( !pExecGlobals->bRestartRequested )
1528  {
1529  Application::SetFilterHdl( LINK( this, Desktop, ImplInitFilterHdl ) );
1530 
1531  // Preload function depends on an initialized sfx application!
1533 
1534  // use system window dialogs
1535  Application::SetSystemWindowMode( SystemWindowFlags::DIALOG );
1536 
1538 
1539  if ( !rCmdLineArgs.IsInvisible() &&
1540  !rCmdLineArgs.IsNoQuickstart() )
1541  InitializeQuickstartMode( xContext );
1542 
1543  if ( xDesktop.is() )
1544  xDesktop->addTerminateListener( new RequestHandlerController );
1546 
1547  // FIXME: move this somewhere sensible.
1548 #if HAVE_FEATURE_OPENCL
1549  CheckOpenCLCompute(xDesktop);
1550 #endif
1551 
1552  // Reap the process started by fire_glxtest_process().
1554 
1555  // Release solar mutex just before we wait for our client to connect
1556  {
1557  SolarMutexReleaser aReleaser;
1558 
1559  // Post user event to startup first application component window
1560  // We have to send this OpenClients message short before execute() to
1561  // minimize the risk that this message overtakes type detection construction!!
1562  Application::PostUserEvent( LINK( this, Desktop, OpenClients_Impl ) );
1563 
1564  // Post event to enable acceptors
1565  Application::PostUserEvent( LINK( this, Desktop, EnableAcceptors_Impl) );
1566 
1567  // Acquire solar mutex just before we enter our message loop
1568  }
1569 
1570  // call Application::Execute to process messages in vcl message loop
1571 #if HAVE_FEATURE_JAVA
1572  // The JavaContext contains an interaction handler which is used when
1573  // the creation of a Java Virtual Machine fails
1574  css::uno::ContextLayer layer2(
1575  new svt::JavaContext( css::uno::getCurrentContext() ) );
1576 #endif
1577  // check whether the shutdown is caused by restart just before entering the Execute
1578  pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested ||
1579  xRestartManager->isRestartRequested(true);
1580 
1581  if ( !pExecGlobals->bRestartRequested )
1582  {
1583  // if this run of the office is triggered by restart, some additional actions should be done
1584  DoRestartActionsIfNecessary( !rCmdLineArgs.IsInvisible() && !rCmdLineArgs.IsNoQuickstart() );
1585 
1586  Execute();
1587  }
1588  }
1589  else
1590  {
1591  if (xDesktop.is())
1592  xDesktop->terminate();
1593  }
1594  // CAUTION: you do not necessarily get here e.g. on the Mac.
1595  // please put all deinitialization code into doShutdown
1596  return doShutdown();
1597 }
1598 
1600 {
1601  if( ! pExecGlobals )
1602  return EXIT_SUCCESS;
1603 
1604  if (m_aUpdateThread.joinable())
1605  m_aUpdateThread.join();
1606 
1607  if (pExecGlobals->xJVMloadThread.is())
1608  {
1609  pExecGlobals->xJVMloadThread->join();
1610  pExecGlobals->xJVMloadThread.clear();
1611  }
1612 
1613  pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested ||
1614  OfficeRestartManager::get(comphelper::getProcessComponentContext())->
1615  isRestartRequested(true);
1616  if ( pExecGlobals->bRestartRequested )
1617  SetRestartState();
1618 
1619  // Restore old value
1620  const CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
1621  if ( rCmdLineArgs.IsHeadless() || rCmdLineArgs.IsEventTesting() )
1622  {
1623  std::shared_ptr< comphelper::ConfigurationChanges > xChanges(
1625  officecfg::Office::Common::Misc::UseSystemFileDialog::set( pExecGlobals->bUseSystemFileDialog, xChanges );
1626  xChanges->commit();
1627  }
1628 
1629  OUString pidfileName = rCmdLineArgs.GetPidfileName();
1630  if ( !pidfileName.isEmpty() )
1631  {
1632  OUString pidfileURL;
1633 
1634  if ( osl_getFileURLFromSystemPath(pidfileName.pData, &pidfileURL.pData) == osl_File_E_None )
1635  {
1636  if ( osl::File::remove( pidfileURL ) != osl::FileBase::E_None )
1637  {
1638  SAL_WARN("desktop.app", "shutdown: cannot remove pidfile " << pidfileURL);
1639  }
1640  }
1641  else
1642  {
1643  SAL_WARN("desktop.app", "shutdown: cannot get pidfile URL from path" << pidfileName);
1644  }
1645  }
1646 
1647  // remove temp directory
1650 
1651  // flush evtl. configuration changes so that all config files in user
1652  // dir are written
1654 
1655  if (pExecGlobals->bRestartRequested)
1656  {
1657  // tdf#128523
1658  RemoveIconCacheDirectory();
1659 
1660  // a restart is already requested, usually due to a configuration change
1661  // that needs a restart to get active. If this is the case, do not try
1662  // to use SecureUserConfig to safe this still untested new configuration
1663  }
1664  else
1665  {
1666  // Test if SecureUserConfig is active. If yes and we are at this point, regular shutdown
1667  // is in progress and the currently used configuration was working. Try to secure this
1668  // working configuration for later eventually necessary restores
1669  comphelper::BackupFileHelper aBackupFileHelper;
1670 
1671  aBackupFileHelper.tryPush();
1672  aBackupFileHelper.tryPushExtensionInfo();
1673  }
1674 
1675  // The acceptors in the AcceptorMap must be released (in DeregisterServices)
1676  // with the solar mutex unlocked, to avoid deadlock:
1677  {
1678  SolarMutexReleaser aReleaser;
1680 #if HAVE_FEATURE_SCRIPTING
1682 #endif
1683  }
1684 
1685  // be sure that path/language options gets destroyed before
1686  // UCB is deinitialized
1687  pExecGlobals->pLanguageOptions.reset();
1688  pExecGlobals->pPathOptions.reset();
1689 
1691 
1692  bool bRR = pExecGlobals->bRestartRequested;
1693  delete pExecGlobals;
1694  pExecGlobals = nullptr;
1695 
1696  if ( bRR )
1697  {
1698  restartOnMac(true);
1699  if ( m_rSplashScreen.is() )
1700  m_rSplashScreen->reset();
1701 
1703  }
1704  return EXIT_SUCCESS;
1705 }
1706 
1707 IMPL_STATIC_LINK( Desktop, ImplInitFilterHdl, ::ConvertData&, rData, bool )
1708 {
1710 }
1711 
1713 {
1714  try
1715  {
1716  css::configuration::theDefaultProvider::get(
1718  return true;
1719  }
1720  catch( css::lang::ServiceNotRegisteredException & e )
1721  {
1724  }
1725  catch( const css::configuration::MissingBootstrapFileException& e )
1726  {
1728  e.BootstrapFileURL ));
1730  }
1731  catch( const css::configuration::InvalidBootstrapFileException& e )
1732  {
1734  e.BootstrapFileURL ));
1736  }
1737  catch( const css::configuration::InstallationIncompleteException& )
1738  {
1739  OUString aVersionFileURL;
1740  OUString aMsg;
1741  utl::Bootstrap::PathStatus aPathStatus = utl::Bootstrap::locateVersionFile( aVersionFileURL );
1742  if ( aPathStatus == utl::Bootstrap::PATH_EXISTS )
1744  else
1746 
1748  }
1749  catch ( const css::configuration::backend::BackendAccessException& exception)
1750  {
1751  // [cm122549] It is assumed in this case that the message
1752  // coming from InitConfiguration (in fact CreateApplicationConf...)
1753  // is suitable for display directly.
1754  FatalError( MakeStartupErrorMessage( exception.Message ) );
1755  }
1756  catch ( const css::configuration::backend::BackendSetupException& exception)
1757  {
1758  // [cm122549] It is assumed in this case that the message
1759  // coming from InitConfiguration (in fact CreateApplicationConf...)
1760  // is suitable for display directly.
1761  FatalError( MakeStartupErrorMessage( exception.Message ) );
1762  }
1763  catch ( const css::configuration::CannotLoadConfigurationException& )
1764  {
1766  OUString() ));
1768  }
1769  catch( const css::uno::Exception& )
1770  {
1772  OUString() ));
1774  }
1775  return false;
1776 }
1777 
1779 {
1780  css::uno::Reference< css::util::XFlushable >(
1781  css::configuration::theDefaultProvider::get(
1783  css::uno::UNO_QUERY_THROW)->flush();
1784 }
1785 
1787 {
1788  try
1789  {
1790  // the shutdown icon sits in the systray and allows the user to keep
1791  // the office instance running for quicker restart
1792  // this will only be activated if --quickstart was specified on cmdline
1793 
1794  bool bQuickstart = shouldLaunchQuickstart();
1795 
1796  // Try to instantiate quickstart service. This service is not mandatory, so
1797  // do nothing if service is not available
1798 
1799  // #i105753# the following if was invented for performance
1800  // unfortunately this broke the Mac behavior which is to always run
1801  // in quickstart mode since Mac applications do not usually quit
1802  // when the last document closes.
1803  // Note that this claim that on macOS we "always run in quickstart mode"
1804  // has nothing to do with (quick) *starting* (i.e. starting automatically
1805  // when the user logs in), though, but with not quitting when no documents
1806  // are open.
1807  #ifndef MACOSX
1808  if ( bQuickstart )
1809  #endif
1810  {
1811  css::office::Quickstart::createStart(rxContext, bQuickstart);
1812  }
1813  return true;
1814  }
1815  catch( const css::uno::Exception& )
1816  {
1817  return false;
1818  }
1819 }
1820 
1822 {
1824  return;
1825 
1826  StyleSettings hStyleSettings = rSettings.GetStyleSettings();
1827  MouseSettings hMouseSettings = rSettings.GetMouseSettings();
1828 
1829  DragFullOptions nDragFullOptions = hStyleSettings.GetDragFullOptions();
1830 
1831  SvtTabAppearanceCfg aAppearanceCfg;
1832  DragMode nDragMode = aAppearanceCfg.GetDragMode();
1833  switch ( nDragMode )
1834  {
1835  case DragMode::FullWindow:
1836  nDragFullOptions |= DragFullOptions::All;
1837  break;
1838  case DragMode::Frame:
1839  nDragFullOptions &= ~DragFullOptions::All;
1840  break;
1841  case DragMode::SystemDep:
1842  default:
1843  break;
1844  }
1845 
1846  MouseFollowFlags nFollow = hMouseSettings.GetFollow();
1847  hMouseSettings.SetFollow( aAppearanceCfg.IsMenuMouseFollow() ? (nFollow|MouseFollowFlags::Menu) : (nFollow&~MouseFollowFlags::Menu));
1848  rSettings.SetMouseSettings(hMouseSettings);
1849 
1850  SvtMenuOptions aMenuOpt;
1851  hStyleSettings.SetUseImagesInMenus(aMenuOpt.GetMenuIconsState());
1852  hStyleSettings.SetContextMenuShortcuts(aMenuOpt.GetContextMenuShortcuts());
1853  hStyleSettings.SetDragFullOptions( nDragFullOptions );
1854  rSettings.SetStyleSettings ( hStyleSettings );
1855 }
1856 
1857 namespace {
1858 
1859 class ExitTimer : public Timer
1860 {
1861  public:
1862  ExitTimer()
1863  {
1864  SetTimeout(500);
1865  Start();
1866  }
1867  virtual void Invoke() override
1868  {
1869  _exit(42);
1870  }
1871 };
1872 
1873 }
1874 
1875 IMPL_LINK_NOARG(Desktop, OpenClients_Impl, void*, void)
1876 {
1877  // #i114963#
1878  // Enable IPC thread before OpenClients
1879  //
1880  // This is because it is possible for another client to connect during the OpenClients() call.
1881  // This can happen on Windows when document is printed (not opened) and another client wants to print (when printing multiple documents).
1882  // 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
1883  //
1884  // ALSO:
1885  //
1886  // Multiple clients may request simultaneous connections.
1887  // When this server closes down it attempts to recreate the pipe (in RequestHandler::Disable()).
1888  // It's possible that the client has a pending connection request.
1889  // When the IPC thread is not running, this connection locks (because maPipe.accept()) is never called
1891  OpenClients();
1892 
1893  CloseSplashScreen();
1894  CheckFirstRun( );
1895 #ifdef _WIN32
1896  // Registers a COM class factory of the service manager with the windows operating system.
1897  Reference< XMultiServiceFactory > xSMgr= comphelper::getProcessServiceFactory();
1898  xSMgr->createInstance("com.sun.star.bridge.OleApplicationRegistration");
1899  xSMgr->createInstance("com.sun.star.comp.ole.EmbedServer");
1900 #endif
1901  const char *pExitPostStartup = getenv ("OOO_EXIT_POST_STARTUP");
1902  if (pExitPostStartup && *pExitPostStartup)
1903  new ExitTimer();
1904 }
1905 
1907 {
1908 
1909  const CommandLineArgs& rArgs = GetCommandLineArgs();
1910 
1911  if (!rArgs.IsQuickstart())
1912  {
1913  OUString aHelpModule;
1914  if (rArgs.IsHelpWriter()) {
1915  aHelpModule = "swriter";
1916  } else if (rArgs.IsHelpCalc()) {
1917  aHelpModule = "scalc";
1918  } else if (rArgs.IsHelpDraw()) {
1919  aHelpModule = "sdraw";
1920  } else if (rArgs.IsHelpImpress()) {
1921  aHelpModule = "simpress";
1922  } else if (rArgs.IsHelpBase()) {
1923  aHelpModule = "sdatabase";
1924  } else if (rArgs.IsHelpBasic()) {
1925  aHelpModule = "sbasic";
1926  } else if (rArgs.IsHelpMath()) {
1927  aHelpModule = "smath";
1928  }
1929  if (!aHelpModule.isEmpty()) {
1930  OUString aHelpURL = "vnd.sun.star.help://"
1931  + aHelpModule
1932  + "/start?Language="
1934 #if defined UNX
1935  aHelpURL += "&System=UNX";
1936 #elif defined _WIN32
1937  aHelpURL += "&System=WIN";
1938 #endif
1939  Application::GetHelp()->Start(aHelpURL, static_cast<const vcl::Window*>(nullptr));
1940  return;
1941  }
1942  }
1943 
1944  // Disable AutoSave feature in case "--norestore" or a similar command line switch is set on the command line.
1945  // The reason behind: AutoSave/EmergencySave/AutoRecovery share the same data.
1946  // But the require that all documents, which are saved as backup should exists inside
1947  // memory. May be this mechanism will be inconsistent if the configuration exists...
1948  // but no document inside memory corresponds to this data.
1949  // Further it's not acceptable to recover such documents without any UI. It can
1950  // need some time, where the user won't see any results and wait for finishing the office startup...
1951  bool bAllowRecoveryAndSessionManagement = ( !rArgs.IsNoRestore() ) && ( !rArgs.IsHeadless() );
1952 
1953 #if !defined ANDROID
1954  // Enter safe mode if requested
1956  handleSafeMode();
1957  }
1958 #endif
1959 
1960 #if HAVE_FEATURE_BREAKPAD
1961  if (officecfg::Office::Common::Misc::CrashReport::get() && CrashReporter::crashReportInfoExists())
1962  handleCrashReport();
1963 #endif
1964 
1965  if ( ! bAllowRecoveryAndSessionManagement )
1966  {
1967  try
1968  {
1969  Reference< XDispatch > xRecovery = css::frame::theAutoRecovery::get( ::comphelper::getProcessComponentContext() );
1970  Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create( ::comphelper::getProcessComponentContext() );
1971 
1972  css::util::URL aCmd;
1973  aCmd.Complete = "vnd.sun.star.autorecovery:/disableRecovery";
1974  xParser->parseStrict(aCmd);
1975 
1976  xRecovery->dispatch(aCmd, css::uno::Sequence< css::beans::PropertyValue >());
1977  }
1978  catch(const css::uno::Exception&)
1979  {
1980  TOOLS_WARN_EXCEPTION( "desktop.app", "Could not disable AutoRecovery.");
1981  }
1982  }
1983  else
1984  {
1985  bool bCrashed = false;
1986  bool bExistsRecoveryData = false;
1987  bool bExistsSessionData = false;
1988  bool const bDisableRecovery
1989  = getenv("OOO_DISABLE_RECOVERY") != nullptr
1990  || !officecfg::Office::Recovery::RecoveryInfo::Enabled::get();
1991 
1992  impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
1993 
1994  if ( !bDisableRecovery &&
1995  (
1996  bExistsRecoveryData || // => crash with files => recovery
1997  bCrashed // => crash without files => error report
1998  )
1999  )
2000  {
2001  try
2002  {
2003  impl_callRecoveryUI(
2004  false , // false => force recovery instead of emergency save
2005  bExistsRecoveryData);
2006  }
2007  catch(const css::uno::Exception&)
2008  {
2009  TOOLS_WARN_EXCEPTION( "desktop.app", "Error during recovery");
2010  }
2011  }
2012 
2013  Reference< XSessionManagerListener2 > xSessionListener;
2014  try
2015  {
2016  // specifies whether the UI-interaction on Session shutdown is allowed
2017  bool bUIOnSessionShutdownAllowed = officecfg::Office::Recovery::SessionShutdown::DocumentStoreUIEnabled::get();
2018  xSessionListener = SessionListener::createWithOnQuitFlag(
2019  ::comphelper::getProcessComponentContext(), bUIOnSessionShutdownAllowed);
2020  }
2021  catch(const css::uno::Exception&)
2022  {
2023  TOOLS_WARN_EXCEPTION( "desktop.app", "Registration of session listener failed");
2024  }
2025 
2026  if ( !bExistsRecoveryData && xSessionListener.is() )
2027  {
2028  // session management
2029  try
2030  {
2031  xSessionListener->doRestore();
2032  }
2033  catch(const css::uno::Exception&)
2034  {
2035  TOOLS_WARN_EXCEPTION( "desktop.app", "Error in session management");
2036  }
2037  }
2038  }
2039 
2040  // write this information here to avoid depending on vcl in the crash reporter lib
2041  CrashReporter::addKeyValue("Language", Application::GetSettings().GetLanguageTag().getBcp47(), CrashReporter::Create);
2042 
2044 
2045  ProcessDocumentsRequest aRequest(rArgs.getCwdUrl());
2046  aRequest.aOpenList = rArgs.GetOpenList();
2047  aRequest.aViewList = rArgs.GetViewList();
2048  aRequest.aStartList = rArgs.GetStartList();
2049  aRequest.aPrintList = rArgs.GetPrintList();
2050  aRequest.aPrintToList = rArgs.GetPrintToList();
2051  aRequest.aPrinterName = rArgs.GetPrinterName();
2052  aRequest.aForceOpenList = rArgs.GetForceOpenList();
2053  aRequest.aForceNewList = rArgs.GetForceNewList();
2054  aRequest.aConversionList = rArgs.GetConversionList();
2055  aRequest.aConversionParams = rArgs.GetConversionParams();
2056  aRequest.aConversionOut = rArgs.GetConversionOut();
2057  aRequest.aImageConversionType = rArgs.GetImageConversionType();
2058  aRequest.aInFilter = rArgs.GetInFilter();
2059  aRequest.bTextCat = rArgs.IsTextCat();
2060  aRequest.bScriptCat = rArgs.IsScriptCat();
2061 
2062  if ( !aRequest.aOpenList.empty() ||
2063  !aRequest.aViewList.empty() ||
2064  !aRequest.aStartList.empty() ||
2065  !aRequest.aPrintList.empty() ||
2066  !aRequest.aForceOpenList.empty() ||
2067  !aRequest.aForceNewList.empty() ||
2068  ( !aRequest.aPrintToList.empty() && !aRequest.aPrinterName.isEmpty() ) ||
2069  !aRequest.aConversionList.empty() )
2070  {
2071  if ( rArgs.HasModuleParam() )
2072  {
2073  SvtModuleOptions aOpt;
2074 
2075  // Support command line parameters to start a module (as preselection)
2077  aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::EFactory::WRITER );
2078  else if ( rArgs.IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
2079  aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::EFactory::CALC );
2080  else if ( rArgs.IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
2081  aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::EFactory::IMPRESS );
2082  else if ( rArgs.IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
2083  aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::EFactory::DRAW );
2084  }
2085 
2086  // check for printing disabled
2087  if( ( !(aRequest.aPrintList.empty() && aRequest.aPrintToList.empty()) )
2089  {
2090  aRequest.aPrintList.clear();
2091  aRequest.aPrintToList.clear();
2092  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
2093  VclMessageType::Warning, VclButtonsType::Ok,
2094  DpResId(STR_ERR_PRINTDISABLED)));
2095  xBox->run();
2096  }
2097 
2098  // Process request
2099  if ( RequestHandler::ExecuteCmdLineRequests(aRequest, false) )
2100  {
2101  // Don't do anything if we have successfully called terminate at desktop:
2102  return;
2103  }
2104  }
2105 
2106  // no default document if a document was loaded by recovery or by command line or if soffice is used as server
2107  Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
2108  Reference< XElementAccess > xList( xDesktop->getFrames(), UNO_QUERY_THROW );
2109  if ( xList->hasElements() )
2110  return;
2111 
2112  if ( rArgs.IsQuickstart() || rArgs.IsInvisible() || Application::AnyInput( VclInputFlags::APPEVENT ) )
2113  // soffice was started as tray icon ...
2114  return;
2115 
2116  OpenDefault();
2117 }
2118 
2120 {
2121  OUString aName;
2122  SvtModuleOptions aOpt;
2123 
2124  const CommandLineArgs& rArgs = GetCommandLineArgs();
2125  if ( rArgs.IsNoDefault() ) return;
2126  if ( rArgs.HasModuleParam() )
2127  {
2128  // Support new command line parameters to start a module
2131  else if ( rArgs.IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
2133  else if ( rArgs.IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
2135  else if ( rArgs.IsBase() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) )
2137  else if ( rArgs.IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
2139  else if ( rArgs.IsMath() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH ) )
2141  else if ( rArgs.IsGlobal() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
2143  else if ( rArgs.IsWeb() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
2145  }
2146 
2147  if ( aName.isEmpty() )
2148  {
2150  {
2151  ShowBackingComponent(nullptr);
2152  return;
2153  }
2154 
2155  // Old way to create a default document
2166  else
2167  return;
2168  }
2169 
2170  ProcessDocumentsRequest aRequest(rArgs.getCwdUrl());
2171  aRequest.aOpenList.push_back(aName);
2172  RequestHandler::ExecuteCmdLineRequests(aRequest, false);
2173 }
2174 
2175 
2176 OUString GetURL_Impl(
2177  const OUString& rName, std::optional< OUString > const & cwdUrl )
2178 {
2179  // if rName is a vnd.sun.star.script URL do not attempt to parse it
2180  // as INetURLObj does not handle URLs there
2181  if (rName.startsWith("vnd.sun.star.script"))
2182  {
2183  return rName;
2184  }
2185 
2186  // don't touch file urls, those should already be in internal form
2187  // they won't get better here (#112849#)
2188  if (comphelper::isFileUrl(rName))
2189  {
2190  return rName;
2191  }
2192 
2193  if ( rName.startsWith("service:"))
2194  {
2195  return rName;
2196  }
2197 
2198  // Add path separator to these directory and make given URL (rName) absolute by using of current working directory
2199  // Attention: "setFinalSlash()" is necessary for calling "smartRel2Abs()"!!!
2200  // Otherwise last part will be ignored and wrong result will be returned!!!
2201  // "smartRel2Abs()" interpret given URL as file not as path. So he truncate last element to get the base path ...
2202  // But if we add a separator - he doesn't do it anymore.
2203  INetURLObject aObj;
2204  if (cwdUrl) {
2205  aObj.SetURL(*cwdUrl);
2206  aObj.setFinalSlash();
2207  }
2208 
2209  // Use the provided parameters for smartRel2Abs to support the usage of '%' in system paths.
2210  // Otherwise this char won't get encoded and we are not able to load such files later,
2211  bool bWasAbsolute;
2212  INetURLObject aURL = aObj.smartRel2Abs( rName, bWasAbsolute, false, INetURLObject::EncodeMechanism::WasEncoded,
2213  RTL_TEXTENCODING_UTF8, true );
2214  OUString aFileURL = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
2215 
2216  ::osl::FileStatus aStatus( osl_FileStatus_Mask_FileURL );
2217  ::osl::DirectoryItem aItem;
2218  if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
2219  ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
2220  aFileURL = aStatus.getFileURL();
2221 
2222  return aFileURL;
2223 }
2224 
2226 {
2227  switch ( rAppEvent.GetEvent() )
2228  {
2230  // every time an accept parameter is used we create an acceptor
2231  // with the corresponding accept-string
2232  createAcceptor(rAppEvent.GetStringData());
2233  break;
2235  if ( !GetCommandLineArgs().IsInvisible() && !impl_bringToFrontRecoveryUI() )
2236  {
2237  Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2238 
2239  // find active task - the active task is always a visible task
2240  Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext );
2241  Reference< css::frame::XFrame > xTask = xDesktop->getActiveFrame();
2242  if ( !xTask.is() )
2243  {
2244  // get any task if there is no active one
2245  Reference< css::container::XIndexAccess > xList = xDesktop->getFrames();
2246  if ( xList->getCount() > 0 )
2247  xList->getByIndex(0) >>= xTask;
2248  }
2249 
2250  if ( xTask.is() )
2251  {
2252  Reference< css::awt::XTopWindow > xTop( xTask->getContainerWindow(), UNO_QUERY );
2253  xTop->toFront();
2254  }
2255  else
2256  {
2257  // no visible task that could be activated found
2258  Reference< css::awt::XWindow > xContainerWindow;
2259  Reference< XFrame > xBackingFrame = xDesktop->findFrame( "_blank", 0);
2260  if (xBackingFrame.is())
2261  xContainerWindow = xBackingFrame->getContainerWindow();
2262  if (xContainerWindow.is())
2263  {
2264  Reference< XController > xStartModule = StartModule::createWithParentWindow(xContext, xContainerWindow);
2265  Reference< css::awt::XWindow > xBackingWin(xStartModule, UNO_QUERY);
2266  // Attention: You MUST(!) call setComponent() before you call attachFrame().
2267  // Because the backing component set the property "IsBackingMode" of the frame
2268  // to true inside attachFrame(). But setComponent() reset this state every time ...
2269  xBackingFrame->setComponent(xBackingWin, xStartModule);
2270  xStartModule->attachFrame(xBackingFrame);
2271  xContainerWindow->setVisible(true);
2272 
2273  VclPtr<vcl::Window> pCompWindow = VCLUnoHelper::GetWindow(xBackingFrame->getComponentWindow());
2274  if (pCompWindow)
2275  pCompWindow->PaintImmediately();
2276  }
2277  }
2278  }
2279  break;
2281  {
2282  const CommandLineArgs& rCmdLine = GetCommandLineArgs();
2283  if ( !rCmdLine.IsInvisible() && !rCmdLine.IsTerminateAfterInit() )
2284  {
2285  ProcessDocumentsRequest docsRequest(rCmdLine.getCwdUrl());
2286  std::vector<OUString> const & data(rAppEvent.GetStringsData());
2287  docsRequest.aOpenList.insert(
2288  docsRequest.aOpenList.end(), data.begin(), data.end());
2289  RequestHandler::ExecuteCmdLineRequests(docsRequest, false);
2290  }
2291  }
2292  break;
2294  // start help for a specific URL
2295  Application::GetHelp()->Start(rAppEvent.GetStringData(), static_cast<vcl::Window*>(nullptr));
2296  break;
2298  {
2299  const CommandLineArgs& rCmdLine = GetCommandLineArgs();
2300  if ( !rCmdLine.IsInvisible() && !rCmdLine.IsTerminateAfterInit() )
2301  {
2302  ProcessDocumentsRequest docsRequest(rCmdLine.getCwdUrl());
2303  std::vector<OUString> const & data(rAppEvent.GetStringsData());
2304  docsRequest.aPrintList.insert(
2305  docsRequest.aPrintList.end(), data.begin(), data.end());
2306  RequestHandler::ExecuteCmdLineRequests(docsRequest, false);
2307  }
2308  }
2309  break;
2311  {
2312  Desktop* pD = dynamic_cast<Desktop*>(GetpApp());
2313  OSL_ENSURE( pD, "no desktop ?!?" );
2314  if( pD )
2315  pD->doShutdown();
2316  }
2317  break;
2319  if ( !GetCommandLineArgs().IsInvisible() )
2320  {
2321  // If the office has been started the second time its command line arguments are sent through a pipe
2322  // connection to the first office. We want to reuse the quickstart option for the first office.
2323  // NOTICE: The quickstart service must be initialized inside the "main thread", so we use the
2324  // application events to do this (they are executed inside main thread)!!!
2325  // Don't start quickstart service if the user specified "--invisible" on the command line!
2326  Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2327  css::office::Quickstart::createStart(xContext, true/*Quickstart*/);
2328  }
2329  break;
2331  // This is only used on macOS, and only for About or Preferences.
2332  // Ignore all errors here. It's clicking a menu entry only ...
2333  // The user will try it again, in case nothing happens .-)
2334  try
2335  {
2336  Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2337 
2338  Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext );
2339 
2340  Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create(xContext);
2341  css::util::URL aCommand;
2342  if( rAppEvent.GetStringData() == "PREFERENCES" )
2343  aCommand.Complete = ".uno:OptionsTreeDialog";
2344  else if( rAppEvent.GetStringData() == "ABOUT" )
2345  aCommand.Complete = ".uno:About";
2346  if( !aCommand.Complete.isEmpty() )
2347  {
2348  xParser->parseStrict(aCommand);
2349 
2350  css::uno::Reference< css::frame::XDispatch > xDispatch = xDesktop->queryDispatch(aCommand, OUString(), 0);
2351  if (xDispatch.is())
2352  xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >());
2353  }
2354  }
2355  catch(const css::uno::Exception&)
2356  {
2357  TOOLS_WARN_EXCEPTION("desktop.app", "exception thrown by dialog");
2358  }
2359  break;
2361  // try to remove corresponding acceptor
2362  destroyAcceptor(rAppEvent.GetStringData());
2363  break;
2364  default:
2365  SAL_WARN( "desktop.app", "this cannot happen");
2366  break;
2367  }
2368 }
2369 
2371 {
2372  const CommandLineArgs &rCmdLine = GetCommandLineArgs();
2373  // Show intro only if this is normal start (e.g. no server, no quickstart, no printing )
2374  if ( !(!rCmdLine.IsInvisible() &&
2375  !rCmdLine.IsHeadless() &&
2376  !rCmdLine.IsQuickstart() &&
2377  !rCmdLine.IsMinimized() &&
2378  !rCmdLine.IsNoLogo() &&
2379  !rCmdLine.IsTerminateAfterInit() &&
2380  rCmdLine.GetPrintList().empty() &&
2381  rCmdLine.GetPrintToList().empty() &&
2382  rCmdLine.GetConversionList().empty()) )
2383  return;
2384 
2385  // Determine application name from command line parameters
2386  OUString aAppName;
2387  if ( rCmdLine.IsWriter() )
2388  aAppName = "writer";
2389  else if ( rCmdLine.IsCalc() )
2390  aAppName = "calc";
2391  else if ( rCmdLine.IsDraw() )
2392  aAppName = "draw";
2393  else if ( rCmdLine.IsImpress() )
2394  aAppName = "impress";
2395  else if ( rCmdLine.IsBase() )
2396  aAppName = "base";
2397  else if ( rCmdLine.IsGlobal() )
2398  aAppName = "global";
2399  else if ( rCmdLine.IsMath() )
2400  aAppName = "math";
2401  else if ( rCmdLine.IsWeb() )
2402  aAppName = "web";
2403 
2404  // Which splash to use
2405  OUString aSplashService( "com.sun.star.office.SplashScreen" );
2406  if ( rCmdLine.HasSplashPipe() )
2407  aSplashService = "com.sun.star.office.PipeSplashScreen";
2408 
2409  Sequence< Any > aSeq( 2 );
2410  aSeq[0] <<= true; // bVisible
2411  aSeq[1] <<= aAppName;
2412  css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2413  m_rSplashScreen.set(
2414  xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aSplashService, aSeq, xContext),
2415  UNO_QUERY);
2416 
2417  if(m_rSplashScreen.is())
2418  m_rSplashScreen->start("SplashScreen", 100);
2419 
2420 }
2421 
2422 void Desktop::SetSplashScreenProgress(sal_Int32 iProgress)
2423 {
2424  if(m_rSplashScreen.is())
2425  {
2426  m_rSplashScreen->setValue(iProgress);
2427  }
2428 }
2429 
2430 void Desktop::SetSplashScreenText( const OUString& rText )
2431 {
2432  if( m_rSplashScreen.is() )
2433  {
2434  m_rSplashScreen->setText( rText );
2435  }
2436 }
2437 
2439 {
2440  if(m_rSplashScreen.is())
2441  {
2442  SolarMutexGuard ensureSolarMutex;
2443  m_rSplashScreen->end();
2444  m_rSplashScreen = nullptr;
2445  }
2446 }
2447 
2448 
2449 IMPL_STATIC_LINK_NOARG(Desktop, AsyncInitFirstRun, Timer *, void)
2450 {
2451  // does initializations which are necessary for the first run of the office
2452  try
2453  {
2454  Reference< XJobExecutor > xExecutor = theJobExecutor::get( ::comphelper::getProcessComponentContext() );
2455  xExecutor->trigger( "onFirstRunInitialization" );
2456  }
2457  catch(const css::uno::Exception&)
2458  {
2459  TOOLS_WARN_EXCEPTION( "desktop.app", "Desktop::DoFirstRunInitializations: caught an exception while trigger job executor" );
2460  }
2461 }
2462 
2464 {
2465  if (GetCommandLineArgs().IsNoDefault())
2466  {
2467  return;
2468  }
2470  Reference< XDesktop2 > xDesktop = css::frame::Desktop::create(xContext);
2471  if (progress != nullptr)
2472  {
2473  progress->SetSplashScreenProgress(60);
2474  }
2475  Reference< XFrame > xBackingFrame = xDesktop->findFrame( "_blank", 0);
2476  Reference< css::awt::XWindow > xContainerWindow;
2477 
2478  if (xBackingFrame.is())
2479  xContainerWindow = xBackingFrame->getContainerWindow();
2480  if (!xContainerWindow.is())
2481  return;
2482 
2483  // set the WindowExtendedStyle::Document style. Normally, this is done by the TaskCreator service when a "_blank"
2484  // frame/window is created. Since we do not use the TaskCreator here, we need to mimic its behavior,
2485  // otherwise documents loaded into this frame will later on miss functionality depending on the style.
2486  VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
2487  SAL_WARN_IF( !pContainerWindow, "desktop.app", "Desktop::Main: no implementation access to the frame's container window!" );
2488  pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WindowExtendedStyle::Document );
2489  if (progress != nullptr)
2490  {
2491  progress->SetSplashScreenProgress(75);
2492  }
2493 
2494  Reference< XController > xStartModule = StartModule::createWithParentWindow( xContext, xContainerWindow);
2495  // Attention: You MUST(!) call setComponent() before you call attachFrame().
2496  // Because the backing component set the property "IsBackingMode" of the frame
2497  // to true inside attachFrame(). But setComponent() reset this state everytimes ...
2498  xBackingFrame->setComponent(Reference< XWindow >(xStartModule, UNO_QUERY), xStartModule);
2499  if (progress != nullptr)
2500  {
2501  progress->SetSplashScreenProgress(100);
2502  }
2503  xStartModule->attachFrame(xBackingFrame);
2504  if (progress != nullptr)
2505  {
2506  progress->CloseSplashScreen();
2507  }
2508  xContainerWindow->setVisible(true);
2509 }
2510 
2511 
2513 {
2514  if (!officecfg::Office::Common::Misc::FirstRun::get())
2515  return;
2516 
2517  // use VCL timer, which won't trigger during shutdown if the
2518  // application exits before timeout
2520 
2521 #ifdef _WIN32
2522  // Check if Quickstarter should be started (on Windows only)
2523  OUString sRootKey = ReplaceStringHookProc("Software\\%OOOVENDOR\\%PRODUCTNAME\\%PRODUCTVERSION");
2524  WCHAR szValue[8192];
2525  DWORD nValueSize = sizeof(szValue);
2526  HKEY hKey;
2527  if (ERROR_SUCCESS == RegOpenKeyW(HKEY_LOCAL_MACHINE, o3tl::toW(sRootKey.getStr()), &hKey))
2528  {
2529  if ( ERROR_SUCCESS == RegQueryValueExW( hKey, L"RunQuickstartAtFirstStart", nullptr, nullptr, reinterpret_cast<LPBYTE>(szValue), &nValueSize ) )
2530  {
2531  css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2532  css::office::Quickstart::createAutoStart(xContext, true/*Quickstart*/, true/*bAutostart*/);
2533  RegCloseKey( hKey );
2534  }
2535  }
2536 #endif
2537 
2538  std::shared_ptr< comphelper::ConfigurationChanges > batch(
2540  officecfg::Office::Common::Misc::FirstRun::set(false, batch);
2541  batch->commit();
2542 }
2543 
2544 }
2545 
2546 /* 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:145
static bool ExecuteCmdLineRequests(ProcessDocumentsRequest &, bool noTerminate)
static bool IsInExecute()
static bool InitializeConfiguration()
Definition: app.cxx:1712
void OpenSplashScreen()
Definition: app.cxx:2370
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 Help * GetHelp()
void CheckFirstRun()
checks if the office is run the first time
Definition: app.cxx:2512
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:169
static PathStatus locateBootstrapFile(OUString &_rURL)
OUString GetURL_Impl(const OUString &rName, std::optional< OUString > const &cwdUrl)
Definition: app.cxx:2176
void SetBootstrapStatus(BootstrapStatus nStatus)
Definition: app.hxx:105
int doShutdown()
Definition: app.cxx:1599
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:2422
void SetApplicationDefaults(Application *pApp)
bool IsHeadless() const
Definition: cmdlineargs.hxx:68
MouseFollowFlags GetFollow() const
BootstrapError m_aBootstrapError
Definition: app.hxx:165
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:1707
static OutputDevice * GetDefaultDevice()
bool IsSafeMode() const
Definition: cmdlineargs.hxx:96
static void ShowBackingComponent(Desktop *progress)
Definition: app.cxx:2463
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:1821
static void FlushConfiguration()
Definition: app.cxx:1778
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()
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
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:170
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:94
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()
float u
void SetContextMenuShortcuts(TriState eContextMenuShortcuts)
virtual void Start() override
bool HasSplashPipe() const
bool m_bCleanedExtensionCache
Definition: app.hxx:163
static CommandLineArgs & GetCommandLineArgs()
Definition: app.cxx:376
void SetSplashScreenText(const OUString &rText)
Definition: app.cxx:2430
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:2119
void SetUseImagesInMenus(TriState eUseImagesInMenus)
IMPL_LINK_NOARG(Desktop, OpenClients_Impl, void *, void)
Definition: app.cxx:1875
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:2449
OUString m_aBootstrapErrorMessage
Definition: app.hxx:166
static OUString getProductKey()
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
static uno::Reference< css::uno::XComponentContext > xContext
Definition: init.cxx:2169
std::thread m_aUpdateThread
Definition: app.hxx:171
static void HandleAppEvent(const ApplicationEvent &rAppEvent)
Definition: app.cxx:2225
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:1786
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:1906
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:2438
DragFullOptions
OUString const & GetStringData() const
bool GetDisablePrinting() const
void dispose()
static void HandleBootstrapPathErrors(::utl::Bootstrap::Status, std::u16string_view aMsg)
Definition: app.cxx:601
DragMode GetDragMode() const
static bool CheckExtensionDependencies()
bool Lockfile_execWarning(Lockfile const *that)
Definition: lockfile2.cxx:29
BootstrapStatus GetBootstrapStatus() const
Definition: app.hxx:109
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()
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