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