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