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