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