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