Commits

releng  committed 865200f

CWS-TOOLING: integrate CWS extmgr01
2009-07-28 15:37:52 +0200 dv r274410 : #i103856# Create dialog before using it
2009-07-27 15:24:42 +0200 dv r274368 : #i103831# Made selectEntry virtual so the correct function will be used from the listbox with buttons
2009-07-27 14:17:08 +0200 dv r274366 : #i103831# Made selectEntry virtual so the correct function will be used from the listbox with buttons
2009-07-07 08:23:17 +0200 dv r273765 : #i102666# Extension check on startup after office update -> fixed repaint problem
2009-07-06 11:28:28 +0200 dv r273729 : #i102666# Extension check on startup after office update -> fixed Mac OS X issues
2009-07-02 15:01:35 +0200 dv r273654 : #i102666# Extension check on startup after office update -> set last checked to never when aborting
2009-07-01 12:18:52 +0200 dv r273564 : Removed unused variable
2009-07-01 07:25:01 +0200 dv r273542 : #i102666# Extension check on startup after office update -> better layout
2009-06-30 14:56:16 +0200 dv r273506 : #i102666# Extension check on startup after office update -> mark incompatible extensions in extension manager
2009-06-30 12:43:55 +0200 dv r273502 : CWS-TOOLING: rebase CWS extmgr01 to trunk@273468 (milestone: DEV300:m51)
2009-06-29 13:26:54 +0200 dv r273469 : Now with newline at the end
2009-06-29 11:54:07 +0200 dv r273462 : #i102666# Extension check on startup after office update -> exit button of dialog disables extensions, too
2009-06-26 16:26:02 +0200 dv r273428 : #i102666# Extension check on startup after office update -> better progress handling
2009-06-26 14:50:34 +0200 dv r273417 : fixed crash when shutting down while initial waiting
2009-06-26 14:46:40 +0200 dv r273416 : #i102666# Extension check on startup after office update
2009-06-24 07:30:57 +0200 dv r273306 : #i102666# Extension check on startup after update
2009-06-11 12:03:10 +0200 dv r272863 : #i102666# Extension check on startup after update
2009-06-11 11:59:29 +0200 dv r272862 : #i102666# Extension check on startup after update
2009-06-09 15:50:05 +0200 dv r272773 : CWS-TOOLING: rebase CWS extmgr01 to trunk@272291 (milestone: DEV300:m49)

  • Participants
  • Parent commits 4500120

Comments (0)

Files changed (31)

File desktop/inc/app.hxx

         static rtl::OUString    GetLicensePath();
         static sal_Bool         LicenseNeedsAcceptance();
         static sal_Bool         IsFirstStartWizardNeeded();
+        static sal_Bool         CheckExtensionDependencies();
 
 	private:
 		// Bootstrap methods

File desktop/source/app/app.cxx

         tools::InitTestToolLib();
         RTL_LOGFILE_CONTEXT_TRACE( aLog, "} tools::InitTestToolLib" );
 
