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