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