summaryrefslogtreecommitdiff
path: root/desktop/source/app
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/source/app')
-rw-r--r--desktop/source/app/app.cxx3338
-rw-r--r--desktop/source/app/appfirststart.cxx318
-rw-r--r--desktop/source/app/appinit.cxx484
-rw-r--r--desktop/source/app/appinit.hxx50
-rw-r--r--desktop/source/app/appsys.cxx69
-rw-r--r--desktop/source/app/appsys.hxx42
-rwxr-xr-xdesktop/source/app/check_ext_deps.cxx431
-rw-r--r--desktop/source/app/checkinstall.cxx118
-rw-r--r--desktop/source/app/checkinstall.hxx42
-rw-r--r--desktop/source/app/cmdlineargs.cxx900
-rw-r--r--desktop/source/app/cmdlineargs.hxx212
-rw-r--r--desktop/source/app/cmdlinehelp.cxx173
-rw-r--r--desktop/source/app/cmdlinehelp.hxx23
-rw-r--r--desktop/source/app/configinit.cxx303
-rw-r--r--desktop/source/app/configinit.hxx71
-rw-r--r--desktop/source/app/copyright_ascii_ooo.c10
-rw-r--r--desktop/source/app/copyright_ascii_sun.c8
-rw-r--r--desktop/source/app/desktop.hrc91
-rw-r--r--desktop/source/app/desktop.src234
-rw-r--r--desktop/source/app/desktopcontext.cxx63
-rw-r--r--desktop/source/app/desktopcontext.hxx50
-rw-r--r--desktop/source/app/desktopresid.cxx44
-rw-r--r--desktop/source/app/desktopresid.hxx44
-rw-r--r--desktop/source/app/dispatchwatcher.cxx514
-rw-r--r--desktop/source/app/dispatchwatcher.hxx124
-rw-r--r--desktop/source/app/exports.dxp3
-rw-r--r--desktop/source/app/langselect.cxx558
-rw-r--r--desktop/source/app/langselect.hxx74
-rw-r--r--desktop/source/app/lockfile.cxx256
-rw-r--r--desktop/source/app/lockfile.hxx99
-rw-r--r--desktop/source/app/lockfile2.cxx70
-rw-r--r--desktop/source/app/main.c36
-rw-r--r--desktop/source/app/makefile.mk115
-rw-r--r--desktop/source/app/officeipcthread.cxx996
-rw-r--r--desktop/source/app/officeipcthread.hxx165
-rw-r--r--desktop/source/app/omutexmember.hxx61
-rw-r--r--desktop/source/app/sofficemain.cxx52
-rw-r--r--desktop/source/app/sofficemain.h43
-rw-r--r--desktop/source/app/userinstall.cxx301
-rw-r--r--desktop/source/app/userinstall.hxx52
-rw-r--r--desktop/source/app/version.map34
41 files changed, 10671 insertions, 0 deletions
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
new file mode 100644
index 000000000000..cf5997ea3722
--- /dev/null
+++ b/desktop/source/app/app.cxx
@@ -0,0 +1,3338 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include <cstdlib>
+#include <vector>
+
+#include <memory>
+#include <unistd.h>
+#include "app.hxx"
+#include "desktop.hrc"
+#include "appinit.hxx"
+#include "officeipcthread.hxx"
+#include "cmdlineargs.hxx"
+#include "desktopresid.hxx"
+#include "dispatchwatcher.hxx"
+#include "configinit.hxx"
+#include "lockfile.hxx"
+#include "checkinstall.hxx"
+#include "cmdlinehelp.hxx"
+#include "userinstall.hxx"
+#include "desktopcontext.hxx"
+#include "exithelper.hxx"
+#include "../migration/pages.hxx"
+
+#include <svtools/javacontext.hxx>
+#include <com/sun/star/frame/XSessionManagerListener.hpp>
+#include <com/sun/star/frame/XSynchronousDispatch.hpp>
+#include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
+#include <com/sun/star/configuration/CorruptedConfigurationException.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/util/XFlushable.hpp>
+#include <com/sun/star/system/XSystemShellExecute.hpp>
+#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/WrappedTargetException.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/view/XPrintable.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/configuration/MissingBootstrapFileException.hpp>
+#include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
+#include <com/sun/star/configuration/InstallationIncompleteException.hpp>
+#include <com/sun/star/configuration/backend/BackendSetupException.hpp>
+#include <com/sun/star/configuration/backend/BackendAccessException.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/task/XJobExecutor.hpp>
+#include <com/sun/star/task/XRestartManager.hpp>
+#ifndef _COM_SUN_STAR_TASK_XJOBEXECUTOR_HPP_
+#include <com/sun/star/task/XJob.hpp>
+#endif
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/ui/XUIElementFactoryRegistration.hpp>
+#include <com/sun/star/frame/XUIControllerRegistration.hpp>
+
+#include <com/sun/star/java/XJavaVM.hpp>
+#include <tools/testtoolloader.hxx>
+#include <tools/solar.h>
+#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
+#include <toolkit/unohlp.hxx>
+#endif
+#include <vos/security.hxx>
+#include <vos/ref.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/configurationhelper.hxx>
+#ifndef _UTL__HXX_
+#include <unotools/configmgr.hxx>
+#endif
+#include <unotools/configitem.hxx>
+#include <unotools/confignode.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <tools/tempfile.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <osl/module.h>
+#include <osl/file.hxx>
+#include <osl/signal.h>
+#include <rtl/uuid.h>
+#include <rtl/uri.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svl/languageoptions.hxx>
+#include <unotools/internaloptions.hxx>
+#include <svtools/miscopt.hxx>
+#include <svtools/menuoptions.hxx>
+#include <unotools/syslocaleoptions.hxx>
+#include <unotools/syslocale.hxx>
+#include <svl/folderrestriction.hxx>
+#include <unotools/tempfile.hxx>
+#include <rtl/logfile.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/instance.hxx>
+#include <unotools/configmgr.hxx>
+#include <vcl/help.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/stdtext.hxx>
+#include <vcl/msgbox.hxx>
+#include <sfx2/sfx.hrc>
+#include <ucbhelper/contentbroker.hxx>
+#include <unotools/bootstrap.hxx>
+#include <cppuhelper/bootstrap.hxx>
+
+#include "vos/process.hxx"
+
+#include <svtools/fontsubstconfig.hxx>
+#include <svtools/accessibilityoptions.hxx>
+#include <svtools/apearcfg.hxx>
+#include <unotools/misccfg.hxx>
+#include <svtools/filter.hxx>
+#include <unotools/regoptions.hxx>
+
+#include "langselect.hxx"
+
+#if defined MACOSX
+#include <errno.h>
+#include <sys/wait.h>
+#endif
+
+#define DEFINE_CONST_UNICODE(CONSTASCII) UniString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))
+#define U2S(STRING) ::rtl::OUStringToOString(STRING, RTL_TEXTENCODING_UTF8)
+
+using namespace vos;
+using namespace rtl;
+
+//Gives an ICE with MSVC6
+//namespace css = ::com::sun::star;
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+//using namespace ::com::sun::star::bridge;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::view;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::system;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::container;
+
+namespace css = ::com::sun::star;
+
+ResMgr* desktop::Desktop::pResMgr = 0;
+
+namespace desktop
+{
+
+static SalMainPipeExchangeSignalHandler* pSignalHandler = 0;
+static sal_Bool _bCrashReporterEnabled = sal_True;
+
+static const ::rtl::OUString CFG_PACKAGE_COMMON_HELP ( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Office.Common/Help"));
+static const ::rtl::OUString CFG_PATH_REG ( RTL_CONSTASCII_USTRINGPARAM( "Registration" ));
+static const ::rtl::OUString CFG_ENTRY_REGURL ( RTL_CONSTASCII_USTRINGPARAM( "URL" ));
+static const ::rtl::OUString CFG_ENTRY_TEMPLATEREGURL ( RTL_CONSTASCII_USTRINGPARAM( "TemplateURL" ));
+
+// ----------------------------------------------------------------------------
+
+ResMgr* Desktop::GetDesktopResManager()
+{
+ if ( !Desktop::pResMgr )
+ {
+ String aMgrName = String::CreateFromAscii( "dkt" );
+
+ // Create desktop resource manager and bootstrap process
+ // was successful. Use default way to get language specific message.
+ if ( Application::IsInExecute() )
+ Desktop::pResMgr = ResMgr::CreateResMgr( U2S( aMgrName ));
+
+ if ( !Desktop::pResMgr )
+ {
+ // Use VCL to get the correct language specific message as we
+ // are in the bootstrap process and not able to get the installed
+ // language!!
+/*
+ LanguageType aLanguageType = LANGUAGE_DONTKNOW;
+
+ Desktop::pResMgr = ResMgr::SearchCreateResMgr( U2S( aMgrName ), aLanguageType );
+ AllSettings as = GetSettings();
+ as.SetUILanguage(aLanguageType);
+ SetSettings(as);
+*/
+ // LanguageSelection langselect;
+ OUString aUILocaleString = LanguageSelection::getLanguageString();
+ sal_Int32 nIndex = 0;
+ OUString aLanguage = aUILocaleString.getToken( 0, '-', nIndex);
+ OUString aCountry = aUILocaleString.getToken( 0, '-', nIndex);
+ OUString aVariant = aUILocaleString.getToken( 0, '-', nIndex);
+
+ ::com::sun::star::lang::Locale aLocale( aLanguage, aCountry, aVariant );
+
+ Desktop::pResMgr = ResMgr::SearchCreateResMgr( U2S( aMgrName ), aLocale);
+ AllSettings as = GetSettings();
+ as.SetUILocale(aLocale);
+ SetSettings(as);
+ }
+ }
+
+ return Desktop::pResMgr;
+}
+
+// ----------------------------------------------------------------------------
+// Get a message string securely. There is a fallback string if the resource
+// is not available.
+
+OUString Desktop::GetMsgString( USHORT nId, const OUString& aFaultBackMsg )
+{
+ ResMgr* resMgr = GetDesktopResManager();
+ if ( !resMgr )
+ return aFaultBackMsg;
+ else
+ return OUString( String( ResId( nId, *resMgr )));
+}
+
+OUString MakeStartupErrorMessage(OUString const & aErrorMessage)
+{
+ OUStringBuffer aDiagnosticMessage( 100 );
+
+ ResMgr* pResMgr = Desktop::GetDesktopResManager();
+ if ( pResMgr )
+ aDiagnosticMessage.append( OUString(String(ResId(STR_BOOTSTRAP_ERR_CANNOT_START, *pResMgr))) );
+ else
+ aDiagnosticMessage.appendAscii( "The program cannot be started." );
+
+ aDiagnosticMessage.appendAscii( "\n" );
+
+ aDiagnosticMessage.append( aErrorMessage );
+
+ return aDiagnosticMessage.makeStringAndClear();
+}
+
+OUString MakeStartupConfigAccessErrorMessage( OUString const & aInternalErrMsg )
+{
+ OUStringBuffer aDiagnosticMessage( 200 );
+
+ ResMgr* pResMgr = Desktop::GetDesktopResManager();
+ if ( pResMgr )
+ aDiagnosticMessage.append( OUString(String(ResId(STR_BOOTSTRAP_ERR_CFG_DATAACCESS, *pResMgr ))) );
+ else
+ aDiagnosticMessage.appendAscii( "The program cannot be started." );
+
+ if ( aInternalErrMsg.getLength() > 0 )
+ {
+ aDiagnosticMessage.appendAscii( "\n\n" );
+ if ( pResMgr )
+ aDiagnosticMessage.append( OUString(String(ResId(STR_INTERNAL_ERRMSG, *pResMgr ))) );
+ else
+ aDiagnosticMessage.appendAscii( "The following internal error has occured:\n\n" );
+ aDiagnosticMessage.append( aInternalErrMsg );
+ }
+
+ return aDiagnosticMessage.makeStringAndClear();
+}
+
+//=============================================================================
+// shows a simple error box with the given message ... but exits from these process !
+//
+// Fatal errors cant be solved by the process ... nor any recovery can help.
+// Mostly the installation was damaged and must be repaired manually .. or by calling
+// setup again.
+//
+// On the other side we must make sure that no further actions will be possible within
+// the current office process ! No pipe requests, no menu/toolbar/shortuct actions
+// are allowed. Otherwise we will force a "crash inside a crash".
+//
+// Thats why we have to use a special native message box here which does not use yield :-)
+//=============================================================================
+void FatalError(const ::rtl::OUString& sMessage)
+{
+ ::rtl::OUString sProductKey = ::utl::Bootstrap::getProductKey();
+ if ( ! sProductKey.getLength())
+ {
+ ::vos::OStartupInfo aInfo;
+ aInfo.getExecutableFile( sProductKey );
+
+ ::sal_uInt32 nLastIndex = sProductKey.lastIndexOf('/');
+ if ( nLastIndex > 0 )
+ sProductKey = sProductKey.copy( nLastIndex+1 );
+ }
+
+ ::rtl::OUStringBuffer sTitle (128);
+ sTitle.append (sProductKey );
+ sTitle.appendAscii (" - Fatal Error");
+
+ Application::ShowNativeErrorBox (sTitle.makeStringAndClear (), sMessage);
+ _exit(ExitHelper::E_FATAL_ERROR);
+}
+
+static bool ShouldSuppressUI(CommandLineArgs* pCmdLine)
+{
+ return pCmdLine->IsInvisible() ||
+ pCmdLine->IsHeadless() ||
+ pCmdLine->IsQuickstart();
+}
+
+CommandLineArgs* Desktop::GetCommandLineArgs()
+{
+ static CommandLineArgs* pArgs = 0;
+ if ( !pArgs )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pArgs )
+ {
+ pArgs = new CommandLineArgs;
+ }
+ }
+
+ return pArgs;
+}
+
+sal_Bool InitConfiguration()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (jb99855) ::InitConfiguration" );
+
+ Reference< XMultiServiceFactory > xProvider( CreateApplicationConfigurationProvider( ) );
+ return xProvider.is();
+}
+
+namespace
+{
+ struct BrandName
+ : public rtl::Static< String, BrandName > {};
+ struct Version
+ : public rtl::Static< String, Version > {};
+ struct AboutBoxVersion
+ : public rtl::Static< String, AboutBoxVersion > {};
+ struct OOOVendor
+ : public rtl::Static< String, OOOVendor > {};
+ struct Extension
+ : public rtl::Static< String, Extension > {};
+ struct XMLFileFormatName
+ : public rtl::Static< String, XMLFileFormatName > {};
+ struct XMLFileFormatVersion
+ : public rtl::Static< String, XMLFileFormatVersion > {};
+ struct WriterCompatibilityVersionOOo11
+ : public rtl::Static< String, WriterCompatibilityVersionOOo11 > {};
+}
+
+void ReplaceStringHookProc( UniString& rStr )
+{
+ static int nAll = 0, nPro = 0;
+
+ nAll++;
+ if ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND )
+ {
+ String &rBrandName = BrandName::get();
+ String &rVersion = Version::get();
+ String &rAboutBoxVersion = AboutBoxVersion::get();
+ String &rExtension = Extension::get();
+ String &rXMLFileFormatName = XMLFileFormatName::get();
+ String &rXMLFileFormatVersion = XMLFileFormatVersion::get();
+
+ if ( !rBrandName.Len() )
+ {
+ rtl::OUString aTmp;
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
+ aRet >>= aTmp;
+ rBrandName = aTmp;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTXMLFILEFORMATNAME );
+ aRet >>= aTmp;
+ rXMLFileFormatName = aTmp;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTXMLFILEFORMATVERSION );
+ aRet >>= aTmp;
+ rXMLFileFormatVersion = aTmp;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION );
+ aRet >>= aTmp;
+ rVersion = aTmp;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::ABOUTBOXPRODUCTVERSION );
+ aRet >>= aTmp;
+ rAboutBoxVersion = aTmp;
+
+ if ( !rExtension.Len() )
+ {
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTEXTENSION );
+ aRet >>= aTmp;
+ rExtension = aTmp;
+ }
+ }
+
+ nPro++;
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTNAME", rBrandName );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTVERSION", rVersion );
+ rStr.SearchAndReplaceAllAscii( "%ABOUTBOXPRODUCTVERSION", rAboutBoxVersion );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTEXTENSION", rExtension );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTXMLFILEFORMATNAME", rXMLFileFormatName );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTXMLFILEFORMATVERSION", rXMLFileFormatVersion );
+ }
+ if ( rStr.SearchAscii( "%OOOVENDOR" ) != STRING_NOTFOUND )
+ {
+ String &rOOOVendor = OOOVendor::get();
+
+ if ( !rOOOVendor.Len() )
+ {
+ rtl::OUString aTmp;
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::OOOVENDOR );
+ aRet >>= aTmp;
+ rOOOVendor = aTmp;
+
+ }
+ rStr.SearchAndReplaceAllAscii( "%OOOVENDOR" ,rOOOVendor );
+ }
+
+ if ( rStr.SearchAscii( "%WRITERCOMPATIBILITYVERSIONOOO11" ) != STRING_NOTFOUND )
+ {
+ String &rWriterCompatibilityVersionOOo11 = WriterCompatibilityVersionOOo11::get();
+ if ( !rWriterCompatibilityVersionOOo11.Len() )
+ {
+ rtl::OUString aTmp;
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::WRITERCOMPATIBILITYVERSIONOOO11 );
+ aRet >>= aTmp;
+ rWriterCompatibilityVersionOOo11 = aTmp;
+ }
+
+ rStr.SearchAndReplaceAllAscii( "%WRITERCOMPATIBILITYVERSIONOOO11",
+ rWriterCompatibilityVersionOOo11 );
+ }
+}
+
+static const char pLastSyncFileName[] = "lastsynchronized";
+static const sal_Int32 nStrLenLastSync = 16;
+
+static bool needsSynchronization(
+ ::rtl::OUString const & baseSynchronizedURL, ::rtl::OUString const & userSynchronizedURL )
+{
+ bool bNeedsSync( false );
+
+ ::osl::DirectoryItem itemUserFile;
+ ::osl::File::RC err1 =
+ ::osl::DirectoryItem::get(userSynchronizedURL, itemUserFile);
+
+ //If it does not exist, then there is nothing to be done
+ if (err1 == ::osl::File::E_NOENT)
+ {
+ return true;
+ }
+ else if (err1 != ::osl::File::E_None)
+ {
+ OSL_ENSURE(0, "Cannot access lastsynchronized in user layer");
+ return true; //sync just in case
+ }
+
+ //If last synchronized does not exist in base layer, then do nothing
+ ::osl::DirectoryItem itemBaseFile;
+ ::osl::File::RC err2 = ::osl::DirectoryItem::get(baseSynchronizedURL, itemBaseFile);
+ if (err2 == ::osl::File::E_NOENT)
+ {
+ return true;
+
+ }
+ else if (err2 != ::osl::File::E_None)
+ {
+ OSL_ENSURE(0, "Cannot access file lastsynchronized in base layer");
+ return true; //sync just in case
+ }
+
+ //compare the modification time of the extension folder and the last
+ //modified file
+ ::osl::FileStatus statUser(FileStatusMask_ModifyTime);
+ ::osl::FileStatus statBase(FileStatusMask_ModifyTime);
+ if (itemUserFile.getFileStatus(statUser) == ::osl::File::E_None)
+ {
+ if (itemBaseFile.getFileStatus(statBase) == ::osl::File::E_None)
+ {
+ TimeValue timeUser = statUser.getModifyTime();
+ TimeValue timeBase = statBase.getModifyTime();
+
+ if (timeUser.Seconds < timeBase.Seconds)
+ bNeedsSync = true;
+ }
+ else
+ {
+ OSL_ASSERT(0);
+ bNeedsSync = true;
+ }
+ }
+ else
+ {
+ OSL_ASSERT(0);
+ bNeedsSync = true;
+ }
+
+ return bNeedsSync;
+}
+
+static ::rtl::OUString getBrandSharePreregBundledPathURL()
+{
+ ::rtl::OUString url(
+ RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/share/prereg/bundled"));
+
+ ::rtl::Bootstrap::expandMacros(url);
+ return url;
+}
+
+static ::rtl::OUString getUserBundledExtPathURL()
+{
+ ::rtl::OUString folder( RTL_CONSTASCII_USTRINGPARAM( "$BUNDLED_EXTENSIONS_USER" ));
+ ::rtl::Bootstrap::expandMacros(folder);
+
+ return folder;
+}
+
+static ::rtl::OUString getLastSyncFileURLFromBrandInstallation()
+{
+ ::rtl::OUString aURL = getBrandSharePreregBundledPathURL();
+ ::sal_Int32 nLastIndex = aURL.lastIndexOf('/');
+
+ ::rtl::OUStringBuffer aTmp( aURL );
+
+ if ( nLastIndex != aURL.getLength()-1 )
+ aTmp.appendAscii( "/" );
+ aTmp.appendAscii( pLastSyncFileName );
+
+ return aTmp.makeStringAndClear();
+}
+
+static ::rtl::OUString getLastSyncFileURLFromUserInstallation()
+{
+ ::rtl::OUString aUserBundledPathURL = getUserBundledExtPathURL();
+ ::sal_Int32 nLastIndex = aUserBundledPathURL.lastIndexOf('/');
+
+ ::rtl::OUStringBuffer aTmp( aUserBundledPathURL );
+
+ if ( nLastIndex != aUserBundledPathURL.getLength()-1 )
+ aTmp.appendAscii( "/" );
+ aTmp.appendAscii( pLastSyncFileName );
+
+ return aTmp.makeStringAndClear();
+}
+
+static osl::FileBase::RC copy_bundled_recursive(
+ const rtl::OUString& srcUnqPath,
+ const rtl::OUString& dstUnqPath,
+ sal_Int32 TypeToCopy )
+throw()
+{
+ osl::FileBase::RC err = osl::FileBase::E_None;
+
+ if( TypeToCopy == -1 ) // Document
+ {
+ err = osl::File::copy( srcUnqPath,dstUnqPath );
+ }
+ else if( TypeToCopy == +1 ) // Folder
+ {
+ osl::Directory aDir( srcUnqPath );
+ aDir.open();
+
+ err = osl::Directory::create( dstUnqPath );
+ osl::FileBase::RC next = err;
+ if( err == osl::FileBase::E_None ||
+ err == osl::FileBase::E_EXIST )
+ {
+ err = osl::FileBase::E_None;
+ sal_Int32 n_Mask = FileStatusMask_FileURL | FileStatusMask_FileName | FileStatusMask_Type;
+
+ osl::DirectoryItem aDirItem;
+
+ while( err == osl::FileBase::E_None && ( next = aDir.getNextItem( aDirItem ) ) == osl::FileBase::E_None )
+ {
+ sal_Bool IsDoc = false;
+ sal_Bool bFilter = false;
+ osl::FileStatus aFileStatus( n_Mask );
+ aDirItem.getFileStatus( aFileStatus );
+ if( aFileStatus.isValid( FileStatusMask_Type ) )
+ IsDoc = aFileStatus.getFileType() == osl::FileStatus::Regular;
+
+ // Getting the information for the next recursive copy
+ sal_Int32 newTypeToCopy = IsDoc ? -1 : +1;
+
+ rtl::OUString newSrcUnqPath;
+ if( aFileStatus.isValid( FileStatusMask_FileURL ) )
+ newSrcUnqPath = aFileStatus.getFileURL();
+
+ rtl::OUString newDstUnqPath = dstUnqPath;
+ rtl::OUString tit;
+ if( aFileStatus.isValid( FileStatusMask_FileName ) )
+ {
+ ::rtl::OUString aFileName = aFileStatus.getFileName();
+ tit = rtl::Uri::encode( aFileName,
+ rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 );
+
+ // Special treatment for "lastsychronized" file. Must not be
+ // copied from the bundled folder!
+ if ( IsDoc && aFileName.equalsAscii( pLastSyncFileName ))
+ bFilter = true;
+ }
+
+ if( newDstUnqPath.lastIndexOf( sal_Unicode('/') ) != newDstUnqPath.getLength()-1 )
+ newDstUnqPath += rtl::OUString::createFromAscii( "/" );
+
+ newDstUnqPath += tit;
+
+ if (( newSrcUnqPath != dstUnqPath ) && !bFilter )
+ err = copy_bundled_recursive( newSrcUnqPath,newDstUnqPath, newTypeToCopy );
+ }
+
+ if( err == osl::FileBase::E_None && next != osl::FileBase::E_NOENT )
+ err = next;
+ }
+ aDir.close();
+ }
+
+ return err;
+}
+
+Desktop::Desktop()
+: m_bServicesRegistered( false )
+, m_aBootstrapError( BE_OK )
+, m_pLockfile( NULL )
+{
+ RTL_LOGFILE_TRACE( "desktop (cd100003) ::Desktop::Desktop" );
+}
+
+Desktop::~Desktop()
+{
+}
+
+void Desktop::Init()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::Init" );
+ SetBootstrapStatus(BS_OK);
+
+ // Check for lastsynchronized file for bundled extensions in the user directory
+ // and test if synchronzation is necessary!
+ {
+ ::rtl::OUString aUserLastSyncFilePathURL = getLastSyncFileURLFromUserInstallation();
+ ::rtl::OUString aPreregSyncFilePathURL = getLastSyncFileURLFromBrandInstallation();
+
+ if ( needsSynchronization( aPreregSyncFilePathURL, aUserLastSyncFilePathURL ))
+ {
+ rtl::OUString aUserPath = getUserBundledExtPathURL();
+ rtl::OUString aPreregBundledPath = getBrandSharePreregBundledPathURL();
+
+ // copy bundled folder to the user directory
+ osl::FileBase::RC rc = osl::Directory::createPath(aUserPath);
+ (void) rc;
+ copy_bundled_recursive( aPreregBundledPath, aUserPath, +1 );
+ }
+ }
+
+ // create service factory...
+ Reference < XMultiServiceFactory > rSMgr = CreateApplicationServiceManager();
+ if( rSMgr.is() )
+ {
+ ::comphelper::setProcessServiceFactory( rSMgr );
+ }
+ else
+ {
+ SetBootstrapError( BE_UNO_SERVICEMANAGER );
+ }
+
+ if ( GetBootstrapError() == BE_OK )
+ {
+ // prepare language
+ if ( !LanguageSelection::prepareLanguage() )
+ {
+ if ( LanguageSelection::getStatus() == LanguageSelection::LS_STATUS_CANNOT_DETERMINE_LANGUAGE )
+ SetBootstrapError( BE_LANGUAGE_MISSING );
+ else
+ SetBootstrapError( BE_OFFICECONFIG_BROKEN );
+ }
+ }
+
+ if ( GetBootstrapError() == BE_OK )
+ {
+ CommandLineArgs* pCmdLineArgs = GetCommandLineArgs();
+#ifdef UNX
+ // check whether we need to print cmdline help
+ if ( pCmdLineArgs->IsHelp() ) {
+ displayCmdlineHelp();
+ SetBootstrapStatus(BS_TERMINATE);
+ }
+#endif
+ // start ipc thread only for non-remote offices
+ RTL_LOGFILE_CONTEXT( aLog2, "desktop (cd100003) ::OfficeIPCThread::EnableOfficeIPCThread" );
+ OfficeIPCThread::Status aStatus = OfficeIPCThread::EnableOfficeIPCThread();
+ if ( aStatus == OfficeIPCThread::IPC_STATUS_BOOTSTRAP_ERROR )
+ {
+ SetBootstrapError( BE_PATHINFO_MISSING );
+ }
+ else if ( aStatus == OfficeIPCThread::IPC_STATUS_2ND_OFFICE )
+ {
+ // 2nd office startup should terminate after sending cmdlineargs through pipe
+ SetBootstrapStatus(BS_TERMINATE);
+ }
+ else if ( pCmdLineArgs->IsHelp() )
+ {
+ // disable IPC thread in an instance that is just showing a help message
+ OfficeIPCThread::DisableOfficeIPCThread();
+ }
+ pSignalHandler = new SalMainPipeExchangeSignalHandler;
+ }
+}
+
+void Desktop::DeInit()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::DeInit" );
+
+ try {
+ // instead of removing of the configManager just let it commit all the changes
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
+ utl::ConfigManager::GetConfigManager()->StoreConfigItems();
+ FlushConfiguration();
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
+
+ // close splashscreen if it's still open
+ CloseSplashScreen();
+ Reference<XMultiServiceFactory> xXMultiServiceFactory(::comphelper::getProcessServiceFactory());
+ DestroyApplicationServiceManager( xXMultiServiceFactory );
+ // nobody should get a destroyd service factory...
+ ::comphelper::setProcessServiceFactory( NULL );
+
+ // clear lockfile
+ if (m_pLockfile != NULL)
+ m_pLockfile->clean();
+
+ OfficeIPCThread::DisableOfficeIPCThread();
+ if( pSignalHandler )
+ DELETEZ( pSignalHandler );
+ } catch (RuntimeException&) {
+ // someone threw an exception during shutdown
+ // this will leave some garbage behind..
+ }
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "FINISHED WITH Destop::DeInit" );
+}
+
+BOOL Desktop::QueryExit()
+{
+ try
+ {
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
+ utl::ConfigManager::GetConfigManager()->StoreConfigItems();
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
+ }
+ catch ( RuntimeException& )
+ {
+ }
+
+ const sal_Char SUSPEND_QUICKSTARTVETO[] = "SuspendQuickstartVeto";
+
+ Reference< ::com::sun::star::frame::XDesktop >
+ xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ UNO_QUERY );
+
+ Reference < ::com::sun::star::beans::XPropertySet > xPropertySet( xDesktop, UNO_QUERY );
+ if ( xPropertySet.is() )
+ {
+ Any a;
+ a <<= (sal_Bool)sal_True;
+ xPropertySet->setPropertyValue( OUSTRING(RTL_CONSTASCII_USTRINGPARAM( SUSPEND_QUICKSTARTVETO )), a );
+ }
+
+ BOOL bExit = ( !xDesktop.is() || xDesktop->terminate() );
+
+
+ if ( !bExit && xPropertySet.is() )
+ {
+ Any a;
+ a <<= (sal_Bool)sal_False;
+ xPropertySet->setPropertyValue( OUSTRING(RTL_CONSTASCII_USTRINGPARAM( SUSPEND_QUICKSTARTVETO )), a );
+ }
+ else
+ {
+ FlushConfiguration();
+ try
+ {
+ // it is no problem to call DisableOfficeIPCThread() more than once
+ // it also looks to be threadsafe
+ OfficeIPCThread::DisableOfficeIPCThread();
+ }
+ catch ( RuntimeException& )
+ {
+ }
+
+ if (m_pLockfile != NULL) m_pLockfile->clean();
+ }
+
+ return bExit;
+}
+
+void Desktop::HandleBootstrapPathErrors( ::utl::Bootstrap::Status aBootstrapStatus, const OUString& aDiagnosticMessage )
+{
+ if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
+ {
+ sal_Bool bWorkstationInstallation = sal_False;
+ ::rtl::OUString aBaseInstallURL;
+ ::rtl::OUString aUserInstallURL;
+ ::rtl::OUString aProductKey;
+ ::rtl::OUString aTemp;
+ ::vos::OStartupInfo aInfo;
+
+ aInfo.getExecutableFile( aProductKey );
+ sal_uInt32 lastIndex = aProductKey.lastIndexOf('/');
+ if ( lastIndex > 0 )
+ aProductKey = aProductKey.copy( lastIndex+1 );
+
+ aTemp = ::utl::Bootstrap::getProductKey( aProductKey );
+ if ( aTemp.getLength() > 0 )
+ aProductKey = aTemp;
+
+ ::utl::Bootstrap::PathStatus aBaseInstallStatus = ::utl::Bootstrap::locateBaseInstallation( aBaseInstallURL );
+ ::utl::Bootstrap::PathStatus aUserInstallStatus = ::utl::Bootstrap::locateUserInstallation( aUserInstallURL );
+
+ if (( aBaseInstallStatus == ::utl::Bootstrap::PATH_EXISTS &&
+ aUserInstallStatus == ::utl::Bootstrap::PATH_EXISTS ))
+ {
+ if ( aBaseInstallURL != aUserInstallURL )
+ bWorkstationInstallation = sal_True;
+ }
+
+ OUString aMessage;
+ OUStringBuffer aBuffer( 100 );
+ aBuffer.append( aDiagnosticMessage );
+
+ aBuffer.appendAscii( "\n" );
+
+ ErrorBox aBootstrapFailedBox( NULL, WB_OK, aMessage );
+ aBootstrapFailedBox.SetText( aProductKey );
+ aBootstrapFailedBox.Execute();
+ }
+}
+
+// Create a error message depending on bootstrap failure code and an optional file url
+::rtl::OUString Desktop::CreateErrorMsgString(
+ utl::Bootstrap::FailureCode nFailureCode,
+ const ::rtl::OUString& aFileURL )
+{
+ OUString aMsg;
+ OUString aFilePath;
+ sal_Bool bFileInfo = sal_True;
+
+ switch ( nFailureCode )
+ {
+ /// the shared installation directory could not be located
+ case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_PATH_INVALID,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The installation path is not available." )) );
+ bFileInfo = sal_False;
+ }
+ break;
+
+ /// the bootstrap INI file could not be found or read
+ case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is missing." )) );
+ }
+ break;
+
+ /// the bootstrap INI is missing a required entry
+ /// the bootstrap INI contains invalid data
+ case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
+ case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_CORRUPT,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is corrupt." )) );
+ }
+ break;
+
+ /// the version locator INI file could not be found or read
+ case ::utl::Bootstrap::MISSING_VERSION_FILE:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is missing." )) );
+ }
+ break;
+
+ /// the version locator INI has no entry for this version
+ case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SUPPORT,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The main configuration file \"$1\" does not support the current version." )) );
+ }
+ break;
+
+ /// the user installation directory does not exist
+ case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_DIR_MISSING,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration directory \"$1\" is missing." )) );
+ }
+ break;
+
+ /// some bootstrap data was invalid in unexpected ways
+ case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
+ {
+ aMsg = GetMsgString( STR_BOOTSTRAP_ERR_INTERNAL,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "An internal failure occurred." )) );
+ bFileInfo = sal_False;
+ }
+ break;
+
+ case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
+ {
+ // This needs to be improved, see #i67575#:
+ aMsg = OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "Invalid version file entry" ) );
+ bFileInfo = sal_False;
+ }
+ break;
+
+ case ::utl::Bootstrap::NO_FAILURE:
+ {
+ OSL_ASSERT(false);
+ }
+ break;
+ }
+
+ if ( bFileInfo )
+ {
+ String aMsgString( aMsg );
+
+ osl::File::getSystemPathFromFileURL( aFileURL, aFilePath );
+
+ aMsgString.SearchAndReplaceAscii( "$1", aFilePath );
+ aMsg = aMsgString;
+ }
+
+ return MakeStartupErrorMessage( aMsg );
+}
+
+void Desktop::HandleBootstrapErrors( BootstrapError aBootstrapError )
+{
+ if ( aBootstrapError == BE_PATHINFO_MISSING )
+ {
+ OUString aErrorMsg;
+ OUString aBuffer;
+ utl::Bootstrap::Status aBootstrapStatus;
+ utl::Bootstrap::FailureCode nFailureCode;
+
+ aBootstrapStatus = ::utl::Bootstrap::checkBootstrapStatus( aBuffer, nFailureCode );
+ if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
+ {
+ switch ( nFailureCode )
+ {
+ case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
+ case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
+ {
+ aErrorMsg = CreateErrorMsgString( nFailureCode, OUString() );
+ }
+ break;
+
+ /// the bootstrap INI file could not be found or read
+ /// the bootstrap INI is missing a required entry
+ /// the bootstrap INI contains invalid data
+ case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
+ case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
+ case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
+ {
+ OUString aBootstrapFileURL;
+
+ utl::Bootstrap::locateBootstrapFile( aBootstrapFileURL );
+ aErrorMsg = CreateErrorMsgString( nFailureCode, aBootstrapFileURL );
+ }
+ break;
+
+ /// the version locator INI file could not be found or read
+ /// the version locator INI has no entry for this version
+ /// the version locator INI entry is not a valid directory URL
+ case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
+ case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
+ case ::utl::Bootstrap::MISSING_VERSION_FILE:
+ {
+ OUString aVersionFileURL;
+
+ utl::Bootstrap::locateVersionFile( aVersionFileURL );
+ aErrorMsg = CreateErrorMsgString( nFailureCode, aVersionFileURL );
+ }
+ break;
+
+ /// the user installation directory does not exist
+ case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
+ {
+ OUString aUserInstallationURL;
+
+ utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
+ aErrorMsg = CreateErrorMsgString( nFailureCode, aUserInstallationURL );
+ }
+ break;
+
+ case ::utl::Bootstrap::NO_FAILURE:
+ {
+ OSL_ASSERT(false);
+ }
+ break;
+ }
+
+ HandleBootstrapPathErrors( aBootstrapStatus, aErrorMsg );
+ }
+ }
+ else if ( aBootstrapError == BE_UNO_SERVICEMANAGER || aBootstrapError == BE_UNO_SERVICE_CONFIG_MISSING )
+ {
+ // Uno service manager is not available. VCL needs a uno service manager to display a message box!!!
+ // Currently we are not able to display a message box with a service manager due to this limitations inside VCL.
+
+ // When UNO is not properly initialized, all kinds of things can fail
+ // and cause the process to crash (e.g., a call to GetMsgString may
+ // crash when somewhere deep within that call Any::operator <= is used
+ // with a PropertyValue, and no binary UNO type description for
+ // PropertyValue is available). To give the user a hint even if
+ // generating and displaying a message box below crashes, print a
+ // hard-coded message on stderr first:
+ fputs(
+ aBootstrapError == BE_UNO_SERVICEMANAGER
+ ? ("The application cannot be started. " "\n"
+ "The component manager is not available." "\n")
+ // STR_BOOTSTRAP_ERR_CANNOT_START, STR_BOOTSTRAP_ERR_NO_SERVICE
+ : ("The application cannot be started. " "\n"
+ "The configuration service is not available." "\n"),
+ // STR_BOOTSTRAP_ERR_CANNOT_START,
+ // STR_BOOTSTRAP_ERR_NO_CFG_SERVICE
+ stderr);
+
+ // First sentence. We cannot bootstrap office further!
+ OUString aMessage;
+ OUStringBuffer aDiagnosticMessage( 100 );
+
+ OUString aErrorMsg;
+
+ if ( aBootstrapError == BE_UNO_SERVICEMANAGER )
+ aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SERVICE,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The service manager is not available." )) );
+ else
+ aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_CFG_SERVICE,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration service is not available." )) );
+
+ aDiagnosticMessage.append( aErrorMsg );
+ aDiagnosticMessage.appendAscii( "\n" );
+
+ // Due to the fact the we haven't a backup applicat.rdb file anymore it is not possible to
+ // repair the installation with the setup executable besides the office executable. Now
+ // we have to ask the user to start the setup on CD/installation directory manually!!
+ OUString aStartSetupManually( GetMsgString(
+ STR_ASK_START_SETUP_MANUALLY,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "Start setup application to repair the installation from CD, or the folder containing the installation packages." )) ));
+
+ aDiagnosticMessage.append( aStartSetupManually );
+ aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
+
+ FatalError( aMessage);
+ }
+ else if ( aBootstrapError == BE_OFFICECONFIG_BROKEN )
+ {
+ OUString aMessage;
+ OUStringBuffer aDiagnosticMessage( 100 );
+ OUString aErrorMsg;
+ aErrorMsg = GetMsgString( STR_CONFIG_ERR_ACCESS_GENERAL,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "A general error occurred while accessing your central configuration." )) );
+ aDiagnosticMessage.append( aErrorMsg );
+ aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
+ FatalError(aMessage);
+ }
+ else if ( aBootstrapError == BE_USERINSTALL_FAILED )
+ {
+ OUString aMessage;
+ OUStringBuffer aDiagnosticMessage( 100 );
+ OUString aErrorMsg;
+ aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_INTERNAL,
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "User installation could not be completed" )) );
+ aDiagnosticMessage.append( aErrorMsg );
+ aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
+ FatalError(aMessage);
+ }
+ else if ( aBootstrapError == BE_LANGUAGE_MISSING )
+ {
+ OUString aMessage;
+ OUStringBuffer aDiagnosticMessage( 100 );
+ OUString aErrorMsg;
+ aErrorMsg = GetMsgString(
+ //@@@ FIXME: should use an own resource string => #i36213#
+ STR_BOOTSTRAP_ERR_LANGUAGE_MISSING,
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Language could not be determined." )) );
+ aDiagnosticMessage.append( aErrorMsg );
+ aMessage = MakeStartupErrorMessage(
+ aDiagnosticMessage.makeStringAndClear() );
+ FatalError(aMessage);
+ }
+ else if (( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE ) ||
+ ( aBootstrapError == BE_USERINSTALL_NOWRITEACCESS ))
+ {
+ OUString aUserInstallationURL;
+ OUString aUserInstallationPath;
+ OUString aMessage;
+ OUString aErrorMsg;
+ OUStringBuffer aDiagnosticMessage( 100 );
+
+ utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
+
+ if ( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE )
+ aErrorMsg = GetMsgString(
+ STR_BOOSTRAP_ERR_NOTENOUGHDISKSPACE,
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "User installation could not be completed due to insufficient free disk space." )) );
+ else
+ aErrorMsg = GetMsgString(
+ STR_BOOSTRAP_ERR_NOACCESSRIGHTS,
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "User installation could not be processed due to missing access rights." )) );
+
+ osl::File::getSystemPathFromFileURL( aUserInstallationURL, aUserInstallationPath );
+
+ aDiagnosticMessage.append( aErrorMsg );
+ aDiagnosticMessage.append( aUserInstallationPath );
+ aMessage = MakeStartupErrorMessage(
+ aDiagnosticMessage.makeStringAndClear() );
+ FatalError(aMessage);
+ }
+
+ return;
+}
+
+
+void Desktop::retrieveCrashReporterState()
+{
+ static const ::rtl::OUString CFG_PACKAGE_RECOVERY = ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery/");
+ static const ::rtl::OUString CFG_PATH_CRASHREPORTER = ::rtl::OUString::createFromAscii("CrashReporter" );
+ static const ::rtl::OUString CFG_ENTRY_ENABLED = ::rtl::OUString::createFromAscii("Enabled" );
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ sal_Bool bEnabled( sal_True );
+ if ( xSMGR.is() )
+ {
+ css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
+ xSMGR,
+ CFG_PACKAGE_RECOVERY,
+ CFG_PATH_CRASHREPORTER,
+ CFG_ENTRY_ENABLED,
+ ::comphelper::ConfigurationHelper::E_READONLY);
+ aVal >>= bEnabled;
+ }
+ _bCrashReporterEnabled = bEnabled;
+}
+
+sal_Bool Desktop::isUIOnSessionShutdownAllowed()
+{
+ static const ::rtl::OUString CFG_PACKAGE_RECOVERY = ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery/");
+ static const ::rtl::OUString CFG_PATH_SESSION = ::rtl::OUString::createFromAscii("SessionShutdown" );
+ static const ::rtl::OUString CFG_ENTRY_UIENABLED = ::rtl::OUString::createFromAscii("DocumentStoreUIEnabled" );
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ sal_Bool bResult = sal_False;
+ if ( xSMGR.is() )
+ {
+ css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
+ xSMGR,
+ CFG_PACKAGE_RECOVERY,
+ CFG_PATH_SESSION,
+ CFG_ENTRY_UIENABLED,
+ ::comphelper::ConfigurationHelper::E_READONLY);
+ aVal >>= bResult;
+ }
+
+ return bResult;
+}
+
+//-----------------------------------------------
+/** @short check if crash reporter feature is enabled or
+ disabled.
+*/
+sal_Bool Desktop::isCrashReporterEnabled()
+{
+ return _bCrashReporterEnabled;
+}
+
+//-----------------------------------------------
+/** @short check if recovery must be started or not.
+
+ @param bCrashed [boolean ... out!]
+ the office crashed last times.
+ But may be there are no recovery data.
+ Usefull to trigger the error report tool without
+ showing the recovery UI.
+
+ @param bRecoveryDataExists [boolean ... out!]
+ there exists some recovery data.
+
+ @param bSessionDataExists [boolean ... out!]
+ there exists some session data.
+ Because the user may be logged out last time from it's
+ unix session...
+*/
+void impl_checkRecoveryState(sal_Bool& bCrashed ,
+ sal_Bool& bRecoveryDataExists,
+ sal_Bool& bSessionDataExists )
+{
+ static const ::rtl::OUString SERVICENAME_RECOVERYCORE = ::rtl::OUString::createFromAscii("com.sun.star.frame.AutoRecovery");
+ static const ::rtl::OUString PROP_CRASHED = ::rtl::OUString::createFromAscii("Crashed" );
+ static const ::rtl::OUString PROP_EXISTSRECOVERY = ::rtl::OUString::createFromAscii("ExistsRecoveryData" );
+ static const ::rtl::OUString PROP_EXISTSSESSION = ::rtl::OUString::createFromAscii("ExistsSessionData" );
+ static const ::rtl::OUString CFG_PACKAGE_RECOVERY = ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery/");
+ static const ::rtl::OUString CFG_PATH_RECOVERYINFO = ::rtl::OUString::createFromAscii("RecoveryInfo" );
+
+ bCrashed = sal_False;
+ bRecoveryDataExists = sal_False;
+ bSessionDataExists = sal_False;
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+ try
+ {
+ css::uno::Reference< css::beans::XPropertySet > xRecovery(
+ xSMGR->createInstance(SERVICENAME_RECOVERYCORE),
+ css::uno::UNO_QUERY_THROW);
+
+ xRecovery->getPropertyValue(PROP_CRASHED ) >>= bCrashed ;
+ xRecovery->getPropertyValue(PROP_EXISTSRECOVERY) >>= bRecoveryDataExists;
+ xRecovery->getPropertyValue(PROP_EXISTSSESSION ) >>= bSessionDataExists ;
+ }
+ catch(const css::uno::Exception&) {}
+}
+
+//-----------------------------------------------
+/* @short start the recovery wizard.
+
+ @param bEmergencySave
+ differs between EMERGENCY_SAVE and RECOVERY
+*/
+sal_Bool impl_callRecoveryUI(sal_Bool bEmergencySave ,
+ sal_Bool bCrashed ,
+ sal_Bool bExistsRecoveryData)
+{
+ static ::rtl::OUString SERVICENAME_RECOVERYUI = ::rtl::OUString::createFromAscii("com.sun.star.comp.svx.RecoveryUI" );
+ static ::rtl::OUString SERVICENAME_URLPARSER = ::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" );
+ static ::rtl::OUString COMMAND_EMERGENCYSAVE = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/doEmergencySave");
+ static ::rtl::OUString COMMAND_RECOVERY = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/doAutoRecovery" );
+ static ::rtl::OUString COMMAND_CRASHREPORT = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/doCrashReport" );
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ css::uno::Reference< css::frame::XSynchronousDispatch > xRecoveryUI(
+ xSMGR->createInstance(SERVICENAME_RECOVERYUI),
+ css::uno::UNO_QUERY_THROW);
+
+ css::uno::Reference< css::util::XURLTransformer > xURLParser(
+ xSMGR->createInstance(SERVICENAME_URLPARSER),
+ css::uno::UNO_QUERY_THROW);
+
+ css::util::URL aURL;
+ if (bEmergencySave)
+ aURL.Complete = COMMAND_EMERGENCYSAVE;
+ else
+ {
+ if (bExistsRecoveryData)
+ aURL.Complete = COMMAND_RECOVERY;
+ else
+ if (bCrashed && Desktop::isCrashReporterEnabled() )
+ aURL.Complete = COMMAND_CRASHREPORT;
+ }
+
+ sal_Bool bRet = sal_False;
+ if ( aURL.Complete.getLength() > 0 )
+ {
+ xURLParser->parseStrict(aURL);
+
+ css::uno::Any aRet = xRecoveryUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
+ aRet >>= bRet;
+ }
+ return bRet;
+}
+
+/*
+ * Save all open documents so they will be reopened
+ * the next time the application ist started
+ *
+ * returns sal_True if at least one document could be saved...
+ *
+ */
+
+sal_Bool Desktop::_bTasksSaved = sal_False;
+
+sal_Bool Desktop::SaveTasks()
+{
+ return impl_callRecoveryUI(
+ sal_True , // sal_True => force emergency save
+ sal_False, // 2. and 3. param not used if 1. = true!
+ sal_False);
+}
+
+namespace {
+
+void restartOnMac(bool passArguments) {
+#if defined MACOSX
+ OfficeIPCThread::DisableOfficeIPCThread();
+ rtl::OUString execUrl;
+ OSL_VERIFY(osl_getExecutableFile(&execUrl.pData) == osl_Process_E_None);
+ rtl::OUString execPath;
+ rtl::OString execPath8;
+ if ((osl::FileBase::getSystemPathFromFileURL(execUrl, execPath)
+ != osl::FileBase::E_None) ||
+ !execPath.convertToString(
+ &execPath8, osl_getThreadTextEncoding(),
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
+ {
+ std::abort();
+ }
+ std::vector< rtl::OString > args;
+ args.push_back(execPath8);
+ bool wait = false;
+ if (passArguments) {
+ sal_uInt32 n = osl_getCommandArgCount();
+ for (sal_uInt32 i = 0; i < n; ++i) {
+ rtl::OUString arg;
+ OSL_VERIFY(osl_getCommandArg(i, &arg.pData) == osl_Process_E_None);
+ if (arg.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("-accept="))) {
+ wait = true;
+ }
+ rtl::OString arg8;
+ if (!arg.convertToString(
+ &arg8, osl_getThreadTextEncoding(),
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
+ {
+ std::abort();
+ }
+ args.push_back(arg8);
+ }
+ }
+ std::vector< char const * > argPtrs;
+ for (std::vector< rtl::OString >::iterator i(args.begin()); i != args.end();
+ ++i)
+ {
+ argPtrs.push_back(i->getStr());
+ }
+ argPtrs.push_back(0);
+ execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
+ if (errno == ENOTSUP) { // happens when multithreaded on OS X < 10.6
+ pid_t pid = fork();
+ if (pid == 0) {
+ execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
+ } else if (pid > 0) {
+ // Two simultaneously running soffice processes lead to two dock
+ // icons, so avoid waiting here unless it must be assumed that the
+ // process invoking soffice itself wants to wait for soffice to
+ // finish:
+ if (!wait) {
+ return;
+ }
+ int stat;
+ if (waitpid(pid, &stat, 0) == pid && WIFEXITED(stat)) {
+ _exit(WEXITSTATUS(stat));
+ }
+ }
+ }
+ std::abort();
+#else
+ (void) passArguments; // avoid warnings
+#endif
+}
+
+}
+
+USHORT Desktop::Exception(USHORT nError)
+{
+ // protect against recursive calls
+ static BOOL bInException = FALSE;
+
+ sal_uInt16 nOldMode = Application::GetSystemWindowMode();
+ Application::SetSystemWindowMode( nOldMode & ~SYSTEMWINDOW_MODE_NOAUTOMODE );
+ Application::SetDefDialogParent( NULL );
+
+ if ( bInException )
+ {
+ String aDoubleExceptionString;
+ Application::Abort( aDoubleExceptionString );
+ }
+
+ bInException = TRUE;
+ CommandLineArgs* pArgs = GetCommandLineArgs();
+
+ // save all modified documents ... if it's allowed doing so.
+ sal_Bool bRestart = sal_False;
+ sal_Bool bAllowRecoveryAndSessionManagement = (
+ ( !pArgs->IsNoRestore() ) && // some use cases of office must work without recovery
+ ( !pArgs->IsHeadless() ) &&
+ ( !pArgs->IsServer() ) &&
+ (( nError & EXC_MAJORTYPE ) != EXC_DISPLAY ) && // recovery cant work without UI ... but UI layer seams to be the reason for this crash
+ ( Application::IsInExecute() ) // crashes during startup and shutdown should be ignored (they indicates a corrupt installation ...)
+ );
+ if ( bAllowRecoveryAndSessionManagement )
+ bRestart = SaveTasks();
+
+ FlushConfiguration();
+
+ switch( nError & EXC_MAJORTYPE )
+ {
+ case EXC_RSCNOTLOADED:
+ {
+ String aResExceptionString;
+ Application::Abort( aResExceptionString );
+ break;
+ }
+
+ case EXC_SYSOBJNOTCREATED:
+ {
+ String aSysResExceptionString;
+ Application::Abort( aSysResExceptionString );
+ break;
+ }
+
+ default:
+ {
+ if (m_pLockfile != NULL) {
+ m_pLockfile->clean();
+ }
+ if( bRestart )
+ {
+ OfficeIPCThread::DisableOfficeIPCThread();
+ if( pSignalHandler )
+ DELETEZ( pSignalHandler );
+ restartOnMac(false);
+ _exit( ExitHelper::E_CRASH_WITH_RESTART );
+ }
+ else
+ {
+ Application::Abort( String() );
+ }
+
+ break;
+ }
+ }
+
+ OSL_ASSERT(false); // unreachable
+ return 0;
+}
+
+void Desktop::AppEvent( const ApplicationEvent& rAppEvent )
+{
+ HandleAppEvent( rAppEvent );
+}
+
+void Desktop::Main()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::Main" );
+
+ // Remember current context object
+ com::sun::star::uno::ContextLayer layer(
+ com::sun::star::uno::getCurrentContext() );
+
+ BootstrapError eError = GetBootstrapError();
+ if ( eError != BE_OK )
+ {
+ HandleBootstrapErrors( eError );
+ return;
+ }
+
+ BootstrapStatus eStatus = GetBootstrapStatus();
+ if (eStatus == BS_TERMINATE) {
+ return;
+ }
+
+ // Detect desktop environment - need to do this as early as possible
+ com::sun::star::uno::setCurrentContext(
+ new DesktopContext( com::sun::star::uno::getCurrentContext() ) );
+
+ CommandLineArgs* pCmdLineArgs = GetCommandLineArgs();
+
+ // setup configuration error handling
+ ConfigurationErrorHandler aConfigErrHandler;
+ if (!ShouldSuppressUI(pCmdLineArgs))
+ aConfigErrHandler.activate();
+
+ ResMgr::SetReadStringHook( ReplaceStringHookProc );
+
+ // Startup screen
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main { OpenSplashScreen" );
+ OpenSplashScreen();
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main } OpenSplashScreen" );
+
+ {
+ UserInstall::UserInstallError instErr_fin = UserInstall::finalize();
+ if ( instErr_fin != UserInstall::E_None)
+ {
+ OSL_ENSURE(sal_False, "userinstall failed");
+ if ( instErr_fin == UserInstall::E_NoDiskSpace )
+ HandleBootstrapErrors( BE_USERINSTALL_NOTENOUGHDISKSPACE );
+ else if ( instErr_fin == UserInstall::E_NoWriteAccess )
+ HandleBootstrapErrors( BE_USERINSTALL_NOWRITEACCESS );
+ else
+ HandleBootstrapErrors( BE_USERINSTALL_FAILED );
+ return;
+ }
+ // refresh path information
+ utl::Bootstrap::reloadData();
+ SetSplashScreenProgress(25);
+ }
+
+ Reference< XMultiServiceFactory > xSMgr =
+ ::comphelper::getProcessServiceFactory();
+
+ std::auto_ptr<SvtLanguageOptions> pLanguageOptions;
+ std::auto_ptr<SvtPathOptions> pPathOptions;
+
+ Reference< ::com::sun::star::task::XRestartManager > xRestartManager;
+ sal_Bool bRestartRequested( sal_False );
+ sal_Bool bUseSystemFileDialog(sal_True);
+ int nAcquireCount( 0 );
+ Reference < css::document::XEventListener > xGlobalBroadcaster;
+ try
+ {
+ RegisterServices( xSMgr );
+
+ //SetSplashScreenProgress(15);
+
+#ifndef UNX
+ if ( pCmdLineArgs->IsHelp() ) {
+ displayCmdlineHelp();
+ return;
+ }
+#endif
+
+ // check user installation directory for lockfile so we can be sure
+ // there is no other instance using our data files from a remote host
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main -> Lockfile" );
+ m_pLockfile = new Lockfile;
+ if ( !pCmdLineArgs->IsInvisible() && !pCmdLineArgs->IsNoLockcheck() && !m_pLockfile->check( Lockfile_execWarning )) {
+ // Lockfile exists, and user clicked 'no'
+ return;
+ }
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main <- Lockfile" );
+
+ // check if accessibility is enabled but not working and allow to quit
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ GetEnableATToolSupport" );
+ if( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() )
+ {
+ BOOL bQuitApp;
+
+ if( !InitAccessBridge( true, bQuitApp ) )
+ if( bQuitApp )
+ return;
+ }
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} GetEnableATToolSupport" );
+
+ // terminate if requested...
+ if( pCmdLineArgs->IsTerminateAfterInit() ) return;
+
+
+ // Read the common configuration items for optimization purpose
+ if ( !InitializeConfiguration() ) return;
+
+ //SetSplashScreenProgress(20);
+
+ // set static variable to enabled/disable crash reporter
+ retrieveCrashReporterState();
+ if ( !isCrashReporterEnabled() )
+ {
+ osl_setErrorReporting( sal_False );
+ // disable stack trace feature
+ }
+
+ // create title string
+ sal_Bool bCheckOk = sal_False;
+ ::com::sun::star::lang::Locale aLocale;
+ String aMgrName = String::CreateFromAscii( "iso" );
+ ResMgr* pLabelResMgr = ResMgr::SearchCreateResMgr( U2S( aMgrName ), aLocale );
+ if ( !pLabelResMgr )
+ {
+ // no "iso" resource -> search for "ooo" resource
+ aMgrName = String::CreateFromAscii( "ooo" );
+ pLabelResMgr = ResMgr::SearchCreateResMgr( U2S( aMgrName ), aLocale);
+ }
+ String aTitle = pLabelResMgr ? String( ResId( RID_APPTITLE, *pLabelResMgr ) ) : String();
+ delete pLabelResMgr;
+/*
+ // locale and UI locale in AppSettings are now retrieved from configuration or system directly via SvtSysLocale
+ // no reason to set while starting
+ // set UI language and locale
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ set locale settings" );
+ //LanguageSelection langselect;
+ OUString aUILocaleString = LanguageSelection::getLanguageString();
+ Locale aUILocale = LanguageSelection::IsoStringToLocale(aUILocaleString);
+ LanguageType eLanguage = SvtSysLocale().GetLanguage();
+
+ // #i39040#, do not call anything between GetSettings and SetSettings that might have
+ // a side effect on the settings (like, eg, SvtSysLocaleOptions().GetLocaleLanguageType(),
+ // which changes the MiscSettings !!! )
+ AllSettings aSettings( Application::GetSettings() );
+ aSettings.SetUILocale( aUILocale );
+ aSettings.SetLanguage( eLanguage );
+ Application::SetSettings( aSettings );
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} set locale settings" );
+*/
+
+ // Check for StarOffice/Suite specific extensions runs also with OpenOffice installation sets
+ OUString aTitleString( aTitle );
+ bCheckOk = CheckInstallation( aTitleString );
+ if ( !bCheckOk )
+ return;
+ else
+ aTitle = aTitleString;
+
+#ifdef DBG_UTIL
+ //include version ID in non product builds
+ ::rtl::OUString aDefault;
+ aTitle += DEFINE_CONST_UNICODE(" [");
+ String aVerId( utl::Bootstrap::getBuildIdData( aDefault ));
+ aTitle += aVerId;
+ aTitle += ']';
+#endif
+
+ SetDisplayName( aTitle );
+// SetSplashScreenProgress(30);
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ create SvtPathOptions and SvtLanguageOptions" );
+ pPathOptions.reset( new SvtPathOptions);
+// SetSplashScreenProgress(40);
+// pLanguageOptions = new SvtLanguageOptions(sal_True);
+// SetSplashScreenProgress(45);
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} create SvtPathOptions and SvtLanguageOptions" );
+
+ // Check special env variable #111015#
+ std::vector< String > aUnrestrictedFolders;
+ svt::getUnrestrictedFolders( aUnrestrictedFolders );
+
+ if ( aUnrestrictedFolders.size() > 0 )
+ {
+ // Set different working directory. The first entry is
+ // the new work path.
+ String aWorkPath = aUnrestrictedFolders[0];
+ SvtPathOptions().SetWorkPath( aWorkPath );
+ }
+
+ // create service for loadin SFX (still needed in startup)
+ xGlobalBroadcaster = Reference < css::document::XEventListener >
+ ( xSMgr->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.frame.GlobalEventBroadcaster" ) ), UNO_QUERY );
+
+ /* ensure existance of a default window that messages can be dispatched to
+ This is for the benefit of testtool which uses PostUserEvent extensively
+ and else can deadlock while creating this window from another tread while
+ the main thread is not yet in the event loop.
+ */
+ Application::GetDefaultDevice();
+
+ // initialize test-tool library (if available)
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ tools::InitTestToolLib" );
+ tools::InitTestToolLib();
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} tools::InitTestToolLib" );
+
+ // Check if bundled or shared extensions were added /removed
+ // and process those extensions (has to be done before checking
+ // the extension dependencies!
+ SynchronizeExtensionRepositories();
+ bool bAbort = CheckExtensionDependencies();
+ if ( bAbort )
+ return;
+ // First Start Wizard allowed ?
+ if ( ! pCmdLineArgs->IsNoFirstStartWizard())
+ {
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ FirstStartWizard" );
+
+ if (IsFirstStartWizardNeeded())
+ {
+ ::utl::RegOptions().removeReminder(); // remove patch registration reminder
+ Reference< XJob > xFirstStartJob( xSMgr->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.comp.desktop.FirstStart" ) ), UNO_QUERY );
+ if (xFirstStartJob.is())
+ {
+ sal_Bool bDone = sal_False;
+ Sequence< NamedValue > lArgs(2);
+ lArgs[0].Name = ::rtl::OUString::createFromAscii("LicenseNeedsAcceptance");
+ lArgs[0].Value <<= LicenseNeedsAcceptance();
+ lArgs[1].Name = ::rtl::OUString::createFromAscii("LicensePath");
+ lArgs[1].Value <<= GetLicensePath();
+
+ xFirstStartJob->execute(lArgs) >>= bDone;
+ if ( !bDone )
+ {
+ return;
+ }
+ }
+ }
+ else if ( RegistrationPage::hasReminderDateCome() )
+ RegistrationPage::executeSingleMode();
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} FirstStartWizard" );
+ }
+
+ // keep a language options instance...
+ pLanguageOptions.reset( new SvtLanguageOptions(sal_True));
+
+ if (xGlobalBroadcaster.is())
+ {
+ css::document::EventObject aEvent;
+ aEvent.EventName = ::rtl::OUString::createFromAscii("OnStartApp");
+ xGlobalBroadcaster->notifyEvent(aEvent);
+ }
+
+ SetSplashScreenProgress(50);
+ // Backing Component
+ sal_Bool bCrashed = sal_False;
+ sal_Bool bExistsRecoveryData = sal_False;
+ sal_Bool bExistsSessionData = sal_False;
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ impl_checkRecoveryState" );
+ impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} impl_checkRecoveryState" );
+
+ {
+ ::comphelper::ComponentContext aContext( xSMgr );
+ xRestartManager.set( aContext.getSingleton( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) ) ), UNO_QUERY );
+ }
+
+ // check whether the shutdown is caused by restart
+ bRestartRequested = ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) );
+
+ if ( pCmdLineArgs->IsHeadless() )
+ {
+ // Ensure that we use not the system file dialogs as
+ // headless mode relies on Application::EnableHeadlessMode()
+ // which does only work for VCL dialogs!!
+ SvtMiscOptions aMiscOptions;
+ bUseSystemFileDialog = aMiscOptions.UseSystemFileDialog();
+ aMiscOptions.SetUseSystemFileDialog( sal_False );
+ }
+
+ if ( !bRestartRequested )
+ {
+ if (
+ (pCmdLineArgs->IsEmptyOrAcceptOnly() ) &&
+ (SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE)) &&
+ (!bExistsRecoveryData ) &&
+ (!bExistsSessionData ) &&
+ (!Application::AnyInput( INPUT_APPEVENT ) )
+ )
+ {
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ create BackingComponent" );
+ Reference< XFrame > xDesktopFrame( xSMgr->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY );
+ if (xDesktopFrame.is())
+ {
+ // SetSplashScreenProgress(60);
+ Reference< XFrame > xBackingFrame;
+ Reference< ::com::sun::star::awt::XWindow > xContainerWindow;
+
+ xBackingFrame = xDesktopFrame->findFrame(OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" )), 0);
+ if (xBackingFrame.is())
+ xContainerWindow = xBackingFrame->getContainerWindow();
+ if (xContainerWindow.is())
+ {
+ // set the WB_EXT_DOCUMENT style. Normally, this is done by the TaskCreator service when a "_blank"
+ // frame/window is created. Since we do not use the TaskCreator here, we need to mimic its behavior,
+ // otherwise documents loaded into this frame will later on miss functionality depending on the style.
+ Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
+ OSL_ENSURE( pContainerWindow, "Desktop::Main: no implementation access to the frame's container window!" );
+ pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WB_EXT_DOCUMENT );
+
+ SetSplashScreenProgress(75);
+ Sequence< Any > lArgs(1);
+ lArgs[0] <<= xContainerWindow;
+
+ Reference< XController > xBackingComp(
+ xSMgr->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule") ), lArgs),
+ UNO_QUERY);
+ // SetSplashScreenProgress(80);
+ if (xBackingComp.is())
+ {
+ Reference< ::com::sun::star::awt::XWindow > xBackingWin(xBackingComp, UNO_QUERY);
+ // Attention: You MUST(!) call setComponent() before you call attachFrame().
+ // Because the backing component set the property "IsBackingMode" of the frame
+ // to true inside attachFrame(). But setComponent() reset this state everytimes ...
+ xBackingFrame->setComponent(xBackingWin, xBackingComp);
+ SetSplashScreenProgress(100);
+ xBackingComp->attachFrame(xBackingFrame);
+ CloseSplashScreen();
+ xContainerWindow->setVisible(sal_True);
+ }
+ }
+ }
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "} create BackingComponent" );
+ }
+ }
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& wte )
+ {
+ com::sun::star::uno::Exception te;
+ wte.TargetException >>= te;
+ FatalError( MakeStartupConfigAccessErrorMessage(wte.Message + te.Message) );
+ return;
+ }
+ catch ( com::sun::star::uno::Exception& e )
+ {
+ FatalError( MakeStartupErrorMessage(e.Message) );
+ return;
+ }
+ /*
+ catch ( ... )
+ {
+ FatalError( MakeStartupErrorMessage(
+ OUString::createFromAscii(
+ "Unknown error during startup (Office wrapper service).\nInstallation could be damaged.")));
+ return;
+ }
+ */
+// SetSplashScreenProgress(55);
+
+ SvtFontSubstConfig().Apply();
+
+ SvtTabAppearanceCfg aAppearanceCfg;
+ aAppearanceCfg.SetInitialized();
+ aAppearanceCfg.SetApplicationDefaults( this );
+ SvtAccessibilityOptions aOptions;
+ aOptions.SetVCLSettings();
+// SetSplashScreenProgress(60);
+
+ if ( !bRestartRequested )
+ {
+ Application::SetFilterHdl( LINK( this, Desktop, ImplInitFilterHdl ) );
+
+ sal_Bool bTerminateRequested = sal_False;
+
+ // Preload function depends on an initialized sfx application!
+ SetSplashScreenProgress(75);
+
+ // use system window dialogs
+ Application::SetSystemWindowMode( SYSTEMWINDOW_MODE_DIALOG );
+
+ // SetSplashScreenProgress(80);
+
+ if ( !bTerminateRequested && !pCmdLineArgs->IsInvisible() &&
+ !pCmdLineArgs->IsNoQuickstart() )
+ InitializeQuickstartMode( xSMgr );
+
+ RTL_LOGFILE_CONTEXT( aLog2, "desktop (cd100003) createInstance com.sun.star.frame.Desktop" );
+ try
+ {
+ Reference< XDesktop > xDesktop( xSMgr->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY );
+ if ( xDesktop.is() )
+ xDesktop->addTerminateListener( new OfficeIPCThreadController );
+ SetSplashScreenProgress(100);
+ }
+ catch ( com::sun::star::uno::Exception& e )
+ {
+ FatalError( MakeStartupErrorMessage(e.Message) );
+ return;
+ }
+ /*
+ catch ( ... )
+ {
+ FatalError( MakeStartupErrorMessage(
+ OUString::createFromAscii(
+ "Unknown error during startup (TD/Desktop service).\nInstallation could be damaged.")));
+ return;
+ }
+ */
+
+ // Post user event to startup first application component window
+ // We have to send this OpenClients message short before execute() to
+ // minimize the risk that this message overtakes type detection contruction!!
+ Application::PostUserEvent( LINK( this, Desktop, OpenClients_Impl ) );
+
+ // Post event to enable acceptors
+ Application::PostUserEvent( LINK( this, Desktop, EnableAcceptors_Impl) );
+
+ // The configuration error handler currently is only for startup
+ aConfigErrHandler.deactivate();
+
+ // Acquire solar mutex just before we enter our message loop
+ if ( nAcquireCount )
+ Application::AcquireSolarMutex( nAcquireCount );
+
+ // call Application::Execute to process messages in vcl message loop
+ RTL_LOGFILE_PRODUCT_TRACE( "PERFORMANCE - enter Application::Execute()" );
+
+ try
+ {
+ // The JavaContext contains an interaction handler which is used when
+ // the creation of a Java Virtual Machine fails
+ com::sun::star::uno::ContextLayer layer2(
+ new svt::JavaContext( com::sun::star::uno::getCurrentContext() ) );
+
+ // check whether the shutdown is caused by restart just before entering the Execute
+ bRestartRequested = bRestartRequested || ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) );
+
+ if ( !bRestartRequested )
+ {
+ // if this run of the office is triggered by restart, some additional actions should be done
+ DoRestartActionsIfNecessary( !pCmdLineArgs->IsInvisible() && !pCmdLineArgs->IsNoQuickstart() );
+
+ Execute();
+ }
+ }
+ catch(const com::sun::star::document::CorruptedFilterConfigurationException& exFilterCfg)
+ {
+ OfficeIPCThread::SetDowning();
+ FatalError( MakeStartupErrorMessage(exFilterCfg.Message) );
+ }
+ catch(const com::sun::star::configuration::CorruptedConfigurationException& exAnyCfg)
+ {
+ OfficeIPCThread::SetDowning();
+ FatalError( MakeStartupErrorMessage(exAnyCfg.Message) );
+ }
+ }
+
+ if ( bRestartRequested )
+ SetRestartState();
+
+ if (xGlobalBroadcaster.is())
+ {
+ css::document::EventObject aEvent;
+ aEvent.EventName = ::rtl::OUString::createFromAscii("OnCloseApp");
+ xGlobalBroadcaster->notifyEvent(aEvent);
+ }
+
+ delete pResMgr;
+ // Restore old value
+ if ( pCmdLineArgs->IsHeadless() )
+ SvtMiscOptions().SetUseSystemFileDialog( bUseSystemFileDialog );
+
+ // remove temp directory
+ RemoveTemporaryDirectory();
+ FlushConfiguration();
+ // The acceptors in the AcceptorMap must be released (in DeregisterServices)
+ // with the solar mutex unlocked, to avoid deadlock:
+ nAcquireCount = Application::ReleaseSolarMutex();
+ DeregisterServices();
+ Application::AcquireSolarMutex(nAcquireCount);
+ tools::DeInitTestToolLib();
+ // be sure that path/language options gets destroyed before
+ // UCB is deinitialized
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "-> dispose path/language options" );
+ pLanguageOptions.reset( 0 );
+ pPathOptions.reset( 0 );
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- dispose path/language options" );
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "-> deinit ucb" );
+ ::ucbhelper::ContentBroker::deinitialize();
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- deinit ucb" );
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "FINISHED WITH Destop::Main" );
+ if ( bRestartRequested )
+ {
+ restartOnMac(true);
+ // wouldn't the solution be more clean if SalMain returns the exit code to the system?
+ _exit( ExitHelper::E_NORMAL_RESTART );
+ }
+}
+
+IMPL_LINK( Desktop, ImplInitFilterHdl, ConvertData*, pData )
+{
+ return GraphicFilter::GetGraphicFilter()->GetFilterCallback().Call( pData );
+}
+
+sal_Bool Desktop::InitializeConfiguration()
+{
+ sal_Bool bOk = sal_False;
+
+ try
+ {
+ bOk = InitConfiguration();
+ }
+ catch( ::com::sun::star::lang::ServiceNotRegisteredException& )
+ {
+ this->HandleBootstrapErrors( Desktop::BE_UNO_SERVICE_CONFIG_MISSING );
+ }
+ catch( ::com::sun::star::configuration::MissingBootstrapFileException& e )
+ {
+ OUString aMsg( CreateErrorMsgString( utl::Bootstrap::MISSING_BOOTSTRAP_FILE,
+ e.BootstrapFileURL ));
+ HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_USER_INSTALL, aMsg );
+ }
+ catch( ::com::sun::star::configuration::InvalidBootstrapFileException& e )
+ {
+ OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY,
+ e.BootstrapFileURL ));
+ HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
+ }
+ catch( ::com::sun::star::configuration::InstallationIncompleteException& )
+ {
+ OUString aVersionFileURL;
+ OUString aMsg;
+ utl::Bootstrap::PathStatus aPathStatus = utl::Bootstrap::locateVersionFile( aVersionFileURL );
+ if ( aPathStatus == utl::Bootstrap::PATH_EXISTS )
+ aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE_ENTRY, aVersionFileURL );
+ else
+ aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE, aVersionFileURL );
+
+ HandleBootstrapPathErrors( ::utl::Bootstrap::MISSING_USER_INSTALL, aMsg );
+ }
+ catch ( com::sun::star::configuration::backend::BackendAccessException& exception)
+ {
+ // [cm122549] It is assumed in this case that the message
+ // coming from InitConfiguration (in fact CreateApplicationConf...)
+ // is suitable for display directly.
+ FatalError( MakeStartupErrorMessage( exception.Message ) );
+ }
+ catch ( com::sun::star::configuration::backend::BackendSetupException& exception)
+ {
+ // [cm122549] It is assumed in this case that the message
+ // coming from InitConfiguration (in fact CreateApplicationConf...)
+ // is suitable for display directly.
+ FatalError( MakeStartupErrorMessage( exception.Message ) );
+ }
+ catch ( ::com::sun::star::configuration::CannotLoadConfigurationException& )
+ {
+ OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
+ OUString() ));
+ HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
+ OUString() ));
+ HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
+ }
+
+ return bOk;
+}
+
+void Desktop::FlushConfiguration()
+{
+ Reference < XFlushable > xCFGFlush( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
+ if (xCFGFlush.is())
+ {
+ xCFGFlush->flush();
+ }
+ else
+ {
+ // because there is no method to flush the condiguration data, we must dispose the ConfigManager
+ Reference < XComponent > xCFGDispose( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
+ if (xCFGDispose.is())
+ xCFGDispose->dispose();
+ }
+}
+
+sal_Bool Desktop::InitializeQuickstartMode( Reference< XMultiServiceFactory >& rSMgr )
+{
+ try
+ {
+ // the shutdown icon sits in the systray and allows the user to keep
+ // the office instance running for quicker restart
+ // this will only be activated if -quickstart was specified on cmdline
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) createInstance com.sun.star.office.Quickstart" );
+
+ sal_Bool bQuickstart = GetCommandLineArgs()->IsQuickstart();
+ Sequence< Any > aSeq( 1 );
+ aSeq[0] <<= bQuickstart;
+
+ // Try to instanciate quickstart service. This service is not mandatory, so
+ // do nothing if service is not available
+
+ // #i105753# the following if was invented for performance
+ // unfortunately this broke the QUARTZ behavior which is to always run
+ // in quickstart mode since Mac applications do not usually quit
+ // when the last document closes
+ #ifndef QUARTZ
+ if ( bQuickstart )
+ #endif
+ {
+ Reference < XComponent > xQuickstart( rSMgr->createInstanceWithArguments(
+ DEFINE_CONST_UNICODE( "com.sun.star.office.Quickstart" ), aSeq ),
+ UNO_QUERY );
+ }
+ return sal_True;
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ return sal_False;
+ }
+}
+
+void Desktop::SystemSettingsChanging( AllSettings& rSettings, Window* )
+{
+ if ( !SvtTabAppearanceCfg::IsInitialized () )
+ return;
+
+# define DRAGFULL_OPTION_ALL \
+ ( DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE \
+ | DRAGFULL_OPTION_OBJECTMOVE | DRAGFULL_OPTION_OBJECTSIZE \
+ | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT \
+ | DRAGFULL_OPTION_SCROLL )
+# define DRAGFULL_OPTION_NONE ((sal_uInt32)~DRAGFULL_OPTION_ALL)
+
+ StyleSettings hStyleSettings = rSettings.GetStyleSettings();
+ MouseSettings hMouseSettings = rSettings.GetMouseSettings();
+
+ sal_uInt32 nDragFullOptions = hStyleSettings.GetDragFullOptions();
+
+ SvtTabAppearanceCfg aAppearanceCfg;
+ sal_uInt16 nGet = aAppearanceCfg.GetDragMode();
+ switch ( nGet )
+ {
+ case DragFullWindow:
+ nDragFullOptions |= DRAGFULL_OPTION_ALL;
+ break;
+ case DragFrame:
+ nDragFullOptions &= DRAGFULL_OPTION_NONE;
+ break;
+ case DragSystemDep:
+ default:
+ break;
+ }
+
+ sal_uInt32 nFollow = hMouseSettings.GetFollow();
+ hMouseSettings.SetFollow( aAppearanceCfg.IsMenuMouseFollow() ? (nFollow|MOUSE_FOLLOW_MENU) : (nFollow&~MOUSE_FOLLOW_MENU));
+ rSettings.SetMouseSettings(hMouseSettings);
+
+ BOOL bUseImagesInMenus = hStyleSettings.GetUseImagesInMenus();
+
+ SvtMenuOptions aMenuOpt;
+ nGet = aMenuOpt.GetMenuIconsState();
+ switch ( nGet )
+ {
+ case 0:
+ bUseImagesInMenus = FALSE;
+ break;
+ case 1:
+ bUseImagesInMenus = TRUE;
+ break;
+ case 2:
+ default:
+ break;
+ }
+ hStyleSettings.SetUseImagesInMenus(bUseImagesInMenus);
+
+ sal_uInt16 nTabStyle = hStyleSettings.GetTabControlStyle();
+ nTabStyle &= ~STYLE_TABCONTROL_SINGLELINE;
+ if( aAppearanceCfg.IsSingleLineTabCtrl() )
+ nTabStyle |=STYLE_TABCONTROL_SINGLELINE;
+
+ nTabStyle &= ~STYLE_TABCONTROL_COLOR;
+ if( aAppearanceCfg.IsColoredTabCtrl() )
+ nTabStyle |= STYLE_TABCONTROL_COLOR;
+
+ hStyleSettings.SetTabControlStyle(nTabStyle);
+
+ hStyleSettings.SetDragFullOptions( nDragFullOptions );
+ rSettings.SetStyleSettings ( hStyleSettings );
+}
+
+// ========================================================================
+IMPL_LINK( Desktop, AsyncInitFirstRun, void*, EMPTYARG )
+{
+ DoFirstRunInitializations();
+ return 0L;
+}
+
+// ========================================================================
+
+class ExitTimer : public Timer
+{
+ public:
+ ExitTimer()
+ {
+ SetTimeout(500);
+ Start();
+ }
+ virtual void Timeout()
+ {
+ exit(42);
+ }
+};
+
+IMPL_LINK( Desktop, OpenClients_Impl, void*, EMPTYARG )
+{
+ RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "PERFORMANCE - DesktopOpenClients_Impl()" );
+
+ OpenClients();
+
+ OfficeIPCThread::SetReady();
+
+ // CloseStartupScreen();
+ CloseSplashScreen();
+
+ CheckFirstRun( );
+
+ // allow ipc interaction
+// OfficeIPCThread::SetReady();
+
+ EnableOleAutomation();
+
+ if (getenv ("OOO_EXIT_POST_STARTUP"))
+ new ExitTimer();
+ return 0;
+}
+
+// enable acceptos
+IMPL_LINK( Desktop, EnableAcceptors_Impl, void*, EMPTYARG )
+{
+ enableAcceptors();
+ return 0;
+}
+
+
+// Registers a COM class factory of the service manager with the windows operating system.
+void Desktop::EnableOleAutomation()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (jl97489) ::Desktop::EnableOleAutomation" );
+#ifdef WNT
+ Reference< XMultiServiceFactory > xSMgr= comphelper::getProcessServiceFactory();
+ xSMgr->createInstance(DEFINE_CONST_UNICODE("com.sun.star.bridge.OleApplicationRegistration"));
+ xSMgr->createInstance(DEFINE_CONST_UNICODE("com.sun.star.comp.ole.EmbedServer"));
+#endif
+}
+
+sal_Bool Desktop::CheckOEM()
+{
+ Reference<XMultiServiceFactory> rFactory = ::comphelper::getProcessServiceFactory();
+ Reference<XJob> rOemJob(rFactory->createInstance(
+ OUString::createFromAscii("com.sun.star.office.OEMPreloadJob")),
+ UNO_QUERY );
+ Sequence<NamedValue> args;
+ sal_Bool bResult = sal_False;
+ if (rOemJob.is()) {
+ Any aResult = rOemJob->execute(args);
+ aResult >>= bResult;
+ return bResult;
+ } else {
+ return sal_True;
+ }
+}
+
+void Desktop::PreloadModuleData( CommandLineArgs* pArgs )
+{
+ Reference< XMultiServiceFactory > rFactory = ::comphelper::getProcessServiceFactory();
+
+ Sequence < com::sun::star::beans::PropertyValue > args(1);
+ args[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Hidden"));
+ args[0].Value <<= sal_True;
+ Reference < XComponentLoader > xLoader( ::comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ), UNO_QUERY );
+
+ if ( !xLoader.is() )
+ return;
+
+ if ( pArgs->IsWriter() )
+ {
+ try
+ {
+ Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/swriter"),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
+ xDoc->close( sal_False );
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ if ( pArgs->IsCalc() )
+ {
+ try
+ {
+ Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/scalc"),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
+ xDoc->close( sal_False );
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ if ( pArgs->IsDraw() )
+ {
+ try
+ {
+ Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/sdraw"),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
+ xDoc->close( sal_False );
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ if ( pArgs->IsImpress() )
+ {
+ try
+ {
+ Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/simpress"),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
+ xDoc->close( sal_False );
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+}
+
+void Desktop::PreloadConfigurationData()
+{
+ Reference< XMultiServiceFactory > rFactory = ::comphelper::getProcessServiceFactory();
+ Reference< XNameAccess > xNameAccess( rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.frame.UICommandDescription" )), UNO_QUERY );
+
+ rtl::OUString aWriterDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" ));
+ rtl::OUString aCalcDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocument" ));
+ rtl::OUString aDrawDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" ));
+ rtl::OUString aImpressDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ));
+
+ // preload commands configuration
+ if ( xNameAccess.is() )
+ {
+ Any a;
+ Reference< XNameAccess > xCmdAccess;
+
+ try
+ {
+ a = xNameAccess->getByName( aWriterDoc );
+ a >>= xCmdAccess;
+ if ( xCmdAccess.is() )
+ {
+ xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:BasicShapes" ));
+ xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:EditGlossary" ));
+ }
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ try
+ {
+ a = xNameAccess->getByName( aCalcDoc );
+ a >>= xCmdAccess;
+ if ( xCmdAccess.is() )
+ xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:InsertObjectStarMath" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ try
+ {
+ // draw and impress share the same configuration file (DrawImpressCommands.xcu)
+ a = xNameAccess->getByName( aDrawDoc );
+ a >>= xCmdAccess;
+ if ( xCmdAccess.is() )
+ xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:Polygon" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ // preload window state configuration
+ xNameAccess = Reference< XNameAccess >( rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.ui.WindowStateConfiguration" )), UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ Any a;
+ Reference< XNameAccess > xWindowAccess;
+ try
+ {
+ a = xNameAccess->getByName( aWriterDoc );
+ a >>= xWindowAccess;
+ if ( xWindowAccess.is() )
+ xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ try
+ {
+ a = xNameAccess->getByName( aCalcDoc );
+ a >>= xWindowAccess;
+ if ( xWindowAccess.is() )
+ xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ try
+ {
+ a = xNameAccess->getByName( aDrawDoc );
+ a >>= xWindowAccess;
+ if ( xWindowAccess.is() )
+ xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ try
+ {
+ a = xNameAccess->getByName( aImpressDoc );
+ a >>= xWindowAccess;
+ if ( xWindowAccess.is() )
+ xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ // preload user interface element factories
+ Sequence< Sequence< css::beans::PropertyValue > > aSeqSeqPropValue;
+ Reference< ::com::sun::star::ui::XUIElementFactoryRegistration > xUIElementFactory(
+ rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.ui.UIElementFactoryManager" )),
+ UNO_QUERY );
+ if ( xUIElementFactory.is() )
+ {
+ try
+ {
+ aSeqSeqPropValue = xUIElementFactory->getRegisteredFactories();
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ // preload popup menu controller factories. As all controllers are in the same
+ // configuration file they also get preloaded!
+ Reference< ::com::sun::star::frame::XUIControllerRegistration > xPopupMenuControllerFactory(
+ rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.frame.PopupMenuControllerFactory" )),
+ UNO_QUERY );
+ if ( xPopupMenuControllerFactory.is() )
+ {
+ try
+ {
+ xPopupMenuControllerFactory->hasController(
+ DEFINE_CONST_UNICODE( ".uno:CharFontName" ),
+ OUString() );
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ // preload filter configuration
+ Sequence< OUString > aSeq;
+ xNameAccess = Reference< XNameAccess >( rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" )), UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ try
+ {
+ aSeq = xNameAccess->getElementNames();
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ // preload type detection configuration
+ xNameAccess = Reference< XNameAccess >( rFactory->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.document.TypeDetection" )), UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ try
+ {
+ aSeq = xNameAccess->getElementNames();
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
+ static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) );
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > xConfigProvider;
+ xConfigProvider = Reference< XMultiServiceFactory > (
+ rFactory->createInstance( sConfigSrvc ),UNO_QUERY );
+
+ if ( xConfigProvider.is() )
+ {
+ // preload writer configuration
+ Sequence< Any > theArgs(1);
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Writer/MailMergeWizard" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // WriterWeb
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.WriterWeb/Content" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload compatibility
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Compatibility/WriterCompatibilityVersion" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload calc configuration
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Calc/Content" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload impress configuration
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.UI.Effects/UserInterface" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Impress/Layout" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload draw configuration
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Draw/Layout" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload ui configuration
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.UI/FilterClassification" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+
+ // preload addons configuration
+ theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Addons/AddonUI" );
+ try
+ {
+ xNameAccess = Reference< XNameAccess >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
+ }
+ catch (::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+}
+
+void Desktop::OpenClients()
+{
+
+ // check if a document has been recovered - if there is one of if a document was loaded by cmdline, no default document
+ // should be created
+ Reference < XComponent > xFirst;
+ BOOL bLoaded = FALSE;
+
+ CommandLineArgs* pArgs = GetCommandLineArgs();
+ SvtInternalOptions aInternalOptions;
+
+ Reference<XMultiServiceFactory> rFactory = ::comphelper::getProcessServiceFactory();
+
+ if (!pArgs->IsQuickstart()) {
+ sal_Bool bShowHelp = sal_False;
+ ::rtl::OUStringBuffer aHelpURLBuffer;
+ if (pArgs->IsHelpWriter()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://swriter/start");
+ } else if (pArgs->IsHelpCalc()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://scalc/start");
+ } else if (pArgs->IsHelpDraw()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdraw/start");
+ } else if (pArgs->IsHelpImpress()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://simpress/start");
+ } else if (pArgs->IsHelpBase()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdatabase/start");
+ } else if (pArgs->IsHelpBasic()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sbasic/start");
+ } else if (pArgs->IsHelpMath()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://smath/start");
+ }
+ if (bShowHelp) {
+ Help *pHelp = Application::GetHelp();
+
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::LOCALE );
+ rtl::OUString aTmp;
+ aRet >>= aTmp;
+ aHelpURLBuffer.appendAscii("?Language=");
+ aHelpURLBuffer.append(aTmp);
+#if defined UNX
+ aHelpURLBuffer.appendAscii("&System=UNX");
+#elif defined WNT
+ aHelpURLBuffer.appendAscii("&System=WIN");
+#elif defined MAC
+ aHelpURLBuffer.appendAscii("&System=MAC");
+#elif defined OS2
+ aHelpURLBuffer.appendAscii("&System=OS2");
+#endif
+ pHelp->Start(aHelpURLBuffer.makeStringAndClear(), NULL);
+ return;
+ }
+ }
+ else
+ {
+ OUString aIniName;
+ ::vos::OStartupInfo aInfo;
+
+ aInfo.getExecutableFile( aIniName );
+ sal_uInt32 lastIndex = aIniName.lastIndexOf('/');
+ if ( lastIndex > 0 )
+ {
+ aIniName = aIniName.copy( 0, lastIndex+1 );
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "perftune" ));
+#if defined(WNT) || defined(OS2)
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( ".ini" ));
+#else
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "rc" ));
+#endif
+ }
+
+ rtl::Bootstrap aPerfTuneIniFile( aIniName );
+
+ OUString aDefault( RTL_CONSTASCII_USTRINGPARAM( "0" ));
+ OUString aPreloadData;
+
+ aPerfTuneIniFile.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "QuickstartPreloadConfiguration" )), aPreloadData, aDefault );
+ if ( aPreloadData.equalsAscii( "1" ))
+ {
+ if ( pArgs->IsWriter() ||
+ pArgs->IsCalc() ||
+ pArgs->IsDraw() ||
+ pArgs->IsImpress() )
+ {
+ PreloadModuleData( pArgs );
+ }
+
+ PreloadConfigurationData();
+ }
+ }
+
+ // Disable AutoSave feature in case "-norestore" or a similare command line switch is set on the command line.
+ // The reason behind: AutoSave/EmergencySave/AutoRecovery share the same data.
+ // But the require that all documents, which are saved as backup should exists inside
+ // memory. May be this mechanism will be inconsistent if the configuration exists ...
+ // but no document inside memory corrspond to this data.
+ // Furter it's not acceptable to recover such documents without any UI. It can
+ // need some time, where the user wont see any results and wait for finishing the office startup ...
+ sal_Bool bAllowRecoveryAndSessionManagement = (
+ ( !pArgs->IsNoRestore() ) &&
+ ( !pArgs->IsHeadless() ) &&
+ ( !pArgs->IsServer() )
+ );
+
+ if ( ! bAllowRecoveryAndSessionManagement )
+ {
+ /*
+ ::comphelper::ConfigurationHelper::writeDirectKey(
+ ::comphelper::getProcessServiceFactory(),
+ ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery"),
+ ::rtl::OUString::createFromAscii("AutoSave"),
+ ::rtl::OUString::createFromAscii("Enabled"),
+ ::com::sun::star::uno::makeAny(sal_False),
+ ::comphelper::ConfigurationHelper::E_STANDARD);
+
+ */
+ try
+ {
+ Reference< XDispatch > xRecovery(
+ ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.AutoRecovery")) ),
+ ::com::sun::star::uno::UNO_QUERY_THROW );
+
+ Reference< XURLTransformer > xParser(
+ ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ),
+ ::com::sun::star::uno::UNO_QUERY_THROW );
+
+ css::util::URL aCmd;
+ aCmd.Complete = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/disableRecovery");
+ xParser->parseStrict(aCmd);
+
+ xRecovery->dispatch(aCmd, css::uno::Sequence< css::beans::PropertyValue >());
+ }
+ catch(const css::uno::Exception& e)
+ {
+ OUString aMessage = OUString::createFromAscii("Could not disable AutoRecovery.\n")
+ + e.Message;
+ OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ }
+ else
+ {
+ sal_Bool bCrashed = sal_False;
+ sal_Bool bExistsRecoveryData = sal_False;
+ sal_Bool bExistsSessionData = sal_False;
+
+ impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
+
+ if ( !getenv ("OOO_DISABLE_RECOVERY") &&
+ ( ! bLoaded ) &&
+ (
+ ( bExistsRecoveryData ) || // => crash with files => recovery
+ ( bCrashed ) // => crash without files => error report
+ )
+ )
+ {
+ try
+ {
+ impl_callRecoveryUI(
+ sal_False , // false => force recovery instead of emergency save
+ bCrashed ,
+ bExistsRecoveryData);
+ /* TODO we cant be shure, that at least one document could be recovered here successfully
+ So we set bLoaded=TRUE to supress opening of the default document.
+ But we should make it more safe. Otherwhise we have an office without an UI ...
+ ...
+ May be we can check the desktop if some documents are existing there.
+ */
+ Reference< XFramesSupplier > xTasksSupplier(
+ ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ ::com::sun::star::uno::UNO_QUERY_THROW );
+ Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY_THROW );
+ if ( xList->hasElements() )
+ bLoaded = sal_True;
+ }
+ catch(const css::uno::Exception& e)
+ {
+ OUString aMessage = OUString::createFromAscii("Error during recovery\n")
+ + e.Message;
+ OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ }
+
+ Reference< XInitialization > xSessionListener;
+ try
+ {
+ xSessionListener = Reference< XInitialization >(::comphelper::getProcessServiceFactory()->createInstance(
+ OUString::createFromAscii("com.sun.star.frame.SessionListener")), UNO_QUERY_THROW);
+
+ // specifies whether the UI-interaction on Session shutdown is allowed
+ sal_Bool bAllowUI = isUIOnSessionShutdownAllowed();
+ css::beans::NamedValue aProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowUserInteractionOnQuit" ) ),
+ css::uno::makeAny( bAllowUI ) );
+ css::uno::Sequence< css::uno::Any > aArgs( 1 );
+ aArgs[0] <<= aProperty;
+
+ xSessionListener->initialize( aArgs );
+ }
+ catch(const com::sun::star::uno::Exception& e)
+ {
+ OUString aMessage = OUString::createFromAscii("Registration of session listener failed\n")
+ + e.Message;
+ OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+
+ if (
+ ( ! bLoaded ) &&
+ ( bExistsSessionData )
+ )
+ {
+ // session management
+ try
+ {
+ Reference< XSessionManagerListener > r(xSessionListener, UNO_QUERY_THROW);
+ bLoaded = r->doRestore();
+ }
+ catch(const com::sun::star::uno::Exception& e)
+ {
+ OUString aMessage = OUString::createFromAscii("Error in session management\n")
+ + e.Message;
+ OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ }
+ }
+
+ OfficeIPCThread::EnableRequests();
+
+ sal_Bool bShutdown( sal_False );
+ if ( !pArgs->IsServer() )
+ {
+ ProcessDocumentsRequest aRequest(pArgs->getCwdUrl());
+ aRequest.pcProcessed = NULL;
+
+ pArgs->GetOpenList( aRequest.aOpenList );
+ pArgs->GetViewList( aRequest.aViewList );
+ pArgs->GetStartList( aRequest.aStartList );
+ pArgs->GetPrintList( aRequest.aPrintList );
+ pArgs->GetPrintToList( aRequest.aPrintToList );
+ pArgs->GetPrinterName( aRequest.aPrinterName );
+ pArgs->GetForceOpenList( aRequest.aForceOpenList );
+ pArgs->GetForceNewList( aRequest.aForceNewList );
+
+ if ( aRequest.aOpenList.getLength() > 0 ||
+ aRequest.aViewList.getLength() > 0 ||
+ aRequest.aStartList.getLength() > 0 ||
+ aRequest.aPrintList.getLength() > 0 ||
+ aRequest.aForceOpenList.getLength() > 0 ||
+ aRequest.aForceNewList.getLength() > 0 ||
+ ( aRequest.aPrintToList.getLength() > 0 && aRequest.aPrinterName.getLength() > 0 ))
+ {
+ bLoaded = sal_True;
+
+ if ( pArgs->HasModuleParam() )
+ {
+ SvtModuleOptions aOpt;
+
+ // Support command line parameters to start a module (as preselection)
+ if ( pArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::E_WRITER );
+ else if ( pArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
+ aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::E_CALC );
+ else if ( pArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
+ aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::E_IMPRESS );
+ else if ( pArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
+ aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::E_DRAW );
+ }
+
+ // check for printing disabled
+ if( ( aRequest.aPrintList.getLength() || aRequest.aPrintToList.getLength() )
+ && Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
+ {
+ aRequest.aPrintList = rtl::OUString();
+ aRequest.aPrintToList = rtl::OUString();
+ ResMgr* pDtResMgr = GetDesktopResManager();
+ if( pDtResMgr )
+ {
+ ErrorBox aBox( NULL, ResId( EBX_ERR_PRINTDISABLED, *pDtResMgr ) );
+ aBox.Execute();
+ }
+ }
+
+ // Process request
+ bShutdown = OfficeIPCThread::ExecuteCmdLineRequests( aRequest );
+ }
+ }
+
+ // Don't do anything if we have successfully called terminate at desktop
+ if ( bShutdown )
+ return;
+
+ // no default document if a document was loaded by recovery or by command line or if soffice is used as server
+ Reference< XFramesSupplier > xTasksSupplier(
+ ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ ::com::sun::star::uno::UNO_QUERY_THROW );
+ Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY_THROW );
+ if ( xList->hasElements() || pArgs->IsServer() )
+ return;
+
+ if ( pArgs->IsQuickstart() || pArgs->IsInvisible() || pArgs->IsBean() || Application::AnyInput( INPUT_APPEVENT ) )
+ // soffice was started as tray icon ...
+ return;
+ {
+ OpenDefault();
+ }
+}
+
+void Desktop::OpenDefault()
+{
+
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::OpenDefault" );
+
+ ::rtl::OUString aName;
+ SvtModuleOptions aOpt;
+
+ CommandLineArgs* pArgs = GetCommandLineArgs();
+ if ( pArgs->IsNoDefault() ) return;
+ if ( pArgs->HasModuleParam() )
+ {
+ // Support new command line parameters to start a module
+ if ( pArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITER );
+ else if ( pArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_CALC );
+ else if ( pArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_IMPRESS );
+ else if ( pArgs->IsBase() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DATABASE );
+ else if ( pArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DRAW );
+ else if ( pArgs->IsMath() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_MATH );
+ else if ( pArgs->IsGlobal() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITERGLOBAL );
+ else if ( pArgs->IsWeb() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITERWEB );
+ }
+
+ if ( !aName.getLength() )
+ {
+ // Old way to create a default document
+ if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITER );
+ else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_CALC );
+ else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_IMPRESS );
+ else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DATABASE );
+ else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
+ aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DRAW );
+ else
+ return;
+ }
+
+ ProcessDocumentsRequest aRequest(pArgs->getCwdUrl());
+ aRequest.pcProcessed = NULL;
+ aRequest.aOpenList = aName;
+ OfficeIPCThread::ExecuteCmdLineRequests( aRequest );
+}
+
+
+String GetURL_Impl(
+ const String& rName, boost::optional< rtl::OUString > const & cwdUrl )
+{
+ // if rName is a vnd.sun.star.script URL do not attempt to parse it
+ // as INetURLObj does not handle handle there URLs
+ if (rName.CompareToAscii("vnd.sun.star.script" , 19) == COMPARE_EQUAL)
+ {
+ return rName;
+ }
+
+ // dont touch file urls, those should already be in internal form
+ // they won't get better here (#112849#)
+ if (rName.CompareToAscii("file:" , 5) == COMPARE_EQUAL)
+ {
+ return rName;
+ }
+
+ if ( rName.CompareToAscii("service:" , 8) == COMPARE_EQUAL )
+ {
+ return rName;
+ }
+
+ // Add path seperator to these directory and make given URL (rName) absolute by using of current working directory
+ // Attention: "setFianlSlash()" is neccessary for calling "smartRel2Abs()"!!!
+ // Otherwhise last part will be ignored and wrong result will be returned!!!
+ // "smartRel2Abs()" interpret given URL as file not as path. So he truncate last element to get the base path ...
+ // But if we add a seperator - he doesn't do it anymore.
+ INetURLObject aObj;
+ if (cwdUrl) {
+ aObj.SetURL(*cwdUrl);
+ aObj.setFinalSlash();
+ }
+
+ // Use the provided parameters for smartRel2Abs to support the usage of '%' in system paths.
+ // Otherwise this char won't get encoded and we are not able to load such files later,
+ // see #110156#
+ bool bWasAbsolute;
+ INetURLObject aURL = aObj.smartRel2Abs( rName, bWasAbsolute, false, INetURLObject::WAS_ENCODED,
+ RTL_TEXTENCODING_UTF8, true );
+ String aFileURL = aURL.GetMainURL(INetURLObject::NO_DECODE);
+
+ ::osl::FileStatus aStatus( FileStatusMask_FileURL );
+ ::osl::DirectoryItem aItem;
+ if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
+ ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
+ aFileURL = aStatus.getFileURL();
+
+ return aFileURL;
+}
+
+void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
+{
+ if ( rAppEvent.GetEvent() == "APPEAR" && !GetCommandLineArgs()->IsInvisible() )
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ // find active task - the active task is always a visible task
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFramesSupplier >
+ xDesktop( xSMGR->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ ::com::sun::star::uno::UNO_QUERY );
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xTask = xDesktop->getActiveFrame();
+ if ( !xTask.is() )
+ {
+ // get any task if there is no active one
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > xList( xDesktop->getFrames(), ::com::sun::star::uno::UNO_QUERY );
+ if ( xList->getCount()>0 )
+ xList->getByIndex(0) >>= xTask;
+ }
+
+ if ( xTask.is() )
+ {
+ Reference< com::sun::star::awt::XTopWindow > xTop( xTask->getContainerWindow(), UNO_QUERY );
+ xTop->toFront();
+ }
+ else
+ {
+ // no visible task that could be activated found
+ Reference< XFrame > xBackingFrame;
+ Reference< ::com::sun::star::awt::XWindow > xContainerWindow;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xDesktopFrame( xDesktop, UNO_QUERY );
+
+ xBackingFrame = xDesktopFrame->findFrame(OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" )), 0);
+ if (xBackingFrame.is())
+ xContainerWindow = xBackingFrame->getContainerWindow();
+ if (xContainerWindow.is())
+ {
+ Sequence< Any > lArgs(1);
+ lArgs[0] <<= xContainerWindow;
+ Reference< XController > xBackingComp(
+ xSMGR->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule") ), lArgs),
+ UNO_QUERY);
+ if (xBackingComp.is())
+ {
+ Reference< ::com::sun::star::awt::XWindow > xBackingWin(xBackingComp, UNO_QUERY);
+ // Attention: You MUST(!) call setComponent() before you call attachFrame().
+ // Because the backing component set the property "IsBackingMode" of the frame
+ // to true inside attachFrame(). But setComponent() reset this state everytimes ...
+ xBackingFrame->setComponent(xBackingWin, xBackingComp);
+ xBackingComp->attachFrame(xBackingFrame);
+ xContainerWindow->setVisible(sal_True);
+
+ Window* pCompWindow = VCLUnoHelper::GetWindow(xBackingFrame->getComponentWindow());
+ if (pCompWindow)
+ pCompWindow->Update();
+ }
+ }
+ }
+ }
+ else if ( rAppEvent.GetEvent() == "QUICKSTART" && !GetCommandLineArgs()->IsInvisible() )
+ {
+ // If the office has been started the second time its command line arguments are sent through a pipe
+ // connection to the first office. We want to reuse the quickstart option for the first office.
+ // NOTICE: The quickstart service must be initialized inside the "main thread", so we use the
+ // application events to do this (they are executed inside main thread)!!!
+ // Don't start quickstart service if the user specified "-invisible" on the command line!
+ sal_Bool bQuickstart( sal_True );
+ Sequence< Any > aSeq( 1 );
+ aSeq[0] <<= bQuickstart;
+
+ Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance(
+ DEFINE_CONST_UNICODE( "com.sun.star.office.Quickstart" )),
+ UNO_QUERY );
+ if ( xQuickstart.is() )
+ xQuickstart->initialize( aSeq );
+ }
+ else if ( rAppEvent.GetEvent() == "ACCEPT" )
+ {
+ // every time an accept parameter is used we create an acceptor
+ // with the corresponding accept-string
+ OUString aAcceptString(rAppEvent.GetData().GetBuffer());
+ createAcceptor(aAcceptString);
+ }
+ else if ( rAppEvent.GetEvent() == "UNACCEPT" )
+ {
+ // try to remove corresponding acceptor
+ OUString aUnAcceptString(rAppEvent.GetData().GetBuffer());
+ destroyAcceptor(aUnAcceptString);
+ }
+ else if ( rAppEvent.GetEvent() == "SaveDocuments" )
+ {
+ Desktop::_bTasksSaved = sal_False;
+ Desktop::_bTasksSaved = SaveTasks();
+ }
+ else if ( rAppEvent.GetEvent() == "OPENHELPURL" )
+ {
+ // start help for a specific URL
+ OUString aHelpURL(rAppEvent.GetData().GetBuffer());
+ Help *pHelp = Application::GetHelp();
+ pHelp->Start(aHelpURL, NULL);
+ }
+ else if ( rAppEvent.GetEvent() == APPEVENT_OPEN_STRING )
+ {
+ OUString aOpenURL(rAppEvent.GetData().GetBuffer());
+
+ CommandLineArgs* pCmdLine = GetCommandLineArgs();
+ if ( !pCmdLine->IsInvisible() && !pCmdLine->IsTerminateAfterInit() )
+ {
+ ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
+ pCmdLine->getCwdUrl());
+ pDocsRequest->aOpenList = aOpenURL;
+ pDocsRequest->pcProcessed = NULL;
+
+ OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
+ delete pDocsRequest;
+ }
+ }
+ else if ( rAppEvent.GetEvent() == APPEVENT_PRINT_STRING )
+ {
+ OUString aPrintURL(rAppEvent.GetData().GetBuffer());
+
+ CommandLineArgs* pCmdLine = GetCommandLineArgs();
+ if ( !pCmdLine->IsInvisible() && !pCmdLine->IsTerminateAfterInit() )
+ {
+ ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
+ pCmdLine->getCwdUrl());
+ pDocsRequest->aPrintList = aPrintURL;
+ pDocsRequest->pcProcessed = NULL;
+
+ OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
+ delete pDocsRequest;
+ }
+ }
+#ifndef UNX
+ else if ( rAppEvent.GetEvent() == "HELP" )
+ {
+ // in non unix version allow showing of cmdline help window
+ displayCmdlineHelp();
+ }
+#endif
+ else if ( rAppEvent.GetEvent() == "SHOWDIALOG" )
+ {
+ // ignore all errors here. It's clicking a menu entry only ...
+ // The user will try it again, in case nothing happens .-)
+ try
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
+
+ com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >
+ xDesktop( xSMGR->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ ::com::sun::star::uno::UNO_QUERY );
+
+ // check provider ... we know it's weak reference only
+ if ( ! xDesktop.is())
+ return;
+
+ css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))), css::uno::UNO_QUERY_THROW);
+ css::util::URL aCommand;
+ if( rAppEvent.GetData().EqualsAscii( "PREFERENCES" ) )
+ aCommand.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:OptionsTreeDialog" ) );
+ else if( rAppEvent.GetData().EqualsAscii( "ABOUT" ) )
+ aCommand.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:About" ) );
+ if( aCommand.Complete.getLength() )
+ {
+ xParser->parseStrict(aCommand);
+
+ css::uno::Reference< css::frame::XDispatch > xDispatch = xDesktop->queryDispatch(aCommand, rtl::OUString(), 0);
+ if (xDispatch.is())
+ xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >());
+ }
+ }
+ catch(const css::uno::Exception&)
+ {}
+ }
+}
+
+void Desktop::OpenSplashScreen()
+{
+ ::rtl::OUString aTmpString;
+ CommandLineArgs* pCmdLine = GetCommandLineArgs();
+ sal_Bool bVisible = sal_False;
+ // Show intro only if this is normal start (e.g. no server, no quickstart, no printing )
+ if ( !pCmdLine->IsInvisible() &&
+ !pCmdLine->IsQuickstart() &&
+ !pCmdLine->IsMinimized() &&
+ !pCmdLine->IsNoLogo() &&
+ !pCmdLine->IsTerminateAfterInit() &&
+ !pCmdLine->GetPrintList( aTmpString ) &&
+ !pCmdLine->GetPrintToList( aTmpString ) )
+ {
+ // Determine application name from command line parameters
+ OUString aAppName;
+ if ( pCmdLine->IsWriter() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer" ));
+ else if ( pCmdLine->IsCalc() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc" ));
+ else if ( pCmdLine->IsDraw() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw" ));
+ else if ( pCmdLine->IsImpress() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress" ));
+ else if ( pCmdLine->IsBase() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "base" ));
+ else if ( pCmdLine->IsGlobal() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "global" ));
+ else if ( pCmdLine->IsMath() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math" ));
+ else if ( pCmdLine->IsWeb() )
+ aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "web" ));
+
+ bVisible = sal_True;
+ Sequence< Any > aSeq( 2 );
+ aSeq[0] <<= bVisible;
+ aSeq[1] <<= aAppName;
+ m_rSplashScreen = Reference<XStatusIndicator>(
+ comphelper::getProcessServiceFactory()->createInstanceWithArguments(
+ OUString::createFromAscii("com.sun.star.office.SplashScreen"),
+ aSeq), UNO_QUERY);
+
+ if(m_rSplashScreen.is())
+ m_rSplashScreen->start(OUString::createFromAscii("SplashScreen"), 100);
+ }
+
+}
+
+void Desktop::SetSplashScreenProgress(sal_Int32 iProgress)
+{
+ if(m_rSplashScreen.is())
+ {
+ m_rSplashScreen->setValue(iProgress);
+ }
+}
+
+void Desktop::SetSplashScreenText( const ::rtl::OUString& rText )
+{
+ if( m_rSplashScreen.is() )
+ {
+ m_rSplashScreen->setText( rText );
+ }
+}
+
+void Desktop::CloseSplashScreen()
+{
+ if(m_rSplashScreen.is())
+ {
+ m_rSplashScreen->end();
+ m_rSplashScreen = NULL;
+ }
+}
+
+// ========================================================================
+void Desktop::DoFirstRunInitializations()
+{
+ try
+ {
+ Reference< XJobExecutor > xExecutor( ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.task.JobExecutor" ) ), UNO_QUERY );
+ if( xExecutor.is() )
+ xExecutor->trigger( ::rtl::OUString::createFromAscii("onFirstRunInitialization") );
+ }
+ catch(const ::com::sun::star::uno::Exception&)
+ {
+ OSL_ENSURE( sal_False, "Desktop::DoFirstRunInitializations: caught an exception while trigger job executor ..." );
+ }
+}
+
+// ========================================================================
+void Desktop::CheckFirstRun( )
+{
+ const ::rtl::OUString sCommonMiscNodeName = ::rtl::OUString::createFromAscii( "/org.openoffice.Office.Common/Misc" );
+ const ::rtl::OUString sFirstRunNodeName = ::rtl::OUString::createFromAscii( "FirstRun" );
+
+ // --------------------------------------------------------------------
+ // check if this is the first office start
+
+ // for this, open the Common/Misc node where this info is stored
+ ::utl::OConfigurationTreeRoot aCommonMisc = ::utl::OConfigurationTreeRoot::createWithServiceFactory(
+ ::comphelper::getProcessServiceFactory( ),
+ sCommonMiscNodeName,
+ 2,
+ ::utl::OConfigurationTreeRoot::CM_UPDATABLE
+ );
+
+ // read the flag
+ OSL_ENSURE( aCommonMisc.isValid(), "Desktop::CheckFirstRun: could not open the config node needed!" );
+ sal_Bool bIsFirstRun = sal_False;
+ aCommonMisc.getNodeValue( sFirstRunNodeName ) >>= bIsFirstRun;
+
+ if ( !bIsFirstRun )
+ // nothing to do ....
+ return;
+
+ // --------------------------------------------------------------------
+ // it is the first run
+ // this has once been done using a vos timer. this could lead to problems when
+ // the timer would trigger when the app is already going down again, since VCL would
+ // no longer be available. Since the old handler would do a postUserEvent to the main
+ // thread anyway, we can use a vcl timer here to prevent the race contition (#107197#)
+ m_firstRunTimer.SetTimeout(3000); // 3 sec.
+ m_firstRunTimer.SetTimeoutHdl(LINK(this, Desktop, AsyncInitFirstRun));
+ m_firstRunTimer.Start();
+
+ // --------------------------------------------------------------------
+ // reset the config flag
+
+ // set the value
+ aCommonMisc.setNodeValue( sFirstRunNodeName, makeAny( (sal_Bool)sal_False ) );
+ // commit the changes
+ aCommonMisc.commit();
+}
+
+}
diff --git a/desktop/source/app/appfirststart.cxx b/desktop/source/app/appfirststart.cxx
new file mode 100644
index 000000000000..c06d94fd0812
--- /dev/null
+++ b/desktop/source/app/appfirststart.cxx
@@ -0,0 +1,318 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include <osl/file.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/datetime.hxx>
+#include <unotools/configmgr.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+
+#include "app.hxx"
+
+using ::rtl::OUString;
+using namespace ::desktop;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+
+static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
+static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) );
+
+/* Path of the license. */
+OUString Desktop::GetLicensePath()
+{
+ // license file name
+ static const char *szLicensePath = "/share/readme";
+#if defined(WNT) || defined(OS2)
+ static const char *szWNTLicenseName = "/license";
+ static const char *szWNTLicenseExt = ".txt";
+#else
+ static const char *szUNXLicenseName = "/LICENSE";
+ static const char *szUNXLicenseExt = "";
+#endif
+ static OUString aLicensePath;
+
+ if (aLicensePath.getLength() > 0)
+ return aLicensePath;
+
+ OUString aBaseInstallPath(RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR"));
+ rtl::Bootstrap::expandMacros(aBaseInstallPath);
+
+ // determine the filename of the license to show
+ OUString aLangString;
+ ::com::sun::star::lang::Locale aLocale;
+ OString aMgrName = OString("dkt");
+
+ AllSettings aSettings(Application::GetSettings());
+ aLocale = aSettings.GetUILocale();
+ ResMgr* pLocalResMgr = ResMgr::SearchCreateResMgr(aMgrName, aLocale);
+
+ aLangString = aLocale.Language;
+ if ( aLocale.Country.getLength() != 0 )
+ {
+ aLangString += OUString::createFromAscii("-");
+ aLangString += aLocale.Country;
+ if ( aLocale.Variant.getLength() != 0 )
+ {
+ aLangString += OUString::createFromAscii("-");
+ aLangString += aLocale.Variant;
+ }
+ }
+#if defined(WNT) || defined(OS2)
+ aLicensePath =
+ aBaseInstallPath + OUString::createFromAscii(szLicensePath)
+ + OUString::createFromAscii(szWNTLicenseName)
+ + OUString::createFromAscii("_")
+ + aLangString
+ + OUString::createFromAscii(szWNTLicenseExt);
+#else
+ aLicensePath =
+ aBaseInstallPath + OUString::createFromAscii(szLicensePath)
+ + OUString::createFromAscii(szUNXLicenseName)
+ + OUString::createFromAscii("_")
+ + aLangString
+ + OUString::createFromAscii(szUNXLicenseExt);
+#endif
+ delete pLocalResMgr;
+ return aLicensePath;
+}
+
+/* Check if we need to accept license. */
+sal_Bool Desktop::LicenseNeedsAcceptance()
+{
+ // Don't show a license
+ return sal_False;
+/*
+ sal_Bool bShowLicense = sal_True;
+ sal_Int32 nOpenSourceContext = 0;
+ try
+ {
+ ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::OPENSOURCECONTEXT ) >>= nOpenSourceContext;
+ }
+ catch( const ::com::sun::star::uno::Exception& ) {}
+
+ // open source needs no license
+ if ( nOpenSourceContext > 0 )
+ bShowLicense = sal_False;
+
+ return bShowLicense;
+*/
+}
+
+/* Local function - get access to the configuration */
+static Reference< XPropertySet > impl_getConfigurationAccess( const OUString& rPath )
+{
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > xConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance( sConfigSrvc ), UNO_QUERY_THROW );
+
+ Sequence< Any > aArgs( 1 );
+ NamedValue aValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "NodePath" ) ), makeAny( rPath ) );
+ aArgs[0] <<= aValue;
+ return Reference< XPropertySet >(
+ xConfigProvider->createInstanceWithArguments( sAccessSrvc, aArgs ), UNO_QUERY_THROW );
+}
+
+/* Local function - was the wizard completed already? */
+static sal_Bool impl_isFirstStart()
+{
+ try {
+ Reference< XPropertySet > xPSet = impl_getConfigurationAccess( OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Setup/Office" ) ) );
+
+ Any result = xPSet->getPropertyValue(OUString::createFromAscii("FirstStartWizardCompleted"));
+ sal_Bool bCompleted = sal_False;
+ if ((result >>= bCompleted) && bCompleted)
+ return sal_False; // wizard was already completed
+ else
+ return sal_True;
+ } catch (const Exception&)
+ {
+ return sal_True;
+ }
+}
+
+/* Local function - convert oslDateTime to tools DateTime */
+static DateTime impl_oslDateTimeToDateTime(const oslDateTime& aDateTime)
+{
+ return DateTime(
+ Date(aDateTime.Day, aDateTime.Month, aDateTime.Year),
+ Time(aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds));
+}
+
+/* Local function - get DateTime from a string */
+static sal_Bool impl_parseDateTime(const OUString& aString, DateTime& aDateTime)
+{
+ // take apart a canonical literal xsd:dateTime string
+ //CCYY-MM-DDThh:mm:ss(Z)
+
+ OUString aDateTimeString = aString.trim();
+
+ // check length
+ if (aDateTimeString.getLength() < 19 || aDateTimeString.getLength() > 20)
+ return sal_False;
+
+ sal_Int32 nDateLength = 10;
+ sal_Int32 nTimeLength = 8;
+
+ OUString aDateTimeSep = OUString::createFromAscii("T");
+ OUString aDateSep = OUString::createFromAscii("-");
+ OUString aTimeSep = OUString::createFromAscii(":");
+ OUString aUTCString = OUString::createFromAscii("Z");
+
+ OUString aDateString = aDateTimeString.copy(0, nDateLength);
+ OUString aTimeString = aDateTimeString.copy(nDateLength+1, nTimeLength);
+
+ sal_Int32 nIndex = 0;
+ sal_Int32 nYear = aDateString.getToken(0, '-', nIndex).toInt32();
+ sal_Int32 nMonth = aDateString.getToken(0, '-', nIndex).toInt32();
+ sal_Int32 nDay = aDateString.getToken(0, '-', nIndex).toInt32();
+ nIndex = 0;
+ sal_Int32 nHour = aTimeString.getToken(0, ':', nIndex).toInt32();
+ sal_Int32 nMinute = aTimeString.getToken(0, ':', nIndex).toInt32();
+ sal_Int32 nSecond = aTimeString.getToken(0, ':', nIndex).toInt32();
+
+ Date tmpDate((USHORT)nDay, (USHORT)nMonth, (USHORT)nYear);
+ Time tmpTime(nHour, nMinute, nSecond);
+ DateTime tmpDateTime(tmpDate, tmpTime);
+ if (aString.indexOf(aUTCString) < 0)
+ tmpDateTime.ConvertToUTC();
+
+ aDateTime = tmpDateTime;
+ return sal_True;
+}
+
+/* Local function - was the license accepted already? */
+static sal_Bool impl_isLicenseAccepted()
+{
+ // If no license will be shown ... it must not be accepted.
+ // So it was accepted "hardly" by the outside installer.
+ // But if the configuration entry "HideEula" will be removed afterwards ..
+ // we have to show the licese page again and user has to accept it here .-)
+ if ( ! Desktop::LicenseNeedsAcceptance() )
+ return sal_True;
+
+ try
+ {
+ Reference< XPropertySet > xPSet = impl_getConfigurationAccess( OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Setup/Office" ) ) );
+
+ Any result = xPSet->getPropertyValue(OUString::createFromAscii("LicenseAcceptDate"));
+
+ OUString aAcceptDate;
+ if (result >>= aAcceptDate)
+ {
+ // compare to date of license file
+ OUString aLicenseURL = Desktop::GetLicensePath();
+ osl::DirectoryItem aDirItem;
+ if (osl::DirectoryItem::get(aLicenseURL, aDirItem) != osl::FileBase::E_None)
+ return sal_False;
+ osl::FileStatus aStatus(FileStatusMask_All);
+ if (aDirItem.getFileStatus(aStatus) != osl::FileBase::E_None)
+ return sal_False;
+ TimeValue aTimeVal = aStatus.getModifyTime();
+ oslDateTime aDateTimeVal;
+ if (!osl_getDateTimeFromTimeValue(&aTimeVal, &aDateTimeVal))
+ return sal_False;
+
+ // compare dates
+ DateTime aLicenseDateTime = impl_oslDateTimeToDateTime(aDateTimeVal);
+ DateTime aAcceptDateTime;
+ if (!impl_parseDateTime(aAcceptDate, aAcceptDateTime))
+ return sal_False;
+
+ if ( aAcceptDateTime > aLicenseDateTime )
+ return sal_True;
+ }
+ return sal_False;
+ } catch (const Exception&)
+ {
+ return sal_False;
+ }
+}
+
+/* Check if we need the first start wizard. */
+sal_Bool Desktop::IsFirstStartWizardNeeded()
+{
+ return impl_isFirstStart() || !impl_isLicenseAccepted();
+}
+
+void Desktop::DoRestartActionsIfNecessary( sal_Bool bQuickStart )
+{
+ if ( bQuickStart )
+ {
+ try
+ {
+ Reference< XPropertySet > xPSet = impl_getConfigurationAccess( OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Setup/Office" ) ) );
+
+ OUString sPropName( RTL_CONSTASCII_USTRINGPARAM( "OfficeRestartInProgress" ) );
+ Any aRestart = xPSet->getPropertyValue( sPropName );
+ sal_Bool bRestart = sal_False;
+ if ( ( aRestart >>= bRestart ) && bRestart )
+ {
+ xPSet->setPropertyValue( sPropName, makeAny( sal_False ) );
+ Reference< util::XChangesBatch >( xPSet, UNO_QUERY_THROW )->commitChanges();
+
+ Sequence< Any > aSeq( 2 );
+ aSeq[0] <<= sal_True;
+ aSeq[1] <<= sal_True;
+
+ Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.office.Quickstart" ) ) ),UNO_QUERY_THROW );
+ xQuickstart->initialize( aSeq );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ // this is no critical operation so it should not prevent office from starting
+ }
+ }
+}
+
+void Desktop::SetRestartState()
+{
+ try
+ {
+ Reference< XPropertySet > xPSet = impl_getConfigurationAccess( OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Setup/Office" ) ) );
+ OUString sPropName( RTL_CONSTASCII_USTRINGPARAM( "OfficeRestartInProgress" ) );
+ xPSet->setPropertyValue( sPropName, makeAny( sal_True ) );
+ Reference< util::XChangesBatch >( xPSet, UNO_QUERY_THROW )->commitChanges();
+ }
+ catch( uno::Exception& )
+ {
+ // this is no critical operation, ignore the exception
+ }
+
+}
+
diff --git a/desktop/source/app/appinit.cxx b/desktop/source/app/appinit.cxx
new file mode 100644
index 000000000000..97eb3f555f60
--- /dev/null
+++ b/desktop/source/app/appinit.cxx
@@ -0,0 +1,484 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include <algorithm>
+
+#include "app.hxx"
+#include "cmdlineargs.hxx"
+#include "desktopresid.hxx"
+#include "desktop.hrc"
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/XCurrentContext.hpp>
+#include <com/sun/star/packages/zip/ZipIOException.hpp>
+
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/ucb/XContentProviderManager.hpp>
+#include <com/sun/star/ucb/XContentProviderFactory.hpp>
+#include <uno/current_context.hxx>
+#include <cppuhelper/servicefactory.hxx>
+#include <cppuhelper/bootstrap.hxx>
+#include <osl/file.hxx>
+#include <osl/module.h>
+#include <vos/process.hxx>
+#include <rtl/uri.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/bootstrap.hxx>
+#include <comphelper/regpathhelper.hxx>
+#include <tools/debug.hxx>
+#include <tools/tempfile.hxx>
+#include <ucbhelper/configurationkeys.hxx>
+
+#include <cppuhelper/bootstrap.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/rcid.h>
+
+#include <rtl/logfile.hxx>
+#include <rtl/instance.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <unotools/tempfile.hxx>
+#include <ucbhelper/contentbroker.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/startoptions.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/internaloptions.hxx>
+
+
+#define DEFINE_CONST_OUSTRING(CONSTASCII) OUString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))
+
+#define DESKTOP_TEMPDIRNAME "soffice.tmp"
+
+using namespace rtl;
+using namespace vos;
+using namespace desktop;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::ucb;
+
+namespace desktop
+{
+
+// -----------------------------------------------------------------------------
+
+static bool configureUcb(bool bServer, rtl::OUString const & rPortalConnect)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (sb93797) ::configureUcb" );
+ Reference< XMultiServiceFactory >
+ xServiceFactory( comphelper::getProcessServiceFactory() );
+ if (!xServiceFactory.is())
+ {
+ DBG_ERROR("configureUcb(): No XMultiServiceFactory");
+ return false;
+ }
+
+ rtl::OUString aPipe;
+ vos::OSecurity().getUserIdent(aPipe);
+
+ rtl::OUStringBuffer aPortal;
+ if (rPortalConnect.getLength() != 0)
+ {
+ aPortal.append(sal_Unicode(','));
+ aPortal.append(rPortalConnect);
+ }
+
+ Sequence< Any > aArgs(6);
+ aArgs[0]
+ <<= rtl::OUString::createFromAscii(bServer ?
+ UCB_CONFIGURATION_KEY1_SERVER :
+ UCB_CONFIGURATION_KEY1_LOCAL);
+ aArgs[1]
+ <<= rtl::OUString::createFromAscii(UCB_CONFIGURATION_KEY2_OFFICE);
+ aArgs[2] <<= rtl::OUString::createFromAscii("PIPE");
+ aArgs[3] <<= aPipe;
+ aArgs[4] <<= rtl::OUString::createFromAscii("PORTAL");
+ aArgs[5] <<= aPortal.makeStringAndClear();
+
+ bool ret =
+ ::ucbhelper::ContentBroker::initialize( xServiceFactory, aArgs ) != false;
+
+#ifdef GNOME_VFS_ENABLED
+ // register GnomeUCP if necessary
+ ::ucbhelper::ContentBroker* cb = ::ucbhelper::ContentBroker::get();
+ if(cb) {
+ try {
+ Reference< XCurrentContext > xCurrentContext(
+ getCurrentContext());
+ if (xCurrentContext.is())
+ {
+ Any aValue = xCurrentContext->getValueByName(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "system.desktop-environment" ) )
+ );
+ rtl::OUString aDesktopEnvironment;
+ if ((aValue >>= aDesktopEnvironment)
+ && aDesktopEnvironment.equalsAscii("GNOME"))
+ {
+ Reference<XContentProviderManager> xCPM =
+ cb->getContentProviderManagerInterface();
+#if 0
+ try
+ {
+
+ Reference<XContentProviderFactory> xCPF(
+ xServiceFactory->createInstance(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.ucb.ContentProviderProxyFactory")),
+ UNO_QUERY);
+ if(xCPF.is())
+ xCPM->registerContentProvider(
+ xCPF->createContentProvider(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.ucb.GnomeVFSContentProvider"
+ )
+ ),
+ rtl::OUString::createFromAscii(".*"),
+ false);
+ } catch (...)
+ {
+ }
+#else
+
+ // Workaround for P1 #124597#. Instanciate GNOME-VFS-UCP in the thread that initialized
+ // GNOME in order to avoid a deadlock that may occure in case UCP gets initialized from
+ // a different thread. The latter may happen when calling the Office remotely via UNO.
+ // THIS IS NOT A FIX, JUST A WORKAROUND!
+
+ try
+ {
+ Reference<XContentProvider> xCP(
+ xServiceFactory->createInstance(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.ucb.GnomeVFSContentProvider")),
+ UNO_QUERY);
+ if(xCP.is())
+ xCPM->registerContentProvider(
+ xCP,
+ rtl::OUString::createFromAscii(".*"),
+ false);
+ } catch (...)
+ {
+ }
+ }
+#endif
+ }
+ } catch (RuntimeException e) {
+ }
+ }
+#endif // GNOME_VFS_ENABLED
+
+ return ret;;
+}
+
+Reference< XMultiServiceFactory > Desktop::CreateApplicationServiceManager()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::createApplicationServiceManager" );
+
+ try
+ {
+ Reference<XComponentContext> xComponentContext = ::cppu::defaultBootstrap_InitialComponentContext();
+ Reference<XMultiServiceFactory> xMS(xComponentContext->getServiceManager(), UNO_QUERY);
+
+ return xMS;
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ return Reference< XMultiServiceFactory >();
+}
+
+void Desktop::DestroyApplicationServiceManager( Reference< XMultiServiceFactory >& xSMgr )
+{
+ Reference< XPropertySet > xProps( xSMgr, UNO_QUERY );
+ if ( xProps.is() )
+ {
+ try
+ {
+ Reference< XComponent > xComp;
+ if (xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xComp )
+ {
+ xComp->dispose();
+ }
+ }
+ catch ( UnknownPropertyException& )
+ {
+ }
+ }
+}
+
+void Desktop::RegisterServices( Reference< XMultiServiceFactory >& xSMgr )
+{
+ if( !m_bServicesRegistered )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::registerServices" );
+
+ // read command line parameters
+ ::rtl::OUString conDcp;
+ ::rtl::OUString aClientDisplay;
+ ::rtl::OUString aTmpString;
+ sal_Bool bHeadlessMode = sal_False;
+
+ // interpret command line arguments
+ CommandLineArgs* pCmdLine = GetCommandLineArgs();
+
+ // read accept string from configuration
+ conDcp = SvtStartOptions().GetConnectionURL();
+
+ if ( pCmdLine->GetAcceptString( aTmpString ))
+ conDcp = aTmpString;
+
+ // Headless mode for FAT Office
+ bHeadlessMode = pCmdLine->IsHeadless();
+ if ( bHeadlessMode )
+ Application::EnableHeadlessMode();
+
+ if ( conDcp.getLength() > 0 )
+ {
+ // accept incoming connections (scripting and one rvp)
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (lo119109) desktop::Desktop::createAcceptor()" );
+ createAcceptor(conDcp);
+ }
+
+ // improves parallel processing on Sun ONE Webtop
+ // servicemanager up -> copy user installation
+ if ( pCmdLine->IsServer() )
+ {
+ // Check some mandatory environment states if "-server" is possible. Otherwise ignore
+ // this parameter.
+ Reference< com::sun::star::container::XContentEnumerationAccess > rContent( xSMgr , UNO_QUERY );
+ if( rContent.is() )
+ {
+ OUString sPortalService = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.portal.InstallUser" ) );
+ Reference < com::sun::star::container::XEnumeration > rEnum = rContent->createContentEnumeration( sPortalService );
+ if ( !rEnum.is() )
+ {
+ // Reset server parameter so it is ignored in the furthermore startup process
+ pCmdLine->SetBoolParam( CommandLineArgs::CMD_BOOLPARAM_SERVER, sal_False );
+ }
+ }
+ }
+
+ ::rtl::OUString aPortalConnect;
+ bool bServer = (bool)pCmdLine->IsServer();
+
+ pCmdLine->GetPortalConnectString( aPortalConnect );
+ if ( !configureUcb( bServer, aPortalConnect ) )
+ {
+ DBG_ERROR( "Can't configure UCB" );
+ throw com::sun::star::uno::Exception(rtl::OUString::createFromAscii("RegisterServices, configureUcb"), NULL);
+ }
+
+ CreateTemporaryDirectory();
+ m_bServicesRegistered = true;
+ }
+}
+
+namespace
+{
+ struct acceptorMap : public rtl::Static< AcceptorMap, acceptorMap > {};
+ struct CurrentTempURL : public rtl::Static< String, CurrentTempURL > {};
+}
+
+static sal_Bool bAccept = sal_False;
+
+void Desktop::createAcceptor(const OUString& aAcceptString)
+{
+ // check whether the requested acceptor already exists
+ AcceptorMap &rMap = acceptorMap::get();
+ AcceptorMap::const_iterator pIter = rMap.find(aAcceptString);
+ if (pIter == rMap.end() ) {
+
+ Sequence< Any > aSeq( 2 );
+ aSeq[0] <<= aAcceptString;
+ aSeq[1] <<= bAccept;
+ Reference<XInitialization> rAcceptor(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ OUString::createFromAscii( "com.sun.star.office.Acceptor" )), UNO_QUERY );
+ if ( rAcceptor.is() ) {
+ try{
+ rAcceptor->initialize( aSeq );
+ rMap.insert(AcceptorMap::value_type(aAcceptString, rAcceptor));
+ } catch (com::sun::star::uno::Exception&) {
+ // no error handling needed...
+ // acceptor just won't come up
+ OSL_ENSURE(sal_False, "Acceptor could not be created.");
+ }
+ } else {
+ // there is already an acceptor with this description
+ OSL_ENSURE(sal_False, "Acceptor already exists.");
+ }
+
+ }
+}
+
+class enable
+{
+ private:
+ Sequence<Any> m_aSeq;
+ public:
+ enable() : m_aSeq(1) {
+ m_aSeq[0] <<= sal_True;
+ }
+ void operator() (const AcceptorMap::value_type& val) {
+ if (val.second.is()) {
+ val.second->initialize(m_aSeq);
+ }
+ }
+};
+
+void Desktop::enableAcceptors()
+{
+ RTL_LOGFILE_CONTEXT(aLog, "desktop (lo119109) Desktop::enableAcceptors");
+ if (!bAccept)
+ {
+ // from now on, all new acceptors are enabled
+ bAccept = sal_True;
+ // enable existing acceptors by calling initialize(true)
+ // on all existing acceptors
+ AcceptorMap &rMap = acceptorMap::get();
+ std::for_each(rMap.begin(), rMap.end(), enable());
+ }
+}
+
+void Desktop::destroyAcceptor(const OUString& aAcceptString)
+{
+ // special case stop all acceptors
+ AcceptorMap &rMap = acceptorMap::get();
+ if (aAcceptString.compareToAscii("all") == 0) {
+ rMap.clear();
+
+ } else {
+ // try to remove acceptor from map
+ AcceptorMap::const_iterator pIter = rMap.find(aAcceptString);
+ if (pIter != rMap.end() ) {
+ // remove reference from map
+ // this is the last reference and the acceptor will be destructed
+ rMap.erase(aAcceptString);
+ } else {
+ OSL_ENSURE(sal_False, "Found no acceptor to remove");
+ }
+ }
+}
+
+
+void Desktop::DeregisterServices()
+{
+ // stop all acceptors by clearing the map
+ acceptorMap::get().clear();
+}
+
+void Desktop::CreateTemporaryDirectory()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::createTemporaryDirectory" );
+
+ ::rtl::OUString aTempBaseURL;
+ try
+ {
+ SvtPathOptions aOpt;
+ aTempBaseURL = aOpt.GetTempPath();
+ }
+ catch ( RuntimeException& e )
+ {
+ // Catch runtime exception here: We have to add language dependent info
+ // to the exception message. Fallback solution uses hard coded string.
+ OUString aMsg;
+ DesktopResId aResId( STR_BOOTSTRAP_ERR_NO_PATHSET_SERVICE );
+ aResId.SetRT( RSC_STRING );
+ if ( aResId.GetResMgr()->IsAvailable( aResId ))
+ aMsg = String( aResId );
+ else
+ aMsg = OUString( RTL_CONSTASCII_USTRINGPARAM( "The path manager is not available.\n" ));
+ e.Message = aMsg + e.Message;
+ throw e;
+ }
+
+ // remove possible old directory and base directory
+ SvtInternalOptions aInternalOpt;
+
+ // set temp base directory
+ sal_Int32 nLength = aTempBaseURL.getLength();
+ if ( aTempBaseURL.matchAsciiL( "/", 1, nLength-1 ) )
+ aTempBaseURL = aTempBaseURL.copy( 0, nLength - 1 );
+
+ String aOldTempURL = aInternalOpt.GetCurrentTempURL();
+ if ( aOldTempURL.Len() > 0 )
+ {
+ // remove old temporary directory
+ ::utl::UCBContentHelper::Kill( aOldTempURL );
+ }
+
+ String aRet;
+ ::rtl::OUString aTempPath( aTempBaseURL );
+
+ // create new current temporary directory
+ ::utl::LocalFileHelper::ConvertURLToPhysicalName( aTempBaseURL, aRet );
+ ::osl::FileBase::getFileURLFromSystemPath( aRet, aTempPath );
+ aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempPath );
+ if ( !aTempPath.getLength() )
+ {
+ ::osl::File::getTempDirURL( aTempBaseURL );
+
+ nLength = aTempBaseURL.getLength();
+ if ( aTempBaseURL.matchAsciiL( "/", 1, nLength-1 ) )
+ aTempBaseURL = aTempBaseURL.copy( 0, nLength - 1 );
+
+ aTempPath = aTempBaseURL;
+ ::osl::FileBase::getFileURLFromSystemPath( aRet, aTempPath );
+ aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempPath );
+ }
+
+ // set new current temporary directory
+ ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aTempPath, aRet );
+ aInternalOpt.SetCurrentTempURL( aRet );
+ CurrentTempURL::get() = aRet;
+}
+
+void Desktop::RemoveTemporaryDirectory()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::removeTemporaryDirectory" );
+
+ // remove current temporary directory
+ String &rCurrentTempURL = CurrentTempURL::get();
+ if ( rCurrentTempURL.Len() > 0 )
+ {
+ if ( ::utl::UCBContentHelper::Kill( rCurrentTempURL ) )
+ SvtInternalOptions().SetCurrentTempURL( String() );
+ }
+}
+
+} // namespace desktop
diff --git a/desktop/source/app/appinit.hxx b/desktop/source/app/appinit.hxx
new file mode 100644
index 000000000000..c5b48fd4a488
--- /dev/null
+++ b/desktop/source/app/appinit.hxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_APPINIT_HXX_
+#define _DESKTOP_APPINIT_HXX_
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+namespace desktop
+{
+
+::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > createApplicationServiceManager();
+
+sal_Bool InitializeInstallation( const rtl::OUString& rAppFilename );
+void registerServices( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSMgr );
+void deregisterServices();
+
+void destroyApplicationServiceManager( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSMgr );
+
+void createTemporaryDirectory();
+void removeTemporaryDirectory();
+
+}
+
+#endif
diff --git a/desktop/source/app/appsys.cxx b/desktop/source/app/appsys.cxx
new file mode 100644
index 000000000000..4cff81e3bb54
--- /dev/null
+++ b/desktop/source/app/appsys.cxx
@@ -0,0 +1,69 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "appsys.hxx"
+
+#ifdef WNT
+
+#include <rtl/ustring.hxx>
+#include <tools/solar.h>
+#include <tools/prewin.h>
+#include <winreg.h>
+#include <tools/postwin.h>
+#include <tools/urlobj.hxx>
+
+
+#define U2S(STRING) ::rtl::OUStringToOString(STRING, RTL_TEXTENCODING_UTF8)
+
+namespace desktop
+{
+
+void FATToVFat_Impl( String& aName )
+{
+ INetURLObject aObj( aName );
+ if ( aObj.GetProtocol() == INET_PROT_FILE )
+ {
+ WIN32_FIND_DATA aData;
+ HANDLE h = FindFirstFile( U2S(aName).getStr(), &aData );
+ if ( h )
+ {
+ // FAT-Kurzname in VFAT-Langname wandeln
+ aObj.removeSegment();
+ aObj.insertName( String::CreateFromAscii( aData.cFileName ) );
+ aName = aObj.PathToFileName();
+ FindClose( h );
+ }
+ }
+}
+
+}
+
+#endif // WNT
+
diff --git a/desktop/source/app/appsys.hxx b/desktop/source/app/appsys.hxx
new file mode 100644
index 000000000000..5d1b06c1bbe7
--- /dev/null
+++ b/desktop/source/app/appsys.hxx
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_APPSYS_HXX_
+#define _DESKTOP_APPSYS_HXX_
+
+#include <tools/string.hxx>
+
+namespace desktop
+{
+
+#ifdef WNT
+void FATToVFat_Impl( String& aName );
+#endif
+
+}
+
+#endif // _DESKTOP_APPSYS_HXX_
diff --git a/desktop/source/app/check_ext_deps.cxx b/desktop/source/app/check_ext_deps.cxx
new file mode 100755
index 000000000000..664e63c7f6ca
--- /dev/null
+++ b/desktop/source/app/check_ext_deps.cxx
@@ -0,0 +1,431 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "osl/file.hxx"
+#include "osl/mutex.hxx"
+
+#include <rtl/bootstrap.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/logfile.hxx>
+#include "cppuhelper/compbase3.hxx"
+
+#include "vcl/wrkwin.hxx"
+#include "vcl/timer.hxx"
+
+#include <unotools/configmgr.hxx>
+#include "toolkit/helper/vclunohelper.hxx"
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/bootstrap.hxx>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/ExtensionManager.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/deployment/ui/LicenseDialog.hpp"
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/task/XJobExecutor.hpp>
+#include <com/sun/star/task/XInteractionApprove.hpp>
+#include <com/sun/star/task/XInteractionAbort.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
+#include <com/sun/star/util/XChangesBatch.hpp>
+
+#include "app.hxx"
+
+#include "../deployment/inc/dp_misc.h"
+
+using rtl::OUString;
+using namespace desktop;
+using namespace com::sun::star;
+
+#define UNISTRING(s) OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+
+namespace
+{
+//For use with XExtensionManager.synchronize
+class SilentCommandEnv
+ : public ::cppu::WeakImplHelper3< ucb::XCommandEnvironment,
+ task::XInteractionHandler,
+ ucb::XProgressHandler >
+{
+ Desktop *mpDesktop;
+ sal_Int32 mnLevel;
+ sal_Int32 mnProgress;
+
+public:
+ SilentCommandEnv( Desktop* pDesktop );
+ virtual ~SilentCommandEnv();
+
+ // XCommandEnvironment
+ virtual uno::Reference<task::XInteractionHandler > SAL_CALL
+ getInteractionHandler() throw (uno::RuntimeException);
+ virtual uno::Reference<ucb::XProgressHandler >
+ SAL_CALL getProgressHandler() throw (uno::RuntimeException);
+
+ // XInteractionHandler
+ virtual void SAL_CALL handle(
+ uno::Reference<task::XInteractionRequest > const & xRequest )
+ throw (uno::RuntimeException);
+
+ // XProgressHandler
+ virtual void SAL_CALL push( uno::Any const & Status )
+ throw (uno::RuntimeException);
+ virtual void SAL_CALL update( uno::Any const & Status )
+ throw (uno::RuntimeException);
+ virtual void SAL_CALL pop() throw (uno::RuntimeException);
+};
+
+//-----------------------------------------------------------------------------
+SilentCommandEnv::SilentCommandEnv( Desktop* pDesktop )
+{
+ mpDesktop = pDesktop;
+ mnLevel = 0;
+ mnProgress = 25;
+}
+
+//-----------------------------------------------------------------------------
+SilentCommandEnv::~SilentCommandEnv()
+{
+ mpDesktop->SetSplashScreenText( OUString() );
+}
+
+//-----------------------------------------------------------------------------
+Reference<task::XInteractionHandler> SilentCommandEnv::getInteractionHandler()
+ throw (uno::RuntimeException)
+{
+ return this;
+}
+
+//-----------------------------------------------------------------------------
+Reference<ucb::XProgressHandler> SilentCommandEnv::getProgressHandler()
+ throw (uno::RuntimeException)
+{
+ return this;
+}
+
+//-----------------------------------------------------------------------------
+// XInteractionHandler
+void SilentCommandEnv::handle( Reference< task::XInteractionRequest> const & xRequest )
+ throw (uno::RuntimeException)
+{
+ deployment::LicenseException licExc;
+
+ uno::Any request( xRequest->getRequest() );
+ bool bApprove = true;
+
+ if ( request >>= licExc )
+ {
+ uno::Reference< uno::XComponentContext > xContext = comphelper_getProcessComponentContext();
+ uno::Reference< ui::dialogs::XExecutableDialog > xDialog(
+ deployment::ui::LicenseDialog::create(
+ xContext, VCLUnoHelper::GetInterface( NULL ),
+ licExc.ExtensionName, licExc.Text ) );
+ sal_Int16 res = xDialog->execute();
+ if ( res == ui::dialogs::ExecutableDialogResults::CANCEL )
+ bApprove = false;
+ else if ( res == ui::dialogs::ExecutableDialogResults::OK )
+ bApprove = true;
+ else
+ {
+ OSL_ASSERT(0);
+ }
+ }
+
+ // We approve everything here
+ uno::Sequence< Reference< task::XInteractionContinuation > > conts( xRequest->getContinuations() );
+ Reference< task::XInteractionContinuation > const * pConts = conts.getConstArray();
+ sal_Int32 len = conts.getLength();
+
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ if ( bApprove )
+ {
+ uno::Reference< task::XInteractionApprove > xInteractionApprove( pConts[ pos ], uno::UNO_QUERY );
+ if ( xInteractionApprove.is() )
+ xInteractionApprove->select();
+ }
+ else
+ {
+ uno::Reference< task::XInteractionAbort > xInteractionAbort( pConts[ pos ], uno::UNO_QUERY );
+ if ( xInteractionAbort.is() )
+ xInteractionAbort->select();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// XProgressHandler
+void SilentCommandEnv::push( uno::Any const & rStatus )
+ throw (uno::RuntimeException)
+{
+ OUString sText;
+ mnLevel += 1;
+
+ if ( rStatus.hasValue() && ( rStatus >>= sText) )
+ {
+ if ( mnLevel <= 3 )
+ mpDesktop->SetSplashScreenText( sText );
+ else
+ mpDesktop->SetSplashScreenProgress( ++mnProgress );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SilentCommandEnv::update( uno::Any const & rStatus )
+ throw (uno::RuntimeException)
+{
+ OUString sText;
+ if ( rStatus.hasValue() && ( rStatus >>= sText) )
+ {
+ mpDesktop->SetSplashScreenText( sText );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SilentCommandEnv::pop() throw (uno::RuntimeException)
+{
+ mnLevel -= 1;
+}
+
+} // end namespace
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
+static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) );
+//------------------------------------------------------------------------------
+static sal_Int16 impl_showExtensionDialog( uno::Reference< uno::XComponentContext > &xContext )
+{
+ rtl::OUString sServiceName = UNISTRING("com.sun.star.deployment.ui.UpdateRequiredDialog");
+ uno::Reference< uno::XInterface > xService;
+ sal_Int16 nRet = 0;
+
+ uno::Reference< lang::XMultiComponentFactory > xServiceManager( xContext->getServiceManager() );
+ if( !xServiceManager.is() )
+ throw uno::RuntimeException(
+ UNISTRING( "impl_showExtensionDialog(): unable to obtain service manager from component context" ), uno::Reference< uno::XInterface > () );
+
+ xService = xServiceManager->createInstanceWithContext( sServiceName, xContext );
+ uno::Reference< ui::dialogs::XExecutableDialog > xExecuteable( xService, uno::UNO_QUERY );
+ if ( xExecuteable.is() )
+ nRet = xExecuteable->execute();
+
+ return nRet;
+}
+
+//------------------------------------------------------------------------------
+// Check dependencies of all packages
+//------------------------------------------------------------------------------
+static bool impl_checkDependencies( const uno::Reference< uno::XComponentContext > &xContext )
+{
+ uno::Sequence< uno::Sequence< uno::Reference< deployment::XPackage > > > xAllPackages;
+ uno::Reference< deployment::XExtensionManager > xExtensionManager = deployment::ExtensionManager::get( xContext );
+
+ if ( !xExtensionManager.is() )
+ {
+ OSL_ENSURE( 0, "Could not get the Extension Manager!" );
+ return true;
+ }
+
+ try {
+ xAllPackages = xExtensionManager->getAllExtensions( uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >() );
+ }
+ catch ( deployment::DeploymentException & ) { return true; }
+ catch ( ucb::CommandFailedException & ) { return true; }
+ catch ( ucb::CommandAbortedException & ) { return true; }
+ catch ( lang::IllegalArgumentException & e ) {
+ throw uno::RuntimeException( e.Message, e.Context );
+ }
+
+ sal_Int32 nMax = 2;
+#ifdef DEBUG
+ nMax = 3;
+#endif
+
+ for ( sal_Int32 i = 0; i < xAllPackages.getLength(); ++i )
+ {
+ uno::Sequence< uno::Reference< deployment::XPackage > > xPackageList = xAllPackages[i];
+
+ for ( sal_Int32 j = 0; (j<nMax) && (j < xPackageList.getLength()); ++j )
+ {
+ uno::Reference< deployment::XPackage > xPackage = xPackageList[j];
+ if ( xPackage.is() )
+ {
+ bool bRegistered = false;
+ try {
+ beans::Optional< beans::Ambiguous< sal_Bool > > option( xPackage->isRegistered( uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >() ) );
+ if ( option.IsPresent )
+ {
+ ::beans::Ambiguous< sal_Bool > const & reg = option.Value;
+ if ( reg.IsAmbiguous )
+ bRegistered = false;
+ else
+ bRegistered = reg.Value ? true : false;
+ }
+ else
+ bRegistered = false;
+ }
+ catch ( uno::RuntimeException & ) { throw; }
+ catch ( uno::Exception & exc) {
+ (void) exc;
+ OSL_ENSURE( 0, ::rtl::OUStringToOString( exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+
+ if ( bRegistered )
+ {
+ bool bDependenciesValid = false;
+ try {
+ bDependenciesValid = xPackage->checkDependencies( uno::Reference< ucb::XCommandEnvironment >() );
+ }
+ catch ( deployment::DeploymentException & ) {}
+ if ( ! bDependenciesValid )
+ {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
+//------------------------------------------------------------------------------
+// resets the 'check needed' flag (needed, if aborted)
+//------------------------------------------------------------------------------
+static void impl_setNeedsCompatCheck()
+{
+ try {
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ // get configuration provider
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+
+ Sequence< Any > theArgs(1);
+ beans::NamedValue v( OUString::createFromAscii("NodePath"),
+ makeAny( OUString::createFromAscii("org.openoffice.Setup/Office") ) );
+ theArgs[0] <<= v;
+ Reference< beans::XPropertySet > pset = Reference< beans::XPropertySet >(
+ theConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY_THROW );
+
+ Any value = makeAny( OUString::createFromAscii("never") );
+
+ pset->setPropertyValue( OUString::createFromAscii("LastCompatibilityCheckID"), value );
+ Reference< util::XChangesBatch >( pset, UNO_QUERY_THROW )->commitChanges();
+ }
+ catch (const Exception&) {}
+}
+
+//------------------------------------------------------------------------------
+static bool impl_check()
+{
+ uno::Reference< uno::XComponentContext > xContext = comphelper_getProcessComponentContext();
+
+ bool bDependenciesValid = impl_checkDependencies( xContext );
+
+ short nRet = 0;
+
+ if ( !bDependenciesValid )
+ nRet = impl_showExtensionDialog( xContext );
+
+ if ( nRet == -1 )
+ {
+ impl_setNeedsCompatCheck();
+ return true;
+ }
+ else
+ return false;
+}
+
+//------------------------------------------------------------------------------
+// to check if we need checking the dependencies of the extensions again, we compare
+// the build id of the office with the one of the last check
+//------------------------------------------------------------------------------
+static bool impl_needsCompatCheck()
+{
+ bool bNeedsCheck = false;
+ rtl::OUString aLastCheckBuildID;
+ rtl::OUString aCurrentBuildID( UNISTRING( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}" ) );
+ rtl::Bootstrap::expandMacros( aCurrentBuildID );
+
+ try {
+ Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ // get configuration provider
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+
+ Sequence< Any > theArgs(1);
+ beans::NamedValue v( OUString::createFromAscii("NodePath"),
+ makeAny( OUString::createFromAscii("org.openoffice.Setup/Office") ) );
+ theArgs[0] <<= v;
+ Reference< beans::XPropertySet > pset = Reference< beans::XPropertySet >(
+ theConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY_THROW );
+
+ Any result = pset->getPropertyValue( OUString::createFromAscii("LastCompatibilityCheckID") );
+
+ result >>= aLastCheckBuildID;
+ if ( aLastCheckBuildID != aCurrentBuildID )
+ {
+ bNeedsCheck = true;
+ result <<= aCurrentBuildID;
+ pset->setPropertyValue( OUString::createFromAscii("LastCompatibilityCheckID"), result );
+ Reference< util::XChangesBatch >( pset, UNO_QUERY_THROW )->commitChanges();
+ }
+#ifdef DEBUG
+ bNeedsCheck = true;
+#endif
+ }
+ catch (const Exception&) {}
+
+ return bNeedsCheck;
+}
+
+//------------------------------------------------------------------------------
+// Do we need to check the dependencies of the extensions?
+// When there are unresolved issues, we can't continue with startup
+sal_Bool Desktop::CheckExtensionDependencies()
+{
+ sal_Bool bAbort = false;
+
+ if ( impl_needsCompatCheck() )
+ bAbort = impl_check();
+
+ return bAbort;
+}
+
+void Desktop::SynchronizeExtensionRepositories()
+{
+ RTL_LOGFILE_CONTEXT(aLog,"desktop (jl) ::Desktop::SynchronizeExtensionRepositories");
+ dp_misc::syncRepositories( new SilentCommandEnv( this ) );
+}
diff --git a/desktop/source/app/checkinstall.cxx b/desktop/source/app/checkinstall.cxx
new file mode 100644
index 000000000000..bb7258554cfe
--- /dev/null
+++ b/desktop/source/app/checkinstall.cxx
@@ -0,0 +1,118 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "checkinstall.hxx"
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <comphelper/processfactory.hxx>
+#include <vcl/msgbox.hxx>
+#include <tools/date.hxx>
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+
+namespace desktop
+{
+
+sal_Bool CheckInstallation( OUString& rTitle )
+{
+ try
+ {
+ Reference< XMultiServiceFactory > xSMgr = ::comphelper::getProcessServiceFactory();
+ Reference< XExactName > xExactName( xSMgr->createInstance(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.desktop.Evaluation" ))),
+ UNO_QUERY );
+ if ( xExactName.is() )
+ {
+ try
+ {
+ rTitle = xExactName->getExactName( rTitle );
+ Reference< XMaterialHolder > xMaterialHolder( xExactName, UNO_QUERY );
+ if ( xMaterialHolder.is() )
+ {
+ com::sun::star::util::Date aExpirationDate;
+ Any a = xMaterialHolder->getMaterial();
+ if ( a >>= aExpirationDate )
+ {
+ Date aToday;
+ Date aTimeBombDate( aExpirationDate.Day, aExpirationDate.Month, aExpirationDate.Year );
+ if ( aToday > aTimeBombDate )
+ {
+ InfoBox aInfoBox( NULL, String::CreateFromAscii( "This version has expired" ) );
+ aInfoBox.Execute();
+ return sal_False;
+ }
+ }
+
+ return sal_True;
+ }
+ else
+ {
+ InfoBox aInfoBox( NULL, rTitle );
+ aInfoBox.Execute();
+ return sal_False;
+ }
+ }
+ catch ( RuntimeException& )
+ {
+ // Evaluation version expired!
+ return sal_False;
+ }
+ }
+ else
+ {
+ Reference< com::sun::star::container::XContentEnumerationAccess > rContent( xSMgr , UNO_QUERY );
+ if( rContent.is() )
+ {
+ OUString sEvalService = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.office.Evaluation" ) );
+ Reference < com::sun::star::container::XEnumeration > rEnum = rContent->createContentEnumeration( sEvalService );
+ if ( rEnum.is() )
+ {
+ InfoBox aInfoBox( NULL, rTitle );
+ aInfoBox.Execute();
+ return sal_False;
+ }
+ }
+ }
+ }
+ catch(Exception)
+ {
+ }
+
+ return sal_True;
+}
+
+} // namespace desktop
diff --git a/desktop/source/app/checkinstall.hxx b/desktop/source/app/checkinstall.hxx
new file mode 100644
index 000000000000..495ea3161bd3
--- /dev/null
+++ b/desktop/source/app/checkinstall.hxx
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_CHECKINSTALL_HXX_
+#define _DESKTOP_CHECKINSTALL_HXX_
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+
+
+namespace desktop
+{
+
+sal_Bool CheckInstallation( rtl::OUString& rTitle );
+
+}
+
+#endif // _DESKTOP_CHECKINSTALL_HXX_
diff --git a/desktop/source/app/cmdlineargs.cxx b/desktop/source/app/cmdlineargs.cxx
new file mode 100644
index 000000000000..0625191ee2ea
--- /dev/null
+++ b/desktop/source/app/cmdlineargs.cxx
@@ -0,0 +1,900 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+#include <cmdlineargs.hxx>
+#include <vcl/svapp.hxx>
+#include <rtl/uri.hxx>
+#include <rtl/ustring.hxx>
+#include "rtl/process.h"
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/uri/XExternalUriReferenceTranslator.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include "tools/getprocessworkingdir.hxx"
+
+#include <svl/documentlockfile.hxx>
+
+using namespace rtl;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uri;
+using namespace com::sun::star::uno;
+
+namespace desktop
+{
+
+namespace {
+
+class ExtCommandLineSupplier: public CommandLineArgs::Supplier {
+public:
+ explicit ExtCommandLineSupplier():
+ m_count(rtl_getAppCommandArgCount()),
+ m_index(0)
+ {
+ rtl::OUString url;
+ if (tools::getProcessWorkingDir(&url)) {
+ m_cwdUrl.reset(url);
+ }
+ }
+
+ virtual ~ExtCommandLineSupplier() {}
+
+ virtual boost::optional< rtl::OUString > getCwdUrl() { return m_cwdUrl; }
+
+ virtual bool next(rtl::OUString * argument) {
+ OSL_ASSERT(argument != NULL);
+ if (m_index < m_count) {
+ rtl_getAppCommandArg(m_index++, &argument->pData);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+private:
+ boost::optional< rtl::OUString > m_cwdUrl;
+ sal_uInt32 m_count;
+ sal_uInt32 m_index;
+};
+
+}
+
+static CommandLineArgs::BoolParam aModuleGroupDefinition[] =
+{
+ CommandLineArgs::CMD_BOOLPARAM_WRITER,
+ CommandLineArgs::CMD_BOOLPARAM_CALC,
+ CommandLineArgs::CMD_BOOLPARAM_DRAW,
+ CommandLineArgs::CMD_BOOLPARAM_IMPRESS,
+ CommandLineArgs::CMD_BOOLPARAM_GLOBAL,
+ CommandLineArgs::CMD_BOOLPARAM_MATH,
+ CommandLineArgs::CMD_BOOLPARAM_WEB,
+ CommandLineArgs::CMD_BOOLPARAM_BASE
+};
+
+CommandLineArgs::GroupDefinition CommandLineArgs::m_pGroupDefinitions[ CommandLineArgs::CMD_GRPID_COUNT ] =
+{
+ { 8, aModuleGroupDefinition }
+};
+
+CommandLineArgs::Supplier::Exception::Exception() {}
+
+CommandLineArgs::Supplier::Exception::Exception(Exception const &) {}
+
+CommandLineArgs::Supplier::Exception::~Exception() {}
+
+CommandLineArgs::Supplier::Exception &
+CommandLineArgs::Supplier::Exception::operator =(Exception const &)
+{ return *this; }
+
+CommandLineArgs::Supplier::~Supplier() {}
+
+// intialize class with command line parameters from process environment
+CommandLineArgs::CommandLineArgs()
+{
+ ResetParamValues();
+ ExtCommandLineSupplier s;
+ ParseCommandLine_Impl( s );
+}
+
+CommandLineArgs::CommandLineArgs( Supplier& supplier )
+{
+ ResetParamValues();
+ ParseCommandLine_Impl( supplier );
+}
+
+// ----------------------------------------------------------------------------
+
+void CommandLineArgs::ParseCommandLine_Impl( Supplier& supplier )
+{
+ m_cwdUrl = supplier.getCwdUrl();
+ Reference<XMultiServiceFactory> xMS(comphelper::getProcessServiceFactory(), UNO_QUERY);
+ OSL_ENSURE(xMS.is(), "CommandLineArgs: no ProcessServiceFactory.");
+
+ Reference< XExternalUriReferenceTranslator > xTranslator(
+ xMS->createInstance(
+ OUString::createFromAscii(
+ "com.sun.star.uri.ExternalUriReferenceTranslator")),
+ UNO_QUERY);
+
+ // parse command line arguments
+ sal_Bool bPrintEvent = sal_False;
+ sal_Bool bOpenEvent = sal_True;
+ sal_Bool bViewEvent = sal_False;
+ sal_Bool bStartEvent = sal_False;
+ sal_Bool bPrintToEvent = sal_False;
+ sal_Bool bPrinterName = sal_False;
+ sal_Bool bForceOpenEvent = sal_False;
+ sal_Bool bForceNewEvent = sal_False;
+ sal_Bool bDisplaySpec = sal_False;
+
+ m_eArgumentCount = NONE;
+
+ for (;;)
+ {
+ ::rtl::OUString aArg;
+ if ( !supplier.next( &aArg ) )
+ {
+ break;
+ }
+ // convert file URLs to internal form #112849#
+ if (aArg.indexOf(OUString::createFromAscii("file:"))==0 &&
+ xTranslator.is())
+ {
+ OUString tmp(xTranslator->translateToInternal(aArg));
+ if (tmp.getLength() > 0)
+ aArg = tmp;
+ }
+ String aArgStr = aArg;
+
+ if ( aArg.getLength() > 0 )
+ {
+ m_eArgumentCount = m_eArgumentCount == NONE ? ONE : MANY;
+ if ( !InterpretCommandLineParameter( aArg ))
+ {
+ if ( aArgStr.GetChar(0) == '-' )
+ {
+ // handle this argument as an option
+ if ( aArgStr.EqualsIgnoreCaseAscii( "-n" ))
+ {
+ // force new documents based on the following documents
+ bForceNewEvent = sal_True;
+ bOpenEvent = sal_False;
+ bForceOpenEvent = sal_False;
+ bPrintToEvent = sal_False;
+ bPrintEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_False;
+ }
+ else if ( aArgStr.EqualsIgnoreCaseAscii( "-o" ))
+ {
+ // force open documents regards if they are templates or not
+ bForceOpenEvent = sal_True;
+ bOpenEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bPrintToEvent = sal_False;
+ bPrintEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_False;
+ }
+ else if ( aArgStr.EqualsIgnoreCaseAscii( "-pt" ))
+ {
+ // Print to special printer
+ bPrintToEvent = sal_True;
+ bPrinterName = sal_True;
+ bPrintEvent = sal_False;
+ bOpenEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_False;
+ bForceOpenEvent = sal_False;
+ }
+ else if ( aArgStr.EqualsIgnoreCaseAscii( "-p" ))
+ {
+ // Print to default printer
+ bPrintEvent = sal_True;
+ bPrintToEvent = sal_False;
+ bOpenEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bForceOpenEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_False;
+ }
+ else if ( aArgStr.EqualsIgnoreCaseAscii( "-view" ))
+ {
+ // open in viewmode
+ bOpenEvent = sal_False;
+ bPrintEvent = sal_False;
+ bPrintToEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bForceOpenEvent = sal_False;
+ bViewEvent = sal_True;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_False;
+ }
+ else if ( aArgStr.EqualsIgnoreCaseAscii( "-show" ))
+ {
+ // open in viewmode
+ bOpenEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_True;
+ bPrintEvent = sal_False;
+ bPrintToEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bForceOpenEvent = sal_False;
+ bDisplaySpec = sal_False;
+ }
+ else if ( aArgStr.EqualsIgnoreCaseAscii( "-display" ))
+ {
+ // set display
+ bOpenEvent = sal_False;
+ bPrintEvent = sal_False;
+ bForceOpenEvent = sal_False;
+ bPrintToEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_True;
+ }
+ else if ( aArgStr.EqualsIgnoreCaseAscii( "-language" ))
+ {
+ bOpenEvent = sal_False;
+ bPrintEvent = sal_False;
+ bForceOpenEvent = sal_False;
+ bPrintToEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_False;
+ }
+
+ #ifdef MACOSX
+ /* #i84053# ignore -psn on Mac
+ Platform dependent #ifdef here is ugly, however this is currently
+ the only platform dependent parameter. Should more appear
+ we should find a better solution
+ */
+ else if ( aArgStr.CompareToAscii( "-psn", 4 ) == COMPARE_EQUAL )
+ {
+ // finder argument from MacOSX
+ bOpenEvent = sal_False;
+ bPrintEvent = sal_False;
+ bForceOpenEvent = sal_False;
+ bPrintToEvent = sal_False;
+ bForceNewEvent = sal_False;
+ bViewEvent = sal_False;
+ bStartEvent = sal_False;
+ bDisplaySpec = sal_False;
+ }
+ #endif
+ }
+ else
+ {
+ if ( bPrinterName && bPrintToEvent )
+ {
+ // first argument after "-pt" this must be the printer name
+ AddStringListParam_Impl( CMD_STRINGPARAM_PRINTERNAME, aArgStr );
+ bPrinterName = sal_False;
+ }
+ else
+ {
+ // handle this argument as a filename
+ if ( bOpenEvent )
+ AddStringListParam_Impl( CMD_STRINGPARAM_OPENLIST, aArgStr );
+ else if ( bViewEvent )
+ AddStringListParam_Impl( CMD_STRINGPARAM_VIEWLIST, aArgStr );
+ else if ( bStartEvent )
+ AddStringListParam_Impl( CMD_STRINGPARAM_STARTLIST, aArgStr );
+ else if ( bPrintEvent )
+ AddStringListParam_Impl( CMD_STRINGPARAM_PRINTLIST, aArgStr );
+ else if ( bPrintToEvent )
+ AddStringListParam_Impl( CMD_STRINGPARAM_PRINTTOLIST, aArgStr );
+ else if ( bForceNewEvent )
+ AddStringListParam_Impl( CMD_STRINGPARAM_FORCENEWLIST, aArgStr );
+ else if ( bForceOpenEvent )
+ AddStringListParam_Impl( CMD_STRINGPARAM_FORCEOPENLIST, aArgStr );
+ else if ( bDisplaySpec ){
+ AddStringListParam_Impl( CMD_STRINGPARAM_DISPLAY, aArgStr );
+ bDisplaySpec = sal_False; // only one display, not a lsit
+ bOpenEvent = sal_True; // set back to standard
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void CommandLineArgs::AddStringListParam_Impl( StringParam eParam, const rtl::OUString& aParam )
+{
+ OSL_ASSERT( eParam >= 0 && eParam < CMD_STRINGPARAM_COUNT );
+ if ( m_aStrParams[eParam].getLength() )
+ m_aStrParams[eParam] += ::rtl::OUString::valueOf( (sal_Unicode)APPEVENT_PARAM_DELIMITER );
+ m_aStrParams[eParam] += aParam;
+ m_aStrSetParams[eParam] = sal_True;
+}
+
+void CommandLineArgs::SetBoolParam_Impl( BoolParam eParam, sal_Bool bValue )
+{
+ OSL_ASSERT( eParam >= 0 && eParam < CMD_BOOLPARAM_COUNT );
+ m_aBoolParams[eParam] = bValue;
+}
+
+sal_Bool CommandLineArgs::InterpretCommandLineParameter( const ::rtl::OUString& aArg )
+{
+ String aArgStr( aArg );
+
+ if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-minimized" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_MINIMIZED, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-invisible" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_INVISIBLE, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-norestore" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NORESTORE, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-nodefault" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NODEFAULT, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-bean" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_BEAN, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-plugin" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_PLUGIN, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-server" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_SERVER, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-headless" )) == sal_True )
+ {
+ // Headless means also invisibile, so set this parameter to true!
+ SetBoolParam_Impl( CMD_BOOLPARAM_HEADLESS, sal_True );
+ SetBoolParam_Impl( CMD_BOOLPARAM_INVISIBLE, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-quickstart" )) == sal_True )
+ {
+#if defined(WNT) || defined(OS2) || defined(QUARTZ)
+ SetBoolParam_Impl( CMD_BOOLPARAM_QUICKSTART, sal_True );
+#endif
+ SetBoolParam_Impl( CMD_BOOLPARAM_NOQUICKSTART, sal_False );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-quickstart=no" )))
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NOQUICKSTART, sal_True );
+ SetBoolParam_Impl( CMD_BOOLPARAM_QUICKSTART, sal_False );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-terminate_after_init" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_TERMINATEAFTERINIT, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-nofirststartwizard" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NOFIRSTSTARTWIZARD, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-nologo" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NOLOGO, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-nolockcheck" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_NOLOCKCHECK, sal_True );
+ // Workaround for automated testing
+ ::svt::DocumentLockFile::AllowInteraction( sal_False );
+
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-help" ))
+ || aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-h" ))
+ || aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-?" )))
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELP, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-helpwriter" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPWRITER, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-helpcalc" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPCALC, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-helpdraw" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPDRAW, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-helpimpress" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPIMPRESS, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-helpbase" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPBASE, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-helpbasic" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPBASIC, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-helpmath" )) == sal_True )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_HELPMATH, sal_True );
+ return sal_True;
+ }
+ #ifdef MACOSX
+ /* #i84053# ignore -psn on Mac
+ Platform dependent #ifdef here is ugly, however this is currently
+ the only platform dependent parameter. Should more appear
+ we should find a better solution
+ */
+ else if ( aArg.compareToAscii( "-psn", 4 ) == 0 )
+ {
+ SetBoolParam_Impl( CMD_BOOLPARAM_PSN, sal_True );
+ return sal_True;
+ }
+ #endif
+ else if ( aArgStr.Copy(0, 8).EqualsIgnoreCaseAscii( "-accept=" ))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_ACCEPT, aArgStr.Copy( 8 ) );
+ return sal_True;
+ }
+ else if ( aArgStr.Copy(0, 10).EqualsIgnoreCaseAscii( "-unaccept=" ))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_UNACCEPT, aArgStr.Copy( 10 ) );
+ return sal_True;
+ }
+ else if ( aArgStr.CompareIgnoreCaseToAscii( "-portal," ,
+ RTL_CONSTASCII_LENGTH( "-portal," )) == COMPARE_EQUAL )
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_PORTAL, aArgStr.Copy( RTL_CONSTASCII_LENGTH( "-portal," )) );
+ return sal_True;
+ }
+ else if ( aArgStr.Copy( 0, 7 ).EqualsIgnoreCaseAscii( "-userid" ))
+ {
+ if ( aArgStr.Len() > 8 )
+ {
+ rtl::OUString aUserDir = aArgStr;
+ AddStringListParam_Impl(
+ CMD_STRINGPARAM_USERDIR,
+ ::rtl::Uri::decode( aUserDir.copy( 8 ),
+ rtl_UriDecodeWithCharset,
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+ return sal_True;
+ }
+ else if ( aArgStr.Copy( 0, 15).EqualsIgnoreCaseAscii( "-clientdisplay=" ))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_CLIENTDISPLAY, aArgStr.Copy( 15 ) );
+ return sal_True;
+ }
+ else if ( aArgStr.Copy(0, 9).EqualsIgnoreCaseAscii( "-version=" ))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_VERSION, aArgStr.Copy( 9 ) );
+ return sal_True;
+ }
+ else if ( aArgStr.Copy(0, 10).EqualsIgnoreCaseAscii( "-language=" ))
+ {
+ AddStringListParam_Impl( CMD_STRINGPARAM_LANGUAGE, aArgStr.Copy( 10 ) );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-writer" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_WRITER );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_WRITER, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-calc" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_CALC );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_CALC, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-draw" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_DRAW );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_DRAW, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-impress" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_IMPRESS );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_IMPRESS, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-base" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_BASE );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_BASE, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-global" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_GLOBAL );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_GLOBAL, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-math" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_MATH );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_MATH, sal_True );
+ return sal_True;
+ }
+ else if ( aArg.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "-web" )) == sal_True )
+ {
+ sal_Bool bAlreadySet = CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_WEB );
+ if ( !bAlreadySet )
+ SetBoolParam_Impl( CMD_BOOLPARAM_WEB, sal_True );
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+sal_Bool CommandLineArgs::CheckGroupMembers( GroupParamId nGroupId, BoolParam nExcludeMember ) const
+{
+ // Check if at least one bool param out of a group is set. An exclude member can be provided.
+ for ( int i = 0; i < m_pGroupDefinitions[nGroupId].nCount; i++ )
+ {
+ BoolParam nParam = m_pGroupDefinitions[nGroupId].pGroupMembers[i];
+ if ( nParam != nExcludeMember && m_aBoolParams[nParam] )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+void CommandLineArgs::ResetParamValues()
+{
+ int i;
+
+ for ( i = 0; i < CMD_BOOLPARAM_COUNT; i++ )
+ m_aBoolParams[i] = sal_False;
+ for ( i = 0; i < CMD_STRINGPARAM_COUNT; i++ )
+ m_aStrSetParams[i] = sal_False;
+ m_eArgumentCount = NONE;
+}
+
+void CommandLineArgs::SetBoolParam( BoolParam eParam, sal_Bool bNewValue )
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+
+ OSL_ASSERT( ( eParam >= 0 && eParam < CMD_BOOLPARAM_COUNT ) );
+ m_aBoolParams[eParam] = bNewValue;
+}
+
+sal_Bool CommandLineArgs::IsMinimized() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_MINIMIZED ];
+}
+
+sal_Bool CommandLineArgs::IsInvisible() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_INVISIBLE ];
+}
+
+sal_Bool CommandLineArgs::IsNoRestore() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NORESTORE ];
+}
+
+sal_Bool CommandLineArgs::IsNoDefault() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NODEFAULT ];
+}
+
+sal_Bool CommandLineArgs::IsBean() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_BEAN ];
+}
+
+sal_Bool CommandLineArgs::IsServer() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_SERVER ];
+}
+
+sal_Bool CommandLineArgs::IsHeadless() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HEADLESS ];
+}
+
+sal_Bool CommandLineArgs::IsQuickstart() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_QUICKSTART ];
+}
+
+sal_Bool CommandLineArgs::IsNoQuickstart() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NOQUICKSTART ];
+}
+
+sal_Bool CommandLineArgs::IsTerminateAfterInit() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_TERMINATEAFTERINIT ];
+}
+
+sal_Bool CommandLineArgs::IsNoFirstStartWizard() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NOFIRSTSTARTWIZARD ];
+}
+
+sal_Bool CommandLineArgs::IsNoLogo() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NOLOGO ];
+}
+
+sal_Bool CommandLineArgs::IsNoLockcheck() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_NOLOCKCHECK ];
+}
+
+sal_Bool CommandLineArgs::IsHelp() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELP ];
+}
+sal_Bool CommandLineArgs::IsHelpWriter() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPWRITER ];
+}
+
+sal_Bool CommandLineArgs::IsHelpCalc() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPCALC ];
+}
+
+sal_Bool CommandLineArgs::IsHelpDraw() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPDRAW ];
+}
+
+sal_Bool CommandLineArgs::IsHelpImpress() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPIMPRESS ];
+}
+
+sal_Bool CommandLineArgs::IsHelpBase() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPBASE ];
+}
+sal_Bool CommandLineArgs::IsHelpMath() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPMATH ];
+}
+sal_Bool CommandLineArgs::IsHelpBasic() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_HELPBASIC ];
+}
+
+sal_Bool CommandLineArgs::IsWriter() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_WRITER ];
+}
+
+sal_Bool CommandLineArgs::IsCalc() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_CALC ];
+}
+
+sal_Bool CommandLineArgs::IsDraw() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_DRAW ];
+}
+
+sal_Bool CommandLineArgs::IsImpress() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_IMPRESS ];
+}
+
+sal_Bool CommandLineArgs::IsBase() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_BASE ];
+}
+
+sal_Bool CommandLineArgs::IsGlobal() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_GLOBAL ];
+}
+
+sal_Bool CommandLineArgs::IsMath() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_MATH ];
+}
+
+sal_Bool CommandLineArgs::IsWeb() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_aBoolParams[ CMD_BOOLPARAM_WEB ];
+}
+
+sal_Bool CommandLineArgs::HasModuleParam() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return CheckGroupMembers( CMD_GRPID_MODULE, CMD_BOOLPARAM_COUNT );
+}
+
+sal_Bool CommandLineArgs::GetPortalConnectString( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_PORTAL ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_PORTAL ];
+}
+
+sal_Bool CommandLineArgs::GetAcceptString( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_ACCEPT ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_ACCEPT ];
+}
+
+sal_Bool CommandLineArgs::GetUnAcceptString( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_UNACCEPT ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_UNACCEPT ];
+}
+
+sal_Bool CommandLineArgs::GetOpenList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_OPENLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_OPENLIST ];
+}
+
+sal_Bool CommandLineArgs::GetViewList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_VIEWLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_VIEWLIST ];
+}
+
+sal_Bool CommandLineArgs::GetStartList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_STARTLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_STARTLIST ];
+}
+
+sal_Bool CommandLineArgs::GetForceOpenList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_FORCEOPENLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_FORCEOPENLIST ];
+}
+
+sal_Bool CommandLineArgs::GetForceNewList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_FORCENEWLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_FORCENEWLIST ];
+}
+
+sal_Bool CommandLineArgs::GetPrintList( ::rtl::OUString& rPara) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_PRINTLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_PRINTLIST ];
+}
+
+sal_Bool CommandLineArgs::GetPrintToList( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_PRINTTOLIST ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_PRINTTOLIST ];
+}
+
+sal_Bool CommandLineArgs::GetPrinterName( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_PRINTERNAME ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_PRINTERNAME ];
+}
+
+sal_Bool CommandLineArgs::GetLanguage( ::rtl::OUString& rPara ) const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ rPara = m_aStrParams[ CMD_STRINGPARAM_LANGUAGE ];
+ return m_aStrSetParams[ CMD_STRINGPARAM_LANGUAGE ];
+}
+
+sal_Bool CommandLineArgs::IsEmpty() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+ return m_eArgumentCount == NONE;
+}
+
+sal_Bool CommandLineArgs::IsEmptyOrAcceptOnly() const
+{
+ osl::MutexGuard aMutexGuard( m_aMutex );
+
+ return m_eArgumentCount == NONE ||
+ ( ( m_eArgumentCount == ONE ) && ( m_aStrParams[ CMD_STRINGPARAM_ACCEPT ].getLength() )) ||
+ ( ( m_eArgumentCount == ONE ) && m_aBoolParams[ CMD_BOOLPARAM_PSN ] );
+}
+
+} // namespace desktop
diff --git a/desktop/source/app/cmdlineargs.hxx b/desktop/source/app/cmdlineargs.hxx
new file mode 100644
index 000000000000..615577098c2d
--- /dev/null
+++ b/desktop/source/app/cmdlineargs.hxx
@@ -0,0 +1,212 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_COMMANDLINEARGS_HXX_
+#define _DESKTOP_COMMANDLINEARGS_HXX_
+
+#include <rtl/ustring.hxx>
+#include <osl/mutex.hxx>
+#include "boost/optional.hpp"
+
+namespace desktop
+{
+
+class CommandLineArgs
+{
+ public:
+ enum BoolParam // must be zero based!
+ {
+ CMD_BOOLPARAM_MINIMIZED,
+ CMD_BOOLPARAM_INVISIBLE,
+ CMD_BOOLPARAM_NORESTORE,
+ CMD_BOOLPARAM_BEAN,
+ CMD_BOOLPARAM_PLUGIN,
+ CMD_BOOLPARAM_SERVER,
+ CMD_BOOLPARAM_HEADLESS,
+ CMD_BOOLPARAM_QUICKSTART,
+ CMD_BOOLPARAM_NOQUICKSTART,
+ CMD_BOOLPARAM_TERMINATEAFTERINIT,
+ CMD_BOOLPARAM_NOFIRSTSTARTWIZARD,
+ CMD_BOOLPARAM_NOLOGO,
+ CMD_BOOLPARAM_NOLOCKCHECK,
+ CMD_BOOLPARAM_NODEFAULT,
+ CMD_BOOLPARAM_HELP,
+ CMD_BOOLPARAM_WRITER,
+ CMD_BOOLPARAM_CALC,
+ CMD_BOOLPARAM_DRAW,
+ CMD_BOOLPARAM_IMPRESS,
+ CMD_BOOLPARAM_GLOBAL,
+ CMD_BOOLPARAM_MATH,
+ CMD_BOOLPARAM_WEB,
+ CMD_BOOLPARAM_BASE,
+ CMD_BOOLPARAM_HELPWRITER,
+ CMD_BOOLPARAM_HELPCALC,
+ CMD_BOOLPARAM_HELPDRAW,
+ CMD_BOOLPARAM_HELPBASIC,
+ CMD_BOOLPARAM_HELPMATH,
+ CMD_BOOLPARAM_HELPIMPRESS,
+ CMD_BOOLPARAM_HELPBASE,
+ CMD_BOOLPARAM_PSN,
+ CMD_BOOLPARAM_COUNT // must be last element!
+ };
+
+ enum StringParam // must be zero based!
+ {
+ CMD_STRINGPARAM_PORTAL,
+ CMD_STRINGPARAM_ACCEPT,
+ CMD_STRINGPARAM_UNACCEPT,
+ CMD_STRINGPARAM_USERDIR,
+ CMD_STRINGPARAM_CLIENTDISPLAY,
+ CMD_STRINGPARAM_OPENLIST,
+ CMD_STRINGPARAM_VIEWLIST,
+ CMD_STRINGPARAM_STARTLIST,
+ CMD_STRINGPARAM_FORCEOPENLIST,
+ CMD_STRINGPARAM_FORCENEWLIST,
+ CMD_STRINGPARAM_PRINTLIST,
+ CMD_STRINGPARAM_VERSION,
+ CMD_STRINGPARAM_PRINTTOLIST,
+ CMD_STRINGPARAM_PRINTERNAME,
+ CMD_STRINGPARAM_DISPLAY,
+ CMD_STRINGPARAM_LANGUAGE,
+ CMD_STRINGPARAM_COUNT // must be last element!
+ };
+
+ enum GroupParamId
+ {
+ CMD_GRPID_MODULE,
+ CMD_GRPID_COUNT
+ };
+
+ struct Supplier {
+ // Thrown from constructors and next:
+ class Exception {
+ public:
+ Exception();
+ Exception(Exception const &);
+ virtual ~Exception();
+ Exception & operator =(Exception const &);
+ };
+
+ virtual ~Supplier();
+ virtual boost::optional< rtl::OUString > getCwdUrl() = 0;
+ virtual bool next(rtl::OUString * argument) = 0;
+ };
+
+ CommandLineArgs();
+ CommandLineArgs( Supplier& supplier );
+
+ boost::optional< rtl::OUString > getCwdUrl() const { return m_cwdUrl; }
+
+ // generic methods to access parameter
+ void SetBoolParam( BoolParam eParam, sal_Bool bNewValue );
+
+ // Access to bool parameters
+ sal_Bool IsMinimized() const;
+ sal_Bool IsInvisible() const;
+ sal_Bool IsNoRestore() const;
+ sal_Bool IsNoDefault() const;
+ sal_Bool IsBean() const;
+ sal_Bool IsServer() const;
+ sal_Bool IsHeadless() const;
+ sal_Bool IsQuickstart() const;
+ sal_Bool IsNoQuickstart() const;
+ sal_Bool IsTerminateAfterInit() const;
+ sal_Bool IsNoFirstStartWizard() const;
+ sal_Bool IsNoLogo() const;
+ sal_Bool IsNoLockcheck() const;
+ sal_Bool IsHelp() const;
+ sal_Bool IsHelpWriter() const;
+ sal_Bool IsHelpCalc() const;
+ sal_Bool IsHelpDraw() const;
+ sal_Bool IsHelpImpress() const;
+ sal_Bool IsHelpBase() const;
+ sal_Bool IsHelpMath() const;
+ sal_Bool IsHelpBasic() const;
+ sal_Bool IsWriter() const;
+ sal_Bool IsCalc() const;
+ sal_Bool IsDraw() const;
+ sal_Bool IsImpress() const;
+ sal_Bool IsBase() const;
+ sal_Bool IsGlobal() const;
+ sal_Bool IsMath() const;
+ sal_Bool IsWeb() const;
+ sal_Bool HasModuleParam() const;
+
+ // Access to string parameters
+ sal_Bool GetPortalConnectString( ::rtl::OUString& rPara) const;
+ sal_Bool GetAcceptString( ::rtl::OUString& rPara) const;
+ sal_Bool GetUnAcceptString( ::rtl::OUString& rPara) const;
+ sal_Bool GetOpenList( ::rtl::OUString& rPara) const;
+ sal_Bool GetViewList( ::rtl::OUString& rPara) const;
+ sal_Bool GetStartList( ::rtl::OUString& rPara) const;
+ sal_Bool GetForceOpenList( ::rtl::OUString& rPara) const;
+ sal_Bool GetForceNewList( ::rtl::OUString& rPara) const;
+ sal_Bool GetPrintList( ::rtl::OUString& rPara) const;
+ sal_Bool GetPrintToList( ::rtl::OUString& rPara ) const;
+ sal_Bool GetPrinterName( ::rtl::OUString& rPara ) const;
+ sal_Bool GetLanguage( ::rtl::OUString& rPara ) const;
+
+ // Special analyzed states (does not match directly to a command line parameter!)
+ sal_Bool IsPrinting() const;
+ sal_Bool IsEmpty() const;
+ sal_Bool IsEmptyOrAcceptOnly() const;
+
+ private:
+ enum Count { NONE, ONE, MANY };
+
+ struct GroupDefinition
+ {
+ sal_Int32 nCount;
+ BoolParam* pGroupMembers;
+ };
+
+ // no copy and operator=
+ CommandLineArgs( const CommandLineArgs& );
+ CommandLineArgs operator=( const CommandLineArgs& );
+
+ sal_Bool InterpretCommandLineParameter( const ::rtl::OUString& );
+ void ParseCommandLine_Impl( Supplier& supplier );
+ void ResetParamValues();
+ sal_Bool CheckGroupMembers( GroupParamId nGroup, BoolParam nExcludeMember ) const;
+
+ void AddStringListParam_Impl( StringParam eParam, const rtl::OUString& aParam );
+ void SetBoolParam_Impl( BoolParam eParam, sal_Bool bValue );
+
+ boost::optional< rtl::OUString > m_cwdUrl;
+ sal_Bool m_aBoolParams[ CMD_BOOLPARAM_COUNT ]; // Stores boolean parameters
+ rtl::OUString m_aStrParams[ CMD_STRINGPARAM_COUNT ]; // Stores string parameters
+ sal_Bool m_aStrSetParams[ CMD_STRINGPARAM_COUNT ]; // Stores if string parameters are provided on cmdline
+ Count m_eArgumentCount; // Number of Args
+ mutable ::osl::Mutex m_aMutex;
+
+ // static definition for groups where only one member can be true
+ static GroupDefinition m_pGroupDefinitions[ CMD_GRPID_COUNT ];
+};
+
+}
+
+#endif
diff --git a/desktop/source/app/cmdlinehelp.cxx b/desktop/source/app/cmdlinehelp.cxx
new file mode 100644
index 000000000000..c4530e9ce61c
--- /dev/null
+++ b/desktop/source/app/cmdlinehelp.cxx
@@ -0,0 +1,173 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include <stdlib.h>
+#ifdef UNX
+#include <stdio.h>
+#endif
+#include <sal/types.h>
+#include <tools/string.hxx>
+#include <vcl/msgbox.hxx>
+#include <rtl/bootstrap.hxx>
+#include <app.hxx>
+
+#include "desktopresid.hxx"
+#include "desktop.hrc"
+#include "cmdlinehelp.hxx"
+
+namespace desktop
+{
+ // to be able to display the help nicely in a dialog box with propotional font,
+ // we need to split it in chunks...
+ // ___HEAD___
+ // LEFT RIGHT
+ // LEFT RIGHT
+ // LEFT RIGHT
+ // __BOTTOM__
+ // [OK]
+
+ const char *aCmdLineHelp_head =
+ "%PRODUCTNAME %PRODUCTVERSION %PRODUCTEXTENSION %BUILDID\n"\
+ "\n"\
+ "Usage: %CMDNAME [options] [documents...]\n"\
+ "\n"\
+ "Options:\n";
+ const char *aCmdLineHelp_left =
+ "-minimized \n"\
+ "-invisible \n"\
+ "-norestore \n"\
+ "-quickstart \n"\
+ "-nologo \n"\
+ "-nolockcheck \n"\
+ "-nodefault \n"\
+ "-headless \n"\
+ "-help/-h/-? \n"\
+ "-writer \n"\
+ "-calc \n"\
+ "-draw \n"\
+ "-impress \n"\
+ "-base \n"\
+ "-math \n"\
+ "-global \n"\
+ "-web \n"\
+ "-o \n"\
+ "-n \n";
+ const char *aCmdLineHelp_right =
+ "keep startup bitmap minimized.\n"\
+ "no startup screen, no default document and no UI.\n"\
+ "suppress restart/restore after fatal errors.\n"\
+ "starts the quickstart service (only available on windows and OS/2 platform)\n"\
+ "don't show startup screen.\n"\
+ "don't check for remote instances using the installation\n"\
+ "don't start with an empty document\n"\
+ "like invisible but no userinteraction at all.\n"\
+ "show this message and exit.\n"\
+ "create new text document.\n"\
+ "create new spreadsheet document.\n"\
+ "create new drawing.\n"\
+ "create new presentation.\n"\
+ "create new database.\n"\
+ "create new formula.\n"\
+ "create new global document.\n"\
+ "create new HTML document.\n"\
+ "open documents regardless whether they are templates or not.\n"\
+ "always open documents as new files (use as template).\n";
+ const char *aCmdLineHelp_bottom =
+ "-display <display>\n"\
+ " Specify X-Display to use in Unix/X11 versions.\n"
+ "-p <documents...>\n"\
+ " print the specified documents on the default printer.\n"\
+ "-pt <printer> <documents...>\n"\
+ " print the specified documents on the specified printer.\n"\
+ "-view <documents...>\n"\
+ " open the specified documents in viewer-(readonly-)mode.\n"\
+ "-show <presentation>\n"\
+ " open the specified presentation and start it immediately\n"\
+ "-accept=<accept-string>\n"\
+ " Specify an UNO connect-string to create an UNO acceptor through which\n"\
+ " other programs can connect to access the API\n"\
+ "-unaccept=<accept-string>\n"\
+ " Close an acceptor that was created with -accept=<accept-string>\n"\
+ " Use -unnaccept=all to close all open acceptors\n"\
+ "Remaining arguments will be treated as filenames or URLs of documents to open.\n";
+
+ void ReplaceStringHookProc( UniString& rStr );
+
+ void displayCmdlineHelp()
+ {
+ // if you put variables in other chunks don't forget to call the replace routines
+ // for those chunks...
+ String aHelpMessage_head(aCmdLineHelp_head, RTL_TEXTENCODING_ASCII_US);
+ String aHelpMessage_left(aCmdLineHelp_left, RTL_TEXTENCODING_ASCII_US);
+ String aHelpMessage_right(aCmdLineHelp_right, RTL_TEXTENCODING_ASCII_US);
+ String aHelpMessage_bottom(aCmdLineHelp_bottom, RTL_TEXTENCODING_ASCII_US);
+ ReplaceStringHookProc(aHelpMessage_head);
+ ::rtl::OUString aDefault;
+ String aVerId( ::utl::Bootstrap::getBuildIdData( aDefault ));
+ aHelpMessage_head.SearchAndReplaceAscii( "%BUILDID", aVerId );
+ aHelpMessage_head.SearchAndReplaceAscii( "%CMDNAME", String( "soffice", RTL_TEXTENCODING_ASCII_US) );
+#ifdef UNX
+ // on unix use console for output
+ fprintf(stderr, "%s\n", ByteString(aHelpMessage_head,
+ RTL_TEXTENCODING_ASCII_US).GetBuffer());
+ // merge left and right column
+ int n = aHelpMessage_left.GetTokenCount ('\n');
+ ByteString bsLeft(aHelpMessage_left, RTL_TEXTENCODING_ASCII_US);
+ ByteString bsRight(aHelpMessage_right, RTL_TEXTENCODING_ASCII_US);
+ for ( int i = 0; i < n; i++ )
+ {
+ fprintf(stderr, "%s", bsLeft.GetToken(i, '\n').GetBuffer());
+ fprintf(stderr, "%s\n", bsRight.GetToken(i, '\n').GetBuffer());
+ }
+ fprintf(stderr, "%s", ByteString(aHelpMessage_bottom,
+ RTL_TEXTENCODING_ASCII_US).GetBuffer());
+#else
+ // rest gets a dialog box
+ CmdlineHelpDialog aDlg;
+ aDlg.m_ftHead.SetText(aHelpMessage_head);
+ aDlg.m_ftLeft.SetText(aHelpMessage_left);
+ aDlg.m_ftRight.SetText(aHelpMessage_right);
+ aDlg.m_ftBottom.SetText(aHelpMessage_bottom);
+ aDlg.Execute();
+#endif
+ }
+#ifndef UNX
+ CmdlineHelpDialog::CmdlineHelpDialog (void)
+ : ModalDialog( NULL, DesktopResId( DLG_CMDLINEHELP ) )
+ , m_ftHead( this, DesktopResId( TXT_DLG_CMDLINEHELP_HEADER ) )
+ , m_ftLeft( this, DesktopResId( TXT_DLG_CMDLINEHELP_LEFT ) )
+ , m_ftRight( this, DesktopResId( TXT_DLG_CMDLINEHELP_RIGHT ) )
+ , m_ftBottom( this, DesktopResId( TXT_DLG_CMDLINEHELP_BOTTOM ) )
+ , m_btOk( this, DesktopResId( BTN_DLG_CMDLINEHELP_OK ) )
+ {
+ FreeResource();
+ }
+#endif
+}
diff --git a/desktop/source/app/cmdlinehelp.hxx b/desktop/source/app/cmdlinehelp.hxx
new file mode 100644
index 000000000000..4bca6e7e7d1a
--- /dev/null
+++ b/desktop/source/app/cmdlinehelp.hxx
@@ -0,0 +1,23 @@
+#include <vcl/dialog.hxx>
+#include <vcl/fixed.hxx>
+#ifndef _SV_BUTTON_HXX
+#include <vcl/button.hxx>
+#endif
+
+namespace desktop
+{
+ void displayCmdlineHelp( void );
+#ifndef UNX
+ class CmdlineHelpDialog : public ModalDialog
+ {
+ public:
+ CmdlineHelpDialog ( void );
+
+ FixedText m_ftHead;
+ FixedText m_ftLeft;
+ FixedText m_ftRight;
+ FixedText m_ftBottom;
+ OKButton m_btOk;
+ };
+#endif
+}
diff --git a/desktop/source/app/configinit.cxx b/desktop/source/app/configinit.cxx
new file mode 100644
index 000000000000..bd722a136e8a
--- /dev/null
+++ b/desktop/source/app/configinit.cxx
@@ -0,0 +1,303 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "configinit.hxx"
+
+#include "desktop.hrc"
+#include "app.hxx"
+#include <comphelper/processfactory.hxx>
+#include <uno/current_context.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <stdio.h>
+#include <map>
+#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
+#include <com/sun/star/configuration/CannotLoadConfigurationException.hpp>
+#include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
+#include <com/sun/star/configuration/backend/BackendSetupException.hpp>
+#include <com/sun/star/configuration/backend/CannotConnectException.hpp>
+
+// ----------------------------------------------------------------------------
+
+namespace uno = ::com::sun::star::uno;
+namespace lang = ::com::sun::star::lang;
+namespace configuration = ::com::sun::star::configuration;
+namespace backend = ::com::sun::star::configuration::backend;
+using rtl::OUString;
+using uno::UNO_QUERY;
+using desktop::Desktop;
+
+// ----------------------------------------------------------------------------
+static char const CONFIGURATION_PROVIDER[] = "com.sun.star.configuration.ConfigurationProvider";
+
+static char const CONFIGURATION_ERROR_HANDLER[] = "com.sun.star.configuration.backend.InteractionHandler";
+
+// must be aligned with configmgr/source/misc/configinteractionhandler
+static char const CONFIG_ERROR_HANDLER[] = "configuration.interaction-handler";
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+#define arraysize( arr ) ( sizeof (arr)/sizeof *(arr) )
+
+typedef uno::Reference< lang::XMultiServiceFactory > ConfigurationProvider;
+
+#define OUSTRING( constascii ) OUString( RTL_CONSTASCII_USTRINGPARAM( constascii ) )
+
+#define OU2O( ustr, enc ) rtl::OUStringToOString( (ustr), RTL_TEXTENCODING_ ## enc )
+
+#define k_PROVIDER OUSTRING( CONFIGURATION_PROVIDER )
+#define k_ERRORHANDLER OUSTRING( CONFIGURATION_ERROR_HANDLER )
+// ----------------------------------------------------------------------------
+// Get a message string securely. There is a fallback string if the resource
+// is not available. Adapted from Desktop::GetMsgString()
+
+OUString getMsgString( USHORT nId, char const * aFallBackMsg )
+{
+ ResMgr* pResMgr = Desktop::GetDesktopResManager();
+ if ( !pResMgr || !nId )
+ return OUString::createFromAscii(aFallBackMsg);
+ else
+ return OUString( String(ResId( nId, *pResMgr )));
+}
+// ----------------------------------------------------------------------------
+/** Creates the normal configuration provider.
+
+*/
+static
+ConfigurationProvider createDefaultConfigurationProvider( )
+{
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
+
+ OSL_ENSURE( xServiceManager.is(),"No ServiceManager set for CreateApplicationConfigurationProvider");
+
+ ConfigurationProvider xProvider;
+
+ if (xServiceManager.is())
+ {
+
+ xProvider.set( xServiceManager->createInstance(k_PROVIDER), UNO_QUERY);
+ }
+
+ if (!xProvider.is())
+ {
+ OUString const sMsg = OUSTRING("Service \"") + k_PROVIDER +
+ OUSTRING("\" is not available at the service manager.");
+
+ throw lang::ServiceNotRegisteredException(sMsg, xServiceManager);
+ }
+
+ return xProvider;
+}
+// ----------------------------------------------------------------------------
+/// @attention this method must be called from a catch statement!
+static void handleGeneralException(uno::Exception& aException,
+ const rtl::OUString& aMessage)
+{
+ aException.Message = aMessage ;
+ throw ;
+}
+// ----------------------------------------------------------------------------
+
+uno::Reference< lang::XMultiServiceFactory > CreateApplicationConfigurationProvider( )
+{
+ uno::Reference< lang::XMultiServiceFactory > xProvider;
+
+ try
+ {
+ xProvider = createDefaultConfigurationProvider( );
+ }
+ catch (configuration::InvalidBootstrapFileException & exception)
+ {
+ handleGeneralException(exception,
+ getMsgString( STR_CONFIG_ERR_SETTINGS_INCOMPLETE,
+ "The startup settings for your configuration settings are incomplete. "));
+ }
+ catch (backend::CannotConnectException & exception)
+ {
+ handleGeneralException(exception,
+ getMsgString( STR_CONFIG_ERR_CANNOT_CONNECT,
+ "A connection to your configuration settings could not be established. "));
+ }
+ catch (backend::BackendSetupException & exception)
+ {
+ handleGeneralException(exception,
+ getMsgString( STR_CONFIG_ERR_CANNOT_CONNECT,
+ "A connection to your configuration settings could not be established. "));
+ }
+ catch (configuration::CannotLoadConfigurationException & exception)
+ {
+ handleGeneralException(exception,
+ getMsgString( STR_CONFIG_ERR_CANNOT_CONNECT,
+ "A connection to your configuration settings could not be established. "));
+ }
+ catch (uno::Exception & exception)
+ {
+ handleGeneralException(exception,
+ getMsgString( STR_CONFIG_ERR_ACCESS_GENERAL,
+ "A general error occurred while accessing your configuration settings."));
+ }
+
+
+ return xProvider ;
+}
+// ----------------------------------------------------------------------------
+
+
+
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+// ConfigurationErrorHandler
+// ----------------------------------------------------------------------------
+
+namespace
+{
+ typedef uno::Reference< uno::XCurrentContext > CurrentContext;
+ class SimpleCurrentContext : public cppu::WeakImplHelper1< uno::XCurrentContext >
+ {
+ CurrentContext m_xChainedContext;
+ public:
+ explicit
+ SimpleCurrentContext(const CurrentContext & xChainedContext)
+ : m_xChainedContext(xChainedContext)
+ {}
+
+ void install() { uno::setCurrentContext(this); }
+ void deinstall() { uno::setCurrentContext(m_xChainedContext); }
+
+ uno::Any getChainedValueByName( OUString const & aName) const
+ {
+ return m_xChainedContext.is()
+ ? m_xChainedContext->getValueByName(aName)
+ : uno::Any();
+ }
+
+ // XCurrentContext
+ virtual uno::Any SAL_CALL
+ getValueByName( OUString const & aName)
+ throw (uno::RuntimeException);
+ };
+
+ uno::Any SAL_CALL
+ SimpleCurrentContext::getValueByName( OUString const & aName)
+ throw (uno::RuntimeException)
+ {
+ return getChainedValueByName(aName);
+ }
+
+}
+
+// ----------------------------------------------------------------------------
+class ConfigurationErrorHandler::Context : public SimpleCurrentContext
+{
+public:
+ Context()
+ : SimpleCurrentContext( uno::getCurrentContext() )
+ {
+ }
+
+ ~Context()
+ {
+ }
+
+ // XCurrentContext
+ virtual uno::Any SAL_CALL
+ getValueByName( OUString const & aName)
+ throw (uno::RuntimeException);
+
+private:
+ InteractionHandler m_xHandler;
+};
+
+//------------------------------------------------------------------------------
+uno::Any SAL_CALL ConfigurationErrorHandler::Context::getValueByName( OUString const & aName)
+ throw (uno::RuntimeException)
+{
+ if ( aName.equalsAscii( CONFIG_ERROR_HANDLER ) )
+ {
+ if ( !m_xHandler.is() )
+ m_xHandler = ConfigurationErrorHandler::getDefaultInteractionHandler();
+ return uno::Any( m_xHandler );
+ }
+ return SimpleCurrentContext::getValueByName( aName );
+}
+
+//------------------------------------------------------------------------------
+ConfigurationErrorHandler::~ConfigurationErrorHandler()
+{
+ deactivate();
+}
+
+//------------------------------------------------------------------------------
+/// installs the handler into the current context
+void ConfigurationErrorHandler::activate()
+{
+ if (!m_pContext)
+ {
+ m_pContext = new Context;
+ m_pContext->acquire();
+ }
+ m_pContext->install();
+}
+
+//------------------------------------------------------------------------------
+/// deinstalls the handler from the current context, restoring the previous context
+void ConfigurationErrorHandler::deactivate()
+{
+ if (m_pContext)
+ {
+ m_pContext->deinstall();
+ m_pContext->release();
+ m_pContext = 0;
+ }
+}
+//------------------------------------------------------------------------------
+
+ConfigurationErrorHandler::InteractionHandler ConfigurationErrorHandler::getDefaultInteractionHandler()
+{
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
+
+ OSL_ENSURE( xServiceManager.is(),"No ServiceManager set for ConfigurationErrorHandler");
+
+ InteractionHandler xHandler;
+
+ if (xServiceManager.is())
+ {
+ xHandler.set( xServiceManager->createInstance(k_ERRORHANDLER), UNO_QUERY );
+ }
+
+ return xHandler;
+}
+//------------------------------------------------------------------------------
+
+
+
diff --git a/desktop/source/app/configinit.hxx b/desktop/source/app/configinit.hxx
new file mode 100644
index 000000000000..68df86656bea
--- /dev/null
+++ b/desktop/source/app/configinit.hxx
@@ -0,0 +1,71 @@
+#ifndef _DESKTOP_CONFIGINIT_HXX_
+#define _DESKTOP_CONFIGINIT_HXX_
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <rtl/ustring.hxx>
+
+/** creates a ConfigurationProvider instance
+Important: exceptions thrown from that method will contain a readily
+displayable message.
+
+ @return
+ The default configuration provider for the application or<br/>
+ <NULL/>, if startup was canceled
+
+ @throw com::sun::star::configuration::CannotLoadConfigurationException
+ if the configuration provider can't be created
+
+ @throw com::sun::star::lang::ServiceNotRegisteredException
+ if the ConfigurationProvider service is unknwon
+
+ @throw com::sun::star::lang::WrappedTargetException
+ if the configuration backend could be created,
+ but incurred a failure later
+
+*/
+extern
+com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ CreateApplicationConfigurationProvider( );
+
+//-----------------------------------------------------------------------------
+#include <com/sun/star/task/XInteractionHandler.hpp>
+
+/**
+ sets an InteractionHandler for configuration errors in the current context.
+
+ */
+ class ConfigurationErrorHandler
+ {
+ public:
+ typedef com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > InteractionHandler;
+
+ /// Constructor: Uses the default interaction handler
+ ConfigurationErrorHandler()
+ : m_pContext(0), m_xHandler()
+ {}
+
+ /// Constructor: Uses an externally provided interaction handler
+ ConfigurationErrorHandler(const InteractionHandler & xHandler)
+ : m_pContext(0), m_xHandler( xHandler )
+ {}
+
+ ~ConfigurationErrorHandler();
+
+ static InteractionHandler getDefaultInteractionHandler();
+
+ /// installs the handler into the current context
+ void activate();
+ /// deinstalls the handler from the current context, restoring the previous context
+ void deactivate();
+ private:
+ class Context;
+ Context * m_pContext;
+ InteractionHandler m_xHandler;
+ private:
+ // not implemented - suppress copy
+ ConfigurationErrorHandler(const ConfigurationErrorHandler&);
+ void operator=(const ConfigurationErrorHandler&);
+ };
+
+//-----------------------------------------------------------------------------
+#endif
diff --git a/desktop/source/app/copyright_ascii_ooo.c b/desktop/source/app/copyright_ascii_ooo.c
new file mode 100644
index 000000000000..7439547f62b4
--- /dev/null
+++ b/desktop/source/app/copyright_ascii_ooo.c
@@ -0,0 +1,10 @@
+
+ /*
+ * copyright text to see as text in the soffice binary
+ *
+ */
+
+extern const char copyright_text_1[];
+
+const char copyright_text_1[] = "Copyright © 2000, 2010 Oracle and/or its affiliates, All rights reserved.";
+
diff --git a/desktop/source/app/copyright_ascii_sun.c b/desktop/source/app/copyright_ascii_sun.c
new file mode 100644
index 000000000000..c7de54e98fba
--- /dev/null
+++ b/desktop/source/app/copyright_ascii_sun.c
@@ -0,0 +1,8 @@
+
+ /*
+ * copyright text to see as text in the soffice binary
+ *
+ */
+
+const char copyright_text_1[] = "Copyright © 2000, 2010 Oracle and/or its affiliates, All rights reserved.";
+
diff --git a/desktop/source/app/desktop.hrc b/desktop/source/app/desktop.hrc
new file mode 100644
index 000000000000..9c68d7b9fd2d
--- /dev/null
+++ b/desktop/source/app/desktop.hrc
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_HRC_
+#define _DESKTOP_HRC_
+
+#ifndef _SOLAR_HRC
+#include <svl/solar.hrc>
+#endif
+
+#define RID_DESKTOP_DIALOG_START 2000
+#define RID_FIRSTSTSTART_START 3000
+#define RID_DESKTOP_STRING_START 10000
+
+
+#define INFOBOX_CMDLINEHELP (RID_DESKTOP_DIALOG_START+51)
+#define INFOBOX_EXPIRED (RID_DESKTOP_DIALOG_START+52)
+
+#define QBX_USERDATALOCKED (RID_DESKTOP_DIALOG_START+100)
+
+#define DLG_CMDLINEHELP (RID_DESKTOP_DIALOG_START+101)
+#define TXT_DLG_CMDLINEHELP_HEADER (RID_DESKTOP_DIALOG_START+102)
+#define TXT_DLG_CMDLINEHELP_LEFT (RID_DESKTOP_DIALOG_START+103)
+#define TXT_DLG_CMDLINEHELP_RIGHT (RID_DESKTOP_DIALOG_START+104)
+#define TXT_DLG_CMDLINEHELP_BOTTOM (RID_DESKTOP_DIALOG_START+105)
+#define BTN_DLG_CMDLINEHELP_OK (RID_DESKTOP_DIALOG_START+106)
+
+#define QBX_CONFIG_IMPORTSETTINGS (RID_DESKTOP_DIALOG_START+180)
+
+#define EBX_ERR_PRINTDISABLED (RID_DESKTOP_DIALOG_START+190)
+
+#define STR_RECOVER_QUERY (RID_DESKTOP_STRING_START+0)
+#define STR_RECOVER_TITLE (RID_DESKTOP_STRING_START+1)
+#define STR_RECOVER_PREPARED (RID_DESKTOP_STRING_START+2)
+
+#define STR_BOOTSTRAP_ERR_CANNOT_START (RID_DESKTOP_STRING_START+100)
+#define STR_BOOTSTRAP_ERR_DIR_MISSING (RID_DESKTOP_STRING_START+101)
+#define STR_BOOTSTRAP_ERR_PATH_INVALID (RID_DESKTOP_STRING_START+102)
+#define STR_BOOTSTRAP_ERR_NO_PATH (RID_DESKTOP_STRING_START+103)
+#define STR_BOOTSTRAP_ERR_INTERNAL (RID_DESKTOP_STRING_START+104)
+#define STR_BOOTSTRAP_ERR_FILE_CORRUPT (RID_DESKTOP_STRING_START+105)
+#define STR_BOOTSTRAP_ERR_FILE_MISSING (RID_DESKTOP_STRING_START+106)
+#define STR_BOOTSTRAP_ERR_NO_SUPPORT (RID_DESKTOP_STRING_START+107)
+#define STR_BOOTSTRAP_ERR_LANGUAGE_MISSING (RID_DESKTOP_STRING_START+108)
+
+#define STR_BOOTSTRAP_ERR_NO_SERVICE (RID_DESKTOP_STRING_START+120)
+#define STR_BOOTSTRAP_ERR_NO_CFG_SERVICE (RID_DESKTOP_STRING_START+121)
+#define STR_BOOTSTRAP_ERR_CFG_DATAACCESS (RID_DESKTOP_STRING_START+122)
+#define STR_BOOTSTRAP_ERR_NO_PATHSET_SERVICE (RID_DESKTOP_STRING_START+123)
+
+#define STR_ASK_START_SETUP_MANUALLY (RID_DESKTOP_STRING_START+152)
+
+#define STR_INTERNAL_ERRMSG (RID_DESKTOP_STRING_START+161)
+
+#define STR_CONFIG_ERR_SETTINGS_INCOMPLETE (RID_DESKTOP_STRING_START+182)
+#define STR_CONFIG_ERR_CANNOT_CONNECT (RID_DESKTOP_STRING_START+183)
+#define STR_CONFIG_ERR_RIGHTS_MISSING (RID_DESKTOP_STRING_START+184)
+#define STR_CONFIG_ERR_ACCESS_GENERAL (RID_DESKTOP_STRING_START+187)
+#define STR_CONFIG_ERR_NO_WRITE_ACCESS (RID_DESKTOP_STRING_START+188)
+
+#define STR_BOOSTRAP_ERR_NOTENOUGHDISKSPACE (RID_DESKTOP_STRING_START+189)
+#define STR_BOOSTRAP_ERR_NOACCESSRIGHTS (RID_DESKTOP_STRING_START+190)
+
+#define STR_TITLE_USERDATALOCKED (RID_DESKTOP_STRING_START+206)
+#define STR_TITLE_EXPIRED (RID_DESKTOP_STRING_START+207)
+
+#endif // _DESKTOP_HRC_
diff --git a/desktop/source/app/desktop.src b/desktop/source/app/desktop.src
new file mode 100644
index 000000000000..2f6897adf80e
--- /dev/null
+++ b/desktop/source/app/desktop.src
@@ -0,0 +1,234 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "desktop.hrc"
+
+
+String STR_RECOVER_QUERY
+{
+ Text [ en-US ] = "Should the file \"$1\" be restored?" ;
+};
+
+String STR_RECOVER_TITLE
+{
+ Text [ en-US ] = "File Recovery" ;
+};
+
+WarningBox STR_RECOVER_PREPARED
+{
+ Message [ en-US ] = "An unrecoverable error has occurred.\n\nAll modified files have been saved and can\nprobably be recovered at program restart." ;
+};
+
+String STR_BOOTSTRAP_ERR_CANNOT_START
+{
+ Text [ en-US ] = "The application cannot be started. ";
+};
+
+String STR_BOOTSTRAP_ERR_DIR_MISSING
+{
+ Text [ en-US ] = "The configuration directory \"$1\" could not be found.";
+};
+
+String STR_BOOTSTRAP_ERR_PATH_INVALID
+{
+ Text [ en-US ] = "The installation path is invalid.";
+};
+
+String STR_BOOTSTRAP_ERR_NO_PATH
+{
+ Text [ en-US ] = "The installation path is not available.";
+};
+
+String STR_BOOTSTRAP_ERR_INTERNAL
+{
+ Text [ en-US ] = "An internal error occurred.";
+};
+
+String STR_BOOTSTRAP_ERR_FILE_CORRUPT
+{
+ Text [ en-US ] = "The configuration file \"$1\" is corrupt.";
+};
+
+String STR_BOOTSTRAP_ERR_FILE_MISSING
+{
+ Text [ en-US ] = "The configuration file \"$1\" was not found.";
+};
+
+String STR_BOOTSTRAP_ERR_NO_SUPPORT
+{
+ Text [ en-US ] = "The configuration file \"$1\" does not support the current version.";
+};
+
+String STR_BOOTSTRAP_ERR_LANGUAGE_MISSING
+{
+ Text [ en-US ] = "The user interface language cannot be determined.";
+};
+
+String STR_BOOTSTRAP_ERR_NO_SERVICE
+{
+ Text [ en-US ] = "The component manager is not available.";
+};
+
+String STR_BOOTSTRAP_ERR_NO_CFG_SERVICE
+{
+ Text [ en-US ] = "The configuration service is not available.";
+};
+
+String STR_ASK_START_SETUP_MANUALLY
+{
+ Text [ en-US ] = "Start the setup application to repair the installation from the CD or the folder containing the installation packages.";
+};
+
+String STR_CONFIG_ERR_SETTINGS_INCOMPLETE
+{
+ Text [ en-US ] = "The startup settings for accessing the central configuration are incomplete. ";
+};
+
+String STR_CONFIG_ERR_CANNOT_CONNECT
+{
+ Text [ en-US ] = "A connection to the central configuration could not be established. ";
+};
+
+String STR_CONFIG_ERR_RIGHTS_MISSING
+{
+ Text [ en-US ] = "You cannot access the central configuration because of missing access rights. ";
+};
+
+String STR_CONFIG_ERR_ACCESS_GENERAL
+{
+ Text [ en-US ] = "A general error occurred while accessing your central configuration. ";
+};
+
+String STR_CONFIG_ERR_NO_WRITE_ACCESS
+{
+ Text [ en-US ] = "The changes to your personal settings cannot be stored centrally because of missing access rights. ";
+};
+
+String STR_BOOTSTRAP_ERR_CFG_DATAACCESS
+{
+ Text [ en-US ] = "%PRODUCTNAME cannot be started due to an error in accessing the %PRODUCTNAME configuration data.\n\nPlease contact your system administrator." ;
+};
+
+String STR_INTERNAL_ERRMSG
+{
+ Text [ en-US ] = "The following internal error has occurred: " ;
+};
+
+QueryBox QBX_USERDATALOCKED
+{
+ Buttons = WB_YES_NO ;
+ DefButton = WB_DEF_NO ;
+ Message [ en-US ] = "Either another instance of %PRODUCTNAME is accessing your personal settings or your personal settings are locked.\nSimultaneous access can lead to inconsistencies in your personal settings. Before continuing, you should make sure user '$u' closes %PRODUCTNAME on host '$h'.\n\nDo you really want to continue?";
+};
+
+String STR_TITLE_USERDATALOCKED
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTVERSION";
+};
+
+InfoBox INFOBOX_CMDLINEHELP
+{
+ Buttons = WB_OK ;
+ DefButton = WB_DEF_OK ;
+ Message = "";
+};
+
+ModalDialog DLG_CMDLINEHELP
+{
+ Text = "Help Message...";
+ Size = MAP_APPFONT(250, 365);
+ Border = True;
+ SVLook = True;
+ Moveable = True;
+
+ FixedText TXT_DLG_CMDLINEHELP_HEADER
+ {
+ Size = MAP_APPFONT(240, 50);
+ Pos = MAP_APPFONT(5, 5);
+ Text = "HEADER";
+ };
+ FixedText TXT_DLG_CMDLINEHELP_LEFT
+ {
+ Size = MAP_APPFONT(50, 150);
+ Pos = MAP_APPFONT(5, 50);
+ Text = "LEFT";
+ };
+ FixedText TXT_DLG_CMDLINEHELP_RIGHT
+ {
+ Size = MAP_APPFONT(190, 150);
+ Pos = MAP_APPFONT(60, 50);
+ Text = "RIGHT";
+ };
+ FixedText TXT_DLG_CMDLINEHELP_BOTTOM
+ {
+ Size = MAP_APPFONT(240, 145);
+ Pos = MAP_APPFONT(5, 200);
+ Text = "BOTTOM";
+ };
+ OKButton BTN_DLG_CMDLINEHELP_OK
+ {
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Pos = MAP_APPFONT(95, 345);
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+};
+
+ErrorBox EBX_ERR_PRINTDISABLED
+{
+ Buttons = WB_OK ;
+ DefButton = WB_DEF_OK ;
+ Message [ en-US ] = "Printing is disabled. No documents can be printed.";
+};
+
+InfoBox INFOBOX_EXPIRED
+{
+ Buttons = WB_OK ;
+ DefButton = WB_DEF_OK ;
+ Message [ en-US ] = "This Evaluation Version has expired. To find out more about %PRODUCTNAME,\nvisit http://www.oracle.com/us/products/applications/open-office.";
+};
+
+String STR_TITLE_EXPIRED
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTVERSION";
+};
+
+String STR_BOOTSTRAP_ERR_NO_PATHSET_SERVICE
+{
+ Text [ en-US ] = "The path manager is not available.\n";
+};
+
+String STR_BOOSTRAP_ERR_NOTENOUGHDISKSPACE
+{
+ Text [ en-US ] = "%PRODUCTNAME user installation could not be completed due to insufficient free disk space. Please free more disc space at the following location and restart %PRODUCTNAME:\n\n";
+};
+
+String STR_BOOSTRAP_ERR_NOACCESSRIGHTS
+{
+ Text [ en-US ] = "%PRODUCTNAME user installation could not be processed due to missing access rights. Please make sure that you have sufficient access rights for the following location and restart %PRODUCTNAME:\n\n";
+};
+
diff --git a/desktop/source/app/desktopcontext.cxx b/desktop/source/app/desktopcontext.cxx
new file mode 100644
index 000000000000..e516b5eadd46
--- /dev/null
+++ b/desktop/source/app/desktopcontext.cxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+#include "desktopcontext.hxx"
+
+#include <vcl/svapp.hxx>
+#include <svtools/javainteractionhandler.hxx>
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::task;
+
+namespace desktop
+{
+
+DesktopContext::DesktopContext( const Reference< XCurrentContext > & ctx )
+ : m_xNextContext( ctx )
+{
+}
+
+Any SAL_CALL DesktopContext::getValueByName( const OUString& Name) throw (RuntimeException)
+{
+ Any retVal;
+
+ if ( 0 == Name.compareToAscii( JAVA_INTERACTION_HANDLER_NAME ))
+ {
+ retVal = makeAny( Reference< XInteractionHandler >( new svt::JavaInteractionHandler()) );
+ }
+ else if( m_xNextContext.is() )
+ {
+ // Call next context in chain if found
+ retVal = m_xNextContext->getValueByName( Name );
+ }
+ return retVal;
+}
+
+}
diff --git a/desktop/source/app/desktopcontext.hxx b/desktop/source/app/desktopcontext.hxx
new file mode 100644
index 000000000000..88948e753af5
--- /dev/null
+++ b/desktop/source/app/desktopcontext.hxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_DESKTOPCONTEXT_HXX_
+#define _DESKTOP_DESKTOPCONTEXT_HXX_
+
+#include <cppuhelper/implbase1.hxx>
+#include <uno/current_context.hxx>
+
+namespace desktop
+{
+ class DesktopContext: public cppu::WeakImplHelper1< com::sun::star::uno::XCurrentContext >
+ {
+ public:
+ DesktopContext( const com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > & ctx);
+
+ // XCurrentContext
+ virtual com::sun::star::uno::Any SAL_CALL getValueByName( const rtl::OUString& Name )
+ throw (com::sun::star::uno::RuntimeException);
+
+ private:
+ com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > m_xNextContext;
+ };
+}
+
+#endif // _DESKTOP_DESKTOPCONTEXT_HXX_
diff --git a/desktop/source/app/desktopresid.cxx b/desktop/source/app/desktopresid.cxx
new file mode 100644
index 000000000000..90cc8e220fba
--- /dev/null
+++ b/desktop/source/app/desktopresid.cxx
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+
+#include "desktopresid.hxx"
+#include "app.hxx"
+
+// -----------------------------------------------------------------------
+namespace desktop
+{
+
+DesktopResId::DesktopResId( USHORT nId ) :
+ ResId( nId, *Desktop::GetDesktopResManager() )
+{
+}
+
+}
diff --git a/desktop/source/app/desktopresid.hxx b/desktop/source/app/desktopresid.hxx
new file mode 100644
index 000000000000..410ca429f5ad
--- /dev/null
+++ b/desktop/source/app/desktopresid.hxx
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_RESID_HXX_
+#define _DESKTOP_RESID_HXX_
+
+#include <tools/resid.hxx>
+
+namespace desktop
+{
+
+class DesktopResId : public ResId
+{
+ public:
+ DesktopResId( USHORT nId );
+};
+
+}
+
+#endif // _DESKTOP_RESID_HXX_
diff --git a/desktop/source/app/dispatchwatcher.cxx b/desktop/source/app/dispatchwatcher.cxx
new file mode 100644
index 000000000000..db7f3c45964f
--- /dev/null
+++ b/desktop/source/app/dispatchwatcher.cxx
@@ -0,0 +1,514 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dispatchwatcher.hxx"
+#include <rtl/ustring.hxx>
+#include <tools/string.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/synchronousdispatch.hxx>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/util/CloseVetoException.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/view/XPrintable.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/document/MacroExecMode.hpp>
+#include <com/sun/star/document/UpdateDocMode.hpp>
+
+#include <tools/urlobj.hxx>
+#include <comphelper/mediadescriptor.hxx>
+
+#include <vector>
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::view;
+
+namespace desktop
+{
+
+String GetURL_Impl(
+ const String& rName, boost::optional< rtl::OUString > const & cwdUrl );
+
+struct DispatchHolder
+{
+ DispatchHolder( const URL& rURL, Reference< XDispatch >& rDispatch ) :
+ aURL( rURL ), xDispatch( rDispatch ) {}
+
+ URL aURL;
+ rtl::OUString cwdUrl;
+ Reference< XDispatch > xDispatch;
+};
+
+Mutex* DispatchWatcher::pWatcherMutex = NULL;
+
+Mutex& DispatchWatcher::GetMutex()
+{
+ if ( !pWatcherMutex )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pWatcherMutex )
+ pWatcherMutex = new osl::Mutex();
+ }
+
+ return *pWatcherMutex;
+}
+
+// Create or get the dispatch watcher implementation. This implementation must be
+// a singleton to prevent access to the framework after it wants to terminate.
+DispatchWatcher* DispatchWatcher::GetDispatchWatcher()
+{
+ static Reference< XInterface > xDispatchWatcher;
+ static DispatchWatcher* pDispatchWatcher = NULL;
+
+ if ( !xDispatchWatcher.is() )
+ {
+ ::osl::MutexGuard aGuard( GetMutex() );
+
+ if ( !xDispatchWatcher.is() )
+ {
+ pDispatchWatcher = new DispatchWatcher();
+
+ // We have to hold a reference to ourself forever to prevent our own destruction.
+ xDispatchWatcher = static_cast< cppu::OWeakObject *>( pDispatchWatcher );
+ }
+ }
+
+ return pDispatchWatcher;
+}
+
+
+DispatchWatcher::DispatchWatcher()
+ : m_nRequestCount(0)
+{
+}
+
+
+DispatchWatcher::~DispatchWatcher()
+{
+}
+
+
+sal_Bool DispatchWatcher::executeDispatchRequests( const DispatchList& aDispatchRequestsList, bool bNoTerminate )
+{
+ Reference< XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ UNO_QUERY );
+
+ DispatchList::const_iterator p;
+ std::vector< DispatchHolder > aDispatches;
+ ::rtl::OUString aAsTemplateArg( RTL_CONSTASCII_USTRINGPARAM( "AsTemplate"));
+
+ for ( p = aDispatchRequestsList.begin(); p != aDispatchRequestsList.end(); p++ )
+ {
+ String aPrinterName;
+ const DispatchRequest& aDispatchRequest = *p;
+
+ // create parameter array
+ sal_Int32 nCount = 4;
+ if ( aDispatchRequest.aPreselectedFactory.getLength() )
+ nCount++;
+
+ // we need more properties for a print/print to request
+ if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
+ aDispatchRequest.aRequestType == REQUEST_PRINTTO )
+ nCount++;
+
+ Sequence < PropertyValue > aArgs( nCount );
+
+ // mark request as user interaction from outside
+ aArgs[0].Name = ::rtl::OUString::createFromAscii("Referer");
+ aArgs[0].Value <<= ::rtl::OUString::createFromAscii("private:OpenEvent");
+
+ if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
+ aDispatchRequest.aRequestType == REQUEST_PRINTTO )
+ {
+ aArgs[1].Name = ::rtl::OUString::createFromAscii("ReadOnly");
+ aArgs[2].Name = ::rtl::OUString::createFromAscii("OpenNewView");
+ aArgs[3].Name = ::rtl::OUString::createFromAscii("Hidden");
+ aArgs[4].Name = ::rtl::OUString::createFromAscii("Silent");
+ }
+ else
+ {
+ Reference < com::sun::star::task::XInteractionHandler > xInteraction(
+ ::comphelper::getProcessServiceFactory()->createInstance( OUString::createFromAscii("com.sun.star.task.InteractionHandler") ),
+ com::sun::star::uno::UNO_QUERY );
+
+ aArgs[1].Name = OUString::createFromAscii( "InteractionHandler" );
+ aArgs[1].Value <<= xInteraction;
+
+ sal_Int16 nMacroExecMode = ::com::sun::star::document::MacroExecMode::USE_CONFIG;
+ aArgs[2].Name = OUString::createFromAscii( "MacroExecutionMode" );
+ aArgs[2].Value <<= nMacroExecMode;
+
+ sal_Int16 nUpdateDoc = ::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG;
+ aArgs[3].Name = OUString::createFromAscii( "UpdateDocMode" );
+ aArgs[3].Value <<= nUpdateDoc;
+ }
+
+ if ( aDispatchRequest.aPreselectedFactory.getLength() )
+ {
+ aArgs[nCount-1].Name = ::comphelper::MediaDescriptor::PROP_DOCUMENTSERVICE();
+ aArgs[nCount-1].Value <<= aDispatchRequest.aPreselectedFactory;
+ }
+
+ String aName( GetURL_Impl( aDispatchRequest.aURL, aDispatchRequest.aCwdUrl ) );
+ ::rtl::OUString aTarget( RTL_CONSTASCII_USTRINGPARAM("_default") );
+
+ if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
+ aDispatchRequest.aRequestType == REQUEST_PRINTTO )
+ {
+ // documents opened for printing are opened readonly because they must be opened as a new document and this
+ // document could be open already
+ aArgs[1].Value <<= sal_True;
+
+ // always open a new document for printing, because it must be disposed afterwards
+ aArgs[2].Value <<= sal_True;
+
+ // printing is done in a hidden view
+ aArgs[3].Value <<= sal_True;
+
+ // load document for printing without user interaction
+ aArgs[4].Value <<= sal_True;
+
+ // hidden documents should never be put into open tasks
+ aTarget = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_blank") );
+ }
+
+ // load the document ... if they are loadable!
+ // Otherwise try to dispatch it ...
+ Reference < XPrintable > xDoc;
+ if(
+ ( aName.CompareToAscii( ".uno" , 4 ) == COMPARE_EQUAL ) ||
+ ( aName.CompareToAscii( "slot:" , 5 ) == COMPARE_EQUAL ) ||
+ ( aName.CompareToAscii( "macro:", 6 ) == COMPARE_EQUAL ) ||
+ ( aName.CompareToAscii("vnd.sun.star.script", 19) == COMPARE_EQUAL)
+ )
+ {
+ // Attention: URL must be parsed full. Otherwise some detections on it will fail!
+ // It doesnt matter, if parser isn't available. Because; We try loading of URL then ...
+ URL aURL ;
+ aURL.Complete = aName;
+
+ Reference < XDispatch > xDispatcher ;
+ Reference < XDispatchProvider > xProvider ( xDesktop, UNO_QUERY );
+ Reference < XURLTransformer > xParser ( ::comphelper::getProcessServiceFactory()->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ), ::com::sun::star::uno::UNO_QUERY );
+
+ if( xParser.is() == sal_True )
+ xParser->parseStrict( aURL );
+
+ if( xProvider.is() == sal_True )
+ xDispatcher = xProvider->queryDispatch( aURL, ::rtl::OUString(), 0 );
+
+ if( xDispatcher.is() == sal_True )
+ {
+ {
+ ::osl::ClearableMutexGuard aGuard( GetMutex() );
+ // Remember request so we can find it in statusChanged!
+ m_aRequestContainer.insert( DispatchWatcherHashMap::value_type( aURL.Complete, (sal_Int32)1 ) );
+ m_nRequestCount++;
+ }
+
+ // Use local vector to store dispatcher because we have to fill our request container before
+ // we can dispatch. Otherwise it would be possible that statusChanged is called before we dispatched all requests!!
+ aDispatches.push_back( DispatchHolder( aURL, xDispatcher ));
+ }
+ }
+ else if ( ( aName.CompareToAscii( "service:" , 8 ) == COMPARE_EQUAL ) )
+ {
+ // TODO: the dispatch has to be done for loadComponentFromURL as well. Please ask AS for more details.
+ URL aURL ;
+ aURL.Complete = aName;
+
+ Reference < XDispatch > xDispatcher ;
+ Reference < XDispatchProvider > xProvider ( xDesktop, UNO_QUERY );
+ Reference < XURLTransformer > xParser ( ::comphelper::getProcessServiceFactory()->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ), ::com::sun::star::uno::UNO_QUERY );
+
+ if( xParser.is() == sal_True )
+ xParser->parseStrict( aURL );
+
+ if( xProvider.is() == sal_True )
+ xDispatcher = xProvider->queryDispatch( aURL, ::rtl::OUString(), 0 );
+
+ if( xDispatcher.is() == sal_True )
+ {
+ try
+ {
+ // We have to be listener to catch errors during dispatching URLs.
+ // Otherwise it would be possible to have an office running without an open
+ // window!!
+ Sequence < PropertyValue > aArgs2(1);
+ aArgs2[0].Name = ::rtl::OUString::createFromAscii("SynchronMode");
+ aArgs2[0].Value <<= sal_True;
+ Reference < XNotifyingDispatch > xDisp( xDispatcher, UNO_QUERY );
+ if ( xDisp.is() )
+ xDisp->dispatchWithNotification( aURL, aArgs2, DispatchWatcher::GetDispatchWatcher() );
+ else
+ xDispatcher->dispatch( aURL, aArgs2 );
+ }
+ catch ( ::com::sun::star::uno::Exception& )
+ {
+ OUString aMsg = OUString::createFromAscii(
+ "Desktop::OpenDefault() IllegalArgumentException while calling XNotifyingDispatch: ");
+ OSL_ENSURE( sal_False, OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ }
+ }
+ else
+ {
+ INetURLObject aObj( aName );
+ if ( aObj.GetProtocol() == INET_PROT_PRIVATE )
+ aTarget = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_default") );
+
+ // Set "AsTemplate" argument according to request type
+ if ( aDispatchRequest.aRequestType == REQUEST_FORCENEW ||
+ aDispatchRequest.aRequestType == REQUEST_FORCEOPEN )
+ {
+ sal_Int32 nIndex = aArgs.getLength();
+ aArgs.realloc( nIndex+1 );
+ aArgs[nIndex].Name = aAsTemplateArg;
+ if ( aDispatchRequest.aRequestType == REQUEST_FORCENEW )
+ aArgs[nIndex].Value <<= sal_True;
+ else
+ aArgs[nIndex].Value <<= sal_False;
+ }
+
+ // if we are called in viewmode, open document read-only
+ // #95425#
+ if(aDispatchRequest.aRequestType == REQUEST_VIEW) {
+ sal_Int32 nIndex = aArgs.getLength();
+ aArgs.realloc(nIndex+1);
+ aArgs[nIndex].Name = OUString::createFromAscii("ReadOnly");
+ aArgs[nIndex].Value <<= sal_True;
+ }
+
+ // if we are called with -start set Start in mediadescriptor
+ if(aDispatchRequest.aRequestType == REQUEST_START) {
+ sal_Int32 nIndex = aArgs.getLength();
+ aArgs.realloc(nIndex+1);
+ aArgs[nIndex].Name = OUString::createFromAscii("StartPresentation");
+ aArgs[nIndex].Value <<= sal_True;
+ }
+
+ // This is a synchron loading of a component so we don't have to deal with our statusChanged listener mechanism.
+
+ try
+ {
+ xDoc = Reference < XPrintable >( ::comphelper::SynchronousDispatch::dispatch( xDesktop, aName, aTarget, 0, aArgs ), UNO_QUERY );
+ //xDoc = Reference < XPrintable >( xDesktop->loadComponentFromURL( aName, aTarget, 0, aArgs ), UNO_QUERY );
+ }
+ catch ( ::com::sun::star::lang::IllegalArgumentException& iae)
+ {
+ OUString aMsg = OUString::createFromAscii(
+ "Dispatchwatcher IllegalArgumentException while calling loadComponentFromURL: ")
+ + iae.Message;
+ OSL_ENSURE( sal_False, OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ catch (com::sun::star::io::IOException& ioe)
+ {
+ OUString aMsg = OUString::createFromAscii(
+ "Dispatchwatcher IOException while calling loadComponentFromURL: ")
+ + ioe.Message;
+ OSL_ENSURE( sal_False, OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ if ( aDispatchRequest.aRequestType == REQUEST_OPEN ||
+ aDispatchRequest.aRequestType == REQUEST_VIEW ||
+ aDispatchRequest.aRequestType == REQUEST_START ||
+ aDispatchRequest.aRequestType == REQUEST_FORCEOPEN ||
+ aDispatchRequest.aRequestType == REQUEST_FORCENEW )
+ {
+ // request is completed
+ OfficeIPCThread::RequestsCompleted( 1 );
+ }
+ else if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
+ aDispatchRequest.aRequestType == REQUEST_PRINTTO )
+ {
+ if ( xDoc.is() )
+ {
+ if ( aDispatchRequest.aRequestType == REQUEST_PRINTTO )
+ {
+ // create the printer
+ Sequence < PropertyValue > aPrinterArgs( 1 );
+ aPrinterArgs[0].Name = ::rtl::OUString::createFromAscii("Name");
+ aPrinterArgs[0].Value <<= ::rtl::OUString( aDispatchRequest.aPrinterName );
+ xDoc->setPrinter( aPrinterArgs );
+ }
+
+ // print ( also without user interaction )
+ Sequence < PropertyValue > aPrinterArgs( 1 );
+ aPrinterArgs[0].Name = ::rtl::OUString::createFromAscii("Wait");
+ aPrinterArgs[0].Value <<= ( sal_Bool ) sal_True;
+ xDoc->print( aPrinterArgs );
+ }
+ else
+ {
+ // place error message here ...
+ }
+
+ // remove the document
+ try
+ {
+ Reference < XCloseable > xClose( xDoc, UNO_QUERY );
+ if ( xClose.is() )
+ xClose->close( sal_True );
+ else
+ {
+ Reference < XComponent > xComp( xDoc, UNO_QUERY );
+ if ( xComp.is() )
+ xComp->dispose();
+ }
+ }
+ catch ( com::sun::star::util::CloseVetoException& )
+ {
+ }
+
+ // request is completed
+ OfficeIPCThread::RequestsCompleted( 1 );
+ }
+ }
+ }
+
+ if ( aDispatches.size() > 0 )
+ {
+ // Execute all asynchronous dispatches now after we placed them into our request container!
+ Sequence < PropertyValue > aArgs( 2 );
+ aArgs[0].Name = ::rtl::OUString::createFromAscii("Referer");
+ aArgs[0].Value <<= ::rtl::OUString::createFromAscii("private:OpenEvent");
+ aArgs[1].Name = ::rtl::OUString::createFromAscii("SynchronMode");
+ aArgs[1].Value <<= sal_True;
+
+ for ( sal_uInt32 n = 0; n < aDispatches.size(); n++ )
+ {
+ Reference< XDispatch > xDispatch = aDispatches[n].xDispatch;
+ Reference < XNotifyingDispatch > xDisp( xDispatch, UNO_QUERY );
+ if ( xDisp.is() )
+ xDisp->dispatchWithNotification( aDispatches[n].aURL, aArgs, this );
+ else
+ {
+ ::osl::ClearableMutexGuard aGuard( GetMutex() );
+ m_nRequestCount--;
+ aGuard.clear();
+ xDispatch->dispatch( aDispatches[n].aURL, aArgs );
+ }
+ }
+ }
+
+ ::osl::ClearableMutexGuard aGuard( GetMutex() );
+ bool bEmpty = (m_nRequestCount == 0);
+ aGuard.clear();
+
+ // No more asynchronous requests?
+ // The requests are removed from the request container after they called back to this
+ // implementation via statusChanged!!
+ if ( bEmpty && !bNoTerminate /*m_aRequestContainer.empty()*/ )
+ {
+ // We have to check if we have an open task otherwise we have to shutdown the office.
+ Reference< XFramesSupplier > xTasksSupplier( xDesktop, UNO_QUERY );
+ aGuard.clear();
+
+ Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY );
+
+ if ( !xList->hasElements() )
+ {
+ // We don't have any task open so we have to shutdown ourself!!
+ Reference< XDesktop > xDesktop2( xTasksSupplier, UNO_QUERY );
+ if ( xDesktop2.is() )
+ return xDesktop2->terminate();
+ }
+ }
+
+ return sal_False;
+}
+
+
+void SAL_CALL DispatchWatcher::disposing( const ::com::sun::star::lang::EventObject& )
+throw(::com::sun::star::uno::RuntimeException)
+{
+}
+
+
+void SAL_CALL DispatchWatcher::dispatchFinished( const DispatchResultEvent& ) throw( RuntimeException )
+{
+ osl::ClearableMutexGuard aGuard( GetMutex() );
+ sal_Int16 nCount = --m_nRequestCount;
+ aGuard.clear();
+ OfficeIPCThread::RequestsCompleted( 1 );
+/*
+ // Find request in our hash map and remove it as a pending request
+ DispatchWatcherHashMap::iterator pDispatchEntry = m_aRequestContainer.find( rEvent.FeatureURL.Complete ) ;
+ if ( pDispatchEntry != m_aRequestContainer.end() )
+ {
+ m_aRequestContainer.erase( pDispatchEntry );
+ aGuard.clear();
+ OfficeIPCThread::RequestsCompleted( 1 );
+ }
+ else
+ aGuard.clear();
+*/
+ if ( !nCount && !OfficeIPCThread::AreRequestsPending() )
+ {
+ // We have to check if we have an open task otherwise we have to shutdown the office.
+ Reference< XFramesSupplier > xTasksSupplier( ::comphelper::getProcessServiceFactory()->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
+ UNO_QUERY );
+ Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY );
+
+ if ( !xList->hasElements() )
+ {
+ // We don't have any task open so we have to shutdown ourself!!
+ Reference< XDesktop > xDesktop( xTasksSupplier, UNO_QUERY );
+ if ( xDesktop.is() )
+ xDesktop->terminate();
+ }
+ }
+}
+
+}
+
+
+
+
+
+
+
+
diff --git a/desktop/source/app/dispatchwatcher.hxx b/desktop/source/app/dispatchwatcher.hxx
new file mode 100644
index 000000000000..2b3f1ab54680
--- /dev/null
+++ b/desktop/source/app/dispatchwatcher.hxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_DISPATCHWATCHER_HXX
+#define _DESKTOP_DISPATCHWATCHER_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/frame/XNotifyingDispatch.hpp>
+#include <com/sun/star/frame/XDispatchResultListener.hpp>
+
+#include "officeipcthread.hxx"
+#include <hash_map>
+#include <vector>
+
+namespace desktop
+{
+
+/*
+ Class for controlls dispatching of command URL through office command line. There
+ are "dangerous" command URLs, that can result in a running office without UI. To prevent
+ this situation the implementation surveile all dispatches and looks for an open task if
+ there is arose a problem. If there is none the office will be shutdown to prevent a
+ running office without UI.
+*/
+
+struct OUStringHashCode
+{
+ size_t operator()( const ::rtl::OUString& sString ) const
+ {
+ return sString.hashCode();
+ }
+};
+
+class DispatchWatcherHashMap : public ::std::hash_map< ::rtl::OUString, sal_Int32, OUStringHashCode, ::std::equal_to< ::rtl::OUString > >
+{
+ public:
+ inline void free()
+ {
+ DispatchWatcherHashMap().swap( *this );
+ }
+};
+
+class DispatchWatcher : public ::cppu::WeakImplHelper1< ::com::sun::star::frame::XDispatchResultListener >
+{
+ public:
+ enum RequestType
+ {
+ REQUEST_OPEN,
+ REQUEST_VIEW,
+ REQUEST_START,
+ REQUEST_PRINT,
+ REQUEST_PRINTTO,
+ REQUEST_FORCEOPEN,
+ REQUEST_FORCENEW
+ };
+
+ struct DispatchRequest
+ {
+ DispatchRequest( RequestType aType, const ::rtl::OUString& aFile, boost::optional< rtl::OUString > const & cwdUrl, const ::rtl::OUString& aPrinter, const ::rtl::OUString& aFact ) :
+ aRequestType( aType ), aURL( aFile ), aCwdUrl( cwdUrl ), aPrinterName( aPrinter ), aPreselectedFactory( aFact ) {}
+
+ RequestType aRequestType;
+ rtl::OUString aURL;
+ boost::optional< rtl::OUString > aCwdUrl;
+ rtl::OUString aPrinterName;
+ rtl::OUString aPreselectedFactory;
+ };
+
+ typedef std::vector< DispatchRequest > DispatchList;
+
+ virtual ~DispatchWatcher();
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XDispachResultListener
+ virtual void SAL_CALL dispatchFinished( const com::sun::star::frame::DispatchResultEvent& aEvent ) throw( com::sun::star::uno::RuntimeException );
+
+ // Access function to get a dispatcher watcher reference. There must be a global reference holder
+ static DispatchWatcher* GetDispatchWatcher();
+
+ // execute new dispatch request
+ sal_Bool executeDispatchRequests( const DispatchList& aDispatches, bool bNoTerminate = false );
+
+ private:
+ DispatchWatcher();
+
+ static ::osl::Mutex& GetMutex();
+
+ DispatchWatcherHashMap m_aRequestContainer;
+
+ static ::osl::Mutex* pWatcherMutex;
+
+ sal_Int16 m_nRequestCount;
+};
+
+}
+
+#endif // _DESKTOP_DISPATCHWATCHER_HXX
diff --git a/desktop/source/app/exports.dxp b/desktop/source/app/exports.dxp
new file mode 100644
index 000000000000..9630d7e06768
--- /dev/null
+++ b/desktop/source/app/exports.dxp
@@ -0,0 +1,3 @@
+component_getImplementationEnvironment
+component_writeInfo
+component_getFactory
diff --git a/desktop/source/app/langselect.cxx b/desktop/source/app/langselect.cxx
new file mode 100644
index 000000000000..9df8d82a37ff
--- /dev/null
+++ b/desktop/source/app/langselect.cxx
@@ -0,0 +1,558 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "app.hxx"
+#include "langselect.hxx"
+#include "cmdlineargs.hxx"
+#include <stdio.h>
+
+#include <rtl/string.hxx>
+#include <rtl/bootstrap.hxx>
+#include <unotools/pathoptions.hxx>
+#include <tools/resid.hxx>
+#include <tools/config.hxx>
+#include <i18npool/mslangid.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/lang/XLocalizable.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include "com/sun/star/util/XFlushable.hpp"
+#include <rtl/locale.hxx>
+#include <rtl/instance.hxx>
+#include <osl/process.h>
+#include <osl/file.hxx>
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+
+namespace desktop {
+
+static char const SOFFICE_BOOTSTRAP[] = "Bootstrap";
+static char const SOFFICE_STARTLANG[] = "STARTLANG";
+
+sal_Bool LanguageSelection::bFoundLanguage = sal_False;
+OUString LanguageSelection::aFoundLanguage;
+LanguageSelection::LanguageSelectionStatus LanguageSelection::m_eStatus = LS_STATUS_OK;
+
+const OUString LanguageSelection::usFallbackLanguage = OUString::createFromAscii("en-US");
+
+static sal_Bool existsURL( OUString const& sURL )
+{
+ using namespace osl;
+ DirectoryItem aDirItem;
+
+ if (sURL.getLength() != 0)
+ return ( DirectoryItem::get( sURL, aDirItem ) == DirectoryItem::E_None );
+
+ return sal_False;
+}
+
+// locate soffice.ini/.rc file
+static OUString locateSofficeIniFile()
+{
+ OUString aUserDataPath;
+ OUString aSofficeIniFileURL;
+
+ // Retrieve the default file URL for the soffice.ini/rc
+ rtl::Bootstrap().getIniName( aSofficeIniFileURL );
+
+ if ( utl::Bootstrap::locateUserData( aUserDataPath ) == utl::Bootstrap::PATH_EXISTS )
+ {
+ const char CONFIG_DIR[] = "/config";
+
+ sal_Int32 nIndex = aSofficeIniFileURL.lastIndexOf( '/');
+ if ( nIndex > 0 )
+ {
+ OUString aUserSofficeIniFileURL;
+ OUStringBuffer aBuffer( aUserDataPath );
+ aBuffer.appendAscii( CONFIG_DIR );
+ aBuffer.append( aSofficeIniFileURL.copy( nIndex ));
+ aUserSofficeIniFileURL = aBuffer.makeStringAndClear();
+
+ if ( existsURL( aUserSofficeIniFileURL ))
+ return aUserSofficeIniFileURL;
+ }
+ }
+ // Fallback try to use the soffice.ini/rc from program folder
+ return aSofficeIniFileURL;
+}
+
+Locale LanguageSelection::IsoStringToLocale(const OUString& str)
+{
+ Locale l;
+ sal_Int32 index=0;
+ l.Language = str.getToken(0, '-', index);
+ if (index >= 0) l.Country = str.getToken(0, '-', index);
+ if (index >= 0) l.Variant = str.getToken(0, '-', index);
+ return l;
+}
+
+bool LanguageSelection::prepareLanguage()
+{
+ m_eStatus = LS_STATUS_OK;
+ OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
+ Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
+ Reference< XLocalizable > theConfigProvider;
+ try
+ {
+ theConfigProvider = Reference< XLocalizable >(theMSF->createInstance( sConfigSrvc ),UNO_QUERY_THROW );
+ }
+ catch(const Exception&)
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ }
+
+ if(!theConfigProvider.is())
+ return false;
+
+ sal_Bool bSuccess = sal_False;
+
+ // #i42730#get the windows 16Bit locale - it should be preferred over the UI language
+ try
+ {
+ Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.System/L10N/", sal_False), UNO_QUERY_THROW);
+ Any aWin16SysLocale = xProp->getPropertyValue(OUString::createFromAscii("SystemLocale"));
+ ::rtl::OUString sWin16SysLocale;
+ aWin16SysLocale >>= sWin16SysLocale;
+ if( sWin16SysLocale.getLength())
+ setDefaultLanguage(sWin16SysLocale);
+ }
+ catch(const Exception&)
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ }
+
+ // #i32939# use system locale to set document default locale
+ try
+ {
+ OUString usLocale;
+ Reference< XPropertySet > xLocaleProp(getConfigAccess(
+ "org.openoffice.System/L10N", sal_True), UNO_QUERY_THROW);
+ xLocaleProp->getPropertyValue(OUString::createFromAscii("Locale")) >>= usLocale;
+ setDefaultLanguage(usLocale);
+ }
+ catch (Exception&)
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ }
+
+ // get the selected UI language as string
+ bool bCmdLanguage( false );
+ bool bIniLanguage( false );
+ OUString aEmpty;
+ OUString aLocaleString = getUserUILanguage();
+
+ if ( aLocaleString.getLength() == 0 )
+ {
+ CommandLineArgs* pCmdLineArgs = Desktop::GetCommandLineArgs();
+ if ( pCmdLineArgs )
+ {
+ pCmdLineArgs->GetLanguage(aLocaleString);
+ if (isInstalledLanguage(aLocaleString, sal_False))
+ {
+ bCmdLanguage = true;
+ bFoundLanguage = true;
+ aFoundLanguage = aLocaleString;
+ }
+ else
+ aLocaleString = aEmpty;
+ }
+
+ if ( !bCmdLanguage )
+ {
+ OUString aSOfficeIniURL = locateSofficeIniFile();
+ Config aConfig(aSOfficeIniURL);
+ aConfig.SetGroup( SOFFICE_BOOTSTRAP );
+ OString sLang = aConfig.ReadKey( SOFFICE_STARTLANG );
+ aLocaleString = OUString( sLang.getStr(), sLang.getLength(), RTL_TEXTENCODING_ASCII_US );
+ if (isInstalledLanguage(aLocaleString, sal_False))
+ {
+ bIniLanguage = true;
+ bFoundLanguage = true;
+ aFoundLanguage = aLocaleString;
+ }
+ else
+ aLocaleString = aEmpty;
+ }
+ }
+
+ // user further fallbacks for the UI language
+ if ( aLocaleString.getLength() == 0 )
+ aLocaleString = getLanguageString();
+
+ if ( aLocaleString.getLength() > 0 )
+ {
+ try
+ {
+ // prepare default config provider by localizing it to the selected locale
+ // this will ensure localized configuration settings to be selected accoring to the
+ // UI language.
+ Locale loc = LanguageSelection::IsoStringToLocale(aLocaleString);
+ // flush any data already written to the configuration (which
+ // currently uses independent caches for different locales and thus
+ // would ignore data written to another cache):
+ Reference< XFlushable >(theConfigProvider, UNO_QUERY_THROW)->
+ flush();
+ theConfigProvider->setLocale(loc);
+
+ Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.Setup/L10N/", sal_True), UNO_QUERY_THROW);
+ if ( !bCmdLanguage )
+ {
+ // Store language only
+ xProp->setPropertyValue(OUString::createFromAscii("ooLocale"), makeAny(aLocaleString));
+ Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
+ }
+
+ if ( bIniLanguage )
+ {
+ // Store language only
+ Reference< XPropertySet > xProp2(getConfigAccess("org.openoffice.Office.Linguistic/General/", sal_True), UNO_QUERY_THROW);
+ xProp2->setPropertyValue(OUString::createFromAscii("UILocale"), makeAny(aLocaleString));
+ Reference< XChangesBatch >(xProp2, UNO_QUERY_THROW)->commitChanges();
+ }
+
+ MsLangId::setConfiguredSystemUILanguage( MsLangId::convertLocaleToLanguage(loc) );
+
+ OUString sLocale;
+ xProp->getPropertyValue(OUString::createFromAscii("ooSetupSystemLocale")) >>= sLocale;
+ if ( sLocale.getLength() )
+ {
+ loc = LanguageSelection::IsoStringToLocale(sLocale);
+ MsLangId::setConfiguredSystemLanguage( MsLangId::convertLocaleToLanguage(loc) );
+ }
+ else
+ MsLangId::setConfiguredSystemLanguage( MsLangId::getSystemLanguage() );
+
+ bSuccess = sal_True;
+ }
+ catch ( PropertyVetoException& )
+ {
+ // we are not allowed to change this
+ }
+ catch (Exception& e)
+ {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, aMsg.getStr());
+
+ }
+ }
+
+ // #i32939# setting of default document locale
+ // #i32939# this should not be based on the UI language
+ setDefaultLanguage(aLocaleString);
+
+ return bSuccess;
+}
+
+void LanguageSelection::setDefaultLanguage(const OUString& sLocale)
+{
+ // #i32939# setting of default document language
+ //
+ // See #i42730# for rules for determining source of settings
+
+ // determine script type of locale
+ LanguageType nLang = MsLangId::convertIsoStringToLanguage(sLocale);
+ sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage(nLang);
+
+ switch (nScriptType)
+ {
+ case SCRIPTTYPE_ASIAN:
+ MsLangId::setConfiguredAsianFallback( nLang );
+ break;
+ case SCRIPTTYPE_COMPLEX:
+ MsLangId::setConfiguredComplexFallback( nLang );
+ break;
+ default:
+ MsLangId::setConfiguredWesternFallback( nLang );
+ break;
+ }
+}
+
+OUString LanguageSelection::getUserUILanguage()
+{
+ // check whether the user has selected a specific language
+ OUString aUserLanguage = getUserLanguage();
+ if (aUserLanguage.getLength() > 0 )
+ {
+ if (isInstalledLanguage(aUserLanguage))
+ {
+ // all is well
+ bFoundLanguage = sal_True;
+ aFoundLanguage = aUserLanguage;
+ return aFoundLanguage;
+ }
+ else
+ {
+ // selected language is not/no longer installed
+ resetUserLanguage();
+ }
+ }
+
+ return aUserLanguage;
+}
+
+OUString LanguageSelection::getLanguageString()
+{
+ // did we already find a language?
+ if (bFoundLanguage)
+ return aFoundLanguage;
+
+ // check whether the user has selected a specific language
+ OUString aUserLanguage = getUserUILanguage();
+ if (aUserLanguage.getLength() > 0 )
+ return aUserLanguage ;
+
+ // try to use system default
+ aUserLanguage = getSystemLanguage();
+ if (aUserLanguage.getLength() > 0 )
+ {
+ if (isInstalledLanguage(aUserLanguage, sal_False))
+ {
+ // great, system default language is available
+ bFoundLanguage = sal_True;
+ aFoundLanguage = aUserLanguage;
+ return aFoundLanguage;
+ }
+ }
+ // fallback 1: en-US
+ OUString usFB = usFallbackLanguage;
+ if (isInstalledLanguage(usFB))
+ {
+ bFoundLanguage = sal_True;
+ aFoundLanguage = usFallbackLanguage;
+ return aFoundLanguage;
+ }
+
+ // fallback didn't work use first installed language
+ aUserLanguage = getFirstInstalledLanguage();
+
+ bFoundLanguage = sal_True;
+ aFoundLanguage = aUserLanguage;
+ return aFoundLanguage;
+}
+
+Reference< XNameAccess > LanguageSelection::getConfigAccess(const sal_Char* pPath, sal_Bool bUpdate)
+{
+ Reference< XNameAccess > xNameAccess;
+ try{
+ OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
+ OUString sAccessSrvc;
+ if (bUpdate)
+ sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess");
+ else
+ sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");
+
+ OUString sConfigURL = OUString::createFromAscii(pPath);
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
+ if (theMSF.is()) {
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
+ theMSF->createInstance( sConfigSrvc ),UNO_QUERY_THROW );
+
+ // access the provider
+ Sequence< Any > theArgs(1);
+ theArgs[ 0 ] <<= sConfigURL;
+ xNameAccess = Reference< XNameAccess > (
+ theConfigProvider->createInstanceWithArguments(
+ sAccessSrvc, theArgs ), UNO_QUERY_THROW );
+ }
+ } catch (com::sun::star::uno::Exception& e)
+ {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, aMsg.getStr());
+ }
+ return xNameAccess;
+}
+
+Sequence< OUString > LanguageSelection::getInstalledLanguages()
+{
+ Sequence< OUString > seqLanguages;
+ Reference< XNameAccess > xAccess = getConfigAccess("org.openoffice.Setup/Office/InstalledLocales", sal_False);
+ if (!xAccess.is()) return seqLanguages;
+ seqLanguages = xAccess->getElementNames();
+ return seqLanguages;
+}
+
+// FIXME
+// it's not very clever to handle language fallbacks here, but
+// right now, there is no place that handles those fallbacks globally
+static Sequence< OUString > _getFallbackLocales(const OUString& aIsoLang)
+{
+ Sequence< OUString > seqFallbacks;
+ if (aIsoLang.equalsAscii("zh-HK")) {
+ seqFallbacks = Sequence< OUString >(1);
+ seqFallbacks[0] = OUString::createFromAscii("zh-TW");
+ }
+ return seqFallbacks;
+}
+
+sal_Bool LanguageSelection::isInstalledLanguage(OUString& usLocale, sal_Bool bExact)
+{
+ sal_Bool bInstalled = sal_False;
+ Sequence< OUString > seqLanguages = getInstalledLanguages();
+ for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
+ {
+ if (usLocale.equals(seqLanguages[i]))
+ {
+ bInstalled = sal_True;
+ break;
+ }
+ }
+
+ if (!bInstalled && !bExact)
+ {
+ // try fallback locales
+ Sequence< OUString > seqFallbacks = _getFallbackLocales(usLocale);
+ for (sal_Int32 j=0; j<seqFallbacks.getLength(); j++)
+ {
+ for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
+ {
+ if (seqFallbacks[j].equals(seqLanguages[i]))
+ {
+ bInstalled = sal_True;
+ usLocale = seqFallbacks[j];
+ break;
+ }
+ }
+ }
+ }
+
+ if (!bInstalled && !bExact)
+ {
+ // no exact match was found, well try to find a substitute
+ OUString aInstalledLocale;
+ for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
+ {
+ if (usLocale.indexOf(seqLanguages[i]) == 0)
+ {
+ // requested locale starts with the installed locale
+ // (i.e. installed locale has index 0 in requested locale)
+ bInstalled = sal_True;
+ usLocale = seqLanguages[i];
+ break;
+ }
+ }
+ }
+ return bInstalled;
+}
+
+OUString LanguageSelection::getFirstInstalledLanguage()
+{
+ OUString aLanguage;
+ Sequence< OUString > seqLanguages = getInstalledLanguages();
+ if (seqLanguages.getLength() > 0)
+ aLanguage = seqLanguages[0];
+ return aLanguage;
+}
+
+OUString LanguageSelection::getUserLanguage()
+{
+ OUString aUserLanguage;
+ Reference< XNameAccess > xAccess(getConfigAccess("org.openoffice.Office.Linguistic/General", sal_False));
+ if (xAccess.is())
+ {
+ try
+ {
+ xAccess->getByName(OUString::createFromAscii("UILocale")) >>= aUserLanguage;
+ }
+ catch ( NoSuchElementException const & )
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ return OUString();
+ }
+ catch ( WrappedTargetException const & )
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ return OUString();
+ }
+ }
+ return aUserLanguage;
+}
+
+OUString LanguageSelection::getSystemLanguage()
+{
+ OUString aUserLanguage;
+ Reference< XNameAccess > xAccess(getConfigAccess("org.openoffice.System/L10N", sal_False));
+ if (xAccess.is())
+ {
+ try
+ {
+ xAccess->getByName(OUString::createFromAscii("UILocale")) >>= aUserLanguage;
+ }
+ catch ( NoSuchElementException const & )
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ return OUString();
+ }
+ catch ( WrappedTargetException const & )
+ {
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ return OUString();
+ }
+ }
+ return aUserLanguage;
+}
+
+
+void LanguageSelection::resetUserLanguage()
+{
+ try
+ {
+ Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.Office.Linguistic/General", sal_True), UNO_QUERY_THROW);
+ xProp->setPropertyValue(OUString::createFromAscii("UILocale"), makeAny(OUString::createFromAscii("")));
+ Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
+ }
+ catch ( PropertyVetoException& )
+ {
+ // we are not allowed to change this
+ }
+ catch ( Exception& e)
+ {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, aMsg.getStr());
+ m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
+ }
+}
+
+LanguageSelection::LanguageSelectionStatus LanguageSelection::getStatus()
+{
+ return m_eStatus;
+}
+
+} // namespace desktop
diff --git a/desktop/source/app/langselect.hxx b/desktop/source/app/langselect.hxx
new file mode 100644
index 000000000000..bdf3cd6364de
--- /dev/null
+++ b/desktop/source/app/langselect.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <list>
+#include <sal/types.h>
+#include <tools/string.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/resid.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <svl/languageoptions.hxx>
+
+namespace desktop
+{
+
+class LanguageSelection
+{
+public:
+ enum LanguageSelectionStatus
+ {
+ LS_STATUS_OK,
+ LS_STATUS_CANNOT_DETERMINE_LANGUAGE,
+ LS_STATUS_CONFIGURATIONACCESS_BROKEN
+ };
+
+ static com::sun::star::lang::Locale IsoStringToLocale(const rtl::OUString& str);
+ static rtl::OUString getLanguageString();
+ static bool prepareLanguage();
+ static LanguageSelectionStatus getStatus();
+
+private:
+ static const rtl::OUString usFallbackLanguage;
+ static rtl::OUString aFoundLanguage;
+ static sal_Bool bFoundLanguage;
+ static LanguageSelectionStatus m_eStatus;
+
+ static com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >
+ getConfigAccess(const sal_Char* pPath, sal_Bool bUpdate=sal_False);
+ static com::sun::star::uno::Sequence< rtl::OUString > getInstalledLanguages();
+ static sal_Bool isInstalledLanguage(rtl::OUString& usLocale, sal_Bool bExact=sal_False);
+ static rtl::OUString getFirstInstalledLanguage();
+ static rtl::OUString getUserUILanguage();
+ static rtl::OUString getUserLanguage();
+ static rtl::OUString getSystemLanguage();
+ static void resetUserLanguage();
+ static void setDefaultLanguage(const rtl::OUString&);
+};
+
+} //namespace desktop
diff --git a/desktop/source/app/lockfile.cxx b/desktop/source/app/lockfile.cxx
new file mode 100644
index 000000000000..9cc447a6c56b
--- /dev/null
+++ b/desktop/source/app/lockfile.cxx
@@ -0,0 +1,256 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+#include <stdlib.h>
+#include <time.h>
+#ifdef WNT
+#include <tools/prewin.h>
+#include <windows.h>
+#include <tools/postwin.h>
+#endif
+#include <sal/types.h>
+#include <osl/file.hxx>
+#include <osl/socket.hxx>
+#include <osl/security.hxx>
+#include <unotools/bootstrap.hxx>
+#include <tools/string.hxx>
+#include <tools/config.hxx>
+
+#include "lockfile.hxx"
+
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::utl;
+
+
+namespace desktop {
+
+ // initialize static members...
+ // lock suffix
+ const OUString Lockfile::Suffix()
+ { return OUString::createFromAscii( "/.lock" ); }
+ // values for datafile
+ const ByteString Lockfile::Group()
+ { return ByteString( "Lockdata" ); }
+ const ByteString Lockfile::Userkey()
+ { return ByteString( "User" ); }
+ const ByteString Lockfile::Hostkey()
+ { return ByteString( "Host" ); }
+ const ByteString Lockfile::Stampkey()
+ { return ByteString( "Stamp" ); }
+ const ByteString Lockfile::Timekey()
+ { return ByteString( "Time" ); }
+ const ByteString Lockfile::IPCkey()
+ { return ByteString( "IPCServer" ); }
+
+ Lockfile::Lockfile( bool bIPCserver )
+ :m_bIPCserver(bIPCserver)
+ ,m_bRemove(sal_False)
+ ,m_bIsLocked(sal_False)
+ {
+ // build the file-url to use for the lock
+ OUString aUserPath;
+ utl::Bootstrap::locateUserInstallation( aUserPath );
+ m_aLockname = aUserPath + Suffix();
+
+ // generate ID
+ const int nIdBytes = 16;
+ char tmpId[nIdBytes*2+1];
+ time_t t;
+ srand( (unsigned)(t = time( NULL )) );
+ int tmpByte = 0;
+ for (int i = 0; i<nIdBytes; i++) {
+ tmpByte = rand( ) % 0xFF;
+ sprintf( tmpId+i*2, "%02X", tmpByte ); // #100211# - checked
+ }
+ tmpId[nIdBytes*2]=0x00;
+ m_aId = OUString::createFromAscii( tmpId );
+
+ // generate date string
+ char *tmpTime = ctime( &t );
+ if (tmpTime != NULL) {
+ m_aDate = OUString::createFromAscii( tmpTime );
+ sal_Int32 i = m_aDate.indexOf('\n');
+ if (i > 0)
+ m_aDate = m_aDate.copy(0, i);
+ }
+
+
+ // try to create file
+ File aFile(m_aLockname);
+ if (aFile.open( OpenFlag_Create ) == File::E_EXIST) {
+ m_bIsLocked = sal_True;
+ } else {
+ // new lock created
+ aFile.close( );
+ syncToFile( );
+ m_bRemove = sal_True;
+ }
+ }
+
+ sal_Bool Lockfile::check( fpExecWarning execWarning )
+ {
+
+ if (m_bIsLocked) {
+ // lock existed, ask user what to do
+ if (isStale() ||
+ (execWarning != 0 && (*execWarning)( this ))) {
+ // remove file and create new
+ File::remove( m_aLockname );
+ File aFile(m_aLockname);
+ aFile.open( OpenFlag_Create );
+ aFile.close( );
+ syncToFile( );
+ m_bRemove = sal_True;
+ return sal_True;
+ } else {
+ //leave alone and return false
+ m_bRemove = sal_False;
+ return sal_False;
+ }
+ } else {
+ // lock was created by us
+ return sal_True;
+ }
+ }
+
+ sal_Bool Lockfile::isStale( void ) const
+ {
+ // this checks whether the lockfile was created on the same
+ // host by the same user. Should this be the case it is safe
+ // to assume that it is a stale lockfile which can be overwritten
+ String aLockname = m_aLockname;
+ Config aConfig(aLockname);
+ aConfig.SetGroup(Group());
+ ByteString aIPCserver = aConfig.ReadKey( IPCkey() );
+ if (! aIPCserver.EqualsIgnoreCaseAscii( "true" ))
+ return false;
+
+ ByteString aHost = aConfig.ReadKey( Hostkey() );
+ ByteString aUser = aConfig.ReadKey( Userkey() );
+ // lockfile from same host?
+ ByteString myHost;
+#ifdef WNT
+ /*
+ prevent windows from connecting to the net to get it's own
+ hostname by using the netbios name
+ */
+ sal_Int32 sz = MAX_COMPUTERNAME_LENGTH + 1;
+ char* szHost = new char[sz];
+ if (GetComputerName(szHost, (LPDWORD)&sz))
+ myHost = OString(szHost);
+ else
+ myHost = OString("UNKNOWN");
+ delete[] szHost;
+#else
+ oslSocketResult sRes;
+ myHost = OUStringToOString(
+ SocketAddr::getLocalHostname( &sRes ), RTL_TEXTENCODING_ASCII_US );
+#endif
+ if (aHost == myHost) {
+ // lockfile by same UID
+ OUString myUserName;
+ Security aSecurity;
+ aSecurity.getUserName( myUserName );
+ ByteString myUser = OUStringToOString( myUserName, RTL_TEXTENCODING_ASCII_US );
+ if (aUser == myUser)
+ return sal_True;
+ }
+ return sal_False;
+ }
+
+ void Lockfile::syncToFile( void ) const
+ {
+ String aLockname = m_aLockname;
+ Config aConfig(aLockname);
+ aConfig.SetGroup(Group());
+
+ // get information
+ ByteString aHost;
+#ifdef WNT
+ /*
+ prevent windows from connecting to the net to get it's own
+ hostname by using the netbios name
+ */
+ sal_Int32 sz = MAX_COMPUTERNAME_LENGTH + 1;
+ char* szHost = new char[sz];
+ if (GetComputerName(szHost, (LPDWORD)&sz))
+ aHost = OString(szHost);
+ else
+ aHost = OString("UNKNOWN");
+ delete[] szHost;
+#else
+ oslSocketResult sRes;
+ aHost = OUStringToOString(
+ SocketAddr::getLocalHostname( &sRes ), RTL_TEXTENCODING_ASCII_US );
+#endif
+ OUString aUserName;
+ Security aSecurity;
+ aSecurity.getUserName( aUserName );
+ ByteString aUser = OUStringToOString( aUserName, RTL_TEXTENCODING_ASCII_US );
+ ByteString aTime = OUStringToOString( m_aDate, RTL_TEXTENCODING_ASCII_US );
+ ByteString aStamp = OUStringToOString( m_aId, RTL_TEXTENCODING_ASCII_US );
+
+ // write information
+ aConfig.WriteKey( Userkey(), aUser );
+ aConfig.WriteKey( Hostkey(), aHost );
+ aConfig.WriteKey( Stampkey(), aStamp );
+ aConfig.WriteKey( Timekey(), aTime );
+ aConfig.WriteKey(
+ IPCkey(),
+ m_bIPCserver ? ByteString("true") : ByteString("false") );
+ aConfig.Flush( );
+ }
+
+ void Lockfile::clean( void )
+ {
+ if ( m_bRemove )
+ {
+ File::remove( m_aLockname );
+ m_bRemove = sal_False;
+ }
+ }
+
+ Lockfile::~Lockfile( void )
+ {
+ // unlock userdata by removing file
+ if ( m_bRemove )
+ File::remove( m_aLockname );
+ }
+}
+
+
+
+
+
+
+
+
+
diff --git a/desktop/source/app/lockfile.hxx b/desktop/source/app/lockfile.hxx
new file mode 100644
index 000000000000..248e44c52160
--- /dev/null
+++ b/desktop/source/app/lockfile.hxx
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/* Information:
+ * This class implements a mechanism to lock a users installation directory,
+ * which is necessesary because instances of staroffice could be running on
+ * different hosts while using the same directory thus causing data
+ * inconsistency.
+ * When an existing lock is detected, the user will be asked whether he wants
+ * to continue anyway, thus removing the lock and replacing it with a new one
+ *
+ * ideas:
+ * - store information about user and host and time in the lockfile and display
+ * these when asking whether to remove the lockfile.
+ * - periodically check the lockfile and warn the user when it gets replaced
+ *
+ */
+
+#include "sal/types.h"
+#include "rtl/ustring.hxx"
+
+class ByteString;
+
+namespace desktop {
+
+ class Lockfile;
+ bool Lockfile_execWarning( Lockfile * that );
+
+ class Lockfile
+ {
+ public:
+
+ // contructs a new lockfile onject
+ Lockfile( bool bIPCserver = true );
+
+ // separating GUI code:
+ typedef bool (* fpExecWarning)( Lockfile * that );
+
+ // checks the lockfile, asks user when lockfile is
+ // found (iff gui) and returns false when we may not continue
+ sal_Bool check( fpExecWarning execWarning );
+
+ // removes the lockfile. should only be called in exceptional situations
+ void clean(void);
+
+ // removes the lockfile
+ ~Lockfile(void);
+
+ private:
+ // data in lockfile
+ static const ByteString Group();
+ static const ByteString Userkey();
+ static const ByteString Hostkey();
+ static const ByteString Stampkey();
+ static const ByteString Timekey();
+ static const ByteString IPCkey();
+ // lockfilename
+ static const rtl::OUString Suffix();
+ bool m_bIPCserver;
+ // full qualified name (file://-url) of the lockfile
+ rtl::OUString m_aLockname;
+ // flag whether the d'tor should delete the lock
+ sal_Bool m_bRemove;
+ sal_Bool m_bIsLocked;
+ // ID
+ rtl::OUString m_aId;
+ rtl::OUString m_aDate;
+ // access to data in file
+ void syncToFile(void) const;
+ sal_Bool isStale(void) const;
+ friend bool Lockfile_execWarning( Lockfile * that );
+
+ };
+
+}
diff --git a/desktop/source/app/lockfile2.cxx b/desktop/source/app/lockfile2.cxx
new file mode 100644
index 000000000000..c155d9e6a3cd
--- /dev/null
+++ b/desktop/source/app/lockfile2.cxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "vcl/msgbox.hxx"
+#include "desktopresid.hxx"
+#include "desktop.hrc"
+#include "tools/config.hxx"
+#include "lockfile.hxx"
+
+
+namespace desktop {
+
+bool Lockfile_execWarning( Lockfile * that )
+{
+ // read information from lock
+ String aLockname = that->m_aLockname;
+ Config aConfig(aLockname);
+ aConfig.SetGroup(that->Group());
+ ByteString aHost = aConfig.ReadKey( that->Hostkey() );
+ ByteString aUser = aConfig.ReadKey( that->Userkey() );
+ ByteString aStamp = aConfig.ReadKey( that->Stampkey() );
+ ByteString aTime = aConfig.ReadKey( that->Timekey() );
+
+ // display warning and return response
+ QueryBox aBox( NULL, DesktopResId( QBX_USERDATALOCKED ) );
+ // set box title
+ String aTitle = String( DesktopResId( STR_TITLE_USERDATALOCKED ));
+ aBox.SetText( aTitle );
+ // insert values...
+ String aMsgText = aBox.GetMessText( );
+ aMsgText.SearchAndReplaceAscii(
+ "$u", String( aUser, RTL_TEXTENCODING_ASCII_US) );
+ aMsgText.SearchAndReplaceAscii(
+ "$h", String( aHost, RTL_TEXTENCODING_ASCII_US) );
+ aMsgText.SearchAndReplaceAscii(
+ "$t", String( aTime, RTL_TEXTENCODING_ASCII_US) );
+ aBox.SetMessText(aMsgText);
+ // do it
+ return aBox.Execute( ) == RET_YES;
+}
+
+}
+
diff --git a/desktop/source/app/main.c b/desktop/source/app/main.c
new file mode 100644
index 000000000000..dceaf1a3fba1
--- /dev/null
+++ b/desktop/source/app/main.c
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sal/config.h"
+
+#include "sal/main.h"
+
+#include "sofficemain.h"
+
+SAL_IMPLEMENT_MAIN() {
+ return soffice_main();
+}
diff --git a/desktop/source/app/makefile.mk b/desktop/source/app/makefile.mk
new file mode 100644
index 000000000000..085d8520e7ad
--- /dev/null
+++ b/desktop/source/app/makefile.mk
@@ -0,0 +1,115 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=desktop
+TARGET=dkt
+AUTOSEG=true
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : ../deployment/inc/dp_misc.mk
+
+.IF "$(ENABLE_GNOMEVFS)"=="TRUE"
+CFLAGS+=-DGNOME_VFS_ENABLED
+.ENDIF
+
+# .IF "$(OS)" == "WNT"
+# .IF "$(COM)" == "GCC"
+# DEPLOYMENTMISCLIB = -ldeploymentmisc$(DLLPOSTFIX)
+# .ELSE
+# DEPLOYMENTMISCLIB = ideploymentmisc$(DLLPOSTFIX).lib
+# .ENDIF
+# .ELIF "$(OS)" == "OS2"
+# DEPLOYMENTMISCLIB = ideploymentmisc$(DLLPOSTFIX).lib
+# .ELSE
+# DEPLOYMENTMISCLIB = -ldeploymentmisc$(DLLPOSTFIX)
+# .ENDIF
+
+SHL1TARGET = sofficeapp
+SHL1OBJS = \
+ $(SLO)$/app.obj \
+ $(SLO)$/appfirststart.obj \
+ $(SLO)$/appinit.obj \
+ $(SLO)$/appsys.obj \
+ $(SLO)$/checkinstall.obj \
+ $(SLO)$/check_ext_deps.obj \
+ $(SLO)$/cmdlineargs.obj \
+ $(SLO)$/cmdlinehelp.obj \
+ $(SLO)$/configinit.obj \
+ $(SLO)$/desktopcontext.obj \
+ $(SLO)$/desktopresid.obj \
+ $(SLO)$/dispatchwatcher.obj \
+ $(SLO)$/langselect.obj \
+ $(SLO)$/lockfile.obj \
+ $(SLO)$/lockfile2.obj \
+ $(SLO)$/officeipcthread.obj \
+ $(SLO)$/sofficemain.obj \
+ $(SLO)$/userinstall.obj
+
+SHL1LIBS = $(SLB)$/mig.lib
+
+SHL1STDLIBS = \
+ $(COMPHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(DEPLOYMENTMISCLIB) \
+ $(I18NISOLANGLIB) \
+ $(SALLIB) \
+ $(SFXLIB) \
+ $(SVLLIB) \
+ $(SVTOOLLIB) \
+ $(TKLIB) \
+ $(TOOLSLIB) \
+ $(UCBHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(VCLLIB) \
+ $(VOSLIB)
+SHL1VERSIONMAP = version.map
+SHL1IMPLIB = i$(SHL1TARGET)
+DEF1NAME = $(SHL1TARGET)
+
+OBJFILES = \
+ $(OBJ)$/copyright_ascii_ooo.obj \
+ $(OBJ)$/main.obj
+.IF "$(GUI)" != "OS2"
+OBJFILES += \
+ $(OBJ)$/copyright_ascii_sun.obj
+.ENDIF
+
+SLOFILES = $(SHL1OBJS)
+
+SRS1NAME= desktop
+SRC1FILES= desktop.src
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/desktop/source/app/officeipcthread.cxx b/desktop/source/app/officeipcthread.cxx
new file mode 100644
index 000000000000..fc74c3fb4504
--- /dev/null
+++ b/desktop/source/app/officeipcthread.cxx
@@ -0,0 +1,996 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "app.hxx"
+#include "officeipcthread.hxx"
+#include "cmdlineargs.hxx"
+#include "dispatchwatcher.hxx"
+#include <memory>
+#include <stdio.h>
+#include <vos/process.hxx>
+#include <unotools/bootstrap.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/help.hxx>
+#include <unotools/configmgr.hxx>
+#include <osl/thread.hxx>
+#include <rtl/digest.h>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/instance.hxx>
+#include <osl/conditn.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/strbuf.hxx>
+#include <comphelper/processfactory.hxx>
+#include "osl/file.hxx"
+#include "rtl/process.h"
+#include "tools/getprocessworkingdir.hxx"
+
+using namespace vos;
+using namespace rtl;
+using namespace desktop;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+
+const char *OfficeIPCThread::sc_aTerminationSequence = "InternalIPC::TerminateThread";
+const int OfficeIPCThread::sc_nTSeqLength = 28;
+const char *OfficeIPCThread::sc_aShowSequence = "-tofront";
+const int OfficeIPCThread::sc_nShSeqLength = 5;
+const char *OfficeIPCThread::sc_aConfirmationSequence = "InternalIPC::ProcessingDone";
+const int OfficeIPCThread::sc_nCSeqLength = 27;
+
+namespace { static char const ARGUMENT_PREFIX[] = "InternalIPC::Arguments"; }
+
+// Type of pipe we use
+enum PipeMode
+{
+ PIPEMODE_DONTKNOW,
+ PIPEMODE_CREATED,
+ PIPEMODE_CONNECTED
+};
+
+namespace desktop
+{
+
+namespace {
+
+class Parser: public CommandLineArgs::Supplier {
+public:
+ explicit Parser(rtl::OString const & input): m_input(input) {
+ if (!m_input.match(ARGUMENT_PREFIX) ||
+ m_input.getLength() == RTL_CONSTASCII_LENGTH(ARGUMENT_PREFIX))
+ {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ m_index = RTL_CONSTASCII_LENGTH(ARGUMENT_PREFIX);
+ switch (m_input[m_index++]) {
+ case '0':
+ break;
+ case '1':
+ {
+ rtl::OUString url;
+ if (!next(&url, false)) {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ m_cwdUrl.reset(url);
+ break;
+ }
+ case '2':
+ {
+ rtl::OUString path;
+ if (!next(&path, false)) {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ rtl::OUString url;
+ if (osl::FileBase::getFileURLFromSystemPath(path, url) ==
+ osl::FileBase::E_None)
+ {
+ m_cwdUrl.reset(url);
+ }
+ break;
+ }
+ default:
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ }
+
+ virtual ~Parser() {}
+
+ virtual boost::optional< rtl::OUString > getCwdUrl() { return m_cwdUrl; }
+
+ virtual bool next(rtl::OUString * argument) { return next(argument, true); }
+
+private:
+ virtual bool next(rtl::OUString * argument, bool prefix) {
+ OSL_ASSERT(argument != NULL);
+ if (m_index < m_input.getLength()) {
+ if (prefix) {
+ if (m_input[m_index] != ',') {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ ++m_index;
+ }
+ rtl::OStringBuffer b;
+ while (m_index < m_input.getLength()) {
+ char c = m_input[m_index];
+ if (c == ',') {
+ break;
+ }
+ ++m_index;
+ if (c == '\\') {
+ if (m_index < m_input.getLength()) {
+ c = m_input[m_index++];
+ switch (c) {
+ case '0':
+ c = '\0';
+ break;
+ case ',':
+ case '\\':
+ break;
+ default:
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ } else {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ }
+ b.append(c);
+ }
+ rtl::OString b2(b.makeStringAndClear());
+ if (!rtl_convertStringToUString(
+ &argument->pData, b2.getStr(), b2.getLength(),
+ RTL_TEXTENCODING_UTF8,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
+ {
+ throw CommandLineArgs::Supplier::Exception();
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ boost::optional< rtl::OUString > m_cwdUrl;
+ rtl::OString m_input;
+ sal_Int32 m_index;
+};
+
+bool addArgument(
+ ByteString * arguments, char prefix, rtl::OUString const & argument)
+{
+ rtl::OString utf8;
+ if (!argument.convertToString(
+ &utf8, RTL_TEXTENCODING_UTF8,
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
+ {
+ return false;
+ }
+ *arguments += prefix;
+ for (sal_Int32 i = 0; i < utf8.getLength(); ++i) {
+ char c = utf8[i];
+ switch (c) {
+ case '\0':
+ *arguments += "\\0";
+ break;
+ case ',':
+ *arguments += "\\,";
+ break;
+ case '\\':
+ *arguments += "\\\\";
+ break;
+ default:
+ *arguments += c;
+ break;
+ }
+ }
+ return true;
+}
+
+}
+
+OfficeIPCThread* OfficeIPCThread::pGlobalOfficeIPCThread = 0;
+namespace { struct Security : public rtl::Static<OSecurity, Security> {}; }
+::osl::Mutex* OfficeIPCThread::pOfficeIPCThreadMutex = 0;
+
+
+String CreateMD5FromString( const OUString& aMsg )
+{
+ // PRE: aStr "file"
+ // BACK: Str "ababab....0f" Hexcode String
+
+ rtlDigest handle = rtl_digest_create( rtl_Digest_AlgorithmMD5 );
+ if ( handle > 0 )
+ {
+ const sal_uInt8* pData = (const sal_uInt8*)aMsg.getStr();
+ sal_uInt32 nSize = ( aMsg.getLength() * sizeof( sal_Unicode ));
+ sal_uInt32 nMD5KeyLen = rtl_digest_queryLength( handle );
+ sal_uInt8* pMD5KeyBuffer = new sal_uInt8[ nMD5KeyLen ];
+
+ rtl_digest_init( handle, pData, nSize );
+ rtl_digest_update( handle, pData, nSize );
+ rtl_digest_get( handle, pMD5KeyBuffer, nMD5KeyLen );
+ rtl_digest_destroy( handle );
+
+ // Create hex-value string from the MD5 value to keep the string size minimal
+ OUStringBuffer aBuffer( nMD5KeyLen * 2 + 1 );
+ for ( sal_uInt32 i = 0; i < nMD5KeyLen; i++ )
+ aBuffer.append( (sal_Int32)pMD5KeyBuffer[i], 16 );
+
+ delete [] pMD5KeyBuffer;
+ return aBuffer.makeStringAndClear();
+ }
+
+ return String();
+}
+
+class ProcessEventsClass_Impl
+{
+public:
+ DECL_STATIC_LINK( ProcessEventsClass_Impl, CallEvent, void* pEvent );
+ DECL_STATIC_LINK( ProcessEventsClass_Impl, ProcessDocumentsEvent, void* pEvent );
+};
+
+IMPL_STATIC_LINK_NOINSTANCE( ProcessEventsClass_Impl, CallEvent, void*, pEvent )
+{
+ // Application events are processed by the Desktop::HandleAppEvent implementation.
+ Desktop::HandleAppEvent( *((ApplicationEvent*)pEvent) );
+ delete (ApplicationEvent*)pEvent;
+ return 0;
+}
+
+IMPL_STATIC_LINK_NOINSTANCE( ProcessEventsClass_Impl, ProcessDocumentsEvent, void*, pEvent )
+{
+ // Documents requests are processed by the OfficeIPCThread implementation
+ ProcessDocumentsRequest* pDocsRequest = (ProcessDocumentsRequest*)pEvent;
+
+ if ( pDocsRequest )
+ {
+ OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
+ delete pDocsRequest;
+ }
+ return 0;
+}
+
+void ImplPostForeignAppEvent( ApplicationEvent* pEvent )
+{
+ Application::PostUserEvent( STATIC_LINK( NULL, ProcessEventsClass_Impl, CallEvent ), pEvent );
+}
+
+void ImplPostProcessDocumentsEvent( ProcessDocumentsRequest* pEvent )
+{
+ Application::PostUserEvent( STATIC_LINK( NULL, ProcessEventsClass_Impl, ProcessDocumentsEvent ), pEvent );
+}
+
+OSignalHandler::TSignalAction SAL_CALL SalMainPipeExchangeSignalHandler::signal(TSignalInfo *pInfo)
+{
+ if( pInfo->Signal == osl_Signal_Terminate )
+ OfficeIPCThread::DisableOfficeIPCThread();
+ return (TAction_CallNextHandler);
+}
+
+// ----------------------------------------------------------------------------
+
+// The OfficeIPCThreadController implementation is a bookkeeper for all pending requests
+// that were created by the OfficeIPCThread. The requests are waiting to be processed by
+// our framework loadComponentFromURL function (e.g. open/print request).
+// During shutdown the framework is asking OfficeIPCThreadController about pending requests.
+// If there are pending requests framework has to stop the shutdown process. It is waiting
+// for these requests because framework is not able to handle shutdown and open a document
+// concurrently.
+
+
+// XServiceInfo
+OUString SAL_CALL OfficeIPCThreadController::getImplementationName()
+throw ( RuntimeException )
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.OfficeIPCThreadController" ));
+}
+
+sal_Bool SAL_CALL OfficeIPCThreadController::supportsService( const OUString& )
+throw ( RuntimeException )
+{
+ return sal_False;
+}
+
+Sequence< OUString > SAL_CALL OfficeIPCThreadController::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ Sequence< OUString > aSeq( 0 );
+ return aSeq;
+}
+
+// XEventListener
+void SAL_CALL OfficeIPCThreadController::disposing( const EventObject& )
+throw( RuntimeException )
+{
+}
+
+// XTerminateListener
+void SAL_CALL OfficeIPCThreadController::queryTermination( const EventObject& )
+throw( TerminationVetoException, RuntimeException )
+{
+ // Desktop ask about pending request through our office ipc pipe. We have to
+ // be sure that no pending request is waiting because framework is not able to
+ // handle shutdown and open a document concurrently.
+
+ if ( OfficeIPCThread::AreRequestsPending() )
+ throw TerminationVetoException();
+ else
+ OfficeIPCThread::SetDowning();
+}
+
+void SAL_CALL OfficeIPCThreadController::notifyTermination( const EventObject& )
+throw( RuntimeException )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+::osl::Mutex& OfficeIPCThread::GetMutex()
+{
+ // Get or create our mutex for thread-saftey
+ if ( !pOfficeIPCThreadMutex )
+ {
+ ::osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() );
+ if ( !pOfficeIPCThreadMutex )
+ pOfficeIPCThreadMutex = new osl::Mutex;
+ }
+
+ return *pOfficeIPCThreadMutex;
+}
+
+void OfficeIPCThread::SetDowning()
+{
+ // We have the order to block all incoming requests. Framework
+ // wants to shutdown and we have to make sure that no loading/printing
+ // requests are executed anymore.
+ ::osl::MutexGuard aGuard( GetMutex() );
+
+ if ( pGlobalOfficeIPCThread )
+ pGlobalOfficeIPCThread->mbDowning = true;
+}
+
+static bool s_bInEnableRequests = false;
+
+void OfficeIPCThread::EnableRequests( bool i_bEnable )
+{
+ // switch between just queueing the requests and executing them
+ ::osl::MutexGuard aGuard( GetMutex() );
+
+ if ( pGlobalOfficeIPCThread )
+ {
+ s_bInEnableRequests = true;
+ pGlobalOfficeIPCThread->mbRequestsEnabled = i_bEnable;
+ if( i_bEnable )
+ {
+ // hit the compiler over the head
+ ProcessDocumentsRequest aEmptyReq = ProcessDocumentsRequest( boost::optional< rtl::OUString >() );
+ // trigger already queued requests
+ OfficeIPCThread::ExecuteCmdLineRequests( aEmptyReq );
+ }
+ s_bInEnableRequests = false;
+ }
+}
+
+sal_Bool OfficeIPCThread::AreRequestsPending()
+{
+ // Give info about pending requests
+ ::osl::MutexGuard aGuard( GetMutex() );
+ if ( pGlobalOfficeIPCThread )
+ return ( pGlobalOfficeIPCThread->mnPendingRequests > 0 );
+ else
+ return sal_False;
+}
+
+void OfficeIPCThread::RequestsCompleted( int nCount )
+{
+ // Remove nCount pending requests from our internal counter
+ ::osl::MutexGuard aGuard( GetMutex() );
+ if ( pGlobalOfficeIPCThread )
+ {
+ if ( pGlobalOfficeIPCThread->mnPendingRequests > 0 )
+ pGlobalOfficeIPCThread->mnPendingRequests -= nCount;
+ }
+}
+
+OfficeIPCThread::Status OfficeIPCThread::EnableOfficeIPCThread()
+{
+ ::osl::MutexGuard aGuard( GetMutex() );
+
+ if( pGlobalOfficeIPCThread )
+ return IPC_STATUS_OK;
+
+ ::rtl::OUString aUserInstallPath;
+ ::rtl::OUString aDummy;
+
+ ::vos::OStartupInfo aInfo;
+ OfficeIPCThread* pThread = new OfficeIPCThread;
+
+ pThread->maPipeIdent = OUString( RTL_CONSTASCII_USTRINGPARAM( "SingleOfficeIPC_" ) );
+
+ // The name of the named pipe is created with the hashcode of the user installation directory (without /user). We have to retrieve
+ // this information from a unotools implementation.
+ ::utl::Bootstrap::PathStatus aLocateResult = ::utl::Bootstrap::locateUserInstallation( aUserInstallPath );
+ if ( aLocateResult == ::utl::Bootstrap::PATH_EXISTS || aLocateResult == ::utl::Bootstrap::PATH_VALID)
+ aDummy = aUserInstallPath;
+ else
+ {
+ delete pThread;
+ return IPC_STATUS_BOOTSTRAP_ERROR;
+ }
+
+ // Try to determine if we are the first office or not! This should prevent multiple
+ // access to the user directory !
+ // First we try to create our pipe if this fails we try to connect. We have to do this
+ // in a loop because the the other office can crash or shutdown between createPipe
+ // and connectPipe!!
+
+ OUString aIniName;
+
+ aInfo.getExecutableFile( aIniName );
+ sal_uInt32 lastIndex = aIniName.lastIndexOf('/');
+ if ( lastIndex > 0 )
+ {
+ aIniName = aIniName.copy( 0, lastIndex+1 );
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "perftune" ));
+#if defined(WNT) || defined(OS2)
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( ".ini" ));
+#else
+ aIniName += OUString( RTL_CONSTASCII_USTRINGPARAM( "rc" ));
+#endif
+ }
+
+ ::rtl::Bootstrap aPerfTuneIniFile( aIniName );
+
+ OUString aDefault( RTL_CONSTASCII_USTRINGPARAM( "0" ));
+ OUString aPreloadData;
+
+ aPerfTuneIniFile.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "FastPipeCommunication" )), aPreloadData, aDefault );
+
+
+ OUString aUserInstallPathHashCode;
+
+ if ( aPreloadData.equalsAscii( "1" ))
+ {
+ sal_Char szBuffer[32];
+ sprintf( szBuffer, "%d", SUPD );
+ aUserInstallPathHashCode = OUString( szBuffer, strlen(szBuffer), osl_getThreadTextEncoding() );
+ }
+ else
+ aUserInstallPathHashCode = CreateMD5FromString( aDummy );
+
+
+ // Check result to create a hash code from the user install path
+ if ( aUserInstallPathHashCode.getLength() == 0 )
+ return IPC_STATUS_BOOTSTRAP_ERROR; // Something completely broken, we cannot create a valid hash code!
+
+ pThread->maPipeIdent = pThread->maPipeIdent + aUserInstallPathHashCode;
+
+ PipeMode nPipeMode = PIPEMODE_DONTKNOW;
+ do
+ {
+ OSecurity &rSecurity = Security::get();
+ // Try to create pipe
+ if ( pThread->maPipe.create( pThread->maPipeIdent.getStr(), OPipe::TOption_Create, rSecurity ))
+ {
+ // Pipe created
+ nPipeMode = PIPEMODE_CREATED;
+ }
+ else if( pThread->maPipe.create( pThread->maPipeIdent.getStr(), OPipe::TOption_Open, rSecurity )) // Creation not successfull, now we try to connect
+ {
+ // Pipe connected to first office
+ nPipeMode = PIPEMODE_CONNECTED;
+ }
+ else
+ {
+ OPipe::TPipeError eReason = pThread->maPipe.getError();
+ if ((eReason == OPipe::E_ConnectionRefused) || (eReason == OPipe::E_invalidError))
+ return IPC_STATUS_BOOTSTRAP_ERROR;
+
+ // Wait for second office to be ready
+ TimeValue aTimeValue;
+ aTimeValue.Seconds = 0;
+ aTimeValue.Nanosec = 10000000; // 10ms
+ osl::Thread::wait( aTimeValue );
+ }
+
+ } while ( nPipeMode == PIPEMODE_DONTKNOW );
+
+ if ( nPipeMode == PIPEMODE_CREATED )
+ {
+ // Seems we are the one and only, so start listening thread
+ pGlobalOfficeIPCThread = pThread;
+ pThread->create(); // starts thread
+ }
+ else
+ {
+ // Seems another office is running. Pipe arguments to it and self terminate
+ pThread->maStreamPipe = pThread->maPipe;
+
+ sal_Bool bWaitBeforeClose = sal_False;
+ ByteString aArguments(RTL_CONSTASCII_STRINGPARAM(ARGUMENT_PREFIX));
+ rtl::OUString cwdUrl;
+ if (!(tools::getProcessWorkingDir(&cwdUrl) &&
+ addArgument(&aArguments, '1', cwdUrl)))
+ {
+ aArguments += '0';
+ }
+ sal_uInt32 nCount = rtl_getAppCommandArgCount();
+ for( sal_uInt32 i=0; i < nCount; i++ )
+ {
+ rtl_getAppCommandArg( i, &aDummy.pData );
+ if( aDummy.indexOf('-',0) != 0 )
+ {
+ bWaitBeforeClose = sal_True;
+ }
+ if (!addArgument(&aArguments, ',', aDummy)) {
+ return IPC_STATUS_BOOTSTRAP_ERROR;
+ }
+ }
+ // finaly, write the string onto the pipe
+ pThread->maStreamPipe.write( aArguments.GetBuffer(), aArguments.Len() );
+ pThread->maStreamPipe.write( "\0", 1 );
+
+ // wait for confirmation #95361# #95425#
+ ByteString aToken(sc_aConfirmationSequence);
+ char *aReceiveBuffer = new char[aToken.Len()+1];
+ int n = pThread->maStreamPipe.read( aReceiveBuffer, aToken.Len() );
+ aReceiveBuffer[n]='\0';
+
+ delete pThread;
+ if (aToken.CompareTo(aReceiveBuffer)!= COMPARE_EQUAL) {
+ // something went wrong
+ delete[] aReceiveBuffer;
+ return IPC_STATUS_BOOTSTRAP_ERROR;
+ } else {
+ delete[] aReceiveBuffer;
+ return IPC_STATUS_2ND_OFFICE;
+ }
+ }
+
+ return IPC_STATUS_OK;
+}
+
+void OfficeIPCThread::DisableOfficeIPCThread()
+{
+ osl::ClearableMutexGuard aMutex( GetMutex() );
+
+ if( pGlobalOfficeIPCThread )
+ {
+ OfficeIPCThread *pOfficeIPCThread = pGlobalOfficeIPCThread;
+ pGlobalOfficeIPCThread = 0;
+
+ // send thread a termination message
+ // this is done so the subsequent join will not hang
+ // because the thread hangs in accept of pipe
+ OPipe Pipe( pOfficeIPCThread->maPipeIdent, OPipe::TOption_Open, Security::get() );
+ //Pipe.send( TERMINATION_SEQUENCE, TERMINATION_LENGTH );
+ if (Pipe.isValid())
+ {
+ Pipe.send( sc_aTerminationSequence, sc_nTSeqLength+1 ); // also send 0-byte
+
+ // close the pipe so that the streampipe on the other
+ // side produces EOF
+ Pipe.close();
+ }
+
+ // release mutex to avoid deadlocks
+ aMutex.clear();
+
+ OfficeIPCThread::SetReady(pOfficeIPCThread);
+
+ // exit gracefully and join
+ pOfficeIPCThread->join();
+ delete pOfficeIPCThread;
+
+
+ }
+}
+
+OfficeIPCThread::OfficeIPCThread() :
+ mbDowning( false ),
+ mbRequestsEnabled( false ),
+ mnPendingRequests( 0 ),
+ mpDispatchWatcher( 0 )
+{
+}
+
+OfficeIPCThread::~OfficeIPCThread()
+{
+ ::osl::ClearableMutexGuard aGuard( GetMutex() );
+
+ if ( mpDispatchWatcher )
+ mpDispatchWatcher->release();
+ maPipe.close();
+ maStreamPipe.close();
+ pGlobalOfficeIPCThread = 0;
+}
+
+static void AddURLToStringList( const rtl::OUString& aURL, rtl::OUString& aStringList )
+{
+ if ( aStringList.getLength() )
+ aStringList += ::rtl::OUString::valueOf( (sal_Unicode)APPEVENT_PARAM_DELIMITER );
+ aStringList += aURL;
+}
+
+void OfficeIPCThread::SetReady(OfficeIPCThread* pThread)
+{
+ if (pThread == NULL) pThread = pGlobalOfficeIPCThread;
+ if (pThread != NULL)
+ {
+ pThread->cReady.set();
+ }
+}
+
+void SAL_CALL OfficeIPCThread::run()
+{
+ do
+ {
+ OPipe::TPipeError
+ nError = maPipe.accept( maStreamPipe );
+
+
+ if( nError == OStreamPipe::E_None )
+ {
+
+ // #111143# and others:
+ // if we receive a request while the office is displaying some dialog or error during
+ // bootstrap, that dialogs event loop might get events that are dispatched by this thread
+ // we have to wait for cReady to be set by the real main loop.
+ // only reqests that dont dispatch events may be processed before cReady is set.
+ cReady.wait();
+
+ // we might have decided to shutdown while we were sleeping
+ if (!pGlobalOfficeIPCThread) return;
+
+ // only lock the mutex when processing starts, othewise we deadlock when the office goes
+ // down during wait
+ osl::ClearableMutexGuard aGuard( GetMutex() );
+
+ ByteString aArguments;
+ // test byte by byte
+ const int nBufSz = 2048;
+ char pBuf[nBufSz];
+ int nBytes = 0;
+ int nResult = 0;
+ // read into pBuf until '\0' is read or read-error
+ while ((nResult=maStreamPipe.recv( pBuf+nBytes, nBufSz-nBytes))>0) {
+ nBytes += nResult;
+ if (pBuf[nBytes-1]=='\0') {
+ aArguments += pBuf;
+ break;
+ }
+ }
+ // don't close pipe ...
+
+ // #90717# Is this a lookup message from another application? if so, ignore
+ if ( aArguments.Len() == 0 )
+ continue;
+
+ // is this a termination message ? if so, terminate
+ if(( aArguments.CompareTo( sc_aTerminationSequence, sc_nTSeqLength ) == COMPARE_EQUAL ) ||
+ mbDowning ) return;
+ String aEmpty;
+ std::auto_ptr< CommandLineArgs > aCmdLineArgs;
+ try
+ {
+ Parser p( aArguments );
+ aCmdLineArgs.reset( new CommandLineArgs( p ) );
+ }
+ catch ( CommandLineArgs::Supplier::Exception & )
+ {
+#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
+ fprintf( stderr, "Error in received command line arguments\n" );
+#endif
+ continue;
+ }
+ CommandLineArgs *pCurrentCmdLineArgs = Desktop::GetCommandLineArgs();
+
+ if ( aCmdLineArgs->IsQuickstart() )
+ {
+ // we have to use application event, because we have to start quickstart service in main thread!!
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty,
+ "QUICKSTART", aEmpty );
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+
+ // handle request for acceptor
+ sal_Bool bAcceptorRequest = sal_False;
+ OUString aAcceptString;
+ if ( aCmdLineArgs->GetAcceptString(aAcceptString) && Desktop::CheckOEM()) {
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty,
+ "ACCEPT", aAcceptString );
+ ImplPostForeignAppEvent( pAppEvent );
+ bAcceptorRequest = sal_True;
+ }
+ // handle acceptor removal
+ OUString aUnAcceptString;
+ if ( aCmdLineArgs->GetUnAcceptString(aUnAcceptString) ) {
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty,
+ "UNACCEPT", aUnAcceptString );
+ ImplPostForeignAppEvent( pAppEvent );
+ bAcceptorRequest = sal_True;
+ }
+
+#ifndef UNX
+ // only in non-unix version, we need to handle a -help request
+ // in a running instance in order to display the command line help
+ if ( aCmdLineArgs->IsHelp() ) {
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty, "HELP", aEmpty );
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+#endif
+
+ sal_Bool bDocRequestSent = sal_False;
+ ProcessDocumentsRequest* pRequest = new ProcessDocumentsRequest(
+ aCmdLineArgs->getCwdUrl());
+ cProcessed.reset();
+ pRequest->pcProcessed = &cProcessed;
+
+ // Print requests are not dependent on the -invisible cmdline argument as they are
+ // loaded with the "hidden" flag! So they are always checked.
+ bDocRequestSent |= aCmdLineArgs->GetPrintList( pRequest->aPrintList );
+ bDocRequestSent |= ( aCmdLineArgs->GetPrintToList( pRequest->aPrintToList ) &&
+ aCmdLineArgs->GetPrinterName( pRequest->aPrinterName ) );
+
+ if ( !pCurrentCmdLineArgs->IsInvisible() )
+ {
+ // Read cmdline args that can open/create documents. As they would open a window
+ // they are only allowed if the "-invisible" is currently not used!
+ bDocRequestSent |= aCmdLineArgs->GetOpenList( pRequest->aOpenList );
+ bDocRequestSent |= aCmdLineArgs->GetViewList( pRequest->aViewList );
+ bDocRequestSent |= aCmdLineArgs->GetStartList( pRequest->aStartList );
+ bDocRequestSent |= aCmdLineArgs->GetForceOpenList( pRequest->aForceOpenList );
+ bDocRequestSent |= aCmdLineArgs->GetForceNewList( pRequest->aForceNewList );
+
+ // Special command line args to create an empty document for a given module
+
+ // #i18338# (lo)
+ // we only do this if no document was specified on the command line,
+ // since this would be inconsistent with the the behaviour of
+ // the first process, see OpenClients() (call to OpenDefault()) in app.cxx
+ if ( aCmdLineArgs->HasModuleParam() && Desktop::CheckOEM() && (!bDocRequestSent))
+ {
+ SvtModuleOptions aOpt;
+ SvtModuleOptions::EFactory eFactory = SvtModuleOptions::E_WRITER;
+ if ( aCmdLineArgs->IsWriter() )
+ eFactory = SvtModuleOptions::E_WRITER;
+ else if ( aCmdLineArgs->IsCalc() )
+ eFactory = SvtModuleOptions::E_CALC;
+ else if ( aCmdLineArgs->IsDraw() )
+ eFactory = SvtModuleOptions::E_DRAW;
+ else if ( aCmdLineArgs->IsImpress() )
+ eFactory = SvtModuleOptions::E_IMPRESS;
+ else if ( aCmdLineArgs->IsBase() )
+ eFactory = SvtModuleOptions::E_DATABASE;
+ else if ( aCmdLineArgs->IsMath() )
+ eFactory = SvtModuleOptions::E_MATH;
+ else if ( aCmdLineArgs->IsGlobal() )
+ eFactory = SvtModuleOptions::E_WRITERGLOBAL;
+ else if ( aCmdLineArgs->IsWeb() )
+ eFactory = SvtModuleOptions::E_WRITERWEB;
+
+ if ( pRequest->aOpenList.getLength() )
+ pRequest->aModule = aOpt.GetFactoryName( eFactory );
+ else
+ AddURLToStringList( aOpt.GetFactoryEmptyDocumentURL( eFactory ), pRequest->aOpenList );
+ bDocRequestSent = sal_True;
+ }
+ }
+
+ if (!aCmdLineArgs->IsQuickstart() && Desktop::CheckOEM()) {
+ sal_Bool bShowHelp = sal_False;
+ rtl::OUStringBuffer aHelpURLBuffer;
+ if (aCmdLineArgs->IsHelpWriter()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://swriter/start");
+ } else if (aCmdLineArgs->IsHelpCalc()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://scalc/start");
+ } else if (aCmdLineArgs->IsHelpDraw()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdraw/start");
+ } else if (aCmdLineArgs->IsHelpImpress()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://simpress/start");
+ } else if (aCmdLineArgs->IsHelpBase()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdatabase/start");
+ } else if (aCmdLineArgs->IsHelpBasic()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://sbasic/start");
+ } else if (aCmdLineArgs->IsHelpMath()) {
+ bShowHelp = sal_True;
+ aHelpURLBuffer.appendAscii("vnd.sun.star.help://smath/start");
+ }
+ if (bShowHelp) {
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::LOCALE );
+ rtl::OUString aTmp;
+ aRet >>= aTmp;
+ aHelpURLBuffer.appendAscii("?Language=");
+ aHelpURLBuffer.append(aTmp);
+#if defined UNX
+ aHelpURLBuffer.appendAscii("&System=UNX");
+#elif defined WNT
+ aHelpURLBuffer.appendAscii("&System=WIN");
+#elif defined MAC
+ aHelpURLBuffer.appendAscii("&System=MAC");
+#elif defined OS2
+ aHelpURLBuffer.appendAscii("&System=OS2");
+#endif
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty,
+ "OPENHELPURL", aHelpURLBuffer.makeStringAndClear());
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+ }
+
+ if ( bDocRequestSent && Desktop::CheckOEM())
+ {
+ // Send requests to dispatch watcher if we have at least one. The receiver
+ // is responsible to delete the request after processing it.
+ if ( aCmdLineArgs->HasModuleParam() )
+ {
+ SvtModuleOptions aOpt;
+
+ // Support command line parameters to start a module (as preselection)
+ if ( aCmdLineArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
+ pRequest->aModule = aOpt.GetFactoryName( SvtModuleOptions::E_WRITER );
+ else if ( aCmdLineArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
+ pRequest->aModule = aOpt.GetFactoryName( SvtModuleOptions::E_CALC );
+ else if ( aCmdLineArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
+ pRequest->aModule= aOpt.GetFactoryName( SvtModuleOptions::E_IMPRESS );
+ else if ( aCmdLineArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
+ pRequest->aModule= aOpt.GetFactoryName( SvtModuleOptions::E_DRAW );
+ }
+
+
+ ImplPostProcessDocumentsEvent( pRequest );
+ }
+ else
+ {
+ // delete not used request again
+ delete pRequest;
+ pRequest = NULL;
+ }
+ if (( aArguments.CompareTo( sc_aShowSequence, sc_nShSeqLength ) == COMPARE_EQUAL ) ||
+ aCmdLineArgs->IsEmpty() )
+ {
+ // no document was sent, just bring Office to front
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent( aEmpty, aEmpty, "APPEAR", aEmpty );
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+
+ // we don't need the mutex any longer...
+ aGuard.clear();
+ // wait for processing to finish
+ if (bDocRequestSent)
+ cProcessed.wait();
+ // processing finished, inform the requesting end
+ nBytes = 0;
+ while (
+ (nResult = maStreamPipe.send(sc_aConfirmationSequence+nBytes, sc_nCSeqLength-nBytes))>0 &&
+ ((nBytes += nResult) < sc_nCSeqLength) ) ;
+ // now we can close, don't we?
+ // maStreamPipe.close();
+
+ }
+ else
+ {
+#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
+ fprintf( stderr, "Error on accept: %d\n", (int)nError );
+#endif
+ TimeValue tval;
+ tval.Seconds = 1;
+ tval.Nanosec = 0;
+ sleep( tval );
+ }
+ } while( schedule() );
+}
+
+static void AddToDispatchList(
+ DispatchWatcher::DispatchList& rDispatchList,
+ boost::optional< rtl::OUString > const & cwdUrl,
+ const OUString& aRequestList,
+ DispatchWatcher::RequestType nType,
+ const OUString& aParam,
+ const OUString& aFactory )
+{
+ if ( aRequestList.getLength() > 0 )
+ {
+ sal_Int32 nIndex = 0;
+ do
+ {
+ OUString aToken = aRequestList.getToken( 0, APPEVENT_PARAM_DELIMITER, nIndex );
+ if ( aToken.getLength() > 0 )
+ rDispatchList.push_back(
+ DispatchWatcher::DispatchRequest( nType, aToken, cwdUrl, aParam, aFactory ));
+ }
+ while ( nIndex >= 0 );
+ }
+}
+
+sal_Bool OfficeIPCThread::ExecuteCmdLineRequests( ProcessDocumentsRequest& aRequest )
+{
+ // protect the dispatch list
+ osl::ClearableMutexGuard aGuard( GetMutex() );
+
+ static DispatchWatcher::DispatchList aDispatchList;
+
+ rtl::OUString aEmpty;
+ // Create dispatch list for dispatch watcher
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aOpenList, DispatchWatcher::REQUEST_OPEN, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aViewList, DispatchWatcher::REQUEST_VIEW, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aStartList, DispatchWatcher::REQUEST_START, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aPrintList, DispatchWatcher::REQUEST_PRINT, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aPrintToList, DispatchWatcher::REQUEST_PRINTTO, aRequest.aPrinterName, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aForceOpenList, DispatchWatcher::REQUEST_FORCEOPEN, aEmpty, aRequest.aModule );
+ AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aForceNewList, DispatchWatcher::REQUEST_FORCENEW, aEmpty, aRequest.aModule );
+
+ sal_Bool bShutdown( sal_False );
+
+ if ( pGlobalOfficeIPCThread )
+ {
+ if( ! pGlobalOfficeIPCThread->AreRequestsEnabled() )
+ return bShutdown;
+
+ pGlobalOfficeIPCThread->mnPendingRequests += aDispatchList.size();
+ if ( !pGlobalOfficeIPCThread->mpDispatchWatcher )
+ {
+ pGlobalOfficeIPCThread->mpDispatchWatcher = DispatchWatcher::GetDispatchWatcher();
+ pGlobalOfficeIPCThread->mpDispatchWatcher->acquire();
+ }
+
+ // copy for execute
+ DispatchWatcher::DispatchList aTempList( aDispatchList );
+ aDispatchList.clear();
+
+ aGuard.clear();
+
+ // Execute dispatch requests
+ bShutdown = pGlobalOfficeIPCThread->mpDispatchWatcher->executeDispatchRequests( aTempList, s_bInEnableRequests );
+
+ // set processed flag
+ if (aRequest.pcProcessed != NULL)
+ aRequest.pcProcessed->set();
+ }
+
+ return bShutdown;
+}
+
+}
diff --git a/desktop/source/app/officeipcthread.hxx b/desktop/source/app/officeipcthread.hxx
new file mode 100644
index 000000000000..2cbcab0fce2a
--- /dev/null
+++ b/desktop/source/app/officeipcthread.hxx
@@ -0,0 +1,165 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DESKTOP_OFFICEIPCTHREAD_HXX_
+#define _DESKTOP_OFFICEIPCTHREAD_HXX_
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/frame/XTerminateListener.hpp>
+#include <vos/pipe.hxx>
+#include <vos/security.hxx>
+#include <vos/thread.hxx>
+#include <vos/signal.hxx>
+#include <rtl/ustring.hxx>
+#ifndef _CPPUHELPER_WEAKBASE2_HXX_
+#include <cppuhelper/implbase2.hxx>
+#endif
+#include <osl/conditn.hxx>
+#include "boost/optional.hpp"
+
+namespace desktop
+{
+
+class SalMainPipeExchangeSignalHandler : public vos::OSignalHandler
+{
+ virtual TSignalAction SAL_CALL signal(TSignalInfo *pInfo);
+};
+
+// A request for the current office
+// that was given by command line or by IPC pipe communication.
+struct ProcessDocumentsRequest
+{
+ ProcessDocumentsRequest(boost::optional< rtl::OUString > const & cwdUrl):
+ aCwdUrl(cwdUrl), pcProcessed( NULL ) {}
+
+ boost::optional< ::rtl::OUString > aCwdUrl;
+ ::rtl::OUString aModule;
+ ::rtl::OUString aOpenList; // Documents that should be opened in the default way
+ ::rtl::OUString aViewList; // Documents that should be opened in viewmode
+ ::rtl::OUString aStartList; // Documents/Presentations that should be started
+ ::rtl::OUString aPrintList; // Documents that should be printed on default printer
+ ::rtl::OUString aForceOpenList; // Documents that should be forced to open for editing (even templates)
+ ::rtl::OUString aForceNewList; // Documents that should be forced to create a new document
+ ::rtl::OUString aPrinterName; // The printer name that should be used for printing
+ ::rtl::OUString aPrintToList; // Documents that should be printed on the given printer
+ ::osl::Condition *pcProcessed; // pointer condition to be set when the request has been processed
+};
+
+class DispatchWatcher;
+class OfficeIPCThread : public vos::OThread
+{
+ private:
+ static OfficeIPCThread* pGlobalOfficeIPCThread;
+ static ::osl::Mutex* pOfficeIPCThreadMutex;
+
+ vos::OPipe maPipe;
+ vos::OStreamPipe maStreamPipe;
+ rtl::OUString maPipeIdent;
+ bool mbDowning;
+ bool mbRequestsEnabled;
+ int mnPendingRequests;
+ DispatchWatcher* mpDispatchWatcher;
+
+ /* condition to be set when the request has been processed */
+ ::osl::Condition cProcessed;
+
+ /* condition to be set when the main event loop is ready
+ otherwise an error dialogs event loop could eat away
+ requests from a 2nd office */
+ ::osl::Condition cReady;
+
+ static ::osl::Mutex& GetMutex();
+ static const char *sc_aTerminationSequence;
+ static const int sc_nTSeqLength;
+ static const char *sc_aShowSequence;
+ static const int sc_nShSeqLength;
+ static const char *sc_aConfirmationSequence;
+ static const int sc_nCSeqLength;
+
+ OfficeIPCThread();
+
+ protected:
+ /// Working method which should be overridden
+ virtual void SAL_CALL run();
+
+ public:
+ enum Status
+ {
+ IPC_STATUS_OK,
+ IPC_STATUS_2ND_OFFICE,
+ IPC_STATUS_BOOTSTRAP_ERROR
+ };
+
+ virtual ~OfficeIPCThread();
+
+ // controlling pipe communication during shutdown
+ static void SetDowning();
+ static void EnableRequests( bool i_bEnable = true );
+ static sal_Bool AreRequestsPending();
+ static void RequestsCompleted( int n = 1 );
+ static sal_Bool ExecuteCmdLineRequests( ProcessDocumentsRequest& );
+
+ // return FALSE if second office
+ static Status EnableOfficeIPCThread();
+ static void DisableOfficeIPCThread();
+ // start dispatching events...
+ static void SetReady(OfficeIPCThread* pThread = NULL);
+
+ bool AreRequestsEnabled() const { return mbRequestsEnabled && ! mbDowning; }
+};
+
+
+class OfficeIPCThreadController : public ::cppu::WeakImplHelper2<
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::frame::XTerminateListener >
+{
+ public:
+ OfficeIPCThreadController() {}
+ virtual ~OfficeIPCThreadController() {}
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw ( ::com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw ( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XTerminateListener
+ virtual void SAL_CALL queryTermination( const ::com::sun::star::lang::EventObject& aEvent )
+ throw( ::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL notifyTermination( const ::com::sun::star::lang::EventObject& aEvent )
+ throw( ::com::sun::star::uno::RuntimeException );
+};
+
+}
+
+#endif // _DESKTOP_OFFICEIPCTHREAD_HXX_
diff --git a/desktop/source/app/omutexmember.hxx b/desktop/source/app/omutexmember.hxx
new file mode 100644
index 000000000000..1edb90fec8c6
--- /dev/null
+++ b/desktop/source/app/omutexmember.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_OMUTEXMEMBER_HXX_
+#define __FRAMEWORK_OMUTEXMEMBER_HXX_
+
+//_________________________________________________________________________________________________________________
+// includes
+//_________________________________________________________________________________________________________________
+
+#include <osl/mutex.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// definitions
+//_________________________________________________________________________________________________________________
+
+/*-************************************************************************************************************//**
+ @short definition of a public mutex member
+ @descr You can use this struct as baseclass to get a public mutex member for right initialization.
+ Don't use it as member. You can't guarantee the right order of initialization of baseclasses then!
+ And some other helper classes share the mutex with an implementation and must have a valid one.
+
+ @seealso See implementation of constructors in derived classes for further informations!
+
+ @devstatus ready
+*//*-*************************************************************************************************************/
+
+struct OMutexMember
+{
+ ::osl::Mutex m_aMutex;
+};
+
+#endif // #ifndef __FRAMEWORK_OMUTEXMEMBER_HXX_
diff --git a/desktop/source/app/sofficemain.cxx b/desktop/source/app/sofficemain.cxx
new file mode 100644
index 000000000000..fc06850f237a
--- /dev/null
+++ b/desktop/source/app/sofficemain.cxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "app.hxx"
+
+#include <rtl/logfile.hxx>
+#include <tools/extendapplicationenvironment.hxx>
+
+BOOL SVMain();
+
+// -=-= main() -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+extern "C" int soffice_main()
+{
+ tools::extendApplicationEnvironment();
+
+ RTL_LOGFILE_PRODUCT_TRACE( "PERFORMANCE - enter Main()" );
+
+ desktop::Desktop aDesktop;
+ // This string is used during initialization of the Gtk+ VCL module
+ aDesktop.SetAppName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("soffice")) );
+ SVMain();
+
+ return 0;
+}
diff --git a/desktop/source/app/sofficemain.h b/desktop/source/app/sofficemain.h
new file mode 100644
index 000000000000..97775acd7016
--- /dev/null
+++ b/desktop/source/app/sofficemain.h
@@ -0,0 +1,43 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DESKTOP_SOURCE_APP_SOFFICEMAIN_H
+#define INCLUDED_DESKTOP_SOURCE_APP_SOFFICEMAIN_H
+
+#include "sal/config.h"
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+int soffice_main(void);
+
+#if defined __cplusplus
+}
+#endif
+
+#endif
diff --git a/desktop/source/app/userinstall.cxx b/desktop/source/app/userinstall.cxx
new file mode 100644
index 000000000000..546a6f0ad13c
--- /dev/null
+++ b/desktop/source/app/userinstall.cxx
@@ -0,0 +1,301 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+
+#include "userinstall.hxx"
+#include "langselect.hxx"
+
+#include <stdio.h>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/file.hxx>
+#include <osl/mutex.hxx>
+#include <osl/process.h>
+#include <osl/diagnose.h>
+#include <vos/security.hxx>
+#include <vos/ref.hxx>
+#include <vos/process.hxx>
+
+#ifndef _TOOLS_RESMGR_HXX_
+#include <tools/resmgr.hxx>
+#endif
+#include <unotools/bootstrap.hxx>
+#include <svl/languageoptions.hxx>
+#ifndef _SVTOOLS_SYSLOCALEOPTIONSOPTIONS_HXX
+#include <unotools/syslocaleoptions.hxx>
+#endif
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <i18npool/mslangid.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/beans/XHierarchicalPropertySet.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XLocalizable.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+
+#include "app.hxx"
+
+using namespace rtl;
+using namespace osl;
+using namespace utl;
+using namespace com::sun::star::container;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+
+
+namespace desktop {
+
+ static UserInstall::UserInstallError create_user_install(OUString&);
+
+ static bool is_user_install()
+ {
+ try
+ {
+ OUString sConfigSrvc(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationProvider" ) );
+ OUString sAccessSrvc(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationAccess" ) );
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > theMSF
+ = comphelper::getProcessServiceFactory();
+ Reference< XMultiServiceFactory > theConfigProvider
+ = Reference< XMultiServiceFactory >(
+ theMSF->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+
+ // localize the provider to user selection
+// Reference< XLocalizable > localizable(theConfigProvider, UNO_QUERY_THROW);
+// LanguageType aUserLanguageType = LanguageSelection::getLanguageType();
+// Locale aLocale( MsLangId::convertLanguageToIsoString(aUserLanguageType));
+// localizable->setLocale(aLocale);
+
+ Reference< XLocalizable > localizable(theConfigProvider, UNO_QUERY_THROW);
+ OUString aUserLanguage = LanguageSelection::getLanguageString();
+ Locale aLocale = LanguageSelection::IsoStringToLocale(aUserLanguage);
+ localizable->setLocale(aLocale);
+
+ Sequence< Any > theArgs(1);
+ NamedValue v;
+ v.Name = OUString::createFromAscii("NodePath");
+ v.Value = makeAny(OUString::createFromAscii("org.openoffice.Setup"));
+ theArgs[0] <<= v;
+ Reference< XHierarchicalNameAccess> hnacc(
+ theConfigProvider->createInstanceWithArguments(
+ sAccessSrvc, theArgs), UNO_QUERY_THROW);
+
+ try
+ {
+ sal_Bool bValue = sal_False;
+ hnacc->getByHierarchicalName(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Office/ooSetupInstCompleted" ) ) ) >>= bValue;
+
+ return bValue ? true : false;
+ }
+ catch ( NoSuchElementException const & )
+ {
+ // just return false in this case.
+ }
+ }
+ catch (Exception const & e)
+ {
+ OString msg(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US));
+ OSL_ENSURE(sal_False, msg.getStr());
+ }
+
+ return false;
+ }
+
+ UserInstall::UserInstallError UserInstall::finalize()
+ {
+ OUString aUserInstallPath;
+ utl::Bootstrap::PathStatus aLocateResult =
+ utl::Bootstrap::locateUserInstallation(aUserInstallPath);
+
+ switch (aLocateResult) {
+
+ case utl::Bootstrap::DATA_INVALID:
+ case utl::Bootstrap::DATA_MISSING:
+ case utl::Bootstrap::DATA_UNKNOWN:
+ // cannot find a valid path or path is missing
+ return E_Unknown;
+
+ case utl::Bootstrap::PATH_EXISTS:
+ {
+ // path exists, check if an installation lives there
+ if ( is_user_install() )
+ {
+ return E_None;
+ }
+ // Note: fall-thru intended.
+ }
+ case utl::Bootstrap::PATH_VALID:
+ // found a path but need to create user install
+ return create_user_install(aUserInstallPath);
+ default:
+ return E_Unknown;
+ }
+ }
+
+ static osl::FileBase::RC copy_recursive( const rtl::OUString& srcUnqPath, const rtl::OUString& dstUnqPath)
+ {
+
+ FileBase::RC err;
+ DirectoryItem aDirItem;
+ DirectoryItem::get(srcUnqPath, aDirItem);
+ FileStatus aFileStatus(FileStatusMask_All);
+ aDirItem.getFileStatus(aFileStatus);
+
+ if( aFileStatus.getFileType() == FileStatus::Directory)
+ {
+ // create directory if not already there
+ err = Directory::create( dstUnqPath );
+ if (err == osl::FileBase::E_EXIST)
+ err = osl::FileBase::E_None;
+
+ FileBase::RC next = err;
+ if (err == osl::FileBase::E_None)
+ {
+ // iterate through directory contents
+ Directory aDir( srcUnqPath );
+ aDir.open();
+ while (err == osl::FileBase::E_None &&
+ (next = aDir.getNextItem( aDirItem )) == osl::FileBase::E_None)
+ {
+ aDirItem.getFileStatus(aFileStatus);
+ // generate new src/dst pair and make recursive call
+ rtl::OUString newSrcUnqPath = aFileStatus.getFileURL();
+ rtl::OUString newDstUnqPath = dstUnqPath;
+ rtl::OUString itemname = aFileStatus.getFileName();
+ // append trailing '/' if needed
+ if (newDstUnqPath.lastIndexOf(sal_Unicode('/')) != newDstUnqPath.getLength()-1)
+ newDstUnqPath += rtl::OUString::createFromAscii("/");
+ newDstUnqPath += itemname;
+ // recursion
+ err = copy_recursive(newSrcUnqPath, newDstUnqPath);
+ }
+ aDir.close();
+
+ if ( err != osl::FileBase::E_None )
+ return err;
+ if( next != FileBase::E_NOENT )
+ err = FileBase::E_INVAL;
+ }
+ }
+ else
+ {
+ // copy single file - foldback
+ err = File::copy( srcUnqPath,dstUnqPath );
+ }
+ return err;
+ }
+
+ static const char *pszSrcList[] = {
+ "/presets",
+ NULL
+ };
+ static const char *pszDstList[] = {
+ "/user",
+ NULL
+ };
+
+
+ static UserInstall::UserInstallError create_user_install(OUString& aUserPath)
+ {
+ OUString aBasePath;
+ if (utl::Bootstrap::locateBaseInstallation(aBasePath) != utl::Bootstrap::PATH_EXISTS)
+ return UserInstall::E_InvalidBaseinstall;
+
+ // create the user directory
+ FileBase::RC rc = Directory::createPath(aUserPath);
+ if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST)) return UserInstall::E_Creation;
+
+ // copy data from shared data directory of base installation
+ for (sal_Int32 i=0; pszSrcList[i]!=NULL && pszDstList[i]!=NULL; i++)
+ {
+ rc = copy_recursive(
+ aBasePath + OUString::createFromAscii(pszSrcList[i]),
+ aUserPath + OUString::createFromAscii(pszDstList[i]));
+ if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST))
+ {
+ if ( rc == FileBase::E_NOSPC )
+ return UserInstall::E_NoDiskSpace;
+ else if ( rc == FileBase::E_ACCES )
+ return UserInstall::E_NoWriteAccess;
+ else
+ return UserInstall::E_Creation;
+ }
+ }
+ try
+ {
+ OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
+ OUString sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess");
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ theMSF->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+ Sequence< Any > theArgs(1);
+ NamedValue v(OUString::createFromAscii("NodePath"), makeAny(OUString::createFromAscii("org.openoffice.Setup")));
+ //v.Name = OUString::createFromAscii("NodePath");
+ //v.Value = makeAny(OUString::createFromAscii("org.openoffice.Setup"));
+ theArgs[0] <<= v;
+ Reference< XHierarchicalPropertySet> hpset(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW);
+ hpset->setHierarchicalPropertyValue(OUString::createFromAscii("Office/ooSetupInstCompleted"), makeAny(sal_True));
+ Reference< XChangesBatch >(hpset, UNO_QUERY_THROW)->commitChanges();
+ }
+ catch ( PropertyVetoException& )
+ {
+ // we are not allowed to change this
+ }
+ catch (Exception& e)
+ {
+ OString aMsg("create_user_install(): ");
+ aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, aMsg.getStr());
+ return UserInstall::E_Creation;
+ }
+
+ return UserInstall::E_None;
+
+ }
+}
+
+
diff --git a/desktop/source/app/userinstall.hxx b/desktop/source/app/userinstall.hxx
new file mode 100644
index 000000000000..8d6a51cd66be
--- /dev/null
+++ b/desktop/source/app/userinstall.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+
+namespace desktop
+{
+
+class UserInstall
+{
+public:
+ enum UserInstallError {
+ E_None, // no error
+ E_Creation, // error while creating user install
+ E_InvalidBaseinstall, // corrupt base installation
+ E_SetupFailed, // external setup did not run correctly
+ E_Configuration, // error while accessing configuration
+ E_License, // License not accepted
+ E_NoDiskSpace, // not enough disk space
+ E_NoWriteAccess, // no write access
+ E_Unknown // unknown error
+ };
+
+ static UserInstallError finalize();
+};
+}
diff --git a/desktop/source/app/version.map b/desktop/source/app/version.map
new file mode 100644
index 000000000000..0ffffcd58635
--- /dev/null
+++ b/desktop/source/app/version.map
@@ -0,0 +1,34 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+UDK_3_0_0 {
+ global:
+ soffice_main;
+
+ local:
+ *;
+};