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