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