Line data Source code
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 <config_features.h>
21 : #include <config_folders.h>
22 :
23 : #include <sal/config.h>
24 :
25 : #include <iostream>
26 :
27 : #include "app.hxx"
28 : #include "desktop.hrc"
29 : #include "cmdlineargs.hxx"
30 : #include "cmdlinehelp.hxx"
31 : #include "dispatchwatcher.hxx"
32 : #include "configinit.hxx"
33 : #include "lockfile.hxx"
34 : #include "userinstall.hxx"
35 : #include "desktopcontext.hxx"
36 : #include "exithelper.h"
37 : #include "migration.hxx"
38 :
39 : #include <svl/languageoptions.hxx>
40 : #include <svtools/javacontext.hxx>
41 : #include <com/sun/star/beans/XPropertySet.hpp>
42 : #include <com/sun/star/frame/theAutoRecovery.hpp>
43 : #include <com/sun/star/frame/theGlobalEventBroadcaster.hpp>
44 : #include <com/sun/star/frame/SessionListener.hpp>
45 : #include <com/sun/star/frame/XSessionManagerListener.hpp>
46 : #include <com/sun/star/frame/XSynchronousDispatch.hpp>
47 : #include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
48 : #include <com/sun/star/configuration/CorruptedConfigurationException.hpp>
49 : #include <com/sun/star/configuration/theDefaultProvider.hpp>
50 : #include <com/sun/star/util/XFlushable.hpp>
51 : #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
52 : #include <com/sun/star/frame/Desktop.hpp>
53 : #include <com/sun/star/frame/StartModule.hpp>
54 : #include <com/sun/star/frame/XComponentLoader.hpp>
55 : #include <com/sun/star/view/XPrintable.hpp>
56 : #include <com/sun/star/awt/XTopWindow.hpp>
57 : #include <com/sun/star/util/URLTransformer.hpp>
58 : #include <com/sun/star/util/XURLTransformer.hpp>
59 : #include <com/sun/star/util/XCloseable.hpp>
60 : #include <com/sun/star/frame/XDispatchProvider.hpp>
61 : #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
62 : #include <com/sun/star/configuration/MissingBootstrapFileException.hpp>
63 : #include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
64 : #include <com/sun/star/configuration/InstallationIncompleteException.hpp>
65 : #include <com/sun/star/configuration/backend/BackendSetupException.hpp>
66 : #include <com/sun/star/configuration/backend/BackendAccessException.hpp>
67 : #include <com/sun/star/task/theJobExecutor.hpp>
68 : #include <com/sun/star/task/OfficeRestartManager.hpp>
69 : #include <com/sun/star/task/XRestartManager.hpp>
70 : #include <com/sun/star/document/XDocumentEventListener.hpp>
71 : #include <com/sun/star/frame/theUICommandDescription.hpp>
72 : #include <com/sun/star/ui/theUIElementFactoryManager.hpp>
73 : #include <com/sun/star/ui/theWindowStateConfiguration.hpp>
74 : #include <com/sun/star/frame/XUIControllerRegistration.hpp>
75 : #include <com/sun/star/frame/thePopupMenuControllerFactory.hpp>
76 : #include <com/sun/star/office/Quickstart.hpp>
77 :
78 : #include <toolkit/helper/vclunohelper.hxx>
79 : #include <comphelper/configuration.hxx>
80 : #include <comphelper/processfactory.hxx>
81 : #include <unotools/bootstrap.hxx>
82 : #include <unotools/configmgr.hxx>
83 : #include <unotools/moduleoptions.hxx>
84 : #include <unotools/localfilehelper.hxx>
85 : #include <officecfg/Office/Common.hxx>
86 : #include <officecfg/Office/Recovery.hxx>
87 : #include <officecfg/Setup.hxx>
88 : #include <osl/file.hxx>
89 : #include <osl/process.h>
90 : #include <rtl/uri.hxx>
91 : #include <unotools/pathoptions.hxx>
92 : #include <svtools/miscopt.hxx>
93 : #include <svtools/menuoptions.hxx>
94 : #include <rtl/bootstrap.hxx>
95 : #include <vcl/help.hxx>
96 : #include <vcl/layout.hxx>
97 : #include <vcl/settings.hxx>
98 : #include <sfx2/sfx.hrc>
99 : #include <sfx2/app.hxx>
100 : #include <svl/itemset.hxx>
101 : #include <svl/eitem.hxx>
102 : #include <basic/sbstar.hxx>
103 :
104 : #include <svtools/fontsubstconfig.hxx>
105 : #include <svtools/accessibilityoptions.hxx>
106 : #include <svtools/apearcfg.hxx>
107 : #include <vcl/graphicfilter.hxx>
108 :
109 : #include "langselect.hxx"
110 :
111 : #include <config_telepathy.h>
112 :
113 : #if ENABLE_TELEPATHY
114 : #include <tubes/manager.hxx>
115 : #endif
116 :
117 : #if defined MACOSX
118 : #include <errno.h>
119 : #include <sys/wait.h>
120 : #endif
121 :
122 : #ifdef WNT
123 : #ifdef _MSC_VER
124 : #pragma warning(push, 1) /* disable warnings within system headers */
125 : #pragma warning (disable: 4005)
126 : #endif
127 : #define WIN32_LEAN_AND_MEAN
128 : #include <windows.h>
129 : #ifdef _MSC_VER
130 : #pragma warning(pop)
131 : #endif
132 : #endif //WNT
133 :
134 : #if defined WNT
135 : #include <process.h>
136 : #define GETPID _getpid
137 : #else
138 : #include <unistd.h>
139 : #define GETPID getpid
140 : #endif
141 :
142 : using namespace ::com::sun::star::awt;
143 : using namespace ::com::sun::star::uno;
144 : using namespace ::com::sun::star::util;
145 : using namespace ::com::sun::star::lang;
146 : using namespace ::com::sun::star::beans;
147 : using namespace ::com::sun::star::frame;
148 : using namespace ::com::sun::star::document;
149 : using namespace ::com::sun::star::view;
150 : using namespace ::com::sun::star::task;
151 : using namespace ::com::sun::star::system;
152 : using namespace ::com::sun::star::ui;
153 : using namespace ::com::sun::star::ui::dialogs;
154 : using namespace ::com::sun::star::container;
155 :
156 : ResMgr* desktop::Desktop::pResMgr = 0;
157 :
158 : namespace desktop
159 : {
160 :
161 : static oslSignalHandler pSignalHandler = 0;
162 :
163 : namespace {
164 :
165 : #if HAVE_FEATURE_EXTENSIONS
166 :
167 : // Remove any existing UserInstallation's extensions cache data remaining from
168 : // old installations. This addresses at least two problems:
169 : //
170 : // For one, apparently due to the old share/prereg/bundled mechanism (disabled
171 : // since 5c47e5f63a79a9e72ec4a100786b1bbf65137ed4 "fdo#51252 Disable copying
172 : // share/prereg/bundled to avoid startup crashes"), the user/extensions/bundled
173 : // cache could contain corrupted information (like a UNO component registered
174 : // twice, which got changed from active to passive registration in one LO
175 : // version, but the version of the corresponding bundled extension only
176 : // incremented in a later LO version).
177 : //
178 : // For another, UserInstallations have been seen in the wild where no extensions
179 : // were installed per-user (any longer), but user/uno_packages/cache/registry/
180 : // com.sun.star.comp.deployment.component.PackageRegistryBackend/*.rdb files
181 : // contained data nevertheless.
182 : //
183 : // When a LO upgrade is detected (i.e., no user/extensions/buildid or one
184 : // containing an old build ID), then user/extensions and
185 : // user/uno_packages/cache/registry/
186 : // com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc are
187 : // removed. That should prevent any problems starting the service manager due
188 : // to old junk. Later on in Desktop::SynchronizeExtensionRepositories, the
189 : // removed cache data is recreated.
190 : //
191 : // Multiple instances of soffice.bin can execute this code in parallel for a
192 : // single UserInstallation, as it is called before OfficeIPCThread is set up.
193 : // Therefore, any errors here only lead to SAL_WARNs.
194 : //
195 : // At least in theory, this function could be removed again once no
196 : // UserInstallation can be poisoned by old junk any more.
197 160 : bool cleanExtensionCache() {
198 : OUString buildId(
199 160 : "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("version") ":buildid}");
200 160 : rtl::Bootstrap::expandMacros(buildId); //TODO: detect failure
201 : OUString extDir(
202 : "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap")
203 320 : ":UserInstallation}/user/extensions");
204 160 : rtl::Bootstrap::expandMacros(extDir); //TODO: detect failure
205 320 : OUString buildIdFile(extDir + "/buildid");
206 320 : osl::File fr(buildIdFile);
207 160 : osl::FileBase::RC rc = fr.open(osl_File_OpenFlag_Read);
208 160 : switch (rc) {
209 : case osl::FileBase::E_None:
210 : {
211 96 : rtl::ByteSequence s1;
212 96 : rc = fr.readLine(s1);
213 96 : osl::FileBase::RC rc2 = fr.close();
214 : SAL_WARN_IF(
215 : rc2 != osl::FileBase::E_None, "desktop.app",
216 : "cannot close " << fr.getURL() << " after reading: " << +rc2);
217 : // readLine returns E_AGAIN for a zero-size file:
218 96 : if (rc != osl::FileBase::E_None && rc != osl::FileBase::E_AGAIN) {
219 : SAL_WARN( "desktop.app", "cannot read from " << fr.getURL() << ": " << +rc);
220 0 : break;
221 : }
222 : OUString s2(
223 96 : reinterpret_cast< char const * >(s1.getConstArray()),
224 192 : s1.getLength(), RTL_TEXTENCODING_ISO_8859_1);
225 : // using ISO 8859-1 avoids any and all conversion errors; the
226 : // content should only be a subset of ASCII, anyway
227 96 : if (s2 == buildId) {
228 96 : return false;
229 : }
230 0 : break;
231 : }
232 : case osl::FileBase::E_NOENT:
233 64 : break;
234 : default:
235 : SAL_WARN( "desktop.app", "cannot open " << fr.getURL() << " for reading: " << +rc);
236 0 : break;
237 : }
238 64 : utl::removeTree(extDir);
239 : OUString userRcFile(
240 : "$UNO_USER_PACKAGES_CACHE/registry/"
241 64 : "com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
242 64 : rtl::Bootstrap::expandMacros(userRcFile); //TODO: detect failure
243 64 : rc = osl::File::remove(userRcFile);
244 : SAL_WARN_IF(
245 : rc != osl::FileBase::E_None && rc != osl::FileBase::E_NOENT, "desktop.app",
246 : "cannot remove file " << userRcFile << ": " << +rc);
247 64 : rc = osl::Directory::createPath(extDir);
248 : SAL_WARN_IF(
249 : rc != osl::FileBase::E_None && rc != osl::FileBase::E_EXIST, "desktop.app",
250 : "cannot create path " << extDir << ": " << +rc);
251 128 : osl::File fw(buildIdFile);
252 64 : rc = fw.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
253 64 : if (rc != osl::FileBase::E_None) {
254 : SAL_WARN( "desktop.app", "cannot open " << fw.getURL() << " for writing: " << +rc);
255 0 : return true;
256 : }
257 128 : OString buf(OUStringToOString(buildId, RTL_TEXTENCODING_UTF8));
258 : // using UTF-8 avoids almost all conversion errors (and buildid
259 : // containing single surrogate halves should never happen, anyway); the
260 : // content should only be a subset of ASCII, anyway
261 64 : sal_uInt64 n = 0;
262 64 : rc = fw.write(buf.getStr(), buf.getLength(), n);
263 : SAL_WARN_IF(
264 : (rc != osl::FileBase::E_None
265 : || n != static_cast< sal_uInt32 >(buf.getLength())),
266 : "desktop.app",
267 : "cannot write to " << fw.getURL() << ": " << +rc << ", " << n);
268 64 : rc = fw.close();
269 : SAL_WARN_IF(
270 : rc != osl::FileBase::E_None, "desktop.app",
271 : "cannot close " << fw.getURL() << " after writing: " << +rc);
272 288 : return true;
273 : }
274 :
275 : #endif
276 :
277 0 : bool shouldLaunchQuickstart()
278 : {
279 0 : bool bQuickstart = Desktop::GetCommandLineArgs().IsQuickstart();
280 0 : if (!bQuickstart)
281 : {
282 0 : const SfxPoolItem* pItem=0;
283 0 : SfxItemSet aQLSet(SfxGetpApp()->GetPool(), SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER);
284 0 : SfxGetpApp()->GetOptions(aQLSet);
285 0 : SfxItemState eState = aQLSet.GetItemState(SID_ATTR_QUICKLAUNCHER, false, &pItem);
286 0 : if (SfxItemState::SET == eState)
287 0 : bQuickstart = static_cast<const SfxBoolItem*>(pItem)->GetValue();
288 : }
289 0 : return bQuickstart;
290 : }
291 :
292 64 : void SetRestartState() {
293 : try {
294 : boost::shared_ptr< comphelper::ConfigurationChanges > batch(
295 64 : comphelper::ConfigurationChanges::create());
296 64 : officecfg::Setup::Office::OfficeRestartInProgress::set(true, batch);
297 64 : batch->commit();
298 0 : } catch (css::uno::Exception & e) {
299 : SAL_WARN("desktop.app", "ignoring Exception \"" << e.Message << "\"");
300 : }
301 64 : }
302 :
303 96 : void DoRestartActionsIfNecessary(bool quickstart) {
304 96 : if (quickstart) {
305 : try {
306 0 : if (officecfg::Setup::Office::OfficeRestartInProgress::get()) {
307 : boost::shared_ptr< comphelper::ConfigurationChanges > batch(
308 0 : comphelper::ConfigurationChanges::create());
309 : officecfg::Setup::Office::OfficeRestartInProgress::set(
310 0 : false, batch);
311 0 : batch->commit();
312 : css::office::Quickstart::createStart(
313 : comphelper::getProcessComponentContext(),
314 0 : shouldLaunchQuickstart());
315 : }
316 0 : } catch (css::uno::Exception & e) {
317 : SAL_WARN(
318 : "desktop.app", "ignoring Exception \"" << e.Message << "\"");
319 : }
320 : }
321 96 : }
322 :
323 : }
324 :
325 :
326 :
327 0 : ResMgr* Desktop::GetDesktopResManager()
328 : {
329 0 : if ( !Desktop::pResMgr )
330 : {
331 : // Create desktop resource manager and bootstrap process
332 : // was successful. Use default way to get language specific message.
333 0 : if ( Application::IsInExecute() )
334 0 : Desktop::pResMgr = ResMgr::CreateResMgr("dkt");
335 :
336 0 : if ( !Desktop::pResMgr )
337 : {
338 : // Use VCL to get the correct language specific message as we
339 : // are in the bootstrap process and not able to get the installed
340 : // language!!
341 0 : OUString aUILocaleString = langselect::getEmergencyLocale();
342 0 : LanguageTag aLanguageTag( aUILocaleString);
343 : //! ResMgr may modify the Locale for fallback!
344 0 : Desktop::pResMgr = ResMgr::SearchCreateResMgr( "dkt", aLanguageTag);
345 0 : AllSettings as = GetSettings();
346 0 : as.SetUILanguageTag(aLanguageTag);
347 0 : SetSettings(as);
348 : }
349 : }
350 :
351 0 : return Desktop::pResMgr;
352 : }
353 :
354 : namespace {
355 :
356 :
357 : // Get a message string securely. There is a fallback string if the resource
358 : // is not available.
359 :
360 0 : OUString GetMsgString(
361 : sal_uInt16 nId, const OUString& aFallbackMsg,
362 : bool bAlwaysUseFallbackMsg = false )
363 : {
364 0 : if ( !bAlwaysUseFallbackMsg )
365 : {
366 0 : ResMgr* resMgr = Desktop::GetDesktopResManager();
367 0 : if ( resMgr )
368 0 : return ResId(nId, *resMgr).toString();
369 : }
370 0 : return aFallbackMsg;
371 : }
372 :
373 0 : OUString MakeStartupErrorMessage(
374 : OUString const & aErrorMessage, bool bAlwaysUseFallbackMsg = false )
375 : {
376 0 : OUStringBuffer aDiagnosticMessage( 100 );
377 :
378 : aDiagnosticMessage.append(
379 : GetMsgString(
380 : STR_BOOTSTRAP_ERR_CANNOT_START, "The program cannot be started.",
381 0 : bAlwaysUseFallbackMsg ) );
382 :
383 0 : aDiagnosticMessage.appendAscii( "\n" );
384 :
385 0 : aDiagnosticMessage.append( aErrorMessage );
386 :
387 0 : return aDiagnosticMessage.makeStringAndClear();
388 : }
389 :
390 0 : OUString MakeStartupConfigAccessErrorMessage( OUString const & aInternalErrMsg )
391 : {
392 0 : OUStringBuffer aDiagnosticMessage( 200 );
393 :
394 0 : ResMgr* pResMgr = Desktop::GetDesktopResManager();
395 0 : if ( pResMgr )
396 0 : aDiagnosticMessage.append( ResId(STR_BOOTSTRAP_ERR_CFG_DATAACCESS, *pResMgr).toString() );
397 : else
398 0 : aDiagnosticMessage.appendAscii( "The program cannot be started." );
399 :
400 0 : if ( !aInternalErrMsg.isEmpty() )
401 : {
402 0 : aDiagnosticMessage.appendAscii( "\n\n" );
403 0 : if ( pResMgr )
404 0 : aDiagnosticMessage.append( ResId(STR_INTERNAL_ERRMSG, *pResMgr).toString() );
405 : else
406 0 : aDiagnosticMessage.appendAscii( "The following internal error has occurred:\n\n" );
407 0 : aDiagnosticMessage.append( aInternalErrMsg );
408 : }
409 :
410 0 : return aDiagnosticMessage.makeStringAndClear();
411 : }
412 :
413 :
414 : // shows a simple error box with the given message ... but exits from these process !
415 : // Fatal errors can't be solved by the process ... nor any recovery can help.
416 : // Mostly the installation was damaged and must be repaired manually .. or by calling
417 : // setup again.
418 : // On the other side we must make sure that no further actions will be possible within
419 : // the current office process ! No pipe requests, no menu/toolbar/shortuct actions
420 : // are allowed. Otherwise we will force a "crash inside a crash".
421 : // Thats why we have to use a special native message box here which does not use yield :-)
422 :
423 0 : void FatalError(const OUString& sMessage)
424 : {
425 0 : OUString sProductKey = ::utl::Bootstrap::getProductKey();
426 0 : if ( sProductKey.isEmpty())
427 : {
428 0 : osl_getExecutableFile( &sProductKey.pData );
429 :
430 0 : ::sal_uInt32 nLastIndex = sProductKey.lastIndexOf('/');
431 0 : if ( nLastIndex > 0 )
432 0 : sProductKey = sProductKey.copy( nLastIndex+1 );
433 : }
434 :
435 0 : OUStringBuffer sTitle (128);
436 0 : sTitle.append (sProductKey );
437 0 : sTitle.appendAscii (" - Fatal Error");
438 :
439 0 : Application::ShowNativeErrorBox (sTitle.makeStringAndClear (), sMessage);
440 0 : _exit(EXITHELPER_FATAL_ERROR);
441 : }
442 :
443 160 : static bool ShouldSuppressUI(const CommandLineArgs& rCmdLine)
444 : {
445 160 : return rCmdLine.IsInvisible() ||
446 160 : rCmdLine.IsHeadless() ||
447 160 : rCmdLine.IsQuickstart();
448 : }
449 :
450 : struct theCommandLineArgs : public rtl::Static< CommandLineArgs, theCommandLineArgs > {};
451 :
452 : }
453 :
454 1216 : CommandLineArgs& Desktop::GetCommandLineArgs()
455 : {
456 1216 : return theCommandLineArgs::get();
457 : }
458 :
459 : namespace
460 : {
461 : struct BrandName
462 : : public rtl::Static< OUString, BrandName > {};
463 : struct Version
464 : : public rtl::Static< OUString, Version > {};
465 : struct AboutBoxVersion
466 : : public rtl::Static< OUString, AboutBoxVersion > {};
467 : struct AboutBoxVersionSuffix
468 : : public rtl::Static< OUString, AboutBoxVersionSuffix > {};
469 : struct OOOVendor
470 : : public rtl::Static< OUString, OOOVendor > {};
471 : struct Extension
472 : : public rtl::Static< OUString, Extension > {};
473 : }
474 :
475 1328800 : OUString ReplaceStringHookProc( const OUString& rStr )
476 : {
477 1328800 : OUString sRet(rStr);
478 :
479 1328800 : if (sRet.indexOf("%PRODUCT") != -1 || sRet.indexOf("%ABOUTBOX") != -1)
480 : {
481 1940 : OUString sBrandName = BrandName::get();
482 3880 : OUString sVersion = Version::get();
483 3880 : OUString sBuildId = utl::Bootstrap::getBuildIdData("development");
484 3880 : OUString sAboutBoxVersion = AboutBoxVersion::get();
485 3880 : OUString sAboutBoxVersionSuffix = AboutBoxVersionSuffix::get();
486 3880 : OUString sExtension = Extension::get();
487 :
488 1940 : if ( sBrandName.isEmpty() )
489 : {
490 1940 : sBrandName = utl::ConfigManager::getProductName();
491 1940 : sVersion = utl::ConfigManager::getProductVersion();
492 1940 : sAboutBoxVersion = utl::ConfigManager::getAboutBoxProductVersion();
493 1940 : sAboutBoxVersionSuffix = utl::ConfigManager::getAboutBoxProductVersionSuffix();
494 1940 : if ( sExtension.isEmpty() )
495 : {
496 1940 : sExtension = utl::ConfigManager::getProductExtension();
497 : }
498 : }
499 :
500 1940 : sRet = sRet.replaceAll( "%PRODUCTNAME", sBrandName );
501 1940 : sRet = sRet.replaceAll( "%PRODUCTVERSION", sVersion );
502 1940 : sRet = sRet.replaceAll( "%BUILDID", sBuildId );
503 1940 : sRet = sRet.replaceAll( "%ABOUTBOXPRODUCTVERSIONSUFFIX", sAboutBoxVersionSuffix );
504 1940 : sRet = sRet.replaceAll( "%ABOUTBOXPRODUCTVERSION", sAboutBoxVersion );
505 3880 : sRet = sRet.replaceAll( "%PRODUCTEXTENSION", sExtension );
506 : }
507 :
508 1328800 : if ( sRet.indexOf( "%OOOVENDOR" ) != -1 )
509 : {
510 0 : OUString sOOOVendor = OOOVendor::get();
511 :
512 0 : if ( sOOOVendor.isEmpty() )
513 : {
514 0 : sOOOVendor = utl::ConfigManager::getVendor();
515 : }
516 :
517 0 : sRet = sRet.replaceAll( "%OOOVENDOR", sOOOVendor );
518 : }
519 :
520 1328800 : return sRet;
521 : }
522 :
523 160 : Desktop::Desktop()
524 : : m_bCleanedExtensionCache(false)
525 : , m_bServicesRegistered(false)
526 : , m_aBootstrapError(BE_OK)
527 160 : , m_aBootstrapStatus(BS_OK)
528 : {
529 : SAL_INFO( "desktop.app", "desktop (cd100003) ::Desktop::Desktop" );
530 160 : }
531 :
532 160 : Desktop::~Desktop()
533 : {
534 : #if ENABLE_TELEPATHY
535 : TeleManager::finalize();
536 : #endif
537 160 : }
538 :
539 160 : void Desktop::Init()
540 : {
541 : SAL_INFO( "desktop.app", "desktop (cd100003) ::Desktop::Init" );
542 160 : SetBootstrapStatus(BS_OK);
543 :
544 : #if HAVE_FEATURE_EXTENSIONS
545 160 : m_bCleanedExtensionCache = cleanExtensionCache();
546 : #endif
547 :
548 : // We need to have service factory before going further, but see fdo#37195.
549 : // Doing this will mmap common.rdb, making it not overwritable on windows,
550 : // so this can't happen before the synchronization above. Lets rework this
551 : // so that the above is called *from* CreateApplicationServiceManager or
552 : // something to enforce this gotcha
553 : try
554 : {
555 160 : InitApplicationServiceManager();
556 : }
557 0 : catch (css::uno::Exception & e)
558 : {
559 0 : SetBootstrapError( BE_UNO_SERVICEMANAGER, e.Message );
560 : }
561 :
562 160 : if ( m_aBootstrapError == BE_OK )
563 : {
564 : try
565 : {
566 160 : if (!langselect::prepareLocale())
567 : {
568 0 : SetBootstrapError( BE_LANGUAGE_MISSING, OUString() );
569 : }
570 : }
571 0 : catch (css::uno::Exception & e)
572 : {
573 0 : SetBootstrapError( BE_OFFICECONFIG_BROKEN, e.Message );
574 : }
575 : }
576 :
577 : if ( true )
578 : {
579 160 : const CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
580 :
581 : // start ipc thread only for non-remote offices
582 : SAL_INFO( "desktop.app", "desktop (cd100003) ::OfficeIPCThread::EnableOfficeIPCThread" );
583 160 : OfficeIPCThread::Status aStatus = OfficeIPCThread::EnableOfficeIPCThread();
584 160 : if ( aStatus == OfficeIPCThread::IPC_STATUS_PIPE_ERROR )
585 : {
586 : #if HAVE_FEATURE_MACOSX_SANDBOX
587 : // In a sandboxed LO, on 10.8.2 at least, creating the
588 : // Unix domain socket fails. Ignore that as hopefully
589 : // people running a sandboxed LO won't attempt starting it
590 : // from the command-line or otherwise in tricky ways, so
591 : // the normal OS X mechanism that prevents multiple
592 : // instances of an app from being started should work
593 : // fine. I hope.
594 : #elif defined ANDROID
595 : // Ignore crack pipe errors on Android, too
596 : #else
597 : // Keep using this oddly named BE_PATHINFO_MISSING value
598 : // for pipe-related errors on other platforms. Of course
599 : // this crack with two (if not more) levels of our own
600 : // error codes hiding the actual system error code is
601 : // broken, but that is done all over the code, let's leave
602 : // re-enginering that to another year.
603 0 : SetBootstrapError( BE_PATHINFO_MISSING, OUString() );
604 : #endif
605 : }
606 160 : else if ( aStatus == OfficeIPCThread::IPC_STATUS_BOOTSTRAP_ERROR )
607 : {
608 0 : SetBootstrapError( BE_PATHINFO_MISSING, OUString() );
609 : }
610 160 : else if ( aStatus == OfficeIPCThread::IPC_STATUS_2ND_OFFICE )
611 : {
612 : // 2nd office startup should terminate after sending cmdlineargs through pipe
613 0 : SetBootstrapStatus(BS_TERMINATE);
614 : }
615 480 : else if ( !rCmdLineArgs.GetUnknown().isEmpty()
616 480 : || rCmdLineArgs.IsHelp() || rCmdLineArgs.IsVersion() )
617 : {
618 : // disable IPC thread in an instance that is just showing a help message
619 0 : OfficeIPCThread::DisableOfficeIPCThread();
620 : }
621 160 : pSignalHandler = osl_addSignalHandler(SalMainPipeExchangeSignal_impl, NULL);
622 : }
623 160 : }
624 :
625 1350 : void Desktop::InitFinished()
626 : {
627 : SAL_INFO( "desktop.app", "desktop (cd100003) ::Desktop::InitFinished" );
628 :
629 1350 : CloseSplashScreen();
630 1350 : }
631 :
632 160 : void Desktop::DeInit()
633 : {
634 : SAL_INFO( "desktop.app", "desktop (cd100003) ::Desktop::DeInit" );
635 :
636 : try {
637 : // instead of removing of the configManager just let it commit all the changes
638 : SAL_INFO( "desktop.app", "<- store config items" );
639 160 : utl::ConfigManager::storeConfigItems();
640 160 : FlushConfiguration();
641 : SAL_INFO( "desktop.app", "<- store config items" );
642 :
643 : // close splashscreen if it's still open
644 160 : CloseSplashScreen();
645 : Reference< XComponent >(
646 320 : comphelper::getProcessComponentContext(), UNO_QUERY_THROW )->
647 160 : dispose();
648 : // nobody should get a destroyed service factory...
649 160 : ::comphelper::setProcessServiceFactory( NULL );
650 :
651 : // clear lockfile
652 160 : m_xLockfile.reset();
653 :
654 160 : OfficeIPCThread::DisableOfficeIPCThread();
655 160 : if( pSignalHandler )
656 160 : osl_removeSignalHandler( pSignalHandler );
657 0 : } catch (const RuntimeException&) {
658 : // someone threw an exception during shutdown
659 : // this will leave some garbage behind..
660 : }
661 :
662 : SAL_INFO( "desktop.app", "FINISHED WITH Desktop::DeInit" );
663 160 : }
664 :
665 0 : bool Desktop::QueryExit()
666 : {
667 : try
668 : {
669 : SAL_INFO( "desktop.app", "<- store config items" );
670 0 : utl::ConfigManager::storeConfigItems();
671 : SAL_INFO( "desktop.app", "<- store config items" );
672 : }
673 0 : catch ( const RuntimeException& )
674 : {
675 : }
676 :
677 0 : const sal_Char SUSPEND_QUICKSTARTVETO[] = "SuspendQuickstartVeto";
678 :
679 0 : Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
680 0 : Reference< XPropertySet > xPropertySet(xDesktop, UNO_QUERY_THROW);
681 0 : xPropertySet->setPropertyValue( OUString(SUSPEND_QUICKSTARTVETO ), Any(true) );
682 :
683 0 : bool bExit = xDesktop->terminate();
684 :
685 0 : if ( !bExit )
686 : {
687 0 : xPropertySet->setPropertyValue( OUString(SUSPEND_QUICKSTARTVETO ), Any(false) );
688 : }
689 : else
690 : {
691 0 : FlushConfiguration();
692 : try
693 : {
694 : // it is no problem to call DisableOfficeIPCThread() more than once
695 : // it also looks to be threadsafe
696 0 : OfficeIPCThread::DisableOfficeIPCThread();
697 : }
698 0 : catch ( const RuntimeException& )
699 : {
700 : }
701 :
702 0 : m_xLockfile.reset();
703 :
704 : }
705 :
706 0 : return bExit;
707 : }
708 :
709 0 : void Desktop::HandleBootstrapPathErrors( ::utl::Bootstrap::Status aBootstrapStatus, const OUString& aDiagnosticMessage )
710 : {
711 0 : if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
712 : {
713 0 : OUString aProductKey;
714 0 : OUString aTemp;
715 :
716 0 : osl_getExecutableFile( &aProductKey.pData );
717 0 : sal_uInt32 lastIndex = aProductKey.lastIndexOf('/');
718 0 : if ( lastIndex > 0 )
719 0 : aProductKey = aProductKey.copy( lastIndex+1 );
720 :
721 0 : aTemp = ::utl::Bootstrap::getProductKey( aProductKey );
722 0 : if ( !aTemp.isEmpty() )
723 0 : aProductKey = aTemp;
724 :
725 0 : OUString const aMessage(aDiagnosticMessage + "\n");
726 :
727 0 : MessageDialog aBootstrapFailedBox(NULL, aMessage);
728 0 : aBootstrapFailedBox.SetText( aProductKey );
729 0 : aBootstrapFailedBox.Execute();
730 : }
731 0 : }
732 :
733 : // Create a error message depending on bootstrap failure code and an optional file url
734 0 : OUString Desktop::CreateErrorMsgString(
735 : utl::Bootstrap::FailureCode nFailureCode,
736 : const OUString& aFileURL )
737 : {
738 0 : OUString aMsg;
739 0 : OUString aFilePath;
740 0 : bool bFileInfo = true;
741 :
742 0 : switch ( nFailureCode )
743 : {
744 : /// the shared installation directory could not be located
745 : case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
746 : {
747 0 : aMsg = GetMsgString( STR_BOOTSTRAP_ERR_PATH_INVALID,
748 0 : OUString( "The installation path is not available." ) );
749 0 : bFileInfo = false;
750 : }
751 0 : break;
752 :
753 : /// the bootstrap INI file could not be found or read
754 : case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
755 : {
756 0 : aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
757 0 : OUString( "The configuration file \"$1\" is missing." ) );
758 : }
759 0 : break;
760 :
761 : /// the bootstrap INI is missing a required entry
762 : /// the bootstrap INI contains invalid data
763 : case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
764 : case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
765 : {
766 0 : aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_CORRUPT,
767 0 : OUString( "The configuration file \"$1\" is corrupt." ) );
768 : }
769 0 : break;
770 :
771 : /// the version locator INI file could not be found or read
772 : case ::utl::Bootstrap::MISSING_VERSION_FILE:
773 : {
774 0 : aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
775 0 : OUString( "The configuration file \"$1\" is missing." ) );
776 : }
777 0 : break;
778 :
779 : /// the version locator INI has no entry for this version
780 : case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
781 : {
782 0 : aMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SUPPORT,
783 0 : OUString( "The main configuration file \"$1\" does not support the current version." ) );
784 : }
785 0 : break;
786 :
787 : /// the user installation directory does not exist
788 : case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
789 : {
790 0 : aMsg = GetMsgString( STR_BOOTSTRAP_ERR_DIR_MISSING,
791 0 : OUString( "The configuration directory \"$1\" is missing." ) );
792 : }
793 0 : break;
794 :
795 : /// some bootstrap data was invalid in unexpected ways
796 : case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
797 : {
798 0 : aMsg = GetMsgString( STR_BOOTSTRAP_ERR_INTERNAL,
799 0 : OUString( "An internal failure occurred." ) );
800 0 : bFileInfo = false;
801 : }
802 0 : break;
803 :
804 : case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
805 : {
806 : // This needs to be improved, see #i67575#:
807 0 : aMsg = "Invalid version file entry";
808 0 : bFileInfo = false;
809 : }
810 0 : break;
811 :
812 : case ::utl::Bootstrap::NO_FAILURE:
813 : {
814 : OSL_ASSERT(false);
815 : }
816 0 : break;
817 : }
818 :
819 0 : if ( bFileInfo )
820 : {
821 0 : OUString aMsgString( aMsg );
822 :
823 0 : osl::File::getSystemPathFromFileURL( aFileURL, aFilePath );
824 :
825 0 : aMsgString = aMsgString.replaceFirst( "$1", aFilePath );
826 0 : aMsg = aMsgString;
827 : }
828 :
829 0 : return MakeStartupErrorMessage( aMsg );
830 : }
831 :
832 0 : void Desktop::HandleBootstrapErrors(
833 : BootstrapError aBootstrapError, OUString const & aErrorMessage )
834 : {
835 0 : if ( aBootstrapError == BE_PATHINFO_MISSING )
836 : {
837 0 : OUString aErrorMsg;
838 0 : OUString aBuffer;
839 : utl::Bootstrap::Status aBootstrapStatus;
840 : utl::Bootstrap::FailureCode nFailureCode;
841 :
842 0 : aBootstrapStatus = ::utl::Bootstrap::checkBootstrapStatus( aBuffer, nFailureCode );
843 0 : if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
844 : {
845 0 : switch ( nFailureCode )
846 : {
847 : case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
848 : case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
849 : {
850 0 : aErrorMsg = CreateErrorMsgString( nFailureCode, OUString() );
851 : }
852 0 : break;
853 :
854 : /// the bootstrap INI file could not be found or read
855 : /// the bootstrap INI is missing a required entry
856 : /// the bootstrap INI contains invalid data
857 : case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
858 : case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
859 : case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
860 : {
861 0 : OUString aBootstrapFileURL;
862 :
863 0 : utl::Bootstrap::locateBootstrapFile( aBootstrapFileURL );
864 0 : aErrorMsg = CreateErrorMsgString( nFailureCode, aBootstrapFileURL );
865 : }
866 0 : break;
867 :
868 : /// the version locator INI file could not be found or read
869 : /// the version locator INI has no entry for this version
870 : /// the version locator INI entry is not a valid directory URL
871 : case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
872 : case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
873 : case ::utl::Bootstrap::MISSING_VERSION_FILE:
874 : {
875 0 : OUString aVersionFileURL;
876 :
877 0 : utl::Bootstrap::locateVersionFile( aVersionFileURL );
878 0 : aErrorMsg = CreateErrorMsgString( nFailureCode, aVersionFileURL );
879 : }
880 0 : break;
881 :
882 : /// the user installation directory does not exist
883 : case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
884 : {
885 0 : OUString aUserInstallationURL;
886 :
887 0 : utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
888 0 : aErrorMsg = CreateErrorMsgString( nFailureCode, aUserInstallationURL );
889 : }
890 0 : break;
891 :
892 : case ::utl::Bootstrap::NO_FAILURE:
893 : {
894 : OSL_ASSERT(false);
895 : }
896 0 : break;
897 : }
898 :
899 0 : HandleBootstrapPathErrors( aBootstrapStatus, aErrorMsg );
900 0 : }
901 : }
902 0 : else if ( aBootstrapError == BE_UNO_SERVICEMANAGER || aBootstrapError == BE_UNO_SERVICE_CONFIG_MISSING )
903 : {
904 : // Uno service manager is not available. VCL needs a uno service manager to display a message box!!!
905 : // Currently we are not able to display a message box with a service manager due to this limitations inside VCL.
906 :
907 : // When UNO is not properly initialized, all kinds of things can fail
908 : // and cause the process to crash (e.g., a call to GetMsgString may
909 : // crash when somewhere deep within that call Any::operator <= is used
910 : // with a PropertyValue, and no binary UNO type description for
911 : // PropertyValue is available). To give the user a hint even if
912 : // generating and displaying a message box below crashes, print a
913 : // hard-coded message on stderr first:
914 : std::cerr
915 0 : << "The application cannot be started.\n"
916 : // STR_BOOTSTRAP_ERR_CANNOT_START
917 : << (aBootstrapError == BE_UNO_SERVICEMANAGER
918 : ? "The component manager is not available.\n"
919 : // STR_BOOTSTRAP_ERR_NO_SERVICE
920 0 : : "The configuration service is not available.\n");
921 : // STR_BOOTSTRAP_ERR_NO_CFG_SERVICE
922 0 : if ( !aErrorMessage.isEmpty() )
923 : {
924 0 : std::cerr << "(\"" << aErrorMessage << "\")\n";
925 : }
926 :
927 : // First sentence. We cannot bootstrap office further!
928 0 : OUString aMessage;
929 0 : OUStringBuffer aDiagnosticMessage( 100 );
930 :
931 0 : OUString aErrorMsg;
932 :
933 0 : if ( aBootstrapError == BE_UNO_SERVICEMANAGER )
934 0 : aErrorMsg = "The service manager is not available.";
935 : else
936 0 : aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_CFG_SERVICE,
937 0 : OUString( "The configuration service is not available." ) );
938 :
939 0 : aDiagnosticMessage.append( aErrorMsg );
940 0 : aDiagnosticMessage.appendAscii( "\n" );
941 0 : if ( !aErrorMessage.isEmpty() )
942 : {
943 0 : aDiagnosticMessage.appendAscii( "(\"" );
944 0 : aDiagnosticMessage.append( aErrorMessage );
945 0 : aDiagnosticMessage.appendAscii( "\")\n" );
946 : }
947 :
948 : // Due to the fact the we haven't a backup applicat.rdb file anymore it is not possible to
949 : // repair the installation with the setup executable besides the office executable. Now
950 : // we have to ask the user to start the setup on CD/installation directory manually!!
951 : OUString aStartSetupManually( GetMsgString(
952 : STR_ASK_START_SETUP_MANUALLY,
953 : OUString( "Start setup application to repair the installation from CD, or the folder containing the installation packages." ),
954 0 : aBootstrapError == BE_UNO_SERVICEMANAGER ) );
955 :
956 0 : aDiagnosticMessage.append( aStartSetupManually );
957 0 : aMessage = MakeStartupErrorMessage(
958 : aDiagnosticMessage.makeStringAndClear(),
959 0 : aBootstrapError == BE_UNO_SERVICEMANAGER );
960 :
961 0 : FatalError( aMessage);
962 : }
963 0 : else if ( aBootstrapError == BE_OFFICECONFIG_BROKEN )
964 : {
965 : OUString msg(
966 : GetMsgString(
967 : STR_CONFIG_ERR_ACCESS_GENERAL,
968 : ("A general error occurred while accessing your central"
969 0 : " configuration.")));
970 0 : if (!aErrorMessage.isEmpty()) {
971 0 : msg += "\n(\"" + aErrorMessage + "\")";
972 : }
973 0 : FatalError(MakeStartupErrorMessage(msg));
974 : }
975 0 : else if ( aBootstrapError == BE_USERINSTALL_FAILED )
976 : {
977 0 : OUString aMessage;
978 0 : OUStringBuffer aDiagnosticMessage( 100 );
979 0 : OUString aErrorMsg;
980 0 : aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_USERINSTALL_FAILED,
981 0 : OUString( "User installation could not be completed" ) );
982 0 : aDiagnosticMessage.append( aErrorMsg );
983 0 : aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
984 0 : FatalError(aMessage);
985 : }
986 0 : else if ( aBootstrapError == BE_LANGUAGE_MISSING )
987 : {
988 0 : OUString aMessage;
989 0 : OUStringBuffer aDiagnosticMessage( 100 );
990 0 : OUString aErrorMsg;
991 0 : aErrorMsg = GetMsgString(
992 : //@@@ FIXME: should use an own resource string => #i36213#
993 : STR_BOOTSTRAP_ERR_LANGUAGE_MISSING,
994 0 : OUString( "Language could not be determined." ) );
995 0 : aDiagnosticMessage.append( aErrorMsg );
996 0 : aMessage = MakeStartupErrorMessage(
997 0 : aDiagnosticMessage.makeStringAndClear() );
998 0 : FatalError(aMessage);
999 : }
1000 0 : else if (( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE ) ||
1001 : ( aBootstrapError == BE_USERINSTALL_NOWRITEACCESS ))
1002 : {
1003 0 : OUString aUserInstallationURL;
1004 0 : OUString aUserInstallationPath;
1005 0 : OUString aMessage;
1006 0 : OUString aErrorMsg;
1007 0 : OUStringBuffer aDiagnosticMessage( 100 );
1008 :
1009 0 : utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
1010 :
1011 0 : if ( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE )
1012 0 : aErrorMsg = GetMsgString(
1013 : STR_BOOSTRAP_ERR_NOTENOUGHDISKSPACE,
1014 0 : OUString( "User installation could not be completed due to insufficient free disk space." ) );
1015 : else
1016 0 : aErrorMsg = GetMsgString(
1017 : STR_BOOSTRAP_ERR_NOACCESSRIGHTS,
1018 0 : OUString( "User installation could not be processed due to missing access rights." ) );
1019 :
1020 0 : osl::File::getSystemPathFromFileURL( aUserInstallationURL, aUserInstallationPath );
1021 :
1022 0 : aDiagnosticMessage.append( aErrorMsg );
1023 0 : aDiagnosticMessage.append( aUserInstallationPath );
1024 0 : aMessage = MakeStartupErrorMessage(
1025 0 : aDiagnosticMessage.makeStringAndClear() );
1026 0 : FatalError(aMessage);
1027 : }
1028 :
1029 0 : return;
1030 : }
1031 :
1032 :
1033 0 : bool Desktop::isUIOnSessionShutdownAllowed()
1034 : {
1035 : return officecfg::Office::Recovery::SessionShutdown::DocumentStoreUIEnabled
1036 0 : ::get();
1037 : }
1038 :
1039 :
1040 : /** @short check if recovery must be started or not.
1041 :
1042 : @param bCrashed [boolean ... out!]
1043 : the office crashed last times.
1044 : But may be there are no recovery data.
1045 : Useful to trigger the error report tool without
1046 : showing the recovery UI.
1047 :
1048 : @param bRecoveryDataExists [boolean ... out!]
1049 : there exists some recovery data.
1050 :
1051 : @param bSessionDataExists [boolean ... out!]
1052 : there exists some session data.
1053 : Because the user may be logged out last time from it's
1054 : unix session...
1055 : */
1056 160 : void impl_checkRecoveryState(bool& bCrashed ,
1057 : bool& bRecoveryDataExists,
1058 : bool& bSessionDataExists )
1059 : {
1060 160 : bCrashed = officecfg::Office::Recovery::RecoveryInfo::Crashed::get();
1061 320 : bool elements = officecfg::Office::Recovery::RecoveryList::get()->
1062 160 : hasElements();
1063 : bool session
1064 160 : = officecfg::Office::Recovery::RecoveryInfo::SessionData::get();
1065 160 : bRecoveryDataExists = elements && !session;
1066 160 : bSessionDataExists = elements && session;
1067 160 : }
1068 :
1069 :
1070 : /* @short start the recovery wizard.
1071 :
1072 : @param bEmergencySave
1073 : differs between EMERGENCY_SAVE and RECOVERY
1074 : */
1075 0 : bool impl_callRecoveryUI(bool bEmergencySave ,
1076 : bool bExistsRecoveryData)
1077 : {
1078 0 : static OUString SERVICENAME_RECOVERYUI("com.sun.star.comp.svx.RecoveryUI");
1079 0 : static OUString COMMAND_EMERGENCYSAVE("vnd.sun.star.autorecovery:/doEmergencySave");
1080 0 : static OUString COMMAND_RECOVERY("vnd.sun.star.autorecovery:/doAutoRecovery");
1081 :
1082 0 : css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1083 :
1084 : Reference< css::frame::XSynchronousDispatch > xRecoveryUI(
1085 0 : xContext->getServiceManager()->createInstanceWithContext(SERVICENAME_RECOVERYUI, xContext),
1086 0 : css::uno::UNO_QUERY_THROW);
1087 :
1088 : Reference< css::util::XURLTransformer > xURLParser =
1089 0 : css::util::URLTransformer::create(::comphelper::getProcessComponentContext());
1090 :
1091 0 : css::util::URL aURL;
1092 0 : if (bEmergencySave)
1093 0 : aURL.Complete = COMMAND_EMERGENCYSAVE;
1094 0 : else if (bExistsRecoveryData)
1095 0 : aURL.Complete = COMMAND_RECOVERY;
1096 : else
1097 0 : return false;
1098 :
1099 0 : xURLParser->parseStrict(aURL);
1100 :
1101 0 : css::uno::Any aRet = xRecoveryUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
1102 0 : bool bRet = false;
1103 0 : aRet >>= bRet;
1104 0 : return !bEmergencySave || bRet;
1105 : }
1106 :
1107 : /*
1108 : * Save all open documents so they will be reopened
1109 : * the next time the application is started
1110 : *
1111 : * returns sal_True if at least one document could be saved...
1112 : *
1113 : */
1114 :
1115 0 : bool Desktop::SaveTasks()
1116 : {
1117 : return impl_callRecoveryUI(
1118 : true , // sal_True => force emergency save
1119 0 : false);
1120 : }
1121 :
1122 : namespace {
1123 :
1124 64 : void restartOnMac(bool passArguments) {
1125 : #if defined MACOSX
1126 : OfficeIPCThread::DisableOfficeIPCThread();
1127 : #if HAVE_FEATURE_MACOSX_SANDBOX
1128 : (void) passArguments; // avoid warnings
1129 : ResMgr *resMgr = Desktop::GetDesktopResManager();
1130 : OUString aMessage = ResId(STR_LO_MUST_BE_RESTARTED, *resMgr).toString();
1131 :
1132 : MessageDialog aRestartBox(NULL, aMessage);
1133 : aRestartBox.Execute();
1134 : #else
1135 : OUString execUrl;
1136 : OSL_VERIFY(osl_getExecutableFile(&execUrl.pData) == osl_Process_E_None);
1137 : OUString execPath;
1138 : OString execPath8;
1139 : if ((osl::FileBase::getSystemPathFromFileURL(execUrl, execPath)
1140 : != osl::FileBase::E_None) ||
1141 : !execPath.convertToString(
1142 : &execPath8, osl_getThreadTextEncoding(),
1143 : (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
1144 : RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
1145 : {
1146 : std::abort();
1147 : }
1148 : std::vector< OString > args;
1149 : args.push_back(execPath8);
1150 : bool wait = false;
1151 : if (passArguments) {
1152 : sal_uInt32 n = osl_getCommandArgCount();
1153 : for (sal_uInt32 i = 0; i < n; ++i) {
1154 : OUString arg;
1155 : OSL_VERIFY(osl_getCommandArg(i, &arg.pData) == osl_Process_E_None);
1156 : if (arg.match("--accept=")) {
1157 : wait = true;
1158 : }
1159 : OString arg8;
1160 : if (!arg.convertToString(
1161 : &arg8, osl_getThreadTextEncoding(),
1162 : (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
1163 : RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
1164 : {
1165 : std::abort();
1166 : }
1167 : args.push_back(arg8);
1168 : }
1169 : }
1170 : std::vector< char const * > argPtrs;
1171 : for (std::vector< OString >::iterator i(args.begin()); i != args.end();
1172 : ++i)
1173 : {
1174 : argPtrs.push_back(i->getStr());
1175 : }
1176 : argPtrs.push_back(0);
1177 : execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
1178 : if (errno == ENOTSUP) { // happens when multithreaded on OS X < 10.6
1179 : pid_t pid = fork();
1180 : if (pid == 0) {
1181 : execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
1182 : } else if (pid > 0) {
1183 : // Two simultaneously running soffice processes lead to two dock
1184 : // icons, so avoid waiting here unless it must be assumed that the
1185 : // process invoking soffice itself wants to wait for soffice to
1186 : // finish:
1187 : if (!wait) {
1188 : return;
1189 : }
1190 : int stat;
1191 : if (waitpid(pid, &stat, 0) == pid && WIFEXITED(stat)) {
1192 : _exit(WEXITSTATUS(stat));
1193 : }
1194 : }
1195 : }
1196 : std::abort();
1197 : #endif
1198 : #else
1199 : (void) passArguments; // avoid warnings
1200 : #endif
1201 64 : }
1202 :
1203 : }
1204 :
1205 0 : sal_uInt16 Desktop::Exception(sal_uInt16 nError)
1206 : {
1207 : // protect against recursive calls
1208 : static bool bInException = false;
1209 :
1210 0 : sal_uInt16 nOldMode = Application::GetSystemWindowMode();
1211 0 : Application::SetSystemWindowMode( nOldMode & ~SYSTEMWINDOW_MODE_NOAUTOMODE );
1212 0 : Application::SetDefDialogParent( NULL );
1213 :
1214 0 : if ( bInException )
1215 : {
1216 0 : OUString aDoubleExceptionString;
1217 0 : Application::Abort( aDoubleExceptionString );
1218 : }
1219 :
1220 0 : bInException = true;
1221 0 : const CommandLineArgs& rArgs = GetCommandLineArgs();
1222 :
1223 : // save all modified documents ... if it's allowed doing so.
1224 0 : bool bRestart = false;
1225 : bool bAllowRecoveryAndSessionManagement = (
1226 0 : ( !rArgs.IsNoRestore() ) && // some use cases of office must work without recovery
1227 0 : ( !rArgs.IsHeadless() ) &&
1228 0 : (( nError & EXC_MAJORTYPE ) != EXC_DISPLAY ) && // recovery can't work without UI ... but UI layer seems to be the reason for this crash
1229 0 : ( Application::IsInExecute() ) // crashes during startup and shutdown should be ignored (they indicates a corrupt installation ...)
1230 0 : );
1231 0 : if ( bAllowRecoveryAndSessionManagement )
1232 0 : bRestart = SaveTasks();
1233 :
1234 0 : FlushConfiguration();
1235 :
1236 0 : switch( nError & EXC_MAJORTYPE )
1237 : {
1238 : case EXC_RSCNOTLOADED:
1239 : {
1240 0 : OUString aResExceptionString;
1241 0 : Application::Abort( aResExceptionString );
1242 0 : break;
1243 : }
1244 :
1245 : default:
1246 : {
1247 0 : m_xLockfile.reset();
1248 :
1249 0 : if( bRestart )
1250 : {
1251 0 : OfficeIPCThread::DisableOfficeIPCThread();
1252 0 : if( pSignalHandler )
1253 0 : osl_removeSignalHandler( pSignalHandler );
1254 :
1255 0 : restartOnMac(false);
1256 0 : if ( m_rSplashScreen.is() )
1257 0 : m_rSplashScreen->reset();
1258 :
1259 0 : _exit( EXITHELPER_CRASH_WITH_RESTART );
1260 : }
1261 : else
1262 : {
1263 0 : Application::Abort( OUString() );
1264 : }
1265 :
1266 0 : break;
1267 : }
1268 : }
1269 :
1270 : OSL_ASSERT(false); // unreachable
1271 0 : return 0;
1272 : }
1273 :
1274 0 : void Desktop::AppEvent( const ApplicationEvent& rAppEvent )
1275 : {
1276 0 : HandleAppEvent( rAppEvent );
1277 0 : }
1278 :
1279 :
1280 160 : struct ExecuteGlobals
1281 : {
1282 : Reference < css::document::XDocumentEventListener > xGlobalBroadcaster;
1283 : bool bRestartRequested;
1284 : bool bUseSystemFileDialog;
1285 : std::unique_ptr<SvtLanguageOptions> pLanguageOptions;
1286 : std::unique_ptr<SvtPathOptions> pPathOptions;
1287 :
1288 160 : ExecuteGlobals()
1289 : : bRestartRequested( false )
1290 160 : , bUseSystemFileDialog( true )
1291 160 : {}
1292 : };
1293 :
1294 : static ExecuteGlobals* pExecGlobals = NULL;
1295 :
1296 160 : int Desktop::Main()
1297 : {
1298 160 : pExecGlobals = new ExecuteGlobals();
1299 :
1300 : SAL_INFO( "desktop.app", "desktop (cd100003) ::Desktop::Main" );
1301 :
1302 : // Remember current context object
1303 : com::sun::star::uno::ContextLayer layer(
1304 160 : com::sun::star::uno::getCurrentContext() );
1305 :
1306 160 : if ( m_aBootstrapError != BE_OK )
1307 : {
1308 0 : HandleBootstrapErrors( m_aBootstrapError, m_aBootstrapErrorMessage );
1309 0 : return EXIT_FAILURE;
1310 : }
1311 :
1312 160 : BootstrapStatus eStatus = GetBootstrapStatus();
1313 160 : if (eStatus == BS_TERMINATE) {
1314 0 : return EXIT_SUCCESS;
1315 : }
1316 :
1317 : // Detect desktop environment - need to do this as early as possible
1318 : com::sun::star::uno::setCurrentContext(
1319 160 : new DesktopContext( com::sun::star::uno::getCurrentContext() ) );
1320 :
1321 160 : CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
1322 :
1323 : #if HAVE_FEATURE_DESKTOP
1324 320 : OUString aUnknown( rCmdLineArgs.GetUnknown() );
1325 160 : if ( !aUnknown.isEmpty() )
1326 : {
1327 0 : displayCmdlineHelp( aUnknown );
1328 0 : return EXIT_FAILURE;
1329 : }
1330 160 : if ( rCmdLineArgs.IsHelp() )
1331 : {
1332 0 : displayCmdlineHelp( OUString() );
1333 0 : return EXIT_SUCCESS;
1334 : }
1335 160 : if ( rCmdLineArgs.IsVersion() )
1336 : {
1337 0 : displayVersion();
1338 0 : return EXIT_SUCCESS;
1339 : }
1340 : #endif
1341 : // setup configuration error handling
1342 320 : ConfigurationErrorHandler aConfigErrHandler;
1343 160 : if (!ShouldSuppressUI(rCmdLineArgs))
1344 0 : aConfigErrHandler.activate();
1345 :
1346 160 : ResMgr::SetReadStringHook( ReplaceStringHookProc );
1347 :
1348 : // Startup screen
1349 : SAL_INFO( "desktop.app", "desktop (lo119109) Desktop::Main { OpenSplashScreen" );
1350 160 : OpenSplashScreen();
1351 : SAL_INFO( "desktop.app", "desktop (lo119109) Desktop::Main } OpenSplashScreen" );
1352 :
1353 160 : SetSplashScreenProgress(10);
1354 :
1355 160 : userinstall::Status inst_fin = userinstall::finalize();
1356 160 : if (inst_fin != userinstall::EXISTED && inst_fin != userinstall::CREATED)
1357 : {
1358 : SAL_WARN( "desktop.app", "userinstall failed");
1359 0 : if ( inst_fin == userinstall::ERROR_NO_SPACE )
1360 : HandleBootstrapErrors(
1361 0 : BE_USERINSTALL_NOTENOUGHDISKSPACE, OUString() );
1362 0 : else if ( inst_fin == userinstall::ERROR_CANT_WRITE )
1363 0 : HandleBootstrapErrors( BE_USERINSTALL_NOWRITEACCESS, OUString() );
1364 : else
1365 0 : HandleBootstrapErrors( BE_USERINSTALL_FAILED, OUString() );
1366 0 : return EXIT_FAILURE;
1367 : }
1368 : // refresh path information
1369 160 : utl::Bootstrap::reloadData();
1370 160 : SetSplashScreenProgress(20);
1371 :
1372 320 : Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1373 :
1374 320 : Reference< XRestartManager > xRestartManager( OfficeRestartManager::get(xContext) );
1375 :
1376 320 : Reference< XDesktop2 > xDesktop;
1377 : try
1378 : {
1379 160 : RegisterServices(xContext);
1380 :
1381 160 : SetSplashScreenProgress(25);
1382 :
1383 : #if HAVE_FEATURE_DESKTOP
1384 : // check user installation directory for lockfile so we can be sure
1385 : // there is no other instance using our data files from a remote host
1386 : SAL_INFO( "desktop.app", "desktop (lo119109) Desktop::Main -> Lockfile" );
1387 160 : m_xLockfile.reset(new Lockfile);
1388 :
1389 320 : if ( !rCmdLineArgs.IsHeadless() && !rCmdLineArgs.IsInvisible() &&
1390 160 : !rCmdLineArgs.IsNoLockcheck() && !m_xLockfile->check( Lockfile_execWarning ))
1391 : {
1392 : // Lockfile exists, and user clicked 'no'
1393 0 : return EXIT_FAILURE;
1394 : }
1395 : SAL_INFO( "desktop.app", "desktop (lo119109) Desktop::Main <- Lockfile" );
1396 :
1397 : // check if accessibility is enabled but not working and allow to quit
1398 : SAL_INFO( "desktop.app", "{ GetEnableATToolSupport" );
1399 160 : if( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() )
1400 : {
1401 0 : if( !InitAccessBridge() )
1402 0 : return EXIT_FAILURE;
1403 : }
1404 : SAL_INFO( "desktop.app", "} GetEnableATToolSupport" );
1405 : #endif
1406 :
1407 : // terminate if requested...
1408 160 : if( rCmdLineArgs.IsTerminateAfterInit() )
1409 0 : return EXIT_SUCCESS;
1410 :
1411 : // Read the common configuration items for optimization purpose
1412 160 : if ( !InitializeConfiguration() )
1413 0 : return EXIT_FAILURE;
1414 :
1415 160 : SetSplashScreenProgress(30);
1416 :
1417 : // set static variable to disable crash reporting
1418 160 : osl_setErrorReporting( false );
1419 :
1420 : // create title string
1421 160 : LanguageTag aLocale( LANGUAGE_SYSTEM);
1422 160 : ResMgr* pLabelResMgr = ResMgr::SearchCreateResMgr( "ofa", aLocale );
1423 320 : OUString aTitle = pLabelResMgr ? ResId(RID_APPTITLE, *pLabelResMgr).toString() : OUString();
1424 160 : delete pLabelResMgr;
1425 :
1426 : #ifdef DBG_UTIL
1427 : //include buildid in non product builds
1428 : OUString aDefault("development");
1429 : aTitle += " [";
1430 : aTitle += utl::Bootstrap::getBuildIdData(aDefault);
1431 : aTitle += "]";
1432 : #endif
1433 :
1434 160 : SetDisplayName( aTitle );
1435 160 : SetSplashScreenProgress(35);
1436 : SAL_INFO( "desktop.app", "{ create SvtPathOptions and SvtLanguageOptions" );
1437 160 : pExecGlobals->pPathOptions.reset( new SvtPathOptions);
1438 160 : SetSplashScreenProgress(40);
1439 : SAL_INFO( "desktop.app", "} create SvtPathOptions and SvtLanguageOptions" );
1440 :
1441 160 : xDesktop = css::frame::Desktop::create( xContext );
1442 :
1443 : // create service for loadin SFX (still needed in startup)
1444 320 : pExecGlobals->xGlobalBroadcaster = Reference < css::document::XDocumentEventListener >
1445 160 : ( css::frame::theGlobalEventBroadcaster::get(xContext), UNO_SET_THROW );
1446 :
1447 : /* ensure existence of a default window that messages can be dispatched to
1448 : This is for the benefit of testtool which uses PostUserEvent extensively
1449 : and else can deadlock while creating this window from another tread while
1450 : the main thread is not yet in the event loop.
1451 : */
1452 160 : Application::GetDefaultDevice();
1453 :
1454 : #if HAVE_FEATURE_EXTENSIONS
1455 : // Check if bundled or shared extensions were added /removed
1456 : // and process those extensions (has to be done before checking
1457 : // the extension dependencies!
1458 160 : SynchronizeExtensionRepositories();
1459 160 : bool bAbort = CheckExtensionDependencies();
1460 160 : if ( bAbort )
1461 0 : return EXIT_FAILURE;
1462 :
1463 160 : if (inst_fin == userinstall::CREATED)
1464 : {
1465 64 : Migration::migrateSettingsIfNecessary();
1466 : }
1467 : #endif
1468 :
1469 : // keep a language options instance...
1470 160 : pExecGlobals->pLanguageOptions.reset( new SvtLanguageOptions(true));
1471 :
1472 320 : css::document::DocumentEvent aEvent;
1473 160 : aEvent.EventName = "OnStartApp";
1474 160 : pExecGlobals->xGlobalBroadcaster->documentEventOccured(aEvent);
1475 :
1476 160 : SetSplashScreenProgress(50);
1477 :
1478 : // Backing Component
1479 160 : bool bCrashed = false;
1480 160 : bool bExistsRecoveryData = false;
1481 160 : bool bExistsSessionData = false;
1482 :
1483 : SAL_INFO( "desktop.app", "{ impl_checkRecoveryState" );
1484 160 : impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
1485 : SAL_INFO( "desktop.app", "} impl_checkRecoveryState" );
1486 :
1487 320 : OUString pidfileName = rCmdLineArgs.GetPidfileName();
1488 160 : if ( !pidfileName.isEmpty() )
1489 : {
1490 0 : OUString pidfileURL;
1491 :
1492 0 : if ( osl_getFileURLFromSystemPath(pidfileName.pData, &pidfileURL.pData) == osl_File_E_None )
1493 : {
1494 0 : osl::File pidfile( pidfileURL );
1495 : osl::FileBase::RC rc;
1496 :
1497 0 : osl::File::remove( pidfileURL );
1498 0 : if ( (rc = pidfile.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create ) ) == osl::File::E_None )
1499 : {
1500 0 : OString pid( OString::number( GETPID() ) );
1501 0 : sal_uInt64 written = 0;
1502 0 : if ( pidfile.write(pid.getStr(), pid.getLength(), written) != osl::File::E_None )
1503 : {
1504 : SAL_WARN("desktop.app", "cannot write pidfile " << pidfile.getURL());
1505 : }
1506 0 : pidfile.close();
1507 : }
1508 : else
1509 : {
1510 : SAL_WARN("desktop.app", "cannot open pidfile " << pidfile.getURL() << osl::FileBase::RC(rc));
1511 0 : }
1512 : }
1513 : else
1514 : {
1515 : SAL_WARN("desktop.app", "cannot get pidfile URL from path" << pidfileName);
1516 0 : }
1517 : }
1518 :
1519 160 : if ( rCmdLineArgs.IsHeadless() )
1520 : {
1521 : // Ensure that we use not the system file dialogs as
1522 : // headless mode relies on Application::EnableHeadlessMode()
1523 : // which does only work for VCL dialogs!!
1524 160 : SvtMiscOptions aMiscOptions;
1525 160 : pExecGlobals->bUseSystemFileDialog = aMiscOptions.UseSystemFileDialog();
1526 160 : aMiscOptions.SetUseSystemFileDialog( false );
1527 : }
1528 :
1529 160 : pExecGlobals->bRestartRequested = xRestartManager->isRestartRequested(
1530 320 : true);
1531 160 : if ( !pExecGlobals->bRestartRequested )
1532 : {
1533 480 : if ((!rCmdLineArgs.WantsToLoadDocument() && !rCmdLineArgs.IsInvisible() && !rCmdLineArgs.IsHeadless() && !rCmdLineArgs.IsQuickstart()) &&
1534 96 : (SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE)) &&
1535 0 : (!bExistsRecoveryData ) &&
1536 192 : (!bExistsSessionData ) &&
1537 0 : (!Application::AnyInput( VCL_INPUT_APPEVENT ) ))
1538 : {
1539 : SAL_INFO( "desktop.app", "{ create BackingComponent" );
1540 0 : ShowBackingComponent(this);
1541 : SAL_INFO( "desktop.app", "} create BackingComponent" );
1542 : }
1543 160 : }
1544 : }
1545 0 : catch ( const com::sun::star::lang::WrappedTargetException& wte )
1546 : {
1547 0 : com::sun::star::uno::Exception te;
1548 0 : wte.TargetException >>= te;
1549 0 : FatalError( MakeStartupConfigAccessErrorMessage(wte.Message + te.Message) );
1550 : }
1551 0 : catch ( const com::sun::star::uno::Exception& e )
1552 : {
1553 0 : FatalError( MakeStartupErrorMessage(e.Message) );
1554 : }
1555 160 : SetSplashScreenProgress(55);
1556 :
1557 160 : SvtFontSubstConfig().Apply();
1558 :
1559 320 : SvtTabAppearanceCfg aAppearanceCfg;
1560 160 : SvtTabAppearanceCfg::SetInitialized();
1561 160 : aAppearanceCfg.SetApplicationDefaults( this );
1562 320 : SvtAccessibilityOptions aOptions;
1563 160 : aOptions.SetVCLSettings();
1564 160 : SetSplashScreenProgress(60);
1565 :
1566 : #if ENABLE_TELEPATHY
1567 : bool bListen = rCmdLineArgs.IsInvisible();
1568 : TeleManager::init( bListen );
1569 : #endif
1570 :
1571 160 : if ( !pExecGlobals->bRestartRequested )
1572 : {
1573 96 : Application::SetFilterHdl( LINK( this, Desktop, ImplInitFilterHdl ) );
1574 96 : bool bTerminateRequested = false;
1575 :
1576 : // Preload function depends on an initialized sfx application!
1577 96 : SetSplashScreenProgress(75);
1578 :
1579 : // use system window dialogs
1580 96 : Application::SetSystemWindowMode( SYSTEMWINDOW_MODE_DIALOG );
1581 :
1582 96 : SetSplashScreenProgress(80);
1583 :
1584 96 : if ( !bTerminateRequested && !rCmdLineArgs.IsInvisible() &&
1585 0 : !rCmdLineArgs.IsNoQuickstart() )
1586 0 : InitializeQuickstartMode( xContext );
1587 :
1588 : SAL_INFO( "desktop.app", "desktop (cd100003) createInstance com.sun.star.frame.Desktop" );
1589 : try
1590 : {
1591 96 : if ( xDesktop.is() )
1592 96 : xDesktop->addTerminateListener( new OfficeIPCThreadController );
1593 96 : SetSplashScreenProgress(100);
1594 : }
1595 0 : catch ( const com::sun::star::uno::Exception& e )
1596 : {
1597 0 : FatalError( MakeStartupErrorMessage(e.Message) );
1598 : }
1599 :
1600 : // Release solar mutex just before we wait for our client to connect
1601 96 : int nAcquireCount = Application::ReleaseSolarMutex();
1602 :
1603 : // Post user event to startup first application component window
1604 : // We have to send this OpenClients message short before execute() to
1605 : // minimize the risk that this message overtakes type detection construction!!
1606 96 : Application::PostUserEvent( LINK( this, Desktop, OpenClients_Impl ) );
1607 :
1608 : // Post event to enable acceptors
1609 96 : Application::PostUserEvent( LINK( this, Desktop, EnableAcceptors_Impl) );
1610 :
1611 : // The configuration error handler currently is only for startup
1612 96 : aConfigErrHandler.deactivate();
1613 :
1614 : // Acquire solar mutex just before we enter our message loop
1615 96 : if ( nAcquireCount )
1616 96 : Application::AcquireSolarMutex( nAcquireCount );
1617 :
1618 : // call Application::Execute to process messages in vcl message loop
1619 : SAL_INFO( "desktop.app", "PERFORMANCE - enter Application::Execute()" );
1620 :
1621 : try
1622 : {
1623 : #if HAVE_FEATURE_JAVA
1624 : // The JavaContext contains an interaction handler which is used when
1625 : // the creation of a Java Virtual Machine fails
1626 : com::sun::star::uno::ContextLayer layer2(
1627 96 : new svt::JavaContext( com::sun::star::uno::getCurrentContext() ) );
1628 : #endif
1629 : // check whether the shutdown is caused by restart just before entering the Execute
1630 192 : pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested ||
1631 288 : xRestartManager->isRestartRequested(true);
1632 :
1633 96 : if ( !pExecGlobals->bRestartRequested )
1634 : {
1635 : // if this run of the office is triggered by restart, some additional actions should be done
1636 96 : DoRestartActionsIfNecessary( !rCmdLineArgs.IsInvisible() && !rCmdLineArgs.IsNoQuickstart() );
1637 :
1638 96 : Execute();
1639 96 : }
1640 : }
1641 0 : catch(const com::sun::star::document::CorruptedFilterConfigurationException& exFilterCfg)
1642 : {
1643 0 : OfficeIPCThread::SetDowning();
1644 0 : FatalError( MakeStartupErrorMessage(exFilterCfg.Message) );
1645 : }
1646 0 : catch(const com::sun::star::configuration::CorruptedConfigurationException& exAnyCfg)
1647 : {
1648 0 : OfficeIPCThread::SetDowning();
1649 0 : FatalError( MakeStartupErrorMessage(exAnyCfg.Message) );
1650 : }
1651 0 : catch( const ::com::sun::star::uno::Exception& exUNO)
1652 : {
1653 0 : OfficeIPCThread::SetDowning();
1654 0 : FatalError( exUNO.Message);
1655 : }
1656 0 : catch( const std::exception& exSTD)
1657 : {
1658 0 : OfficeIPCThread::SetDowning();
1659 0 : FatalError( OUString::createFromAscii( exSTD.what()));
1660 : }
1661 0 : catch( ...)
1662 : {
1663 0 : OfficeIPCThread::SetDowning();
1664 0 : FatalError( OUString( "Caught Unknown Exception: Aborting!"));
1665 : }
1666 : }
1667 : else
1668 : {
1669 64 : if (xDesktop.is())
1670 64 : xDesktop->terminate();
1671 : }
1672 : // CAUTION: you do not necessarily get here e.g. on the Mac.
1673 : // please put all deinitialization code into doShutdown
1674 320 : return doShutdown();
1675 : }
1676 :
1677 160 : int Desktop::doShutdown()
1678 : {
1679 160 : if( ! pExecGlobals )
1680 0 : return EXIT_SUCCESS;
1681 :
1682 352 : pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested ||
1683 448 : OfficeRestartManager::get(comphelper::getProcessComponentContext())->
1684 480 : isRestartRequested(true);
1685 160 : if ( pExecGlobals->bRestartRequested )
1686 64 : SetRestartState();
1687 :
1688 160 : if (pExecGlobals->xGlobalBroadcaster.is())
1689 : {
1690 160 : css::document::DocumentEvent aEvent;
1691 160 : aEvent.EventName = "OnCloseApp";
1692 160 : pExecGlobals->xGlobalBroadcaster->documentEventOccured(aEvent);
1693 : }
1694 :
1695 160 : delete pResMgr, pResMgr = NULL;
1696 : // Restore old value
1697 160 : const CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
1698 160 : if ( rCmdLineArgs.IsHeadless() )
1699 160 : SvtMiscOptions().SetUseSystemFileDialog( pExecGlobals->bUseSystemFileDialog );
1700 :
1701 160 : OUString pidfileName = rCmdLineArgs.GetPidfileName();
1702 160 : if ( !pidfileName.isEmpty() )
1703 : {
1704 0 : OUString pidfileURL;
1705 :
1706 0 : if ( osl_getFileURLFromSystemPath(pidfileName.pData, &pidfileURL.pData) == osl_File_E_None )
1707 : {
1708 0 : if ( osl::File::remove( pidfileURL ) != osl::FileBase::E_None )
1709 : {
1710 : SAL_WARN("desktop.app", "shutdown: cannot remove pidfile " << pidfileURL);
1711 : }
1712 : }
1713 : else
1714 : {
1715 : SAL_WARN("desktop.app", "shutdown: cannot get pidfile URL from path" << pidfileName);
1716 0 : }
1717 : }
1718 :
1719 : // remove temp directory
1720 160 : RemoveTemporaryDirectory();
1721 160 : FlushConfiguration();
1722 : // The acceptors in the AcceptorMap must be released (in DeregisterServices)
1723 : // with the solar mutex unlocked, to avoid deadlock:
1724 160 : sal_uLong nAcquireCount = Application::ReleaseSolarMutex();
1725 160 : DeregisterServices();
1726 : #if HAVE_FEATURE_SCRIPTING
1727 160 : StarBASIC::DetachAllDocBasicItems();
1728 : #endif
1729 160 : Application::AcquireSolarMutex(nAcquireCount);
1730 : // be sure that path/language options gets destroyed before
1731 : // UCB is deinitialized
1732 : SAL_INFO( "desktop.app", "-> dispose path/language options" );
1733 160 : pExecGlobals->pLanguageOptions.reset( 0 );
1734 160 : pExecGlobals->pPathOptions.reset( 0 );
1735 : SAL_INFO( "desktop.app", "<- dispose path/language options" );
1736 :
1737 160 : bool bRR = pExecGlobals->bRestartRequested;
1738 160 : delete pExecGlobals, pExecGlobals = NULL;
1739 :
1740 : SAL_INFO( "desktop.app", "FINISHED WITH Desktop::Main" );
1741 160 : if ( bRR )
1742 : {
1743 64 : restartOnMac(true);
1744 64 : if ( m_rSplashScreen.is() )
1745 0 : m_rSplashScreen->reset();
1746 :
1747 64 : return EXITHELPER_NORMAL_RESTART;
1748 : }
1749 96 : return EXIT_SUCCESS;
1750 : }
1751 :
1752 28 : IMPL_LINK( Desktop, ImplInitFilterHdl, ConvertData*, pData )
1753 : {
1754 14 : return GraphicFilter::GetGraphicFilter().GetFilterCallback().Call( pData );
1755 : }
1756 :
1757 160 : bool Desktop::InitializeConfiguration()
1758 : {
1759 : SAL_INFO( "desktop.app", "desktop (jb99855) ::InitConfiguration" );
1760 : try
1761 : {
1762 : css::configuration::theDefaultProvider::get(
1763 160 : comphelper::getProcessComponentContext() );
1764 160 : return true;
1765 : }
1766 0 : catch( ::com::sun::star::lang::ServiceNotRegisteredException & e )
1767 : {
1768 : this->HandleBootstrapErrors(
1769 0 : Desktop::BE_UNO_SERVICE_CONFIG_MISSING, e.Message );
1770 : }
1771 0 : catch( const ::com::sun::star::configuration::MissingBootstrapFileException& e )
1772 : {
1773 : OUString aMsg( CreateErrorMsgString( utl::Bootstrap::MISSING_BOOTSTRAP_FILE,
1774 0 : e.BootstrapFileURL ));
1775 0 : HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_USER_INSTALL, aMsg );
1776 : }
1777 0 : catch( const ::com::sun::star::configuration::InvalidBootstrapFileException& e )
1778 : {
1779 : OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY,
1780 0 : e.BootstrapFileURL ));
1781 0 : HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
1782 : }
1783 0 : catch( const ::com::sun::star::configuration::InstallationIncompleteException& )
1784 : {
1785 0 : OUString aVersionFileURL;
1786 0 : OUString aMsg;
1787 0 : utl::Bootstrap::PathStatus aPathStatus = utl::Bootstrap::locateVersionFile( aVersionFileURL );
1788 0 : if ( aPathStatus == utl::Bootstrap::PATH_EXISTS )
1789 0 : aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE_ENTRY, aVersionFileURL );
1790 : else
1791 0 : aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE, aVersionFileURL );
1792 :
1793 0 : HandleBootstrapPathErrors( ::utl::Bootstrap::MISSING_USER_INSTALL, aMsg );
1794 : }
1795 0 : catch ( const com::sun::star::configuration::backend::BackendAccessException& exception)
1796 : {
1797 : // [cm122549] It is assumed in this case that the message
1798 : // coming from InitConfiguration (in fact CreateApplicationConf...)
1799 : // is suitable for display directly.
1800 0 : FatalError( MakeStartupErrorMessage( exception.Message ) );
1801 : }
1802 0 : catch ( const com::sun::star::configuration::backend::BackendSetupException& exception)
1803 : {
1804 : // [cm122549] It is assumed in this case that the message
1805 : // coming from InitConfiguration (in fact CreateApplicationConf...)
1806 : // is suitable for display directly.
1807 0 : FatalError( MakeStartupErrorMessage( exception.Message ) );
1808 : }
1809 0 : catch ( const ::com::sun::star::configuration::CannotLoadConfigurationException& )
1810 : {
1811 : OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
1812 0 : OUString() ));
1813 0 : HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
1814 : }
1815 0 : catch( const ::com::sun::star::uno::Exception& )
1816 : {
1817 : OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
1818 0 : OUString() ));
1819 0 : HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
1820 : }
1821 0 : return false;
1822 : }
1823 :
1824 320 : void Desktop::FlushConfiguration()
1825 : {
1826 : css::uno::Reference< css::util::XFlushable >(
1827 : css::configuration::theDefaultProvider::get(
1828 : comphelper::getProcessComponentContext()),
1829 320 : css::uno::UNO_QUERY_THROW)->flush();
1830 320 : }
1831 :
1832 0 : bool Desktop::InitializeQuickstartMode( const Reference< XComponentContext >& rxContext )
1833 : {
1834 : try
1835 : {
1836 : // the shutdown icon sits in the systray and allows the user to keep
1837 : // the office instance running for quicker restart
1838 : // this will only be activated if --quickstart was specified on cmdline
1839 : SAL_INFO( "desktop.app", "desktop (cd100003) createInstance com.sun.star.office.Quickstart" );
1840 :
1841 0 : bool bQuickstart = shouldLaunchQuickstart();
1842 :
1843 : // Try to instantiate quickstart service. This service is not mandatory, so
1844 : // do nothing if service is not available
1845 :
1846 : // #i105753# the following if was invented for performance
1847 : // unfortunately this broke the Mac behavior which is to always run
1848 : // in quickstart mode since Mac applications do not usually quit
1849 : // when the last document closes.
1850 : // Note that this claim that on OS X we "always run in quickstart mode"
1851 : // has nothing to do with (quick) *starting* (i.e. starting automatically
1852 : // when the user logs in), though, but with not quitting when no documents
1853 : // are open.
1854 : #ifndef MACOSX
1855 0 : if ( bQuickstart )
1856 : #endif
1857 : {
1858 0 : css::office::Quickstart::createStart(rxContext, bQuickstart);
1859 : }
1860 0 : return true;
1861 : }
1862 0 : catch( const ::com::sun::star::uno::Exception& )
1863 : {
1864 0 : return false;
1865 : }
1866 : }
1867 :
1868 320 : void Desktop::OverrideSystemSettings( AllSettings& rSettings )
1869 : {
1870 320 : if ( !SvtTabAppearanceCfg::IsInitialized () )
1871 480 : return;
1872 :
1873 160 : StyleSettings hStyleSettings = rSettings.GetStyleSettings();
1874 320 : MouseSettings hMouseSettings = rSettings.GetMouseSettings();
1875 :
1876 160 : sal_uInt32 nDragFullOptions = hStyleSettings.GetDragFullOptions();
1877 :
1878 320 : SvtTabAppearanceCfg aAppearanceCfg;
1879 160 : sal_uInt16 nDragMode = aAppearanceCfg.GetDragMode();
1880 160 : switch ( nDragMode )
1881 : {
1882 : case DragFullWindow:
1883 0 : nDragFullOptions |= DRAGFULL_OPTION_ALL;
1884 0 : break;
1885 : case DragFrame:
1886 0 : nDragFullOptions &= ((sal_uInt32)~DRAGFULL_OPTION_ALL);
1887 0 : break;
1888 : case DragSystemDep:
1889 : default:
1890 160 : break;
1891 : }
1892 :
1893 160 : sal_uInt32 nFollow = hMouseSettings.GetFollow();
1894 160 : hMouseSettings.SetFollow( aAppearanceCfg.IsMenuMouseFollow() ? (nFollow|MOUSE_FOLLOW_MENU) : (nFollow&~MOUSE_FOLLOW_MENU));
1895 160 : rSettings.SetMouseSettings(hMouseSettings);
1896 :
1897 160 : SvtMenuOptions aMenuOpt;
1898 160 : hStyleSettings.SetUseImagesInMenus(aMenuOpt.GetMenuIconsState());
1899 160 : hStyleSettings.SetDragFullOptions( nDragFullOptions );
1900 320 : rSettings.SetStyleSettings ( hStyleSettings );
1901 : }
1902 :
1903 :
1904 78 : IMPL_LINK_NOARG(Desktop, AsyncInitFirstRun)
1905 : {
1906 39 : DoFirstRunInitializations();
1907 39 : return 0L;
1908 : }
1909 :
1910 :
1911 :
1912 0 : class ExitTimer : public Timer
1913 : {
1914 : public:
1915 0 : ExitTimer()
1916 0 : {
1917 0 : SetTimeout(500);
1918 0 : Start();
1919 0 : }
1920 0 : virtual void Timeout() SAL_OVERRIDE
1921 : {
1922 0 : exit(42);
1923 : }
1924 : };
1925 :
1926 192 : IMPL_LINK_NOARG(Desktop, OpenClients_Impl)
1927 : {
1928 : SAL_INFO( "desktop.app", "PERFORMANCE - DesktopOpenClients_Impl()" );
1929 :
1930 : try {
1931 96 : OpenClients();
1932 :
1933 96 : OfficeIPCThread::SetReady();
1934 :
1935 96 : CloseSplashScreen();
1936 96 : CheckFirstRun( );
1937 96 : EnableOleAutomation();
1938 :
1939 96 : const char *pExitPostStartup = getenv ("OOO_EXIT_POST_STARTUP");
1940 96 : if (pExitPostStartup && *pExitPostStartup)
1941 0 : new ExitTimer();
1942 0 : } catch (const ::com::sun::star::uno::Exception &e) {
1943 0 : OUString a( "UNO exception during client open:\n" );
1944 0 : Application::Abort( a + e.Message );
1945 : }
1946 96 : return 0;
1947 : }
1948 :
1949 : // enable acceptos
1950 192 : IMPL_LINK_NOARG(Desktop, EnableAcceptors_Impl)
1951 : {
1952 96 : enableAcceptors();
1953 96 : return 0;
1954 : }
1955 :
1956 :
1957 : // Registers a COM class factory of the service manager with the windows operating system.
1958 96 : void Desktop::EnableOleAutomation()
1959 : {
1960 : SAL_INFO( "desktop.app", "desktop (jl97489) ::Desktop::EnableOleAutomation" );
1961 : #ifdef WNT
1962 : Reference< XMultiServiceFactory > xSMgr= comphelper::getProcessServiceFactory();
1963 : xSMgr->createInstance("com.sun.star.bridge.OleApplicationRegistration");
1964 : xSMgr->createInstance("com.sun.star.comp.ole.EmbedServer");
1965 : #endif
1966 96 : }
1967 :
1968 0 : void Desktop::PreloadModuleData( const CommandLineArgs& rArgs )
1969 : {
1970 0 : Sequence < com::sun::star::beans::PropertyValue > args(1);
1971 0 : args[0].Name = "Hidden";
1972 0 : args[0].Value <<= sal_True;
1973 0 : Reference < XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
1974 :
1975 0 : if ( rArgs.IsWriter() )
1976 : {
1977 : try
1978 : {
1979 0 : Reference < ::com::sun::star::util::XCloseable > xDoc( xDesktop->loadComponentFromURL( OUString("private:factory/swriter"),
1980 0 : OUString("_blank"), 0, args ), UNO_QUERY_THROW );
1981 0 : xDoc->close( sal_False );
1982 : }
1983 0 : catch ( const com::sun::star::uno::Exception& )
1984 : {
1985 : }
1986 : }
1987 0 : if ( rArgs.IsCalc() )
1988 : {
1989 : try
1990 : {
1991 0 : Reference < ::com::sun::star::util::XCloseable > xDoc( xDesktop->loadComponentFromURL( OUString("private:factory/scalc"),
1992 0 : OUString("_blank"), 0, args ), UNO_QUERY_THROW );
1993 0 : xDoc->close( sal_False );
1994 : }
1995 0 : catch ( const com::sun::star::uno::Exception& )
1996 : {
1997 : }
1998 : }
1999 0 : if ( rArgs.IsDraw() )
2000 : {
2001 : try
2002 : {
2003 0 : Reference < ::com::sun::star::util::XCloseable > xDoc( xDesktop->loadComponentFromURL( OUString("private:factory/sdraw"),
2004 0 : OUString("_blank"), 0, args ), UNO_QUERY_THROW );
2005 0 : xDoc->close( sal_False );
2006 : }
2007 0 : catch ( const com::sun::star::uno::Exception& )
2008 : {
2009 : }
2010 : }
2011 0 : if ( rArgs.IsImpress() )
2012 : {
2013 : try
2014 : {
2015 0 : Reference < ::com::sun::star::util::XCloseable > xDoc( xDesktop->loadComponentFromURL( OUString("private:factory/simpress"),
2016 0 : OUString("_blank"), 0, args ), UNO_QUERY_THROW );
2017 0 : xDoc->close( sal_False );
2018 : }
2019 0 : catch ( const com::sun::star::uno::Exception& )
2020 : {
2021 : }
2022 0 : }
2023 0 : }
2024 :
2025 0 : void Desktop::PreloadConfigurationData()
2026 : {
2027 0 : Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2028 0 : Reference< XNameAccess > xNameAccess = css::frame::theUICommandDescription::get(xContext);
2029 :
2030 0 : OUString aWriterDoc( "com.sun.star.text.TextDocument" );
2031 0 : OUString aCalcDoc( "com.sun.star.sheet.SpreadsheetDocument" );
2032 0 : OUString aDrawDoc( "com.sun.star.drawing.DrawingDocument" );
2033 0 : OUString aImpressDoc( "com.sun.star.presentation.PresentationDocument" );
2034 :
2035 : // preload commands configuration
2036 0 : Any a;
2037 0 : Reference< XNameAccess > xCmdAccess;
2038 :
2039 : try
2040 : {
2041 0 : a = xNameAccess->getByName( aWriterDoc );
2042 0 : a >>= xCmdAccess;
2043 0 : if ( xCmdAccess.is() )
2044 : {
2045 0 : xCmdAccess->getByName(".uno:BasicShapes");
2046 0 : xCmdAccess->getByName(".uno:EditGlossary");
2047 : }
2048 : }
2049 0 : catch ( const ::com::sun::star::uno::Exception& )
2050 : {
2051 : }
2052 :
2053 : try
2054 : {
2055 0 : a = xNameAccess->getByName( aCalcDoc );
2056 0 : a >>= xCmdAccess;
2057 0 : if ( xCmdAccess.is() )
2058 0 : xCmdAccess->getByName(".uno:InsertObjectStarMath");
2059 : }
2060 0 : catch ( const ::com::sun::star::uno::Exception& )
2061 : {
2062 : }
2063 :
2064 : try
2065 : {
2066 : // draw and impress share the same configuration file (DrawImpressCommands.xcu)
2067 0 : a = xNameAccess->getByName( aDrawDoc );
2068 0 : a >>= xCmdAccess;
2069 0 : if ( xCmdAccess.is() )
2070 0 : xCmdAccess->getByName(".uno:Polygon");
2071 : }
2072 0 : catch ( const ::com::sun::star::uno::Exception& )
2073 : {
2074 : }
2075 :
2076 : // preload window state configuration
2077 0 : xNameAccess = theWindowStateConfiguration::get( xContext );
2078 0 : Reference< XNameAccess > xWindowAccess;
2079 : try
2080 : {
2081 0 : a = xNameAccess->getByName( aWriterDoc );
2082 0 : a >>= xWindowAccess;
2083 0 : if ( xWindowAccess.is() )
2084 0 : xWindowAccess->getByName("private:resource/toolbar/standardbar");
2085 : }
2086 0 : catch ( const ::com::sun::star::uno::Exception& )
2087 : {
2088 : }
2089 : try
2090 : {
2091 0 : a = xNameAccess->getByName( aCalcDoc );
2092 0 : a >>= xWindowAccess;
2093 0 : if ( xWindowAccess.is() )
2094 0 : xWindowAccess->getByName("private:resource/toolbar/standardbar");
2095 : }
2096 0 : catch ( const ::com::sun::star::uno::Exception& )
2097 : {
2098 : }
2099 : try
2100 : {
2101 0 : a = xNameAccess->getByName( aDrawDoc );
2102 0 : a >>= xWindowAccess;
2103 0 : if ( xWindowAccess.is() )
2104 0 : xWindowAccess->getByName("private:resource/toolbar/standardbar");
2105 : }
2106 0 : catch ( const ::com::sun::star::uno::Exception& )
2107 : {
2108 : }
2109 : try
2110 : {
2111 0 : a = xNameAccess->getByName( aImpressDoc );
2112 0 : a >>= xWindowAccess;
2113 0 : if ( xWindowAccess.is() )
2114 0 : xWindowAccess->getByName("private:resource/toolbar/standardbar");
2115 : }
2116 0 : catch ( const ::com::sun::star::uno::Exception& )
2117 : {
2118 : }
2119 :
2120 : // preload user interface element factories
2121 0 : Reference< XUIElementFactoryManager > xUIElementFactory = theUIElementFactoryManager::get( xContext );
2122 : try
2123 : {
2124 0 : xUIElementFactory->getRegisteredFactories();
2125 : }
2126 0 : catch ( const ::com::sun::star::uno::Exception& )
2127 : {
2128 : }
2129 :
2130 : // preload popup menu controller factories. As all controllers are in the same
2131 : // configuration file they also get preloaded!
2132 :
2133 : Reference< css::frame::XUIControllerRegistration > xPopupMenuControllerFactory =
2134 0 : css::frame::thePopupMenuControllerFactory::get( xContext );
2135 : try
2136 : {
2137 0 : (void)xPopupMenuControllerFactory->hasController(
2138 : OUString( ".uno:CharFontName" ),
2139 0 : OUString() );
2140 : }
2141 0 : catch ( const ::com::sun::star::uno::Exception& )
2142 : {
2143 : }
2144 :
2145 : // preload filter configuration
2146 0 : xNameAccess = Reference< XNameAccess >(
2147 0 : xContext->getServiceManager()->createInstanceWithContext("com.sun.star.document.FilterFactory", xContext),
2148 0 : UNO_QUERY );
2149 0 : if ( xNameAccess.is() )
2150 : {
2151 : try
2152 : {
2153 0 : xNameAccess->getElementNames();
2154 : }
2155 0 : catch ( const ::com::sun::star::uno::Exception& )
2156 : {
2157 : }
2158 : }
2159 :
2160 : // preload type detection configuration
2161 0 : xNameAccess = Reference< XNameAccess >(
2162 0 : xContext->getServiceManager()->createInstanceWithContext("com.sun.star.document.TypeDetection", xContext),
2163 0 : UNO_QUERY );
2164 0 : if ( xNameAccess.is() )
2165 : {
2166 : try
2167 : {
2168 0 : xNameAccess->getElementNames();
2169 : }
2170 0 : catch ( const ::com::sun::star::uno::Exception& )
2171 : {
2172 : }
2173 0 : }
2174 0 : }
2175 :
2176 96 : void Desktop::OpenClients()
2177 : {
2178 :
2179 : // check if a document has been recovered - if there is one of if a document was loaded by cmdline, no default document
2180 : // should be created
2181 96 : Reference < XComponent > xFirst;
2182 96 : bool bRecovery = false;
2183 :
2184 96 : const CommandLineArgs& rArgs = GetCommandLineArgs();
2185 :
2186 96 : if (!rArgs.IsQuickstart())
2187 : {
2188 96 : bool bShowHelp = false;
2189 96 : OUStringBuffer aHelpURLBuffer;
2190 96 : if (rArgs.IsHelpWriter()) {
2191 0 : bShowHelp = true;
2192 0 : aHelpURLBuffer.appendAscii("vnd.sun.star.help://swriter/start");
2193 96 : } else if (rArgs.IsHelpCalc()) {
2194 0 : bShowHelp = true;
2195 0 : aHelpURLBuffer.appendAscii("vnd.sun.star.help://scalc/start");
2196 96 : } else if (rArgs.IsHelpDraw()) {
2197 0 : bShowHelp = true;
2198 0 : aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdraw/start");
2199 96 : } else if (rArgs.IsHelpImpress()) {
2200 0 : bShowHelp = true;
2201 0 : aHelpURLBuffer.appendAscii("vnd.sun.star.help://simpress/start");
2202 96 : } else if (rArgs.IsHelpBase()) {
2203 0 : bShowHelp = true;
2204 0 : aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdatabase/start");
2205 96 : } else if (rArgs.IsHelpBasic()) {
2206 0 : bShowHelp = true;
2207 0 : aHelpURLBuffer.appendAscii("vnd.sun.star.help://sbasic/start");
2208 96 : } else if (rArgs.IsHelpMath()) {
2209 0 : bShowHelp = true;
2210 0 : aHelpURLBuffer.appendAscii("vnd.sun.star.help://smath/start");
2211 : }
2212 96 : if (bShowHelp) {
2213 0 : aHelpURLBuffer.appendAscii("?Language=");
2214 0 : aHelpURLBuffer.append(utl::ConfigManager::getLocale());
2215 : #if defined UNX
2216 0 : aHelpURLBuffer.appendAscii("&System=UNX");
2217 : #elif defined WNT
2218 : aHelpURLBuffer.appendAscii("&System=WIN");
2219 : #endif
2220 0 : Application::GetHelp()->Start(
2221 0 : aHelpURLBuffer.makeStringAndClear(), NULL);
2222 0 : return;
2223 96 : }
2224 : }
2225 : else
2226 : {
2227 0 : OUString aIniName;
2228 :
2229 0 : osl_getExecutableFile( &aIniName.pData );
2230 0 : sal_uInt32 lastIndex = aIniName.lastIndexOf('/');
2231 0 : if ( lastIndex > 0 )
2232 : {
2233 0 : aIniName = aIniName.copy( 0, lastIndex+1 );
2234 0 : aIniName += "perftune";
2235 : #if defined(WNT)
2236 : aIniName += ".ini";
2237 : #else
2238 0 : aIniName += "rc";
2239 : #endif
2240 : }
2241 :
2242 0 : rtl::Bootstrap aPerfTuneIniFile( aIniName );
2243 :
2244 0 : OUString aDefault( "0" );
2245 0 : OUString aPreloadData;
2246 :
2247 0 : aPerfTuneIniFile.getFrom( OUString( "QuickstartPreloadConfiguration" ), aPreloadData, aDefault );
2248 0 : if ( aPreloadData == "1" )
2249 : {
2250 0 : if ( rArgs.IsWriter() ||
2251 0 : rArgs.IsCalc() ||
2252 0 : rArgs.IsDraw() ||
2253 0 : rArgs.IsImpress() )
2254 : {
2255 0 : PreloadModuleData( rArgs );
2256 : }
2257 :
2258 0 : PreloadConfigurationData();
2259 0 : }
2260 : }
2261 :
2262 : // Disable AutoSave feature in case "--norestore" or a similar command line switch is set on the command line.
2263 : // The reason behind: AutoSave/EmergencySave/AutoRecovery share the same data.
2264 : // But the require that all documents, which are saved as backup should exists inside
2265 : // memory. May be this mechanism will be inconsistent if the configuration exists ...
2266 : // but no document inside memory corrspond to this data.
2267 : // Furter it's not acceptable to recover such documents without any UI. It can
2268 : // need some time, where the user wont see any results and wait for finishing the office startup ...
2269 96 : bool bAllowRecoveryAndSessionManagement = ( !rArgs.IsNoRestore() ) && ( !rArgs.IsHeadless() );
2270 :
2271 96 : if ( ! bAllowRecoveryAndSessionManagement )
2272 : {
2273 : try
2274 : {
2275 96 : Reference< XDispatch > xRecovery = css::frame::theAutoRecovery::get( ::comphelper::getProcessComponentContext() );
2276 192 : Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create( ::comphelper::getProcessComponentContext() );
2277 :
2278 192 : css::util::URL aCmd;
2279 96 : aCmd.Complete = "vnd.sun.star.autorecovery:/disableRecovery";
2280 96 : xParser->parseStrict(aCmd);
2281 :
2282 192 : xRecovery->dispatch(aCmd, css::uno::Sequence< css::beans::PropertyValue >());
2283 : }
2284 0 : catch(const css::uno::Exception& e)
2285 : {
2286 : SAL_WARN( "desktop.app", "Could not disable AutoRecovery." << e.Message);
2287 : }
2288 : }
2289 : else
2290 : {
2291 0 : bool bCrashed = false;
2292 0 : bool bExistsRecoveryData = false;
2293 0 : bool bExistsSessionData = false;
2294 :
2295 0 : impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
2296 :
2297 0 : if ( !getenv ("OOO_DISABLE_RECOVERY") &&
2298 : (
2299 0 : ( bExistsRecoveryData ) || // => crash with files => recovery
2300 : ( bCrashed ) // => crash without files => error report
2301 : )
2302 : )
2303 : {
2304 : try
2305 : {
2306 : bRecovery = impl_callRecoveryUI(
2307 : false , // false => force recovery instead of emergency save
2308 0 : bExistsRecoveryData);
2309 : }
2310 0 : catch(const css::uno::Exception& e)
2311 : {
2312 : SAL_WARN( "desktop.app", "Error during recovery" << e.Message);
2313 : }
2314 : }
2315 :
2316 0 : Reference< XSessionManagerListener2 > xSessionListener;
2317 : try
2318 : {
2319 : // specifies whether the UI-interaction on Session shutdown is allowed
2320 0 : xSessionListener = SessionListener::createWithOnQuitFlag(
2321 0 : ::comphelper::getProcessComponentContext(), isUIOnSessionShutdownAllowed());
2322 : }
2323 0 : catch(const com::sun::star::uno::Exception& e)
2324 : {
2325 : SAL_WARN( "desktop.app", "Registration of session listener failed" << e.Message);
2326 : }
2327 :
2328 0 : if ( !bExistsRecoveryData && xSessionListener.is() )
2329 : {
2330 : // session management
2331 : try
2332 : {
2333 0 : xSessionListener->doRestore();
2334 : }
2335 0 : catch(const com::sun::star::uno::Exception& e)
2336 : {
2337 : SAL_WARN( "desktop.app", "Error in session management" << e.Message);
2338 : }
2339 0 : }
2340 : }
2341 :
2342 96 : OfficeIPCThread::EnableRequests();
2343 :
2344 96 : ProcessDocumentsRequest aRequest(rArgs.getCwdUrl());
2345 96 : aRequest.pcProcessed = NULL;
2346 :
2347 96 : aRequest.aOpenList = rArgs.GetOpenList();
2348 96 : aRequest.aViewList = rArgs.GetViewList();
2349 96 : aRequest.aStartList = rArgs.GetStartList();
2350 96 : aRequest.aPrintList = rArgs.GetPrintList();
2351 96 : aRequest.aPrintToList = rArgs.GetPrintToList();
2352 96 : aRequest.aPrinterName = rArgs.GetPrinterName();
2353 96 : aRequest.aForceOpenList = rArgs.GetForceOpenList();
2354 96 : aRequest.aForceNewList = rArgs.GetForceNewList();
2355 96 : aRequest.aConversionList = rArgs.GetConversionList();
2356 96 : aRequest.aConversionParams = rArgs.GetConversionParams();
2357 96 : aRequest.aConversionOut = rArgs.GetConversionOut();
2358 96 : aRequest.aInFilter = rArgs.GetInFilter();
2359 96 : aRequest.bTextCat = rArgs.IsTextCat();
2360 :
2361 288 : if ( !aRequest.aOpenList.empty() ||
2362 192 : !aRequest.aViewList.empty() ||
2363 192 : !aRequest.aStartList.empty() ||
2364 192 : !aRequest.aPrintList.empty() ||
2365 192 : !aRequest.aForceOpenList.empty() ||
2366 192 : !aRequest.aForceNewList.empty() ||
2367 288 : ( !aRequest.aPrintToList.empty() && !aRequest.aPrinterName.isEmpty() ) ||
2368 96 : !aRequest.aConversionList.empty() )
2369 : {
2370 0 : if ( rArgs.HasModuleParam() )
2371 : {
2372 0 : SvtModuleOptions aOpt;
2373 :
2374 : // Support command line parameters to start a module (as preselection)
2375 0 : if ( rArgs.IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
2376 0 : aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::E_WRITER );
2377 0 : else if ( rArgs.IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
2378 0 : aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::E_CALC );
2379 0 : else if ( rArgs.IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
2380 0 : aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::E_IMPRESS );
2381 0 : else if ( rArgs.IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
2382 0 : aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::E_DRAW );
2383 : }
2384 :
2385 : // check for printing disabled
2386 0 : if( ( !(aRequest.aPrintList.empty() && aRequest.aPrintToList.empty()) )
2387 0 : && Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
2388 : {
2389 0 : aRequest.aPrintList.clear();
2390 0 : aRequest.aPrintToList.clear();
2391 0 : ResMgr* pDtResMgr = GetDesktopResManager();
2392 0 : if( pDtResMgr )
2393 : {
2394 0 : MessageDialog aBox(NULL, ResId(STR_ERR_PRINTDISABLED, *pDtResMgr));
2395 0 : aBox.Execute();
2396 : }
2397 : }
2398 :
2399 : // Process request
2400 0 : if ( OfficeIPCThread::ExecuteCmdLineRequests( aRequest ) )
2401 : {
2402 : // Don't do anything if we have successfully called terminate at desktop:
2403 0 : return;
2404 : }
2405 : }
2406 :
2407 : // no default document if a document was loaded by recovery or by command line or if soffice is used as server
2408 96 : Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
2409 96 : Reference< XElementAccess > xList( xDesktop->getFrames(), UNO_QUERY_THROW );
2410 96 : if ( xList->hasElements() )
2411 0 : return;
2412 :
2413 96 : if ( rArgs.IsQuickstart() || rArgs.IsInvisible() || Application::AnyInput( VCL_INPUT_APPEVENT ) )
2414 : // soffice was started as tray icon ...
2415 96 : return;
2416 :
2417 0 : if ( bRecovery )
2418 : {
2419 0 : ShowBackingComponent(0);
2420 : }
2421 : else
2422 : {
2423 0 : OpenDefault();
2424 0 : }
2425 : }
2426 :
2427 0 : void Desktop::OpenDefault()
2428 : {
2429 :
2430 : SAL_INFO( "desktop.app", "desktop (cd100003) ::Desktop::OpenDefault" );
2431 :
2432 0 : OUString aName;
2433 0 : SvtModuleOptions aOpt;
2434 :
2435 0 : const CommandLineArgs& rArgs = GetCommandLineArgs();
2436 0 : if ( rArgs.IsNoDefault() ) return;
2437 0 : if ( rArgs.HasModuleParam() )
2438 : {
2439 : // Support new command line parameters to start a module
2440 0 : if ( rArgs.IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
2441 0 : aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITER );
2442 0 : else if ( rArgs.IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
2443 0 : aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_CALC );
2444 0 : else if ( rArgs.IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
2445 0 : aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_IMPRESS );
2446 0 : else if ( rArgs.IsBase() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
2447 0 : aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DATABASE );
2448 0 : else if ( rArgs.IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
2449 0 : aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DRAW );
2450 0 : else if ( rArgs.IsMath() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) )
2451 0 : aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_MATH );
2452 0 : else if ( rArgs.IsGlobal() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
2453 0 : aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITERGLOBAL );
2454 0 : else if ( rArgs.IsWeb() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
2455 0 : aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITERWEB );
2456 : }
2457 :
2458 0 : if ( aName.isEmpty() )
2459 : {
2460 : // Old way to create a default document
2461 0 : if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
2462 0 : aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITER );
2463 0 : else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
2464 0 : aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_CALC );
2465 0 : else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
2466 0 : aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_IMPRESS );
2467 0 : else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
2468 0 : aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DATABASE );
2469 0 : else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
2470 0 : aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DRAW );
2471 : else
2472 0 : return;
2473 : }
2474 :
2475 0 : ProcessDocumentsRequest aRequest(rArgs.getCwdUrl());
2476 0 : aRequest.pcProcessed = NULL;
2477 0 : aRequest.aOpenList.push_back(aName);
2478 0 : OfficeIPCThread::ExecuteCmdLineRequests( aRequest );
2479 : }
2480 :
2481 :
2482 0 : OUString GetURL_Impl(
2483 : const OUString& rName, boost::optional< OUString > const & cwdUrl )
2484 : {
2485 : // if rName is a vnd.sun.star.script URL do not attempt to parse it
2486 : // as INetURLObj does not handle handle there URLs
2487 0 : if (rName.startsWith("vnd.sun.star.script"))
2488 : {
2489 0 : return rName;
2490 : }
2491 :
2492 : // dont touch file urls, those should already be in internal form
2493 : // they won't get better here (#112849#)
2494 0 : if (rName.startsWith("file:"))
2495 : {
2496 0 : return rName;
2497 : }
2498 :
2499 0 : if ( rName.startsWith("service:"))
2500 : {
2501 0 : return rName;
2502 : }
2503 :
2504 : // Add path separator to these directory and make given URL (rName) absolute by using of current working directory
2505 : // Attention: "setFinalSlash()" is necessary for calling "smartRel2Abs()"!!!
2506 : // Otherwhise last part will be ignored and wrong result will be returned!!!
2507 : // "smartRel2Abs()" interpret given URL as file not as path. So he truncate last element to get the base path ...
2508 : // But if we add a separator - he doesn't do it anymore.
2509 0 : INetURLObject aObj;
2510 0 : if (cwdUrl) {
2511 0 : aObj.SetURL(*cwdUrl);
2512 0 : aObj.setFinalSlash();
2513 : }
2514 :
2515 : // Use the provided parameters for smartRel2Abs to support the usage of '%' in system paths.
2516 : // Otherwise this char won't get encoded and we are not able to load such files later,
2517 : bool bWasAbsolute;
2518 : INetURLObject aURL = aObj.smartRel2Abs( rName, bWasAbsolute, false, INetURLObject::WAS_ENCODED,
2519 0 : RTL_TEXTENCODING_UTF8, true );
2520 0 : OUString aFileURL = aURL.GetMainURL(INetURLObject::NO_DECODE);
2521 :
2522 0 : ::osl::FileStatus aStatus( osl_FileStatus_Mask_FileURL );
2523 0 : ::osl::DirectoryItem aItem;
2524 0 : if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
2525 0 : ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
2526 0 : aFileURL = aStatus.getFileURL();
2527 :
2528 0 : return aFileURL;
2529 : }
2530 :
2531 0 : void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
2532 : {
2533 0 : switch ( rAppEvent.GetEvent() )
2534 : {
2535 : case ApplicationEvent::TYPE_ACCEPT:
2536 : // every time an accept parameter is used we create an acceptor
2537 : // with the corresponding accept-string
2538 0 : createAcceptor(rAppEvent.GetStringData());
2539 0 : break;
2540 : case ApplicationEvent::TYPE_APPEAR:
2541 0 : if ( !GetCommandLineArgs().IsInvisible() )
2542 : {
2543 0 : Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2544 :
2545 : // find active task - the active task is always a visible task
2546 0 : Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext );
2547 0 : Reference< css::frame::XFrame > xTask = xDesktop->getActiveFrame();
2548 0 : if ( !xTask.is() )
2549 : {
2550 : // get any task if there is no active one
2551 0 : Reference< css::container::XIndexAccess > xList( xDesktop->getFrames(), ::com::sun::star::uno::UNO_QUERY );
2552 0 : if ( xList->getCount() > 0 )
2553 0 : xList->getByIndex(0) >>= xTask;
2554 : }
2555 :
2556 0 : if ( xTask.is() )
2557 : {
2558 0 : Reference< com::sun::star::awt::XTopWindow > xTop( xTask->getContainerWindow(), UNO_QUERY );
2559 0 : xTop->toFront();
2560 : }
2561 : else
2562 : {
2563 : // no visible task that could be activated found
2564 0 : Reference< ::com::sun::star::awt::XWindow > xContainerWindow;
2565 0 : Reference< XFrame > xBackingFrame = xDesktop->findFrame(OUString( "_blank" ), 0);
2566 0 : if (xBackingFrame.is())
2567 0 : xContainerWindow = xBackingFrame->getContainerWindow();
2568 0 : if (xContainerWindow.is())
2569 : {
2570 0 : Reference< XController > xStartModule = StartModule::createWithParentWindow(xContext, xContainerWindow);
2571 0 : Reference< ::com::sun::star::awt::XWindow > xBackingWin(xStartModule, UNO_QUERY);
2572 : // Attention: You MUST(!) call setComponent() before you call attachFrame().
2573 : // Because the backing component set the property "IsBackingMode" of the frame
2574 : // to true inside attachFrame(). But setComponent() reset this state every time ...
2575 0 : xBackingFrame->setComponent(xBackingWin, xStartModule);
2576 0 : xStartModule->attachFrame(xBackingFrame);
2577 0 : xContainerWindow->setVisible(sal_True);
2578 :
2579 0 : vcl::Window* pCompWindow = VCLUnoHelper::GetWindow(xBackingFrame->getComponentWindow());
2580 0 : if (pCompWindow)
2581 0 : pCompWindow->Update();
2582 0 : }
2583 0 : }
2584 : }
2585 0 : break;
2586 : case ApplicationEvent::TYPE_HELP:
2587 0 : displayCmdlineHelp(rAppEvent.GetStringData());
2588 0 : break;
2589 : case ApplicationEvent::TYPE_VERSION:
2590 0 : displayVersion();
2591 0 : break;
2592 : case ApplicationEvent::TYPE_OPEN:
2593 : {
2594 0 : const CommandLineArgs& rCmdLine = GetCommandLineArgs();
2595 0 : if ( !rCmdLine.IsInvisible() && !rCmdLine.IsTerminateAfterInit() )
2596 : {
2597 : ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
2598 0 : rCmdLine.getCwdUrl());
2599 0 : std::vector<OUString> const & data(rAppEvent.GetStringsData());
2600 : pDocsRequest->aOpenList.insert(
2601 0 : pDocsRequest->aOpenList.end(), data.begin(), data.end());
2602 0 : pDocsRequest->pcProcessed = NULL;
2603 :
2604 0 : OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
2605 0 : delete pDocsRequest;
2606 : }
2607 : }
2608 0 : break;
2609 : case ApplicationEvent::TYPE_OPENHELPURL:
2610 : // start help for a specific URL
2611 0 : Application::GetHelp()->Start(rAppEvent.GetStringData(), NULL);
2612 0 : break;
2613 : case ApplicationEvent::TYPE_PRINT:
2614 : {
2615 0 : const CommandLineArgs& rCmdLine = GetCommandLineArgs();
2616 0 : if ( !rCmdLine.IsInvisible() && !rCmdLine.IsTerminateAfterInit() )
2617 : {
2618 : ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
2619 0 : rCmdLine.getCwdUrl());
2620 0 : std::vector<OUString> const & data(rAppEvent.GetStringsData());
2621 : pDocsRequest->aPrintList.insert(
2622 0 : pDocsRequest->aPrintList.end(), data.begin(), data.end());
2623 0 : pDocsRequest->pcProcessed = NULL;
2624 :
2625 0 : OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
2626 0 : delete pDocsRequest;
2627 : }
2628 : }
2629 0 : break;
2630 : case ApplicationEvent::TYPE_PRIVATE_DOSHUTDOWN:
2631 : {
2632 0 : Desktop* pD = dynamic_cast<Desktop*>(GetpApp());
2633 : OSL_ENSURE( pD, "no desktop ?!?" );
2634 0 : if( pD )
2635 0 : pD->doShutdown();
2636 : }
2637 0 : break;
2638 : case ApplicationEvent::TYPE_QUICKSTART:
2639 0 : if ( !GetCommandLineArgs().IsInvisible() )
2640 : {
2641 : // If the office has been started the second time its command line arguments are sent through a pipe
2642 : // connection to the first office. We want to reuse the quickstart option for the first office.
2643 : // NOTICE: The quickstart service must be initialized inside the "main thread", so we use the
2644 : // application events to do this (they are executed inside main thread)!!!
2645 : // Don't start quickstart service if the user specified "--invisible" on the command line!
2646 0 : Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2647 0 : css::office::Quickstart::createStart(xContext, true/*Quickstart*/);
2648 : }
2649 0 : break;
2650 : case ApplicationEvent::TYPE_SHOWDIALOG:
2651 : // ignore all errors here. It's clicking a menu entry only ...
2652 : // The user will try it again, in case nothing happens .-)
2653 : try
2654 : {
2655 0 : Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2656 :
2657 0 : Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext );
2658 :
2659 0 : Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create(xContext);
2660 0 : css::util::URL aCommand;
2661 0 : if( rAppEvent.GetStringData() == "PREFERENCES" )
2662 0 : aCommand.Complete = ".uno:OptionsTreeDialog";
2663 0 : else if( rAppEvent.GetStringData() == "ABOUT" )
2664 0 : aCommand.Complete = ".uno:About";
2665 0 : if( !aCommand.Complete.isEmpty() )
2666 : {
2667 0 : xParser->parseStrict(aCommand);
2668 :
2669 0 : css::uno::Reference< css::frame::XDispatch > xDispatch = xDesktop->queryDispatch(aCommand, OUString(), 0);
2670 0 : if (xDispatch.is())
2671 0 : xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >());
2672 0 : }
2673 : }
2674 0 : catch(const css::uno::Exception&)
2675 : {}
2676 0 : break;
2677 : case ApplicationEvent::TYPE_UNACCEPT:
2678 : // try to remove corresponding acceptor
2679 0 : destroyAcceptor(rAppEvent.GetStringData());
2680 0 : break;
2681 : default:
2682 : SAL_WARN( "desktop.app", "this cannot happen");
2683 0 : break;
2684 : }
2685 0 : }
2686 :
2687 160 : void Desktop::OpenSplashScreen()
2688 : {
2689 160 : const CommandLineArgs &rCmdLine = GetCommandLineArgs();
2690 160 : bool bVisible = false;
2691 : // Show intro only if this is normal start (e.g. no server, no quickstart, no printing )
2692 640 : if ( !rCmdLine.IsInvisible() &&
2693 0 : !rCmdLine.IsHeadless() &&
2694 0 : !rCmdLine.IsQuickstart() &&
2695 0 : !rCmdLine.IsMinimized() &&
2696 0 : !rCmdLine.IsNoLogo() &&
2697 0 : !rCmdLine.IsTerminateAfterInit() &&
2698 160 : rCmdLine.GetPrintList().empty() &&
2699 480 : rCmdLine.GetPrintToList().empty() &&
2700 160 : rCmdLine.GetConversionList().empty() )
2701 : {
2702 : // Determine application name from command line parameters
2703 0 : OUString aAppName;
2704 0 : if ( rCmdLine.IsWriter() )
2705 0 : aAppName = "writer";
2706 0 : else if ( rCmdLine.IsCalc() )
2707 0 : aAppName = "calc";
2708 0 : else if ( rCmdLine.IsDraw() )
2709 0 : aAppName = "draw";
2710 0 : else if ( rCmdLine.IsImpress() )
2711 0 : aAppName = "impress";
2712 0 : else if ( rCmdLine.IsBase() )
2713 0 : aAppName = "base";
2714 0 : else if ( rCmdLine.IsGlobal() )
2715 0 : aAppName = "global";
2716 0 : else if ( rCmdLine.IsMath() )
2717 0 : aAppName = "math";
2718 0 : else if ( rCmdLine.IsWeb() )
2719 0 : aAppName = "web";
2720 :
2721 : // Which splash to use
2722 0 : OUString aSplashService( "com.sun.star.office.SplashScreen" );
2723 0 : if ( rCmdLine.HasSplashPipe() )
2724 0 : aSplashService = "com.sun.star.office.PipeSplashScreen";
2725 :
2726 0 : bVisible = true;
2727 0 : Sequence< Any > aSeq( 2 );
2728 0 : aSeq[0] <<= bVisible;
2729 0 : aSeq[1] <<= aAppName;
2730 0 : css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2731 0 : m_rSplashScreen = Reference<XStatusIndicator>(
2732 0 : xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aSplashService, aSeq, xContext),
2733 0 : UNO_QUERY);
2734 :
2735 0 : if(m_rSplashScreen.is())
2736 0 : m_rSplashScreen->start(OUString("SplashScreen"), 100);
2737 : }
2738 :
2739 160 : }
2740 :
2741 1728 : void Desktop::SetSplashScreenProgress(sal_Int32 iProgress)
2742 : {
2743 1728 : if(m_rSplashScreen.is())
2744 : {
2745 0 : m_rSplashScreen->setValue(iProgress);
2746 : }
2747 1728 : }
2748 :
2749 480 : void Desktop::SetSplashScreenText( const OUString& rText )
2750 : {
2751 480 : if( m_rSplashScreen.is() )
2752 : {
2753 0 : m_rSplashScreen->setText( rText );
2754 : }
2755 480 : }
2756 :
2757 1606 : void Desktop::CloseSplashScreen()
2758 : {
2759 1606 : if(m_rSplashScreen.is())
2760 : {
2761 0 : m_rSplashScreen->end();
2762 0 : m_rSplashScreen = NULL;
2763 : }
2764 1606 : }
2765 :
2766 :
2767 39 : void Desktop::DoFirstRunInitializations()
2768 : {
2769 : try
2770 : {
2771 39 : Reference< XJobExecutor > xExecutor = theJobExecutor::get( ::comphelper::getProcessComponentContext() );
2772 39 : xExecutor->trigger( OUString("onFirstRunInitialization") );
2773 : }
2774 0 : catch(const ::com::sun::star::uno::Exception&)
2775 : {
2776 : SAL_WARN( "desktop.app", "Desktop::DoFirstRunInitializations: caught an exception while trigger job executor ..." );
2777 : }
2778 39 : }
2779 :
2780 0 : void Desktop::ShowBackingComponent(Desktop * progress)
2781 : {
2782 0 : if (GetCommandLineArgs().IsNoDefault())
2783 : {
2784 0 : return;
2785 : }
2786 0 : Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
2787 0 : Reference< XDesktop2 > xDesktop = css::frame::Desktop::create(xContext);
2788 0 : if (progress != 0)
2789 : {
2790 0 : progress->SetSplashScreenProgress(60);
2791 : }
2792 0 : Reference< XFrame > xBackingFrame = xDesktop->findFrame(OUString( "_blank" ), 0);
2793 0 : Reference< ::com::sun::star::awt::XWindow > xContainerWindow;
2794 :
2795 0 : if (xBackingFrame.is())
2796 0 : xContainerWindow = xBackingFrame->getContainerWindow();
2797 0 : if (xContainerWindow.is())
2798 : {
2799 : // set the WB_EXT_DOCUMENT style. Normally, this is done by the TaskCreator service when a "_blank"
2800 : // frame/window is created. Since we do not use the TaskCreator here, we need to mimic its behavior,
2801 : // otherwise documents loaded into this frame will later on miss functionality depending on the style.
2802 0 : vcl::Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
2803 : SAL_WARN_IF( !pContainerWindow, "desktop.app", "Desktop::Main: no implementation access to the frame's container window!" );
2804 0 : pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WB_EXT_DOCUMENT );
2805 0 : if (progress != 0)
2806 : {
2807 0 : progress->SetSplashScreenProgress(75);
2808 : }
2809 :
2810 0 : Reference< XController > xStartModule = StartModule::createWithParentWindow( xContext, xContainerWindow);
2811 : // Attention: You MUST(!) call setComponent() before you call attachFrame().
2812 : // Because the backing component set the property "IsBackingMode" of the frame
2813 : // to true inside attachFrame(). But setComponent() reset this state everytimes ...
2814 0 : xBackingFrame->setComponent(Reference< XWindow >(xStartModule, UNO_QUERY), xStartModule);
2815 0 : if (progress != 0)
2816 : {
2817 0 : progress->SetSplashScreenProgress(100);
2818 : }
2819 0 : xStartModule->attachFrame(xBackingFrame);
2820 0 : if (progress != 0)
2821 : {
2822 0 : progress->CloseSplashScreen();
2823 : }
2824 0 : xContainerWindow->setVisible(sal_True);
2825 0 : }
2826 : }
2827 :
2828 :
2829 96 : void Desktop::CheckFirstRun( )
2830 : {
2831 96 : if (officecfg::Office::Common::Misc::FirstRun::get())
2832 : {
2833 : // use VCL timer, which won't trigger during shutdown if the
2834 : // application exits before timeout
2835 64 : m_firstRunTimer.SetTimeout(3000); // 3 sec.
2836 64 : m_firstRunTimer.SetTimeoutHdl(LINK(this, Desktop, AsyncInitFirstRun));
2837 64 : m_firstRunTimer.Start();
2838 :
2839 : #ifdef WNT
2840 : // Check if Quckstarter should be started (on Windows only)
2841 : TCHAR szValue[8192];
2842 : DWORD nValueSize = sizeof(szValue);
2843 : HKEY hKey;
2844 : if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, "Software\\LibreOffice", &hKey ) )
2845 : {
2846 : if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("RunQuickstartAtFirstStart"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
2847 : {
2848 : css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2849 : css::office::Quickstart::createAutoStart(xContext, true/*Quickstart*/, true/*bAutostart*/);
2850 : RegCloseKey( hKey );
2851 : }
2852 : }
2853 : #endif
2854 :
2855 : boost::shared_ptr< comphelper::ConfigurationChanges > batch(
2856 64 : comphelper::ConfigurationChanges::create());
2857 64 : officecfg::Office::Common::Misc::FirstRun::set(false, batch);
2858 64 : batch->commit();
2859 : }
2860 96 : }
2861 :
2862 480 : }
2863 :
2864 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|