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