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