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