xref: /aoo41x/main/desktop/source/app/app.cxx (revision a6114e23)
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             rtl_logfile_longTrace("|    checking last modification time of containing directory %s\n", U2A(rsDirectoryURL));
866             if (aDirectoryStat.getModifyTime().Seconds > aMarkerModifyTime.Seconds)
867             {
868                 rtl_logfile_longTrace("|        containing directory is newer than marker\n");
869                 return true;
870             }
871         }
872     }
873 
874     // No file in the directory is newer than the marker.
875     return false;
876 }
877 
878 
879 // install bundled but non-pre-registered extension blobs
880 static void installBundledExtensionBlobs()
881 {
882 	rtl::OUString aDirUrl( OUSTR("$BRAND_BASE_DIR/share/extensions/install"));
883 	::rtl::Bootstrap::expandMacros( aDirUrl);
884 	::osl::Directory aDir( aDirUrl);
885 
886     // Find out if we can exit early: only when there is an extension file newer
887     // than the marker we have to install any extension.
888     ::rtl::OUString sMarkerURL (RTL_CONSTASCII_USTRINGPARAM("$BUNDLED_EXTENSIONS_USER/lastsynchronized.bundled"));
889     ::rtl::Bootstrap::expandMacros(sMarkerURL);
890     if ( ! needsInstallBundledExtensionBlobs(sMarkerURL, aDirUrl))
891         return;
892     writeLastModified(sMarkerURL);
893 
894     // get the ExtensionManager
895 	::css::uno::Reference< ::css::uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
896 	::css::uno::Reference< ::css::deployment::XExtensionManager> xEM = ::css::deployment::ExtensionManager::get( xContext);
897 	// provide the minimal set of requirements to call ExtensionManager's methods
898 	MinimalCommandEnv* pMiniCmdEnv = new MinimalCommandEnv;
899 	::css::uno::Reference< css::ucb::XCommandEnvironment> xCmdEnv( static_cast< cppu::OWeakObject*>(pMiniCmdEnv), css::uno::UNO_QUERY);
900 	const ::css::beans::NamedValue aNamedProps( OUSTR("SUPPRESS_LICENSE"), ::css::uno::makeAny( OUSTR("1")));
901 	const ::css::uno::Sequence< ::css::beans::NamedValue> xProperties( &aNamedProps, 1);
902 	::css::uno::Reference< ::css::task::XAbortChannel> xAbortChannel;
903 
904 	// get the list of deployed extensions
905 	typedef std::hash_set< rtl::OUString, ::rtl::OUStringHash> StringSet;
906 	StringSet aExtNameSet;
907 	css::uno::Sequence< css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > > xListOfLists = xEM->getAllExtensions( xAbortChannel, xCmdEnv);
908 	const sal_Int32 nLen1 = xListOfLists.getLength();
909 	for( int i1 = 0; i1 < nLen1; ++i1) {
910 		css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > xListOfPacks = xListOfLists[i1];
911 		const sal_Int32 nLen2 = xListOfPacks.getLength();
912 		for( int i2 = 0; i2 < nLen2; ++i2) {
913 			css::uno::Reference<css::deployment::XPackage> xPackage = xListOfPacks[i2];
914 			if( !xPackage.is())
915 				continue;
916 			aExtNameSet.insert( xPackage->getName());
917 		}
918 	}
919 
920 	// iterate over the bundled extension blobs
921 	::osl::File::RC rc = aDir.open();
922 	while( rc == osl::File::E_None) {
923 		::osl::DirectoryItem aDI;
924 		if( aDir.getNextItem( aDI) != osl::File::E_None)
925 			break;
926 		::osl::FileStatus aFileStat( FileStatusMask_Type | FileStatusMask_FileURL);
927 		if( aDI.getFileStatus( aFileStat) != ::osl::File::E_None)
928 			continue;
929 		if( aFileStat.getFileType() != ::osl::FileStatus::Regular)
930 			continue;
931 		try {
932 			// check if the extension is already installed
933 			const rtl::OUString& rExtFileUrl = aFileStat.getFileURL();
934 			const sal_Int32 nBaseIndex = rExtFileUrl.lastIndexOf('/');
935 			const ::rtl::OUString aBaseName = (nBaseIndex < 0) ? rExtFileUrl : rExtFileUrl.copy( nBaseIndex+1);
936 			const bool bFound = (aExtNameSet.find( aBaseName) != aExtNameSet.end());
937 			if( bFound)
938 				continue;
939 			// request to install the extension blob
940 			xEM->addExtension( rExtFileUrl, xProperties, OUSTR("user"), xAbortChannel, xCmdEnv);
941 		// ExtensionManager problems are not worth to die for here
942 		} catch( css::uno::RuntimeException&) {
943 		} catch( css::deployment::DeploymentException&) {
944 		}
945 	}
946 }
947 
948 //=============================================================================
949 
950 Desktop::Desktop()
951 : m_bServicesRegistered( false )
952 , m_aBootstrapError( BE_OK )
953 , m_pLockfile( NULL )
954 {
955     RTL_LOGFILE_TRACE( "desktop (cd100003) ::Desktop::Desktop" );
956 }
957 
958 Desktop::~Desktop()
959 {
960 }
961 
962 void Desktop::Init()
963 {
964     RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::Init" );
965     SetBootstrapStatus(BS_OK);
966 
967     // Check for lastsynchronized file for pre-registered bundled extensions in the user directory
968     // and test if synchronzation is necessary!
969     {
970         ::rtl::OUString aUserLastSyncFilePathURL = getLastSyncFileURLFromUserInstallation();
971         ::rtl::OUString aPreregSyncFilePathURL = getLastSyncFileURLFromBrandInstallation();
972 
973         if ( needsSynchronization( aPreregSyncFilePathURL, aUserLastSyncFilePathURL ))
974         {
975             rtl::OUString aUserPath = getUserBundledExtPathURL();
976             rtl::OUString aPreregBundledPath = getBrandSharePreregBundledPathURL();
977 
978             // copy bundled folder to the user directory
979             osl::FileBase::RC rc = osl::Directory::createPath(aUserPath);
980             (void) rc;
981             copy_prereg_bundled_recursive( aPreregBundledPath, aUserPath, +1 );
982         }
983     }
984 
985     // create service factory...
986     Reference < XMultiServiceFactory > rSMgr = CreateApplicationServiceManager();
987     if( rSMgr.is() )
988     {
989         ::comphelper::setProcessServiceFactory( rSMgr );
990     }
991     else
992     {
993         SetBootstrapError( BE_UNO_SERVICEMANAGER );
994     }
995 
996     if ( GetBootstrapError() == BE_OK )
997     {
998         // prepare language
999         if ( !LanguageSelection::prepareLanguage() )
1000         {
1001             if ( LanguageSelection::getStatus() == LanguageSelection::LS_STATUS_CANNOT_DETERMINE_LANGUAGE )
1002                 SetBootstrapError( BE_LANGUAGE_MISSING );
1003             else
1004                 SetBootstrapError( BE_OFFICECONFIG_BROKEN );
1005         }
1006     }
1007 
1008     if ( GetBootstrapError() == BE_OK )
1009     {
1010         CommandLineArgs* pCmdLineArgs = GetCommandLineArgs();
1011 #ifdef UNX
1012     //  check whether we need to print cmdline help
1013     if ( pCmdLineArgs->IsHelp() ) {
1014         displayCmdlineHelp();
1015         SetBootstrapStatus(BS_TERMINATE);
1016     }
1017 #endif
1018         // start ipc thread only for non-remote offices
1019         RTL_LOGFILE_CONTEXT( aLog2, "desktop (cd100003) ::OfficeIPCThread::EnableOfficeIPCThread" );
1020         OfficeIPCThread::Status aStatus = OfficeIPCThread::EnableOfficeIPCThread();
1021         if ( aStatus == OfficeIPCThread::IPC_STATUS_BOOTSTRAP_ERROR )
1022         {
1023             SetBootstrapError( BE_PATHINFO_MISSING );
1024 
1025         }
1026         else if ( aStatus == OfficeIPCThread::IPC_STATUS_MULTI_TS_ERROR )
1027         {
1028             SetBootstrapError( BE_MUTLISESSION_NOT_SUPPROTED );
1029         }
1030         else if ( aStatus == OfficeIPCThread::IPC_STATUS_2ND_OFFICE )
1031         {
1032             // 2nd office startup should terminate after sending cmdlineargs through pipe
1033             SetBootstrapStatus(BS_TERMINATE);
1034         }
1035         else if ( pCmdLineArgs->IsHelp() )
1036         {
1037             // disable IPC thread in an instance that is just showing a help message
1038             OfficeIPCThread::DisableOfficeIPCThread();
1039         }
1040         pSignalHandler = new SalMainPipeExchangeSignalHandler;
1041     }
1042 }
1043 
1044 void Desktop::DeInit()
1045 {
1046     RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::DeInit" );
1047 
1048     try {
1049         // instead of removing of the configManager just let it commit all the changes
1050         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
1051         utl::ConfigManager::GetConfigManager()->StoreConfigItems();
1052         FlushConfiguration();
1053         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
1054 
1055         // close splashscreen if it's still open
1056         CloseSplashScreen();
1057         Reference<XMultiServiceFactory> xXMultiServiceFactory(::comphelper::getProcessServiceFactory());
1058         DestroyApplicationServiceManager( xXMultiServiceFactory );
1059         // nobody should get a destroyd service factory...
1060         ::comphelper::setProcessServiceFactory( NULL );
1061 
1062         // clear lockfile
1063         if (m_pLockfile != NULL)
1064             m_pLockfile->clean();
1065 
1066         OfficeIPCThread::DisableOfficeIPCThread();
1067         if( pSignalHandler )
1068             DELETEZ( pSignalHandler );
1069     } catch (RuntimeException&) {
1070         // someone threw an exception during shutdown
1071         // this will leave some garbage behind..
1072     }
1073 
1074     RTL_LOGFILE_CONTEXT_TRACE( aLog, "FINISHED WITH Destop::DeInit" );
1075 }
1076 
1077 sal_Bool Desktop::QueryExit()
1078 {
1079     try
1080     {
1081         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
1082         utl::ConfigManager::GetConfigManager()->StoreConfigItems();
1083         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
1084     }
1085     catch ( RuntimeException& )
1086     {
1087     }
1088 
1089     const sal_Char SUSPEND_QUICKSTARTVETO[] = "SuspendQuickstartVeto";
1090 
1091     Reference< ::com::sun::star::frame::XDesktop >
1092             xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
1093                 UNO_QUERY );
1094 
1095     Reference < ::com::sun::star::beans::XPropertySet > xPropertySet( xDesktop, UNO_QUERY );
1096     if ( xPropertySet.is() )
1097     {
1098         Any a;
1099         a <<= (sal_Bool)sal_True;
1100         xPropertySet->setPropertyValue( OUSTRING(RTL_CONSTASCII_USTRINGPARAM( SUSPEND_QUICKSTARTVETO )), a );
1101     }
1102 
1103     sal_Bool bExit = ( !xDesktop.is() || xDesktop->terminate() );
1104 
1105 
1106     if ( !bExit && xPropertySet.is() )
1107     {
1108         Any a;
1109         a <<= (sal_Bool)sal_False;
1110         xPropertySet->setPropertyValue( OUSTRING(RTL_CONSTASCII_USTRINGPARAM( SUSPEND_QUICKSTARTVETO )), a );
1111     }
1112     else
1113     {
1114         FlushConfiguration();
1115         try
1116         {
1117             // it is no problem to call DisableOfficeIPCThread() more than once
1118             // it also looks to be threadsafe
1119             OfficeIPCThread::DisableOfficeIPCThread();
1120         }
1121         catch ( RuntimeException& )
1122         {
1123         }
1124 
1125         if (m_pLockfile != NULL) m_pLockfile->clean();
1126     }
1127 
1128     return bExit;
1129 }
1130 
1131 void Desktop::HandleBootstrapPathErrors( ::utl::Bootstrap::Status aBootstrapStatus, const OUString& aDiagnosticMessage )
1132 {
1133     if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
1134     {
1135         sal_Bool            bWorkstationInstallation = sal_False;
1136         ::rtl::OUString        aBaseInstallURL;
1137         ::rtl::OUString        aUserInstallURL;
1138         ::rtl::OUString        aProductKey;
1139         ::rtl::OUString        aTemp;
1140         ::vos::OStartupInfo aInfo;
1141 
1142         aInfo.getExecutableFile( aProductKey );
1143         sal_uInt32     lastIndex = aProductKey.lastIndexOf('/');
1144         if ( lastIndex > 0 )
1145             aProductKey = aProductKey.copy( lastIndex+1 );
1146 
1147         aTemp = ::utl::Bootstrap::getProductKey( aProductKey );
1148         if ( aTemp.getLength() > 0 )
1149             aProductKey = aTemp;
1150 
1151         ::utl::Bootstrap::PathStatus aBaseInstallStatus = ::utl::Bootstrap::locateBaseInstallation( aBaseInstallURL );
1152         ::utl::Bootstrap::PathStatus aUserInstallStatus = ::utl::Bootstrap::locateUserInstallation( aUserInstallURL );
1153 
1154         if (( aBaseInstallStatus == ::utl::Bootstrap::PATH_EXISTS &&
1155               aUserInstallStatus == ::utl::Bootstrap::PATH_EXISTS        ))
1156         {
1157             if ( aBaseInstallURL != aUserInstallURL )
1158                 bWorkstationInstallation = sal_True;
1159         }
1160 
1161         OUString        aMessage;
1162         OUStringBuffer    aBuffer( 100 );
1163         aBuffer.append( aDiagnosticMessage );
1164 
1165         aBuffer.appendAscii( "\n" );
1166 
1167         ErrorBox aBootstrapFailedBox( NULL, WB_OK, aMessage );
1168         aBootstrapFailedBox.SetText( aProductKey );
1169         aBootstrapFailedBox.Execute();
1170     }
1171 }
1172 
1173 // Create a error message depending on bootstrap failure code and an optional file url
1174 ::rtl::OUString    Desktop::CreateErrorMsgString(
1175     utl::Bootstrap::FailureCode nFailureCode,
1176     const ::rtl::OUString& aFileURL )
1177 {
1178     OUString        aMsg;
1179     OUString        aFilePath;
1180     sal_Bool        bFileInfo = sal_True;
1181 
1182     switch ( nFailureCode )
1183     {
1184         /// the shared installation directory could not be located
1185         case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
1186         {
1187             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_PATH_INVALID,
1188                         OUString( RTL_CONSTASCII_USTRINGPARAM( "The installation path is not available." )) );
1189             bFileInfo = sal_False;
1190         }
1191         break;
1192 
1193         /// the bootstrap INI file could not be found or read
1194         case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
1195         {
1196             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
1197                         OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is missing." )) );
1198         }
1199         break;
1200 
1201         /// the bootstrap INI is missing a required entry
1202         /// the bootstrap INI contains invalid data
1203          case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
1204          case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
1205         {
1206             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_CORRUPT,
1207                         OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is corrupt." )) );
1208         }
1209         break;
1210 
1211         /// the version locator INI file could not be found or read
1212         case ::utl::Bootstrap::MISSING_VERSION_FILE:
1213         {
1214             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
1215                         OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is missing." )) );
1216         }
1217         break;
1218 
1219         /// the version locator INI has no entry for this version
1220          case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
1221         {
1222             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SUPPORT,
1223                         OUString( RTL_CONSTASCII_USTRINGPARAM( "The main configuration file \"$1\" does not support the current version." )) );
1224         }
1225         break;
1226 
1227         /// the user installation directory does not exist
1228            case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
1229         {
1230             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_DIR_MISSING,
1231                         OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration directory \"$1\" is missing." )) );
1232         }
1233         break;
1234 
1235         /// some bootstrap data was invalid in unexpected ways
1236         case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
1237         {
1238             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_INTERNAL,
1239                         OUString( RTL_CONSTASCII_USTRINGPARAM( "An internal failure occurred." )) );
1240             bFileInfo = sal_False;
1241         }
1242         break;
1243 
1244         case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
1245         {
1246             // This needs to be improved, see #i67575#:
1247             aMsg = OUString(
1248                 RTL_CONSTASCII_USTRINGPARAM( "Invalid version file entry" ) );
1249             bFileInfo = sal_False;
1250         }
1251         break;
1252 
1253         case ::utl::Bootstrap::NO_FAILURE:
1254         {
1255             OSL_ASSERT(false);
1256         }
1257         break;
1258     }
1259 
1260     if ( bFileInfo )
1261     {
1262         String aMsgString( aMsg );
1263 
1264         osl::File::getSystemPathFromFileURL( aFileURL, aFilePath );
1265 
1266         aMsgString.SearchAndReplaceAscii( "$1", aFilePath );
1267         aMsg = aMsgString;
1268     }
1269 
1270     return MakeStartupErrorMessage( aMsg );
1271 }
1272 
1273 void Desktop::HandleBootstrapErrors( BootstrapError aBootstrapError )
1274 {
1275 	if ( aBootstrapError == BE_MUTLISESSION_NOT_SUPPROTED ) {
1276 		OUString        aMessage;
1277 		aMessage = GetMsgString( STR_BOOTSTRAP_ERR_MULTISESSION,
1278                         OUString( RTL_CONSTASCII_USTRINGPARAM( "You have another instance running in a different terminal session. Close that instance and then try again." )) );
1279         FatalError(aMessage,sal_False);
1280 
1281 	} else if ( aBootstrapError == BE_PATHINFO_MISSING )
1282     {
1283         OUString                    aErrorMsg;
1284         OUString                    aBuffer;
1285         utl::Bootstrap::Status        aBootstrapStatus;
1286         utl::Bootstrap::FailureCode    nFailureCode;
1287 
1288         aBootstrapStatus = ::utl::Bootstrap::checkBootstrapStatus( aBuffer, nFailureCode );
1289         if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
1290         {
1291             switch ( nFailureCode )
1292             {
1293                 case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
1294                 case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
1295                 {
1296                     aErrorMsg = CreateErrorMsgString( nFailureCode, OUString() );
1297                 }
1298                 break;
1299 
1300                 /// the bootstrap INI file could not be found or read
1301                 /// the bootstrap INI is missing a required entry
1302                 /// the bootstrap INI contains invalid data
1303                  case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
1304                  case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
1305                 case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
1306                 {
1307                     OUString aBootstrapFileURL;
1308 
1309                     utl::Bootstrap::locateBootstrapFile( aBootstrapFileURL );
1310                     aErrorMsg = CreateErrorMsgString( nFailureCode, aBootstrapFileURL );
1311                 }
1312                 break;
1313 
1314                 /// the version locator INI file could not be found or read
1315                 /// the version locator INI has no entry for this version
1316                 /// the version locator INI entry is not a valid directory URL
1317                    case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
1318                  case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
1319                  case ::utl::Bootstrap::MISSING_VERSION_FILE:
1320                 {
1321                     OUString aVersionFileURL;
1322 
1323                     utl::Bootstrap::locateVersionFile( aVersionFileURL );
1324                     aErrorMsg = CreateErrorMsgString( nFailureCode, aVersionFileURL );
1325                 }
1326                 break;
1327 
1328                 /// the user installation directory does not exist
1329                    case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
1330                 {
1331                     OUString aUserInstallationURL;
1332 
1333                     utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
1334                     aErrorMsg = CreateErrorMsgString( nFailureCode, aUserInstallationURL );
1335                 }
1336                 break;
1337 
1338                 case ::utl::Bootstrap::NO_FAILURE:
1339                 {
1340                     OSL_ASSERT(false);
1341                 }
1342                 break;
1343             }
1344 
1345             HandleBootstrapPathErrors( aBootstrapStatus, aErrorMsg );
1346         }
1347     }
1348     else if ( aBootstrapError == BE_UNO_SERVICEMANAGER || aBootstrapError == BE_UNO_SERVICE_CONFIG_MISSING )
1349     {
1350         // Uno service manager is not available. VCL needs a uno service manager to display a message box!!!
1351         // Currently we are not able to display a message box with a service manager due to this limitations inside VCL.
1352 
1353         // When UNO is not properly initialized, all kinds of things can fail
1354         // and cause the process to crash (e.g., a call to GetMsgString may
1355         // crash when somewhere deep within that call Any::operator <= is used
1356         // with a PropertyValue, and no binary UNO type description for
1357         // PropertyValue is available).  To give the user a hint even if
1358         // generating and displaying a message box below crashes, print a
1359         // hard-coded message on stderr first:
1360         fputs(
1361             aBootstrapError == BE_UNO_SERVICEMANAGER
1362             ? ("The application cannot be started. " "\n"
1363                "The component manager is not available." "\n")
1364                 // STR_BOOTSTRAP_ERR_CANNOT_START, STR_BOOTSTRAP_ERR_NO_SERVICE
1365             : ("The application cannot be started. " "\n"
1366                "The configuration service is not available." "\n"),
1367                 // STR_BOOTSTRAP_ERR_CANNOT_START,
1368                 // STR_BOOTSTRAP_ERR_NO_CFG_SERVICE
1369             stderr);
1370 
1371         // First sentence. We cannot bootstrap office further!
1372         OUString            aMessage;
1373         OUStringBuffer        aDiagnosticMessage( 100 );
1374 
1375         OUString aErrorMsg;
1376 
1377         if ( aBootstrapError == BE_UNO_SERVICEMANAGER )
1378             aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SERVICE,
1379                             OUString( RTL_CONSTASCII_USTRINGPARAM( "The service manager is not available." )) );
1380         else
1381             aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_CFG_SERVICE,
1382                             OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration service is not available." )) );
1383 
1384         aDiagnosticMessage.append( aErrorMsg );
1385         aDiagnosticMessage.appendAscii( "\n" );
1386 
1387         // Due to the fact the we haven't a backup applicat.rdb file anymore it is not possible to
1388         // repair the installation with the setup executable besides the office executable. Now
1389         // we have to ask the user to start the setup on CD/installation directory manually!!
1390         OUString aStartSetupManually( GetMsgString(
1391             STR_ASK_START_SETUP_MANUALLY,
1392             OUString( RTL_CONSTASCII_USTRINGPARAM( "Start setup application to repair the installation from CD, or the folder containing the installation packages." )) ));
1393 
1394         aDiagnosticMessage.append( aStartSetupManually );
1395         aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
1396 
1397         FatalError( aMessage);
1398     }
1399     else if ( aBootstrapError == BE_OFFICECONFIG_BROKEN )
1400     {
1401         OUString aMessage;
1402         OUStringBuffer aDiagnosticMessage( 100 );
1403         OUString aErrorMsg;
1404         aErrorMsg = GetMsgString( STR_CONFIG_ERR_ACCESS_GENERAL,
1405             OUString( RTL_CONSTASCII_USTRINGPARAM( "A general error occurred while accessing your central configuration." )) );
1406         aDiagnosticMessage.append( aErrorMsg );
1407         aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
1408         FatalError(aMessage);
1409     }
1410     else if ( aBootstrapError == BE_USERINSTALL_FAILED )
1411     {
1412         OUString aMessage;
1413         OUStringBuffer aDiagnosticMessage( 100 );
1414         OUString aErrorMsg;
1415         aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_INTERNAL,
1416             OUString( RTL_CONSTASCII_USTRINGPARAM( "User installation could not be completed" )) );
1417         aDiagnosticMessage.append( aErrorMsg );
1418         aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
1419         FatalError(aMessage);
1420     }
1421     else if ( aBootstrapError == BE_LANGUAGE_MISSING )
1422     {
1423         OUString aMessage;
1424         OUStringBuffer aDiagnosticMessage( 100 );
1425         OUString aErrorMsg;
1426         aErrorMsg = GetMsgString(
1427             //@@@ FIXME: should use an own resource string => #i36213#
1428             STR_BOOTSTRAP_ERR_LANGUAGE_MISSING,
1429             OUString( RTL_CONSTASCII_USTRINGPARAM(
1430                 "Language could not be determined." )) );
1431         aDiagnosticMessage.append( aErrorMsg );
1432         aMessage = MakeStartupErrorMessage(
1433             aDiagnosticMessage.makeStringAndClear() );
1434         FatalError(aMessage);
1435     }
1436     else if (( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE ) ||
1437              ( aBootstrapError == BE_USERINSTALL_NOWRITEACCESS      ))
1438     {
1439         OUString       aUserInstallationURL;
1440         OUString       aUserInstallationPath;
1441         OUString       aMessage;
1442         OUString       aErrorMsg;
1443         OUStringBuffer aDiagnosticMessage( 100 );
1444 
1445         utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
1446 
1447         if ( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE )
1448             aErrorMsg = GetMsgString(
1449                 STR_BOOSTRAP_ERR_NOTENOUGHDISKSPACE,
1450                 OUString( RTL_CONSTASCII_USTRINGPARAM(
1451                     "User installation could not be completed due to insufficient free disk space." )) );
1452         else
1453             aErrorMsg = GetMsgString(
1454                 STR_BOOSTRAP_ERR_NOACCESSRIGHTS,
1455                 OUString( RTL_CONSTASCII_USTRINGPARAM(
1456                     "User installation could not be processed due to missing access rights." )) );
1457 
1458         osl::File::getSystemPathFromFileURL( aUserInstallationURL, aUserInstallationPath );
1459 
1460         aDiagnosticMessage.append( aErrorMsg );
1461         aDiagnosticMessage.append( aUserInstallationPath );
1462         aMessage = MakeStartupErrorMessage(
1463             aDiagnosticMessage.makeStringAndClear() );
1464         FatalError(aMessage);
1465     }
1466 
1467     return;
1468 }
1469 
1470 
1471 void Desktop::retrieveCrashReporterState()
1472 {
1473     static const ::rtl::OUString CFG_PACKAGE_RECOVERY   = ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery/");
1474     static const ::rtl::OUString CFG_PATH_CRASHREPORTER = ::rtl::OUString::createFromAscii("CrashReporter"                  );
1475     static const ::rtl::OUString CFG_ENTRY_ENABLED      = ::rtl::OUString::createFromAscii("Enabled"                        );
1476 
1477     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1478 
1479     sal_Bool bEnabled( sal_True );
1480     if ( xSMGR.is() )
1481     {
1482         css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
1483                                     xSMGR,
1484                                     CFG_PACKAGE_RECOVERY,
1485                                     CFG_PATH_CRASHREPORTER,
1486                                     CFG_ENTRY_ENABLED,
1487                                     ::comphelper::ConfigurationHelper::E_READONLY);
1488         aVal >>= bEnabled;
1489     }
1490     _bCrashReporterEnabled = bEnabled;
1491 }
1492 
1493 sal_Bool Desktop::isUIOnSessionShutdownAllowed()
1494 {
1495     static const ::rtl::OUString CFG_PACKAGE_RECOVERY = ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery/");
1496     static const ::rtl::OUString CFG_PATH_SESSION     = ::rtl::OUString::createFromAscii("SessionShutdown"                );
1497     static const ::rtl::OUString CFG_ENTRY_UIENABLED  = ::rtl::OUString::createFromAscii("DocumentStoreUIEnabled"         );
1498 
1499     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1500 
1501     sal_Bool bResult = sal_False;
1502     if ( xSMGR.is() )
1503     {
1504         css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
1505                                     xSMGR,
1506                                     CFG_PACKAGE_RECOVERY,
1507                                     CFG_PATH_SESSION,
1508                                     CFG_ENTRY_UIENABLED,
1509                                     ::comphelper::ConfigurationHelper::E_READONLY);
1510         aVal >>= bResult;
1511     }
1512 
1513     return bResult;
1514 }
1515 
1516 //-----------------------------------------------
1517 /** @short  check if crash reporter feature is enabled or
1518             disabled.
1519 */
1520 sal_Bool Desktop::isCrashReporterEnabled()
1521 {
1522     return _bCrashReporterEnabled;
1523 }
1524 
1525 //-----------------------------------------------
1526 /** @short  check if recovery must be started or not.
1527 
1528     @param  bCrashed [boolean ... out!]
1529             the office crashed last times.
1530             But may be there are no recovery data.
1531             Usefull to trigger the error report tool without
1532             showing the recovery UI.
1533 
1534     @param  bRecoveryDataExists [boolean ... out!]
1535             there exists some recovery data.
1536 
1537     @param  bSessionDataExists [boolean ... out!]
1538             there exists some session data.
1539             Because the user may be logged out last time from it's
1540             unix session...
1541 */
1542 void impl_checkRecoveryState(sal_Bool& bCrashed           ,
1543                              sal_Bool& bRecoveryDataExists,
1544                              sal_Bool& bSessionDataExists )
1545 {
1546     static const ::rtl::OUString SERVICENAME_RECOVERYCORE = ::rtl::OUString::createFromAscii("com.sun.star.frame.AutoRecovery");
1547     static const ::rtl::OUString PROP_CRASHED             = ::rtl::OUString::createFromAscii("Crashed"                        );
1548     static const ::rtl::OUString PROP_EXISTSRECOVERY      = ::rtl::OUString::createFromAscii("ExistsRecoveryData"             );
1549     static const ::rtl::OUString PROP_EXISTSSESSION       = ::rtl::OUString::createFromAscii("ExistsSessionData"              );
1550     static const ::rtl::OUString CFG_PACKAGE_RECOVERY     = ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery/");
1551     static const ::rtl::OUString CFG_PATH_RECOVERYINFO    = ::rtl::OUString::createFromAscii("RecoveryInfo"                   );
1552 
1553     bCrashed            = sal_False;
1554     bRecoveryDataExists = sal_False;
1555     bSessionDataExists  = sal_False;
1556 
1557     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1558     try
1559     {
1560         css::uno::Reference< css::beans::XPropertySet > xRecovery(
1561             xSMGR->createInstance(SERVICENAME_RECOVERYCORE),
1562             css::uno::UNO_QUERY_THROW);
1563 
1564         xRecovery->getPropertyValue(PROP_CRASHED       ) >>= bCrashed           ;
1565         xRecovery->getPropertyValue(PROP_EXISTSRECOVERY) >>= bRecoveryDataExists;
1566         xRecovery->getPropertyValue(PROP_EXISTSSESSION ) >>= bSessionDataExists ;
1567     }
1568     catch(const css::uno::Exception&) {}
1569 }
1570 
1571 //-----------------------------------------------
1572 /*  @short  start the recovery wizard.
1573 
1574     @param  bEmergencySave
1575             differs between EMERGENCY_SAVE and RECOVERY
1576 */
1577 sal_Bool impl_callRecoveryUI(sal_Bool bEmergencySave     ,
1578                              sal_Bool bCrashed           ,
1579                              sal_Bool bExistsRecoveryData)
1580 {
1581     static ::rtl::OUString SERVICENAME_RECOVERYUI = ::rtl::OUString::createFromAscii("com.sun.star.comp.svx.RecoveryUI"          );
1582     static ::rtl::OUString SERVICENAME_URLPARSER  = ::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer"          );
1583     static ::rtl::OUString COMMAND_EMERGENCYSAVE  = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/doEmergencySave");
1584     static ::rtl::OUString COMMAND_RECOVERY       = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/doAutoRecovery" );
1585     static ::rtl::OUString COMMAND_CRASHREPORT    = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/doCrashReport"  );
1586 
1587     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1588 
1589     css::uno::Reference< css::frame::XSynchronousDispatch > xRecoveryUI(
1590         xSMGR->createInstance(SERVICENAME_RECOVERYUI),
1591         css::uno::UNO_QUERY_THROW);
1592 
1593     css::uno::Reference< css::util::XURLTransformer > xURLParser(
1594         xSMGR->createInstance(SERVICENAME_URLPARSER),
1595         css::uno::UNO_QUERY_THROW);
1596 
1597     css::util::URL aURL;
1598     if (bEmergencySave)
1599         aURL.Complete = COMMAND_EMERGENCYSAVE;
1600     else
1601     {
1602         if (bExistsRecoveryData)
1603             aURL.Complete = COMMAND_RECOVERY;
1604         else
1605         if (bCrashed && Desktop::isCrashReporterEnabled() )
1606             aURL.Complete = COMMAND_CRASHREPORT;
1607     }
1608 
1609     sal_Bool bRet = sal_False;
1610     if ( aURL.Complete.getLength() > 0 )
1611     {
1612         xURLParser->parseStrict(aURL);
1613 
1614         css::uno::Any aRet = xRecoveryUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
1615         aRet >>= bRet;
1616     }
1617     return bRet;
1618 }
1619 
1620 /*
1621  * Save all open documents so they will be reopened
1622  * the next time the application ist started
1623  *
1624  * returns sal_True if at least one document could be saved...
1625  *
1626  */
1627 
1628 sal_Bool Desktop::_bTasksSaved = sal_False;
1629 
1630 sal_Bool Desktop::SaveTasks()
1631 {
1632     return impl_callRecoveryUI(
1633         sal_True , // sal_True => force emergency save
1634         sal_False, // 2. and 3. param not used if 1. = true!
1635         sal_False);
1636 }
1637 
1638 namespace {
1639 
1640 void restartOnMac(bool passArguments) {
1641 #if defined MACOSX
1642     OfficeIPCThread::DisableOfficeIPCThread();
1643     rtl::OUString execUrl;
1644     OSL_VERIFY(osl_getExecutableFile(&execUrl.pData) == osl_Process_E_None);
1645     rtl::OUString execPath;
1646     rtl::OString execPath8;
1647     if ((osl::FileBase::getSystemPathFromFileURL(execUrl, execPath)
1648          != osl::FileBase::E_None) ||
1649         !execPath.convertToString(
1650             &execPath8, osl_getThreadTextEncoding(),
1651             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
1652              RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
1653     {
1654         std::abort();
1655     }
1656     std::vector< rtl::OString > args;
1657     args.push_back(execPath8);
1658     bool wait = false;
1659     if (passArguments) {
1660         sal_uInt32 n = osl_getCommandArgCount();
1661         for (sal_uInt32 i = 0; i < n; ++i) {
1662             rtl::OUString arg;
1663             OSL_VERIFY(osl_getCommandArg(i, &arg.pData) == osl_Process_E_None);
1664             if (arg.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("-accept="))) {
1665                 wait = true;
1666             }
1667             rtl::OString arg8;
1668             if (!arg.convertToString(
1669                     &arg8, osl_getThreadTextEncoding(),
1670                     (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
1671                      RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
1672             {
1673                 std::abort();
1674             }
1675             args.push_back(arg8);
1676         }
1677     }
1678     std::vector< char const * > argPtrs;
1679     for (std::vector< rtl::OString >::iterator i(args.begin()); i != args.end();
1680          ++i)
1681     {
1682         argPtrs.push_back(i->getStr());
1683     }
1684     argPtrs.push_back(0);
1685     execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
1686     if (errno == ENOTSUP) { // happens when multithreaded on OS X < 10.6
1687         pid_t pid = fork();
1688         if (pid == 0) {
1689             execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
1690         } else if (pid > 0) {
1691             // Two simultaneously running soffice processes lead to two dock
1692             // icons, so avoid waiting here unless it must be assumed that the
1693             // process invoking soffice itself wants to wait for soffice to
1694             // finish:
1695             if (!wait) {
1696                 return;
1697             }
1698             int stat;
1699             if (waitpid(pid, &stat, 0) == pid && WIFEXITED(stat)) {
1700                 _exit(WEXITSTATUS(stat));
1701             }
1702         }
1703     }
1704     std::abort();
1705 #else
1706     (void) passArguments; // avoid warnings
1707 #endif
1708 }
1709 
1710 }
1711 
1712 sal_uInt16 Desktop::Exception(sal_uInt16 nError)
1713 {
1714     // protect against recursive calls
1715     static sal_Bool bInException = sal_False;
1716 
1717     sal_uInt16 nOldMode = Application::GetSystemWindowMode();
1718     Application::SetSystemWindowMode( nOldMode & ~SYSTEMWINDOW_MODE_NOAUTOMODE );
1719     Application::SetDefDialogParent( NULL );
1720 
1721     if ( bInException )
1722     {
1723         String aDoubleExceptionString;
1724         Application::Abort( aDoubleExceptionString );
1725     }
1726 
1727     bInException = sal_True;
1728     CommandLineArgs* pArgs = GetCommandLineArgs();
1729 
1730     // save all modified documents ... if it's allowed doing so.
1731     sal_Bool bRestart                           = sal_False;
1732     sal_Bool bAllowRecoveryAndSessionManagement = (
1733                                                     ( !pArgs->IsNoRestore()                    ) && // some use cases of office must work without recovery
1734                                                     ( !pArgs->IsHeadless()                     ) &&
1735                                                     ( !pArgs->IsServer()                       ) &&
1736                                                     (( nError & EXC_MAJORTYPE ) != EXC_DISPLAY ) && // recovery cant work without UI ... but UI layer seams to be the reason for this crash
1737                                                     ( Application::IsInExecute()               )    // crashes during startup and shutdown should be ignored (they indicates a corrupt installation ...)
1738                                                   );
1739     if ( bAllowRecoveryAndSessionManagement )
1740         bRestart = SaveTasks();
1741 
1742     FlushConfiguration();
1743 
1744     switch( nError & EXC_MAJORTYPE )
1745     {
1746         case EXC_RSCNOTLOADED:
1747         {
1748             String aResExceptionString;
1749             Application::Abort( aResExceptionString );
1750             break;
1751         }
1752 
1753         case EXC_SYSOBJNOTCREATED:
1754         {
1755             String aSysResExceptionString;
1756             Application::Abort( aSysResExceptionString );
1757             break;
1758         }
1759 
1760         default:
1761         {
1762             if (m_pLockfile != NULL) {
1763                 m_pLockfile->clean();
1764             }
1765             if( bRestart )
1766             {
1767                 OfficeIPCThread::DisableOfficeIPCThread();
1768                 if( pSignalHandler )
1769                     DELETEZ( pSignalHandler );
1770                 restartOnMac(false);
1771                 _exit( ExitHelper::E_CRASH_WITH_RESTART );
1772             }
1773             else
1774             {
1775                 Application::Abort( String() );
1776             }
1777 
1778             break;
1779         }
1780     }
1781 
1782     OSL_ASSERT(false); // unreachable
1783     return 0;
1784 }
1785 
1786 void Desktop::AppEvent( const ApplicationEvent& rAppEvent )
1787 {
1788     HandleAppEvent( rAppEvent );
1789 }
1790 
1791 struct ExecuteGlobals
1792 {
1793 	Reference < css::document::XEventListener > xGlobalBroadcaster;
1794 	sal_Bool bRestartRequested;
1795 	sal_Bool bUseSystemFileDialog;
1796 	std::auto_ptr<SvtLanguageOptions> pLanguageOptions;
1797     std::auto_ptr<SvtPathOptions> pPathOptions;
1798 
1799     ExecuteGlobals()
1800     : bRestartRequested( sal_False )
1801     , bUseSystemFileDialog( sal_True )
1802     {}
1803 };
1804 
1805 static ExecuteGlobals* pExecGlobals = NULL;
1806 
1807 void Desktop::Main()
1808 {
1809     pExecGlobals = new ExecuteGlobals();
1810 
1811     RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::Main" );
1812 
1813     // Remember current context object
1814     com::sun::star::uno::ContextLayer layer(
1815         com::sun::star::uno::getCurrentContext() );
1816 
1817     BootstrapError eError = GetBootstrapError();
1818     if ( eError != BE_OK )
1819     {
1820         HandleBootstrapErrors( eError );
1821         return;
1822     }
1823 
1824     BootstrapStatus eStatus = GetBootstrapStatus();
1825     if (eStatus == BS_TERMINATE) {
1826         return;
1827     }
1828 
1829     // Detect desktop environment - need to do this as early as possible
1830     com::sun::star::uno::setCurrentContext(
1831         new DesktopContext( com::sun::star::uno::getCurrentContext() ) );
1832 
1833     CommandLineArgs* pCmdLineArgs = GetCommandLineArgs();
1834 
1835     // setup configuration error handling
1836     ConfigurationErrorHandler aConfigErrHandler;
1837     if (!ShouldSuppressUI(pCmdLineArgs))
1838         aConfigErrHandler.activate();
1839 
1840     ResMgr::SetReadStringHook( ReplaceStringHookProc );
1841 
1842     // Startup screen
1843     RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main { OpenSplashScreen" );
1844     OpenSplashScreen();
1845     RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main } OpenSplashScreen" );
1846 
1847     {
1848         UserInstall::UserInstallError instErr_fin = UserInstall::finalize();
1849         if ( instErr_fin != UserInstall::E_None)
1850         {
1851             OSL_ENSURE(sal_False, "userinstall failed");
1852             if ( instErr_fin == UserInstall::E_NoDiskSpace )
1853                 HandleBootstrapErrors( BE_USERINSTALL_NOTENOUGHDISKSPACE );
1854             else if ( instErr_fin == UserInstall::E_NoWriteAccess )
1855                 HandleBootstrapErrors( BE_USERINSTALL_NOWRITEACCESS );
1856             else
1857                 HandleBootstrapErrors( BE_USERINSTALL_FAILED );
1858             return;
1859         }
1860         // refresh path information
1861         utl::Bootstrap::reloadData();
1862         SetSplashScreenProgress(25);
1863     }
1864 
1865     Reference< XMultiServiceFactory > xSMgr =
1866         ::comphelper::getProcessServiceFactory();
1867 
1868     Reference< ::com::sun::star::task::XRestartManager > xRestartManager;
1869     int         nAcquireCount( 0 );
1870     try
1871     {
1872         RegisterServices( xSMgr );
1873 
1874         //SetSplashScreenProgress(15);
1875 
1876 #ifndef UNX
1877         if ( pCmdLineArgs->IsHelp() ) {
1878             displayCmdlineHelp();
1879             return;
1880         }
1881 #endif
1882 
1883         // check user installation directory for lockfile so we can be sure
1884         // there is no other instance using our data files from a remote host
1885         RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main -> Lockfile" );
1886         m_pLockfile = new Lockfile;
1887         if ( !pCmdLineArgs->IsHeadless() && !pCmdLineArgs->IsInvisible() &&
1888              !pCmdLineArgs->IsNoLockcheck() && !m_pLockfile->check( Lockfile_execWarning )) {
1889             // Lockfile exists, and user clicked 'no'
1890             return;
1891         }
1892         RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main <- Lockfile" );
1893 
1894         // check if accessibility is enabled but not working and allow to quit
1895         RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ GetEnableATToolSupport" );
1896         if( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() )
1897         {
1898             sal_Bool bQuitApp;
1899 
1900             if( !InitAccessBridge( true, bQuitApp ) )
1901                 if( bQuitApp )
1902                     return;
1903         }
1904         RTL_LOGFILE_CONTEXT_TRACE( aLog, "} GetEnableATToolSupport" );
1905 
1906         // terminate if requested...
1907         if( pCmdLineArgs->IsTerminateAfterInit() ) return;
1908 
1909         //  Read the common configuration items for optimization purpose
1910         if ( !InitializeConfiguration() ) return;
1911 
1912         //SetSplashScreenProgress(20);
1913 
1914         // set static variable to enabled/disable crash reporter
1915         retrieveCrashReporterState();
1916         if ( !isCrashReporterEnabled() )
1917         {
1918             osl_setErrorReporting( sal_False );
1919             // disable stack trace feature
1920         }
1921 
1922         // create title string
1923         sal_Bool bCheckOk = sal_False;
1924         ::com::sun::star::lang::Locale aLocale;
1925         String aMgrName = String::CreateFromAscii( "ofa" );
1926         ResMgr* pLabelResMgr = ResMgr::SearchCreateResMgr( U2S( aMgrName ), aLocale );
1927         String aTitle = pLabelResMgr ? String( ResId( RID_APPTITLE, *pLabelResMgr ) ) : String();
1928         delete pLabelResMgr;
1929 
1930         // Check for StarOffice/Suite specific extensions runs also with OpenOffice installation sets
1931         OUString aTitleString( aTitle );
1932         bCheckOk = CheckInstallation( aTitleString );
1933         if ( !bCheckOk )
1934             return;
1935         else
1936             aTitle = aTitleString;
1937 
1938 #ifdef DBG_UTIL
1939         //include version ID in non product builds
1940         ::rtl::OUString aDefault;
1941         aTitle += DEFINE_CONST_UNICODE(" [");
1942         String aVerId( utl::Bootstrap::getBuildIdData( aDefault ));
1943         aTitle += aVerId;
1944         aTitle += ']';
1945 #endif
1946 
1947         SetDisplayName( aTitle );
1948         RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ create SvtPathOptions and SvtLanguageOptions" );
1949         pExecGlobals->pPathOptions.reset( new SvtPathOptions);
1950         SetSplashScreenProgress(40);
1951         RTL_LOGFILE_CONTEXT_TRACE( aLog, "} create SvtPathOptions and SvtLanguageOptions" );
1952 
1953         // Check special env variable #111015#
1954         std::vector< String > aUnrestrictedFolders;
1955         svt::getUnrestrictedFolders( aUnrestrictedFolders );
1956 
1957         if ( aUnrestrictedFolders.size() > 0 )
1958         {
1959             // Set different working directory. The first entry is
1960             // the new work path.
1961             String aWorkPath = aUnrestrictedFolders[0];
1962             SvtPathOptions().SetWorkPath( aWorkPath );
1963         }
1964 
1965 	    // create service for loadin SFX (still needed in startup)
1966         pExecGlobals->xGlobalBroadcaster = Reference < css::document::XEventListener >
1967 			( xSMgr->createInstance(
1968             DEFINE_CONST_UNICODE( "com.sun.star.frame.GlobalEventBroadcaster" ) ), UNO_QUERY );
1969 
1970         /* ensure existance of a default window that messages can be dispatched to
1971            This is for the benefit of testtool which uses PostUserEvent extensively
1972            and else can deadlock while creating this window from another tread while
1973            the main thread is not yet in the event loop.
1974         */
1975         Application::GetDefaultDevice();
1976 
1977         // initialize test-tool library (if available)
1978         RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ tools::InitTestToolLib" );
1979         tools::InitTestToolLib();
1980         RTL_LOGFILE_CONTEXT_TRACE( aLog, "} tools::InitTestToolLib" );
1981 
1982         // Check if bundled or shared extensions were added /removed
1983         // and process those extensions (has to be done before checking
1984         // the extension dependencies!
1985         SynchronizeExtensionRepositories();
1986         bool bAbort = CheckExtensionDependencies();
1987         if ( bAbort )
1988             return;
1989 
1990         {
1991             ::comphelper::ComponentContext aContext( xSMgr );
1992             xRestartManager.set( aContext.getSingleton( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) ) ), UNO_QUERY );
1993         }
1994 
1995 		// check whether the shutdown is caused by restart
1996 		pExecGlobals->bRestartRequested = ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) );
1997 
1998         // First Start Wizard allowed ?
1999         if ( ! pCmdLineArgs->IsNoFirstStartWizard() && !pExecGlobals->bRestartRequested )
2000         {
2001             RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ FirstStartWizard" );
2002 
2003             if (IsFirstStartWizardNeeded())
2004             {
2005                 Reference< XJob > xFirstStartJob( xSMgr->createInstance(
2006                     DEFINE_CONST_UNICODE( "com.sun.star.comp.desktop.FirstStart" ) ), UNO_QUERY );
2007                 if (xFirstStartJob.is())
2008                 {
2009                    // mark first start as done
2010                    FinishFirstStart();
2011                 }
2012             }
2013 
2014             RTL_LOGFILE_CONTEXT_TRACE( aLog, "} FirstStartWizard" );
2015         }
2016 
2017         // process non-pre-registered extensions
2018         installBundledExtensionBlobs();
2019 
2020 		// keep a language options instance...
2021 		pExecGlobals->pLanguageOptions.reset( new SvtLanguageOptions(sal_True));
2022 
2023         if (pExecGlobals->xGlobalBroadcaster.is())
2024         {
2025             css::document::EventObject aEvent;
2026             aEvent.EventName = ::rtl::OUString::createFromAscii("OnStartApp");
2027             pExecGlobals->xGlobalBroadcaster->notifyEvent(aEvent);
2028         }
2029 
2030         SetSplashScreenProgress(50);
2031 
2032         // Backing Component
2033         sal_Bool bCrashed            = sal_False;
2034         sal_Bool bExistsRecoveryData = sal_False;
2035         sal_Bool bExistsSessionData  = sal_False;
2036 
2037         RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ impl_checkRecoveryState" );
2038         impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
2039         RTL_LOGFILE_CONTEXT_TRACE( aLog, "} impl_checkRecoveryState" );
2040 
2041         {
2042             ::comphelper::ComponentContext aContext( xSMgr );
2043             xRestartManager.set( aContext.getSingleton( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) ) ), UNO_QUERY );
2044         }
2045 
2046         // check whether the shutdown is caused by restart
2047         pExecGlobals->bRestartRequested = ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) );
2048 
2049         if ( pCmdLineArgs->IsHeadless() )
2050         {
2051             // Ensure that we use not the system file dialogs as
2052             // headless mode relies on Application::EnableHeadlessMode()
2053             // which does only work for VCL dialogs!!
2054             SvtMiscOptions aMiscOptions;
2055             pExecGlobals->bUseSystemFileDialog = aMiscOptions.UseSystemFileDialog();
2056             aMiscOptions.SetUseSystemFileDialog( sal_False );
2057         }
2058 
2059         if ( !pExecGlobals->bRestartRequested )
2060         {
2061             if ((!pCmdLineArgs->WantsToLoadDocument() && !pCmdLineArgs->IsInvisible() && !pCmdLineArgs->IsHeadless() && !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