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