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