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