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