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 // Check if bundled or shared extensions were added /removed 1842 // and process those extensions (has to be done before checking 1843 // the extension dependencies! 1844 SynchronizeExtensionRepositories(); 1845 bool bAbort = CheckExtensionDependencies(); 1846 if ( bAbort ) 1847 return; 1848 1849 { 1850 ::comphelper::ComponentContext aContext( xSMgr ); 1851 xRestartManager.set( aContext.getSingleton( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) ) ), UNO_QUERY ); 1852 } 1853 1854 // check whether the shutdown is caused by restart 1855 pExecGlobals->bRestartRequested = ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) ); 1856 1857 // First Start Wizard allowed ? 1858 if ( ! pCmdLineArgs->IsNoFirstStartWizard() && !pExecGlobals->bRestartRequested ) 1859 { 1860 RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ FirstStartWizard" ); 1861 1862 if (IsFirstStartWizardNeeded()) 1863 { 1864 Reference< XJob > xFirstStartJob( xSMgr->createInstance( 1865 DEFINE_CONST_UNICODE( "com.sun.star.comp.desktop.FirstStart" ) ), UNO_QUERY ); 1866 if (xFirstStartJob.is()) 1867 { 1868 #if 0 // license acceptance is not needed for ASL 1869 sal_Bool bDone = sal_False; 1870 Sequence< NamedValue > lArgs(2); 1871 lArgs[0].Name = ::rtl::OUString::createFromAscii("LicenseNeedsAcceptance"); 1872 lArgs[0].Value <<= LicenseNeedsAcceptance(); 1873 lArgs[1].Name = ::rtl::OUString::createFromAscii("LicensePath"); 1874 lArgs[1].Value <<= GetLicensePath(); 1875 1876 xFirstStartJob->execute(lArgs) >>= bDone; 1877 if ( !bDone ) 1878 { 1879 return; 1880 } 1881 #endif // license acceptance is not needed for ASL 1882 1883 // process non-pre-registered extensions 1884 installBundledExtensionBlobs(); 1885 1886 // mark first start as done 1887 FinishFirstStart(); 1888 } 1889 } 1890 1891 RTL_LOGFILE_CONTEXT_TRACE( aLog, "} FirstStartWizard" ); 1892 } 1893 1894 // keep a language options instance... 1895 pExecGlobals->pLanguageOptions.reset( new SvtLanguageOptions(sal_True)); 1896 1897 if (pExecGlobals->xGlobalBroadcaster.is()) 1898 { 1899 css::document::EventObject aEvent; 1900 aEvent.EventName = ::rtl::OUString::createFromAscii("OnStartApp"); 1901 pExecGlobals->xGlobalBroadcaster->notifyEvent(aEvent); 1902 } 1903 1904 SetSplashScreenProgress(50); 1905 1906 // Backing Component 1907 sal_Bool bCrashed = sal_False; 1908 sal_Bool bExistsRecoveryData = sal_False; 1909 sal_Bool bExistsSessionData = sal_False; 1910 1911 RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ impl_checkRecoveryState" ); 1912 impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData); 1913 RTL_LOGFILE_CONTEXT_TRACE( aLog, "} impl_checkRecoveryState" ); 1914 1915 { 1916 ::comphelper::ComponentContext aContext( xSMgr ); 1917 xRestartManager.set( aContext.getSingleton( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) ) ), UNO_QUERY ); 1918 } 1919 1920 // check whether the shutdown is caused by restart 1921 pExecGlobals->bRestartRequested = ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) ); 1922 1923 if ( pCmdLineArgs->IsHeadless() ) 1924 { 1925 // Ensure that we use not the system file dialogs as 1926 // headless mode relies on Application::EnableHeadlessMode() 1927 // which does only work for VCL dialogs!! 1928 SvtMiscOptions aMiscOptions; 1929 pExecGlobals->bUseSystemFileDialog = aMiscOptions.UseSystemFileDialog(); 1930 aMiscOptions.SetUseSystemFileDialog( sal_False ); 1931 } 1932 1933 if ( !pExecGlobals->bRestartRequested ) 1934 { 1935 if ((!pCmdLineArgs->WantsToLoadDocument() && !pCmdLineArgs->IsInvisible() && !pCmdLineArgs->IsHeadless() ) && 1936 (SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE)) && 1937 (!bExistsRecoveryData ) && 1938 (!bExistsSessionData ) && 1939 (!Application::AnyInput( INPUT_APPEVENT ) )) 1940 { 1941 RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ create BackingComponent" ); 1942 Reference< XFrame > xDesktopFrame( xSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY ); 1943 if (xDesktopFrame.is()) 1944 { 1945 Reference< XFrame > xBackingFrame; 1946 Reference< ::com::sun::star::awt::XWindow > xContainerWindow; 1947 1948 xBackingFrame = xDesktopFrame->findFrame(OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" )), 0); 1949 if (xBackingFrame.is()) 1950 xContainerWindow = xBackingFrame->getContainerWindow(); 1951 if (xContainerWindow.is()) 1952 { 1953 // set the WB_EXT_DOCUMENT style. Normally, this is done by the TaskCreator service when a "_blank" 1954 // frame/window is created. Since we do not use the TaskCreator here, we need to mimic its behavior, 1955 // otherwise documents loaded into this frame will later on miss functionality depending on the style. 1956 Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); 1957 OSL_ENSURE( pContainerWindow, "Desktop::Main: no implementation access to the frame's container window!" ); 1958 pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WB_EXT_DOCUMENT ); 1959 1960 SetSplashScreenProgress(75); 1961 Sequence< Any > lArgs(1); 1962 lArgs[0] <<= xContainerWindow; 1963 1964 Reference< XController > xBackingComp( 1965 xSMgr->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule") ), lArgs), UNO_QUERY); 1966 if (xBackingComp.is()) 1967 { 1968 Reference< ::com::sun::star::awt::XWindow > xBackingWin(xBackingComp, UNO_QUERY); 1969 // Attention: You MUST(!) call setComponent() before you call attachFrame(). 1970 // Because the backing component set the property "IsBackingMode" of the frame 1971 // to true inside attachFrame(). But setComponent() reset this state everytimes ... 1972 xBackingFrame->setComponent(xBackingWin, xBackingComp); 1973 SetSplashScreenProgress(100); 1974 xBackingComp->attachFrame(xBackingFrame); 1975 CloseSplashScreen(); 1976 xContainerWindow->setVisible(sal_True); 1977 } 1978 } 1979 } 1980 RTL_LOGFILE_CONTEXT_TRACE( aLog, "} create BackingComponent" ); 1981 } 1982 } 1983 } 1984 catch ( com::sun::star::lang::WrappedTargetException& wte ) 1985 { 1986 com::sun::star::uno::Exception te; 1987 wte.TargetException >>= te; 1988 FatalError( MakeStartupConfigAccessErrorMessage(wte.Message + te.Message) ); 1989 return; 1990 } 1991 catch ( com::sun::star::uno::Exception& e ) 1992 { 1993 FatalError( MakeStartupErrorMessage(e.Message) ); 1994 return; 1995 } 1996 1997 SvtFontSubstConfig().Apply(); 1998 1999 SvtTabAppearanceCfg aAppearanceCfg; 2000 aAppearanceCfg.SetInitialized(); 2001 aAppearanceCfg.SetApplicationDefaults( this ); 2002 SvtAccessibilityOptions aOptions; 2003 aOptions.SetVCLSettings(); 2004 2005 if ( !pExecGlobals->bRestartRequested ) 2006 { 2007 Application::SetFilterHdl( LINK( this, Desktop, ImplInitFilterHdl ) ); 2008 sal_Bool bTerminateRequested = sal_False; 2009 2010 // Preload function depends on an initialized sfx application! 2011 SetSplashScreenProgress(75); 2012 2013 // use system window dialogs 2014 Application::SetSystemWindowMode( SYSTEMWINDOW_MODE_DIALOG ); 2015 2016 // SetSplashScreenProgress(80); 2017 2018 if ( !bTerminateRequested && !pCmdLineArgs->IsInvisible() && 2019 !pCmdLineArgs->IsNoQuickstart() ) 2020 InitializeQuickstartMode( xSMgr ); 2021 2022 RTL_LOGFILE_CONTEXT( aLog2, "desktop (cd100003) createInstance com.sun.star.frame.Desktop" ); 2023 try 2024 { 2025 Reference< XDesktop > xDesktop( xSMgr->createInstance( 2026 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY ); 2027 if ( xDesktop.is() ) 2028 xDesktop->addTerminateListener( new OfficeIPCThreadController ); 2029 SetSplashScreenProgress(100); 2030 } 2031 catch ( com::sun::star::uno::Exception& e ) 2032 { 2033 FatalError( MakeStartupErrorMessage(e.Message) ); 2034 return; 2035 } 2036 2037 // Post user event to startup first application component window 2038 // We have to send this OpenClients message short before execute() to 2039 // minimize the risk that this message overtakes type detection contruction!! 2040 Application::PostUserEvent( LINK( this, Desktop, OpenClients_Impl ) ); 2041 2042 // Post event to enable acceptors 2043 Application::PostUserEvent( LINK( this, Desktop, EnableAcceptors_Impl) ); 2044 2045 // The configuration error handler currently is only for startup 2046 aConfigErrHandler.deactivate(); 2047 2048 // Acquire solar mutex just before we enter our message loop 2049 if ( nAcquireCount ) 2050 Application::AcquireSolarMutex( nAcquireCount ); 2051 2052 // call Application::Execute to process messages in vcl message loop 2053 RTL_LOGFILE_PRODUCT_TRACE( "PERFORMANCE - enter Application::Execute()" ); 2054 2055 try 2056 { 2057 // The JavaContext contains an interaction handler which is used when 2058 // the creation of a Java Virtual Machine fails 2059 com::sun::star::uno::ContextLayer layer2( 2060 new svt::JavaContext( com::sun::star::uno::getCurrentContext() ) ); 2061 2062 // check whether the shutdown is caused by restart just before entering the Execute 2063 pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested || ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) ); 2064 2065 if ( !pExecGlobals->bRestartRequested ) 2066 { 2067 // if this run of the office is triggered by restart, some additional actions should be done 2068 DoRestartActionsIfNecessary( !pCmdLineArgs->IsInvisible() && !pCmdLineArgs->IsNoQuickstart() ); 2069 2070 Execute(); 2071 } 2072 } 2073 catch(const com::sun::star::document::CorruptedFilterConfigurationException& exFilterCfg) 2074 { 2075 OfficeIPCThread::SetDowning(); 2076 FatalError( MakeStartupErrorMessage(exFilterCfg.Message) ); 2077 } 2078 catch(const com::sun::star::configuration::CorruptedConfigurationException& exAnyCfg) 2079 { 2080 OfficeIPCThread::SetDowning(); 2081 FatalError( MakeStartupErrorMessage(exAnyCfg.Message) ); 2082 } 2083 } 2084 // CAUTION: you do not necessarily get here e.g. on the Mac. 2085 // please put all deinitialization code into doShutdown 2086 doShutdown(); 2087 } 2088 2089 void Desktop::doShutdown() 2090 { 2091 if( ! pExecGlobals ) 2092 return; 2093 2094 if ( pExecGlobals->bRestartRequested ) 2095 SetRestartState(); 2096 2097 if (pExecGlobals->xGlobalBroadcaster.is()) 2098 { 2099 css::document::EventObject aEvent; 2100 aEvent.EventName = ::rtl::OUString::createFromAscii("OnCloseApp"); 2101 pExecGlobals->xGlobalBroadcaster->notifyEvent(aEvent); 2102 } 2103 2104 delete pResMgr, pResMgr = NULL; 2105 // Restore old value 2106 CommandLineArgs* pCmdLineArgs = GetCommandLineArgs(); 2107 if ( pCmdLineArgs->IsHeadless() ) 2108 SvtMiscOptions().SetUseSystemFileDialog( pExecGlobals->bUseSystemFileDialog ); 2109 2110 // remove temp directory 2111 RemoveTemporaryDirectory(); 2112 FlushConfiguration(); 2113 // The acceptors in the AcceptorMap must be released (in DeregisterServices) 2114 // with the solar mutex unlocked, to avoid deadlock: 2115 sal_uLong nAcquireCount = Application::ReleaseSolarMutex(); 2116 DeregisterServices(); 2117 Application::AcquireSolarMutex(nAcquireCount); 2118 tools::DeInitTestToolLib(); 2119 // be sure that path/language options gets destroyed before 2120 // UCB is deinitialized 2121 RTL_LOGFILE_CONTEXT_TRACE( aLog, "-> dispose path/language options" ); 2122 pExecGlobals->pLanguageOptions.reset( 0 ); 2123 pExecGlobals->pPathOptions.reset( 0 ); 2124 RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- dispose path/language options" ); 2125 2126 RTL_LOGFILE_CONTEXT_TRACE( aLog, "-> deinit ucb" ); 2127 ::ucbhelper::ContentBroker::deinitialize(); 2128 RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- deinit ucb" ); 2129 2130 sal_Bool bRR = pExecGlobals->bRestartRequested; 2131 delete pExecGlobals, pExecGlobals = NULL; 2132 2133 RTL_LOGFILE_CONTEXT_TRACE( aLog, "FINISHED WITH Destop::Main" ); 2134 if ( bRR ) 2135 { 2136 restartOnMac(true); 2137 // wouldn't the solution be more clean if SalMain returns the exit code to the system? 2138 _exit( ExitHelper::E_NORMAL_RESTART ); 2139 } 2140 } 2141 2142 IMPL_LINK( Desktop, ImplInitFilterHdl, ConvertData*, pData ) 2143 { 2144 return GraphicFilter::GetGraphicFilter()->GetFilterCallback().Call( pData ); 2145 } 2146 2147 sal_Bool Desktop::InitializeConfiguration() 2148 { 2149 sal_Bool bOk = sal_False; 2150 2151 try 2152 { 2153 bOk = InitConfiguration(); 2154 } 2155 catch( ::com::sun::star::lang::ServiceNotRegisteredException& ) 2156 { 2157 this->HandleBootstrapErrors( Desktop::BE_UNO_SERVICE_CONFIG_MISSING ); 2158 } 2159 catch( ::com::sun::star::configuration::MissingBootstrapFileException& e ) 2160 { 2161 OUString aMsg( CreateErrorMsgString( utl::Bootstrap::MISSING_BOOTSTRAP_FILE, 2162 e.BootstrapFileURL )); 2163 HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_USER_INSTALL, aMsg ); 2164 } 2165 catch( ::com::sun::star::configuration::InvalidBootstrapFileException& e ) 2166 { 2167 OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY, 2168 e.BootstrapFileURL )); 2169 HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg ); 2170 } 2171 catch( ::com::sun::star::configuration::InstallationIncompleteException& ) 2172 { 2173 OUString aVersionFileURL; 2174 OUString aMsg; 2175 utl::Bootstrap::PathStatus aPathStatus = utl::Bootstrap::locateVersionFile( aVersionFileURL ); 2176 if ( aPathStatus == utl::Bootstrap::PATH_EXISTS ) 2177 aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE_ENTRY, aVersionFileURL ); 2178 else 2179 aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE, aVersionFileURL ); 2180 2181 HandleBootstrapPathErrors( ::utl::Bootstrap::MISSING_USER_INSTALL, aMsg ); 2182 } 2183 catch ( com::sun::star::configuration::backend::BackendAccessException& exception) 2184 { 2185 // [cm122549] It is assumed in this case that the message 2186 // coming from InitConfiguration (in fact CreateApplicationConf...) 2187 // is suitable for display directly. 2188 FatalError( MakeStartupErrorMessage( exception.Message ) ); 2189 } 2190 catch ( com::sun::star::configuration::backend::BackendSetupException& exception) 2191 { 2192 // [cm122549] It is assumed in this case that the message 2193 // coming from InitConfiguration (in fact CreateApplicationConf...) 2194 // is suitable for display directly. 2195 FatalError( MakeStartupErrorMessage( exception.Message ) ); 2196 } 2197 catch ( ::com::sun::star::configuration::CannotLoadConfigurationException& ) 2198 { 2199 OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA, 2200 OUString() )); 2201 HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg ); 2202 } 2203 catch( ::com::sun::star::uno::Exception& ) 2204 { 2205 OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA, 2206 OUString() )); 2207 HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg ); 2208 } 2209 2210 return bOk; 2211 } 2212 2213 void Desktop::FlushConfiguration() 2214 { 2215 Reference < XFlushable > xCFGFlush( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY ); 2216 if (xCFGFlush.is()) 2217 { 2218 xCFGFlush->flush(); 2219 } 2220 else 2221 { 2222 // because there is no method to flush the condiguration data, we must dispose the ConfigManager 2223 Reference < XComponent > xCFGDispose( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY ); 2224 if (xCFGDispose.is()) 2225 xCFGDispose->dispose(); 2226 } 2227 } 2228 2229 sal_Bool Desktop::InitializeQuickstartMode( Reference< XMultiServiceFactory >& rSMgr ) 2230 { 2231 try 2232 { 2233 // the shutdown icon sits in the systray and allows the user to keep 2234 // the office instance running for quicker restart 2235 // this will only be activated if -quickstart was specified on cmdline 2236 RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) createInstance com.sun.star.office.Quickstart" ); 2237 2238 sal_Bool bQuickstart = GetCommandLineArgs()->IsQuickstart(); 2239 if ( !bQuickstart ) 2240 { 2241 SfxItemSet aOptSet( SFX_APP()->GetPool(), SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER ); 2242 SFX_APP()->GetOptions(aOptSet); 2243 const SfxPoolItem* pItem; 2244 if ( SFX_ITEM_SET == aOptSet.GetItemState( SID_ATTR_QUICKLAUNCHER, sal_False, &pItem ) ) 2245 bQuickstart = ((const SfxBoolItem*)pItem)->GetValue(); 2246 } 2247 2248 Sequence< Any > aSeq( 1 ); 2249 aSeq[0] <<= bQuickstart; 2250 2251 // Try to instanciate quickstart service. This service is not mandatory, so 2252 // do nothing if service is not available 2253 2254 // #i105753# the following if was invented for performance 2255 // unfortunately this broke the QUARTZ behavior which is to always run 2256 // in quickstart mode since Mac applications do not usually quit 2257 // when the last document closes 2258 #ifndef QUARTZ 2259 if ( bQuickstart ) 2260 #endif 2261 { 2262 Reference < XComponent > xQuickstart( rSMgr->createInstanceWithArguments( 2263 DEFINE_CONST_UNICODE( "com.sun.star.office.Quickstart" ), aSeq ), 2264 UNO_QUERY ); 2265 } 2266 return sal_True; 2267 } 2268 catch( ::com::sun::star::uno::Exception& ) 2269 { 2270 return sal_False; 2271 } 2272 } 2273 2274 void Desktop::SystemSettingsChanging( AllSettings& rSettings, Window* ) 2275 { 2276 if ( !SvtTabAppearanceCfg::IsInitialized () ) 2277 return; 2278 2279 # define DRAGFULL_OPTION_ALL \ 2280 ( DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE \ 2281 | DRAGFULL_OPTION_OBJECTMOVE | DRAGFULL_OPTION_OBJECTSIZE \ 2282 | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT \ 2283 | DRAGFULL_OPTION_SCROLL ) 2284 # define DRAGFULL_OPTION_NONE ((sal_uInt32)~DRAGFULL_OPTION_ALL) 2285 2286 StyleSettings hStyleSettings = rSettings.GetStyleSettings(); 2287 MouseSettings hMouseSettings = rSettings.GetMouseSettings(); 2288 2289 sal_uInt32 nDragFullOptions = hStyleSettings.GetDragFullOptions(); 2290 2291 SvtTabAppearanceCfg aAppearanceCfg; 2292 sal_uInt16 nGet = aAppearanceCfg.GetDragMode(); 2293 switch ( nGet ) 2294 { 2295 case DragFullWindow: 2296 nDragFullOptions |= DRAGFULL_OPTION_ALL; 2297 break; 2298 case DragFrame: 2299 nDragFullOptions &= DRAGFULL_OPTION_NONE; 2300 break; 2301 case DragSystemDep: 2302 default: 2303 break; 2304 } 2305 2306 sal_uInt32 nFollow = hMouseSettings.GetFollow(); 2307 hMouseSettings.SetFollow( aAppearanceCfg.IsMenuMouseFollow() ? (nFollow|MOUSE_FOLLOW_MENU) : (nFollow&~MOUSE_FOLLOW_MENU)); 2308 rSettings.SetMouseSettings(hMouseSettings); 2309 2310 sal_Bool bUseImagesInMenus = hStyleSettings.GetUseImagesInMenus(); 2311 2312 SvtMenuOptions aMenuOpt; 2313 nGet = aMenuOpt.GetMenuIconsState(); 2314 switch ( nGet ) 2315 { 2316 case 0: 2317 bUseImagesInMenus = sal_False; 2318 break; 2319 case 1: 2320 bUseImagesInMenus = sal_True; 2321 break; 2322 case 2: 2323 default: 2324 break; 2325 } 2326 hStyleSettings.SetUseImagesInMenus(bUseImagesInMenus); 2327 2328 hStyleSettings.SetDragFullOptions( nDragFullOptions ); 2329 rSettings.SetStyleSettings ( hStyleSettings ); 2330 } 2331 2332 // ======================================================================== 2333 IMPL_LINK( Desktop, AsyncInitFirstRun, void*, EMPTYARG ) 2334 { 2335 DoFirstRunInitializations(); 2336 return 0L; 2337 } 2338 2339 // ======================================================================== 2340 2341 class ExitTimer : public Timer 2342 { 2343 public: 2344 ExitTimer() 2345 { 2346 SetTimeout(500); 2347 Start(); 2348 } 2349 virtual void Timeout() 2350 { 2351 exit(42); 2352 } 2353 }; 2354 2355 IMPL_LINK( Desktop, OpenClients_Impl, void*, EMPTYARG ) 2356 { 2357 RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "PERFORMANCE - DesktopOpenClients_Impl()" ); 2358 2359 OpenClients(); 2360 2361 OfficeIPCThread::SetReady(); 2362 2363 // CloseStartupScreen(); 2364 CloseSplashScreen(); 2365 CheckFirstRun( ); 2366 EnableOleAutomation(); 2367 2368 if (getenv ("OOO_EXIT_POST_STARTUP")) 2369 new ExitTimer(); 2370 return 0; 2371 } 2372 2373 // enable acceptos 2374 IMPL_LINK( Desktop, EnableAcceptors_Impl, void*, EMPTYARG ) 2375 { 2376 enableAcceptors(); 2377 return 0; 2378 } 2379 2380 2381 // Registers a COM class factory of the service manager with the windows operating system. 2382 void Desktop::EnableOleAutomation() 2383 { 2384 RTL_LOGFILE_CONTEXT( aLog, "desktop (jl97489) ::Desktop::EnableOleAutomation" ); 2385 #ifdef WNT 2386 Reference< XMultiServiceFactory > xSMgr= comphelper::getProcessServiceFactory(); 2387 xSMgr->createInstance(DEFINE_CONST_UNICODE("com.sun.star.bridge.OleApplicationRegistration")); 2388 xSMgr->createInstance(DEFINE_CONST_UNICODE("com.sun.star.comp.ole.EmbedServer")); 2389 #endif 2390 } 2391 2392 sal_Bool Desktop::CheckOEM() 2393 { 2394 Reference<XMultiServiceFactory> rFactory = ::comphelper::getProcessServiceFactory(); 2395 Reference<XJob> rOemJob(rFactory->createInstance( 2396 OUString::createFromAscii("com.sun.star.office.OEMPreloadJob")), 2397 UNO_QUERY ); 2398 Sequence<NamedValue> args; 2399 sal_Bool bResult = sal_False; 2400 if (rOemJob.is()) { 2401 Any aResult = rOemJob->execute(args); 2402 aResult >>= bResult; 2403 return bResult; 2404 } else { 2405 return sal_True; 2406 } 2407 } 2408 2409 void Desktop::PreloadModuleData( CommandLineArgs* pArgs ) 2410 { 2411 Reference< XMultiServiceFactory > rFactory = ::comphelper::getProcessServiceFactory(); 2412 2413 Sequence < com::sun::star::beans::PropertyValue > args(1); 2414 args[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Hidden")); 2415 args[0].Value <<= sal_True; 2416 Reference < XComponentLoader > xLoader( ::comphelper::getProcessServiceFactory()->createInstance( 2417 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ), UNO_QUERY ); 2418 2419 if ( !xLoader.is() ) 2420 return; 2421 2422 if ( pArgs->IsWriter() ) 2423 { 2424 try 2425 { 2426 Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/swriter"), 2427 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW ); 2428 xDoc->close( sal_False ); 2429 } 2430 catch ( com::sun::star::uno::Exception& ) 2431 { 2432 } 2433 } 2434 if ( pArgs->IsCalc() ) 2435 { 2436 try 2437 { 2438 Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/scalc"), 2439 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW ); 2440 xDoc->close( sal_False ); 2441 } 2442 catch ( com::sun::star::uno::Exception& ) 2443 { 2444 } 2445 } 2446 if ( pArgs->IsDraw() ) 2447 { 2448 try 2449 { 2450 Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/sdraw"), 2451 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW ); 2452 xDoc->close( sal_False ); 2453 } 2454 catch ( com::sun::star::uno::Exception& ) 2455 { 2456 } 2457 } 2458 if ( pArgs->IsImpress() ) 2459 { 2460 try 2461 { 2462 Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/simpress"), 2463 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW ); 2464 xDoc->close( sal_False ); 2465 } 2466 catch ( com::sun::star::uno::Exception& ) 2467 { 2468 } 2469 } 2470 } 2471 2472 void Desktop::PreloadConfigurationData() 2473 { 2474 Reference< XMultiServiceFactory > rFactory = ::comphelper::getProcessServiceFactory(); 2475 Reference< XNameAccess > xNameAccess( rFactory->createInstance( 2476 DEFINE_CONST_UNICODE( "com.sun.star.frame.UICommandDescription" )), UNO_QUERY ); 2477 2478 rtl::OUString aWriterDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" )); 2479 rtl::OUString aCalcDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocument" )); 2480 rtl::OUString aDrawDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" )); 2481 rtl::OUString aImpressDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" )); 2482 2483 // preload commands configuration 2484 if ( xNameAccess.is() ) 2485 { 2486 Any a; 2487 Reference< XNameAccess > xCmdAccess; 2488 2489 try 2490 { 2491 a = xNameAccess->getByName( aWriterDoc ); 2492 a >>= xCmdAccess; 2493 if ( xCmdAccess.is() ) 2494 { 2495 xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:BasicShapes" )); 2496 xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:EditGlossary" )); 2497 } 2498 } 2499 catch ( ::com::sun::star::uno::Exception& ) 2500 { 2501 } 2502 2503 try 2504 { 2505 a = xNameAccess->getByName( aCalcDoc ); 2506 a >>= xCmdAccess; 2507 if ( xCmdAccess.is() ) 2508 xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:InsertObjectStarMath" )); 2509 } 2510 catch ( ::com::sun::star::uno::Exception& ) 2511 { 2512 } 2513 2514 try 2515 { 2516 // draw and impress share the same configuration file (DrawImpressCommands.xcu) 2517 a = xNameAccess->getByName( aDrawDoc ); 2518 a >>= xCmdAccess; 2519 if ( xCmdAccess.is() ) 2520 xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:Polygon" )); 2521 } 2522 catch ( ::com::sun::star::uno::Exception& ) 2523 { 2524 } 2525 } 2526 2527 // preload window state configuration 2528 xNameAccess = Reference< XNameAccess >( rFactory->createInstance( 2529 DEFINE_CONST_UNICODE( "com.sun.star.ui.WindowStateConfiguration" )), UNO_QUERY ); 2530 if ( xNameAccess.is() ) 2531 { 2532 Any a; 2533 Reference< XNameAccess > xWindowAccess; 2534 try 2535 { 2536 a = xNameAccess->getByName( aWriterDoc ); 2537 a >>= xWindowAccess; 2538 if ( xWindowAccess.is() ) 2539 xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" )); 2540 } 2541 catch ( ::com::sun::star::uno::Exception& ) 2542 { 2543 } 2544 try 2545 { 2546 a = xNameAccess->getByName( aCalcDoc ); 2547 a >>= xWindowAccess; 2548 if ( xWindowAccess.is() ) 2549 xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" )); 2550 } 2551 catch ( ::com::sun::star::uno::Exception& ) 2552 { 2553 } 2554 try 2555 { 2556 a = xNameAccess->getByName( aDrawDoc ); 2557 a >>= xWindowAccess; 2558 if ( xWindowAccess.is() ) 2559 xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" )); 2560 } 2561 catch ( ::com::sun::star::uno::Exception& ) 2562 { 2563 } 2564 try 2565 { 2566 a = xNameAccess->getByName( aImpressDoc ); 2567 a >>= xWindowAccess; 2568 if ( xWindowAccess.is() ) 2569 xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" )); 2570 } 2571 catch ( ::com::sun::star::uno::Exception& ) 2572 { 2573 } 2574 } 2575 2576 // preload user interface element factories 2577 Sequence< Sequence< css::beans::PropertyValue > > aSeqSeqPropValue; 2578 Reference< ::com::sun::star::ui::XUIElementFactoryRegistration > xUIElementFactory( 2579 rFactory->createInstance( 2580 DEFINE_CONST_UNICODE( "com.sun.star.ui.UIElementFactoryManager" )), 2581 UNO_QUERY ); 2582 if ( xUIElementFactory.is() ) 2583 { 2584 try 2585 { 2586 aSeqSeqPropValue = xUIElementFactory->getRegisteredFactories(); 2587 } 2588 catch ( ::com::sun::star::uno::Exception& ) 2589 { 2590 } 2591 } 2592 2593 // preload popup menu controller factories. As all controllers are in the same 2594 // configuration file they also get preloaded! 2595 Reference< ::com::sun::star::frame::XUIControllerRegistration > xPopupMenuControllerFactory( 2596 rFactory->createInstance( 2597 DEFINE_CONST_UNICODE( "com.sun.star.frame.PopupMenuControllerFactory" )), 2598 UNO_QUERY ); 2599 if ( xPopupMenuControllerFactory.is() ) 2600 { 2601 try 2602 { 2603 xPopupMenuControllerFactory->hasController( 2604 DEFINE_CONST_UNICODE( ".uno:CharFontName" ), 2605 OUString() ); 2606 } 2607 catch ( ::com::sun::star::uno::Exception& ) 2608 { 2609 } 2610 } 2611 2612 // preload filter configuration 2613 Sequence< OUString > aSeq; 2614 xNameAccess = Reference< XNameAccess >( rFactory->createInstance( 2615 DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" )), UNO_QUERY ); 2616 if ( xNameAccess.is() ) 2617 { 2618 try 2619 { 2620 aSeq = xNameAccess->getElementNames(); 2621 } 2622 catch ( ::com::sun::star::uno::Exception& ) 2623 { 2624 } 2625 } 2626 2627 // preload type detection configuration 2628 xNameAccess = Reference< XNameAccess >( rFactory->createInstance( 2629 DEFINE_CONST_UNICODE( "com.sun.star.document.TypeDetection" )), UNO_QUERY ); 2630 if ( xNameAccess.is() ) 2631 { 2632 try 2633 { 2634 aSeq = xNameAccess->getElementNames(); 2635 } 2636 catch ( ::com::sun::star::uno::Exception& ) 2637 { 2638 } 2639 } 2640 2641 static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) ); 2642 static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) ); 2643 2644 // get configuration provider 2645 Reference< XMultiServiceFactory > xConfigProvider; 2646 xConfigProvider = Reference< XMultiServiceFactory > ( 2647 rFactory->createInstance( sConfigSrvc ),UNO_QUERY ); 2648 2649 if ( xConfigProvider.is() ) 2650 { 2651 // preload writer configuration 2652 Sequence< Any > theArgs(1); 2653 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Writer/MailMergeWizard" ); 2654 try 2655 { 2656 xNameAccess = Reference< XNameAccess >( 2657 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY ); 2658 } 2659 catch (::com::sun::star::uno::Exception& ) 2660 { 2661 } 2662 2663 // WriterWeb 2664 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.WriterWeb/Content" ); 2665 try 2666 { 2667 xNameAccess = Reference< XNameAccess >( 2668 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY ); 2669 } 2670 catch (::com::sun::star::uno::Exception& ) 2671 { 2672 } 2673 2674 // preload compatibility 2675 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Compatibility/WriterCompatibilityVersion" ); 2676 try 2677 { 2678 xNameAccess = Reference< XNameAccess >( 2679 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY ); 2680 } 2681 catch (::com::sun::star::uno::Exception& ) 2682 { 2683 } 2684 2685 // preload calc configuration 2686 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Calc/Content" ); 2687 try 2688 { 2689 xNameAccess = Reference< XNameAccess >( 2690 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY ); 2691 } 2692 catch (::com::sun::star::uno::Exception& ) 2693 { 2694 } 2695 2696 // preload impress configuration 2697 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.UI.Effects/UserInterface" ); 2698 try 2699 { 2700 xNameAccess = Reference< XNameAccess >( 2701 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY ); 2702 } 2703 catch (::com::sun::star::uno::Exception& ) 2704 { 2705 } 2706 2707 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Impress/Layout" ); 2708 try 2709 { 2710 xNameAccess = Reference< XNameAccess >( 2711 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY ); 2712 } 2713 catch (::com::sun::star::uno::Exception& ) 2714 { 2715 } 2716 2717 // preload draw configuration 2718 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Draw/Layout" ); 2719 try 2720 { 2721 xNameAccess = Reference< XNameAccess >( 2722 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY ); 2723 } 2724 catch (::com::sun::star::uno::Exception& ) 2725 { 2726 } 2727 2728 // preload ui configuration 2729 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.UI/FilterClassification" ); 2730 try 2731 { 2732 xNameAccess = Reference< XNameAccess >( 2733 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY ); 2734 } 2735 catch (::com::sun::star::uno::Exception& ) 2736 { 2737 } 2738 2739 // preload addons configuration 2740 theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Addons/AddonUI" ); 2741 try 2742 { 2743 xNameAccess = Reference< XNameAccess >( 2744 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY ); 2745 } 2746 catch (::com::sun::star::uno::Exception& ) 2747 { 2748 } 2749 } 2750 } 2751 2752 void Desktop::OpenClients() 2753 { 2754 2755 // check if a document has been recovered - if there is one of if a document was loaded by cmdline, no default document 2756 // should be created 2757 Reference < XComponent > xFirst; 2758 sal_Bool bLoaded = sal_False; 2759 2760 CommandLineArgs* pArgs = GetCommandLineArgs(); 2761 SvtInternalOptions aInternalOptions; 2762 2763 Reference<XMultiServiceFactory> rFactory = ::comphelper::getProcessServiceFactory(); 2764 2765 if (!pArgs->IsQuickstart()) { 2766 sal_Bool bShowHelp = sal_False; 2767 ::rtl::OUStringBuffer aHelpURLBuffer; 2768 if (pArgs->IsHelpWriter()) { 2769 bShowHelp = sal_True; 2770 aHelpURLBuffer.appendAscii("vnd.sun.star.help://swriter/start"); 2771 } else if (pArgs->IsHelpCalc()) { 2772 bShowHelp = sal_True; 2773 aHelpURLBuffer.appendAscii("vnd.sun.star.help://scalc/start"); 2774 } else if (pArgs->IsHelpDraw()) { 2775 bShowHelp = sal_True; 2776 aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdraw/start"); 2777 } else if (pArgs->IsHelpImpress()) { 2778 bShowHelp = sal_True; 2779 aHelpURLBuffer.appendAscii("vnd.sun.star.help://simpress/start"); 2780 } else if (pArgs->IsHelpBase()) { 2781 bShowHelp = sal_True; 2782 aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdatabase/start"); 2783 } else if (pArgs->IsHelpBasic()) { 2784 bShowHelp = sal_True; 2785 aHelpURLBuffer.appendAscii("vnd.sun.star.help://sbasic/start"); 2786 } else if (pArgs->IsHelpMath()) { 2787 bShowHelp = sal_True; 2788 aHelpURLBuffer.appendAscii("vnd.sun.star.help://smath/start"); 2789 } 2790 if (bShowHelp) { 2791 Help *pHelp = Application::GetHelp(); 2792 2793 Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::LOCALE ); 2794 rtl::OUString aTmp; 2795 aRet >>= aTmp; 2796 aHelpURLBuffer.appendAscii("?Language="); 2797 aHelpURLBuffer.append(aTmp); 2798 #if defined UNX 2799 aHelpURLBuffer.appendAscii("&System=UNX"); 2800 #elif defined WNT 2801 aHelpURLBuffer.appendAscii("&System=WIN"); 2802 #elif defined OS2 2803 aHelpURLBuffer.appendAscii("&System=OS2"); 2804 #endif 2805 pHelp->Start(aHelpURLBuffer.makeStringAndClear(), NULL); 2806 return; 2807 } 2808 } 2809 else 2810 { 2811 OUString aIniName; 2812 ::vos::OStartupInfo aInfo; 2813 2814 aInfo.getExecutableFile( aIniName ); 2815 sal_uInt32 lastIndex = aIniName.lastIndexOf('/'); 2816 if ( lastIndex > 0 ) 2817 { 2818 aIniName = aIniName.copy( 0, lastIndex+1 ); 2819 aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "perftune" )); 2820 #if defined(WNT) || defined(OS2) 2821 aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( ".ini" )); 2822 #else 2823 aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "rc" )); 2824 #endif 2825 } 2826 2827 rtl::Bootstrap aPerfTuneIniFile( aIniName ); 2828 2829 OUString aDefault( RTL_CONSTASCII_USTRINGPARAM( "0" )); 2830 OUString aPreloadData; 2831 2832 aPerfTuneIniFile.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "QuickstartPreloadConfiguration" )), aPreloadData, aDefault ); 2833 if ( aPreloadData.equalsAscii( "1" )) 2834 { 2835 if ( pArgs->IsWriter() || 2836 pArgs->IsCalc() || 2837 pArgs->IsDraw() || 2838 pArgs->IsImpress() ) 2839 { 2840 PreloadModuleData( pArgs ); 2841 } 2842 2843 PreloadConfigurationData(); 2844 } 2845 } 2846 2847 // Disable AutoSave feature in case "-norestore" or a similare command line switch is set on the command line. 2848 // The reason behind: AutoSave/EmergencySave/AutoRecovery share the same data. 2849 // But the require that all documents, which are saved as backup should exists inside 2850 // memory. May be this mechanism will be inconsistent if the configuration exists ... 2851 // but no document inside memory corrspond to this data. 2852 // Furter it's not acceptable to recover such documents without any UI. It can 2853 // need some time, where the user wont see any results and wait for finishing the office startup ... 2854 sal_Bool bAllowRecoveryAndSessionManagement = ( 2855 ( !pArgs->IsNoRestore() ) && 2856 ( !pArgs->IsHeadless() ) && 2857 ( !pArgs->IsServer() ) 2858 ); 2859 2860 if ( ! bAllowRecoveryAndSessionManagement ) 2861 { 2862 try 2863 { 2864 Reference< XDispatch > xRecovery( 2865 ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.AutoRecovery")) ), 2866 ::com::sun::star::uno::UNO_QUERY_THROW ); 2867 2868 Reference< XURLTransformer > xParser( 2869 ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ), 2870 ::com::sun::star::uno::UNO_QUERY_THROW ); 2871 2872 css::util::URL aCmd; 2873 aCmd.Complete = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/disableRecovery"); 2874 xParser->parseStrict(aCmd); 2875 2876 xRecovery->dispatch(aCmd, css::uno::Sequence< css::beans::PropertyValue >()); 2877 } 2878 catch(const css::uno::Exception& e) 2879 { 2880 OUString aMessage = OUString::createFromAscii("Could not disable AutoRecovery.\n") 2881 + e.Message; 2882 OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr()); 2883 } 2884 } 2885 else 2886 { 2887 sal_Bool bCrashed = sal_False; 2888 sal_Bool bExistsRecoveryData = sal_False; 2889 sal_Bool bExistsSessionData = sal_False; 2890 2891 impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData); 2892 2893 if ( !getenv ("OOO_DISABLE_RECOVERY") && 2894 ( ! bLoaded ) && 2895 ( 2896 ( bExistsRecoveryData ) || // => crash with files => recovery 2897 ( bCrashed ) // => crash without files => error report 2898 ) 2899 ) 2900 { 2901 try 2902 { 2903 impl_callRecoveryUI( 2904 sal_False , // false => force recovery instead of emergency save 2905 bCrashed , 2906 bExistsRecoveryData); 2907 /* TODO we cant be shure, that at least one document could be recovered here successfully 2908 So we set bLoaded=sal_True to supress opening of the default document. 2909 But we should make it more safe. Otherwhise we have an office without an UI ... 2910 ... 2911 May be we can check the desktop if some documents are existing there. 2912 */ 2913 Reference< XFramesSupplier > xTasksSupplier( 2914 ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ), 2915 ::com::sun::star::uno::UNO_QUERY_THROW ); 2916 Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY_THROW ); 2917 if ( xList->hasElements() ) 2918 bLoaded = sal_True; 2919 } 2920 catch(const css::uno::Exception& e) 2921 { 2922 OUString aMessage = OUString::createFromAscii("Error during recovery\n") 2923 + e.Message; 2924 OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr()); 2925 } 2926 } 2927 2928 Reference< XInitialization > xSessionListener; 2929 try 2930 { 2931 xSessionListener = Reference< XInitialization >(::comphelper::getProcessServiceFactory()->createInstance( 2932 OUString::createFromAscii("com.sun.star.frame.SessionListener")), UNO_QUERY_THROW); 2933 2934 // specifies whether the UI-interaction on Session shutdown is allowed 2935 sal_Bool bAllowUI = isUIOnSessionShutdownAllowed(); 2936 css::beans::NamedValue aProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowUserInteractionOnQuit" ) ), 2937 css::uno::makeAny( bAllowUI ) ); 2938 css::uno::Sequence< css::uno::Any > aArgs( 1 ); 2939 aArgs[0] <<= aProperty; 2940 2941 xSessionListener->initialize( aArgs ); 2942 } 2943 catch(const com::sun::star::uno::Exception& e) 2944 { 2945 OUString aMessage = OUString::createFromAscii("Registration of session listener failed\n") 2946 + e.Message; 2947 OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr()); 2948 } 2949 2950 if ( 2951 ( ! bLoaded ) && 2952 ( bExistsSessionData ) 2953 ) 2954 { 2955 // session management 2956 try 2957 { 2958 Reference< XSessionManagerListener > r(xSessionListener, UNO_QUERY_THROW); 2959 bLoaded = r->doRestore(); 2960 } 2961 catch(const com::sun::star::uno::Exception& e) 2962 { 2963 OUString aMessage = OUString::createFromAscii("Error in session management\n") 2964 + e.Message; 2965 OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr()); 2966 } 2967 } 2968 } 2969 2970 OfficeIPCThread::EnableRequests(); 2971 2972 sal_Bool bShutdown( sal_False ); 2973 if ( !pArgs->IsServer() ) 2974 { 2975 ProcessDocumentsRequest aRequest(pArgs->getCwdUrl()); 2976 aRequest.pcProcessed = NULL; 2977 2978 pArgs->GetOpenList( aRequest.aOpenList ); 2979 pArgs->GetViewList( aRequest.aViewList ); 2980 pArgs->GetStartList( aRequest.aStartList ); 2981 pArgs->GetPrintList( aRequest.aPrintList ); 2982 pArgs->GetPrintToList( aRequest.aPrintToList ); 2983 pArgs->GetPrinterName( aRequest.aPrinterName ); 2984 pArgs->GetForceOpenList( aRequest.aForceOpenList ); 2985 pArgs->GetForceNewList( aRequest.aForceNewList ); 2986 2987 if ( aRequest.aOpenList.getLength() > 0 || 2988 aRequest.aViewList.getLength() > 0 || 2989 aRequest.aStartList.getLength() > 0 || 2990 aRequest.aPrintList.getLength() > 0 || 2991 aRequest.aForceOpenList.getLength() > 0 || 2992 aRequest.aForceNewList.getLength() > 0 || 2993 ( aRequest.aPrintToList.getLength() > 0 && aRequest.aPrinterName.getLength() > 0 )) 2994 { 2995 bLoaded = sal_True; 2996 2997 if ( pArgs->HasModuleParam() ) 2998 { 2999 SvtModuleOptions aOpt; 3000 3001 // Support command line parameters to start a module (as preselection) 3002 if ( pArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) ) 3003 aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::E_WRITER ); 3004 else if ( pArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) ) 3005 aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::E_CALC ); 3006 else if ( pArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) ) 3007 aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::E_IMPRESS ); 3008 else if ( pArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) ) 3009 aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::E_DRAW ); 3010 } 3011 3012 // check for printing disabled 3013 if( ( aRequest.aPrintList.getLength() || aRequest.aPrintToList.getLength() ) 3014 && Application::GetSettings().GetMiscSettings().GetDisablePrinting() ) 3015 { 3016 aRequest.aPrintList = rtl::OUString(); 3017 aRequest.aPrintToList = rtl::OUString(); 3018 ResMgr* pDtResMgr = GetDesktopResManager(); 3019 if( pDtResMgr ) 3020 { 3021 ErrorBox aBox( NULL, ResId( EBX_ERR_PRINTDISABLED, *pDtResMgr ) ); 3022 aBox.Execute(); 3023 } 3024 } 3025 3026 // Process request 3027 bShutdown = OfficeIPCThread::ExecuteCmdLineRequests( aRequest ); 3028 } 3029 } 3030 3031 // Don't do anything if we have successfully called terminate at desktop 3032 if ( bShutdown ) 3033 return; 3034 3035 // no default document if a document was loaded by recovery or by command line or if soffice is used as server 3036 Reference< XFramesSupplier > xTasksSupplier( 3037 ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ), 3038 ::com::sun::star::uno::UNO_QUERY_THROW ); 3039 Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY_THROW ); 3040 if ( xList->hasElements() || pArgs->IsServer() ) 3041 return; 3042 3043 if ( pArgs->IsQuickstart() || pArgs->IsInvisible() || pArgs->IsBean() || Application::AnyInput( INPUT_APPEVENT ) ) 3044 // soffice was started as tray icon ... 3045 return; 3046 { 3047 OpenDefault(); 3048 } 3049 } 3050 3051 void Desktop::OpenDefault() 3052 { 3053 3054 RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::OpenDefault" ); 3055 3056 ::rtl::OUString aName; 3057 SvtModuleOptions aOpt; 3058 3059 CommandLineArgs* pArgs = GetCommandLineArgs(); 3060 if ( pArgs->IsNoDefault() ) return; 3061 if ( pArgs->HasModuleParam() ) 3062 { 3063 // Support new command line parameters to start a module 3064 if ( pArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) ) 3065 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITER ); 3066 else if ( pArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) ) 3067 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_CALC ); 3068 else if ( pArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) ) 3069 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_IMPRESS ); 3070 else if ( pArgs->IsBase() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) ) 3071 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DATABASE ); 3072 else if ( pArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) ) 3073 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DRAW ); 3074 else if ( pArgs->IsMath() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) ) 3075 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_MATH ); 3076 else if ( pArgs->IsGlobal() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) ) 3077 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITERGLOBAL ); 3078 else if ( pArgs->IsWeb() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) ) 3079 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITERWEB ); 3080 } 3081 3082 if ( !aName.getLength() ) 3083 { 3084 // Old way to create a default document 3085 if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) ) 3086 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITER ); 3087 else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) ) 3088 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_CALC ); 3089 else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) ) 3090 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_IMPRESS ); 3091 else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) ) 3092 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DATABASE ); 3093 else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) ) 3094 aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DRAW ); 3095 else 3096 return; 3097 } 3098 3099 ProcessDocumentsRequest aRequest(pArgs->getCwdUrl()); 3100 aRequest.pcProcessed = NULL; 3101 aRequest.aOpenList = aName; 3102 OfficeIPCThread::ExecuteCmdLineRequests( aRequest ); 3103 } 3104 3105 3106 String GetURL_Impl( 3107 const String& rName, boost::optional< rtl::OUString > const & cwdUrl ) 3108 { 3109 // if rName is a vnd.sun.star.script URL do not attempt to parse it 3110 // as INetURLObj does not handle handle there URLs 3111 if (rName.CompareToAscii("vnd.sun.star.script" , 19) == COMPARE_EQUAL) 3112 { 3113 return rName; 3114 } 3115 3116 // dont touch file urls, those should already be in internal form 3117 // they won't get better here (#112849#) 3118 if (rName.CompareToAscii("file:" , 5) == COMPARE_EQUAL) 3119 { 3120 return rName; 3121 } 3122 3123 if ( rName.CompareToAscii("service:" , 8) == COMPARE_EQUAL ) 3124 { 3125 return rName; 3126 } 3127 3128 // Add path seperator to these directory and make given URL (rName) absolute by using of current working directory 3129 // Attention: "setFianlSlash()" is neccessary for calling "smartRel2Abs()"!!! 3130 // Otherwhise last part will be ignored and wrong result will be returned!!! 3131 // "smartRel2Abs()" interpret given URL as file not as path. So he truncate last element to get the base path ... 3132 // But if we add a seperator - he doesn't do it anymore. 3133 INetURLObject aObj; 3134 if (cwdUrl) { 3135 aObj.SetURL(*cwdUrl); 3136 aObj.setFinalSlash(); 3137 } 3138 3139 // Use the provided parameters for smartRel2Abs to support the usage of '%' in system paths. 3140 // Otherwise this char won't get encoded and we are not able to load such files later, 3141 // see #110156# 3142 bool bWasAbsolute; 3143 INetURLObject aURL = aObj.smartRel2Abs( rName, bWasAbsolute, false, INetURLObject::WAS_ENCODED, 3144 RTL_TEXTENCODING_UTF8, true ); 3145 String aFileURL = aURL.GetMainURL(INetURLObject::NO_DECODE); 3146 3147 ::osl::FileStatus aStatus( FileStatusMask_FileURL ); 3148 ::osl::DirectoryItem aItem; 3149 if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) && 3150 ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) ) 3151 aFileURL = aStatus.getFileURL(); 3152 3153 return aFileURL; 3154 } 3155 3156 void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent ) 3157 { 3158 if ( rAppEvent.GetEvent() == "APPEAR" && !GetCommandLineArgs()->IsInvisible() ) 3159 { 3160 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory(); 3161 3162 // find active task - the active task is always a visible task 3163 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFramesSupplier > 3164 xDesktop( xSMGR->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ), 3165 ::com::sun::star::uno::UNO_QUERY ); 3166 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xTask = xDesktop->getActiveFrame(); 3167 if ( !xTask.is() ) 3168 { 3169 // get any task if there is no active one 3170 ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > xList( xDesktop->getFrames(), ::com::sun::star::uno::UNO_QUERY ); 3171 if ( xList->getCount()>0 ) 3172 xList->getByIndex(0) >>= xTask; 3173 } 3174 3175 if ( xTask.is() ) 3176 { 3177 Reference< com::sun::star::awt::XTopWindow > xTop( xTask->getContainerWindow(), UNO_QUERY ); 3178 xTop->toFront(); 3179 } 3180 else 3181 { 3182 // no visible task that could be activated found 3183 Reference< XFrame > xBackingFrame; 3184 Reference< ::com::sun::star::awt::XWindow > xContainerWindow; 3185 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xDesktopFrame( xDesktop, UNO_QUERY ); 3186 3187 xBackingFrame = xDesktopFrame->findFrame(OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" )), 0); 3188 if (xBackingFrame.is()) 3189 xContainerWindow = xBackingFrame->getContainerWindow(); 3190 if (xContainerWindow.is()) 3191 { 3192 Sequence< Any > lArgs(1); 3193 lArgs[0] <<= xContainerWindow; 3194 Reference< XController > xBackingComp( 3195 xSMGR->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule") ), lArgs), 3196 UNO_QUERY); 3197 if (xBackingComp.is()) 3198 { 3199 Reference< ::com::sun::star::awt::XWindow > xBackingWin(xBackingComp, UNO_QUERY); 3200 // Attention: You MUST(!) call setComponent() before you call attachFrame(). 3201 // Because the backing component set the property "IsBackingMode" of the frame 3202 // to true inside attachFrame(). But setComponent() reset this state everytimes ... 3203 xBackingFrame->setComponent(xBackingWin, xBackingComp); 3204 xBackingComp->attachFrame(xBackingFrame); 3205 xContainerWindow->setVisible(sal_True); 3206 3207 Window* pCompWindow = VCLUnoHelper::GetWindow(xBackingFrame->getComponentWindow()); 3208 if (pCompWindow) 3209 pCompWindow->Update(); 3210 } 3211 } 3212 } 3213 } 3214 else if ( rAppEvent.GetEvent() == "QUICKSTART" && !GetCommandLineArgs()->IsInvisible() ) 3215 { 3216 // If the office has been started the second time its command line arguments are sent through a pipe 3217 // connection to the first office. We want to reuse the quickstart option for the first office. 3218 // NOTICE: The quickstart service must be initialized inside the "main thread", so we use the 3219 // application events to do this (they are executed inside main thread)!!! 3220 // Don't start quickstart service if the user specified "-invisible" on the command line! 3221 sal_Bool bQuickstart( sal_True ); 3222 Sequence< Any > aSeq( 1 ); 3223 aSeq[0] <<= bQuickstart; 3224 3225 Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance( 3226 DEFINE_CONST_UNICODE( "com.sun.star.office.Quickstart" )), 3227 UNO_QUERY ); 3228 if ( xQuickstart.is() ) 3229 xQuickstart->initialize( aSeq ); 3230 } 3231 else if ( rAppEvent.GetEvent() == "ACCEPT" ) 3232 { 3233 // every time an accept parameter is used we create an acceptor 3234 // with the corresponding accept-string 3235 OUString aAcceptString(rAppEvent.GetData().GetBuffer()); 3236 createAcceptor(aAcceptString); 3237 } 3238 else if ( rAppEvent.GetEvent() == "UNACCEPT" ) 3239 { 3240 // try to remove corresponding acceptor 3241 OUString aUnAcceptString(rAppEvent.GetData().GetBuffer()); 3242 destroyAcceptor(aUnAcceptString); 3243 } 3244 else if ( rAppEvent.GetEvent() == "SaveDocuments" ) 3245 { 3246 Desktop::_bTasksSaved = sal_False; 3247 Desktop::_bTasksSaved = SaveTasks(); 3248 } 3249 else if ( rAppEvent.GetEvent() == "OPENHELPURL" ) 3250 { 3251 // start help for a specific URL 3252 OUString aHelpURL(rAppEvent.GetData().GetBuffer()); 3253 Help *pHelp = Application::GetHelp(); 3254 pHelp->Start(aHelpURL, NULL); 3255 } 3256 else if ( rAppEvent.GetEvent() == APPEVENT_OPEN_STRING ) 3257 { 3258 OUString aOpenURL(rAppEvent.GetData().GetBuffer()); 3259 3260 CommandLineArgs* pCmdLine = GetCommandLineArgs(); 3261 if ( !pCmdLine->IsInvisible() && !pCmdLine->IsTerminateAfterInit() ) 3262 { 3263 ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest( 3264 pCmdLine->getCwdUrl()); 3265 pDocsRequest->aOpenList = aOpenURL; 3266 pDocsRequest->pcProcessed = NULL; 3267 3268 OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest ); 3269 delete pDocsRequest; 3270 } 3271 } 3272 else if ( rAppEvent.GetEvent() == APPEVENT_PRINT_STRING ) 3273 { 3274 OUString aPrintURL(rAppEvent.GetData().GetBuffer()); 3275 3276 CommandLineArgs* pCmdLine = GetCommandLineArgs(); 3277 if ( !pCmdLine->IsInvisible() && !pCmdLine->IsTerminateAfterInit() ) 3278 { 3279 ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest( 3280 pCmdLine->getCwdUrl()); 3281 pDocsRequest->aPrintList = aPrintURL; 3282 pDocsRequest->pcProcessed = NULL; 3283 3284 OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest ); 3285 delete pDocsRequest; 3286 } 3287 } 3288 #ifndef UNX 3289 else if ( rAppEvent.GetEvent() == "HELP" ) 3290 { 3291 // in non unix version allow showing of cmdline help window 3292 displayCmdlineHelp(); 3293 } 3294 #endif 3295 else if ( rAppEvent.GetEvent() == "SHOWDIALOG" ) 3296 { 3297 // ignore all errors here. It's clicking a menu entry only ... 3298 // The user will try it again, in case nothing happens .-) 3299 try 3300 { 3301 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory(); 3302 3303 com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider > 3304 xDesktop( xSMGR->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ), 3305 ::com::sun::star::uno::UNO_QUERY ); 3306 3307 // check provider ... we know it's weak reference only 3308 if ( ! xDesktop.is()) 3309 return; 3310 3311 css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))), css::uno::UNO_QUERY_THROW); 3312 css::util::URL aCommand; 3313 if( rAppEvent.GetData().EqualsAscii( "PREFERENCES" ) ) 3314 aCommand.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:OptionsTreeDialog" ) ); 3315 else if( rAppEvent.GetData().EqualsAscii( "ABOUT" ) ) 3316 aCommand.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:About" ) ); 3317 if( aCommand.Complete.getLength() ) 3318 { 3319 xParser->parseStrict(aCommand); 3320 3321 css::uno::Reference< css::frame::XDispatch > xDispatch = xDesktop->queryDispatch(aCommand, rtl::OUString(), 0); 3322 if (xDispatch.is()) 3323 xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >()); 3324 } 3325 } 3326 catch(const css::uno::Exception&) 3327 {} 3328 } 3329 else if( rAppEvent.GetEvent() == "PRIVATE:DOSHUTDOWN" ) 3330 { 3331 Desktop* pD = dynamic_cast<Desktop*>(GetpApp()); 3332 OSL_ENSURE( pD, "no desktop ?!?" ); 3333 if( pD ) 3334 pD->doShutdown(); 3335 } 3336 } 3337 3338 void Desktop::OpenSplashScreen() 3339 { 3340 ::rtl::OUString aTmpString; 3341 CommandLineArgs* pCmdLine = GetCommandLineArgs(); 3342 sal_Bool bVisible = sal_False; 3343 // Show intro only if this is normal start (e.g. no server, no quickstart, no printing ) 3344 if ( !pCmdLine->IsInvisible() && 3345 !pCmdLine->IsHeadless() && 3346 !pCmdLine->IsQuickstart() && 3347 !pCmdLine->IsMinimized() && 3348 !pCmdLine->IsNoLogo() && 3349 !pCmdLine->IsTerminateAfterInit() && 3350 !pCmdLine->GetPrintList( aTmpString ) && 3351 !pCmdLine->GetPrintToList( aTmpString ) ) 3352 { 3353 // Determine application name from command line parameters 3354 OUString aAppName; 3355 if ( pCmdLine->IsWriter() ) 3356 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer" )); 3357 else if ( pCmdLine->IsCalc() ) 3358 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc" )); 3359 else if ( pCmdLine->IsDraw() ) 3360 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw" )); 3361 else if ( pCmdLine->IsImpress() ) 3362 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress" )); 3363 else if ( pCmdLine->IsBase() ) 3364 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "base" )); 3365 else if ( pCmdLine->IsGlobal() ) 3366 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "global" )); 3367 else if ( pCmdLine->IsMath() ) 3368 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math" )); 3369 else if ( pCmdLine->IsWeb() ) 3370 aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "web" )); 3371 3372 bVisible = sal_True; 3373 Sequence< Any > aSeq( 2 ); 3374 aSeq[0] <<= bVisible; 3375 aSeq[1] <<= aAppName; 3376 m_rSplashScreen = Reference<XStatusIndicator>( 3377 comphelper::getProcessServiceFactory()->createInstanceWithArguments( 3378 OUString::createFromAscii("com.sun.star.office.SplashScreen"), 3379 aSeq), UNO_QUERY); 3380 3381 if(m_rSplashScreen.is()) 3382 m_rSplashScreen->start(OUString::createFromAscii("SplashScreen"), 100); 3383 } 3384 3385 } 3386 3387 void Desktop::SetSplashScreenProgress(sal_Int32 iProgress) 3388 { 3389 if(m_rSplashScreen.is()) 3390 { 3391 m_rSplashScreen->setValue(iProgress); 3392 } 3393 } 3394 3395 void Desktop::SetSplashScreenText( const ::rtl::OUString& rText ) 3396 { 3397 if( m_rSplashScreen.is() ) 3398 { 3399 m_rSplashScreen->setText( rText ); 3400 } 3401 } 3402 3403 void Desktop::CloseSplashScreen() 3404 { 3405 if(m_rSplashScreen.is()) 3406 { 3407 m_rSplashScreen->end(); 3408 m_rSplashScreen = NULL; 3409 } 3410 } 3411 3412 // ======================================================================== 3413 void Desktop::DoFirstRunInitializations() 3414 { 3415 try 3416 { 3417 Reference< XJobExecutor > xExecutor( ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.task.JobExecutor" ) ), UNO_QUERY ); 3418 if( xExecutor.is() ) 3419 xExecutor->trigger( ::rtl::OUString::createFromAscii("onFirstRunInitialization") ); 3420 } 3421 catch(const ::com::sun::star::uno::Exception&) 3422 { 3423 OSL_ENSURE( sal_False, "Desktop::DoFirstRunInitializations: caught an exception while trigger job executor ..." ); 3424 } 3425 } 3426 3427 // ======================================================================== 3428 void Desktop::CheckFirstRun( ) 3429 { 3430 const ::rtl::OUString sCommonMiscNodeName = ::rtl::OUString::createFromAscii( "/org.openoffice.Office.Common/Misc" ); 3431 const ::rtl::OUString sFirstRunNodeName = ::rtl::OUString::createFromAscii( "FirstRun" ); 3432 3433 // -------------------------------------------------------------------- 3434 // check if this is the first office start 3435 3436 // for this, open the Common/Misc node where this info is stored 3437 ::utl::OConfigurationTreeRoot aCommonMisc = ::utl::OConfigurationTreeRoot::createWithServiceFactory( 3438 ::comphelper::getProcessServiceFactory( ), 3439 sCommonMiscNodeName, 3440 2, 3441 ::utl::OConfigurationTreeRoot::CM_UPDATABLE 3442 ); 3443 3444 // read the flag 3445 OSL_ENSURE( aCommonMisc.isValid(), "Desktop::CheckFirstRun: could not open the config node needed!" ); 3446 sal_Bool bIsFirstRun = sal_False; 3447 aCommonMisc.getNodeValue( sFirstRunNodeName ) >>= bIsFirstRun; 3448 3449 if ( !bIsFirstRun ) 3450 // nothing to do .... 3451 return; 3452 3453 // -------------------------------------------------------------------- 3454 // it is the first run 3455 // this has once been done using a vos timer. this could lead to problems when 3456 // the timer would trigger when the app is already going down again, since VCL would 3457 // no longer be available. Since the old handler would do a postUserEvent to the main 3458 // thread anyway, we can use a vcl timer here to prevent the race contition (#107197#) 3459 m_firstRunTimer.SetTimeout(3000); // 3 sec. 3460 m_firstRunTimer.SetTimeoutHdl(LINK(this, Desktop, AsyncInitFirstRun)); 3461 m_firstRunTimer.Start(); 3462 3463 // -------------------------------------------------------------------- 3464 // reset the config flag 3465 3466 // set the value 3467 aCommonMisc.setNodeValue( sFirstRunNodeName, makeAny( (sal_Bool)sal_False ) ); 3468 // commit the changes 3469 aCommonMisc.commit(); 3470 } 3471 3472 } 3473