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