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