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