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