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