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