diff options
27 files changed, 3093 insertions, 1738 deletions
diff --git a/desktop/inc/app.hxx b/desktop/inc/app.hxx index df875df23ad6..995c7e65e999 100644 --- a/desktop/inc/app.hxx +++ b/desktop/inc/app.hxx @@ -134,6 +134,7 @@ class Desktop : public Application static rtl::OUString GetLicensePath(); static sal_Bool LicenseNeedsAcceptance(); static sal_Bool IsFirstStartWizardNeeded(); + static sal_Bool CheckExtensionDependencies(); private: // Bootstrap methods diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx index 8675d22e0aae..68577b3c1f1e 100644 --- a/desktop/source/app/app.cxx +++ b/desktop/source/app/app.cxx @@ -1387,6 +1387,10 @@ void Desktop::Main() tools::InitTestToolLib(); RTL_LOGFILE_CONTEXT_TRACE( aLog, "} tools::InitTestToolLib" ); + bool bAbort = CheckExtensionDependencies(); + if ( bAbort ) + return; + // First Start Wizard allowed ? if ( ! pCmdLineArgs->IsNoFirstStartWizard()) { diff --git a/desktop/source/app/check_ext_deps.cxx b/desktop/source/app/check_ext_deps.cxx new file mode 100644 index 000000000000..a66031184200 --- /dev/null +++ b/desktop/source/app/check_ext_deps.cxx @@ -0,0 +1,256 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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 <rtl/bootstrap.hxx> +#include <rtl/ustring.hxx> +#include <unotools/configmgr.hxx> + +#include <comphelper/processfactory.hxx> +#include <comphelper/sequence.hxx> +#include <cppuhelper/bootstrap.hxx> + +#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/XPackageManager.hpp" +#include "com/sun/star/deployment/thePackageManagerFactory.hpp" +#include <com/sun/star/task/XJob.hpp> +#include <com/sun/star/task/XJobExecutor.hpp> +#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> +#include <com/sun/star/util/XChangesBatch.hpp> + +#include "app.hxx" + +using rtl::OUString; +using namespace desktop; +using namespace com::sun::star; + +#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) + +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< deployment::XPackageManager > &xPackageManager ) +{ + uno::Sequence< uno::Reference< deployment::XPackage > > packages; + + try { + packages = xPackageManager->getDeployedPackages( uno::Reference< task::XAbortChannel >(), + uno::Reference< ucb::XCommandEnvironment >() ); + } + catch ( deployment::DeploymentException & ) { /* handleGeneralError(e.Cause);*/ } + catch ( ucb::CommandFailedException & ) { /* handleGeneralError(e.Reason);*/ } + catch ( ucb::CommandAbortedException & ) {} + catch ( lang::IllegalArgumentException & e ) { + throw uno::RuntimeException( e.Message, e.Context ); + } + + for ( sal_Int32 i = 0; i < packages.getLength(); ++i ) + { + bool bRegistered = false; + try { + beans::Optional< beans::Ambiguous< sal_Bool > > option( packages[i]->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() ); + bRegistered = false; + } + + if ( bRegistered ) + { + bool bDependenciesValid = false; + try { + bDependenciesValid = packages[i]->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(); + uno::Reference< deployment::XPackageManager > xManager; + bool bDependenciesValid = true; + + try { + xManager = deployment::thePackageManagerFactory::get( xContext )->getPackageManager( UNISTRING("user") ); + } + catch ( ucb::CommandFailedException & ){} + catch ( uno::RuntimeException & ) {} + + if ( xManager.is() ) + bDependenciesValid = impl_checkDependencies( xManager ); + + if ( bDependenciesValid ) + { + try { + xManager = deployment::thePackageManagerFactory::get( xContext )->getPackageManager( UNISTRING("shared") ); + } + catch ( ucb::CommandFailedException & ){} + catch ( uno::RuntimeException & ) {} + + if ( xManager.is() ) + bDependenciesValid = impl_checkDependencies( xManager ); + } + + 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(); + } + } + 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; +} + diff --git a/desktop/source/app/makefile.mk b/desktop/source/app/makefile.mk index 18c2170d3f53..36993bfdf355 100644 --- a/desktop/source/app/makefile.mk +++ b/desktop/source/app/makefile.mk @@ -56,6 +56,7 @@ SHL1OBJS = \ $(SLO)$/appsys.obj \ $(SLO)$/cfgfilter.obj \ $(SLO)$/checkinstall.obj \ + $(SLO)$/check_ext_deps.obj \ $(SLO)$/cmdlineargs.obj \ $(SLO)$/cmdlinehelp.obj \ $(SLO)$/configinit.obj \ diff --git a/desktop/source/deployment/gui/dp_gui.h b/desktop/source/deployment/gui/dp_gui.h index 65fc7635a6ec..7f2cb7a9626a 100644 --- a/desktop/source/deployment/gui/dp_gui.h +++ b/desktop/source/deployment/gui/dp_gui.h @@ -82,6 +82,7 @@ enum PackageState { REGISTERED, NOT_REGISTERED, AMBIGUOUS, NOT_AVAILABLE }; class SelectedPackage: public salhelper::SimpleReferenceObject { public: + SelectedPackage() {} SelectedPackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> &xPackage, const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager> &xPackageManager ) : m_xPackage( xPackage ), diff --git a/desktop/source/deployment/gui/dp_gui.hrc b/desktop/source/deployment/gui/dp_gui.hrc index 412e6a067159..387072c98618 100644 --- a/desktop/source/deployment/gui/dp_gui.hrc +++ b/desktop/source/deployment/gui/dp_gui.hrc @@ -32,7 +32,8 @@ #include "helpid.hrc" // Package Manager Dialog: -#define RID_DLG_PACKAGE_MANAGER RID_DEPLOYMENT_GUI_START +#define RID_DLG_EXTENSION_MANAGER RID_DEPLOYMENT_GUI_START +#define RID_DLG_UPDATE_REQUIRED (RID_DEPLOYMENT_GUI_START + 11) #define RID_EM_BTN_CLOSE 10 #define RID_EM_BTN_HELP 11 @@ -42,27 +43,9 @@ #define RID_EM_BTN_CANCEL 15 #define RID_EM_FT_GET_EXTENSIONS 20 #define RID_EM_FT_PROGRESS 21 +#define RID_EM_FT_MSG 22 // local RIDs: -#define RID_FT_PACKAGES 5 - -#define RID_BTN_CLOSE 10 -#define RID_BTN_HELP 11 - -#define RID_BTN_ADD 20 -#define RID_BTN_REMOVE 21 -#define RID_BTN_ENABLE 22 -#define RID_BTN_DISABLE 23 -#define RID_BTN_EXPORT 24 -#define RID_BTN_CHECK_UPDATES 25 -#define RID_BTN_OPTIONS 26 -#define RID_BTN_GET_EXTENSIONS 27 - -#define RID_IMG_PLUS 41 -#define RID_IMG_PLUS_HC 42 -#define RID_IMG_MINUS 43 -#define RID_IMG_MINUS_HC 44 - #define PB_LICENSE_DOWN 50 #define ML_LICENSE 51 #define BTN_LICENSE_DECLINE 53 @@ -145,18 +128,10 @@ #define RID_DLG_UPDATE_NOUPDATE 30 #define RID_DLG_UPDATE_VERSION 31 -#define RID_DLG_EXTENSION_MANAGER (RID_DEPLOYMENT_GUI_START + 6) - #define RID_DLG_UPDATEINSTALL (RID_DEPLOYMENT_GUI_START + 20) #define RID_INFOBOX_UPDATE_SHARED_EXTENSION (RID_DEPLOYMENT_GUI_START + 21) -#define RID_IMG_DEF_INSTALLATION (RID_DEPLOYMENT_GUI_START+50) -#define RID_IMG_DEF_INSTALLATION_HC (RID_DEPLOYMENT_GUI_START+51) -#define RID_IMG_DEF_DOCUMENT (RID_DEPLOYMENT_GUI_START+52) -#define RID_IMG_DEF_DOCUMENT_HC (RID_DEPLOYMENT_GUI_START+53) -#define RID_IMG_DEF_PACKAGE (RID_DEPLOYMENT_GUI_START+54) -#define RID_IMG_DEF_PACKAGE_HC (RID_DEPLOYMENT_GUI_START+55) #define RID_IMG_WARNING (RID_DEPLOYMENT_GUI_START+56) #define RID_IMG_WARNING_HC (RID_DEPLOYMENT_GUI_START+57) #define RID_IMG_LOCKED (RID_DEPLOYMENT_GUI_START+58) @@ -164,39 +139,26 @@ #define RID_IMG_EXTENSION (RID_DEPLOYMENT_GUI_START+60) #define RID_IMG_EXTENSION_HC (RID_DEPLOYMENT_GUI_START+61) - -#define RID_STR_USER_INSTALLATION (RID_DEPLOYMENT_GUI_START+60) -#define RID_STR_SHARED_INSTALLATION (RID_DEPLOYMENT_GUI_START+61) -#define RID_STR_ENABLED (RID_DEPLOYMENT_GUI_START+62) -#define RID_STR_DISABLED (RID_DEPLOYMENT_GUI_START+63) -#define RID_STR_UNKNOWN (RID_DEPLOYMENT_GUI_START+64) -#define RID_STR_PACKAGE (RID_DEPLOYMENT_GUI_START+65) -#define RID_STR_PACKAGE_STATUS (RID_DEPLOYMENT_GUI_START+66) -#define RID_STR_EXTENSION_VERSION (RID_DEPLOYMENT_GUI_START+67) - - #define RID_STR_ADD_PACKAGES (RID_DEPLOYMENT_GUI_START+70) -#define RID_STR_EXPORT_PACKAGE (RID_DEPLOYMENT_GUI_START+71) -#define RID_STR_EXPORT_PACKAGES (RID_DEPLOYMENT_GUI_START+72) - -#define RID_CTX_ITEM_ADD (RID_DEPLOYMENT_GUI_START+80) -#define RID_CTX_ITEM_REMOVE (RID_DEPLOYMENT_GUI_START+81) -#define RID_CTX_ITEM_ENABLE (RID_DEPLOYMENT_GUI_START+82) -#define RID_CTX_ITEM_DISABLE (RID_DEPLOYMENT_GUI_START+83) -#define RID_CTX_ITEM_EXPORT (RID_DEPLOYMENT_GUI_START+84) -#define RID_CTX_ITEM_CHECK_UPDATE (RID_DEPLOYMENT_GUI_START+85) -#define RID_CTX_ITEM_OPTIONS (RID_DEPLOYMENT_GUI_START+86) - -#define RID_STR_ADDING_PACKAGES (RID_DEPLOYMENT_GUI_START+90) -#define RID_STR_REMOVING_PACKAGES (RID_DEPLOYMENT_GUI_START+91) -#define RID_STR_ENABLING_PACKAGES (RID_DEPLOYMENT_GUI_START+92) -#define RID_STR_DISABLING_PACKAGES (RID_DEPLOYMENT_GUI_START+93) -#define RID_STR_EXPORTING_PACKAGES (RID_DEPLOYMENT_GUI_START+94) - -#define RID_STR_INSTALL_FOR_ALL (RID_DEPLOYMENT_GUI_START+95) -#define RID_STR_INSTALL_FOR_ME (RID_DEPLOYMENT_GUI_START+96) -#define RID_STR_PUBLISHER_LINK (RID_DEPLOYMENT_GUI_START+97) -#define RID_STR_ERROR_UNKNOWN_STATUS (RID_DEPLOYMENT_GUI_START+98) + +#define RID_CTX_ITEM_REMOVE (RID_DEPLOYMENT_GUI_START+80) +#define RID_CTX_ITEM_ENABLE (RID_DEPLOYMENT_GUI_START+81) +#define RID_CTX_ITEM_DISABLE (RID_DEPLOYMENT_GUI_START+82) +#define RID_CTX_ITEM_CHECK_UPDATE (RID_DEPLOYMENT_GUI_START+83) +#define RID_CTX_ITEM_OPTIONS (RID_DEPLOYMENT_GUI_START+84) + +#define RID_STR_ADDING_PACKAGES (RID_DEPLOYMENT_GUI_START+85) +#define RID_STR_REMOVING_PACKAGES (RID_DEPLOYMENT_GUI_START+86) +#define RID_STR_ENABLING_PACKAGES (RID_DEPLOYMENT_GUI_START+87) +#define RID_STR_DISABLING_PACKAGES (RID_DEPLOYMENT_GUI_START+88) + +#define RID_STR_INSTALL_FOR_ALL (RID_DEPLOYMENT_GUI_START+90) +#define RID_STR_INSTALL_FOR_ME (RID_DEPLOYMENT_GUI_START+91) +#define RID_STR_ERROR_UNKNOWN_STATUS (RID_DEPLOYMENT_GUI_START+92) +#define RID_STR_CLOSE_BTN (RID_DEPLOYMENT_GUI_START+93) +#define RID_STR_EXIT_BTN (RID_DEPLOYMENT_GUI_START+94) +#define RID_STR_NO_ADMIN_PRIVILEGE (RID_DEPLOYMENT_GUI_START+95) +#define RID_STR_ERROR_MISSING_DEPENDENCIES (RID_DEPLOYMENT_GUI_START+96) #define WARNINGBOX_CONCURRENTINSTANCE (RID_DEPLOYMENT_GUI_START+100) diff --git a/desktop/source/deployment/gui/dp_gui_dialog.src b/desktop/source/deployment/gui/dp_gui_dialog.src index d3730a12536e..e7c785c86973 100644 --- a/desktop/source/deployment/gui/dp_gui_dialog.src +++ b/desktop/source/deployment/gui/dp_gui_dialog.src @@ -30,192 +30,10 @@ #include "svtools/controldims.hrc" #include "dp_gui.hrc" -ModelessDialog RID_DLG_PACKAGE_MANAGER -{ - HelpId = HID_PACKAGE_MANAGER; - Text [ en-US ] = "Extension Manager"; - - Size = MAP_APPFONT( 300, 200 ); - OutputSize = TRUE; - SVLook = TRUE; - Moveable = TRUE; - Closeable = TRUE; - Sizeable = TRUE; - Hide = TRUE; - - FixedText RID_FT_PACKAGES - { - Group = TRUE; - Left = TRUE; - NoLabel = TRUE; - Text [ en-US ] = "Browse extensions"; - }; - - PushButton RID_BTN_ADD - { - TabStop = TRUE; - Text [ en-US ] = "~Add..."; - }; - PushButton RID_BTN_REMOVE - { - TabStop = TRUE; - Text [ en-US ] = "~Remove"; - }; - PushButton RID_BTN_ENABLE - { - TabStop = TRUE; - Text [ en-US ] = "~Enable"; - }; - PushButton RID_BTN_DISABLE - { - TabStop = TRUE; - Text [ en-US ] = "~Disable"; - }; - PushButton RID_BTN_EXPORT - { - TabStop = TRUE; - Text [ en-US ] = "E~xport..."; - }; - PushButton RID_BTN_CHECK_UPDATES - { - Disable = TRUE; - TabStop = TRUE; - Text [ en-US ] = "~Updates..."; - }; - PushButton RID_BTN_OPTIONS - { - Disable = TRUE; - TabStop = TRUE; - Text [ en-US ] = "~Options..."; - }; - - - - FixedText RID_BTN_GET_EXTENSIONS - { - NoLabel = TRUE; - TabStop = TRUE; - Text [ en-US ] = "Get more extensions here..."; - }; - - OKButton RID_BTN_CLOSE - { - TabStop = TRUE; - DefButton = TRUE; - Text [ en-US ] = "Close"; - }; - HelpButton RID_BTN_HELP - { - TabStop = TRUE; - }; - - Image RID_IMG_PLUS - { - ImageBitmap = Bitmap { File = "plus.bmp"; }; - MASKCOLOR - }; - - Image RID_IMG_PLUS_HC - { - ImageBitmap = Bitmap { File = "plus_sch.bmp"; }; - MASKCOLOR - }; - Image RID_IMG_MINUS - { - ImageBitmap = Bitmap { File = "minus.bmp"; }; - MASKCOLOR - }; - Image RID_IMG_MINUS_HC - { - ImageBitmap = Bitmap { File = "minus_sch.bmp"; }; - MASKCOLOR - }; -}; - - -Image RID_IMG_DEF_INSTALLATION -{ - ImageBitmap = Bitmap { File = "harddisk_16.bmp"; }; - MASKCOLOR -}; -Image RID_IMG_DEF_INSTALLATION_HC -{ - ImageBitmap = Bitmap { File = "harddisk_16_h.bmp"; }; - MASKCOLOR -}; - -Image RID_IMG_DEF_DOCUMENT -{ - ImageBitmap = Bitmap { File = "sc05500.bmp"; }; - MASKCOLOR -}; -Image RID_IMG_DEF_DOCUMENT_HC -{ - ImageBitmap = Bitmap { File = "sch05500.bmp"; }; - MASKCOLOR -}; - -Image RID_IMG_DEF_PACKAGE -{ - ImageBitmap = Bitmap { File = "puzzleslice_16.bmp"; }; - MASKCOLOR -}; -Image RID_IMG_DEF_PACKAGE_HC -{ - ImageBitmap = Bitmap { File = "puzzleslice_16_h.bmp"; }; - MASKCOLOR -}; - - -String RID_STR_USER_INSTALLATION -{ - Text [ en-US ] = "My Extensions"; -}; - -String RID_STR_SHARED_INSTALLATION -{ - Text [ en-US ] = "%PRODUCTNAME Extensions"; -}; - -String RID_STR_PACKAGE -{ - Text [ en-US ] = "Extension"; -}; - -String RID_STR_PACKAGE_STATUS -{ - Text [ en-US ] = "Status"; -}; - -String RID_STR_EXTENSION_VERSION -{ - Text [ en-US ] = "Version"; -}; - String RID_STR_ADD_PACKAGES { Text [ en-US ] = "Add Extension(s)"; }; - -String RID_STR_ENABLED -{ - Text [ en-US ] = "Enabled"; -}; - -String RID_STR_DISABLED -{ - Text [ en-US ] = "Disabled"; -}; - -String RID_STR_UNKNOWN -{ - Text [ en-US ] = "Unknown"; -}; - -String RID_CTX_ITEM_ADD -{ - Text [ en-US ] = "~Add..."; -}; String RID_CTX_ITEM_REMOVE { Text [ en-US ] = "~Remove"; @@ -228,30 +46,15 @@ String RID_CTX_ITEM_DISABLE { Text [ en-US ] = "~Disable"; }; -String RID_CTX_ITEM_EXPORT -{ - Text [ en-US ] = "E~xport..."; -}; String RID_CTX_ITEM_CHECK_UPDATE { Text [ en-US ] = "~Update..."; }; - String RID_CTX_ITEM_OPTIONS { Text [ en-US ] = "~Options..."; }; -String RID_STR_EXPORT_PACKAGE -{ - Text [ en-US ] = "Export Extension"; -}; - -String RID_STR_EXPORT_PACKAGES -{ - Text [ en-US ] = "Export Extensions to..."; -}; - String RID_STR_ADDING_PACKAGES { Text [ en-US ] = "Adding %EXTENSION_NAME"; @@ -272,11 +75,6 @@ String RID_STR_DISABLING_PACKAGES Text [ en-US ] = "Disabling %EXTENSION_NAME"; }; -String RID_STR_EXPORTING_PACKAGES -{ - Text [ en-US ] = "Exporting Extension(s)"; -}; - String RID_STR_INSTALL_FOR_ALL { Text [ en-US ] = "~For all users"; @@ -287,14 +85,31 @@ String RID_STR_INSTALL_FOR_ME Text [ en-US ] = "~Only for me"; }; -String RID_STR_PUBLISHER_LINK +String RID_STR_ERROR_UNKNOWN_STATUS { - Text [ en-US ] = "Publisher"; + Text [ en-US ] = "Error: The status of this extension is unknown"; }; -String RID_STR_ERROR_UNKNOWN_STATUS +String RID_STR_CLOSE_BTN { - Text [ en-US ] = "Error: The status of this extension is unknown"; + Text [ en-US ] = "Close"; +}; + +String RID_STR_EXIT_BTN +{ + Text [ en-US ] = "Quit"; +}; + +String RID_STR_NO_ADMIN_PRIVILEGE +{ + Text [ en-US ] = "%PRODUCTNAME has been updated to a new version. " + "Some shared %PRODUCTNAME extensions are not compatible with this version and need to be updated before %PRODUCTNAME can be started.\n\n" + "Updating of shared extension requires administrator privileges. Contact your system administrator to update the following shared extensions:"; +}; + +String RID_STR_ERROR_MISSING_DEPENDENCIES +{ + Text [ en-US ] = "The extension cannot be enabled as the following system dependencies are not fulfilled:"; }; // Dialog layout diff --git a/desktop/source/deployment/gui/dp_gui_dialog2.cxx b/desktop/source/deployment/gui/dp_gui_dialog2.cxx index 47bcd507cd90..f09d906a840e 100644 --- a/desktop/source/deployment/gui/dp_gui_dialog2.cxx +++ b/desktop/source/deployment/gui/dp_gui_dialog2.cxx @@ -36,7 +36,9 @@ #include "svtools/controldims.hrc" #include "svtools/svtools.hrc" +#include "dp_gui.h" #include "dp_gui_dialog2.hxx" +#include "dp_gui_extlistbox.hxx" #include "dp_gui_shared.hxx" #include "dp_gui_theextmgr.hxx" #include "dp_misc.h" @@ -55,7 +57,7 @@ #include "comphelper/anytostring.hxx" #include "cppuhelper/exc_hlp.hxx" -#include "cppuhelper/implbase1.hxx" +#include "cppuhelper/bootstrap.hxx" #include "comphelper/processfactory.hxx" #include "ucbhelper/content.hxx" @@ -76,6 +78,8 @@ #include "com/sun/star/uno/Any.hxx" #include "com/sun/star/uno/XComponentContext.hpp" +#include "com/sun/star/deployment/thePackageManagerFactory.hpp" + #include <map> #include <vector> #include <boost/shared_ptr.hpp> @@ -91,11 +95,7 @@ using ::rtl::OUString; namespace dp_gui { #define ICON_OFFSET 50 -#define ICON_HEIGHT 42 -#define SMALL_ICON_SIZE 16 -#define RIGHT_ICON_OFFSET 5 #define TOP_OFFSET 3 -#define SPACE_BETWEEN 3 #define LINE_SIZE 4 #define PROGRESS_WIDTH 60 #define PROGRESS_HEIGHT 14 @@ -113,112 +113,18 @@ struct StrAllFiles : public rtl::StaticWithInit< const OUString, StrAllFiles > }; //------------------------------------------------------------------------------ -// struct Entry_Impl -//------------------------------------------------------------------------------ -struct Entry_Impl; - -typedef ::boost::shared_ptr< Entry_Impl > TEntry_Impl; - -struct Entry_Impl -{ - bool m_bActive; - bool m_bLocked; - bool m_bHasOptions; - bool m_bShared; - bool m_bNew; - bool m_bChecked; - PackageState m_eState; - String m_sTitle; - String m_sVersion; - String m_sDescription; - String m_sPublisher; - String m_sPublisherURL; - String m_sErrorText; - Image m_aIcon; - Image m_aIconHC; - svt::FixedHyperlink *m_pPublisher; - - uno::Reference< deployment::XPackage> m_xPackage; - uno::Reference< deployment::XPackageManager> m_xPackageManager; - - Entry_Impl( const uno::Reference< deployment::XPackage > &xPackage, - const uno::Reference< deployment::XPackageManager > &xPackageManager, - PackageState eState ); - ~Entry_Impl(); - - StringCompare CompareTo( const CollatorWrapper *pCollator, const TEntry_Impl pEntry ) const; -}; - -//------------------------------------------------------------------------------ -Entry_Impl::Entry_Impl( const uno::Reference< deployment::XPackage > &xPackage, - const uno::Reference< deployment::XPackageManager > &xPackageManager, - PackageState eState ) : - m_bActive( false ), - m_bLocked( false ), - m_bHasOptions( false ), - m_bShared( false ), - m_bNew( false ), - m_bChecked( false ), - m_eState( eState ), - m_pPublisher( NULL ), +UpdateListEntry::UpdateListEntry( const uno::Reference< deployment::XPackage > &xPackage, + const uno::Reference< deployment::XPackageManager > &xPackageManager ) : m_xPackage( xPackage ), m_xPackageManager( xPackageManager ) -{ - m_sTitle = xPackage->getDisplayName(); - m_sVersion = xPackage->getVersion(); - m_sDescription = xPackage->getDescription(); - - beans::StringPair aInfo( m_xPackage->getPublisherInfo() ); - m_sPublisher = aInfo.First; - m_sPublisherURL = aInfo.Second; - - // get the icons for the package if there are any - uno::Reference< graphic::XGraphic > xGraphic = xPackage->getIcon( false ); - if ( xGraphic.is() ) - m_aIcon = Image( xGraphic ); - - xGraphic = xPackage->getIcon( true ); - if ( xGraphic.is() ) - m_aIconHC = Image( xGraphic ); - else - m_aIconHC = m_aIcon; - - m_bLocked = m_xPackageManager->isReadOnly(); - - if ( eState == AMBIGUOUS ) - m_sErrorText = ExtMgrDialog::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS ); -} - -//------------------------------------------------------------------------------ -Entry_Impl::~Entry_Impl() -{ - delete m_pPublisher; -} +{} //------------------------------------------------------------------------------ -StringCompare Entry_Impl::CompareTo( const CollatorWrapper *pCollator, const TEntry_Impl pEntry ) const -{ - StringCompare eCompare = (StringCompare) pCollator->compareString( m_sTitle, pEntry->m_sTitle ); - if ( eCompare == COMPARE_EQUAL ) - { - eCompare = m_sVersion.CompareTo( pEntry->m_sVersion ); - if ( eCompare == COMPARE_EQUAL ) - { - if ( m_xPackageManager != pEntry->m_xPackageManager ) - { - sal_Int32 nCompare = m_xPackageManager->getContext().compareTo( pEntry->m_xPackageManager->getContext() ); - if ( nCompare < 0 ) - eCompare = COMPARE_LESS; - else if ( nCompare > 0 ) - eCompare = COMPARE_GREATER; - } - } - } - return eCompare; -} +UpdateListEntry::~UpdateListEntry() +{} //------------------------------------------------------------------------------ -// ExtensionBox_Impl +// ExtBoxWithBtns_Impl //------------------------------------------------------------------------------ enum MENU_COMMAND @@ -230,63 +136,21 @@ enum MENU_COMMAND CMD_UPDATE }; -class ExtensionBox_Impl : public ::svt::IExtensionListBox, - public ::cppu::WeakImplHelper1< ::com::sun::star::lang::XEventListener > +class ExtBoxWithBtns_Impl : public ExtensionBox_Impl { - bool m_bHasScrollBar; - bool m_bHasActive; - bool m_bNeedsRecalc; - bool m_bHasNew; - bool m_bInCheckMode; - bool m_bInterfaceLocked; - //Must be guarded together with m_vEntries to ensure a valid index at all times. - //Use m_entriesMutex as guard. - long m_nActive; - long m_nTopIndex; - long m_nStdHeight; - long m_nActiveHeight; - long m_nBtnHeight; Size m_aOutputSize; - Image m_aLockedImage; - Image m_aLockedImageHC; - Image m_aWarningImage; - Image m_aWarningImageHC; - Image m_aDefaultImage; - Image m_aDefaultImageHC; + bool m_bInterfaceLocked; PushButton *m_pOptionsBtn; PushButton *m_pEnableBtn; PushButton *m_pRemoveBtn; - ScrollBar *m_pScrollBar; - - ExtMgrDialog *m_pParent; - TheExtensionManager *m_pManager; - //This mutex is used for synchronizing access to m_vEntries. - //Currently it is used to synchronize adding, removing entries and - //functions like getItemName, getItemDescription, etc. to prevent - //that m_vEntries is accessed at an invalid index. - //ToDo: There are many more places where m_vEntries is read and which may - //fail. For example the Paint method is probable called from the main thread - //while new entries are added / removed in a separate thread. - mutable ::osl::Mutex m_entriesMutex; - std::vector< TEntry_Impl > m_vEntries; - - lang::Locale *m_pLocale; - CollatorWrapper *m_pCollator; - - void CalcActiveHeight( const long nPos ); - long GetTotalHeight() const; - Rectangle GetEntryRect( const long nPos ) const; + + ExtMgrDialog *m_pParent; + void SetButtonPos( const Rectangle& rRect ); void SetButtonStatus( const TEntry_Impl pEntry ); - void SetupScrollBar(); - void DrawRow( const Rectangle& rRect, const TEntry_Impl pEntry ); bool HandleTabKey( bool bReverse ); - bool HandleCursorKey( USHORT nKeyCode ); MENU_COMMAND ShowPopupMenu( const Point &rPos, const long nPos ); - void RecalcAll(); - bool FindEntryPos( const TEntry_Impl pEntry, long nStart, long nEnd, long &nFound ); - bool isHCMode(); //----------------- DECL_DLLPRIVATE_LINK( ScrollHdl, ScrollBar * ); @@ -296,115 +160,29 @@ class ExtensionBox_Impl : public ::svt::IExtensionListBox, DECL_DLLPRIVATE_LINK( HandleRemoveBtn, void * ); DECL_DLLPRIVATE_LINK( HandleHyperlink, svt::FixedHyperlink * ); - //Index starts with 1. - //Throws an com::sun::star::lang::IllegalArgumentException, when the index is invalid. - void checkIndex(sal_Int32 pos) const; - - public: - ExtensionBox_Impl( ExtMgrDialog* pParent, TheExtensionManager *pManager ); - ~ExtensionBox_Impl(); + ExtBoxWithBtns_Impl( ExtMgrDialog* pParent, TheExtensionManager *pManager ); + ~ExtBoxWithBtns_Impl(); virtual void MouseButtonDown( const MouseEvent& rMEvt ); - virtual void Paint( const Rectangle &rPaintRect ); - virtual void Resize(); virtual long Notify( NotifyEvent& rNEvt ); const Size GetMinOutputSizePixel() const; + virtual void RecalcAll(); + virtual void selectEntry( const long nPos ); //----------------- - long addEntry( const uno::Reference< deployment::XPackage > &xPackage, - const uno::Reference< deployment::XPackageManager > &xPackageManager ); - void selectEntry( const long nPos ); void enableButtons( bool bEnable ); - - void updateEntry( const uno::Reference< deployment::XPackage > &xPackage ); - - void prepareChecking( const uno::Reference< deployment::XPackageManager > &xPackageMgr ); - void checkEntries(); - - TheExtensionManager* getExtensionManager() const { return m_pManager; } - - //=================================================================================== - //These functions are used for automatic testing - - /** @return The count of the entries in the list box. */ - virtual sal_Int32 getItemCount() const; - - /** @return The index of the first selected entry in the list box. - When nothing is selected, which is the case when getItemCount returns '0', - then this function returns EXTENSION_LISTBOX_ENTRY_NOTFOUND */ - virtual sal_Int32 getSelIndex() const; - - /** @return The item name of the entry with the given index - The index starts with 0. - Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ - virtual OUString getItemName( sal_Int32 index ) const; - - /** @return The version string of the entry with the given index - The index starts with 0. - Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ - virtual OUString getItemVersion( sal_Int32 index ) const; - - /** @return The description string of the entry with the given index - The index starts with 0. - Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ - virtual OUString getItemDescription( sal_Int32 index ) const; - - /** @return The publisher string of the entry with the given index - The index starts with 0. - Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ - virtual ::rtl::OUString getItemPublisher( sal_Int32 index ) const; - - /** @return The link behind the publisher text of the entry with the given index - The index starts with 0. - Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ - virtual ::rtl::OUString getItemPublisherLink( sal_Int32 index ) const; - - /** The entry at the given position will be selected - Index starts with 0. - Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ - virtual void select( sal_Int32 pos ); - - /** The first found entry with the given name will be selected - When there was no entry found with the name, the selection doesn't change. - Please note that there might be more than one entry with the same - name, because: - 1. the name is not unique - 2. one extension can be installed as user and shared extension. - */ - virtual void select( const OUString & sName ); - - //=================================================================================== - // XEventListener - virtual void SAL_CALL disposing( ::com::sun::star::lang::EventObject const & evt ) - throw (::com::sun::star::uno::RuntimeException); }; //------------------------------------------------------------------------------ -ExtensionBox_Impl::ExtensionBox_Impl( ExtMgrDialog* pParent, TheExtensionManager *pManager ) : - IExtensionListBox( pParent, WB_BORDER | WB_TABSTOP | WB_CHILDDLGCTRL ), - m_bHasScrollBar( false ), - m_bHasActive( false ), - m_bNeedsRecalc( true ), - m_bHasNew( false ), - m_bInCheckMode( false ), +ExtBoxWithBtns_Impl::ExtBoxWithBtns_Impl( ExtMgrDialog* pParent, TheExtensionManager *pManager ) : + ExtensionBox_Impl( pParent, pManager ), m_bInterfaceLocked( false ), - m_nActive( 0 ), - m_nTopIndex( 0 ), - m_nActiveHeight( 0 ), - m_aLockedImage( ExtMgrDialog::getResId( RID_IMG_LOCKED ) ), - m_aLockedImageHC( ExtMgrDialog::getResId( RID_IMG_LOCKED_HC ) ), - m_aWarningImage( ExtMgrDialog::getResId( RID_IMG_WARNING ) ), - m_aWarningImageHC( ExtMgrDialog::getResId( RID_IMG_WARNING_HC ) ), - m_aDefaultImage( ExtMgrDialog::getResId( RID_IMG_EXTENSION ) ), - m_aDefaultImageHC( ExtMgrDialog::getResId( RID_IMG_EXTENSION_HC ) ), m_pOptionsBtn( NULL ), m_pEnableBtn( NULL ), m_pRemoveBtn( NULL ), - m_pScrollBar( NULL ), - m_pParent( pParent ), - m_pManager( pManager ) + m_pParent( pParent ) { m_pOptionsBtn = new PushButton( this, WB_TABSTOP ); m_pEnableBtn = new PushButton( this, WB_TABSTOP ); @@ -415,17 +193,13 @@ ExtensionBox_Impl::ExtensionBox_Impl( ExtMgrDialog* pParent, TheExtensionManager m_pEnableBtn->SetHelpId( HID_EXTENSION_MANAGER_LISTBOX_DISABLE ); m_pRemoveBtn->SetHelpId( HID_EXTENSION_MANAGER_LISTBOX_REMOVE ); - m_pOptionsBtn->SetClickHdl( LINK( this, ExtensionBox_Impl, HandleOptionsBtn ) ); - m_pEnableBtn->SetClickHdl( LINK( this, ExtensionBox_Impl, HandleEnableBtn ) ); - m_pRemoveBtn->SetClickHdl( LINK( this, ExtensionBox_Impl, HandleRemoveBtn ) ); + m_pOptionsBtn->SetClickHdl( LINK( this, ExtBoxWithBtns_Impl, HandleOptionsBtn ) ); + m_pEnableBtn->SetClickHdl( LINK( this, ExtBoxWithBtns_Impl, HandleEnableBtn ) ); + m_pRemoveBtn->SetClickHdl( LINK( this, ExtBoxWithBtns_Impl, HandleRemoveBtn ) ); - m_pScrollBar = new ScrollBar( this, WB_VERT ); - m_pScrollBar->SetScrollHdl( LINK( this, ExtensionBox_Impl, ScrollHdl ) ); - m_pScrollBar->EnableDrag(); - - m_pOptionsBtn->SetText( ExtMgrDialog::getResourceString( RID_CTX_ITEM_OPTIONS ) ); - m_pEnableBtn->SetText( ExtMgrDialog::getResourceString( RID_CTX_ITEM_DISABLE ) ); - m_pRemoveBtn->SetText( ExtMgrDialog::getResourceString( RID_CTX_ITEM_REMOVE ) ); + m_pOptionsBtn->SetText( DialogHelper::getResourceString( RID_CTX_ITEM_OPTIONS ) ); + m_pEnableBtn->SetText( DialogHelper::getResourceString( RID_CTX_ITEM_DISABLE ) ); + m_pRemoveBtn->SetText( DialogHelper::getResourceString( RID_CTX_ITEM_REMOVE ) ); Size aSize = LogicToPixel( Size( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ), MapMode( MAP_APPFONT ) ); @@ -433,288 +207,69 @@ ExtensionBox_Impl::ExtensionBox_Impl( ExtMgrDialog* pParent, TheExtensionManager m_pEnableBtn->SetSizePixel( aSize ); m_pRemoveBtn->SetSizePixel( aSize ); - SetPaintTransparent( true ); - SetPosPixel( Point( RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP ) ); - long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE; - long nTitleHeight = 2*TOP_OFFSET + GetTextHeight(); - if ( nIconHeight < nTitleHeight ) - m_nStdHeight = nTitleHeight; - else - m_nStdHeight = nIconHeight; - m_nStdHeight += GetTextHeight() + TOP_OFFSET; - - nIconHeight = ICON_HEIGHT + 2*TOP_OFFSET + 1; - if ( m_nStdHeight < nIconHeight ) - m_nStdHeight = nIconHeight; - - m_nActiveHeight = m_nStdHeight; - m_nBtnHeight = aSize.Height() + 2 * TOP_OFFSET; - - const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); - if( IsControlBackground() ) - SetBackground( GetControlBackground() ); - else - SetBackground( rStyleSettings.GetFieldColor() ); - - m_pLocale = new lang::Locale( Application::GetSettings().GetLocale() ); - m_pCollator = new CollatorWrapper( ::comphelper::getProcessServiceFactory() ); - m_pCollator->loadDefaultCollator( *m_pLocale, i18n::CollatorOptions::CollatorOptions_IGNORE_CASE ); + SetExtraSize( aSize.Height() + 2 * TOP_OFFSET ); - Show(); + SetScrollHdl( LINK( this, ExtBoxWithBtns_Impl, ScrollHdl ) ); } //------------------------------------------------------------------------------ -ExtensionBox_Impl::~ExtensionBox_Impl() +ExtBoxWithBtns_Impl::~ExtBoxWithBtns_Impl() { - typedef std::vector< TEntry_Impl >::iterator ITER; - -// for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex ) -// (*iIndex)->m_xPackage->removeEventListener( this ); - - m_vEntries.clear(); - delete m_pOptionsBtn; delete m_pEnableBtn; delete m_pRemoveBtn; - delete m_pScrollBar; - - delete m_pLocale; - delete m_pCollator; } //------------------------------------------------------------------------------ -sal_Int32 ExtensionBox_Impl::getItemCount() const -{ - return static_cast< sal_Int32 >( m_vEntries.size() ); -} - //------------------------------------------------------------------------------ -sal_Int32 ExtensionBox_Impl::getSelIndex() const -{ - if ( m_bHasActive ) - { - OSL_ASSERT( m_nActive >= -1); - return static_cast< sal_Int32 >( m_nActive ); - } - else - return static_cast< sal_Int32 >( EXTENSION_LISTBOX_ENTRY_NOTFOUND ); -} - //------------------------------------------------------------------------------ -void ExtensionBox_Impl::checkIndex( sal_Int32 nIndex ) const +const Size ExtBoxWithBtns_Impl::GetMinOutputSizePixel() const { - if ( nIndex < 0 ) - throw lang::IllegalArgumentException( OUSTR("The list index starts with 0"),0, 0 ); - if ( static_cast< sal_uInt32 >( nIndex ) >= m_vEntries.size()) - throw lang::IllegalArgumentException( OUSTR("There is no element at the provided position." - "The position exceeds the number of available list entries"),0, 0 ); -} - -//------------------------------------------------------------------------------ -OUString ExtensionBox_Impl::getItemName( sal_Int32 nIndex ) const -{ - const ::osl::MutexGuard aGuard( m_entriesMutex ); - checkIndex( nIndex ); - return m_vEntries[ nIndex ]->m_sTitle; -} - -//------------------------------------------------------------------------------ -OUString ExtensionBox_Impl::getItemVersion( sal_Int32 nIndex ) const -{ - const ::osl::MutexGuard aGuard( m_entriesMutex ); - checkIndex( nIndex ); - return m_vEntries[ nIndex ]->m_sVersion; -} - -//------------------------------------------------------------------------------ -OUString ExtensionBox_Impl::getItemDescription( sal_Int32 nIndex ) const -{ - const ::osl::MutexGuard aGuard( m_entriesMutex ); - checkIndex( nIndex ); - return m_vEntries[ nIndex ]->m_sDescription; -} - -//------------------------------------------------------------------------------ -OUString ExtensionBox_Impl::getItemPublisher( sal_Int32 nIndex ) const -{ - const ::osl::MutexGuard aGuard( m_entriesMutex ); - checkIndex( nIndex ); - return m_vEntries[ nIndex ]->m_sPublisher; -} - -//------------------------------------------------------------------------------ -OUString ExtensionBox_Impl::getItemPublisherLink( sal_Int32 nIndex ) const -{ - const ::osl::MutexGuard aGuard( m_entriesMutex ); - checkIndex( nIndex ); - return m_vEntries[ nIndex ]->m_sPublisherURL; -} - -//------------------------------------------------------------------------------ -void ExtensionBox_Impl::select( sal_Int32 nIndex ) -{ - const ::osl::MutexGuard aGuard( m_entriesMutex ); - checkIndex( nIndex ); - selectEntry( nIndex ); -} - -//------------------------------------------------------------------------------ -void ExtensionBox_Impl::select( const OUString & sName ) -{ - const ::osl::MutexGuard aGuard( m_entriesMutex ); - typedef ::std::vector< TEntry_Impl >::const_iterator It; - - for ( It iIter = m_vEntries.begin(); iIter < m_vEntries.end(); iIter++ ) - { - if ( sName.equals( (*iIter)->m_sTitle ) ) - { - long nPos = iIter - m_vEntries.begin(); - selectEntry( nPos ); - break; - } - } -} - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -// Title + description + buttons height -void ExtensionBox_Impl::CalcActiveHeight( const long nPos ) -{ - // get title height - long aTextHeight; - long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE; - long nTitleHeight = 2*TOP_OFFSET + GetTextHeight(); - if ( nIconHeight < nTitleHeight ) - aTextHeight = nTitleHeight; - else - aTextHeight = nIconHeight; - - // calc description height - Size aSize = GetOutputSizePixel(); - if ( m_bHasScrollBar ) - aSize.Width() -= m_pScrollBar->GetSizePixel().Width(); - - aSize.Width() -= ICON_OFFSET; - aSize.Height() = 10000; - - Rectangle aRect = GetTextRect( Rectangle( Point(), aSize ), - m_vEntries[ nPos ]->m_sDescription, - TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK ); - aTextHeight += aRect.GetHeight(); - - if ( aTextHeight < m_nStdHeight ) - aTextHeight = m_nStdHeight; - - m_nActiveHeight = aTextHeight + m_nBtnHeight; // button bar height -} - -//------------------------------------------------------------------------------ -const Size ExtensionBox_Impl::GetMinOutputSizePixel() const -{ - long nHeight = m_nStdHeight; + Size aMinSize( ExtensionBox_Impl::GetMinOutputSizePixel() ); + long nHeight = aMinSize.Height(); nHeight += m_pOptionsBtn->GetSizePixel().Height(); nHeight += 2 * TOP_OFFSET; long nWidth = m_pOptionsBtn->GetSizePixel().Width(); nWidth *= 3; - nWidth += 5*TOP_OFFSET; - nWidth += m_pScrollBar->GetSizePixel().Width(); + nWidth += 5*TOP_OFFSET + 20; return Size( nWidth, nHeight ); } -//------------------------------------------------------------------------------ -Rectangle ExtensionBox_Impl::GetEntryRect( const long nPos ) const +// ----------------------------------------------------------------------- +void ExtBoxWithBtns_Impl::RecalcAll() { - Size aSize( GetOutputSizePixel() ); + ExtensionBox_Impl::RecalcAll(); - if ( m_bHasScrollBar ) - aSize.Width() -= m_pScrollBar->GetSizePixel().Width(); + const sal_Int32 nActive = getSelIndex(); - if ( m_vEntries[ nPos ]->m_bActive ) - aSize.Height() = m_nActiveHeight; + if ( nActive != EXTENSION_LISTBOX_ENTRY_NOTFOUND ) + SetButtonPos( GetEntryRect( nActive ) ); else - aSize.Height() = m_nStdHeight; - - Point aPos( 0, -m_nTopIndex + nPos * m_nStdHeight ); - if ( m_bHasActive && ( nPos < m_nActive ) ) - aPos.Y() += m_nActiveHeight - m_nStdHeight; - - return Rectangle( aPos, aSize ); + { + m_pOptionsBtn->Hide(); + m_pEnableBtn->Hide(); + m_pRemoveBtn->Hide(); + } } + //------------------------------------------------------------------------------ //This function may be called with nPos < 0 -void ExtensionBox_Impl::selectEntry( long nPos ) +void ExtBoxWithBtns_Impl::selectEntry( const long nPos ) { - //ToDo whe should not use the guard at such a big scope here. - //Currently it is used to gard m_vEntries and m_nActive. m_nActive will be - //modified in this function. - //It would be probably best to always use a copy of m_vEntries - //and some other state variables from ExtensionBox_Impl for - //the whole painting operation. See issue i86993 - ::osl::ClearableMutexGuard guard(m_entriesMutex); - - if ( m_bInCheckMode ) + if ( HasActive() && ( nPos == getSelIndex() ) ) return; - if ( m_bHasActive ) - { - if ( nPos == m_nActive ) - return; - - m_bHasActive = false; - m_vEntries[ m_nActive ]->m_bActive = false; + ExtensionBox_Impl::selectEntry( nPos ); - if ( IsReallyVisible() ) - Invalidate(); - } - - if ( ( nPos >= 0 ) && ( nPos < (long) m_vEntries.size() ) ) + if ( ( nPos >= 0 ) && ( nPos < GetEntryCount() ) ) { - m_bHasActive = true; - m_nActive = nPos; - m_vEntries[ nPos ]->m_bActive = true; - if ( IsReallyVisible() ) { - Invalidate(); - CalcActiveHeight( nPos ); - SetupScrollBar(); - Rectangle aEntryRect = GetEntryRect( nPos ); - - // If the top of the selected entry isn't visible, make it visible - if ( aEntryRect.Top() < 0 ) - { - m_nTopIndex += aEntryRect.Top(); - aEntryRect.Move( 0, -aEntryRect.Top() ); - } - - // If the bottom of the selected entry isn't visible, make it visible even if now the top - // isn't visible any longer ( the buttons are more important ) - Size aOutputSize = GetOutputSizePixel(); - if ( aEntryRect.Bottom() > aOutputSize.Height() ) - { - m_nTopIndex += ( aEntryRect.Bottom() - aOutputSize.Height() ); - aEntryRect.Move( 0, -( aEntryRect.Bottom() - aOutputSize.Height() ) ); - } - - // If there is unused space below the last entry but all entries don't fit into the box, - // move the content down to use the whole space - const long nTotalHeight = GetTotalHeight(); - if ( m_bHasScrollBar && ( aOutputSize.Height() + m_nTopIndex > nTotalHeight ) ) - { - long nOffset = m_nTopIndex; - m_nTopIndex = nTotalHeight - aOutputSize.Height(); - nOffset -= m_nTopIndex; - aEntryRect.Move( 0, nOffset ); - } - - if ( m_bHasScrollBar ) - m_pScrollBar->SetThumbPos( m_nTopIndex ); - - SetButtonPos( aEntryRect ); + SetButtonPos( GetEntryRect( nPos ) ); } - SetButtonStatus( m_vEntries[ nPos ] ); //dv + SetButtonStatus( GetEntryData( nPos) ); } else { @@ -722,12 +277,10 @@ void ExtensionBox_Impl::selectEntry( long nPos ) m_pEnableBtn->Hide(); m_pRemoveBtn->Hide(); } - guard.clear(); - } // ----------------------------------------------------------------------- -void ExtensionBox_Impl::SetButtonPos( const Rectangle& rRect ) +void ExtBoxWithBtns_Impl::SetButtonPos( const Rectangle& rRect ) { Size aBtnSize( m_pOptionsBtn->GetSizePixel() ); Point aBtnPos( rRect.Left() + ICON_OFFSET, @@ -741,20 +294,20 @@ void ExtensionBox_Impl::SetButtonPos( const Rectangle& rRect ) } // ----------------------------------------------------------------------- -void ExtensionBox_Impl::SetButtonStatus( const TEntry_Impl pEntry ) +void ExtBoxWithBtns_Impl::SetButtonStatus( const TEntry_Impl pEntry ) { if ( ( pEntry->m_eState == REGISTERED ) || ( pEntry->m_eState == NOT_AVAILABLE ) ) { - m_pEnableBtn->SetText( ExtMgrDialog::getResourceString( RID_CTX_ITEM_DISABLE ) ); + m_pEnableBtn->SetText( DialogHelper::getResourceString( RID_CTX_ITEM_DISABLE ) ); m_pEnableBtn->SetHelpId( HID_EXTENSION_MANAGER_LISTBOX_DISABLE ); } else { - m_pEnableBtn->SetText( ExtMgrDialog::getResourceString( RID_CTX_ITEM_ENABLE ) ); + m_pEnableBtn->SetText( DialogHelper::getResourceString( RID_CTX_ITEM_ENABLE ) ); m_pEnableBtn->SetHelpId( HID_EXTENSION_MANAGER_LISTBOX_ENABLE ); } - if ( pEntry->m_eState == NOT_AVAILABLE ) + if ( ( pEntry->m_eState == NOT_AVAILABLE ) || pEntry->m_bMissingDeps ) m_pEnableBtn->Hide(); else { @@ -775,183 +328,23 @@ void ExtensionBox_Impl::SetButtonStatus( const TEntry_Impl pEntry ) } // ----------------------------------------------------------------------- -void ExtensionBox_Impl::DrawRow( const Rectangle& rRect, const TEntry_Impl pEntry ) +bool ExtBoxWithBtns_Impl::HandleTabKey( bool bReverse ) { - const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); - - if ( pEntry->m_bActive ) - SetTextColor( rStyleSettings.GetHighlightTextColor() ); - else if ( ( pEntry->m_eState != REGISTERED ) && ( pEntry->m_eState != NOT_AVAILABLE ) ) - SetTextColor( rStyleSettings.GetDisableColor() ); - else if ( IsControlForeground() ) - SetTextColor( GetControlForeground() ); - else - SetTextColor( rStyleSettings.GetFieldTextColor() ); - - if ( pEntry->m_bActive ) - { - SetLineColor(); - SetFillColor( rStyleSettings.GetHighlightColor() ); - DrawRect( rRect ); - } - else - { - if( IsControlBackground() ) - SetBackground( GetControlBackground() ); - else - SetBackground( rStyleSettings.GetFieldColor() ); - - SetTextFillColor(); - Erase( rRect ); - } - - // Draw extension icon - Point aPos( rRect.TopLeft() ); - aPos += Point( TOP_OFFSET, TOP_OFFSET ); - Image aImage; - if ( ! pEntry->m_aIcon ) - aImage = isHCMode() ? m_aDefaultImageHC : m_aDefaultImage; - else - aImage = isHCMode() ? pEntry->m_aIconHC : pEntry->m_aIcon; - Size aImageSize = aImage.GetSizePixel(); - if ( ( aImageSize.Width() <= ICON_HEIGHT ) && ( aImageSize.Height() <= ICON_HEIGHT ) ) - DrawImage( Point( aPos.X()+((ICON_HEIGHT-aImageSize.Width())/2), aPos.Y()+((ICON_HEIGHT-aImageSize.Height())/2) ), aImage ); - else - DrawImage( aPos, Size( ICON_HEIGHT, ICON_HEIGHT ), aImage ); - - // Setup fonts - Font aStdFont( GetFont() ); - Font aBoldFont( aStdFont ); - aBoldFont.SetWeight( WEIGHT_BOLD ); - SetFont( aBoldFont ); - long aTextHeight = GetTextHeight(); - - // Init publisher link here - if ( !pEntry->m_pPublisher && pEntry->m_sPublisher.Len() ) - { - pEntry->m_pPublisher = new svt::FixedHyperlink( this ); - pEntry->m_pPublisher->SetBackground(); - pEntry->m_pPublisher->SetPaintTransparent( true ); - pEntry->m_pPublisher->SetURL( pEntry->m_sPublisherURL ); - pEntry->m_pPublisher->SetDescription( pEntry->m_sPublisher ); - Size aSize = FixedText::CalcMinimumTextSize( pEntry->m_pPublisher ); - pEntry->m_pPublisher->SetSizePixel( aSize ); - pEntry->m_pPublisher->SetClickHdl( LINK( this, ExtensionBox_Impl, HandleHyperlink ) ); - } - - // Get max title width - long nMaxTitleWidth = rRect.GetWidth() - ICON_OFFSET; - nMaxTitleWidth -= ( 2 * SMALL_ICON_SIZE ) + ( 4 * SPACE_BETWEEN ); - if ( pEntry->m_pPublisher ) - { - nMaxTitleWidth -= pEntry->m_pPublisher->GetSizePixel().Width() + (2*SPACE_BETWEEN); - } - - long aVersionWidth = GetTextWidth( pEntry->m_sVersion ); - long aTitleWidth = GetTextWidth( pEntry->m_sTitle ) + (aTextHeight / 3); - - aPos = rRect.TopLeft() + Point( ICON_OFFSET, TOP_OFFSET ); - - if ( aTitleWidth > nMaxTitleWidth - aVersionWidth ) - { - aTitleWidth = nMaxTitleWidth - aVersionWidth - (aTextHeight / 3); - String aShortTitle = GetEllipsisString( pEntry->m_sTitle, aTitleWidth ); - DrawText( aPos, aShortTitle ); - aTitleWidth += (aTextHeight / 3); - } - else - DrawText( aPos, pEntry->m_sTitle ); - - SetFont( aStdFont ); - DrawText( Point( aPos.X() + aTitleWidth, aPos.Y() ), pEntry->m_sVersion ); - - long nIconHeight = TOP_OFFSET + SMALL_ICON_SIZE; - long nTitleHeight = TOP_OFFSET + GetTextHeight(); - if ( nIconHeight < nTitleHeight ) - aTextHeight = nTitleHeight; - else - aTextHeight = nIconHeight; - - // draw description - String sDescription; - if ( pEntry->m_sErrorText.Len() ) - { - if ( pEntry->m_bActive ) - sDescription = pEntry->m_sErrorText + OUSTR("\n") + pEntry->m_sDescription; - else - sDescription = pEntry->m_sErrorText; - } - else - sDescription = pEntry->m_sDescription; - - aPos.Y() += aTextHeight; - if ( pEntry->m_bActive ) - { - DrawText( Rectangle( aPos.X(), aPos.Y(), rRect.Right(), rRect.Bottom() - m_nBtnHeight ), - sDescription, TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK ); - } - else - { - const long nWidth = GetTextWidth( sDescription ); - if ( nWidth > rRect.GetWidth() - aPos.X() ) - sDescription = GetEllipsisString( sDescription, rRect.GetWidth() - aPos.X() ); - DrawText( aPos, sDescription ); - } - - // Draw publisher link - if ( pEntry->m_pPublisher ) - { - pEntry->m_pPublisher->Show(); - aPos = rRect.TopLeft() + Point( ICON_OFFSET + nMaxTitleWidth + (2*SPACE_BETWEEN), TOP_OFFSET ); - pEntry->m_pPublisher->SetPosPixel( aPos ); - } + sal_Int32 nIndex = getSelIndex(); - // Draw status icons - if ( pEntry->m_bShared ) - { - aPos = rRect.TopRight() + Point( -(RIGHT_ICON_OFFSET + SMALL_ICON_SIZE), TOP_OFFSET ); - DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), isHCMode() ? m_aLockedImageHC : m_aLockedImage ); - } - if ( pEntry->m_eState == AMBIGUOUS ) - { - aPos = rRect.TopRight() + Point( -(RIGHT_ICON_OFFSET + SPACE_BETWEEN + 2*SMALL_ICON_SIZE), TOP_OFFSET ); - DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), isHCMode() ? m_aWarningImageHC : m_aWarningImage ); - } - - SetLineColor( Color( COL_LIGHTGRAY ) ); - DrawLine( rRect.BottomLeft(), rRect.BottomRight() ); -} - -// ----------------------------------------------------------------------- -void ExtensionBox_Impl::RecalcAll() -{ - if ( m_bHasActive ) - CalcActiveHeight( m_nActive ); - - SetupScrollBar(); - - if ( m_bHasActive ) - SetButtonPos( GetEntryRect( m_nActive ) ); - - m_bNeedsRecalc = false; -} - -// ----------------------------------------------------------------------- -bool ExtensionBox_Impl::HandleTabKey( bool bReverse ) -{ - if ( ! m_bHasActive ) + if ( nIndex == EXTENSION_LISTBOX_ENTRY_NOTFOUND ) return false; PushButton *pNext = NULL; if ( m_pOptionsBtn->HasFocus() ) { - if ( !bReverse && !m_vEntries[ m_nActive ]->m_bLocked ) + if ( !bReverse && !GetEntryData( nIndex )->m_bLocked ) pNext = m_pEnableBtn; } else if ( m_pEnableBtn->HasFocus() ) { if ( !bReverse ) pNext = m_pRemoveBtn; - else if ( m_vEntries[ m_nActive ]->m_bHasOptions ) + else if ( GetEntryData( nIndex )->m_bHasOptions ) pNext = m_pOptionsBtn; } else if ( m_pRemoveBtn->HasFocus() ) { @@ -960,14 +353,14 @@ bool ExtensionBox_Impl::HandleTabKey( bool bReverse ) } else { if ( !bReverse ) { - if ( m_vEntries[ m_nActive ]->m_bHasOptions ) + if ( GetEntryData( nIndex )->m_bHasOptions ) pNext = m_pOptionsBtn; - else if ( ! m_vEntries[ m_nActive ]->m_bLocked ) + else if ( ! GetEntryData( nIndex )->m_bLocked ) pNext = m_pEnableBtn; } else { - if ( ! m_vEntries[ m_nActive ]->m_bLocked ) + if ( ! GetEntryData( nIndex )->m_bLocked ) pNext = m_pRemoveBtn; - else if ( m_vEntries[ m_nActive ]->m_bHasOptions ) + else if ( GetEntryData( nIndex )->m_bHasOptions ) pNext = m_pOptionsBtn; } } @@ -982,194 +375,67 @@ bool ExtensionBox_Impl::HandleTabKey( bool bReverse ) } // ----------------------------------------------------------------------- -bool ExtensionBox_Impl::HandleCursorKey( USHORT nKeyCode ) -{ - if ( m_vEntries.empty() ) - return true; - - long nSelect = 0; - - if ( m_bHasActive ) - { - long nPageSize = GetOutputSizePixel().Height() / m_nStdHeight; - if ( nPageSize < 2 ) - nPageSize = 2; - - if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_RIGHT ) ) - nSelect = m_nActive + 1; - else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_LEFT ) ) - nSelect = m_nActive - 1; - else if ( nKeyCode == KEY_HOME ) - nSelect = 0; - else if ( nKeyCode == KEY_END ) - nSelect = m_vEntries.size() - 1; - else if ( nKeyCode == KEY_PAGEUP ) - nSelect = m_nActive - nPageSize + 1; - else if ( nKeyCode == KEY_PAGEDOWN ) - nSelect = m_nActive + nPageSize - 1; - } - else // when there is no selected entry, we will select the first or the last. - { - if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_PAGEDOWN ) || ( nKeyCode == KEY_HOME ) ) - nSelect = 0; - else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_PAGEUP ) || ( nKeyCode == KEY_END ) ) - nSelect = m_vEntries.size() - 1; - } - - if ( nSelect < 0 ) - nSelect = 0; - if ( nSelect >= (long) m_vEntries.size() ) - nSelect = m_vEntries.size() - 1; - - selectEntry( nSelect ); - - return true; -} - -// ----------------------------------------------------------------------- -MENU_COMMAND ExtensionBox_Impl::ShowPopupMenu( const Point & rPos, const long nPos ) +MENU_COMMAND ExtBoxWithBtns_Impl::ShowPopupMenu( const Point & rPos, const long nPos ) { - if ( nPos >= (long) m_vEntries.size() ) + if ( nPos >= (long) getItemCount() ) return CMD_NONE; PopupMenu aPopup; - aPopup.InsertItem( CMD_UPDATE, ExtMgrDialog::getResourceString( RID_CTX_ITEM_CHECK_UPDATE ) ); + aPopup.InsertItem( CMD_UPDATE, DialogHelper::getResourceString( RID_CTX_ITEM_CHECK_UPDATE ) ); - if ( ! m_vEntries[ nPos ]->m_bLocked ) + if ( ! GetEntryData( nPos )->m_bLocked ) { - if ( m_vEntries[ nPos ]->m_eState == REGISTERED ) - aPopup.InsertItem( CMD_DISABLE, ExtMgrDialog::getResourceString( RID_CTX_ITEM_DISABLE ) ); - else if ( m_vEntries[ nPos ]->m_eState != NOT_AVAILABLE ) - aPopup.InsertItem( CMD_ENABLE, ExtMgrDialog::getResourceString( RID_CTX_ITEM_ENABLE ) ); + if ( GetEntryData( nPos )->m_eState == REGISTERED ) + aPopup.InsertItem( CMD_DISABLE, DialogHelper::getResourceString( RID_CTX_ITEM_DISABLE ) ); + else if ( GetEntryData( nPos )->m_eState != NOT_AVAILABLE ) + aPopup.InsertItem( CMD_ENABLE, DialogHelper::getResourceString( RID_CTX_ITEM_ENABLE ) ); - aPopup.InsertItem( CMD_REMOVE, ExtMgrDialog::getResourceString( RID_CTX_ITEM_REMOVE ) ); + aPopup.InsertItem( CMD_REMOVE, DialogHelper::getResourceString( RID_CTX_ITEM_REMOVE ) ); } return (MENU_COMMAND) aPopup.Execute( this, rPos ); } -// ----------------------------------------------------------------------- -void ExtensionBox_Impl::Paint( const Rectangle &/*rPaintRect*/ ) -{ - if ( m_bNeedsRecalc ) - RecalcAll(); - - Point aStart( 0, -m_nTopIndex ); - Size aSize( GetOutputSizePixel() ); - - if ( m_bHasScrollBar ) - aSize.Width() -= m_pScrollBar->GetSizePixel().Width(); - - typedef std::vector< TEntry_Impl >::iterator ITER; - for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex ) - { - aSize.Height() = (*iIndex)->m_bActive ? m_nActiveHeight : m_nStdHeight; - Rectangle aEntryRect( aStart, aSize ); -// if ( aEntryRect.IsOver( rPaintRect ) ) - DrawRow( aEntryRect, *iIndex ); - aStart.Y() += aSize.Height(); - } -} - -// ----------------------------------------------------------------------- -long ExtensionBox_Impl::GetTotalHeight() const -{ - long nHeight = m_vEntries.size() * m_nStdHeight; - - if ( m_bHasActive ) - { - nHeight += m_nActiveHeight - m_nStdHeight; - } - - return nHeight; -} - -// ----------------------------------------------------------------------- -void ExtensionBox_Impl::SetupScrollBar() -{ - const Size aSize = GetOutputSizePixel(); - const long nScrBarSize = GetSettings().GetStyleSettings().GetScrollBarSize(); - const long nTotalHeight = GetTotalHeight(); - const bool bNeedsScrollBar = ( nTotalHeight > aSize.Height() ); - - if ( bNeedsScrollBar ) - { - if ( m_nTopIndex + aSize.Height() > nTotalHeight ) - m_nTopIndex = nTotalHeight - aSize.Height(); - - m_pScrollBar->SetPosSizePixel( Point( aSize.Width() - nScrBarSize, 0 ), - Size( nScrBarSize, aSize.Height() ) ); - m_pScrollBar->SetRangeMax( nTotalHeight ); - m_pScrollBar->SetVisibleSize( aSize.Height() ); - m_pScrollBar->SetPageSize( ( aSize.Height() * 4 ) / 5 ); - m_pScrollBar->SetLineSize( m_nStdHeight ); - m_pScrollBar->SetThumbPos( m_nTopIndex ); - - if ( !m_bHasScrollBar ) - m_pScrollBar->Show(); - } - else if ( m_bHasScrollBar ) - { - m_pScrollBar->Hide(); - m_nTopIndex = 0; - } - - m_bHasScrollBar = bNeedsScrollBar; -} - -// ----------------------------------------------------------------------- -void ExtensionBox_Impl::Resize() -{ - RecalcAll(); -} - //------------------------------------------------------------------------------ -void ExtensionBox_Impl::MouseButtonDown( const MouseEvent& rMEvt ) +void ExtBoxWithBtns_Impl::MouseButtonDown( const MouseEvent& rMEvt ) { if ( m_bInterfaceLocked ) return; const Point aMousePos( rMEvt.GetPosPixel() ); - long nPos = ( aMousePos.Y() + m_nTopIndex ) / m_nStdHeight; - if ( m_bHasActive && ( nPos > m_nActive ) ) - { - if ( aMousePos.Y() + m_nTopIndex <= m_nActive*m_nStdHeight + m_nActiveHeight ) - nPos = m_nActive; - else - nPos = ( aMousePos.Y() + m_nTopIndex - (m_nActiveHeight - m_nStdHeight) ) / m_nStdHeight; - } + const long nPos = PointToPos( aMousePos ); if ( rMEvt.IsRight() ) { switch( ShowPopupMenu( aMousePos, nPos ) ) { case CMD_NONE: break; - case CMD_ENABLE: m_pParent->enablePackage( m_vEntries[ nPos ]->m_xPackageManager, - m_vEntries[ nPos ]->m_xPackage, true ); + case CMD_ENABLE: m_pParent->enablePackage( GetEntryData( nPos )->m_xPackageManager, + GetEntryData( nPos )->m_xPackage, true ); break; - case CMD_DISABLE: m_pParent->enablePackage( m_vEntries[ nPos ]->m_xPackageManager, - m_vEntries[ nPos ]->m_xPackage, false ); + case CMD_DISABLE: m_pParent->enablePackage( GetEntryData( nPos )->m_xPackageManager, + GetEntryData( nPos )->m_xPackage, false ); break; - case CMD_UPDATE: m_pParent->updatePackage( m_vEntries[ nPos ]->m_xPackageManager, - m_vEntries[ nPos ]->m_xPackage ); + case CMD_UPDATE: m_pParent->updatePackage( GetEntryData( nPos )->m_xPackageManager, + GetEntryData( nPos )->m_xPackage ); break; - case CMD_REMOVE: m_pParent->removePackage( m_vEntries[ nPos ]->m_xPackageManager, - m_vEntries[ nPos ]->m_xPackage ); + case CMD_REMOVE: m_pParent->removePackage( GetEntryData( nPos )->m_xPackageManager, + GetEntryData( nPos )->m_xPackage ); break; } } else if ( rMEvt.IsLeft() ) { - if ( rMEvt.IsMod1() && m_bHasActive ) - selectEntry( m_vEntries.size() ); // Selecting an not existing entry will deselect the current one + if ( rMEvt.IsMod1() && HasActive() ) + selectEntry( EXTENSION_LISTBOX_ENTRY_NOTFOUND ); // Selecting an not existing entry will deselect the current one else selectEntry( nPos ); } } //------------------------------------------------------------------------------ -long ExtensionBox_Impl::Notify( NotifyEvent& rNEvt ) +long ExtBoxWithBtns_Impl::Notify( NotifyEvent& rNEvt ) { bool bHandled = false; @@ -1181,364 +447,259 @@ long ExtensionBox_Impl::Notify( NotifyEvent& rNEvt ) if ( nKeyCode == KEY_TAB ) bHandled = HandleTabKey( aKeyCode.IsShift() ); - else if ( aKeyCode.GetGroup() == KEYGROUP_CURSOR ) - bHandled = HandleCursorKey( nKeyCode ); - } - - if ( rNEvt.GetType() == EVENT_COMMAND ) - { - if ( m_bHasScrollBar && - ( rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL ) ) - { - const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData(); - if ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) - { - long nThumbPos = m_pScrollBar->GetThumbPos(); - if ( pData->GetDelta() < 0 ) - m_pScrollBar->DoScroll( nThumbPos + m_nStdHeight ); - else - m_pScrollBar->DoScroll( nThumbPos - m_nStdHeight ); - bHandled = true; - } - } } if ( !bHandled ) - return Control::Notify( rNEvt ); + return ExtensionBox_Impl::Notify( rNEvt ); else return true; } //------------------------------------------------------------------------------ -bool ExtensionBox_Impl::FindEntryPos( const TEntry_Impl pEntry, const long nStart, - const long nEnd, long &nPos ) +void ExtBoxWithBtns_Impl::enableButtons( bool bEnable ) { - nPos = nStart; - if ( nStart > nEnd ) - return false; - - StringCompare eCompare; + m_bInterfaceLocked = ! bEnable; - if ( nStart == nEnd ) + if ( bEnable ) { - eCompare = pEntry->CompareTo( m_pCollator, m_vEntries[ nStart ] ); - if ( eCompare == COMPARE_LESS ) - return false; - else if ( eCompare == COMPARE_EQUAL ) - { - //Workaround. See i86963. - if (pEntry->m_xPackage != m_vEntries[nStart]->m_xPackage) - return false; - - if ( m_bInCheckMode ) - m_vEntries[ nStart ]->m_bChecked = true; - return true; - } - else - { - nPos = nStart + 1; - return false; - } + sal_Int32 nIndex = getSelIndex(); + if ( nIndex != EXTENSION_LISTBOX_ENTRY_NOTFOUND ) + SetButtonStatus( GetEntryData( nIndex ) ); } - - const long nMid = nStart + ( ( nEnd - nStart ) / 2 ); - eCompare = pEntry->CompareTo( m_pCollator, m_vEntries[ nMid ] ); - - if ( eCompare == COMPARE_LESS ) - return FindEntryPos( pEntry, nStart, nMid-1, nPos ); - else if ( eCompare == COMPARE_GREATER ) - return FindEntryPos( pEntry, nMid+1, nEnd, nPos ); else { - //Workaround.See i86963. - if (pEntry->m_xPackage != m_vEntries[nMid]->m_xPackage) - return false; - - if ( m_bInCheckMode ) - m_vEntries[ nMid ]->m_bChecked = true; - nPos = nMid; - return true; + m_pOptionsBtn->Enable( false ); + m_pRemoveBtn->Enable( false ); + m_pEnableBtn->Enable( false ); } } -//------------------------------------------------------------------------------ -long ExtensionBox_Impl::addEntry( const uno::Reference< deployment::XPackage > &xPackage, - const uno::Reference< deployment::XPackageManager > &xPackageManager ) +// ----------------------------------------------------------------------- +IMPL_LINK( ExtBoxWithBtns_Impl, ScrollHdl, ScrollBar*, pScrBar ) { - long nPos = 0; - PackageState eState = m_pManager->getPackageState( xPackage ); - - TEntry_Impl pEntry( new Entry_Impl( xPackage, xPackageManager, eState ) ); - xPackage->addEventListener( this ); - - ::osl::ClearableMutexGuard guard(m_entriesMutex); - if ( m_vEntries.empty() ) - { - pEntry->m_bHasOptions = m_pManager->supportsOptions( xPackage ); - pEntry->m_bShared = ( m_pManager->getSharedPkgMgr() == xPackageManager ); - pEntry->m_bNew = m_bInCheckMode; - m_vEntries.push_back( pEntry ); - } - else - { - if ( !FindEntryPos( pEntry, 0, m_vEntries.size()-1, nPos ) ) - { - pEntry->m_bHasOptions = m_pManager->supportsOptions( xPackage ); - pEntry->m_bShared = ( m_pManager->getSharedPkgMgr() == xPackageManager ); - pEntry->m_bNew = m_bInCheckMode; - m_vEntries.insert( m_vEntries.begin()+nPos, pEntry ); - } - else if ( !m_bInCheckMode ) - { - OSL_ENSURE( 0, "ExtensionBox_Impl::addEntry(): Will not add duplicate entries" ); - } - } - //access to m_nActive must be guarded - if ( !m_bInCheckMode && m_bHasActive && ( m_nActive >= nPos ) ) - m_nActive += 1; + long nDelta = pScrBar->GetDelta(); - guard.clear(); + Point aNewOptPt( m_pOptionsBtn->GetPosPixel() - Point( 0, nDelta ) ); + Point aNewRemPt( m_pRemoveBtn->GetPosPixel() - Point( 0, nDelta ) ); + Point aNewEnPt( m_pEnableBtn->GetPosPixel() - Point( 0, nDelta ) ); - if ( IsReallyVisible() ) - Invalidate(); + DoScroll( nDelta ); - m_bNeedsRecalc = true; + m_pOptionsBtn->SetPosPixel( aNewOptPt ); + m_pRemoveBtn->SetPosPixel( aNewRemPt ); + m_pEnableBtn->SetPosPixel( aNewEnPt ); - return nPos; + return 1; } -//------------------------------------------------------------------------------ -void ExtensionBox_Impl::updateEntry( const uno::Reference< deployment::XPackage > &xPackage ) +// ----------------------------------------------------------------------- +IMPL_LINK( ExtBoxWithBtns_Impl, HandleOptionsBtn, void*, EMPTYARG ) { - typedef std::vector< TEntry_Impl >::iterator ITER; - for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex ) + const sal_Int32 nActive = getSelIndex(); + + if ( nActive != EXTENSION_LISTBOX_ENTRY_NOTFOUND ) { - if ( (*iIndex)->m_xPackage == xPackage ) + SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); + + if ( pFact ) { - PackageState eState = m_pManager->getPackageState( xPackage ); - (*iIndex)->m_bHasOptions = m_pManager->supportsOptions( xPackage ); - (*iIndex)->m_eState = eState; - (*iIndex)->m_sTitle = xPackage->getDisplayName(); - (*iIndex)->m_sVersion = xPackage->getVersion(); - (*iIndex)->m_sDescription = xPackage->getDescription(); - - if ( eState == AMBIGUOUS ) - (*iIndex)->m_sErrorText = ExtMgrDialog::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS ); - else - (*iIndex)->m_sErrorText = String(); + OUString sExtensionId = GetEntryData( nActive )->m_xPackage->getIdentifier().Value; + VclAbstractDialog* pDlg = pFact->CreateOptionsDialog( this, sExtensionId, rtl::OUString() ); - if ( IsReallyVisible() ) - Invalidate(); - break; + pDlg->Execute(); + + delete pDlg; } } + + return 1; } -//------------------------------------------------------------------------------ -void ExtensionBox_Impl::prepareChecking( const uno::Reference< deployment::XPackageManager > &xPackageMgr ) +// ----------------------------------------------------------------------- +IMPL_LINK( ExtBoxWithBtns_Impl, HandleEnableBtn, void*, EMPTYARG ) { - m_bInCheckMode = true; - typedef std::vector< TEntry_Impl >::iterator ITER; - for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex ) + const sal_Int32 nActive = getSelIndex(); + + if ( nActive != EXTENSION_LISTBOX_ENTRY_NOTFOUND ) { - if ( (*iIndex)->m_xPackageManager == xPackageMgr ) - (*iIndex)->m_bChecked = false; - else - (*iIndex)->m_bChecked = true; - (*iIndex)->m_bNew = false; + TEntry_Impl pEntry = GetEntryData( nActive ); + const bool bEnable( pEntry->m_eState != REGISTERED ); + + m_pParent->enablePackage( pEntry->m_xPackageManager, + pEntry->m_xPackage, + bEnable ); } + + return 1; } -//------------------------------------------------------------------------------ -void ExtensionBox_Impl::checkEntries() +// ----------------------------------------------------------------------- +IMPL_LINK( ExtBoxWithBtns_Impl, HandleRemoveBtn, void*, EMPTYARG ) { - long nNewPos = -1; - long nPos = 0; - bool bNeedsUpdate = false; + const sal_Int32 nActive = getSelIndex(); - ::osl::ClearableMutexGuard guard(m_entriesMutex); - typedef std::vector< TEntry_Impl >::iterator ITER; - ITER iIndex = m_vEntries.begin(); - while ( iIndex < m_vEntries.end() ) + if ( nActive != EXTENSION_LISTBOX_ENTRY_NOTFOUND ) { - if ( (*iIndex)->m_bChecked == false ) - { - bNeedsUpdate = true; - nPos = iIndex-m_vEntries.begin(); - if ( (*iIndex)->m_bNew ) - { - if ( nNewPos == - 1) - nNewPos = nPos; - if ( nPos <= m_nActive ) - m_nActive += 1; - } - } - iIndex++; + TEntry_Impl pEntry = GetEntryData( nActive ); + m_pParent->removePackage( pEntry->m_xPackageManager, + pEntry->m_xPackage ); } - guard.clear(); - - m_bInCheckMode = false; - if ( nNewPos != - 1) - selectEntry( nNewPos ); + return 1; +} - if ( bNeedsUpdate ) - { - m_bNeedsRecalc = true; - if ( IsReallyVisible() ) - Invalidate(); - } +//------------------------------------------------------------------------------ +// DialogHelper +//------------------------------------------------------------------------------ +DialogHelper::DialogHelper( const uno::Reference< uno::XComponentContext > &xContext, + Dialog *pWindow ) : + m_pVCLWindow( pWindow ), + m_nEventID( 0 ), + m_bIsBusy( false ) +{ + m_xContext = xContext; } + //------------------------------------------------------------------------------ -bool ExtensionBox_Impl::isHCMode() +DialogHelper::~DialogHelper() { - return (bool)GetDisplayBackground().GetColor().IsDark(); + if ( m_nEventID ) + Application::RemoveUserEvent( m_nEventID ); } //------------------------------------------------------------------------------ -void ExtensionBox_Impl::enableButtons( bool bEnable ) +ResId DialogHelper::getResId( USHORT nId ) { - m_bInterfaceLocked = ! bEnable; + const ::vos::OGuard guard( Application::GetSolarMutex() ); + return ResId( nId, *DeploymentGuiResMgr::get() ); +} - if ( bEnable ) - { - if ( m_bHasActive ) - SetButtonStatus( m_vEntries[ m_nActive ] ); - } - else - { - m_pOptionsBtn->Enable( false ); - m_pRemoveBtn->Enable( false ); - m_pEnableBtn->Enable( false ); +//------------------------------------------------------------------------------ +String DialogHelper::getResourceString( USHORT id ) +{ + // init with non-acquired solar mutex: + BrandName::get(); + const ::vos::OGuard guard( Application::GetSolarMutex() ); + String ret( ResId( id, *DeploymentGuiResMgr::get() ) ); + if (ret.SearchAscii( "%PRODUCTNAME" ) != STRING_NOTFOUND) { + ret.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() ); } + return ret; } //------------------------------------------------------------------------------ -// XEventListener -void ExtensionBox_Impl::disposing( lang::EventObject const & rEvt ) - throw ( uno::RuntimeException ) +bool DialogHelper::IsSharedPkgMgr( const uno::Reference< deployment::XPackageManager > &xPackageManager ) { - uno::Reference< deployment::XPackage > xPackage( rEvt.Source, uno::UNO_QUERY ); + if ( xPackageManager->getContext().equals( OUSTR("shared") ) ) + return true; + else + return false; +} - if ( xPackage.is() ) +//------------------------------------------------------------------------------ +bool DialogHelper::continueOnSharedExtension( const uno::Reference< deployment::XPackageManager > &xPackageManager, + Window *pParent, + const USHORT nResID, + bool &bHadWarning ) +{ + if ( !bHadWarning && IsSharedPkgMgr( xPackageManager ) ) { - ::osl::ClearableMutexGuard aGuard( m_entriesMutex ); - typedef std::vector< TEntry_Impl >::iterator ITER; + const ::vos::OGuard guard( Application::GetSolarMutex() ); + WarningBox aInfoBox( pParent, getResId( nResID ) ); + String aMsgText = aInfoBox.GetMessText(); + aMsgText.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() ); + aInfoBox.SetMessText( aMsgText ); - for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex ) - { - if ( (*iIndex)->m_xPackage == xPackage ) - { - long nPos = iIndex - m_vEntries.begin(); - - m_vEntries.erase( iIndex ); - - if ( IsReallyVisible() ) - Invalidate(); - - if ( m_bHasActive ) - { - if ( nPos < m_nActive ) - m_nActive -= 1; - else if ( ( nPos == m_nActive ) && - ( nPos == (long) m_vEntries.size() ) ) - m_nActive -= 1; - - m_bHasActive = false; - //clear before calling out of this method - aGuard.clear(); - selectEntry( m_nActive ); - } - break; - } - } + bHadWarning = true; + + if ( RET_OK == aInfoBox.Execute() ) + return true; + else + return false; } + else + return true; } -// ----------------------------------------------------------------------- -IMPL_LINK( ExtensionBox_Impl, ScrollHdl, ScrollBar*, pScrBar ) +//------------------------------------------------------------------------------ +void DialogHelper::openWebBrowser( const OUString & sURL, const OUString &sTitle ) const { - long nDelta = pScrBar->GetDelta(); + if ( ! sURL.getLength() ) // Nothing to do, when the URL is empty + return; - m_nTopIndex += nDelta; - Point aNewOptPt( m_pOptionsBtn->GetPosPixel() - Point( 0, nDelta ) ); - Point aNewRemPt( m_pRemoveBtn->GetPosPixel() - Point( 0, nDelta ) ); - Point aNewEnPt( m_pEnableBtn->GetPosPixel() - Point( 0, nDelta ) ); - Point aNewSBPt( m_pScrollBar->GetPosPixel() ); + try + { + uno::Reference< XSystemShellExecute > xSystemShellExecute( + m_xContext->getServiceManager()->createInstanceWithContext( OUSTR( "com.sun.star.system.SystemShellExecute" ), m_xContext), uno::UNO_QUERY_THROW); + //throws css::lang::IllegalArgumentException, css::system::SystemShellExecuteException + xSystemShellExecute->execute( sURL, OUString(), SystemShellExecuteFlags::DEFAULTS ); + } + catch ( uno::Exception& ) + { + uno::Any exc( ::cppu::getCaughtException() ); + OUString msg( ::comphelper::anyToString( exc ) ); + const ::vos::OGuard guard( Application::GetSolarMutex() ); + ErrorBox aErrorBox( NULL, WB_OK, msg ); + aErrorBox.SetText( sTitle ); + aErrorBox.Execute(); + } +} - Rectangle aScrRect( Point(), GetOutputSizePixel() ); - aScrRect.Right() -= pScrBar->GetSizePixel().Width(); - Scroll( 0, -nDelta, aScrRect ); +//------------------------------------------------------------------------------ +bool DialogHelper::installExtensionWarn( const OUString &rExtensionName ) const +{ + const ::vos::OGuard guard( Application::GetSolarMutex() ); + WarningBox aInfo( m_pVCLWindow, getResId( RID_WARNINGBOX_INSTALL_EXTENSION ) ); - m_pOptionsBtn->SetPosPixel( aNewOptPt ); - m_pRemoveBtn->SetPosPixel( aNewRemPt ); - m_pEnableBtn->SetPosPixel( aNewEnPt ); - m_pScrollBar->SetPosPixel( aNewSBPt ); + String sText( aInfo.GetMessText() ); + sText.SearchAndReplaceAllAscii( "%NAME", rExtensionName ); + aInfo.SetMessText( sText ); - return 1; + return ( RET_OK == aInfo.Execute() ); } -// ----------------------------------------------------------------------- -IMPL_LINK( ExtensionBox_Impl, HandleOptionsBtn, void*, EMPTYARG ) +//------------------------------------------------------------------------------ +bool DialogHelper::installForAllUsers( bool &bInstallForAll ) const { - if ( m_bHasActive ) - { - SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); - - if ( pFact ) - { - OUString sExtensionId = m_vEntries[ m_nActive ]->m_xPackage->getIdentifier().Value; - VclAbstractDialog* pDlg = pFact->CreateOptionsDialog( this, sExtensionId, rtl::OUString() ); + const ::vos::OGuard guard( Application::GetSolarMutex() ); + QueryBox aQuery( m_pVCLWindow, getResId( RID_QUERYBOX_INSTALL_FOR_ALL ) ); - pDlg->Execute(); + String sMsgText = aQuery.GetMessText(); + sMsgText.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() ); + aQuery.SetMessText( sMsgText ); - delete pDlg; - } - } + USHORT nYesBtnID = aQuery.GetButtonId( 0 ); + USHORT nNoBtnID = aQuery.GetButtonId( 1 ); - return 1; -} + if ( nYesBtnID != BUTTONDIALOG_BUTTON_NOTFOUND ) + aQuery.SetButtonText( nYesBtnID, getResourceString( RID_STR_INSTALL_FOR_ME ) ); + if ( nNoBtnID != BUTTONDIALOG_BUTTON_NOTFOUND ) + aQuery.SetButtonText( nNoBtnID, getResourceString( RID_STR_INSTALL_FOR_ALL ) ); -// ----------------------------------------------------------------------- -IMPL_LINK( ExtensionBox_Impl, HandleEnableBtn, void*, EMPTYARG ) -{ - if ( m_bHasActive ) - { - const bool bEnable( m_vEntries[ m_nActive ]->m_eState != REGISTERED ); + short nRet = aQuery.Execute(); - m_pParent->enablePackage( m_vEntries[ m_nActive ]->m_xPackageManager, - m_vEntries[ m_nActive ]->m_xPackage, - bEnable ); - } + if ( nRet == RET_CANCEL ) + return false; - return 1; + bInstallForAll = ( nRet == RET_NO ); + return true; } -// ----------------------------------------------------------------------- -IMPL_LINK( ExtensionBox_Impl, HandleRemoveBtn, void*, EMPTYARG ) +//------------------------------------------------------------------------------ +void DialogHelper::PostUserEvent( const Link& rLink, void* pCaller ) { - if ( m_bHasActive ) - { - m_pParent->removePackage( m_vEntries[ m_nActive ]->m_xPackageManager, - m_vEntries[ m_nActive ]->m_xPackage ); - } + if ( m_nEventID ) + Application::RemoveUserEvent( m_nEventID ); - return 1; + m_nEventID = Application::PostUserEvent( rLink, pCaller ); } -// ----------------------------------------------------------------------- -IMPL_LINK( ExtensionBox_Impl, HandleHyperlink, svt::FixedHyperlink*, pHyperlink ) -{ - m_pParent->openWebBrowser( pHyperlink->GetURL() ); - return 1; -} - - //------------------------------------------------------------------------------ // ExtMgrDialog //------------------------------------------------------------------------------ ExtMgrDialog::ExtMgrDialog( Window *pParent, TheExtensionManager *pManager ) : ModelessDialog( pParent, getResId( RID_DLG_EXTENSION_MANAGER ) ), + DialogHelper( pManager->getContext(), (Dialog*) this ), m_aAddBtn( this, getResId( RID_EM_BTN_ADD ) ), m_aUpdateBtn( this, getResId( RID_EM_BTN_CHECK_UPDATES ) ), m_aCloseBtn( this, getResId( RID_EM_BTN_CLOSE ) ), @@ -1557,14 +718,14 @@ ExtMgrDialog::ExtMgrDialog( Window *pParent, TheExtensionManager *pManager ) : m_bEnableWarning( false ), m_bDisableWarning( false ), m_bDeleteWarning( false ), - m_bIsBusy( false ), m_nProgress( 0 ), m_pManager( pManager ) { // free local resources (RID < 256): FreeResource(); - m_pExtensionBox = new ExtensionBox_Impl( this, pManager ); + m_pExtensionBox = new ExtBoxWithBtns_Impl( this, pManager ); + m_pExtensionBox->SetHyperlinkHdl( LINK( this, ExtMgrDialog, HandleHyperlink ) ); m_aAddBtn.SetClickHdl( LINK( this, ExtMgrDialog, HandleAddBtn ) ); m_aUpdateBtn.SetClickHdl( LINK( this, ExtMgrDialog, HandleUpdateBtn ) ); @@ -1608,35 +769,6 @@ ExtMgrDialog::~ExtMgrDialog() } //------------------------------------------------------------------------------ -ResId ExtMgrDialog::getResId( USHORT id ) -{ - const ::vos::OGuard guard( Application::GetSolarMutex() ); - return ResId( id, *DeploymentGuiResMgr::get() ); -} - -//------------------------------------------------------------------------------ -String ExtMgrDialog::getResourceString( USHORT id ) -{ - // init with non-acquired solar mutex: - BrandName::get(); - const ::vos::OGuard guard( Application::GetSolarMutex() ); - String ret( ResId( id, *DeploymentGuiResMgr::get() ) ); - if (ret.SearchAscii( "%PRODUCTNAME" ) != STRING_NOTFOUND) { - ret.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() ); - } - return ret; -} - -//------------------------------------------------------------------------------ -bool ExtMgrDialog::IsSharedPkgMgr( const uno::Reference< deployment::XPackageManager > &xPackageManager ) -{ - if ( xPackageManager->getContext().equals( OUSTR("shared") ) ) - return true; - else - return false; -} - -//------------------------------------------------------------------------------ void ExtMgrDialog::selectEntry( long nPos ) { m_pExtensionBox->selectEntry( nPos ); @@ -1671,96 +803,6 @@ void ExtMgrDialog::checkEntries() } //------------------------------------------------------------------------------ -bool ExtMgrDialog::continueOnSharedExtension( const uno::Reference< deployment::XPackageManager > &xPackageManager, - const USHORT nResID, - bool &bHadWarning ) const -{ - if ( IsSharedPkgMgr( xPackageManager ) && !bHadWarning ) - { - const ::vos::OGuard guard( Application::GetSolarMutex() ); - WarningBox aInfoBox( const_cast< ExtMgrDialog* >(this), getResId( nResID ) ); - String aMsgText = aInfoBox.GetMessText(); - aMsgText.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() ); - aInfoBox.SetMessText( aMsgText ); - - bHadWarning = true; - - if ( RET_OK == aInfoBox.Execute() ) - return true; - else - return false; - } - else - return true; -} - -//------------------------------------------------------------------------------ -void ExtMgrDialog::openWebBrowser( OUString const & sURL ) const -{ - if ( ! sURL.getLength() ) // Nothing to do, when the URL is empty - return; - - try - { - uno::Reference< uno::XComponentContext > xContext = m_pManager->getContext(); - - uno::Reference< XSystemShellExecute > xSystemShellExecute( - xContext->getServiceManager()->createInstanceWithContext( OUSTR( "com.sun.star.system.SystemShellExecute" ), xContext), uno::UNO_QUERY_THROW); - //throws css::lang::IllegalArgumentException, css::system::SystemShellExecuteException - xSystemShellExecute->execute( sURL, OUString(), SystemShellExecuteFlags::DEFAULTS ); - } - catch ( uno::Exception& ) - { - uno::Any exc( ::cppu::getCaughtException() ); - OUString msg( ::comphelper::anyToString( exc ) ); - const ::vos::OGuard guard( Application::GetSolarMutex() ); - ErrorBox aErrorBox( const_cast< ExtMgrDialog* >(this), WB_OK, msg ); - aErrorBox.SetText( GetText() ); - aErrorBox.Execute(); - } -} - -//------------------------------------------------------------------------------ -bool ExtMgrDialog::installForAllUsers( bool &bInstallForAll ) const -{ - const ::vos::OGuard guard( Application::GetSolarMutex() ); - QueryBox aQuery( const_cast< ExtMgrDialog* >(this), getResId( RID_QUERYBOX_INSTALL_FOR_ALL ) ); - - String sMsgText = aQuery.GetMessText(); - sMsgText.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() ); - aQuery.SetMessText( sMsgText ); - - USHORT nYesBtnID = aQuery.GetButtonId( 0 ); - USHORT nNoBtnID = aQuery.GetButtonId( 1 ); - - if ( nYesBtnID != BUTTONDIALOG_BUTTON_NOTFOUND ) - aQuery.SetButtonText( nYesBtnID, getResourceString( RID_STR_INSTALL_FOR_ME ) ); - if ( nNoBtnID != BUTTONDIALOG_BUTTON_NOTFOUND ) - aQuery.SetButtonText( nNoBtnID, getResourceString( RID_STR_INSTALL_FOR_ALL ) ); - - short nRet = aQuery.Execute(); - - if ( nRet == RET_CANCEL ) - return false; - - bInstallForAll = ( nRet == RET_NO ); - return true; -} - -//------------------------------------------------------------------------------ -bool ExtMgrDialog::installExtensionWarn( const OUString &rExtensionName ) const -{ - const ::vos::OGuard guard( Application::GetSolarMutex() ); - WarningBox aInfo( const_cast< ExtMgrDialog* >(this), getResId( RID_WARNINGBOX_INSTALL_EXTENSION ) ); - - String sText( aInfo.GetMessText() ); - sText.SearchAndReplaceAllAscii( "%NAME", rExtensionName ); - aInfo.SetMessText( sText ); - - return ( RET_OK == aInfo.Execute() ); -} - -//------------------------------------------------------------------------------ bool ExtMgrDialog::removeExtensionWarn( const OUString &rExtensionName ) const { const ::vos::OGuard guard( Application::GetSolarMutex() ); @@ -1783,12 +825,12 @@ bool ExtMgrDialog::enablePackage( const uno::Reference< deployment::XPackageMana if ( bEnable ) { - if ( ! continueOnSharedExtension( xPackageManager, RID_WARNINGBOX_ENABLE_SHARED_EXTENSION, m_bEnableWarning ) ) + if ( ! continueOnSharedExtension( xPackageManager, this, RID_WARNINGBOX_ENABLE_SHARED_EXTENSION, m_bEnableWarning ) ) return false; } else { - if ( ! continueOnSharedExtension( xPackageManager, RID_WARNINGBOX_DISABLE_SHARED_EXTENSION, m_bDisableWarning ) ) + if ( ! continueOnSharedExtension( xPackageManager, this, RID_WARNINGBOX_DISABLE_SHARED_EXTENSION, m_bDisableWarning ) ) return false; } @@ -1810,7 +852,7 @@ bool ExtMgrDialog::removePackage( const uno::Reference< deployment::XPackageMana return false; } - if ( ! continueOnSharedExtension( xPackageManager, RID_WARNINGBOX_REMOVE_SHARED_EXTENSION, m_bDeleteWarning ) ) + if ( ! continueOnSharedExtension( xPackageManager, this, RID_WARNINGBOX_REMOVE_SHARED_EXTENSION, m_bDeleteWarning ) ) return false; m_pManager->removePackage( xPackageManager, xPackage ); @@ -1825,7 +867,11 @@ bool ExtMgrDialog::updatePackage( const uno::Reference< deployment::XPackageMana if ( !xPackageManager.is() || !xPackage.is() ) return false; - m_pManager->updatePackage( xPackageManager, xPackage ); + std::vector< TUpdateListEntry > vEntries; + TUpdateListEntry pEntry( new UpdateListEntry( xPackage, xPackageManager ) ); + vEntries.push_back( pEntry ); + + m_pManager->updatePackages( vEntries ); return true; } @@ -1932,7 +978,7 @@ IMPL_LINK( ExtMgrDialog, startProgress, void*, _bLockInterface ) if ( m_aProgressBar.IsVisible() ) m_aProgressBar.SetValue( 100 ); m_xAbortChannel.clear(); -// bLockInterface = false; + OSL_TRACE( " startProgress handler: stop\n" ); } else @@ -1945,7 +991,8 @@ IMPL_LINK( ExtMgrDialog, startProgress, void*, _bLockInterface ) m_aUpdateBtn.Enable( !bLockInterface && m_pExtensionBox->getItemCount() ); m_pExtensionBox->enableButtons( !bLockInterface ); -// pCond->set(); + clearEventID(); + return 0; } @@ -1969,10 +1016,7 @@ void ExtMgrDialog::showProgress( bool _bStart ) OSL_TRACE( "showProgress stop!\n" ); } - Application::PostUserEvent( LINK( this, ExtMgrDialog, startProgress ), (void*) bStart ); -// ::osl::Condition cond; -// Application::PostUserEvent( LINK( this, ExtMgrDialog, startProgress ), &cond ); -// cond.wait(); + DialogHelper::PostUserEvent( LINK( this, ExtMgrDialog, startProgress ), (void*) bStart ); } // ----------------------------------------------------------------------- @@ -2003,7 +1047,7 @@ void ExtMgrDialog::updatePackageInfo( const uno::Reference< deployment::XPackage // ----------------------------------------------------------------------- IMPL_LINK( ExtMgrDialog, HandleAddBtn, void*, EMPTYARG ) { - m_bIsBusy = true; + setBusy( true ); uno::Reference< deployment::XPackageManager > xUserPkgMgr = m_pManager->getUserPkgMgr(); uno::Sequence< OUString > aFileList = raiseAddPicker( xUserPkgMgr ); @@ -2013,7 +1057,7 @@ IMPL_LINK( ExtMgrDialog, HandleAddBtn, void*, EMPTYARG ) m_pManager->installPackage( aFileList[0] ); } - m_bIsBusy = false; + setBusy( false ); return 1; } @@ -2028,7 +1072,7 @@ IMPL_LINK( ExtMgrDialog, HandleUpdateBtn, void*, EMPTYARG ) // ----------------------------------------------------------------------- IMPL_LINK( ExtMgrDialog, HandleHyperlink, svt::FixedHyperlink*, pHyperlink ) { - openWebBrowser( pHyperlink->GetURL() ); + openWebBrowser( pHyperlink->GetURL(), GetText() ); return 1; } @@ -2191,6 +1235,554 @@ BOOL ExtMgrDialog::Close() return bRet; } +//------------------------------------------------------------------------------ +// UpdateRequiredDialog +//------------------------------------------------------------------------------ +UpdateRequiredDialog::UpdateRequiredDialog( Window *pParent, TheExtensionManager *pManager ) : + ModalDialog( pParent, getResId( RID_DLG_UPDATE_REQUIRED ) ), + DialogHelper( pManager->getContext(), (Dialog*) this ), + m_aUpdateNeeded( this, getResId( RID_EM_FT_MSG ) ), + m_aUpdateBtn( this, getResId( RID_EM_BTN_CHECK_UPDATES ) ), + m_aCloseBtn( this, getResId( RID_EM_BTN_CLOSE ) ), + m_aHelpBtn( this, getResId( RID_EM_BTN_HELP ) ), + m_aCancelBtn( this, getResId( RID_EM_BTN_CANCEL ) ), + m_aDivider( this ), + m_aProgressText( this, getResId( RID_EM_FT_PROGRESS ) ), + m_aProgressBar( this, WB_BORDER + WB_3DLOOK ), + m_sAddPackages( getResourceString( RID_STR_ADD_PACKAGES ) ), + m_sCloseText( getResourceString( RID_STR_CLOSE_BTN ) ), + m_bHasProgress( false ), + m_bProgressChanged( false ), + m_bStartProgress( false ), + m_bStopProgress( false ), + m_bUpdateWarning( false ), + m_bDisableWarning( false ), + m_bHasLockedEntries( false ), + m_nProgress( 0 ), + m_pManager( pManager ) +{ + // free local resources (RID < 256): + FreeResource(); + + m_pExtensionBox = new ExtensionBox_Impl( this, pManager ); + m_pExtensionBox->SetHyperlinkHdl( LINK( this, UpdateRequiredDialog, HandleHyperlink ) ); + + m_aUpdateBtn.SetClickHdl( LINK( this, UpdateRequiredDialog, HandleUpdateBtn ) ); + m_aCloseBtn.SetClickHdl( LINK( this, UpdateRequiredDialog, HandleCloseBtn ) ); + m_aCancelBtn.SetClickHdl( LINK( this, UpdateRequiredDialog, HandleCancelBtn ) ); + + String aText = m_aUpdateNeeded.GetText(); + aText.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() ); + m_aUpdateNeeded.SetText( aText ); + + // resize update button + Size aBtnSize = m_aUpdateBtn.GetSizePixel(); + String sTitle = m_aUpdateBtn.GetText(); + long nWidth = m_aUpdateBtn.GetCtrlTextWidth( sTitle ); + nWidth += 2 * m_aUpdateBtn.GetTextHeight(); + if ( nWidth > aBtnSize.Width() ) + m_aUpdateBtn.SetSizePixel( Size( nWidth, aBtnSize.Height() ) ); + + // resize update button + aBtnSize = m_aCloseBtn.GetSizePixel(); + sTitle = m_aCloseBtn.GetText(); + nWidth = m_aCloseBtn.GetCtrlTextWidth( sTitle ); + nWidth += 2 * m_aCloseBtn.GetTextHeight(); + if ( nWidth > aBtnSize.Width() ) + m_aCloseBtn.SetSizePixel( Size( nWidth, aBtnSize.Height() ) ); + + // minimum size: + SetMinOutputSizePixel( + Size( // width: + (5 * m_aHelpBtn.GetSizePixel().Width()) + + (5 * RSC_SP_DLG_INNERBORDER_LEFT ), + // height: + (1 * m_aHelpBtn.GetSizePixel().Height()) + + (1 * m_aUpdateNeeded.GetSizePixel().Height()) + + (1 * m_pExtensionBox->GetMinOutputSizePixel().Height()) + + (3 * RSC_SP_DLG_INNERBORDER_LEFT) ) ); + + m_aDivider.Show(); + m_aProgressBar.Hide(); + m_aUpdateBtn.Enable( false ); + m_aCloseBtn.GrabFocus(); + + m_aTimeoutTimer.SetTimeout( 50 ); // mSec + m_aTimeoutTimer.SetTimeoutHdl( LINK( this, UpdateRequiredDialog, TimeOutHdl ) ); +} + +//------------------------------------------------------------------------------ +UpdateRequiredDialog::~UpdateRequiredDialog() +{ + m_aTimeoutTimer.Stop(); + + delete m_pExtensionBox; +} + +//------------------------------------------------------------------------------ +long UpdateRequiredDialog::addPackageToList( const uno::Reference< deployment::XPackage > &xPackage, + const uno::Reference< deployment::XPackageManager > &xPackageManager ) +{ + // We will only add entries to the list with unsatisfied dependencies + if ( !checkDependencies( xPackage ) ) + { + m_bHasLockedEntries |= (bool) xPackageManager->isReadOnly(); + m_aUpdateBtn.Enable( true ); + return m_pExtensionBox->addEntry( xPackage, xPackageManager ); + } + return 0; +} + +//------------------------------------------------------------------------------ +void UpdateRequiredDialog::prepareChecking( const uno::Reference< deployment::XPackageManager > &xPackageManager ) +{ + if ( xPackageManager.is() ) + m_pExtensionBox->prepareChecking( xPackageManager ); +} + +//------------------------------------------------------------------------------ +void UpdateRequiredDialog::checkEntries() +{ + const ::vos::OGuard guard( Application::GetSolarMutex() ); + m_pExtensionBox->checkEntries(); + + if ( ! hasActiveEntries() ) + { + m_aCloseBtn.SetText( m_sCloseText ); + m_aCloseBtn.GrabFocus(); + } +} + +//------------------------------------------------------------------------------ +bool UpdateRequiredDialog::enablePackage( const uno::Reference< deployment::XPackageManager > &, + const uno::Reference< deployment::XPackage > &xPackage, + bool bEnable ) +{ + m_pManager->enablePackage( xPackage, bEnable ); + + return true; +} + +//------------------------------------------------------------------------------ +IMPL_LINK( UpdateRequiredDialog, HandleCancelBtn, void*, EMPTYARG ) +{ + // m_dialog->m_cmdEnv->m_aborted = true; + if ( m_xAbortChannel.is() ) + { + try + { + m_xAbortChannel->sendAbort(); + } + catch ( uno::RuntimeException & ) + { + OSL_ENSURE( 0, "### unexpected RuntimeException!" ); + } + } + return 1; +} + +// ------------------------------------------------------------------------------ +IMPL_LINK( UpdateRequiredDialog, startProgress, void*, _bLockInterface ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + bool bLockInterface = (bool) _bLockInterface; + + if ( m_bStartProgress && !m_bHasProgress ) + m_aTimeoutTimer.Start(); + + if ( m_bStopProgress ) + { + if ( m_aProgressBar.IsVisible() ) + m_aProgressBar.SetValue( 100 ); + m_xAbortChannel.clear(); + OSL_TRACE( " startProgress handler: stop\n" ); + } + else + { + OSL_TRACE( " startProgress handler: start\n" ); + } + + m_aCancelBtn.Enable( bLockInterface ); + m_aUpdateBtn.Enable( false ); + clearEventID(); + + return 0; +} + +// ------------------------------------------------------------------------------ +void UpdateRequiredDialog::showProgress( bool _bStart ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + bool bStart = _bStart; + + if ( bStart ) + { + m_nProgress = 0; + m_bStartProgress = true; + OSL_TRACE( "showProgress start\n" ); + } + else + { + m_nProgress = 100; + m_bStopProgress = true; + OSL_TRACE( "showProgress stop!\n" ); + } + + DialogHelper::PostUserEvent( LINK( this, UpdateRequiredDialog, startProgress ), (void*) bStart ); +} + +// ----------------------------------------------------------------------- +void UpdateRequiredDialog::updateProgress( const long nProgress ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + m_nProgress = nProgress; +} + +// ----------------------------------------------------------------------- +void UpdateRequiredDialog::updateProgress( const OUString &rText, + const uno::Reference< task::XAbortChannel > &xAbortChannel) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + m_xAbortChannel = xAbortChannel; + m_sProgressText = rText; + m_bProgressChanged = true; +} + +//------------------------------------------------------------------------------ +void UpdateRequiredDialog::updatePackageInfo( const uno::Reference< deployment::XPackage > &xPackage ) +{ + // We will remove all updated packages with satisfied dependencies, but + // we will show all disabled entries so the user sees the result + // of the 'disable all' button + if ( isEnabled( xPackage ) && checkDependencies( xPackage ) ) + m_pExtensionBox->removeEntry( xPackage ); + else + m_pExtensionBox->updateEntry( xPackage ); + + if ( ! hasActiveEntries() ) + { + m_aCloseBtn.SetText( m_sCloseText ); + m_aCloseBtn.GrabFocus(); + } +} + +// ----------------------------------------------------------------------- +IMPL_LINK( UpdateRequiredDialog, HandleUpdateBtn, void*, EMPTYARG ) +{ + ::osl::ClearableMutexGuard aGuard( m_aMutex ); + + std::vector< TUpdateListEntry > vUpdateEntries; + sal_Int32 nCount = m_pExtensionBox->GetEntryCount(); + + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + TEntry_Impl pEntry = m_pExtensionBox->GetEntryData( i ); + TUpdateListEntry pUpdateEntry( new UpdateListEntry( pEntry->m_xPackage, + pEntry->m_xPackageManager ) ); + vUpdateEntries.push_back( pUpdateEntry ); + } + + aGuard.clear(); + + m_pManager->updatePackages( vUpdateEntries ); + + return 1; +} + +// ----------------------------------------------------------------------- +IMPL_LINK( UpdateRequiredDialog, HandleCloseBtn, void*, EMPTYARG ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !isBusy() ) + { + if ( m_bHasLockedEntries ) + EndDialog( -1 ); + else if ( hasActiveEntries() ) + disableAllEntries(); + else + EndDialog( 0 ); + } + + return 1; +} + +// ----------------------------------------------------------------------- +IMPL_LINK( UpdateRequiredDialog, HandleHyperlink, svt::FixedHyperlink*, pHyperlink ) +{ + openWebBrowser( pHyperlink->GetURL(), GetText() ); + + return 1; +} + +// ----------------------------------------------------------------------- +IMPL_LINK( UpdateRequiredDialog, TimeOutHdl, Timer*, EMPTYARG ) +{ + if ( m_bStopProgress ) + { + m_bHasProgress = false; + m_bStopProgress = false; + m_aProgressText.Hide(); + m_aProgressBar.Hide(); + m_aCancelBtn.Hide(); + } + else + { + if ( m_bProgressChanged ) + { + m_bProgressChanged = false; + m_aProgressText.SetText( m_sProgressText ); + } + + if ( m_bStartProgress ) + { + m_bStartProgress = false; + m_bHasProgress = true; + m_aProgressBar.Show(); + m_aProgressText.Show(); + m_aCancelBtn.Enable(); + m_aCancelBtn.Show(); + } + + if ( m_aProgressBar.IsVisible() ) + m_aProgressBar.SetValue( (USHORT) m_nProgress ); + + m_aTimeoutTimer.Start(); + } + + return 1; +} + +//------------------------------------------------------------------------------ +// VCL::Window / Dialog +void UpdateRequiredDialog::Resize() +{ + Size aTotalSize( GetOutputSizePixel() ); + Size aBtnSize( m_aHelpBtn.GetSizePixel() ); + + Point aPos( RSC_SP_DLG_INNERBORDER_LEFT, + aTotalSize.Height() - RSC_SP_DLG_INNERBORDER_BOTTOM - aBtnSize.Height() ); + + m_aHelpBtn.SetPosPixel( aPos ); + + aPos.X() = aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_RIGHT - m_aCloseBtn.GetSizePixel().Width(); + m_aCloseBtn.SetPosPixel( aPos ); + + aPos.X() -= ( RSC_SP_CTRL_X + m_aUpdateBtn.GetSizePixel().Width() ); + m_aUpdateBtn.SetPosPixel( aPos ); + + Size aDivSize( aTotalSize.Width(), LINE_SIZE ); + aPos = Point( 0, aPos.Y() - LINE_SIZE - RSC_SP_DLG_INNERBORDER_BOTTOM ); + m_aDivider.SetPosSizePixel( aPos, aDivSize ); + + // Calc fixed text size + aPos = Point( RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP ); + Size aFTSize = m_aUpdateNeeded.CalcMinimumSize( aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_RIGHT - RSC_SP_DLG_INNERBORDER_LEFT ); + m_aUpdateNeeded.SetPosSizePixel( aPos, aFTSize ); + + // Calc list box size + Size aSize( aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_LEFT - RSC_SP_DLG_INNERBORDER_RIGHT, + aTotalSize.Height() - 2*aBtnSize.Height() - LINE_SIZE - + 2*RSC_SP_DLG_INNERBORDER_TOP - 3*RSC_SP_DLG_INNERBORDER_BOTTOM - aFTSize.Height() ); + aPos.Y() += aFTSize.Height()+RSC_SP_DLG_INNERBORDER_TOP; + + m_pExtensionBox->SetPosSizePixel( aPos, aSize ); + + aPos.X() = aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_RIGHT - aBtnSize.Width(); + aPos.Y() += aSize.Height()+RSC_SP_DLG_INNERBORDER_TOP; + m_aCancelBtn.SetPosPixel( aPos ); + + // Calc progress height + aFTSize = m_aProgressText.GetSizePixel(); + long nProgressHeight = aFTSize.Height(); + + if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) ) + { + ImplControlValue aValue; + bool bNativeOK; + Region aControlRegion( Rectangle( (const Point&)Point(), m_aProgressBar.GetSizePixel() ) ); + Region aNativeControlRegion, aNativeContentRegion; + if( (bNativeOK = GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion, + CTRL_STATE_ENABLED, aValue, rtl::OUString(), + aNativeControlRegion, aNativeContentRegion ) ) != FALSE ) + { + nProgressHeight = aNativeControlRegion.GetBoundRect().GetHeight(); + } + } + + if ( nProgressHeight < PROGRESS_HEIGHT ) + nProgressHeight = PROGRESS_HEIGHT; + + aPos.X() -= ( RSC_SP_CTRL_GROUP_Y + PROGRESS_WIDTH ); + m_aProgressBar.SetPosSizePixel( Point( aPos.X(), aPos.Y() + ((aBtnSize.Height()-nProgressHeight)/2) ), + Size( PROGRESS_WIDTH, nProgressHeight ) ); + + aFTSize.Width() = aPos.X() - 2*RSC_SP_DLG_INNERBORDER_LEFT; + aPos.X() = RSC_SP_DLG_INNERBORDER_LEFT; + aPos.Y() += ( aBtnSize.Height() - aFTSize.Height() - 1 ) / 2; + m_aProgressText.SetPosSizePixel( aPos, aFTSize ); +} + +//------------------------------------------------------------------------------ +// VCL::Dialog +short UpdateRequiredDialog::Execute() +{ + if ( m_bHasLockedEntries ) + { + // Set other text, disable update btn, remove not shared entries from list; + m_aUpdateNeeded.SetText( DialogHelper::getResourceString( RID_STR_NO_ADMIN_PRIVILEGE ) ); + m_aCloseBtn.SetText( DialogHelper::getResourceString( RID_STR_EXIT_BTN ) ); + m_aUpdateBtn.Enable( false ); + m_pExtensionBox->RemoveUnlocked(); + Resize(); + } + + return Dialog::Execute(); +} + +//------------------------------------------------------------------------------ +// VCL::Dialog +BOOL UpdateRequiredDialog::Close() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !isBusy() ) + { + if ( m_bHasLockedEntries ) + EndDialog( -1 ); + else if ( hasActiveEntries() ) + disableAllEntries(); + else + EndDialog( 0 ); + } + + return false; +} + +//------------------------------------------------------------------------------ +// Check dependencies of all packages +//------------------------------------------------------------------------------ +bool UpdateRequiredDialog::isEnabled( const uno::Reference< deployment::XPackage > &xPackage ) const +{ + 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() ); + bRegistered = false; + } + + return bRegistered; +} + +//------------------------------------------------------------------------------ +bool UpdateRequiredDialog::checkDependencies( const uno::Reference< deployment::XPackage > &xPackage ) const +{ + if ( isEnabled( xPackage ) ) + { + bool bDependenciesValid = false; + try { + bDependenciesValid = xPackage->checkDependencies( uno::Reference< ucb::XCommandEnvironment >() ); + } + catch ( deployment::DeploymentException & ) {} + if ( ! bDependenciesValid ) + { + return false; + } + } + return true; +} + +//------------------------------------------------------------------------------ +bool UpdateRequiredDialog::hasActiveEntries() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + bool bRet = false; + long nCount = m_pExtensionBox->GetEntryCount(); + for ( long nIndex = 0; nIndex < nCount; nIndex++ ) + { + TEntry_Impl pEntry = m_pExtensionBox->GetEntryData( nIndex ); + + if ( !checkDependencies( pEntry->m_xPackage ) ) + { + bRet = true; + break; + } + } + + return bRet; +} + +//------------------------------------------------------------------------------ +void UpdateRequiredDialog::disableAllEntries() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + setBusy( true ); + + long nCount = m_pExtensionBox->GetEntryCount(); + for ( long nIndex = 0; nIndex < nCount; nIndex++ ) + { + TEntry_Impl pEntry = m_pExtensionBox->GetEntryData( nIndex ); + enablePackage( pEntry->m_xPackageManager, pEntry->m_xPackage, false ); + } + + setBusy( false ); + + if ( ! hasActiveEntries() ) + m_aCloseBtn.SetText( m_sCloseText ); +} + +//================================================================================= +// UpdateRequiredDialogService +//================================================================================= +UpdateRequiredDialogService::UpdateRequiredDialogService( uno::Sequence< uno::Any > const&, + uno::Reference< uno::XComponentContext > const& xComponentContext ) + : m_xComponentContext( xComponentContext ) +{ +} + +//------------------------------------------------------------------------------ +// XExecutableDialog +//------------------------------------------------------------------------------ +void UpdateRequiredDialogService::setTitle( OUString const & ) throw ( uno::RuntimeException ) +{ +} + +//------------------------------------------------------------------------------ +sal_Int16 UpdateRequiredDialogService::execute() throw ( uno::RuntimeException ) +{ + ::rtl::Reference< ::dp_gui::TheExtensionManager > xManager( TheExtensionManager::get( + m_xComponentContext, + uno::Reference< awt::XWindow >(), + OUString() ) ); + xManager->createDialog( true ); + sal_Int16 nRet = xManager->execute(); + + return nRet; +} + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ SelectedPackage::~SelectedPackage() {} } //namespace dp_gui diff --git a/desktop/source/deployment/gui/dp_gui_dialog2.hxx b/desktop/source/deployment/gui/dp_gui_dialog2.hxx index bab8d52828a9..7536aa403cfe 100644 --- a/desktop/source/deployment/gui/dp_gui_dialog2.hxx +++ b/desktop/source/deployment/gui/dp_gui_dialog2.hxx @@ -46,20 +46,71 @@ #include "rtl/ref.hxx" #include "rtl/ustring.hxx" +#include "cppuhelper/implbase1.hxx" + +#include "com/sun/star/awt/XWindow.hpp" #include "com/sun/star/deployment/XPackage.hpp" #include "com/sun/star/deployment/XPackageManager.hpp" +#include "com/sun/star/uno/XComponentContext.hpp" +#include "com/sun/star/ui/dialogs/XExecutableDialog.hpp" #include "com/sun/star/util/XModifyListener.hpp" namespace dp_gui { //============================================================================== +class ExtBoxWithBtns_Impl; class ExtensionBox_Impl; class TheExtensionManager; //============================================================================== -class ExtMgrDialog : public ModelessDialog +class DialogHelper { - ExtensionBox_Impl *m_pExtensionBox; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext; + Dialog* m_pVCLWindow; + ULONG m_nEventID; + bool m_bIsBusy; + +public: + DialogHelper( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > &, + Dialog *pWindow ); + virtual ~DialogHelper(); + + void openWebBrowser( const ::rtl::OUString & sURL, const ::rtl::OUString & sTitle ) const; + Dialog* getWindow() const { return m_pVCLWindow; }; + void PostUserEvent( const Link& rLink, void* pCaller ); + void clearEventID() { m_nEventID = 0; } + + virtual void showProgress( bool bStart ) = 0; + virtual void updateProgress( const ::rtl::OUString &rText, + const ::com::sun::star::uno::Reference< ::com::sun::star::task::XAbortChannel > &xAbortChannel) = 0; + virtual void updateProgress( const long nProgress ) = 0; + + virtual void updatePackageInfo( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) = 0; + virtual long addPackageToList( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &, + const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > & ) = 0; + + virtual void prepareChecking( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager ) = 0; + virtual void checkEntries() = 0; + + static ResId getResId( USHORT nId ); + static String getResourceString( USHORT id ); + static bool IsSharedPkgMgr( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &); + static bool continueOnSharedExtension( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &, + Window *pParent, + const USHORT nResID, + bool &bHadWarning ); + + void setBusy( const bool bBusy ) { m_bIsBusy = bBusy; } + bool isBusy() const { return m_bIsBusy; } + bool installExtensionWarn( const ::rtl::OUString &rExtensionURL ) const; + bool installForAllUsers( bool &bInstallForAll ) const; +}; + +//============================================================================== +class ExtMgrDialog : public ModelessDialog, + public DialogHelper +{ + ExtBoxWithBtns_Impl *m_pExtensionBox; PushButton m_aAddBtn; PushButton m_aUpdateBtn; OKButton m_aCloseBtn; @@ -81,16 +132,12 @@ class ExtMgrDialog : public ModelessDialog bool m_bEnableWarning; bool m_bDisableWarning; bool m_bDeleteWarning; - bool m_bIsBusy; long m_nProgress; Timer m_aTimeoutTimer; TheExtensionManager *m_pManager; ::com::sun::star::uno::Reference< ::com::sun::star::task::XAbortChannel > m_xAbortChannel; - bool continueOnSharedExtension( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &, - const USHORT nResID, - bool &bHadWarning ) const; bool removeExtensionWarn( const ::rtl::OUString &rExtensionTitle ) const; DECL_DLLPRIVATE_LINK( HandleAddBtn, void * ); @@ -108,9 +155,16 @@ public: virtual long Notify( NotifyEvent& rNEvt ); virtual BOOL Close(); + virtual void showProgress( bool bStart ); + virtual void updateProgress( const ::rtl::OUString &rText, + const ::com::sun::star::uno::Reference< ::com::sun::star::task::XAbortChannel > &xAbortChannel); + virtual void updateProgress( const long nProgress ); + + virtual void updatePackageInfo( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ); + void setGetExtensionsURL( const ::rtl::OUString &rURL ); void selectEntry( long nPos ); - long addPackageToList( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &, + virtual long addPackageToList( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &, const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > & ); bool enablePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager, const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage, @@ -120,27 +174,102 @@ public: bool updatePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager, const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ); - bool isBusy() { return m_bIsBusy; } + virtual void prepareChecking( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager ); + virtual void checkEntries(); + + ::com::sun::star::uno::Sequence< ::rtl::OUString > raiseAddPicker( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager ); +}; + +//============================================================================== +class UpdateRequiredDialog : public ModalDialog, + public DialogHelper +{ + ExtensionBox_Impl *m_pExtensionBox; + FixedText m_aUpdateNeeded; + PushButton m_aUpdateBtn; + PushButton m_aCloseBtn; + HelpButton m_aHelpBtn; + CancelButton m_aCancelBtn; + FixedLine m_aDivider; + FixedText m_aProgressText; + ProgressBar m_aProgressBar; + const String m_sAddPackages; + const String m_sCloseText; + String m_sProgressText; + ::osl::Mutex m_aMutex; + bool m_bHasProgress; + bool m_bProgressChanged; + bool m_bStartProgress; + bool m_bStopProgress; + bool m_bUpdateWarning; + bool m_bDisableWarning; + bool m_bHasLockedEntries; + long m_nProgress; + Timer m_aTimeoutTimer; + TheExtensionManager *m_pManager; + + ::com::sun::star::uno::Reference< ::com::sun::star::task::XAbortChannel > m_xAbortChannel; + + DECL_DLLPRIVATE_LINK( HandleUpdateBtn, void * ); + DECL_DLLPRIVATE_LINK( HandleCloseBtn, void * ); + DECL_DLLPRIVATE_LINK( HandleCancelBtn, void * ); + DECL_DLLPRIVATE_LINK( TimeOutHdl, Timer* ); + DECL_DLLPRIVATE_LINK( startProgress, void * ); + DECL_DLLPRIVATE_LINK( HandleHyperlink, svt::FixedHyperlink * ); - void showProgress( bool bStart ); - void updateProgress( const ::rtl::OUString &rText, + bool isEnabled( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) const; + bool checkDependencies( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) const; + bool hasActiveEntries(); + void disableAllEntries(); + +public: + UpdateRequiredDialog( Window * pParent, TheExtensionManager *pManager ); + virtual ~UpdateRequiredDialog(); + + virtual short Execute(); + virtual void Resize(); + virtual BOOL Close(); +// virtual long Notify( NotifyEvent& rNEvt ); + + virtual void showProgress( bool bStart ); + virtual void updateProgress( const ::rtl::OUString &rText, const ::com::sun::star::uno::Reference< ::com::sun::star::task::XAbortChannel > &xAbortChannel); - void updateProgress( const long nProgress ); - void updatePackageInfo( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ); + virtual void updateProgress( const long nProgress ); - void prepareChecking( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager ); - void checkEntries(); + virtual void updatePackageInfo( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ); - ::com::sun::star::uno::Sequence< ::rtl::OUString > raiseAddPicker( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager ); + void selectEntry( long nPos ); + virtual long addPackageToList( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &, + const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > & ); + bool enablePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager, + const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage, + bool bEnable ); + bool updatePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager, + const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ); - void openWebBrowser( ::rtl::OUString const &sURL ) const; + virtual void prepareChecking( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager ); + virtual void checkEntries(); + + ::com::sun::star::uno::Sequence< ::rtl::OUString > raiseAddPicker( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager ); bool installForAllUsers( bool &bInstallForAll ) const; bool installExtensionWarn( const ::rtl::OUString &rExtensionURL ) const; +}; - static ResId getResId( USHORT id ); - static String getResourceString( USHORT id ); - static bool IsSharedPkgMgr( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &); +//============================================================================== +class UpdateRequiredDialogService : public ::cppu::WeakImplHelper1< ::com::sun::star::ui::dialogs::XExecutableDialog > +{ + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const m_xComponentContext; + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > m_xParent; + ::rtl::OUString m_sInitialTitle; + +public: + UpdateRequiredDialogService( ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > const & args, + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext> const & xComponentContext ); + + // XExecutableDialog + virtual void SAL_CALL setTitle( rtl::OUString const & title ) throw ( ::com::sun::star::uno::RuntimeException ); + virtual sal_Int16 SAL_CALL execute() throw ( ::com::sun::star::uno::RuntimeException ); }; } // namespace dp_gui diff --git a/desktop/source/deployment/gui/dp_gui_dialog2.src b/desktop/source/deployment/gui/dp_gui_dialog2.src index e82e8c762a9e..0ca9f9e74362 100644 --- a/desktop/source/deployment/gui/dp_gui_dialog2.src +++ b/desktop/source/deployment/gui/dp_gui_dialog2.src @@ -97,6 +97,66 @@ ModelessDialog RID_DLG_EXTENSION_MANAGER }; }; +ModalDialog RID_DLG_UPDATE_REQUIRED +{ + HelpId = HID_PACKAGE_MANAGER_UPD_REQ; + Text [ en-US ] = "Extension Update Required"; + + Size = MAP_APPFONT( 300, 200 ); + OutputSize = TRUE; + SVLook = TRUE; + Moveable = TRUE; + Closeable = TRUE; + Sizeable = TRUE; + Hide = TRUE; + + FixedText RID_EM_FT_MSG + { + Text [ en-US ] = "%PRODUCTNAME has been updated to a new version. Some installed %PRODUCTNAME extensions are not compatible with this version and need to be updated before they can be used."; + WordBreak = TRUE; + NoLabel = TRUE; + Size = MAP_APPFONT( 280, 3*RSC_BS_CHARHEIGHT ); + Pos = MAP_APPFONT( 5, 5 ); + }; + + FixedText RID_EM_FT_PROGRESS + { + Hide = TRUE; + Right = TRUE; + Text [ en-US ] = "Adding %EXTENSION_NAME"; + Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT ); + }; + + HelpButton RID_EM_BTN_HELP + { + TabStop = TRUE; + Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ); + }; + + PushButton RID_EM_BTN_CHECK_UPDATES + { + TabStop = TRUE; + Text [ en-US ] = "Check for ~Updates..."; + Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ); + }; + + PushButton RID_EM_BTN_CLOSE + { + TabStop = TRUE; + DefButton = TRUE; + Text [ en-US ] = "Disable all"; + Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ); + }; + + CancelButton RID_EM_BTN_CANCEL + { + TabStop = TRUE; + Hide = TRUE; + Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ); + }; + +}; + Image RID_IMG_WARNING { ImageBitmap = Bitmap { File = "caution_16.png"; }; diff --git a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx index 5a247729082d..889fdc04c9e1 100644 --- a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx +++ b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx @@ -136,7 +136,7 @@ class ProgressCmdEnv uno::Reference< uno::XComponentContext > m_xContext; uno::Reference< task::XAbortChannel> m_xAbortChannel; - ExtMgrDialog *m_pDialog; + DialogHelper *m_pDialogHelper; OUString m_sTitle; bool m_bAborted; bool m_bWarnUser; @@ -157,16 +157,16 @@ public: */ ProgressCmdEnv( const uno::Reference< uno::XComponentContext > rContext, - ExtMgrDialog *pDialog, + DialogHelper *pDialogHelper, const OUString &rTitle ) : m_xContext( rContext ), - m_pDialog( pDialog ), + m_pDialogHelper( pDialogHelper ), m_sTitle( rTitle ), m_bAborted( false ), m_bWarnUser( false ) {} - Dialog * activeDialog() { return m_pDialog; } + Dialog * activeDialog() { return m_pDialogHelper->getWindow(); } void setTitle( const OUString& rNewTitle ) { m_sTitle = rNewTitle; } void startProgress(); @@ -197,14 +197,14 @@ public: //------------------------------------------------------------------------------ struct ExtensionCmd { - enum E_CMD_TYPE { ADD, ENABLE, DISABLE, REMOVE, CHECK_FOR_UPDATE, CHECK_FOR_UPDATES }; + enum E_CMD_TYPE { ADD, ENABLE, DISABLE, REMOVE, CHECK_FOR_UPDATES }; E_CMD_TYPE m_eCmdType; bool m_bWarnUser; OUString m_sExtensionURL; uno::Reference< deployment::XPackageManager > m_xPackageManager; uno::Reference< deployment::XPackage > m_xPackage; - uno::Sequence< uno::Reference< deployment::XPackageManager > > m_xPackageManagers; + std::vector< TUpdateListEntry > m_vExtensionList; ExtensionCmd( const E_CMD_TYPE eCommand, const uno::Reference< deployment::XPackageManager > &rPackageManager, @@ -227,10 +227,10 @@ struct ExtensionCmd m_bWarnUser( false ), m_xPackage( rPackage ) {}; ExtensionCmd( const E_CMD_TYPE eCommand, - const uno::Sequence< uno::Reference< deployment::XPackageManager > > &rPackageManagers ) + const std::vector< TUpdateListEntry > &vExtensionList ) : m_eCmdType( eCommand ), m_bWarnUser( false ), - m_xPackageManagers( rPackageManagers ) {}; + m_vExtensionList( vExtensionList ) {}; }; typedef ::boost::shared_ptr< ExtensionCmd > TExtensionCmd; @@ -239,7 +239,7 @@ typedef ::boost::shared_ptr< ExtensionCmd > TExtensionCmd; class ExtensionCmdQueue::Thread: public dp_gui::Thread { public: - Thread( ExtMgrDialog *pDialog, + Thread( DialogHelper *pDialogHelper, TheExtensionManager *pManager, const uno::Reference< uno::XComponentContext > & rContext ); @@ -250,9 +250,7 @@ public: const uno::Reference< deployment::XPackage > &rPackage ); void enableExtension( const uno::Reference< deployment::XPackage > &rPackage, const bool bEnable ); - void checkForUpdates( const uno::Sequence< uno::Reference< deployment::XPackageManager > > &rPackageManagers ); - void checkForUpdate( const uno::Reference< deployment::XPackageManager > &rPackageManager, - const uno::Reference< deployment::XPackage > &rPackage ); + void checkForUpdates( const std::vector< TUpdateListEntry > &vExtensionList ); void stop(); bool hasTerminated(); bool isBusy(); @@ -280,16 +278,14 @@ private: const uno::Reference< deployment::XPackage > &xPackage ); void _disableExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv, const uno::Reference< deployment::XPackage > &xPackage ); - void _checkForUpdates( const uno::Sequence< uno::Reference< deployment::XPackageManager > > &rPackageManagers, - const uno::Reference< deployment::XPackageManager > &xPackageManager, - const uno::Reference< deployment::XPackage > &xPackage ); + void _checkForUpdates( const std::vector< TUpdateListEntry > &vExtensionList ); enum Input { NONE, START, STOP }; uno::Reference< uno::XComponentContext > m_xContext; std::queue< TExtensionCmd > m_queue; - ExtMgrDialog *m_pDialog; + DialogHelper *m_pDialogHelper; TheExtensionManager *m_pManager; const OUString m_sEnablingPackages; @@ -310,13 +306,15 @@ void ProgressCmdEnv::startProgress() { m_nCurrentProgress = 0; - m_pDialog->showProgress( true ); + if ( m_pDialogHelper ) + m_pDialogHelper->showProgress( true ); } //------------------------------------------------------------------------------ void ProgressCmdEnv::stopProgress() { - m_pDialog->showProgress( false ); + if ( m_pDialogHelper ) + m_pDialogHelper->showProgress( false ); } //------------------------------------------------------------------------------ @@ -327,8 +325,11 @@ void ProgressCmdEnv::progressSection( const OUString &rText, if (! m_bAborted) { m_nCurrentProgress = 0; - m_pDialog->updateProgress( rText, xAbortChannel ); - m_pDialog->updateProgress( 5 ); + if ( m_pDialogHelper ) + { + m_pDialogHelper->updateProgress( rText, xAbortChannel ); + m_pDialogHelper->updateProgress( 5 ); + } } } @@ -338,7 +339,8 @@ void ProgressCmdEnv::updateProgress() if ( ! m_bAborted ) { long nProgress = ((m_nCurrentProgress*5) % 100) + 5; - m_pDialog->updateProgress( nProgress ); + if ( m_pDialogHelper ) + m_pDialogHelper->updateProgress( nProgress ); } } @@ -434,7 +436,7 @@ void ProgressCmdEnv::handle( uno::Reference< task::XInteractionRequest > const & } { vos::OGuard guard(Application::GetSolarMutex()); - short n = DependencyDialog( m_pDialog, deps ).Execute(); + short n = DependencyDialog( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, deps ).Execute(); // Distinguish between closing the dialog and programatically // canceling the dialog (headless VCL): approve = n == RET_OK @@ -445,19 +447,19 @@ void ProgressCmdEnv::handle( uno::Reference< task::XInteractionRequest > const & { vos::OGuard aSolarGuard( Application::GetSolarMutex() ); ResId warnId(WARNINGBOX_NOSHAREDALLOWED, *DeploymentGuiResMgr::get()); - WarningBox warn( m_pDialog, warnId); + WarningBox warn( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, warnId); String msgText = warn.GetMessText(); msgText.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() ); msgText.SearchAndReplaceAllAscii("%NAME", licAgreementExc.ExtensionName); warn.SetMessText(msgText); warn.Execute(); - abort = true; + abort = true; } else if (request >>= licExc) { uno::Reference< ui::dialogs::XExecutableDialog > xDialog( deployment::ui::LicenseDialog::create( - m_xContext, VCLUnoHelper::GetInterface( m_pDialog ), licExc.Text ) ); + m_xContext, VCLUnoHelper::GetInterface( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL ), licExc.Text ) ); sal_Int16 res = xDialog->execute(); if ( res == ui::dialogs::ExecutableDialogResults::CANCEL ) abort = true; @@ -488,7 +490,7 @@ void ProgressCmdEnv::handle( uno::Reference< task::XInteractionRequest > const & verExc.Deployed->getDisplayName()); { vos::OGuard guard(Application::GetSolarMutex()); - WarningBox box( m_pDialog, ResId(id, *DeploymentGuiResMgr::get())); + WarningBox box( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, ResId(id, *DeploymentGuiResMgr::get())); String s; if (bEqualNames) { @@ -526,9 +528,14 @@ void ProgressCmdEnv::handle( uno::Reference< task::XInteractionRequest > const & } else { - vos::OGuard guard(Application::GetSolarMutex()); + if ( m_pDialogHelper ) + { + vos::OGuard guard(Application::GetSolarMutex()); - approve = m_pDialog->installExtensionWarn( instExc.New->getDisplayName() ); + approve = m_pDialogHelper->installExtensionWarn( instExc.New->getDisplayName() ); + } + else + approve = false; abort = !approve; } } @@ -537,7 +544,7 @@ void ProgressCmdEnv::handle( uno::Reference< task::XInteractionRequest > const & vos::OGuard guard( Application::GetSolarMutex() ); String sMsg( ResId( RID_STR_UNSUPPORTED_PLATFORM, *DeploymentGuiResMgr::get() ) ); sMsg.SearchAndReplaceAllAscii( "%Name", platExc.package->getDisplayName() ); - ErrorBox box( m_pDialog, WB_OK, sMsg ); + ErrorBox box( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, WB_OK, sMsg ); box.Execute(); approve = true; } @@ -609,7 +616,7 @@ void ProgressCmdEnv::update_( uno::Any const & rStatus ) text = ::comphelper::anyToString( rStatus ); // fallback const ::vos::OGuard aGuard( Application::GetSolarMutex() ); - const ::std::auto_ptr< ErrorBox > aBox( new ErrorBox( m_pDialog, WB_OK, text ) ); + const ::std::auto_ptr< ErrorBox > aBox( new ErrorBox( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, WB_OK, text ) ); aBox->Execute(); } ++m_nCurrentProgress; @@ -631,23 +638,23 @@ void ProgressCmdEnv::pop() } //------------------------------------------------------------------------------ -ExtensionCmdQueue::Thread::Thread( ExtMgrDialog *pDialog, +ExtensionCmdQueue::Thread::Thread( DialogHelper *pDialogHelper, TheExtensionManager *pManager, const uno::Reference< uno::XComponentContext > & rContext ) : m_xContext( rContext ), - m_pDialog( pDialog ), + m_pDialogHelper( pDialogHelper ), m_pManager( pManager ), - m_sEnablingPackages( ExtMgrDialog::getResourceString( RID_STR_ENABLING_PACKAGES ) ), - m_sDisablingPackages( ExtMgrDialog::getResourceString( RID_STR_DISABLING_PACKAGES ) ), - m_sAddingPackages( ExtMgrDialog::getResourceString( RID_STR_ADDING_PACKAGES ) ), - m_sRemovingPackages( ExtMgrDialog::getResourceString( RID_STR_REMOVING_PACKAGES ) ), - m_sDefaultCmd( ExtMgrDialog::getResourceString( RID_STR_ADD_PACKAGES ) ), + m_sEnablingPackages( DialogHelper::getResourceString( RID_STR_ENABLING_PACKAGES ) ), + m_sDisablingPackages( DialogHelper::getResourceString( RID_STR_DISABLING_PACKAGES ) ), + m_sAddingPackages( DialogHelper::getResourceString( RID_STR_ADDING_PACKAGES ) ), + m_sRemovingPackages( DialogHelper::getResourceString( RID_STR_REMOVING_PACKAGES ) ), + m_sDefaultCmd( DialogHelper::getResourceString( RID_STR_ADD_PACKAGES ) ), m_eInput( NONE ), m_bTerminated( false ), m_bStopped( false ), m_bWorking( false ) { - OSL_ASSERT( pDialog ); + OSL_ASSERT( pDialogHelper ); } //------------------------------------------------------------------------------ @@ -713,41 +720,21 @@ void ExtensionCmdQueue::Thread::enableExtension( const uno::Reference< deploymen } //------------------------------------------------------------------------------ -void ExtensionCmdQueue::Thread::checkForUpdates( const uno::Sequence< uno::Reference< deployment::XPackageManager > > &rPackageManagers ) +void ExtensionCmdQueue::Thread::checkForUpdates( const std::vector< TUpdateListEntry > &vExtensionList ) { ::osl::MutexGuard aGuard( m_mutex ); - //If someone called stop then we do not remove the extension -> game over! + //If someone called stop then we do not update the extension -> game over! if ( m_bStopped ) return; - TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::CHECK_FOR_UPDATES, rPackageManagers ) ); + TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::CHECK_FOR_UPDATES, vExtensionList ) ); m_queue.push( pEntry ); m_eInput = START; m_wakeup.set(); } //------------------------------------------------------------------------------ -void ExtensionCmdQueue::Thread::checkForUpdate( const uno::Reference< deployment::XPackageManager > &rPackageManager, - const uno::Reference< deployment::XPackage > &rPackage ) -{ - ::osl::MutexGuard aGuard( m_mutex ); - - //If someone called stop then we do not remove the extension -> game over! - if ( m_bStopped ) - return; - - if ( rPackageManager.is() && rPackage.is() ) - { - TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::CHECK_FOR_UPDATE, rPackageManager, rPackage ) ); - - m_queue.push( pEntry ); - m_eInput = START; - m_wakeup.set(); - } -} - -//------------------------------------------------------------------------------ //Stopping this thread will not abort the installation of extensions. void ExtensionCmdQueue::Thread::stop() { @@ -779,7 +766,7 @@ void ExtensionCmdQueue::Thread::execute() { #ifdef WNT //Needed for use of the service "com.sun.star.system.SystemShellExecute" in - //ExtMgrDialog::openWebBrowser + //DialogHelper::openWebBrowser CoUninitialize(); HRESULT r = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); #endif @@ -813,7 +800,7 @@ void ExtensionCmdQueue::Thread::execute() if ( eInput == STOP ) break; - ::rtl::Reference< ProgressCmdEnv > currentCmdEnv( new ProgressCmdEnv( m_xContext, m_pDialog, m_sDefaultCmd ) ); + ::rtl::Reference< ProgressCmdEnv > currentCmdEnv( new ProgressCmdEnv( m_xContext, m_pDialogHelper, m_sDefaultCmd ) ); // Do not lock the following part with addExtension. addExtension may be called in the main thread. // If the message box "Do you want to install the extension (or similar)" is shown and then @@ -836,8 +823,7 @@ void ExtensionCmdQueue::Thread::execute() m_queue.pop(); } - if ( bStartProgress && ( pEntry->m_eCmdType != ExtensionCmd::CHECK_FOR_UPDATE ) && - ( pEntry->m_eCmdType != ExtensionCmd::CHECK_FOR_UPDATES ) ) + if ( bStartProgress && ( pEntry->m_eCmdType != ExtensionCmd::CHECK_FOR_UPDATES ) ) { currentCmdEnv->startProgress(); bStartProgress = false; @@ -856,9 +842,8 @@ void ExtensionCmdQueue::Thread::execute() case ExtensionCmd::DISABLE : _disableExtension( currentCmdEnv, pEntry->m_xPackage ); break; - case ExtensionCmd::CHECK_FOR_UPDATE : case ExtensionCmd::CHECK_FOR_UPDATES : - _checkForUpdates( pEntry->m_xPackageManagers, pEntry->m_xPackageManager, pEntry->m_xPackage ); + _checkForUpdates( pEntry->m_vExtensionList ); break; } } @@ -908,7 +893,8 @@ void ExtensionCmdQueue::Thread::execute() const ::vos::OGuard guard( Application::GetSolarMutex() ); ::std::auto_ptr<ErrorBox> box( new ErrorBox( currentCmdEnv->activeDialog(), WB_OK, msg ) ); - box->SetText( m_pDialog->GetText() ); + if ( m_pDialogHelper ) + box->SetText( m_pDialogHelper->getWindow()->GetText() ); box->Execute(); //Continue with installation of the remaining extensions } @@ -1009,21 +995,14 @@ void ExtensionCmdQueue::Thread::_removeExtension( ::rtl::Reference< ProgressCmdE } //------------------------------------------------------------------------------ -void ExtensionCmdQueue::Thread::_checkForUpdates( const uno::Sequence< uno::Reference< deployment::XPackageManager > > &rPackageManagers, - const uno::Reference< deployment::XPackageManager > &xPackageManager, - const uno::Reference< deployment::XPackage > &xPackage ) +void ExtensionCmdQueue::Thread::_checkForUpdates( const std::vector< TUpdateListEntry > &vExtensionList ) { UpdateDialog* pUpdateDialog; std::vector< UpdateData > vData; const ::vos::OGuard guard( Application::GetSolarMutex() ); - if ( xPackageManager.is() && xPackage.is() ) - pUpdateDialog = new UpdateDialog( m_xContext, m_pDialog, new SelectedPackage( xPackage, xPackageManager ), - uno::Sequence< uno::Reference< deployment::XPackageManager > >(), &vData ); - else - pUpdateDialog = new UpdateDialog( m_xContext, m_pDialog, rtl::Reference< SelectedPackage >(), - rPackageManagers, &vData ); + pUpdateDialog = new UpdateDialog( m_xContext, m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, vExtensionList, &vData ); pUpdateDialog->notifyMenubar( true, false ); // prepare the checking, if there updates to be notified via menu bar icon @@ -1046,7 +1025,7 @@ void ExtensionCmdQueue::Thread::_checkForUpdates( const uno::Sequence< uno::Refe short nDialogResult = RET_OK; if ( !dataDownload.empty() ) { - nDialogResult = UpdateInstallDialog( m_pDialog, dataDownload, m_xContext ).Execute(); + nDialogResult = UpdateInstallDialog( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, dataDownload, m_xContext ).Execute(); pUpdateDialog->notifyMenubar( false, true ); // Check, if there are still pending updates to be notified via menu bar icon } else @@ -1057,8 +1036,8 @@ void ExtensionCmdQueue::Thread::_checkForUpdates( const uno::Sequence< uno::Refe { for ( cit i = vData.begin(); i < vData.end(); i++ ) { - if ( i->sWebsiteURL.getLength() > 0 ) - m_pDialog->openWebBrowser( i->sWebsiteURL ); + if ( m_pDialogHelper && ( i->sWebsiteURL.getLength() > 0 ) ) + m_pDialogHelper->openWebBrowser( i->sWebsiteURL, m_pDialogHelper->getWindow()->GetText() ); } } } @@ -1082,7 +1061,8 @@ void ExtensionCmdQueue::Thread::_enableExtension( ::rtl::Reference< ProgressCmdE try { xPackage->registerPackage( xAbortChannel, rCmdEnv.get() ); - m_pDialog->updatePackageInfo( xPackage ); + if ( m_pDialogHelper ) + m_pDialogHelper->updatePackageInfo( xPackage ); } catch ( ::ucb::CommandAbortedException & ) {} @@ -1102,7 +1082,8 @@ void ExtensionCmdQueue::Thread::_disableExtension( ::rtl::Reference< ProgressCmd try { xPackage->revokePackage( xAbortChannel, rCmdEnv.get() ); - m_pDialog->updatePackageInfo( xPackage ); + if ( m_pDialogHelper ) + m_pDialogHelper->updatePackageInfo( xPackage ); } catch ( ::ucb::CommandAbortedException & ) {} @@ -1139,10 +1120,10 @@ OUString ExtensionCmdQueue::Thread::searchAndReplaceAll( const OUString &rSource //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -ExtensionCmdQueue::ExtensionCmdQueue( ExtMgrDialog * pDialog, +ExtensionCmdQueue::ExtensionCmdQueue( DialogHelper * pDialogHelper, TheExtensionManager *pManager, const uno::Reference< uno::XComponentContext > &rContext ) - : m_thread( new Thread( pDialog, pManager, rContext ) ) + : m_thread( new Thread( pDialogHelper, pManager, rContext ) ) { m_thread->launch(); } @@ -1170,15 +1151,9 @@ void ExtensionCmdQueue::enableExtension( const uno::Reference< deployment::XPack m_thread->enableExtension( rPackage, bEnable ); } -void ExtensionCmdQueue::checkForUpdates( const uno::Sequence< uno::Reference< deployment::XPackageManager > > &rPackageManagers ) -{ - m_thread->checkForUpdates( rPackageManagers ); -} - -void ExtensionCmdQueue::checkForUpdate( const uno::Reference< deployment::XPackageManager > &rPackageManager, - const uno::Reference< deployment::XPackage > &rPackage ) +void ExtensionCmdQueue::checkForUpdates( const std::vector< TUpdateListEntry > &vExtensionList ) { - m_thread->checkForUpdate( rPackageManager, rPackage ); + m_thread->checkForUpdates( vExtensionList ); } void ExtensionCmdQueue::stop() diff --git a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx index 06ecefd7749b..2d24f00e3c8e 100644 --- a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx +++ b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx @@ -32,19 +32,14 @@ #ifndef INCLUDED_DP_GUI_EXTENSIONCMDQUEUE_HXX #define INCLUDED_DP_GUI_EXTENSIONCMDQUEUE_HXX -#ifndef _SAL_CONFIG_H_ #include "sal/config.h" -#endif -#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_ #include "com/sun/star/uno/Reference.hxx" -#endif -#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_ -#include "com/sun/star/uno/Sequence.hxx" -#endif -#ifndef _RTL_REF_HXX_ #include "rtl/ref.hxx" -#endif + +#include <vector> + +#include "dp_gui_updatedata.hxx" /// @HTML @@ -56,7 +51,7 @@ namespace com { namespace sun { namespace star { namespace dp_gui { -class ExtMgrDialog; +class DialogHelper; class TheExtensionManager; /** @@ -79,7 +74,7 @@ public: /** Create an instance. */ - ExtensionCmdQueue( ExtMgrDialog * pDialog, + ExtensionCmdQueue( DialogHelper * pDialogHelper, TheExtensionManager *pManager, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > & rContext); @@ -94,9 +89,7 @@ public: const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &rPackage ); void enableExtension( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &rPackage, const bool bEnable ); - void checkForUpdates( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > > &rPackageManagers ); - void checkForUpdate( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &rPackageManager, - const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &rPackage ); + void checkForUpdates( const std::vector< TUpdateListEntry > &vList ); /** This call does not block. It signals the internal thread that it should install the remaining extensions and then terminate. diff --git a/desktop/source/deployment/gui/dp_gui_extlistbox.cxx b/desktop/source/deployment/gui/dp_gui_extlistbox.cxx new file mode 100644 index 000000000000..f4473c2c6fd8 --- /dev/null +++ b/desktop/source/deployment/gui/dp_gui_extlistbox.cxx @@ -0,0 +1,1175 @@ +/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2009 by Sun Microsystems, Inc.
+ *
+ * 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 "svtools/controldims.hrc"
+
+#include "dp_gui.h"
+#include "dp_gui_extlistbox.hxx"
+#include "dp_gui_theextmgr.hxx"
+#include "dp_gui_dialog2.hxx"
+#include "dp_dependencies.hxx"
+
+#include "comphelper/processfactory.hxx"
+#include "com/sun/star/i18n/CollatorOptions.hpp"
+#include "com/sun/star/deployment/DependencyException.hpp"
+#include "com/sun/star/deployment/DeploymentException.hpp"
+
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+using namespace ::com::sun::star;
+
+namespace dp_gui {
+
+//------------------------------------------------------------------------------
+// struct Entry_Impl
+//------------------------------------------------------------------------------
+Entry_Impl::Entry_Impl( const uno::Reference< deployment::XPackage > &xPackage,
+ const uno::Reference< deployment::XPackageManager > &xPackageManager,
+ PackageState eState ) :
+ m_bActive( false ),
+ m_bLocked( false ),
+ m_bHasOptions( false ),
+ m_bShared( false ),
+ m_bNew( false ),
+ m_bChecked( false ),
+ m_bMissingDeps( false ),
+ m_eState( eState ),
+ m_pPublisher( NULL ),
+ m_xPackage( xPackage ),
+ m_xPackageManager( xPackageManager )
+{
+ m_sTitle = xPackage->getDisplayName();
+ m_sVersion = xPackage->getVersion();
+ m_sDescription = xPackage->getDescription();
+
+ beans::StringPair aInfo( m_xPackage->getPublisherInfo() );
+ m_sPublisher = aInfo.First;
+ m_sPublisherURL = aInfo.Second;
+
+ // get the icons for the package if there are any
+ uno::Reference< graphic::XGraphic > xGraphic = xPackage->getIcon( false );
+ if ( xGraphic.is() )
+ m_aIcon = Image( xGraphic );
+
+ xGraphic = xPackage->getIcon( true );
+ if ( xGraphic.is() )
+ m_aIconHC = Image( xGraphic );
+ else
+ m_aIconHC = m_aIcon;
+
+ m_bLocked = m_xPackageManager->isReadOnly();
+
+ if ( eState == AMBIGUOUS )
+ m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS );
+ else if ( eState == NOT_REGISTERED )
+ checkDependencies();
+}
+
+//------------------------------------------------------------------------------
+Entry_Impl::~Entry_Impl()
+{}
+
+//------------------------------------------------------------------------------
+StringCompare Entry_Impl::CompareTo( const CollatorWrapper *pCollator, const TEntry_Impl pEntry ) const
+{
+ StringCompare eCompare = (StringCompare) pCollator->compareString( m_sTitle, pEntry->m_sTitle );
+ if ( eCompare == COMPARE_EQUAL )
+ {
+ eCompare = m_sVersion.CompareTo( pEntry->m_sVersion );
+ if ( eCompare == COMPARE_EQUAL )
+ {
+ if ( m_xPackageManager != pEntry->m_xPackageManager )
+ {
+ sal_Int32 nCompare = m_xPackageManager->getContext().compareTo( pEntry->m_xPackageManager->getContext() );
+ if ( nCompare < 0 )
+ eCompare = COMPARE_LESS;
+ else if ( nCompare > 0 )
+ eCompare = COMPARE_GREATER;
+ }
+ }
+ }
+ return eCompare;
+}
+
+//------------------------------------------------------------------------------
+void Entry_Impl::checkDependencies()
+{
+ try {
+ m_xPackage->checkDependencies( uno::Reference< ucb::XCommandEnvironment >() );
+ }
+ catch ( deployment::DeploymentException &e )
+ {
+ deployment::DependencyException depExc;
+ if ( e.Cause >>= depExc )
+ {
+ rtl::OUString aMissingDep( DialogHelper::getResourceString( RID_STR_ERROR_MISSING_DEPENDENCIES ) );
+ for ( sal_Int32 i = 0; i < depExc.UnsatisfiedDependencies.getLength(); ++i )
+ {
+ aMissingDep += OUSTR("\n");
+ aMissingDep += dp_misc::Dependencies::getErrorText( depExc.UnsatisfiedDependencies[i]);
+ }
+ aMissingDep += OUSTR("\n");
+ m_sErrorText = aMissingDep;
+ m_bMissingDeps = true;
+ }
+ }
+}
+//------------------------------------------------------------------------------
+// ExtensionRemovedListener
+//------------------------------------------------------------------------------
+void ExtensionRemovedListener::disposing( lang::EventObject const & rEvt )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< deployment::XPackage > xPackage( rEvt.Source, uno::UNO_QUERY );
+
+ if ( xPackage.is() )
+ {
+ m_pParent->removeEntry( xPackage );
+ }
+}
+
+//------------------------------------------------------------------------------
+ExtensionRemovedListener::~ExtensionRemovedListener()
+{
+}
+
+//------------------------------------------------------------------------------
+// ExtensionBox_Impl
+//------------------------------------------------------------------------------
+ExtensionBox_Impl::ExtensionBox_Impl( Dialog* pParent, TheExtensionManager *pManager ) :
+ IExtensionListBox( pParent, WB_BORDER | WB_TABSTOP | WB_CHILDDLGCTRL ),
+ m_bHasScrollBar( false ),
+ m_bHasActive( false ),
+ m_bNeedsRecalc( true ),
+ m_bHasNew( false ),
+ m_bInCheckMode( false ),
+ m_bAdjustActive( false ),
+ m_bInDelete( false ),
+ m_nActive( 0 ),
+ m_nTopIndex( 0 ),
+ m_nActiveHeight( 0 ),
+ m_nExtraHeight( 2 ),
+ m_aLockedImage( DialogHelper::getResId( RID_IMG_LOCKED ) ),
+ m_aLockedImageHC( DialogHelper::getResId( RID_IMG_LOCKED_HC ) ),
+ m_aWarningImage( DialogHelper::getResId( RID_IMG_WARNING ) ),
+ m_aWarningImageHC( DialogHelper::getResId( RID_IMG_WARNING_HC ) ),
+ m_aDefaultImage( DialogHelper::getResId( RID_IMG_EXTENSION ) ),
+ m_aDefaultImageHC( DialogHelper::getResId( RID_IMG_EXTENSION_HC ) ),
+ m_pScrollBar( NULL ),
+ m_pManager( pManager )
+{
+ SetHelpId( HID_EXTENSION_MANAGER_LISTBOX );
+
+ m_pScrollBar = new ScrollBar( this, WB_VERT );
+ m_pScrollBar->SetScrollHdl( LINK( this, ExtensionBox_Impl, ScrollHdl ) );
+ m_pScrollBar->EnableDrag();
+
+ SetPaintTransparent( true );
+ SetPosPixel( Point( RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP ) );
+ long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
+ long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
+ if ( nIconHeight < nTitleHeight )
+ m_nStdHeight = nTitleHeight;
+ else
+ m_nStdHeight = nIconHeight;
+ m_nStdHeight += GetTextHeight() + TOP_OFFSET;
+
+ nIconHeight = ICON_HEIGHT + 2*TOP_OFFSET + 1;
+ if ( m_nStdHeight < nIconHeight )
+ m_nStdHeight = nIconHeight;
+
+ m_nActiveHeight = m_nStdHeight;
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ if( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( rStyleSettings.GetFieldColor() );
+
+ m_xRemoveListener = new ExtensionRemovedListener( this );
+
+ m_pLocale = new lang::Locale( Application::GetSettings().GetLocale() );
+ m_pCollator = new CollatorWrapper( ::comphelper::getProcessServiceFactory() );
+ m_pCollator->loadDefaultCollator( *m_pLocale, i18n::CollatorOptions::CollatorOptions_IGNORE_CASE );
+
+ Show();
+}
+
+//------------------------------------------------------------------------------
+ExtensionBox_Impl::~ExtensionBox_Impl()
+{
+ if ( ! m_bInDelete )
+ DeleteRemoved();
+
+ m_bInDelete = true;
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_pPublisher )
+ {
+ delete (*iIndex)->m_pPublisher;
+ (*iIndex)->m_pPublisher = NULL;
+ }
+ (*iIndex)->m_xPackage->removeEventListener( uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
+ }
+
+ m_vEntries.clear();
+
+ delete m_pScrollBar;
+
+ m_xRemoveListener.clear();
+
+ delete m_pLocale;
+ delete m_pCollator;
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 ExtensionBox_Impl::getItemCount() const
+{
+ return static_cast< sal_Int32 >( m_vEntries.size() );
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 ExtensionBox_Impl::getSelIndex() const
+{
+ if ( m_bHasActive )
+ {
+ OSL_ASSERT( m_nActive >= -1);
+ return static_cast< sal_Int32 >( m_nActive );
+ }
+ else
+ return static_cast< sal_Int32 >( EXTENSION_LISTBOX_ENTRY_NOTFOUND );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::checkIndex( sal_Int32 nIndex ) const
+{
+ if ( nIndex < 0 )
+ throw lang::IllegalArgumentException( OUSTR("The list index starts with 0"),0, 0 );
+ if ( static_cast< sal_uInt32 >( nIndex ) >= m_vEntries.size())
+ throw lang::IllegalArgumentException( OUSTR("There is no element at the provided position."
+ "The position exceeds the number of available list entries"),0, 0 );
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemName( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sTitle;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemVersion( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sVersion;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemDescription( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sDescription;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemPublisher( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sPublisher;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemPublisherLink( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sPublisherURL;
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::select( sal_Int32 nIndex )
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ selectEntry( nIndex );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::select( const rtl::OUString & sName )
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ typedef ::std::vector< TEntry_Impl >::const_iterator It;
+
+ for ( It iIter = m_vEntries.begin(); iIter < m_vEntries.end(); iIter++ )
+ {
+ if ( sName.equals( (*iIter)->m_sTitle ) )
+ {
+ long nPos = iIter - m_vEntries.begin();
+ selectEntry( nPos );
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+// Title + description
+void ExtensionBox_Impl::CalcActiveHeight( const long nPos )
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ // get title height
+ long aTextHeight;
+ long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
+ long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
+ if ( nIconHeight < nTitleHeight )
+ aTextHeight = nTitleHeight;
+ else
+ aTextHeight = nIconHeight;
+
+ // calc description height
+ Size aSize = GetOutputSizePixel();
+ if ( m_bHasScrollBar )
+ aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
+
+ aSize.Width() -= ICON_OFFSET;
+ aSize.Height() = 10000;
+
+ rtl::OUString aText( m_vEntries[ nPos ]->m_sErrorText );
+ aText += m_vEntries[ nPos ]->m_sDescription;
+
+ Rectangle aRect = GetTextRect( Rectangle( Point(), aSize ), aText,
+ TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
+ aTextHeight += aRect.GetHeight();
+
+ if ( aTextHeight < m_nStdHeight )
+ aTextHeight = m_nStdHeight;
+
+ m_nActiveHeight = aTextHeight + m_nExtraHeight;
+}
+
+//------------------------------------------------------------------------------
+const Size ExtensionBox_Impl::GetMinOutputSizePixel() const
+{
+ return Size( 200, 80 );
+}
+
+//------------------------------------------------------------------------------
+Rectangle ExtensionBox_Impl::GetEntryRect( const long nPos ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ Size aSize( GetOutputSizePixel() );
+
+ if ( m_bHasScrollBar )
+ aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
+
+ if ( m_vEntries[ nPos ]->m_bActive )
+ aSize.Height() = m_nActiveHeight;
+ else
+ aSize.Height() = m_nStdHeight;
+
+ Point aPos( 0, -m_nTopIndex + nPos * m_nStdHeight );
+ if ( m_bHasActive && ( nPos < m_nActive ) )
+ aPos.Y() += m_nActiveHeight - m_nStdHeight;
+
+ return Rectangle( aPos, aSize );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::DeleteRemoved()
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ m_bInDelete = true;
+
+ if ( ! m_vRemovedEntries.empty() )
+ {
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vRemovedEntries.begin(); iIndex < m_vRemovedEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_pPublisher )
+ {
+ delete (*iIndex)->m_pPublisher;
+ (*iIndex)->m_pPublisher = NULL;
+ }
+ }
+
+ m_vRemovedEntries.clear();
+ }
+
+ m_bInDelete = false;
+}
+
+//------------------------------------------------------------------------------
+//This function may be called with nPos < 0
+void ExtensionBox_Impl::selectEntry( const long nPos )
+{
+ //ToDo whe should not use the guard at such a big scope here.
+ //Currently it is used to gard m_vEntries and m_nActive. m_nActive will be
+ //modified in this function.
+ //It would be probably best to always use a copy of m_vEntries
+ //and some other state variables from ExtensionBox_Impl for
+ //the whole painting operation. See issue i86993
+ ::osl::ClearableMutexGuard guard(m_entriesMutex);
+
+ if ( m_bInCheckMode )
+ return;
+
+ if ( m_bHasActive )
+ {
+ if ( nPos == m_nActive )
+ return;
+
+ m_bHasActive = false;
+ m_vEntries[ m_nActive ]->m_bActive = false;
+ }
+
+ if ( ( nPos >= 0 ) && ( nPos < (long) m_vEntries.size() ) )
+ {
+ m_bHasActive = true;
+ m_nActive = nPos;
+ m_vEntries[ nPos ]->m_bActive = true;
+
+ if ( IsReallyVisible() )
+ {
+ m_bNeedsRecalc = true;
+ m_bAdjustActive = true;
+ }
+ }
+
+ if ( IsReallyVisible() )
+ Invalidate();
+
+ guard.clear();
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::DrawRow( const Rectangle& rRect, const TEntry_Impl pEntry )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( pEntry->m_bActive )
+ SetTextColor( rStyleSettings.GetHighlightTextColor() );
+ else if ( ( pEntry->m_eState != REGISTERED ) && ( pEntry->m_eState != NOT_AVAILABLE ) )
+ SetTextColor( rStyleSettings.GetDisableColor() );
+ else if ( IsControlForeground() )
+ SetTextColor( GetControlForeground() );
+ else
+ SetTextColor( rStyleSettings.GetFieldTextColor() );
+
+ if ( pEntry->m_bActive )
+ {
+ SetLineColor();
+ SetFillColor( rStyleSettings.GetHighlightColor() );
+ DrawRect( rRect );
+ }
+ else
+ {
+ if( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( rStyleSettings.GetFieldColor() );
+
+ SetTextFillColor();
+ Erase( rRect );
+ }
+
+ // Draw extension icon
+ Point aPos( rRect.TopLeft() );
+ aPos += Point( TOP_OFFSET, TOP_OFFSET );
+ Image aImage;
+ if ( ! pEntry->m_aIcon )
+ aImage = isHCMode() ? m_aDefaultImageHC : m_aDefaultImage;
+ else
+ aImage = isHCMode() ? pEntry->m_aIconHC : pEntry->m_aIcon;
+ Size aImageSize = aImage.GetSizePixel();
+ if ( ( aImageSize.Width() <= ICON_HEIGHT ) && ( aImageSize.Height() <= ICON_HEIGHT ) )
+ DrawImage( Point( aPos.X()+((ICON_HEIGHT-aImageSize.Width())/2), aPos.Y()+((ICON_HEIGHT-aImageSize.Height())/2) ), aImage );
+ else
+ DrawImage( aPos, Size( ICON_HEIGHT, ICON_HEIGHT ), aImage );
+
+ // Setup fonts
+ Font aStdFont( GetFont() );
+ Font aBoldFont( aStdFont );
+ aBoldFont.SetWeight( WEIGHT_BOLD );
+ SetFont( aBoldFont );
+ long aTextHeight = GetTextHeight();
+
+ // Init publisher link here
+ if ( !pEntry->m_pPublisher && pEntry->m_sPublisher.Len() )
+ {
+ pEntry->m_pPublisher = new svt::FixedHyperlink( this );
+ pEntry->m_pPublisher->SetBackground();
+ pEntry->m_pPublisher->SetPaintTransparent( true );
+ pEntry->m_pPublisher->SetURL( pEntry->m_sPublisherURL );
+ pEntry->m_pPublisher->SetDescription( pEntry->m_sPublisher );
+ Size aSize = FixedText::CalcMinimumTextSize( pEntry->m_pPublisher );
+ pEntry->m_pPublisher->SetSizePixel( aSize );
+
+ if ( m_aClickHdl.IsSet() )
+ pEntry->m_pPublisher->SetClickHdl( m_aClickHdl );
+ }
+
+ // Get max title width
+ long nMaxTitleWidth = rRect.GetWidth() - ICON_OFFSET;
+ nMaxTitleWidth -= ( 2 * SMALL_ICON_SIZE ) + ( 4 * SPACE_BETWEEN );
+ if ( pEntry->m_pPublisher )
+ {
+ nMaxTitleWidth -= pEntry->m_pPublisher->GetSizePixel().Width() + (2*SPACE_BETWEEN);
+ }
+
+ long aVersionWidth = GetTextWidth( pEntry->m_sVersion );
+ long aTitleWidth = GetTextWidth( pEntry->m_sTitle ) + (aTextHeight / 3);
+
+ aPos = rRect.TopLeft() + Point( ICON_OFFSET, TOP_OFFSET );
+
+ if ( aTitleWidth > nMaxTitleWidth - aVersionWidth )
+ {
+ aTitleWidth = nMaxTitleWidth - aVersionWidth - (aTextHeight / 3);
+ String aShortTitle = GetEllipsisString( pEntry->m_sTitle, aTitleWidth );
+ DrawText( aPos, aShortTitle );
+ aTitleWidth += (aTextHeight / 3);
+ }
+ else
+ DrawText( aPos, pEntry->m_sTitle );
+
+ SetFont( aStdFont );
+ DrawText( Point( aPos.X() + aTitleWidth, aPos.Y() ), pEntry->m_sVersion );
+
+ long nIconHeight = TOP_OFFSET + SMALL_ICON_SIZE;
+ long nTitleHeight = TOP_OFFSET + GetTextHeight();
+ if ( nIconHeight < nTitleHeight )
+ aTextHeight = nTitleHeight;
+ else
+ aTextHeight = nIconHeight;
+
+ // draw description
+ String sDescription;
+ if ( pEntry->m_sErrorText.Len() )
+ {
+ if ( pEntry->m_bActive )
+ sDescription = pEntry->m_sErrorText + OUSTR("\n") + pEntry->m_sDescription;
+ else
+ sDescription = pEntry->m_sErrorText;
+ }
+ else
+ sDescription = pEntry->m_sDescription;
+
+ aPos.Y() += aTextHeight;
+ if ( pEntry->m_bActive )
+ {
+ DrawText( Rectangle( aPos.X(), aPos.Y(), rRect.Right(), rRect.Bottom() - m_nExtraHeight ),
+ sDescription, TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
+ }
+ else
+ {
+ const long nWidth = GetTextWidth( sDescription );
+ if ( nWidth > rRect.GetWidth() - aPos.X() )
+ sDescription = GetEllipsisString( sDescription, rRect.GetWidth() - aPos.X() );
+ DrawText( aPos, sDescription );
+ }
+
+ // Draw publisher link
+ if ( pEntry->m_pPublisher )
+ {
+ pEntry->m_pPublisher->Show();
+ aPos = rRect.TopLeft() + Point( ICON_OFFSET + nMaxTitleWidth + (2*SPACE_BETWEEN), TOP_OFFSET );
+ pEntry->m_pPublisher->SetPosPixel( aPos );
+ }
+
+ // Draw status icons
+ if ( pEntry->m_bShared )
+ {
+ aPos = rRect.TopRight() + Point( -(RIGHT_ICON_OFFSET + SMALL_ICON_SIZE), TOP_OFFSET );
+ DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), isHCMode() ? m_aLockedImageHC : m_aLockedImage );
+ }
+ if ( ( pEntry->m_eState == AMBIGUOUS ) || pEntry->m_bMissingDeps )
+ {
+ aPos = rRect.TopRight() + Point( -(RIGHT_ICON_OFFSET + SPACE_BETWEEN + 2*SMALL_ICON_SIZE), TOP_OFFSET );
+ DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), isHCMode() ? m_aWarningImageHC : m_aWarningImage );
+ }
+
+ SetLineColor( Color( COL_LIGHTGRAY ) );
+ DrawLine( rRect.BottomLeft(), rRect.BottomRight() );
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::RecalcAll()
+{
+ if ( m_bHasActive )
+ CalcActiveHeight( m_nActive );
+
+ SetupScrollBar();
+
+ if ( m_bHasActive )
+ {
+ Rectangle aEntryRect = GetEntryRect( m_nActive );
+
+ if ( m_bAdjustActive )
+ {
+ m_bAdjustActive = false;
+
+ // If the top of the selected entry isn't visible, make it visible
+ if ( aEntryRect.Top() < 0 )
+ {
+ m_nTopIndex += aEntryRect.Top();
+ aEntryRect.Move( 0, -aEntryRect.Top() );
+ }
+
+ // If the bottom of the selected entry isn't visible, make it visible even if now the top
+ // isn't visible any longer ( the buttons are more important )
+ Size aOutputSize = GetOutputSizePixel();
+ if ( aEntryRect.Bottom() > aOutputSize.Height() )
+ {
+ m_nTopIndex += ( aEntryRect.Bottom() - aOutputSize.Height() );
+ aEntryRect.Move( 0, -( aEntryRect.Bottom() - aOutputSize.Height() ) );
+ }
+
+ // If there is unused space below the last entry but all entries don't fit into the box,
+ // move the content down to use the whole space
+ const long nTotalHeight = GetTotalHeight();
+ if ( m_bHasScrollBar && ( aOutputSize.Height() + m_nTopIndex > nTotalHeight ) )
+ {
+ long nOffset = m_nTopIndex;
+ m_nTopIndex = nTotalHeight - aOutputSize.Height();
+ nOffset -= m_nTopIndex;
+ aEntryRect.Move( 0, nOffset );
+ }
+
+ if ( m_bHasScrollBar )
+ m_pScrollBar->SetThumbPos( m_nTopIndex );
+ }
+ }
+
+ m_bNeedsRecalc = false;
+}
+
+// -----------------------------------------------------------------------
+bool ExtensionBox_Impl::HandleTabKey( bool )
+{
+ return false;
+}
+
+// -----------------------------------------------------------------------
+bool ExtensionBox_Impl::HandleCursorKey( USHORT nKeyCode )
+{
+ if ( m_vEntries.empty() )
+ return true;
+
+ long nSelect = 0;
+
+ if ( m_bHasActive )
+ {
+ long nPageSize = GetOutputSizePixel().Height() / m_nStdHeight;
+ if ( nPageSize < 2 )
+ nPageSize = 2;
+
+ if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_RIGHT ) )
+ nSelect = m_nActive + 1;
+ else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_LEFT ) )
+ nSelect = m_nActive - 1;
+ else if ( nKeyCode == KEY_HOME )
+ nSelect = 0;
+ else if ( nKeyCode == KEY_END )
+ nSelect = m_vEntries.size() - 1;
+ else if ( nKeyCode == KEY_PAGEUP )
+ nSelect = m_nActive - nPageSize + 1;
+ else if ( nKeyCode == KEY_PAGEDOWN )
+ nSelect = m_nActive + nPageSize - 1;
+ }
+ else // when there is no selected entry, we will select the first or the last.
+ {
+ if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_PAGEDOWN ) || ( nKeyCode == KEY_HOME ) )
+ nSelect = 0;
+ else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_PAGEUP ) || ( nKeyCode == KEY_END ) )
+ nSelect = m_vEntries.size() - 1;
+ }
+
+ if ( nSelect < 0 )
+ nSelect = 0;
+ if ( nSelect >= (long) m_vEntries.size() )
+ nSelect = m_vEntries.size() - 1;
+
+ selectEntry( nSelect );
+
+ return true;
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::Paint( const Rectangle &/*rPaintRect*/ )
+{
+ if ( !m_bInDelete )
+ DeleteRemoved();
+
+ if ( m_bNeedsRecalc )
+ RecalcAll();
+
+ Point aStart( 0, -m_nTopIndex );
+ Size aSize( GetOutputSizePixel() );
+
+ if ( m_bHasScrollBar )
+ aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
+
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ aSize.Height() = (*iIndex)->m_bActive ? m_nActiveHeight : m_nStdHeight;
+ Rectangle aEntryRect( aStart, aSize );
+ DrawRow( aEntryRect, *iIndex );
+ aStart.Y() += aSize.Height();
+ }
+}
+
+// -----------------------------------------------------------------------
+long ExtensionBox_Impl::GetTotalHeight() const
+{
+ long nHeight = m_vEntries.size() * m_nStdHeight;
+
+ if ( m_bHasActive )
+ {
+ nHeight += m_nActiveHeight - m_nStdHeight;
+ }
+
+ return nHeight;
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::SetupScrollBar()
+{
+ const Size aSize = GetOutputSizePixel();
+ const long nScrBarSize = GetSettings().GetStyleSettings().GetScrollBarSize();
+ const long nTotalHeight = GetTotalHeight();
+ const bool bNeedsScrollBar = ( nTotalHeight > aSize.Height() );
+
+ if ( bNeedsScrollBar )
+ {
+ if ( m_nTopIndex + aSize.Height() > nTotalHeight )
+ m_nTopIndex = nTotalHeight - aSize.Height();
+
+ m_pScrollBar->SetPosSizePixel( Point( aSize.Width() - nScrBarSize, 0 ),
+ Size( nScrBarSize, aSize.Height() ) );
+ m_pScrollBar->SetRangeMax( nTotalHeight );
+ m_pScrollBar->SetVisibleSize( aSize.Height() );
+ m_pScrollBar->SetPageSize( ( aSize.Height() * 4 ) / 5 );
+ m_pScrollBar->SetLineSize( m_nStdHeight );
+ m_pScrollBar->SetThumbPos( m_nTopIndex );
+
+ if ( !m_bHasScrollBar )
+ m_pScrollBar->Show();
+ }
+ else if ( m_bHasScrollBar )
+ {
+ m_pScrollBar->Hide();
+ m_nTopIndex = 0;
+ }
+
+ m_bHasScrollBar = bNeedsScrollBar;
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::Resize()
+{
+ RecalcAll();
+}
+
+//------------------------------------------------------------------------------
+long ExtensionBox_Impl::PointToPos( const Point& rPos )
+{
+ long nPos = ( rPos.Y() + m_nTopIndex ) / m_nStdHeight;
+
+ if ( m_bHasActive && ( nPos > m_nActive ) )
+ {
+ if ( rPos.Y() + m_nTopIndex <= m_nActive*m_nStdHeight + m_nActiveHeight )
+ nPos = m_nActive;
+ else
+ nPos = ( rPos.Y() + m_nTopIndex - (m_nActiveHeight - m_nStdHeight) ) / m_nStdHeight;
+ }
+
+ return nPos;
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ long nPos = PointToPos( rMEvt.GetPosPixel() );
+
+ if ( rMEvt.IsLeft() )
+ {
+ if ( rMEvt.IsMod1() && m_bHasActive )
+ selectEntry( m_vEntries.size() ); // Selecting an not existing entry will deselect the current one
+ else
+ selectEntry( nPos );
+ }
+}
+
+//------------------------------------------------------------------------------
+long ExtensionBox_Impl::Notify( NotifyEvent& rNEvt )
+{
+ if ( !m_bInDelete )
+ DeleteRemoved();
+
+ bool bHandled = false;
+
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ KeyCode aKeyCode = pKEvt->GetKeyCode();
+ USHORT nKeyCode = aKeyCode.GetCode();
+
+ if ( nKeyCode == KEY_TAB )
+ bHandled = HandleTabKey( aKeyCode.IsShift() );
+ else if ( aKeyCode.GetGroup() == KEYGROUP_CURSOR )
+ bHandled = HandleCursorKey( nKeyCode );
+ }
+
+ if ( rNEvt.GetType() == EVENT_COMMAND )
+ {
+ if ( m_bHasScrollBar &&
+ ( rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL ) )
+ {
+ const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
+ if ( pData->GetMode() == COMMAND_WHEEL_SCROLL )
+ {
+ long nThumbPos = m_pScrollBar->GetThumbPos();
+ if ( pData->GetDelta() < 0 )
+ m_pScrollBar->DoScroll( nThumbPos + m_nStdHeight );
+ else
+ m_pScrollBar->DoScroll( nThumbPos - m_nStdHeight );
+ bHandled = true;
+ }
+ }
+ }
+
+ if ( !bHandled )
+ return Control::Notify( rNEvt );
+ else
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool ExtensionBox_Impl::FindEntryPos( const TEntry_Impl pEntry, const long nStart,
+ const long nEnd, long &nPos )
+{
+ nPos = nStart;
+ if ( nStart > nEnd )
+ return false;
+
+ StringCompare eCompare;
+
+ if ( nStart == nEnd )
+ {
+ eCompare = pEntry->CompareTo( m_pCollator, m_vEntries[ nStart ] );
+ if ( eCompare == COMPARE_LESS )
+ return false;
+ else if ( eCompare == COMPARE_EQUAL )
+ {
+ //Workaround. See i86963.
+ if (pEntry->m_xPackage != m_vEntries[nStart]->m_xPackage)
+ return false;
+
+ if ( m_bInCheckMode )
+ m_vEntries[ nStart ]->m_bChecked = true;
+ return true;
+ }
+ else
+ {
+ nPos = nStart + 1;
+ return false;
+ }
+ }
+
+ const long nMid = nStart + ( ( nEnd - nStart ) / 2 );
+ eCompare = pEntry->CompareTo( m_pCollator, m_vEntries[ nMid ] );
+
+ if ( eCompare == COMPARE_LESS )
+ return FindEntryPos( pEntry, nStart, nMid-1, nPos );
+ else if ( eCompare == COMPARE_GREATER )
+ return FindEntryPos( pEntry, nMid+1, nEnd, nPos );
+ else
+ {
+ //Workaround.See i86963.
+ if (pEntry->m_xPackage != m_vEntries[nMid]->m_xPackage)
+ return false;
+
+ if ( m_bInCheckMode )
+ m_vEntries[ nMid ]->m_bChecked = true;
+ nPos = nMid;
+ return true;
+ }
+}
+
+//------------------------------------------------------------------------------
+long ExtensionBox_Impl::addEntry( const uno::Reference< deployment::XPackage > &xPackage,
+ const uno::Reference< deployment::XPackageManager > &xPackageManager )
+{
+ long nPos = 0;
+ PackageState eState = m_pManager->getPackageState( xPackage );
+
+ TEntry_Impl pEntry( new Entry_Impl( xPackage, xPackageManager, eState ) );
+ xPackage->addEventListener( uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
+
+ ::osl::ClearableMutexGuard guard(m_entriesMutex);
+ if ( m_vEntries.empty() )
+ {
+ pEntry->m_bHasOptions = m_pManager->supportsOptions( xPackage );
+ pEntry->m_bShared = ( m_pManager->getSharedPkgMgr() == xPackageManager );
+ pEntry->m_bNew = m_bInCheckMode;
+ m_vEntries.push_back( pEntry );
+ }
+ else
+ {
+ if ( !FindEntryPos( pEntry, 0, m_vEntries.size()-1, nPos ) )
+ {
+ pEntry->m_bHasOptions = m_pManager->supportsOptions( xPackage );
+ pEntry->m_bShared = ( m_pManager->getSharedPkgMgr() == xPackageManager );
+ pEntry->m_bNew = m_bInCheckMode;
+ m_vEntries.insert( m_vEntries.begin()+nPos, pEntry );
+ }
+ else if ( !m_bInCheckMode )
+ {
+ OSL_ENSURE( 0, "ExtensionBox_Impl::addEntry(): Will not add duplicate entries" );
+ }
+ }
+ //access to m_nActive must be guarded
+ if ( !m_bInCheckMode && m_bHasActive && ( m_nActive >= nPos ) )
+ m_nActive += 1;
+
+ guard.clear();
+
+ if ( IsReallyVisible() )
+ Invalidate();
+
+ m_bNeedsRecalc = true;
+
+ return nPos;
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::updateEntry( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_xPackage == xPackage )
+ {
+ PackageState eState = m_pManager->getPackageState( xPackage );
+ (*iIndex)->m_bHasOptions = m_pManager->supportsOptions( xPackage );
+ (*iIndex)->m_eState = eState;
+ (*iIndex)->m_sTitle = xPackage->getDisplayName();
+ (*iIndex)->m_sVersion = xPackage->getVersion();
+ (*iIndex)->m_sDescription = xPackage->getDescription();
+
+ if ( eState == AMBIGUOUS )
+ (*iIndex)->m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS );
+ else
+ (*iIndex)->m_sErrorText = String();
+
+ if ( IsReallyVisible() )
+ Invalidate();
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::removeEntry( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( ! m_bInDelete )
+ {
+ ::osl::ClearableMutexGuard aGuard( m_entriesMutex );
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_xPackage == xPackage )
+ {
+ long nPos = iIndex - m_vEntries.begin();
+
+ // Entries mustn't removed here, because they contain a hyperlink control
+ // which can only be deleted when the thread has the solar mutex. Therefor
+ // the entry will be moved into the m_vRemovedEntries list which will be
+ // cleared on the next paint event
+ m_vRemovedEntries.push_back( *iIndex );
+ m_vEntries.erase( iIndex );
+
+ m_bNeedsRecalc = true;
+
+ if ( IsReallyVisible() )
+ Invalidate();
+
+ if ( m_bHasActive )
+ {
+ if ( nPos < m_nActive )
+ m_nActive -= 1;
+ else if ( ( nPos == m_nActive ) &&
+ ( nPos == (long) m_vEntries.size() ) )
+ m_nActive -= 1;
+
+ m_bHasActive = false;
+ //clear before calling out of this method
+ aGuard.clear();
+ selectEntry( m_nActive );
+ }
+ break;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::RemoveUnlocked()
+{
+ bool bAllRemoved = false;
+
+ while ( ! bAllRemoved )
+ {
+ bAllRemoved = true;
+
+ ::osl::ClearableMutexGuard aGuard( m_entriesMutex );
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( !(*iIndex)->m_bLocked )
+ {
+ bAllRemoved = false;
+ uno::Reference< deployment::XPackage> xPackage = (*iIndex)->m_xPackage;
+ aGuard.clear();
+ removeEntry( xPackage );
+ break;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::prepareChecking( const uno::Reference< deployment::XPackageManager > &xPackageMgr )
+{
+ m_bInCheckMode = true;
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_xPackageManager == xPackageMgr )
+ (*iIndex)->m_bChecked = false;
+ else
+ (*iIndex)->m_bChecked = true;
+ (*iIndex)->m_bNew = false;
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::checkEntries()
+{
+ long nNewPos = -1;
+ long nPos = 0;
+ bool bNeedsUpdate = false;
+
+ ::osl::ClearableMutexGuard guard(m_entriesMutex);
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ ITER iIndex = m_vEntries.begin();
+ while ( iIndex < m_vEntries.end() )
+ {
+ if ( (*iIndex)->m_bChecked == false )
+ {
+ bNeedsUpdate = true;
+ nPos = iIndex-m_vEntries.begin();
+ if ( (*iIndex)->m_bNew )
+ {
+ if ( nNewPos == - 1)
+ nNewPos = nPos;
+ if ( nPos <= m_nActive )
+ m_nActive += 1;
+ }
+ }
+ iIndex++;
+ }
+ guard.clear();
+
+ m_bInCheckMode = false;
+
+ if ( nNewPos != - 1)
+ selectEntry( nNewPos );
+
+ if ( bNeedsUpdate )
+ {
+ m_bNeedsRecalc = true;
+ if ( IsReallyVisible() )
+ Invalidate();
+ }
+}
+//------------------------------------------------------------------------------
+bool ExtensionBox_Impl::isHCMode()
+{
+ return (bool)GetDisplayBackground().GetColor().IsDark();
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::SetScrollHdl( const Link& rLink )
+{
+ if ( m_pScrollBar )
+ m_pScrollBar->SetScrollHdl( rLink );
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::DoScroll( long nDelta )
+{
+ m_nTopIndex += nDelta;
+ Point aNewSBPt( m_pScrollBar->GetPosPixel() );
+
+ Rectangle aScrRect( Point(), GetOutputSizePixel() );
+ aScrRect.Right() -= m_pScrollBar->GetSizePixel().Width();
+ Scroll( 0, -nDelta, aScrRect );
+
+ m_pScrollBar->SetPosPixel( aNewSBPt );
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtensionBox_Impl, ScrollHdl, ScrollBar*, pScrBar )
+{
+ DoScroll( pScrBar->GetDelta() );
+
+ return 1;
+}
+
+} //namespace dp_gui
diff --git a/desktop/source/deployment/gui/dp_gui_extlistbox.hxx b/desktop/source/deployment/gui/dp_gui_extlistbox.hxx new file mode 100644 index 000000000000..e1a17bb06dc9 --- /dev/null +++ b/desktop/source/deployment/gui/dp_gui_extlistbox.hxx @@ -0,0 +1,271 @@ +/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: dp_gui_dialog2.cxx,v $
+ *
+ * $Revision: 1.8.4.8 $
+ *
+ * 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 "rtl/ustring.hxx"
+#include "vcl/scrbar.hxx"
+#include "vcl/fixed.hxx"
+#include "vcl/dialog.hxx"
+
+#include "svtools/extensionlistbox.hxx"
+#include "svtools/fixedhyper.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "unotools/collatorwrapper.hxx"
+
+#include "com/sun/star/lang/Locale.hpp"
+#include "com/sun/star/lang/XEventListener.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+
+#include <boost/shared_ptr.hpp>
+
+namespace dp_gui {
+
+#define SMALL_ICON_SIZE 16
+#define TOP_OFFSET 3
+#define ICON_HEIGHT 42
+#define ICON_OFFSET 50
+#define RIGHT_ICON_OFFSET 5
+#define SPACE_BETWEEN 3
+
+class TheExtensionManager;
+
+typedef ::boost::shared_ptr< svt::FixedHyperlink > TFixedHyperlink;
+
+//------------------------------------------------------------------------------
+// struct Entry_Impl
+//------------------------------------------------------------------------------
+struct Entry_Impl;
+
+typedef ::boost::shared_ptr< Entry_Impl > TEntry_Impl;
+
+struct Entry_Impl
+{
+ bool m_bActive;
+ bool m_bLocked;
+ bool m_bHasOptions;
+ bool m_bShared;
+ bool m_bNew;
+ bool m_bChecked;
+ bool m_bMissingDeps;
+ PackageState m_eState;
+ String m_sTitle;
+ String m_sVersion;
+ String m_sDescription;
+ String m_sPublisher;
+ String m_sPublisherURL;
+ String m_sErrorText;
+ Image m_aIcon;
+ Image m_aIconHC;
+ svt::FixedHyperlink *m_pPublisher;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> m_xPackage;
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager> m_xPackageManager;
+
+ Entry_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager,
+ PackageState eState );
+ ~Entry_Impl();
+
+ StringCompare CompareTo( const CollatorWrapper *pCollator, const TEntry_Impl pEntry ) const;
+ void checkDependencies();
+};
+
+//------------------------------------------------------------------------------
+// class ExtensionBox_Impl
+//------------------------------------------------------------------------------
+
+class ExtensionBox_Impl;
+
+//------------------------------------------------------------------------------
+class ExtensionRemovedListener : public ::cppu::WeakImplHelper1< ::com::sun::star::lang::XEventListener >
+{
+ ExtensionBox_Impl *m_pParent;
+
+public:
+
+ ExtensionRemovedListener( ExtensionBox_Impl *pParent ) { m_pParent = pParent; }
+ ~ExtensionRemovedListener();
+
+ //===================================================================================
+ // XEventListener
+ virtual void SAL_CALL disposing( ::com::sun::star::lang::EventObject const & evt )
+ throw (::com::sun::star::uno::RuntimeException);
+};
+
+//------------------------------------------------------------------------------
+class ExtensionBox_Impl : public ::svt::IExtensionListBox
+{
+ bool m_bHasScrollBar;
+ bool m_bHasActive;
+ bool m_bNeedsRecalc;
+ bool m_bHasNew;
+ bool m_bInCheckMode;
+ bool m_bAdjustActive;
+ bool m_bInDelete;
+ //Must be guarded together with m_vEntries to ensure a valid index at all times.
+ //Use m_entriesMutex as guard.
+ long m_nActive;
+ long m_nTopIndex;
+ long m_nStdHeight;
+ long m_nActiveHeight;
+ long m_nExtraHeight;
+ Size m_aOutputSize;
+ Image m_aLockedImage;
+ Image m_aLockedImageHC;
+ Image m_aWarningImage;
+ Image m_aWarningImageHC;
+ Image m_aDefaultImage;
+ Image m_aDefaultImageHC;
+ Link m_aClickHdl;
+
+ ScrollBar *m_pScrollBar;
+
+ com::sun::star::uno::Reference< ExtensionRemovedListener > m_xRemoveListener;
+
+ TheExtensionManager *m_pManager;
+ //This mutex is used for synchronizing access to m_vEntries.
+ //Currently it is used to synchronize adding, removing entries and
+ //functions like getItemName, getItemDescription, etc. to prevent
+ //that m_vEntries is accessed at an invalid index.
+ //ToDo: There are many more places where m_vEntries is read and which may
+ //fail. For example the Paint method is probable called from the main thread
+ //while new entries are added / removed in a separate thread.
+ mutable ::osl::Mutex m_entriesMutex;
+ std::vector< TEntry_Impl > m_vEntries;
+ std::vector< TEntry_Impl > m_vRemovedEntries;
+
+ ::com::sun::star::lang::Locale *m_pLocale;
+ CollatorWrapper *m_pCollator;
+
+ void CalcActiveHeight( const long nPos );
+ long GetTotalHeight() const;
+ void SetupScrollBar();
+ void DrawRow( const Rectangle& rRect, const TEntry_Impl pEntry );
+ bool HandleTabKey( bool bReverse );
+ bool HandleCursorKey( USHORT nKeyCode );
+ bool FindEntryPos( const TEntry_Impl pEntry, long nStart, long nEnd, long &nFound );
+ bool isHCMode();
+ void DeleteRemoved();
+
+ //-----------------
+ DECL_DLLPRIVATE_LINK( ScrollHdl, ScrollBar * );
+
+ //Index starts with 1.
+ //Throws an com::sun::star::lang::IllegalArgumentException, when the index is invalid.
+ void checkIndex(sal_Int32 pos) const;
+
+
+public:
+ ExtensionBox_Impl( Dialog* pParent, TheExtensionManager *pManager );
+ ~ExtensionBox_Impl();
+
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void Paint( const Rectangle &rPaintRect );
+ virtual void Resize();
+ virtual long Notify( NotifyEvent& rNEvt );
+
+ const Size GetMinOutputSizePixel() const;
+ void SetExtraSize( long nSize ) { m_nExtraHeight = nSize; }
+ TEntry_Impl GetEntryData( long nPos ) { return m_vEntries[ nPos ]; }
+ long GetEntryCount() { return (long) m_vEntries.size(); }
+ Rectangle GetEntryRect( const long nPos ) const;
+ bool HasActive() { return m_bHasActive; }
+ long PointToPos( const Point& rPos );
+ void SetScrollHdl( const Link& rLink );
+ void DoScroll( long nDelta );
+ void SetHyperlinkHdl( const Link& rLink ){ m_aClickHdl = rLink; }
+ virtual void RecalcAll();
+ void RemoveUnlocked();
+
+ //-----------------
+ virtual void selectEntry( const long nPos );
+ long addEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager );
+ void updateEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+ void removeEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+
+ void prepareChecking( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageMgr );
+ void checkEntries();
+
+ TheExtensionManager* getExtensionManager() const { return m_pManager; }
+
+ //===================================================================================
+ //These functions are used for automatic testing
+
+ /** @return The count of the entries in the list box. */
+ virtual sal_Int32 getItemCount() const;
+
+ /** @return The index of the first selected entry in the list box.
+ When nothing is selected, which is the case when getItemCount returns '0',
+ then this function returns EXTENSION_LISTBOX_ENTRY_NOTFOUND */
+ virtual sal_Int32 getSelIndex() const;
+
+ /** @return The item name of the entry with the given index
+ The index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual ::rtl::OUString getItemName( sal_Int32 index ) const;
+
+ /** @return The version string of the entry with the given index
+ The index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual ::rtl::OUString getItemVersion( sal_Int32 index ) const;
+
+ /** @return The description string of the entry with the given index
+ The index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual ::rtl::OUString getItemDescription( sal_Int32 index ) const;
+
+ /** @return The publisher string of the entry with the given index
+ The index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual ::rtl::OUString getItemPublisher( sal_Int32 index ) const;
+
+ /** @return The link behind the publisher text of the entry with the given index
+ The index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual ::rtl::OUString getItemPublisherLink( sal_Int32 index ) const;
+
+ /** The entry at the given position will be selected
+ Index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual void select( sal_Int32 pos );
+
+ /** The first found entry with the given name will be selected
+ When there was no entry found with the name, the selection doesn't change.
+ Please note that there might be more than one entry with the same
+ name, because:
+ 1. the name is not unique
+ 2. one extension can be installed as user and shared extension.
+ */
+ virtual void select( const ::rtl::OUString & sName );
+};
+
+}
diff --git a/desktop/source/deployment/gui/dp_gui_service.cxx b/desktop/source/deployment/gui/dp_gui_service.cxx index 6e61e95f07cb..ee8c5d26c24f 100644 --- a/desktop/source/deployment/gui/dp_gui_service.cxx +++ b/desktop/source/deployment/gui/dp_gui_service.cxx @@ -48,6 +48,7 @@ #include "boost/bind.hpp" #include "license_dialog.hxx" +#include "dp_gui_dialog2.hxx" using namespace ::dp_misc; using namespace ::com::sun::star; @@ -271,27 +272,28 @@ void ServiceImpl::startExecuteModal( { const ::vos::OGuard guard( Application::GetSolarMutex() ); - ::rtl::Reference< ::dp_gui::TheExtensionManager > dialog( + ::rtl::Reference< ::dp_gui::TheExtensionManager > myExtMgr( ::dp_gui::TheExtensionManager::get( m_xComponentContext, m_parent ? *m_parent : Reference<awt::XWindow>(), m_extensionURL ? *m_extensionURL : OUString() ) ); + myExtMgr->createDialog( false ); if (m_initialTitle.getLength() > 0) { - dialog->SetText( m_initialTitle ); + myExtMgr->SetText( m_initialTitle ); m_initialTitle = OUString(); } if ( m_bShowUpdateOnly ) { - dialog->checkUpdates( true, !bCloseDialog ); + myExtMgr->checkUpdates( true, !bCloseDialog ); if ( bCloseDialog ) - dialog->Close(); + myExtMgr->Close(); else - dialog->ToTop( TOTOP_RESTOREWHENMIN ); + myExtMgr->ToTop( TOTOP_RESTOREWHENMIN ); } else { - dialog->Show(); - dialog->ToTop( TOTOP_RESTOREWHENMIN ); + myExtMgr->Show(); + myExtMgr->ToTop( TOTOP_RESTOREWHENMIN ); } } @@ -331,6 +333,12 @@ sdecl::ServiceDecl const licenseDecl( licenseSI, "com.sun.star.comp.deployment.ui.LicenseDialog", "com.sun.star.deployment.ui.LicenseDialog" ); + +sdecl::class_<UpdateRequiredDialogService, sdecl::with_args<true> > updateSI; +sdecl::ServiceDecl const updateDecl( + updateSI, + "com.sun.star.comp.deployment.ui.UpdateRequiredDialog", + "com.sun.star.deployment.ui.UpdateRequiredDialog" ); } // namespace dp_gui extern "C" { @@ -346,7 +354,7 @@ sal_Bool SAL_CALL component_writeInfo( registry::XRegistryKey * pRegistryKey ) { return component_writeInfoHelper( - pServiceManager, pRegistryKey, dp_gui::serviceDecl, dp_gui::licenseDecl ); + pServiceManager, pRegistryKey, dp_gui::serviceDecl, dp_gui::licenseDecl, dp_gui::updateDecl ); } void * SAL_CALL component_getFactory( @@ -355,7 +363,7 @@ void * SAL_CALL component_getFactory( registry::XRegistryKey * pRegistryKey ) { return component_getFactoryHelper( - pImplName, pServiceManager, pRegistryKey, dp_gui::serviceDecl, dp_gui::licenseDecl ); + pImplName, pServiceManager, pRegistryKey, dp_gui::serviceDecl, dp_gui::licenseDecl, dp_gui::updateDecl ); } } // extern "C" diff --git a/desktop/source/deployment/gui/dp_gui_theextmgr.cxx b/desktop/source/deployment/gui/dp_gui_theextmgr.cxx index 721d67c8f35b..3d994f31c395 100644 --- a/desktop/source/deployment/gui/dp_gui_theextmgr.cxx +++ b/desktop/source/deployment/gui/dp_gui_theextmgr.cxx @@ -66,7 +66,10 @@ namespace dp_gui { TheExtensionManager::TheExtensionManager( Window *pParent, const uno::Reference< uno::XComponentContext > &xContext ) : - m_xContext( xContext ) + m_xContext( xContext ), + m_pParent( pParent ), + m_pExtMgrDialog( NULL ), + m_pUpdReqDialog( NULL ) { if ( dp_misc::office_is_running() ) { @@ -76,10 +79,6 @@ TheExtensionManager::TheExtensionManager( Window *pParent, m_xDesktop->addTerminateListener( this ); } - m_pDialog = new ExtMgrDialog( pParent, this ); - - m_pExecuteCmdQueue.reset( new ExtensionCmdQueue( m_pDialog, this, xContext ) ); - m_sPackageManagers.realloc(2); m_sPackageManagers[0] = deployment::thePackageManagerFactory::get( m_xContext )->getPackageManager( OUSTR("user") ); m_sPackageManagers[1] = deployment::thePackageManagerFactory::get( m_xContext )->getPackageManager( OUSTR("shared") );; @@ -110,21 +109,43 @@ TheExtensionManager::TheExtensionManager( Window *pParent, uno::Sequence< uno::Any >( args, 1 )), uno::UNO_QUERY_THROW); try { //throws css::container::NoSuchElementException, css::lang::WrappedTargetException - OUString sURL; uno::Any value = xNameAccessRepositories->getByName( OUSTR( "WebsiteLink" ) ); - sURL = value.get< OUString > (); - m_pDialog->setGetExtensionsURL( sURL ); + m_sGetExtensionsURL = value.get< OUString > (); } catch ( uno::Exception& ) {} - - createPackageList(); } //------------------------------------------------------------------------------ TheExtensionManager::~TheExtensionManager() { - delete m_pDialog; + if ( m_pUpdReqDialog ) + delete m_pUpdReqDialog; + if ( m_pExtMgrDialog ) + delete m_pExtMgrDialog; +} + +//------------------------------------------------------------------------------ +void TheExtensionManager::createDialog( const bool bCreateUpdDlg ) +{ + const ::vos::OGuard guard( Application::GetSolarMutex() ); + + if ( bCreateUpdDlg ) + { + if ( !m_pUpdReqDialog ) + { + m_pUpdReqDialog = new UpdateRequiredDialog( NULL, this ); + m_pExecuteCmdQueue.reset( new ExtensionCmdQueue( (DialogHelper*) m_pUpdReqDialog, this, m_xContext ) ); + createPackageList(); + } + } + else if ( !m_pExtMgrDialog ) + { + m_pExtMgrDialog = new ExtMgrDialog( m_pParent, this ); + m_pExecuteCmdQueue.reset( new ExtensionCmdQueue( (DialogHelper*) m_pExtMgrDialog, this, m_xContext ) ); + m_pExtMgrDialog->setGetExtensionsURL( m_sGetExtensionsURL ); + createPackageList(); + } } //------------------------------------------------------------------------------ @@ -132,7 +153,7 @@ void TheExtensionManager::Show() { const ::vos::OGuard guard( Application::GetSolarMutex() ); - m_pDialog->Show(); + getDialog()->Show(); } //------------------------------------------------------------------------------ @@ -140,7 +161,7 @@ void TheExtensionManager::SetText( const ::rtl::OUString &rTitle ) { const ::vos::OGuard guard( Application::GetSolarMutex() ); - m_pDialog->SetText( rTitle ); + getDialog()->SetText( rTitle ); } //------------------------------------------------------------------------------ @@ -148,25 +169,69 @@ void TheExtensionManager::ToTop( USHORT nFlags ) { const ::vos::OGuard guard( Application::GetSolarMutex() ); - m_pDialog->ToTop( nFlags ); + getDialog()->ToTop( nFlags ); } //------------------------------------------------------------------------------ bool TheExtensionManager::Close() { - return m_pDialog->Close(); + if ( m_pExtMgrDialog ) + return m_pExtMgrDialog->Close(); + else if ( m_pUpdReqDialog ) + return m_pUpdReqDialog->Close(); + else + return true; +} + +//------------------------------------------------------------------------------ +sal_Int16 TheExtensionManager::execute() +{ + sal_Int16 nRet = 0; + + if ( m_pUpdReqDialog ) + { + nRet = m_pUpdReqDialog->Execute(); + delete m_pUpdReqDialog; + m_pUpdReqDialog = NULL; + } + + return nRet; } //------------------------------------------------------------------------------ bool TheExtensionManager::isVisible() { - return m_pDialog->IsVisible(); + return getDialog()->IsVisible(); } //------------------------------------------------------------------------------ bool TheExtensionManager::checkUpdates( bool /* bShowUpdateOnly */, bool /*bParentVisible*/ ) { - m_pExecuteCmdQueue->checkForUpdates( m_sPackageManagers ); + std::vector< TUpdateListEntry > vEntries; + + for ( sal_Int32 i = 0; i < m_sPackageManagers.getLength(); ++i ) + { + uno::Sequence< uno::Reference< deployment::XPackage > > xPackages; + try { + xPackages = m_sPackageManagers[i]->getDeployedPackages( uno::Reference< task::XAbortChannel >(), + uno::Reference< ucb::XCommandEnvironment >() ); + for ( sal_Int32 k = 0; k < xPackages.getLength(); ++k ) + { + TUpdateListEntry pEntry( new UpdateListEntry( xPackages[k], m_sPackageManagers[i] ) ); + vEntries.push_back( pEntry ); + } + } catch ( deployment::DeploymentException & ) { + continue; + } catch ( ucb::CommandFailedException & ) { + continue; + } catch ( ucb::CommandAbortedException & ) { + return true; + } catch ( lang::IllegalArgumentException & e ) { + throw uno::RuntimeException( e.Message, e.Context ); + } + } + + m_pExecuteCmdQueue->checkForUpdates( vEntries ); return true; } @@ -189,10 +254,9 @@ bool TheExtensionManager::removePackage( const uno::Reference< deployment::XPack } //------------------------------------------------------------------------------ -bool TheExtensionManager::updatePackage( const uno::Reference< deployment::XPackageManager > &xPackageManager, - const uno::Reference< deployment::XPackage > &xPackage ) +bool TheExtensionManager::updatePackages( const std::vector< TUpdateListEntry > &vList ) { - m_pExecuteCmdQueue->checkForUpdate( xPackageManager, xPackage ); + m_pExecuteCmdQueue->checkForUpdates( vList ); return true; } @@ -203,6 +267,8 @@ bool TheExtensionManager::installPackage( const OUString &rPackageURL, bool bWar if ( rPackageURL.getLength() == 0 ) return false; + createDialog( false ); + uno::Reference< deployment::XPackageManager > xUserPkgMgr = getUserPkgMgr(); uno::Reference< deployment::XPackageManager > xSharedPkgMgr = getSharedPkgMgr(); @@ -210,7 +276,7 @@ bool TheExtensionManager::installPackage( const OUString &rPackageURL, bool bWar bool bInstallForAll = false; if ( !bWarnUser && ! xSharedPkgMgr->isReadOnly() ) - bInstall = m_pDialog->installForAllUsers( bInstallForAll ); + bInstall = getDialogHelper()->installForAllUsers( bInstallForAll ); if ( !bInstall ) return false; @@ -239,8 +305,10 @@ void TheExtensionManager::terminateDialog() if ( ! dp_misc::office_is_running() ) { const ::vos::OGuard guard( Application::GetSolarMutex() ); - delete m_pDialog; - m_pDialog = NULL; + delete m_pExtMgrDialog; + m_pExtMgrDialog = NULL; + delete m_pUpdReqDialog; + m_pUpdReqDialog = NULL; Application::Quit(); } } @@ -252,7 +320,7 @@ bool TheExtensionManager::createPackageList( const uno::Reference< deployment::X try { packages = xPackageManager->getDeployedPackages( uno::Reference< task::XAbortChannel >(), - uno::Reference< ucb::XCommandEnvironment >() ); + uno::Reference< ucb::XCommandEnvironment >() ); } catch ( deployment::DeploymentException & ) { //handleGeneralError(e.Cause); return true; @@ -267,7 +335,7 @@ bool TheExtensionManager::createPackageList( const uno::Reference< deployment::X for ( sal_Int32 j = 0; j < packages.getLength(); ++j ) { - m_pDialog->addPackageToList( packages[j], xPackageManager ); + getDialogHelper()->addPackageToList( packages[j], xPackageManager ); } return true; @@ -381,8 +449,10 @@ void TheExtensionManager::disposing( lang::EventObject const & rEvt ) if ( dp_misc::office_is_running() ) { const ::vos::OGuard guard( Application::GetSolarMutex() ); - delete m_pDialog; - m_pDialog = NULL; + delete m_pExtMgrDialog; + m_pExtMgrDialog = NULL; + delete m_pUpdReqDialog; + m_pUpdReqDialog = NULL; } s_ExtMgr.clear(); } @@ -393,15 +463,22 @@ void TheExtensionManager::disposing( lang::EventObject const & rEvt ) void TheExtensionManager::queryTermination( ::lang::EventObject const & ) throw ( frame::TerminationVetoException, uno::RuntimeException ) { - if ( m_pExecuteCmdQueue->isBusy() || ( m_pDialog && m_pDialog->isBusy() ) ) + DialogHelper *pDialogHelper = getDialogHelper(); + + if ( m_pExecuteCmdQueue->isBusy() || ( pDialogHelper && pDialogHelper->isBusy() ) ) { ToTop( TOTOP_RESTOREWHENMIN ); throw frame::TerminationVetoException( OUSTR("The office cannot be closed while the Extension Manager is running"), uno::Reference<XInterface>(static_cast<frame::XTerminateListener*>(this), uno::UNO_QUERY)); } - else if ( m_pDialog ) - m_pDialog->Close(); + else + { + if ( m_pExtMgrDialog ) + m_pExtMgrDialog->Close(); + if ( m_pUpdReqDialog ) + m_pUpdReqDialog->Close(); + } } //------------------------------------------------------------------------------ @@ -419,9 +496,9 @@ void TheExtensionManager::modified( ::lang::EventObject const & rEvt ) uno::Reference< deployment::XPackageManager > xPackageManager( rEvt.Source, uno::UNO_QUERY ); if ( xPackageManager.is() ) { - m_pDialog->prepareChecking( xPackageManager ); + getDialogHelper()->prepareChecking( xPackageManager ); createPackageList( xPackageManager ); - m_pDialog->checkEntries(); + getDialogHelper()->checkEntries(); } } @@ -433,7 +510,8 @@ void TheExtensionManager::modified( ::lang::EventObject const & rEvt ) if ( s_ExtMgr.is() ) { OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); - s_ExtMgr->installPackage( extensionURL, true ); + if ( extensionURL.getLength() ) + s_ExtMgr->installPackage( extensionURL, true ); return s_ExtMgr; } @@ -450,7 +528,8 @@ void TheExtensionManager::modified( ::lang::EventObject const & rEvt ) s_ExtMgr = that; } - s_ExtMgr->installPackage( extensionURL, true ); + if ( extensionURL.getLength() ) + s_ExtMgr->installPackage( extensionURL, true ); return s_ExtMgr; } diff --git a/desktop/source/deployment/gui/dp_gui_theextmgr.hxx b/desktop/source/deployment/gui/dp_gui_theextmgr.hxx index 21516c683cc8..4ce6005a9346 100644 --- a/desktop/source/deployment/gui/dp_gui_theextmgr.hxx +++ b/desktop/source/deployment/gui/dp_gui_theextmgr.hxx @@ -44,12 +44,13 @@ #include "com/sun/star/util/XModifyListener.hpp" #include "dp_gui.h" +#include "dp_gui_dialog2.hxx" +#include "dp_gui_updatedata.hxx" //============================================================================== namespace dp_gui { //------------------------------------------------------------------------------ -class ExtMgrDialog; class ExtensionCmdQueue; //------------------------------------------------------------------------------ @@ -65,7 +66,11 @@ private: ::std::auto_ptr< ExtensionCmdQueue > m_pExecuteCmdQueue; - ExtMgrDialog *m_pDialog; + Window *m_pParent; + ExtMgrDialog *m_pExtMgrDialog; + UpdateRequiredDialog *m_pUpdReqDialog; + + ::rtl::OUString m_sGetExtensionsURL; // liste der packages ( xpackage?, mit parent manager, ... ) @@ -79,6 +84,12 @@ public: const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > &xContext ); ~TheExtensionManager(); + void createDialog( const bool bCreateUpdDlg ); + sal_Int16 execute(); + + Dialog* getDialog() { return m_pExtMgrDialog ? (Dialog*) m_pExtMgrDialog : (Dialog*) m_pUpdReqDialog; } + DialogHelper* getDialogHelper() { return m_pExtMgrDialog ? (DialogHelper*) m_pExtMgrDialog : (DialogHelper*) m_pUpdReqDialog; } + void SetText( const ::rtl::OUString &rTitle ); void Show(); void ToTop( USHORT nFlags ); @@ -87,12 +98,12 @@ public: //----------------- bool checkUpdates( bool showUpdateOnly, bool parentVisible ); + bool updatePackages( const std::vector< TUpdateListEntry > &vList ); + bool enablePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage, bool bEnable ); bool removePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager, const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ); - bool updatePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager, - const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ); bool installPackage( const ::rtl::OUString &rPackageURL, bool bWarnUser = false ); bool queryTermination(); diff --git a/desktop/source/deployment/gui/dp_gui_updatedata.hxx b/desktop/source/deployment/gui/dp_gui_updatedata.hxx index ba78112a26f7..610960b99734 100644 --- a/desktop/source/deployment/gui/dp_gui_updatedata.hxx +++ b/desktop/source/deployment/gui/dp_gui_updatedata.hxx @@ -34,6 +34,8 @@ #include "rtl/ustring.hxx" #include "com/sun/star/uno/Reference.hxx" +#include <boost/shared_ptr.hpp> + namespace com { namespace sun { namespace star { namespace deployment { class XPackageManager; @@ -46,6 +48,19 @@ namespace com { namespace sun { namespace star { namespace xml { namespace dom { namespace dp_gui { +struct UpdateListEntry +{ + ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> m_xPackage; + ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager> m_xPackageManager; + + UpdateListEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage, + const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager ); + ~UpdateListEntry(); +}; + +typedef ::boost::shared_ptr< UpdateListEntry > TUpdateListEntry; + + struct UpdateData { ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > aInstalledPackage; diff --git a/desktop/source/deployment/gui/dp_gui_updatedialog.cxx b/desktop/source/deployment/gui/dp_gui_updatedialog.cxx index 370d11c0de63..0e1955359bbc 100644 --- a/desktop/source/deployment/gui/dp_gui_updatedialog.cxx +++ b/desktop/source/deployment/gui/dp_gui_updatedialog.cxx @@ -229,9 +229,7 @@ public: Thread( css::uno::Reference< css::uno::XComponentContext > const & context, UpdateDialog & dialog, - rtl::Reference< dp_gui::SelectedPackage > const & selectedPackage, - css::uno::Sequence< css::uno::Reference< - css::deployment::XPackageManager > > const & packageManagers); + const std::vector< TUpdateListEntry > &vExtensionList); void stop(); @@ -285,9 +283,7 @@ private: css::uno::Reference< css::uno::XComponentContext > m_context; UpdateDialog & m_dialog; - rtl::Reference< dp_gui::SelectedPackage > m_selectedPackage; - css::uno::Sequence< css::uno::Reference< - css::deployment::XPackageManager > > m_packageManagers; + std::vector< dp_gui::TUpdateListEntry > m_vExtensionList; css::uno::Reference< css::deployment::XUpdateInformationProvider > m_updateInformation; @@ -299,13 +295,10 @@ private: UpdateDialog::Thread::Thread( css::uno::Reference< css::uno::XComponentContext > const & context, UpdateDialog & dialog, - rtl::Reference< dp_gui::SelectedPackage > const & selectedPackage, - css::uno::Sequence< css::uno::Reference< - css::deployment::XPackageManager > > const & packageManagers): + const std::vector< dp_gui::TUpdateListEntry > &vExtensionList): m_context(context), m_dialog(dialog), - m_selectedPackage(selectedPackage), - m_packageManagers(packageManagers), + m_vExtensionList(vExtensionList), m_updateInformation( css::deployment::UpdateInformationProvider::create(context)), m_stop(false) @@ -336,55 +329,28 @@ UpdateDialog::Thread::Entry::Entry( UpdateDialog::Thread::~Thread() {} -void UpdateDialog::Thread::execute() { - OSL_ASSERT(m_selectedPackage.is() != (m_packageManagers.getLength() != 0)); +void UpdateDialog::Thread::execute() +{ + OSL_ASSERT( ! m_vExtensionList.empty() ); Map map; - if (m_selectedPackage.is()) { - css::uno::Reference< css::deployment::XPackage > p = m_selectedPackage->getPackage(); - css::uno::Reference< css::deployment::XPackageManager > m= m_selectedPackage->getPackageManager(); + + typedef std::vector< TUpdateListEntry >::const_iterator ITER; + for ( ITER iIndex = m_vExtensionList.begin(); iIndex < m_vExtensionList.end(); ++iIndex ) + { + css::uno::Reference< css::deployment::XPackage > p = (*iIndex)->m_xPackage; + css::uno::Reference< css::deployment::XPackageManager > m = (*iIndex)->m_xPackageManager; if ( p.is() ) { - handle(p, m, &map); - } - } else { - for (sal_Int32 i = 0; i < m_packageManagers.getLength(); ++i) { - css::uno::Reference< css::task::XAbortChannel > abort( - m_packageManagers[i]->createAbortChannel()); { - vos::OGuard g(Application::GetSolarMutex()); - if (m_stop) { + vos::OGuard g( Application::GetSolarMutex() ); + if ( m_stop ) { return; } - m_abort = abort; - } - css::uno::Sequence< - css::uno::Reference< css::deployment::XPackage > > ps; - try { - ps = m_packageManagers[i]->getDeployedPackages( - abort, - css::uno::Reference< css::ucb::XCommandEnvironment >()); - } catch (css::deployment::DeploymentException & e) { - handleGeneralError(e.Cause); - continue; - } catch (css::ucb::CommandFailedException & e) { - handleGeneralError(e.Reason); - continue; - } catch (css::ucb::CommandAbortedException &) { - return; - } catch (css::lang::IllegalArgumentException & e) { - throw css::uno::RuntimeException(e.Message, e.Context); - } - for (sal_Int32 j = 0; j < ps.getLength(); ++j) { - { - vos::OGuard g(Application::GetSolarMutex()); - if (m_stop) { - return; - } - } - handle(ps[j], m_packageManagers[i], &map); } + handle( p, m, &map ); } } + if (!map.empty()) { const rtl::OUString sDefaultURL(dp_misc::getExtensionDefaultUpdateURL()); if (sDefaultURL.getLength()) @@ -597,9 +563,7 @@ bool UpdateDialog::Thread::update( UpdateDialog::UpdateDialog( css::uno::Reference< css::uno::XComponentContext > const & context, Window * parent, - rtl::Reference< dp_gui::SelectedPackage > const & selectedPackage, - css::uno::Sequence< css::uno::Reference< - css::deployment::XPackageManager > > const & packageManagers, + const std::vector< dp_gui::TUpdateListEntry > &vExtensionList, std::vector< dp_gui::UpdateData > * updateData): ModalDialog(parent,DpGuiResId(RID_DLG_UPDATE)), m_context(context), @@ -636,14 +600,12 @@ UpdateDialog::UpdateDialog( m_updateData(*updateData), m_thread( new UpdateDialog::Thread( - context, *this, selectedPackage, - packageManagers)), + context, *this, vExtensionList)), m_nFirstLineDelta(0), m_nOneLineMissing(0) // TODO: check! // , // m_extensionManagerDialog(extensionManagerDialog) - { OSL_ASSERT(updateData != NULL); css::uno::Reference< css::awt::XToolkit > toolkit; @@ -1310,4 +1272,3 @@ IMPL_LINK( UpdateDialog, hyperlink_clicked, svt::FixedHyperlink*, pHyperlink ) return 1; } - diff --git a/desktop/source/deployment/gui/dp_gui_updatedialog.hxx b/desktop/source/deployment/gui/dp_gui_updatedialog.hxx index b038c0ef042f..578ad6b6f01d 100644 --- a/desktop/source/deployment/gui/dp_gui_updatedialog.hxx +++ b/desktop/source/deployment/gui/dp_gui_updatedialog.hxx @@ -48,6 +48,7 @@ #include <svtools/fixedhyper.hxx> #include "descedit.hxx" +#include "dp_gui_updatedata.hxx" /// @HTML @@ -56,18 +57,14 @@ class KeyEvent; class MouseEvent; class ResId; class Window; + namespace com { namespace sun { namespace star { namespace awt { class XThrobber; } namespace deployment { class XPackageManager; } namespace uno { class XComponentContext; } } } } -namespace dp_gui { - class SelectedPackage; - struct UpdateData; -} namespace dp_gui { - /** The modal “Check for Updates” dialog. */ @@ -92,13 +89,9 @@ public: if non-null, check for updates for all managed packages */ UpdateDialog( - com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > - const & context, + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > const & context, Window * parent, - rtl::Reference< dp_gui::SelectedPackage > const & selectedPackage, - com::sun::star::uno::Sequence< com::sun::star::uno::Reference< - com::sun::star::deployment::XPackageManager > > const & - packageManagers, + const std::vector< dp_gui::TUpdateListEntry > &vExtensionList, std::vector< dp_gui::UpdateData > * updateData); ~UpdateDialog(); diff --git a/desktop/source/deployment/gui/makefile.mk b/desktop/source/deployment/gui/makefile.mk index e3211ab7f73f..4d563ae1591a 100644 --- a/desktop/source/deployment/gui/makefile.mk +++ b/desktop/source/deployment/gui/makefile.mk @@ -50,6 +50,7 @@ DLLPRE = SLOFILES = \ $(SLO)$/dp_gui_service.obj \ + $(SLO)$/dp_gui_extlistbox.obj \ $(SLO)$/dp_gui_dialog2.obj \ $(SLO)$/dp_gui_theextmgr.obj \ $(SLO)$/license_dialog.obj \ diff --git a/desktop/source/deployment/registry/dp_backend.cxx b/desktop/source/deployment/registry/dp_backend.cxx index 7f6d003f8577..aa67536bd425 100644 --- a/desktop/source/deployment/registry/dp_backend.cxx +++ b/desktop/source/deployment/registry/dp_backend.cxx @@ -296,6 +296,7 @@ sal_Bool Package::isBundle() throw (RuntimeException) return false; // default } +//______________________________________________________________________________ ::sal_Bool Package::checkPrerequisites( const css::uno::Reference< css::task::XAbortChannel >&, const css::uno::Reference< css::ucb::XCommandEnvironment >&, @@ -308,6 +309,16 @@ sal_Bool Package::isBundle() throw (RuntimeException) return true; } +//______________________________________________________________________________ +::sal_Bool Package::checkDependencies( + const css::uno::Reference< css::ucb::XCommandEnvironment >& ) + throw (css::deployment::DeploymentException, + css::ucb::CommandFailedException, + css::uno::RuntimeException) +{ + return true; +} + //______________________________________________________________________________ Sequence< Reference<deployment::XPackage> > Package::getBundle( diff --git a/desktop/source/deployment/registry/inc/dp_backend.h b/desktop/source/deployment/registry/inc/dp_backend.h index 02e1d79ce2c3..256d4680d795 100644 --- a/desktop/source/deployment/registry/inc/dp_backend.h +++ b/desktop/source/deployment/registry/inc/dp_backend.h @@ -177,6 +177,12 @@ public: css::ucb::CommandAbortedException, css::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL checkDependencies( + const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv ) + throw (css::deployment::DeploymentException, + css::ucb::CommandFailedException, + css::uno::RuntimeException); + virtual void SAL_CALL registerPackage( css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv ) diff --git a/desktop/source/deployment/registry/package/dp_package.cxx b/desktop/source/deployment/registry/package/dp_package.cxx index e39f5e80fc31..14075d0fca38 100644 --- a/desktop/source/deployment/registry/package/dp_package.cxx +++ b/desktop/source/deployment/registry/package/dp_package.cxx @@ -205,6 +205,12 @@ class BackendImpl : public ImplBaseT css::ucb::CommandAbortedException, css::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL checkDependencies( + const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv ) + throw (css::deployment::DeploymentException, + css::ucb::CommandFailedException, + css::uno::RuntimeException); + virtual beans::Optional<OUString> SAL_CALL getIdentifier() throw (RuntimeException); @@ -702,6 +708,22 @@ bool BackendImpl::PackageImpl::checkDependencies( && checkLicense(xCmdEnv, *spDescription, bInstalled, aContextName); } +::sal_Bool BackendImpl::PackageImpl::checkDependencies( + const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv ) + throw (css::deployment::DeploymentException, + css::ucb::CommandFailedException, + css::uno::RuntimeException) +{ + std::auto_ptr<ExtensionDescription> spDescription; + try { + spDescription.reset( + new ExtensionDescription( getMyBackend()->getComponentContext(), m_url_expanded, xCmdEnv )); + } catch (NoDescriptionException& ) { + return sal_True; + } + return checkDependencies(xCmdEnv, *spDescription); +} + beans::Optional<OUString> BackendImpl::PackageImpl::getIdentifier() throw (RuntimeException) { diff --git a/desktop/source/inc/helpid.hrc b/desktop/source/inc/helpid.hrc index 1d10a9f6fbbe..f2d096460bed 100644 --- a/desktop/source/inc/helpid.hrc +++ b/desktop/source/inc/helpid.hrc @@ -66,7 +66,11 @@ #define HID_EXTENSION_MANAGER_LISTBOX_DISABLE (HID_DESKTOP_START + 26) #define HID_EXTENSION_MANAGER_LISTBOX_REMOVE (HID_DESKTOP_START + 27) -#define ACT_DESKTOP_HID_END HID_EXTENSION_MANAGER_LISTBOX_REMOVE +#define HID_EXTENSION_DEPENDENCIES (HID_DESKTOP_START + 28) + +#define HID_PACKAGE_MANAGER_UPD_REQ (HID_DESKTOP_START + 29) + +#define ACT_DESKTOP_HID_END HID_PACKAGE_MANAGER_UPD_REQ // check bounds: #if ACT_DESKTOP_HID_END > HID_DESKTOP_END diff --git a/desktop/util/hidother.src b/desktop/util/hidother.src index f4d06d3fa72b..6f5a86159d75 100644 --- a/desktop/util/hidother.src +++ b/desktop/util/hidother.src @@ -36,6 +36,8 @@ hidspecial HID_PACKAGE_MANAGER_TREELISTBOX { HelpID = HID_PACKAGE_MANAGER_TREELI hidspecial HID_PACKAGE_MANAGER_PROGRESS { HelpID = HID_PACKAGE_MANAGER_PROGRESS; }; hidspecial HID_PACKAGE_MANAGER_PROGRESS_CANCEL { HelpID = HID_PACKAGE_MANAGER_PROGRESS_CANCEL; }; +hidspecial HID_PACKAGE_MANAGER_UPD_REQ { HelpID = HID_PACKAGE_MANAGER_UPD_REQ; }; + hidspecial HID_FIRSTSTART_PREV { HelpId = HID_FIRSTSTART_PREV;}; hidspecial HID_FIRSTSTART_NEXT { HelpId = HID_FIRSTSTART_NEXT;}; hidspecial HID_FIRSTSTART_CANCEL { HelpId = HID_FIRSTSTART_CANCEL;}; @@ -45,7 +47,7 @@ hidspecial UID_FIRSTSTART_HELP { HelpId = UID_FIRSTSTART_HELP;}; hidspecial UID_BTN_LICENSE_ACCEPT { HelpId = UID_BTN_LICENSE_ACCEPT;}; hidspecial HID_DEPLOYMENT_GUI_UPDATE { HelpId = HID_DEPLOYMENT_GUI_UPDATE;}; -hidspecial HID_DEPLOYMENT_GUI_UPDATE { HelpId = HID_DEPLOYMENT_GUI_UPDATEINSTALL;}; +hidspecial HID_DEPLOYMENT_GUI_UPDATEINSTALL { HelpId = HID_DEPLOYMENT_GUI_UPDATEINSTALL;}; hidspecial HID_EXTENSION_MANAGER_LISTBOX { HelpId = HID_EXTENSION_MANAGER_LISTBOX; }; hidspecial HID_EXTENSION_MANAGER_LISTBOX_OPTIONS { HelpId = HID_EXTENSION_MANAGER_LISTBOX_OPTIONS; }; diff --git a/officecfg/registry/schema/org/openoffice/Setup.xcs b/officecfg/registry/schema/org/openoffice/Setup.xcs index 7572879528da..ad6b4d9ce425 100644 --- a/officecfg/registry/schema/org/openoffice/Setup.xcs +++ b/officecfg/registry/schema/org/openoffice/Setup.xcs @@ -352,6 +352,13 @@ </info> <value>false</value> </prop> + <prop oor:name="LastCompatibilityCheckID" oor:type="xs:string"> + <info> + <author>DV</author> + <desc>The build ID of the office. On startup the office will compare this ID with the current build id to decide if the extensions dependencies need to be checked.</desc> + </info> + <value>not checked</value> + </prop> <set oor:name="Factories" oor:node-type="Factory"> <info> <author>AS</author> |