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