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