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