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