+        bool bAbort = CheckExtensionDependencies();
+        if ( bAbort )
+            return;
+
         // First Start Wizard allowed ?
         if ( ! pCmdLineArgs->IsNoFirstStartWizard())
         {

File desktop/source/app/check_ext_deps.cxx

+/*************************************************************************
+ *
+ * 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;
+}
+

File desktop/source/app/makefile.mk

     $(SLO)$/appsys.obj \
     $(SLO)$/cfgfilter.obj \
     $(SLO)$/checkinstall.obj \
+    $(SLO)$/check_ext_deps.obj \
     $(SLO)$/cmdlineargs.obj \
     $(SLO)$/cmdlinehelp.obj \
     $(SLO)$/configinit.obj \

File desktop/source/deployment/gui/dp_gui.h

 
 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 ),

File desktop/source/deployment/gui/dp_gui.hrc

 #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
 #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
 #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)
 #define RID_IMG_EXTENSION                      (RID_DEPLOYMENT_GUI_START+60)
 #define RID_IMG_EXTENSION_HC                   (RID_DEPLOYMENT_GUI_START+61)
 
+#define RID_STR_ADD_PACKAGES                   (RID_DEPLOYMENT_GUI_START+70)
 
-#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_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_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_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)
 

File desktop/source/deployment/gui/dp_gui_dialog.src

 #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";
 {
     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";
     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";
     Text [ en-US ] = "~Only for me";
 };
 
-String RID_STR_PUBLISHER_LINK
-{
-    Text [ en-US ] = "Publisher";
-};
-
 String RID_STR_ERROR_UNKNOWN_STATUS
 {
     Text [ en-US ] = "Error: The status of this extension is unknown";
 };
 
+String RID_STR_CLOSE_BTN
+{
+    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
 // ---------------------------------------------------
 //	row 1 | multi line edit

File desktop/source/deployment/gui/dp_gui_dialog2.cxx

 #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"
 
 #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"
 #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>
 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
 };
 
 //------------------------------------------------------------------------------
-//                          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;
-};
+UpdateListEntry::UpdateListEntry( const uno::Reference< deployment::XPackage > &xPackage,
+                                  const uno::Reference< deployment::XPackageManager > &xPackageManager ) :
+    m_xPackage( xPackage ),
+    m_xPackageManager( xPackageManager )
+{}
 
 //------------------------------------------------------------------------------
-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 ),
-    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 );
-}
+UpdateListEntry::~UpdateListEntry()
+{}
 
 //------------------------------------------------------------------------------
-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;
-}
-
-//------------------------------------------------------------------------------
-//                            ExtensionBox_Impl
+//                            ExtBoxWithBtns_Impl
 //------------------------------------------------------------------------------
 
 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;
+    Size            m_aOutputSize;
     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;
     
     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;
+    ExtMgrDialog   *m_pParent;
 
-	lang::Locale    *m_pLocale;
-	CollatorWrapper *m_pCollator;
-
-    void            CalcActiveHeight( const long nPos );
-    long            GetTotalHeight() const;
-    Rectangle       GetEntryRect( const long nPos ) const;
     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 * );
     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 );
     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 ) );
     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;
+    SetExtraSize( aSize.Height() + 2 * 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 );
-
-    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
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+const Size ExtBoxWithBtns_Impl::GetMinOutputSizePixel() 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 );
-}
-
-//------------------------------------------------------------------------------
-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;
+    {
+        m_pOptionsBtn->Hide();
+        m_pEnableBtn->Hide();
+        m_pRemoveBtn->Hide();
+    }
+}
 
-    Point aPos( 0, -m_nTopIndex + nPos * m_nStdHeight );
-    if ( m_bHasActive && ( nPos < m_nActive ) )
-        aPos.Y() += m_nActiveHeight - m_nStdHeight;
-
-    return Rectangle( aPos, aSize );
-}
 
 //------------------------------------------------------------------------------
 //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 )
+    ExtensionBox_Impl::selectEntry( nPos );
+
+    if ( ( nPos >= 0 ) && ( nPos < GetEntryCount() ) )
     {
-        if ( nPos == m_nActive )
-            return;
-
-        m_bHasActive = false;
-        m_vEntries[ m_nActive ]->m_bActive = false;
-
-        if ( IsReallyVisible() )
-            Invalidate();
-    }
-
-    if ( ( nPos >= 0 ) && ( nPos < (long) m_vEntries.size() ) )
-    {
-        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
     {
         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,
 }
 
 // -----------------------------------------------------------------------
-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
     {
 }
 
 // -----------------------------------------------------------------------
-void ExtensionBox_Impl::DrawRow( const Rectangle& rRect, const TEntry_Impl pEntry )
+bool ExtBoxWithBtns_Impl::HandleTabKey( bool bReverse )
 {
-    const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+    sal_Int32 nIndex = getSelIndex();
 
-    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 );
-    }
-
-    // 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() ) {
     }
     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;
         }
     }
 }
 
 // -----------------------------------------------------------------------
-bool ExtensionBox_Impl::HandleCursorKey( USHORT nKeyCode )
+MENU_COMMAND ExtBoxWithBtns_Impl::ShowPopupMenu( const Point & rPos, const long nPos )
 {
-    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 )
-{
-    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;
 
 
         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;
-            }
-        }
     }