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