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
1533
1534 if ( !pExecGlobals->bRestartRequested )
1535 {
1536 Application::SetFilterHdl( LINK( this, Desktop, ImplInitFilterHdl ) );
1537
1538 // Preload function depends on an initialized sfx application!
1540
1541 // use system window dialogs
1542 Application::SetSystemWindowMode( SystemWindowFlags::DIALOG );
1543
1545
1546 if ( !rCmdLineArgs.IsInvisible() &&
1547 !rCmdLineArgs.IsNoQuickstart() )
1549
1550 if ( xDesktop.is() )
1551 xDesktop->addTerminateListener( new RequestHandlerController );
1553
1554 // FIXME: move this somewhere sensible.
1555#if HAVE_FEATURE_OPENCL
1556 CheckOpenCLCompute(xDesktop);
1557#endif
1558
1559#if !defined(EMSCRIPTEN)
1560 //Running the VCL graphics rendering tests
1561 const char * pDisplay = std::getenv("DISPLAY");
1562 if (!pDisplay || pDisplay[0] == ':')
1563 {
1564 runGraphicsRenderTests();
1565 }
1566#endif
1567
1568 // Post user event to startup first application component window
1569 // We have to send this OpenClients message short before execute() to
1570 // minimize the risk that this message overtakes type detection construction!!
1571 Application::PostUserEvent( LINK( this, Desktop, OpenClients_Impl ) );
1572
1573 // Post event to enable acceptors
1574 Application::PostUserEvent( LINK( this, Desktop, EnableAcceptors_Impl) );
1575
1576 // call Application::Execute to process messages in vcl message loop
1577#if HAVE_FEATURE_JAVA
1578 // The JavaContext contains an interaction handler which is used when
1579 // the creation of a Java Virtual Machine fails
1580 css::uno::ContextLayer layer2(
1581 new svt::JavaContext( css::uno::getCurrentContext() ) );
1582#endif
1583 // check whether the shutdown is caused by restart just before entering the Execute
1584 pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested ||
1585 xRestartManager->isRestartRequested(true);
1586
1587 if ( !pExecGlobals->bRestartRequested )
1588 {
1589 // if this run of the office is triggered by restart, some additional actions should be done
1590 DoRestartActionsIfNecessary( !rCmdLineArgs.IsInvisible() && !rCmdLineArgs.IsNoQuickstart() );
1591
1592 Execute();
1593 }
1594 }
1595 else
1596 {
1597 if (xDesktop.is())
1598 xDesktop->terminate();
1599 }
1600 // CAUTION: you do not necessarily get here e.g. on the Mac.
1601 // please put all deinitialization code into doShutdown
1602 return doShutdown();
1603}
1604
1606{
1607 if( ! pExecGlobals )
1608 return EXIT_SUCCESS;
1609
1610 if (m_aUpdateThread.joinable())
1611 m_aUpdateThread.join();
1612
1613 if (pExecGlobals->xJVMloadThread.is())
1614 {
1615 pExecGlobals->xJVMloadThread->join();
1616 pExecGlobals->xJVMloadThread.clear();
1617 }
1618
1619 pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested ||
1620 OfficeRestartManager::get(comphelper::getProcessComponentContext())->
1621 isRestartRequested(true);
1622 if ( pExecGlobals->bRestartRequested )
1623 SetRestartState();
1624
1625 const CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
1626 OUString pidfileName = rCmdLineArgs.GetPidfileName();
1627 if ( !pidfileName.isEmpty() )
1628 {
1629 OUString pidfileURL;
1630
1631 if ( osl_getFileURLFromSystemPath(pidfileName.pData, &pidfileURL.pData) == osl_File_E_None )
1632 {
1633 if ( osl::File::remove( pidfileURL ) != osl::FileBase::E_None )
1634 {
1635 SAL_WARN("desktop.app", "shutdown: cannot remove pidfile " << pidfileURL);
1636 }
1637 }
1638 else
1639 {
1640 SAL_WARN("desktop.app", "shutdown: cannot get pidfile URL from path" << pidfileName);
1641 }
1642 }
1643
1644 // remove temp directory
1647
1648 // flush evtl. configuration changes so that all config files in user
1649 // dir are written
1651
1652 if (pExecGlobals->bRestartRequested)
1653 {
1654 // tdf#128523
1655 RemoveIconCacheDirectory();
1656
1657 // a restart is already requested, usually due to a configuration change
1658 // that needs a restart to get active. If this is the case, do not try
1659 // to use SecureUserConfig to safe this still untested new configuration
1660 }
1661 else
1662 {
1663 // Test if SecureUserConfig is active. If yes and we are at this point, regular shutdown
1664 // is in progress and the currently used configuration was working. Try to secure this
1665 // working configuration for later eventually necessary restores
1666 comphelper::BackupFileHelper aBackupFileHelper;
1667
1668 aBackupFileHelper.tryPush();
1669 aBackupFileHelper.tryPushExtensionInfo();
1670 }
1671
1672 // The acceptors in the AcceptorMap must be released (in DeregisterServices)
1673 // with the solar mutex unlocked, to avoid deadlock:
1674 {
1675 SolarMutexReleaser aReleaser;
1677#if HAVE_FEATURE_SCRIPTING
1679#endif
1680 }
1681
1682 // be sure that path/language options gets destroyed before
1683 // UCB is deinitialized
1684 pExecGlobals->pCTLLanguageOptions.reset();
1685 pExecGlobals->pPathOptions.reset();
1686
1688
1689 bool bRR = pExecGlobals->bRestartRequested;
1690 delete pExecGlobals;
1691 pExecGlobals = nullptr;
1692
1693 if ( bRR )
1694 {
1695 restartOnMac(true);
1696#if !ENABLE_WASM_STRIP_SPLASH
1697 if ( m_rSplashScreen.is() )
1698 m_rSplashScreen->reset();
1699#endif
1700
1702 }
1703 return EXIT_SUCCESS;
1704}
1705
1706IMPL_STATIC_LINK( Desktop, ImplInitFilterHdl, ::ConvertData&, rData, bool )
1707{
1709}
1710
1712{
1713 try
1714 {
1715 css::configuration::theDefaultProvider::get(
1717 return true;
1718 }
1719 catch( css::lang::ServiceNotRegisteredException & e )
1720 {
1723 }
1724 catch( const css::configuration::MissingBootstrapFileException& e )
1725 {
1727 e.BootstrapFileURL ));
1729 }
1730 catch( const css::configuration::InvalidBootstrapFileException& e )
1731 {
1733 e.BootstrapFileURL ));
1735 }
1736 catch( const css::configuration::InstallationIncompleteException& )
1737 {
1738 OUString aVersionFileURL;
1739 OUString aMsg;
1740 utl::Bootstrap::PathStatus aPathStatus = utl::Bootstrap::locateVersionFile( aVersionFileURL );
1741 if ( aPathStatus == utl::Bootstrap::PATH_EXISTS )
1743 else
1745
1747 }
1748 catch ( const css::configuration::backend::BackendAccessException& exception)
1749 {
1750 // [cm122549] It is assumed in this case that the message
1751 // coming from InitConfiguration (in fact CreateApplicationConf...)
1752 // is suitable for display directly.
1753 FatalError( MakeStartupErrorMessage( exception.Message ) );
1754 }
1755 catch ( const css::configuration::backend::BackendSetupException& exception)
1756 {
1757 // [cm122549] It is assumed in this case that the message
1758 // coming from InitConfiguration (in fact CreateApplicationConf...)
1759 // is suitable for display directly.
1760 FatalError( MakeStartupErrorMessage( exception.Message ) );
1761 }
1762 catch ( const css::configuration::CannotLoadConfigurationException& )
1763 {
1765 OUString() ));
1767 }
1768 catch( const css::uno::Exception& )
1769 {
1771 OUString() ));
1773 }
1774 return false;
1775}
1776
1778{
1779 css::uno::Reference< css::util::XFlushable >(
1780 css::configuration::theDefaultProvider::get(
1782 css::uno::UNO_QUERY_THROW)->flush();
1783}
1784
1785bool Desktop::InitializeQuickstartMode( const Reference< XComponentContext >& rxContext )
1786{
1787 try
1788 {
1789 // the shutdown icon sits in the systray and allows the user to keep
1790 // the office instance running for quicker restart
1791 // this will only be activated if --quickstart was specified on cmdline
1792
1793 bool bQuickstart = shouldLaunchQuickstart();
1794
1795 // Try to instantiate quickstart service. This service is not mandatory, so
1796 // do nothing if service is not available
1797
1798 // #i105753# the following if was invented for performance
1799 // unfortunately this broke the Mac behavior which is to always run
1800 // in quickstart mode since Mac applications do not usually quit
1801 // when the last document closes.
1802 // Note that this claim that on macOS we "always run in quickstart mode"
1803 // has nothing to do with (quick) *starting* (i.e. starting automatically
1804 // when the user logs in), though, but with not quitting when no documents
1805 // are open.
1806 #ifndef MACOSX
1807 if ( bQuickstart )
1808 #endif
1809 {
1810 css::office::Quickstart::createStart(rxContext, bQuickstart);
1811 }
1812 return true;
1813 }
1814 catch( const css::uno::Exception& )
1815 {
1816 return false;
1817 }
1818}
1819
1821{
1823 return;
1824
1825 StyleSettings hStyleSettings = rSettings.GetStyleSettings();
1826 MouseSettings hMouseSettings = rSettings.GetMouseSettings();
1827
1828 DragFullOptions nDragFullOptions = hStyleSettings.GetDragFullOptions();
1829
1830 sal_uInt16 nDragMode = officecfg::Office::Common::View::Window::Drag::get();
1831 switch ( nDragMode )
1832 {
1833 case 0: //FullWindow:
1834 nDragFullOptions |= DragFullOptions::All;
1835 break;
1836 case 1: // Frame:
1837 nDragFullOptions &= ~DragFullOptions::All;
1838 break;
1839 case 2: // SystemDep
1840 default:
1841 break;
1842 }
1843
1844 MouseFollowFlags nFollow = hMouseSettings.GetFollow();
1845 bool bMenuFollowMouse = officecfg::Office::Common::View::Menu::FollowMouse::get();
1846 hMouseSettings.SetFollow( bMenuFollowMouse ? (nFollow|MouseFollowFlags::Menu) : (nFollow&~MouseFollowFlags::Menu));
1847 rSettings.SetMouseSettings(hMouseSettings);
1848
1849 bool bMenuIcons = officecfg::Office::Common::View::Menu::ShowIconsInMenues::get();
1850 bool bSystemMenuIcons = officecfg::Office::Common::View::Menu::IsSystemIconsInMenus::get();
1851 TriState eMenuIcons = bSystemMenuIcons ? TRISTATE_INDET : static_cast<TriState>(bMenuIcons);
1852 hStyleSettings.SetUseImagesInMenus(eMenuIcons);
1853 hStyleSettings.SetContextMenuShortcuts(static_cast<TriState>(officecfg::Office::Common::View::Menu::ShortcutsInContextMenus::get()));
1854 hStyleSettings.SetDragFullOptions( nDragFullOptions );
1855 rSettings.SetStyleSettings ( hStyleSettings );
1856}
1857
1858namespace {
1859
1860class ExitTimer : public Timer
1861{
1862 public:
1863 ExitTimer() : Timer("desktop ExitTimer")
1864 {
1865 SetTimeout(500);
1866 Start();
1867 }
1868 virtual void Invoke() override
1869 {
1870 _exit(42);
1871 }
1872};
1873
1874}
1875
1876IMPL_LINK_NOARG(Desktop, OpenClients_Impl, void*, void)
1877{
1878 // #i114963#
1879 // Enable IPC thread before OpenClients
1880 //
1881 // This is because it is possible for another client to connect during the OpenClients() call.
1882 // This can happen on Windows when document is printed (not opened) and another client wants to print (when printing multiple documents).
1883 // 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
1884 //
1885 // ALSO:
1886 //
1887 // Multiple clients may request simultaneous connections.
1888 // When this server closes down it attempts to recreate the pipe (in RequestHandler::Disable()).
1889 // It's possible that the client has a pending connection request.
1890 // When the IPC thread is not running, this connection locks (because maPipe.accept()) is never called
1892 OpenClients();
1893
1894 CloseSplashScreen();
1895 CheckFirstRun( );
1896#ifdef _WIN32
1897 bool bDontShowDialogs
1898 = Application::IsHeadlessModeEnabled(); // uitest.uicheck fails when the dialog is open
1899 for (sal_uInt16 i = 0; !bDontShowDialogs && i < Application::GetCommandLineParamCount(); i++)
1900 {
1901 if (Application::GetCommandLineParam(i) == "--nologo")
1902 bDontShowDialogs = true;
1903 }
1904 if (!bDontShowDialogs)
1906 // Registers a COM class factory of the service manager with the windows operating system.
1907 Reference< XMultiServiceFactory > xSMgr= comphelper::getProcessServiceFactory();
1908 xSMgr->createInstance("com.sun.star.bridge.OleApplicationRegistration");
1909 xSMgr->createInstance("com.sun.star.comp.ole.EmbedServer");
1910#endif
1911 const char *pExitPostStartup = getenv ("OOO_EXIT_POST_STARTUP");
1912 if (pExitPostStartup && *pExitPostStartup)
1913 new ExitTimer();
1914}
1915
1917{
1918
1919 const CommandLineArgs& rArgs = GetCommandLineArgs();
1920
1921 if (!rArgs.IsQuickstart())
1922 {
1923 OUString aHelpModule;
1924 if (rArgs.IsHelpWriter()) {
1925 aHelpModule = "swriter";
1926 } else if (rArgs.IsHelpCalc()) {
1927 aHelpModule = "scalc";
1928 } else if (rArgs.IsHelpDraw()) {
1929 aHelpModule = "sdraw";
1930 } else if (rArgs.IsHelpImpress()) {
1931 aHelpModule = "simpress";
1932 } else if (rArgs.IsHelpBase()) {
1933 aHelpModule = "sdatabase";
1934 } else if (rArgs.IsHelpBasic()) {
1935 aHelpModule = "sbasic";
1936 } else if (rArgs.IsHelpMath()) {
1937 aHelpModule = "smath";
1938 }
1939 if (!aHelpModule.isEmpty()) {
1940 OUString aHelpURL = "vnd.sun.star.help://"
1941 + aHelpModule
1942 + "/start?Language="
1944#if defined UNX
1945 aHelpURL += "&System=UNX";
1946#elif defined _WIN32
1947 aHelpURL += "&System=WIN";
1948#endif
1949 Application::GetHelp()->Start(aHelpURL);
1950 return;
1951 }
1952 }
1953
1954 // Disable AutoSave feature in case "--norestore" or a similar command line switch is set on the command line.
1955 // The reason behind: AutoSave/EmergencySave/AutoRecovery share the same data.
1956 // But the require that all documents, which are saved as backup should exists inside
1957 // memory. May be this mechanism will be inconsistent if the configuration exists...
1958 // but no document inside memory corresponds to this data.
1959 // Further it's not acceptable to recover such documents without any UI. It can
1960 // need some time, where the user won't see any results and wait for finishing the office startup...
1961 bool bAllowRecoveryAndSessionManagement = ( !rArgs.IsNoRestore() ) && ( !rArgs.IsHeadless() );
1962
1963#if !defined ANDROID
1964 // Enter safe mode if requested
1966 handleSafeMode();
1967 }
1968#endif
1969
1970#if HAVE_FEATURE_BREAKPAD
1971 if (officecfg::Office::Common::Misc::CrashReport::get() && CrashReporter::crashReportInfoExists())
1972 handleCrashReport();
1973#endif
1974
1975 if ( ! bAllowRecoveryAndSessionManagement )
1976 {
1977 try
1978 {
1979 Reference< XDispatch > xRecovery = css::frame::theAutoRecovery::get( ::comphelper::getProcessComponentContext() );
1980 Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create( ::comphelper::getProcessComponentContext() );
1981
1982 css::util::URL aCmd;
1983 aCmd.Complete = "vnd.sun.star.autorecovery:/disableRecovery";
1984 xParser->parseStrict(aCmd);
1985
1986 xRecovery->dispatch(aCmd, css::uno::Sequence< css::beans::PropertyValue >());
1987 }
1988 catch(const css::uno::Exception&)
1989 {
1990 TOOLS_WARN_EXCEPTION( "desktop.app", "Could not disable AutoRecovery.");
1991 }
1992 }
1993 else
1994 {
1995 bool bExistsRecoveryData = false;
1996#if !ENABLE_WASM_STRIP_RECOVERYUI
1997 bool bCrashed = false;
1998 bool bExistsSessionData = false;
1999 bool const bDisableRecovery
2000 = getenv("OOO_DISABLE_RECOVERY") != nullptr
2002 || !officecfg::Office::Recovery::RecoveryInfo::Enabled::get();
2003
2004 impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
2005
2006 if ( !bDisableRecovery &&
2007 (
2008 bExistsRecoveryData || // => crash with files => recovery
2009 bCrashed // => crash without files => error report
2010 )
2011 )
2012 {
2013 try
2014 {
2015 impl_callRecoveryUI(
2016 false , // false => force recovery instead of emergency save
2017 bExistsRecoveryData);
2018 }
2019 catch(const css::uno::Exception&)
2020 {
2021 TOOLS_WARN_EXCEPTION( "desktop.app", "Error during recovery");
2022 }
2023 }
2024#endif
2025
2026 Reference< XSessionManagerListener2 > xSessionListener;
2027 try
2028 {
2029 // specifies whether the UI-interaction on Session shutdown is allowed
2030 bool bUIOnSessionShutdownAllowed = officecfg::Office::Recovery::SessionShutdown::DocumentStoreUIEnabled::get();
2031 xSessionListener = SessionListener::createWithOnQuitFlag(
2032 ::comphelper::getProcessComponentContext(), bUIOnSessionShutdownAllowed);
2033 }
2034 catch(const css::uno::Exception&)
2035 {
2036 TOOLS_WARN_EXCEPTION( "desktop.app", "Registration of session listener failed");
2037 }
2038
2039 if ( !bExistsRecoveryData && xSessionListener.is() )
2040 {
2041 // session management
2042 try
2043 {
2044 xSessionListener->doRestore();
2045 }
2046 catch(const css::uno::Exception&)
2047 {
2048 TOOLS_WARN_EXCEPTION( "desktop.app", "Error in session management");
2049 }
2050 }
2051 }
2052
2053 // write this information here to avoid depending on vcl in the crash reporter lib
2054 CrashReporter::addKeyValue("Language", Application::GetSettings().GetLanguageTag().getBcp47(), CrashReporter::Create);
2055
2057
2058 ProcessDocumentsRequest aRequest(rArgs.getCwdUrl());
2059 aRequest.aOpenList = rArgs.GetOpenList();
2060 aRequest.aViewList = rArgs.GetViewList();
2061 aRequest.aStartList = rArgs.GetStartList();
2062 aRequest.aPrintList = rArgs.GetPrintList();
2063 aRequest.aPrintToList = rArgs.GetPrintToList();
2064 aRequest.aPrinterName = rArgs.GetPrinterName();
2065 aRequest.aForceOpenList = rArgs.GetForceOpenList();
2066 aRequest.aForceNewList = rArgs.GetForceNewList();
2067 aRequest.aConversionList = rArgs.GetConversionList();
2068 aRequest.aConversionParams = rArgs.GetConversionParams();
2069 aRequest.aConversionOut = rArgs.GetConversionOut();
2071 aRequest.aInFilter = rArgs.GetInFilter();
2072 aRequest.bTextCat = rArgs.IsTextCat();
2073 aRequest.bScriptCat = rArgs.IsScriptCat();
2074
2075 if ( !aRequest.aOpenList.empty() ||
2076 !aRequest.aViewList.empty() ||
2077 !aRequest.aStartList.empty() ||
2078 !aRequest.aPrintList.empty() ||
2079 !aRequest.aForceOpenList.empty() ||
2080 !aRequest.aForceNewList.empty() ||
2081 ( !aRequest.aPrintToList.empty() && !aRequest.aPrinterName.isEmpty() ) ||
2082 !aRequest.aConversionList.empty() )
2083 {
2084 if ( rArgs.HasModuleParam() )
2085 {
2086 SvtModuleOptions aOpt;
2087
2088 // Support command line parameters to start a module (as preselection)
2091 else if ( rArgs.IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
2095 else if ( rArgs.IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
2097 }
2098
2099 // check for printing disabled
2100 if( ( !(aRequest.aPrintList.empty() && aRequest.aPrintToList.empty()) )
2102 {
2103 aRequest.aPrintList.clear();
2104 aRequest.aPrintToList.clear();
2105 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
2106 VclMessageType::Warning, VclButtonsType::Ok,
2107 DpResId(STR_ERR_PRINTDISABLED)));
2108 xBox->run();
2109 }
2110
2111 // Process request
2112 if ( RequestHandler::ExecuteCmdLineRequests(aRequest, false) )
2113 {
2114 // Don't do anything if we have successfully called terminate at desktop:
2115 return;
2116 }
2117 }
2118
2119 // no default document if a document was loaded by recovery or by command line or if soffice is used as server
2120 Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
2121 Reference< XElementAccess > xList( xDesktop->getFrames(), UNO_QUERY_THROW );
2122 if ( xList->hasElements() )
2123 return;
2124
2125 if ( rArgs.IsQuickstart() || rArgs.IsInvisible() || Application::AnyInput( VclInputFlags::APPEVENT ) )
2126 // soffice was started as tray icon ...
2127 return;
2128
2129 OpenDefault();
2130}
2131
2133{
2134 OUString aName;
2135 SvtModuleOptions aOpt;
2136
2137 const CommandLineArgs& rArgs = GetCommandLineArgs();
2138 if ( rArgs.IsNoDefault() ) return;
2139 if ( rArgs.HasModuleParam() )
2140 {
2141 // Support new command line parameters to start a module
2144 else if ( rArgs.IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
2148 else if ( rArgs.IsBase() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) )
2150 else if ( rArgs.IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
2152 else if ( rArgs.IsMath() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH ) )
2154 else if ( rArgs.IsGlobal() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
2156 else if ( rArgs.IsWeb() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
2158 }
2159
2160 if ( aName.isEmpty() )
2161 {
2163 {
2164 ShowBackingComponent(nullptr);
2165 return;
2166 }
2167
2168 // Old way to create a default document
2179 else
2180 return;
2181 }
2182
2183 ProcessDocumentsRequest aRequest(rArgs.getCwdUrl());
2184 aRequest.aOpenList.push_back(aName);
2186}
2187
2188
2190 const OUString& rName, std::optional< OUString > const & cwdUrl )
2191{
2192 // if rName is a vnd.sun.star.script URL do not attempt to parse it
2193 // as INetURLObj does not handle URLs there
2194 if (rName.startsWith("vnd.sun.star.script"))
2195 {
2196 return rName;
2197 }
2198
2199 // don't touch file urls, those should already be in internal form
2200 // they won't get better here (#112849#)
2201 if (comphelper::isFileUrl(rName))
2202 {
2203 return rName;
2204 }
2205
2206 if ( rName.startsWith("service:"))
2207 {
2208 return rName;
2209 }
2210
2211 // Add path separator to these directory and make given URL (rName) absolute by using of current working directory
2212 // Attention: "setFinalSlash()" is necessary for calling "smartRel2Abs()"!!!
2213 // Otherwise last part will be ignored and wrong result will be returned!!!
2214 // "smartRel2Abs()" interpret given URL as file not as path. So he truncate last element to get the base path ...
2215 // But if we add a separator - he doesn't do it anymore.
2216 INetURLObject aObj;
2217 if (cwdUrl) {
2218 aObj.SetURL(*cwdUrl);
2219 aObj.setFinalSlash();
2220 }
2221
2222 // Use the provided parameters for smartRel2Abs to support the usage of '%' in system paths.
2223 // Otherwise this char won't get encoded and we are not able to load such files later,
2224 bool bWasAbsolute;
2226 RTL_TEXTENCODING_UTF8, true );
2227 OUString aFileURL = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
2228
2229 ::osl::FileStatus aStatus( osl_FileStatus_Mask_FileURL );
2230 ::osl::DirectoryItem aItem;
2231 if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
2232 ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
2233 aFileURL = aStatus.getFileURL();
2234
2235 return aFileURL;
2236}
2237
2239{
2240 switch ( rAppEvent.GetEvent() )
2241 {
2243 // every time an accept parameter is used we create an acceptor
2244 // with the corresponding accept-string
2245 createAcceptor(rAppEvent.GetStringData());
2246 break;
2248 if ( !GetCommandLineArgs().IsInvisible() && !impl_bringToFrontRecoveryUI() )
2249 {
2250 Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2251
2252 // find active task - the active task is always a visible task
2253 Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext );
2254 Reference< css::frame::XFrame > xTask = xDesktop->getActiveFrame();
2255 if ( !xTask.is() )
2256 {
2257 // get any task if there is no active one
2258 Reference< css::container::XIndexAccess > xList = xDesktop->getFrames();
2259 if ( xList->getCount() > 0 )
2260 xList->getByIndex(0) >>= xTask;
2261 }
2262
2263 if ( xTask.is() )
2264 {
2265 Reference< css::awt::XTopWindow > xTop( xTask->getContainerWindow(), UNO_QUERY );
2266 xTop->toFront();
2267 }
2268 else
2269 {
2270 // no visible task that could be activated found
2271 Reference< css::awt::XWindow > xContainerWindow;
2272 Reference< XFrame > xBackingFrame = xDesktop->findFrame( "_blank", 0);
2273 if (xBackingFrame.is())
2274 xContainerWindow = xBackingFrame->getContainerWindow();
2275 if (xContainerWindow.is())
2276 {
2277 Reference< XController > xStartModule = StartModule::createWithParentWindow(xContext, xContainerWindow);
2278 Reference< css::awt::XWindow > xBackingWin(xStartModule, UNO_QUERY);
2279 // Attention: You MUST(!) call setComponent() before you call attachFrame().
2280 // Because the backing component set the property "IsBackingMode" of the frame
2281 // to true inside attachFrame(). But setComponent() reset this state every time ...
2282 xBackingFrame->setComponent(xBackingWin, xStartModule);
2283 xStartModule->attachFrame(xBackingFrame);
2284 xContainerWindow->setVisible(true);
2285
2286 VclPtr<vcl::Window> pCompWindow = VCLUnoHelper::GetWindow(xBackingFrame->getComponentWindow());
2287 if (pCompWindow)
2288 pCompWindow->PaintImmediately();
2289 }
2290 }
2291 }
2292 break;
2294 {
2295 const CommandLineArgs& rCmdLine = GetCommandLineArgs();
2296 if ( !rCmdLine.IsInvisible() && !rCmdLine.IsTerminateAfterInit() )
2297 {
2298 ProcessDocumentsRequest docsRequest(rCmdLine.getCwdUrl());
2299 std::vector<OUString> const & data(rAppEvent.GetStringsData());
2300 docsRequest.aOpenList.insert(
2301 docsRequest.aOpenList.end(), data.begin(), data.end());
2302 RequestHandler::ExecuteCmdLineRequests(docsRequest, false);
2303 }
2304 }
2305 break;
2307 // start help for a specific URL
2309 break;
2311 {
2312 const CommandLineArgs& rCmdLine = GetCommandLineArgs();
2313 if ( !rCmdLine.IsInvisible() && !rCmdLine.IsTerminateAfterInit() )
2314 {
2315 ProcessDocumentsRequest docsRequest(rCmdLine.getCwdUrl());
2316 std::vector<OUString> const & data(rAppEvent.GetStringsData());
2317 docsRequest.aPrintList.insert(
2318 docsRequest.aPrintList.end(), data.begin(), data.end());
2319 RequestHandler::ExecuteCmdLineRequests(docsRequest, false);
2320 }
2321 }
2322 break;
2324 {
2325 Desktop* pD = dynamic_cast<Desktop*>(GetpApp());
2326 OSL_ENSURE( pD, "no desktop ?!?" );
2327 if( pD )
2328 pD->doShutdown();
2329 }
2330 break;
2332 if ( !GetCommandLineArgs().IsInvisible() )
2333 {
2334 // If the office has been started the second time its command line arguments are sent through a pipe
2335 // connection to the first office. We want to reuse the quickstart option for the first office.
2336 // NOTICE: The quickstart service must be initialized inside the "main thread", so we use the
2337 // application events to do this (they are executed inside main thread)!!!
2338 // Don't start quickstart service if the user specified "--invisible" on the command line!
2339 Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2340 css::office::Quickstart::createStart(xContext, true/*Quickstart*/);
2341 }
2342 break;
2344 // This is only used on macOS, and only for About or Preferences.
2345 // Ignore all errors here. It's clicking a menu entry only ...
2346 // The user will try it again, in case nothing happens .-)
2347 try
2348 {
2349 Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2350
2351 Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext );
2352
2353 Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create(xContext);
2354 css::util::URL aCommand;
2355 if( rAppEvent.GetStringData() == "PREFERENCES" )
2356 aCommand.Complete = ".uno:OptionsTreeDialog";
2357 else if( rAppEvent.GetStringData() == "ABOUT" )
2358 aCommand.Complete = ".uno:About";
2359 if( !aCommand.Complete.isEmpty() )
2360 {
2361 xParser->parseStrict(aCommand);
2362
2363 css::uno::Reference< css::frame::XDispatch > xDispatch = xDesktop->queryDispatch(aCommand, OUString(), 0);
2364 if (xDispatch.is())
2365 xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >());
2366 }
2367 }
2368 catch(const css::uno::Exception&)
2369 {
2370 TOOLS_WARN_EXCEPTION("desktop.app", "exception thrown by dialog");
2371 }
2372 break;
2374 // try to remove corresponding acceptor
2375 destroyAcceptor(rAppEvent.GetStringData());
2376 break;
2377 default:
2378 SAL_WARN( "desktop.app", "this cannot happen");
2379 break;
2380 }
2381}
2382
2383#if !ENABLE_WASM_STRIP_SPLASH
2385{
2386 const CommandLineArgs &rCmdLine = GetCommandLineArgs();
2387 // Show intro only if this is normal start (e.g. no server, no quickstart, no printing )
2388 if ( !(!rCmdLine.IsInvisible() &&
2389 !rCmdLine.IsHeadless() &&
2390 !rCmdLine.IsQuickstart() &&
2391 !rCmdLine.IsMinimized() &&
2392 !rCmdLine.IsNoLogo() &&
2393 !rCmdLine.IsTerminateAfterInit() &&
2394 rCmdLine.GetPrintList().empty() &&
2395 rCmdLine.GetPrintToList().empty() &&
2396 rCmdLine.GetConversionList().empty()) )
2397 return;
2398
2399 // Determine application name from command line parameters
2400 OUString aAppName;
2401 if ( rCmdLine.IsWriter() )
2402 aAppName = "writer";
2403 else if ( rCmdLine.IsCalc() )
2404 aAppName = "calc";
2405 else if ( rCmdLine.IsDraw() )
2406 aAppName = "draw";
2407 else if ( rCmdLine.IsImpress() )
2408 aAppName = "impress";
2409 else if ( rCmdLine.IsBase() )
2410 aAppName = "base";
2411 else if ( rCmdLine.IsGlobal() )
2412 aAppName = "global";
2413 else if ( rCmdLine.IsMath() )
2414 aAppName = "math";
2415 else if ( rCmdLine.IsWeb() )
2416 aAppName = "web";
2417
2418 // Which splash to use
2419 OUString aSplashService( "com.sun.star.office.SplashScreen" );
2420 if ( rCmdLine.HasSplashPipe() )
2421 aSplashService = "com.sun.star.office.PipeSplashScreen";
2422
2423 Sequence< Any > aSeq{ Any(true) /* bVisible */, Any(aAppName) };
2424 css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2425 m_rSplashScreen.set(
2426 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aSplashService, aSeq, xContext),
2427 UNO_QUERY);
2428
2429 if(m_rSplashScreen.is())
2430 m_rSplashScreen->start("SplashScreen", 100);
2431
2432}
2433#endif
2434
2435void Desktop::SetSplashScreenProgress(sal_Int32 iProgress)
2436{
2437#if ENABLE_WASM_STRIP_SPLASH
2438 (void) iProgress;
2439#else
2440 if(m_rSplashScreen.is())
2441 {
2442 m_rSplashScreen->setValue(iProgress);
2443 }
2444#endif
2445}
2446
2447void Desktop::SetSplashScreenText( const OUString& rText )
2448{
2449#if ENABLE_WASM_STRIP_SPLASH
2450 (void) rText;
2451#else
2452 if( m_rSplashScreen.is() )
2453 {
2454 m_rSplashScreen->setText( rText );
2455 }
2456#endif
2457}
2458
2460{
2461#if !ENABLE_WASM_STRIP_SPLASH
2462 if(m_rSplashScreen.is())
2463 {
2464 SolarMutexGuard ensureSolarMutex;
2465 m_rSplashScreen->end();
2466 m_rSplashScreen = nullptr;
2467 }
2468#endif
2469}
2470
2471
2472IMPL_STATIC_LINK_NOARG(Desktop, AsyncInitFirstRun, Timer *, void)
2473{
2474 // does initializations which are necessary for the first run of the office
2475 try
2476 {
2477 Reference< XJobExecutor > xExecutor = theJobExecutor::get( ::comphelper::getProcessComponentContext() );
2478 xExecutor->trigger( "onFirstRunInitialization" );
2479 }
2480 catch(const css::uno::Exception&)
2481 {
2482 TOOLS_WARN_EXCEPTION( "desktop.app", "Desktop::DoFirstRunInitializations: caught an exception while trigger job executor" );
2483 }
2484}
2485
2487{
2488 if (GetCommandLineArgs().IsNoDefault())
2489 {
2490 return;
2491 }
2492 Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
2494 if (progress != nullptr)
2495 {
2496 progress->SetSplashScreenProgress(60);
2497 }
2498 Reference< XFrame > xBackingFrame = xDesktop->findFrame( "_blank", 0);
2499 Reference< css::awt::XWindow > xContainerWindow;
2500
2501 if (xBackingFrame.is())
2502 xContainerWindow = xBackingFrame->getContainerWindow();
2503 if (!xContainerWindow.is())
2504 return;
2505
2506 // set the WindowExtendedStyle::Document style. Normally, this is done by the TaskCreator service when a "_blank"
2507 // frame/window is created. Since we do not use the TaskCreator here, we need to mimic its behavior,
2508 // otherwise documents loaded into this frame will later on miss functionality depending on the style.
2509 VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
2510 SAL_WARN_IF( !pContainerWindow, "desktop.app", "Desktop::Main: no implementation access to the frame's container window!" );
2511 pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WindowExtendedStyle::Document );
2512 if (progress != nullptr)
2513 {
2514 progress->SetSplashScreenProgress(75);
2515 }
2516
2517 Reference< XController > xStartModule = StartModule::createWithParentWindow( xContext, xContainerWindow);
2518 // Attention: You MUST(!) call setComponent() before you call attachFrame().
2519 // Because the backing component set the property "IsBackingMode" of the frame
2520 // to true inside attachFrame(). But setComponent() reset this state everytimes ...
2521 xBackingFrame->setComponent(Reference< XWindow >(xStartModule, UNO_QUERY), xStartModule);
2522 if (progress != nullptr)
2523 {
2524 progress->SetSplashScreenProgress(100);
2525 }
2526 xStartModule->attachFrame(xBackingFrame);
2527 if (progress != nullptr)
2528 {
2529 progress->CloseSplashScreen();
2530 }
2531 xContainerWindow->setVisible(true);
2532}
2533
2534
2536{
2537 if (!officecfg::Office::Common::Misc::FirstRun::get())
2538 return;
2539
2540 // use VCL timer, which won't trigger during shutdown if the
2541 // application exits before timeout
2543
2544#ifdef _WIN32
2545 // Check if Quickstarter should be started (on Windows only)
2546 OUString sRootKey = ReplaceStringHookProc("Software\\%OOOVENDOR\\%PRODUCTNAME\\%PRODUCTVERSION");
2547 WCHAR szValue[8192];
2548 DWORD nValueSize = sizeof(szValue);
2549 HKEY hKey;
2550 if (ERROR_SUCCESS == RegOpenKeyW(HKEY_LOCAL_MACHINE, o3tl::toW(sRootKey.getStr()), &hKey))
2551 {
2552 if ( ERROR_SUCCESS == RegQueryValueExW( hKey, L"RunQuickstartAtFirstStart", nullptr, nullptr, reinterpret_cast<LPBYTE>(szValue), &nValueSize ) )
2553 {
2554 css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2555 css::office::Quickstart::createAutoStart(xContext, true/*Quickstart*/, true/*bAutostart*/);
2556 RegCloseKey( hKey );
2557 }
2558 }
2559#endif
2560
2561 std::shared_ptr< comphelper::ConfigurationChanges > batch(
2563 officecfg::Office::Common::Misc::FirstRun::set(false, batch);
2564 batch->commit();
2565}
2566
2567}
2568
2569/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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)
static void SetVCLSettings()
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:1777
static void InitApplicationServiceManager()
Definition: appinit.cxx:63
static bool InitializeQuickstartMode(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
Definition: app.cxx:1785
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:2459
static void createAcceptor(const OUString &aDescription)
Definition: appinit.cxx:135
virtual void OverrideSystemSettings(AllSettings &rSettings) override
Definition: app.cxx:1820
bool m_bCleanedExtensionCache
Definition: app.hxx:162
void RegisterServices()
Definition: appinit.cxx:86
static void HandleAppEvent(const ApplicationEvent &rAppEvent)
Definition: app.cxx:2238
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:2132
static void OpenClients()
Definition: app.cxx:1916
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:2535
void OpenSplashScreen()
Definition: app.cxx:2384
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:1711
void SetSplashScreenText(const OUString &rText)
Definition: app.cxx:2447
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:2486
std::unique_ptr< Lockfile > m_xLockfile
Definition: app.hxx:168
void SetSplashScreenProgress(sal_Int32)
Definition: app.cxx:2435
virtual void DeInit() override
Definition: app.cxx:542
int doShutdown()
Definition: app.cxx:1605
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:2642
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:1876
OUString GetURL_Impl(const OUString &rName, std::optional< OUString > const &cwdUrl)
Definition: app.cxx:2189
IMPL_STATIC_LINK_NOARG(Desktop, AsyncInitFirstRun, Timer *, void)
Definition: app.cxx:2472
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:1706
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