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