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