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