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