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