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