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