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