LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/desktop/source/deployment/gui - dp_gui_extlistbox.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 658 0.0 %
Date: 2013-07-09 Functions: 0 57 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "svtools/controldims.hrc"
      21             : 
      22             : #include "dp_gui.h"
      23             : #include "dp_gui_extlistbox.hxx"
      24             : #include "dp_gui_theextmgr.hxx"
      25             : #include "dp_gui_dialog2.hxx"
      26             : #include "dp_dependencies.hxx"
      27             : 
      28             : #include "comphelper/processfactory.hxx"
      29             : #include "com/sun/star/i18n/CollatorOptions.hpp"
      30             : #include "com/sun/star/deployment/DependencyException.hpp"
      31             : #include "com/sun/star/deployment/DeploymentException.hpp"
      32             : #include "cppuhelper/weakref.hxx"
      33             : 
      34             : #define USER_PACKAGE_MANAGER    "user"
      35             : #define SHARED_PACKAGE_MANAGER  "shared"
      36             : 
      37             : using namespace ::com::sun::star;
      38             : 
      39             : namespace dp_gui {
      40             : 
      41             : namespace {
      42             : 
      43           0 : struct FindWeakRef
      44             : {
      45             :     const uno::Reference<deployment::XPackage> m_extension;
      46             : 
      47           0 :     FindWeakRef( uno::Reference<deployment::XPackage> const & ext): m_extension(ext) {}
      48             :     bool operator () (uno::WeakReference< deployment::XPackage >  const & ref);
      49             : };
      50             : 
      51           0 : bool FindWeakRef::operator () (uno::WeakReference< deployment::XPackage >  const & ref)
      52             : {
      53           0 :     const uno::Reference<deployment::XPackage> ext(ref);
      54           0 :     if (ext == m_extension)
      55           0 :         return true;
      56           0 :     return false;
      57             : }
      58             : 
      59             : } // end namespace
      60             : //------------------------------------------------------------------------------
      61             : //                          struct Entry_Impl
      62             : //------------------------------------------------------------------------------
      63           0 : Entry_Impl::Entry_Impl( const uno::Reference< deployment::XPackage > &xPackage,
      64             :                         const PackageState eState, const bool bReadOnly ) :
      65             :     m_bActive( false ),
      66             :     m_bLocked( bReadOnly ),
      67             :     m_bHasOptions( false ),
      68             :     m_bUser( false ),
      69             :     m_bShared( false ),
      70             :     m_bNew( false ),
      71             :     m_bChecked( false ),
      72             :     m_bMissingDeps( false ),
      73             :     m_bHasButtons( false ),
      74             :     m_bMissingLic( false ),
      75             :     m_eState( eState ),
      76             :     m_pPublisher( NULL ),
      77           0 :     m_xPackage( xPackage )
      78             : {
      79             :     try
      80             :     {
      81           0 :         m_sTitle = xPackage->getDisplayName();
      82           0 :         m_sVersion = xPackage->getVersion();
      83           0 :         m_sDescription = xPackage->getDescription();
      84           0 :     m_sLicenseText = xPackage->getLicenseText();
      85             : 
      86           0 :         beans::StringPair aInfo( m_xPackage->getPublisherInfo() );
      87           0 :         m_sPublisher = aInfo.First;
      88           0 :         m_sPublisherURL = aInfo.Second;
      89             : 
      90             :         // get the icons for the package if there are any
      91           0 :         uno::Reference< graphic::XGraphic > xGraphic = xPackage->getIcon( false );
      92           0 :         if ( xGraphic.is() )
      93           0 :             m_aIcon = Image( xGraphic );
      94             : 
      95           0 :         xGraphic = xPackage->getIcon( true );
      96           0 :         if ( xGraphic.is() )
      97           0 :             m_aIconHC = Image( xGraphic );
      98             :         else
      99           0 :             m_aIconHC = m_aIcon;
     100             : 
     101           0 :         if ( eState == AMBIGUOUS )
     102           0 :             m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS );
     103           0 :         else if ( eState == NOT_REGISTERED )
     104           0 :             checkDependencies();
     105             :     }
     106           0 :     catch (const deployment::ExtensionRemovedException &) {}
     107           0 :     catch (const uno::RuntimeException &) {}
     108           0 : }
     109             : 
     110             : //------------------------------------------------------------------------------
     111           0 : Entry_Impl::~Entry_Impl()
     112           0 : {}
     113             : 
     114             : //------------------------------------------------------------------------------
     115           0 : StringCompare Entry_Impl::CompareTo( const CollatorWrapper *pCollator, const TEntry_Impl pEntry ) const
     116             : {
     117           0 :     StringCompare eCompare = (StringCompare) pCollator->compareString( m_sTitle, pEntry->m_sTitle );
     118           0 :     if ( eCompare == COMPARE_EQUAL )
     119             :     {
     120           0 :         eCompare = m_sVersion.CompareTo( pEntry->m_sVersion );
     121           0 :         if ( eCompare == COMPARE_EQUAL )
     122             :         {
     123           0 :             sal_Int32 nCompare = m_xPackage->getRepositoryName().compareTo( pEntry->m_xPackage->getRepositoryName() );
     124           0 :             if ( nCompare < 0 )
     125           0 :                 eCompare = COMPARE_LESS;
     126           0 :             else if ( nCompare > 0 )
     127           0 :                 eCompare = COMPARE_GREATER;
     128             :         }
     129             :     }
     130           0 :     return eCompare;
     131             : }
     132             : 
     133             : //------------------------------------------------------------------------------
     134           0 : void Entry_Impl::checkDependencies()
     135             : {
     136             :     try {
     137           0 :         m_xPackage->checkDependencies( uno::Reference< ucb::XCommandEnvironment >() );
     138             :     }
     139           0 :     catch ( const deployment::DeploymentException &e )
     140             :     {
     141           0 :         deployment::DependencyException depExc;
     142           0 :         if ( e.Cause >>= depExc )
     143             :         {
     144           0 :             OUString aMissingDep( DialogHelper::getResourceString( RID_STR_ERROR_MISSING_DEPENDENCIES ) );
     145           0 :             for ( sal_Int32 i = 0; i < depExc.UnsatisfiedDependencies.getLength(); ++i )
     146             :             {
     147           0 :                 aMissingDep += "\n";
     148           0 :                 aMissingDep += dp_misc::Dependencies::getErrorText( depExc.UnsatisfiedDependencies[i]);
     149             :             }
     150           0 :             aMissingDep += "\n";
     151           0 :             m_sErrorText = aMissingDep;
     152           0 :             m_bMissingDeps = true;
     153           0 :         }
     154             :     }
     155           0 : }
     156             : //------------------------------------------------------------------------------
     157             : // ExtensionRemovedListener
     158             : //------------------------------------------------------------------------------
     159           0 : void ExtensionRemovedListener::disposing( lang::EventObject const & rEvt )
     160             :     throw ( uno::RuntimeException )
     161             : {
     162           0 :     uno::Reference< deployment::XPackage > xPackage( rEvt.Source, uno::UNO_QUERY );
     163             : 
     164           0 :     if ( xPackage.is() )
     165             :     {
     166           0 :         m_pParent->removeEntry( xPackage );
     167           0 :     }
     168           0 : }
     169             : 
     170             : //------------------------------------------------------------------------------
     171           0 : ExtensionRemovedListener::~ExtensionRemovedListener()
     172             : {
     173           0 : }
     174             : 
     175             : //------------------------------------------------------------------------------
     176             : // ExtensionBox_Impl
     177             : //------------------------------------------------------------------------------
     178           0 : ExtensionBox_Impl::ExtensionBox_Impl( Window* pParent, TheExtensionManager *pManager ) :
     179             :     IExtensionListBox( pParent, WB_BORDER | WB_TABSTOP | WB_CHILDDLGCTRL ),
     180             :     m_bHasScrollBar( false ),
     181             :     m_bHasActive( false ),
     182             :     m_bNeedsRecalc( true ),
     183             :     m_bInCheckMode( false ),
     184             :     m_bAdjustActive( false ),
     185             :     m_bInDelete( false ),
     186             :     m_nActive( 0 ),
     187             :     m_nTopIndex( 0 ),
     188             :     m_nActiveHeight( 0 ),
     189             :     m_nExtraHeight( 2 ),
     190             :     m_aSharedImage( DialogHelper::getResId( RID_IMG_SHARED ) ),
     191             :     m_aLockedImage( DialogHelper::getResId( RID_IMG_LOCKED ) ),
     192             :     m_aWarningImage( DialogHelper::getResId( RID_IMG_WARNING ) ),
     193             :     m_aDefaultImage( DialogHelper::getResId( RID_IMG_EXTENSION ) ),
     194             :     m_pScrollBar( NULL ),
     195           0 :     m_pManager( pManager )
     196             : {
     197           0 :     Init();
     198           0 : }
     199             : 
     200           0 : ExtensionBox_Impl::ExtensionBox_Impl(Window* pParent) :
     201             :     IExtensionListBox( pParent, WB_BORDER | WB_TABSTOP | WB_CHILDDLGCTRL ),
     202             :     m_bHasScrollBar( false ),
     203             :     m_bHasActive( false ),
     204             :     m_bNeedsRecalc( true ),
     205             :     m_bInCheckMode( false ),
     206             :     m_bAdjustActive( false ),
     207             :     m_bInDelete( false ),
     208             :     m_nActive( 0 ),
     209             :     m_nTopIndex( 0 ),
     210             :     m_nActiveHeight( 0 ),
     211             :     m_nExtraHeight( 2 ),
     212             :     m_aSharedImage( DialogHelper::getResId( RID_IMG_SHARED ) ),
     213             :     m_aLockedImage( DialogHelper::getResId( RID_IMG_LOCKED ) ),
     214             :     m_aWarningImage( DialogHelper::getResId( RID_IMG_WARNING ) ),
     215             :     m_aDefaultImage( DialogHelper::getResId( RID_IMG_EXTENSION ) ),
     216             :     m_pScrollBar( NULL ),
     217           0 :     m_pManager( NULL )
     218             : {
     219           0 :     Init();
     220           0 : }
     221             : 
     222           0 : void ExtensionBox_Impl::Init()
     223             : {
     224           0 :     SetHelpId( HID_EXTENSION_MANAGER_LISTBOX );
     225             : 
     226           0 :     m_pScrollBar = new ScrollBar( this, WB_VERT );
     227           0 :     m_pScrollBar->SetScrollHdl( LINK( this, ExtensionBox_Impl, ScrollHdl ) );
     228           0 :     m_pScrollBar->EnableDrag();
     229             : 
     230           0 :     SetPaintTransparent( true );
     231           0 :     SetPosPixel( Point( RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP ) );
     232           0 :     long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
     233           0 :     long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
     234           0 :     if ( nIconHeight < nTitleHeight )
     235           0 :         m_nStdHeight = nTitleHeight;
     236             :     else
     237           0 :         m_nStdHeight = nIconHeight;
     238           0 :     m_nStdHeight += GetTextHeight() + TOP_OFFSET;
     239             : 
     240           0 :     nIconHeight = ICON_HEIGHT + 2*TOP_OFFSET + 1;
     241           0 :     if ( m_nStdHeight < nIconHeight )
     242           0 :         m_nStdHeight = nIconHeight;
     243             : 
     244           0 :     m_nActiveHeight = m_nStdHeight;
     245             : 
     246           0 :     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
     247           0 :     if( IsControlBackground() )
     248           0 :         SetBackground( GetControlBackground() );
     249             :     else
     250           0 :         SetBackground( rStyleSettings.GetFieldColor() );
     251             : 
     252           0 :     m_xRemoveListener = new ExtensionRemovedListener( this );
     253             : 
     254           0 :     m_pLocale = new lang::Locale( Application::GetSettings().GetLanguageTag().getLocale() );
     255           0 :     m_pCollator = new CollatorWrapper( ::comphelper::getProcessComponentContext() );
     256           0 :     m_pCollator->loadDefaultCollator( *m_pLocale, i18n::CollatorOptions::CollatorOptions_IGNORE_CASE );
     257             : 
     258           0 :     Show();
     259           0 : }
     260             : 
     261             : //------------------------------------------------------------------------------
     262           0 : ExtensionBox_Impl::~ExtensionBox_Impl()
     263             : {
     264           0 :     if ( ! m_bInDelete )
     265           0 :         DeleteRemoved();
     266             : 
     267           0 :     m_bInDelete = true;
     268             : 
     269             :     typedef std::vector< TEntry_Impl >::iterator ITER;
     270             : 
     271           0 :     for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
     272             :     {
     273           0 :         if ( (*iIndex)->m_pPublisher )
     274             :         {
     275           0 :             delete (*iIndex)->m_pPublisher;
     276           0 :             (*iIndex)->m_pPublisher = NULL;
     277             :         }
     278           0 :         (*iIndex)->m_xPackage->removeEventListener( uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
     279             :     }
     280             : 
     281           0 :     m_vEntries.clear();
     282             : 
     283           0 :     delete m_pScrollBar;
     284             : 
     285           0 :     m_xRemoveListener.clear();
     286             : 
     287           0 :     delete m_pLocale;
     288           0 :     delete m_pCollator;
     289           0 : }
     290             : 
     291             : //------------------------------------------------------------------------------
     292           0 : sal_Int32 ExtensionBox_Impl::getItemCount() const
     293             : {
     294           0 :     return static_cast< sal_Int32 >( m_vEntries.size() );
     295             : }
     296             : 
     297             : //------------------------------------------------------------------------------
     298           0 : sal_Int32 ExtensionBox_Impl::getSelIndex() const
     299             : {
     300           0 :     if ( m_bHasActive )
     301             :     {
     302             :         OSL_ASSERT( m_nActive >= -1);
     303           0 :         return static_cast< sal_Int32 >( m_nActive );
     304             :     }
     305             :     else
     306           0 :         return ENTRY_NOTFOUND;
     307             : }
     308             : 
     309             : //------------------------------------------------------------------------------
     310           0 : void ExtensionBox_Impl::checkIndex( sal_Int32 nIndex ) const
     311             : {
     312           0 :     if ( nIndex < 0 )
     313           0 :         throw lang::IllegalArgumentException( "The list index starts with 0",0, 0 );
     314           0 :     if ( static_cast< sal_uInt32 >( nIndex ) >= m_vEntries.size())
     315           0 :         throw lang::IllegalArgumentException( "There is no element at the provided position. The position exceeds the number of available list entries",0, 0 );
     316           0 : }
     317             : 
     318             : //------------------------------------------------------------------------------
     319           0 : OUString ExtensionBox_Impl::getItemName( sal_Int32 nIndex ) const
     320             : {
     321           0 :     const ::osl::MutexGuard aGuard( m_entriesMutex );
     322           0 :     checkIndex( nIndex );
     323           0 :     return m_vEntries[ nIndex ]->m_sTitle;
     324             : }
     325             : 
     326             : //------------------------------------------------------------------------------
     327           0 : OUString ExtensionBox_Impl::getItemVersion( sal_Int32 nIndex ) const
     328             : {
     329           0 :     const ::osl::MutexGuard aGuard( m_entriesMutex );
     330           0 :     checkIndex( nIndex );
     331           0 :     return m_vEntries[ nIndex ]->m_sVersion;
     332             : }
     333             : 
     334             : //------------------------------------------------------------------------------
     335           0 : OUString ExtensionBox_Impl::getItemDescription( sal_Int32 nIndex ) const
     336             : {
     337           0 :     const ::osl::MutexGuard aGuard( m_entriesMutex );
     338           0 :     checkIndex( nIndex );
     339           0 :     return m_vEntries[ nIndex ]->m_sDescription;
     340             : }
     341             : 
     342             : //------------------------------------------------------------------------------
     343           0 : OUString ExtensionBox_Impl::getItemPublisher( sal_Int32 nIndex ) const
     344             : {
     345           0 :     const ::osl::MutexGuard aGuard( m_entriesMutex );
     346           0 :     checkIndex( nIndex );
     347           0 :     return m_vEntries[ nIndex ]->m_sPublisher;
     348             : }
     349             : 
     350             : //------------------------------------------------------------------------------
     351           0 : OUString ExtensionBox_Impl::getItemPublisherLink( sal_Int32 nIndex ) const
     352             : {
     353           0 :     const ::osl::MutexGuard aGuard( m_entriesMutex );
     354           0 :     checkIndex( nIndex );
     355           0 :     return m_vEntries[ nIndex ]->m_sPublisherURL;
     356             : }
     357             : 
     358             : //------------------------------------------------------------------------------
     359           0 : void ExtensionBox_Impl::select( sal_Int32 nIndex )
     360             : {
     361           0 :     const ::osl::MutexGuard aGuard( m_entriesMutex );
     362           0 :     checkIndex( nIndex );
     363           0 :     selectEntry( nIndex );
     364           0 : }
     365             : 
     366             : //------------------------------------------------------------------------------
     367           0 : void ExtensionBox_Impl::select( const OUString & sName )
     368             : {
     369           0 :     const ::osl::MutexGuard aGuard( m_entriesMutex );
     370             :     typedef ::std::vector< TEntry_Impl >::const_iterator It;
     371             : 
     372           0 :     for ( It iIter = m_vEntries.begin(); iIter != m_vEntries.end(); ++iIter )
     373             :     {
     374           0 :         if ( sName.equals( (*iIter)->m_sTitle ))
     375             :         {
     376           0 :             long nPos = iIter - m_vEntries.begin();
     377           0 :             selectEntry( nPos );
     378           0 :             break;
     379             :         }
     380           0 :     }
     381           0 : }
     382             : 
     383             : //------------------------------------------------------------------------------
     384             : // Title + description
     385           0 : void ExtensionBox_Impl::CalcActiveHeight( const long nPos )
     386             : {
     387           0 :     const ::osl::MutexGuard aGuard( m_entriesMutex );
     388             : 
     389             :     // get title height
     390             :     long aTextHeight;
     391           0 :     long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
     392           0 :     long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
     393           0 :     if ( nIconHeight < nTitleHeight )
     394           0 :         aTextHeight = nTitleHeight;
     395             :     else
     396           0 :         aTextHeight = nIconHeight;
     397             : 
     398             :     // calc description height
     399           0 :     Size aSize = GetOutputSizePixel();
     400           0 :     if ( m_bHasScrollBar )
     401           0 :         aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
     402             : 
     403           0 :     aSize.Width() -= ICON_OFFSET;
     404           0 :     aSize.Height() = 10000;
     405             : 
     406           0 :     OUString aText( m_vEntries[ nPos ]->m_sErrorText );
     407           0 :     if ( !aText.isEmpty() )
     408           0 :         aText += "\n";
     409           0 :     aText += m_vEntries[ nPos ]->m_sDescription;
     410             : 
     411             :     Rectangle aRect = GetTextRect( Rectangle( Point(), aSize ), aText,
     412           0 :                                    TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
     413           0 :     aTextHeight += aRect.GetHeight();
     414             : 
     415           0 :     if ( aTextHeight < m_nStdHeight )
     416           0 :         aTextHeight = m_nStdHeight;
     417             : 
     418           0 :     if ( m_vEntries[ nPos ]->m_bHasButtons )
     419           0 :         m_nActiveHeight = aTextHeight + m_nExtraHeight;
     420             :     else
     421           0 :         m_nActiveHeight = aTextHeight + 2;
     422           0 : }
     423             : 
     424             : //------------------------------------------------------------------------------
     425           0 : const Size ExtensionBox_Impl::GetMinOutputSizePixel() const
     426             : {
     427           0 :     return Size( 200, 80 );
     428             : }
     429             : 
     430             : //------------------------------------------------------------------------------
     431           0 : Rectangle ExtensionBox_Impl::GetEntryRect( const long nPos ) const
     432             : {
     433           0 :     const ::osl::MutexGuard aGuard( m_entriesMutex );
     434             : 
     435           0 :     Size aSize( GetOutputSizePixel() );
     436             : 
     437           0 :     if ( m_bHasScrollBar )
     438           0 :         aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
     439             : 
     440           0 :     if ( m_vEntries[ nPos ]->m_bActive )
     441           0 :         aSize.Height() = m_nActiveHeight;
     442             :     else
     443           0 :         aSize.Height() = m_nStdHeight;
     444             : 
     445           0 :     Point aPos( 0, -m_nTopIndex + nPos * m_nStdHeight );
     446           0 :     if ( m_bHasActive && ( nPos < m_nActive ) )
     447           0 :         aPos.Y() += m_nActiveHeight - m_nStdHeight;
     448             : 
     449           0 :     return Rectangle( aPos, aSize );
     450             : }
     451             : 
     452             : //------------------------------------------------------------------------------
     453           0 : void ExtensionBox_Impl::DeleteRemoved()
     454             : {
     455           0 :     const ::osl::MutexGuard aGuard( m_entriesMutex );
     456             : 
     457           0 :     m_bInDelete = true;
     458             : 
     459           0 :     if ( ! m_vRemovedEntries.empty() )
     460             :     {
     461             :         typedef std::vector< TEntry_Impl >::iterator ITER;
     462             : 
     463           0 :         for ( ITER iIndex = m_vRemovedEntries.begin(); iIndex < m_vRemovedEntries.end(); ++iIndex )
     464             :         {
     465           0 :             if ( (*iIndex)->m_pPublisher )
     466             :             {
     467           0 :                 delete (*iIndex)->m_pPublisher;
     468           0 :                 (*iIndex)->m_pPublisher = NULL;
     469             :             }
     470             :         }
     471             : 
     472           0 :         m_vRemovedEntries.clear();
     473             :     }
     474             : 
     475           0 :     m_bInDelete = false;
     476           0 : }
     477             : 
     478             : //------------------------------------------------------------------------------
     479             : //This function may be called with nPos < 0
     480           0 : void ExtensionBox_Impl::selectEntry( const long nPos )
     481             : {
     482             :     //ToDo whe should not use the guard at such a big scope here.
     483             :     //Currently it is used to gard m_vEntries and m_nActive. m_nActive will be
     484             :     //modified in this function.
     485             :     //It would be probably best to always use a copy of m_vEntries
     486             :     //and some other state variables from ExtensionBox_Impl for
     487             :     //the whole painting operation. See issue i86993
     488           0 :     ::osl::ClearableMutexGuard guard(m_entriesMutex);
     489             : 
     490           0 :     if ( m_bInCheckMode )
     491           0 :         return;
     492             : 
     493           0 :     if ( m_bHasActive )
     494             :     {
     495           0 :         if ( nPos == m_nActive )
     496           0 :             return;
     497             : 
     498           0 :         m_bHasActive = false;
     499           0 :         m_vEntries[ m_nActive ]->m_bActive = false;
     500             :     }
     501             : 
     502           0 :     if ( ( nPos >= 0 ) && ( nPos < (long) m_vEntries.size() ) )
     503             :     {
     504           0 :         m_bHasActive = true;
     505           0 :         m_nActive = nPos;
     506           0 :         m_vEntries[ nPos ]->m_bActive = true;
     507             : 
     508           0 :         if ( IsReallyVisible() )
     509             :         {
     510           0 :             m_bAdjustActive = true;
     511             :         }
     512             :     }
     513             : 
     514           0 :     if ( IsReallyVisible() )
     515             :     {
     516           0 :         m_bNeedsRecalc = true;
     517           0 :         Invalidate();
     518             :     }
     519             : 
     520           0 :     guard.clear();
     521             : }
     522             : 
     523             : // -----------------------------------------------------------------------
     524           0 : void ExtensionBox_Impl::DrawRow( const Rectangle& rRect, const TEntry_Impl pEntry )
     525             : {
     526           0 :     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
     527             : 
     528           0 :     if ( pEntry->m_bActive )
     529           0 :         SetTextColor( rStyleSettings.GetHighlightTextColor() );
     530           0 :     else if ( ( pEntry->m_eState != REGISTERED ) && ( pEntry->m_eState != NOT_AVAILABLE ) )
     531           0 :         SetTextColor( rStyleSettings.GetDisableColor() );
     532           0 :     else if ( IsControlForeground() )
     533           0 :         SetTextColor( GetControlForeground() );
     534             :     else
     535           0 :         SetTextColor( rStyleSettings.GetFieldTextColor() );
     536             : 
     537           0 :     if ( pEntry->m_bActive )
     538             :     {
     539           0 :         SetLineColor();
     540           0 :         SetFillColor( rStyleSettings.GetHighlightColor() );
     541           0 :         DrawRect( rRect );
     542             :     }
     543             :     else
     544             :     {
     545           0 :         if( IsControlBackground() )
     546           0 :             SetBackground( GetControlBackground() );
     547             :         else
     548           0 :             SetBackground( rStyleSettings.GetFieldColor() );
     549             : 
     550           0 :         SetTextFillColor();
     551           0 :         Erase( rRect );
     552             :     }
     553             : 
     554             :     // Draw extension icon
     555           0 :     Point aPos( rRect.TopLeft() );
     556           0 :     aPos += Point( TOP_OFFSET, TOP_OFFSET );
     557           0 :     Image aImage;
     558           0 :     if ( ! pEntry->m_aIcon )
     559           0 :         aImage = m_aDefaultImage;
     560             :     else
     561           0 :         aImage = pEntry->m_aIcon;
     562           0 :     Size aImageSize = aImage.GetSizePixel();
     563           0 :     if ( ( aImageSize.Width() <= ICON_WIDTH ) && ( aImageSize.Height() <= ICON_HEIGHT ) )
     564           0 :         DrawImage( Point( aPos.X()+((ICON_WIDTH-aImageSize.Width())/2), aPos.Y()+((ICON_HEIGHT-aImageSize.Height())/2) ), aImage );
     565             :     else
     566           0 :         DrawImage( aPos, Size( ICON_WIDTH, ICON_HEIGHT ), aImage );
     567             : 
     568             :     // Setup fonts
     569           0 :     Font aStdFont( GetFont() );
     570           0 :     Font aBoldFont( aStdFont );
     571           0 :     aBoldFont.SetWeight( WEIGHT_BOLD );
     572           0 :     SetFont( aBoldFont );
     573           0 :     long aTextHeight = GetTextHeight();
     574             : 
     575             :     // Init publisher link here
     576           0 :     if ( !pEntry->m_pPublisher && pEntry->m_sPublisher.Len() )
     577             :     {
     578           0 :         pEntry->m_pPublisher = new FixedHyperlink( this );
     579           0 :         pEntry->m_pPublisher->SetBackground();
     580           0 :         pEntry->m_pPublisher->SetPaintTransparent( true );
     581           0 :         pEntry->m_pPublisher->SetURL( pEntry->m_sPublisherURL );
     582           0 :         pEntry->m_pPublisher->SetText( pEntry->m_sPublisher );
     583           0 :         Size aSize = FixedText::CalcMinimumTextSize( pEntry->m_pPublisher );
     584           0 :         pEntry->m_pPublisher->SetSizePixel( aSize );
     585             : 
     586           0 :         if ( m_aClickHdl.IsSet() )
     587           0 :             pEntry->m_pPublisher->SetClickHdl( m_aClickHdl );
     588             :     }
     589             : 
     590             :     // Get max title width
     591           0 :     long nMaxTitleWidth = rRect.GetWidth() - ICON_OFFSET;
     592           0 :     nMaxTitleWidth -= ( 2 * SMALL_ICON_SIZE ) + ( 4 * SPACE_BETWEEN );
     593           0 :     if ( pEntry->m_pPublisher )
     594             :     {
     595           0 :         nMaxTitleWidth -= pEntry->m_pPublisher->GetSizePixel().Width() + (2*SPACE_BETWEEN);
     596             :     }
     597             : 
     598           0 :     long aVersionWidth = GetTextWidth( pEntry->m_sVersion );
     599           0 :     long aTitleWidth = GetTextWidth( pEntry->m_sTitle ) + (aTextHeight / 3);
     600             : 
     601           0 :     aPos = rRect.TopLeft() + Point( ICON_OFFSET, TOP_OFFSET );
     602             : 
     603           0 :     if ( aTitleWidth > nMaxTitleWidth - aVersionWidth )
     604             :     {
     605           0 :         aTitleWidth = nMaxTitleWidth - aVersionWidth - (aTextHeight / 3);
     606           0 :         String aShortTitle = GetEllipsisString( pEntry->m_sTitle, aTitleWidth );
     607           0 :         DrawText( aPos, aShortTitle );
     608           0 :         aTitleWidth += (aTextHeight / 3);
     609             :     }
     610             :     else
     611           0 :         DrawText( aPos, pEntry->m_sTitle );
     612             : 
     613           0 :     SetFont( aStdFont );
     614           0 :     DrawText( Point( aPos.X() + aTitleWidth, aPos.Y() ), pEntry->m_sVersion );
     615             : 
     616           0 :     long nIconHeight = TOP_OFFSET + SMALL_ICON_SIZE;
     617           0 :     long nTitleHeight = TOP_OFFSET + GetTextHeight();
     618           0 :     if ( nIconHeight < nTitleHeight )
     619           0 :         aTextHeight = nTitleHeight;
     620             :     else
     621           0 :         aTextHeight = nIconHeight;
     622             : 
     623             :     // draw description
     624           0 :     OUString sDescription;
     625           0 :     if ( pEntry->m_sErrorText.Len() )
     626             :     {
     627           0 :         if ( pEntry->m_bActive )
     628           0 :             sDescription = pEntry->m_sErrorText + OUString("\n") + pEntry->m_sDescription;
     629             :         else
     630           0 :             sDescription = pEntry->m_sErrorText;
     631             :     }
     632             :     else
     633           0 :         sDescription = pEntry->m_sDescription;
     634             : 
     635           0 :     aPos.Y() += aTextHeight;
     636           0 :     if ( pEntry->m_bActive )
     637             :     {
     638           0 :         long nExtraHeight = 0;
     639             : 
     640           0 :         if ( pEntry->m_bHasButtons )
     641           0 :             nExtraHeight = m_nExtraHeight;
     642             : 
     643           0 :         DrawText( Rectangle( aPos.X(), aPos.Y(), rRect.Right(), rRect.Bottom() - nExtraHeight ),
     644           0 :                   sDescription, TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
     645             :     }
     646             :     else
     647             :     {
     648             :         //replace LF to space, so words do not stick together in one line view
     649           0 :         sDescription = sDescription.replace(0x000A, ' ');
     650           0 :         const long nWidth = GetTextWidth( sDescription );
     651           0 :         if ( nWidth > rRect.GetWidth() - aPos.X() )
     652           0 :             sDescription = GetEllipsisString( sDescription, rRect.GetWidth() - aPos.X() );
     653           0 :         DrawText( aPos, sDescription );
     654             :     }
     655             : 
     656             :     // Draw publisher link
     657           0 :     if ( pEntry->m_pPublisher )
     658             :     {
     659           0 :         pEntry->m_pPublisher->Show();
     660           0 :         aPos = rRect.TopLeft() + Point( ICON_OFFSET + nMaxTitleWidth + (2*SPACE_BETWEEN), TOP_OFFSET );
     661           0 :         pEntry->m_pPublisher->SetPosPixel( aPos );
     662             :     }
     663             : 
     664             :     // Draw status icons
     665           0 :     if ( !pEntry->m_bUser )
     666             :     {
     667           0 :         aPos = rRect.TopRight() + Point( -(RIGHT_ICON_OFFSET + SMALL_ICON_SIZE), TOP_OFFSET );
     668           0 :         if ( pEntry->m_bLocked )
     669           0 :             DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), m_aLockedImage );
     670             :         else
     671           0 :             DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), m_aSharedImage );
     672             :     }
     673           0 :     if ( ( pEntry->m_eState == AMBIGUOUS ) || pEntry->m_bMissingDeps || pEntry->m_bMissingLic )
     674             :     {
     675           0 :         aPos = rRect.TopRight() + Point( -(RIGHT_ICON_OFFSET + SPACE_BETWEEN + 2*SMALL_ICON_SIZE), TOP_OFFSET );
     676           0 :         DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), m_aWarningImage );
     677             :     }
     678             : 
     679           0 :     SetLineColor( Color( COL_LIGHTGRAY ) );
     680           0 :     DrawLine( rRect.BottomLeft(), rRect.BottomRight() );
     681           0 : }
     682             : 
     683             : // -----------------------------------------------------------------------
     684           0 : void ExtensionBox_Impl::RecalcAll()
     685             : {
     686           0 :     if ( m_bHasActive )
     687           0 :         CalcActiveHeight( m_nActive );
     688             : 
     689           0 :     SetupScrollBar();
     690             : 
     691           0 :     if ( m_bHasActive )
     692             :     {
     693           0 :         Rectangle aEntryRect = GetEntryRect( m_nActive );
     694             : 
     695           0 :         if ( m_bAdjustActive )
     696             :         {
     697           0 :             m_bAdjustActive = false;
     698             : 
     699             :             // If the top of the selected entry isn't visible, make it visible
     700           0 :             if ( aEntryRect.Top() < 0 )
     701             :             {
     702           0 :                 m_nTopIndex += aEntryRect.Top();
     703           0 :                 aEntryRect.Move( 0, -aEntryRect.Top() );
     704             :             }
     705             : 
     706             :             // If the bottom of the selected entry isn't visible, make it visible even if now the top
     707             :             // isn't visible any longer ( the buttons are more important )
     708           0 :             Size aOutputSize = GetOutputSizePixel();
     709           0 :             if ( aEntryRect.Bottom() > aOutputSize.Height() )
     710             :             {
     711           0 :                 m_nTopIndex += ( aEntryRect.Bottom() - aOutputSize.Height() );
     712           0 :                 aEntryRect.Move( 0, -( aEntryRect.Bottom() - aOutputSize.Height() ) );
     713             :             }
     714             : 
     715             :             // If there is unused space below the last entry but all entries don't fit into the box,
     716             :             // move the content down to use the whole space
     717           0 :             const long nTotalHeight = GetTotalHeight();
     718           0 :             if ( m_bHasScrollBar && ( aOutputSize.Height() + m_nTopIndex > nTotalHeight ) )
     719             :             {
     720           0 :                 long nOffset = m_nTopIndex;
     721           0 :                 m_nTopIndex = nTotalHeight - aOutputSize.Height();
     722           0 :                 nOffset -= m_nTopIndex;
     723           0 :                 aEntryRect.Move( 0, nOffset );
     724             :             }
     725             : 
     726           0 :             if ( m_bHasScrollBar )
     727           0 :                 m_pScrollBar->SetThumbPos( m_nTopIndex );
     728             :         }
     729             :     }
     730             : 
     731           0 :     m_bNeedsRecalc = false;
     732           0 : }
     733             : 
     734             : // -----------------------------------------------------------------------
     735           0 : bool ExtensionBox_Impl::HandleTabKey( bool )
     736             : {
     737           0 :     return false;
     738             : }
     739             : 
     740             : // -----------------------------------------------------------------------
     741           0 : bool ExtensionBox_Impl::HandleCursorKey( sal_uInt16 nKeyCode )
     742             : {
     743           0 :     if ( m_vEntries.empty() )
     744           0 :         return true;
     745             : 
     746           0 :     long nSelect = 0;
     747             : 
     748           0 :     if ( m_bHasActive )
     749             :     {
     750           0 :         long nPageSize = GetOutputSizePixel().Height() / m_nStdHeight;
     751           0 :         if ( nPageSize < 2 )
     752           0 :             nPageSize = 2;
     753             : 
     754           0 :         if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_RIGHT ) )
     755           0 :             nSelect = m_nActive + 1;
     756           0 :         else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_LEFT ) )
     757           0 :             nSelect = m_nActive - 1;
     758           0 :         else if ( nKeyCode == KEY_HOME )
     759           0 :             nSelect = 0;
     760           0 :         else if ( nKeyCode == KEY_END )
     761           0 :             nSelect = m_vEntries.size() - 1;
     762           0 :         else if ( nKeyCode == KEY_PAGEUP )
     763           0 :             nSelect = m_nActive - nPageSize + 1;
     764           0 :         else if ( nKeyCode == KEY_PAGEDOWN )
     765           0 :             nSelect = m_nActive + nPageSize - 1;
     766             :     }
     767             :     else // when there is no selected entry, we will select the first or the last.
     768             :     {
     769           0 :         if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_PAGEDOWN ) || ( nKeyCode == KEY_HOME ) )
     770           0 :             nSelect = 0;
     771           0 :         else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_PAGEUP ) || ( nKeyCode == KEY_END ) )
     772           0 :             nSelect = m_vEntries.size() - 1;
     773             :     }
     774             : 
     775           0 :     if ( nSelect < 0 )
     776           0 :         nSelect = 0;
     777           0 :     if ( nSelect >= (long) m_vEntries.size() )
     778           0 :         nSelect = m_vEntries.size() - 1;
     779             : 
     780           0 :     selectEntry( nSelect );
     781             : 
     782           0 :     return true;
     783             : }
     784             : 
     785             : // -----------------------------------------------------------------------
     786           0 : void ExtensionBox_Impl::Paint( const Rectangle &/*rPaintRect*/ )
     787             : {
     788           0 :     if ( !m_bInDelete )
     789           0 :         DeleteRemoved();
     790             : 
     791           0 :     if ( m_bNeedsRecalc )
     792           0 :         RecalcAll();
     793             : 
     794           0 :     Point aStart( 0, -m_nTopIndex );
     795           0 :     Size aSize( GetOutputSizePixel() );
     796             : 
     797           0 :     if ( m_bHasScrollBar )
     798           0 :         aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
     799             : 
     800           0 :     const ::osl::MutexGuard aGuard( m_entriesMutex );
     801             : 
     802             :     typedef std::vector< TEntry_Impl >::iterator ITER;
     803           0 :     for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
     804             :     {
     805           0 :         aSize.Height() = (*iIndex)->m_bActive ? m_nActiveHeight : m_nStdHeight;
     806           0 :         Rectangle aEntryRect( aStart, aSize );
     807           0 :         DrawRow( aEntryRect, *iIndex );
     808           0 :         aStart.Y() += aSize.Height();
     809           0 :     }
     810           0 : }
     811             : 
     812             : // -----------------------------------------------------------------------
     813           0 : long ExtensionBox_Impl::GetTotalHeight() const
     814             : {
     815           0 :     long nHeight = m_vEntries.size() * m_nStdHeight;
     816             : 
     817           0 :     if ( m_bHasActive )
     818             :     {
     819           0 :         nHeight += m_nActiveHeight - m_nStdHeight;
     820             :     }
     821             : 
     822           0 :     return nHeight;
     823             : }
     824             : 
     825             : // -----------------------------------------------------------------------
     826           0 : void ExtensionBox_Impl::SetupScrollBar()
     827             : {
     828           0 :     const Size aSize = GetOutputSizePixel();
     829           0 :     const long nScrBarSize = GetSettings().GetStyleSettings().GetScrollBarSize();
     830           0 :     const long nTotalHeight = GetTotalHeight();
     831           0 :     const bool bNeedsScrollBar = ( nTotalHeight > aSize.Height() );
     832             : 
     833           0 :     if ( bNeedsScrollBar )
     834             :     {
     835           0 :         if ( m_nTopIndex + aSize.Height() > nTotalHeight )
     836           0 :             m_nTopIndex = nTotalHeight - aSize.Height();
     837             : 
     838           0 :         m_pScrollBar->SetPosSizePixel( Point( aSize.Width() - nScrBarSize, 0 ),
     839           0 :                                        Size( nScrBarSize, aSize.Height() ) );
     840           0 :         m_pScrollBar->SetRangeMax( nTotalHeight );
     841           0 :         m_pScrollBar->SetVisibleSize( aSize.Height() );
     842           0 :         m_pScrollBar->SetPageSize( ( aSize.Height() * 4 ) / 5 );
     843           0 :         m_pScrollBar->SetLineSize( m_nStdHeight );
     844           0 :         m_pScrollBar->SetThumbPos( m_nTopIndex );
     845             : 
     846           0 :         if ( !m_bHasScrollBar )
     847           0 :             m_pScrollBar->Show();
     848             :     }
     849           0 :     else if ( m_bHasScrollBar )
     850             :     {
     851           0 :         m_pScrollBar->Hide();
     852           0 :         m_nTopIndex = 0;
     853             :     }
     854             : 
     855           0 :     m_bHasScrollBar = bNeedsScrollBar;
     856           0 : }
     857             : 
     858             : // -----------------------------------------------------------------------
     859           0 : void ExtensionBox_Impl::Resize()
     860             : {
     861           0 :     RecalcAll();
     862           0 : }
     863             : 
     864             : //------------------------------------------------------------------------------
     865           0 : long ExtensionBox_Impl::PointToPos( const Point& rPos )
     866             : {
     867           0 :     long nPos = ( rPos.Y() + m_nTopIndex ) / m_nStdHeight;
     868             : 
     869           0 :     if ( m_bHasActive && ( nPos > m_nActive ) )
     870             :     {
     871           0 :         if ( rPos.Y() + m_nTopIndex <= m_nActive*m_nStdHeight + m_nActiveHeight )
     872           0 :             nPos = m_nActive;
     873             :         else
     874           0 :             nPos = ( rPos.Y() + m_nTopIndex - (m_nActiveHeight - m_nStdHeight) ) / m_nStdHeight;
     875             :     }
     876             : 
     877           0 :     return nPos;
     878             : }
     879             : 
     880             : //------------------------------------------------------------------------------
     881           0 : void ExtensionBox_Impl::MouseButtonDown( const MouseEvent& rMEvt )
     882             : {
     883           0 :     long nPos = PointToPos( rMEvt.GetPosPixel() );
     884             : 
     885           0 :     if ( rMEvt.IsLeft() )
     886             :     {
     887           0 :         if ( rMEvt.IsMod1() && m_bHasActive )
     888           0 :             selectEntry( m_vEntries.size() );   // Selecting an not existing entry will deselect the current one
     889             :         else
     890           0 :             selectEntry( nPos );
     891             :     }
     892           0 : }
     893             : 
     894             : //------------------------------------------------------------------------------
     895           0 : long ExtensionBox_Impl::Notify( NotifyEvent& rNEvt )
     896             : {
     897           0 :     if ( !m_bInDelete )
     898           0 :         DeleteRemoved();
     899             : 
     900           0 :     bool bHandled = false;
     901             : 
     902           0 :     if ( rNEvt.GetType() == EVENT_KEYINPUT )
     903             :     {
     904           0 :         const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
     905           0 :         KeyCode         aKeyCode = pKEvt->GetKeyCode();
     906           0 :         sal_uInt16          nKeyCode = aKeyCode.GetCode();
     907             : 
     908           0 :         if ( nKeyCode == KEY_TAB )
     909           0 :             bHandled = HandleTabKey( aKeyCode.IsShift() );
     910           0 :         else if ( aKeyCode.GetGroup() == KEYGROUP_CURSOR )
     911           0 :             bHandled = HandleCursorKey( nKeyCode );
     912             :     }
     913             : 
     914           0 :     if ( rNEvt.GetType() == EVENT_COMMAND )
     915             :     {
     916           0 :         if ( m_bHasScrollBar &&
     917           0 :              ( rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL ) )
     918             :         {
     919           0 :             const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
     920           0 :             if ( pData->GetMode() == COMMAND_WHEEL_SCROLL )
     921             :             {
     922           0 :                 long nThumbPos = m_pScrollBar->GetThumbPos();
     923           0 :                 if ( pData->GetDelta() < 0 )
     924           0 :                     m_pScrollBar->DoScroll( nThumbPos + m_nStdHeight );
     925             :                 else
     926           0 :                     m_pScrollBar->DoScroll( nThumbPos - m_nStdHeight );
     927           0 :                 bHandled = true;
     928             :             }
     929             :         }
     930             :     }
     931             : 
     932           0 :     if ( !bHandled )
     933           0 :         return Control::Notify( rNEvt );
     934             :     else
     935           0 :         return true;
     936             : }
     937             : 
     938             : //------------------------------------------------------------------------------
     939           0 : bool ExtensionBox_Impl::FindEntryPos( const TEntry_Impl pEntry, const long nStart,
     940             :                                       const long nEnd, long &nPos )
     941             : {
     942           0 :     nPos = nStart;
     943           0 :     if ( nStart > nEnd )
     944           0 :         return false;
     945             : 
     946             :     StringCompare eCompare;
     947             : 
     948           0 :     if ( nStart == nEnd )
     949             :     {
     950           0 :         eCompare = pEntry->CompareTo( m_pCollator, m_vEntries[ nStart ] );
     951           0 :         if ( eCompare == COMPARE_LESS )
     952           0 :             return false;
     953           0 :         else if ( eCompare == COMPARE_EQUAL )
     954             :         {
     955             :             //Workaround. See i86963.
     956           0 :             if (pEntry->m_xPackage != m_vEntries[nStart]->m_xPackage)
     957           0 :                 return false;
     958             : 
     959           0 :             if ( m_bInCheckMode )
     960           0 :                 m_vEntries[ nStart ]->m_bChecked = true;
     961           0 :             return true;
     962             :         }
     963             :         else
     964             :         {
     965           0 :             nPos = nStart + 1;
     966           0 :             return false;
     967             :         }
     968             :     }
     969             : 
     970           0 :     const long nMid = nStart + ( ( nEnd - nStart ) / 2 );
     971           0 :     eCompare = pEntry->CompareTo( m_pCollator, m_vEntries[ nMid ] );
     972             : 
     973           0 :     if ( eCompare == COMPARE_LESS )
     974           0 :         return FindEntryPos( pEntry, nStart, nMid-1, nPos );
     975           0 :     else if ( eCompare == COMPARE_GREATER )
     976           0 :         return FindEntryPos( pEntry, nMid+1, nEnd, nPos );
     977             :     else
     978             :     {
     979             :         //Workaround.See i86963.
     980           0 :         if (pEntry->m_xPackage != m_vEntries[nMid]->m_xPackage)
     981           0 :             return false;
     982             : 
     983           0 :         if ( m_bInCheckMode )
     984           0 :             m_vEntries[ nMid ]->m_bChecked = true;
     985           0 :         nPos = nMid;
     986           0 :         return true;
     987             :     }
     988             : }
     989             : 
     990           0 : void ExtensionBox_Impl::cleanVecListenerAdded()
     991             : {
     992             :     typedef ::std::vector<uno::WeakReference<deployment::XPackage> >::iterator IT;
     993           0 :     IT i = m_vListenerAdded.begin();
     994           0 :     while( i != m_vListenerAdded.end())
     995             :     {
     996           0 :         const uno::Reference<deployment::XPackage> hardRef(*i);
     997           0 :         if (!hardRef.is())
     998           0 :             i = m_vListenerAdded.erase(i);
     999             :         else
    1000           0 :             ++i;
    1001           0 :     }
    1002           0 : }
    1003             : 
    1004           0 : void ExtensionBox_Impl::addEventListenerOnce(
    1005             :     uno::Reference<deployment::XPackage > const & extension)
    1006             : {
    1007             :     //make sure to only add the listener once
    1008           0 :     cleanVecListenerAdded();
    1009           0 :     if ( ::std::find_if(m_vListenerAdded.begin(), m_vListenerAdded.end(),
    1010           0 :                         FindWeakRef(extension))
    1011           0 :          == m_vListenerAdded.end())
    1012             :     {
    1013           0 :         extension->addEventListener( uno::Reference< lang::XEventListener > (
    1014           0 :                                          m_xRemoveListener, uno::UNO_QUERY ) );
    1015           0 :         m_vListenerAdded.push_back(extension);
    1016             :     }
    1017           0 : }
    1018             : 
    1019             : //------------------------------------------------------------------------------
    1020           0 : long ExtensionBox_Impl::addEntry( const uno::Reference< deployment::XPackage > &xPackage,
    1021             :                                   bool bLicenseMissing )
    1022             : {
    1023           0 :     long         nPos = 0;
    1024           0 :     PackageState eState = m_pManager->getPackageState( xPackage );
    1025           0 :     bool         bLocked = m_pManager->isReadOnly( xPackage );
    1026             : 
    1027           0 :     TEntry_Impl pEntry( new Entry_Impl( xPackage, eState, bLocked ) );
    1028             : 
    1029             :     // Don't add empty entries
    1030           0 :     if ( ! pEntry->m_sTitle.Len() )
    1031           0 :         return 0;
    1032             : 
    1033           0 :     ::osl::ClearableMutexGuard guard(m_entriesMutex);
    1034           0 :     if ( m_vEntries.empty() )
    1035             :     {
    1036           0 :         addEventListenerOnce(xPackage);
    1037           0 :         m_vEntries.push_back( pEntry );
    1038             :     }
    1039             :     else
    1040             :     {
    1041           0 :         if ( !FindEntryPos( pEntry, 0, m_vEntries.size()-1, nPos ) )
    1042             :         {
    1043           0 :             addEventListenerOnce(xPackage);
    1044           0 :             m_vEntries.insert( m_vEntries.begin()+nPos, pEntry );
    1045             :         }
    1046           0 :         else if ( !m_bInCheckMode )
    1047             :         {
    1048             :             OSL_FAIL( "ExtensionBox_Impl::addEntry(): Will not add duplicate entries"  );
    1049             :         }
    1050             :     }
    1051             : 
    1052           0 :     pEntry->m_bHasOptions = m_pManager->supportsOptions( xPackage );
    1053           0 :     pEntry->m_bUser       = (xPackage->getRepositoryName() == USER_PACKAGE_MANAGER);
    1054           0 :     pEntry->m_bShared     = (xPackage->getRepositoryName() == SHARED_PACKAGE_MANAGER);
    1055           0 :     pEntry->m_bNew        = m_bInCheckMode;
    1056           0 :     pEntry->m_bMissingLic = bLicenseMissing;
    1057             : 
    1058           0 :     if ( bLicenseMissing )
    1059           0 :         pEntry->m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_MISSING_LICENSE );
    1060             : 
    1061             :     //access to m_nActive must be guarded
    1062           0 :     if ( !m_bInCheckMode && m_bHasActive && ( m_nActive >= nPos ) )
    1063           0 :         m_nActive += 1;
    1064             : 
    1065           0 :     guard.clear();
    1066             : 
    1067           0 :     if ( IsReallyVisible() )
    1068           0 :         Invalidate();
    1069             : 
    1070           0 :     m_bNeedsRecalc = true;
    1071             : 
    1072           0 :     return nPos;
    1073             : }
    1074             : 
    1075             : //------------------------------------------------------------------------------
    1076           0 : void ExtensionBox_Impl::updateEntry( const uno::Reference< deployment::XPackage > &xPackage )
    1077             : {
    1078             :     typedef std::vector< TEntry_Impl >::iterator ITER;
    1079           0 :     for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
    1080             :     {
    1081           0 :         if ( (*iIndex)->m_xPackage == xPackage )
    1082             :         {
    1083           0 :             PackageState eState = m_pManager->getPackageState( xPackage );
    1084           0 :             (*iIndex)->m_bHasOptions = m_pManager->supportsOptions( xPackage );
    1085           0 :             (*iIndex)->m_eState = eState;
    1086           0 :             (*iIndex)->m_sTitle = xPackage->getDisplayName();
    1087           0 :             (*iIndex)->m_sVersion = xPackage->getVersion();
    1088           0 :             (*iIndex)->m_sDescription = xPackage->getDescription();
    1089             : 
    1090           0 :             if ( eState == REGISTERED )
    1091           0 :                 (*iIndex)->m_bMissingLic = false;
    1092             : 
    1093           0 :             if ( eState == AMBIGUOUS )
    1094           0 :                 (*iIndex)->m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS );
    1095           0 :             else if ( ! (*iIndex)->m_bMissingLic )
    1096           0 :                 (*iIndex)->m_sErrorText = String();
    1097             : 
    1098           0 :             if ( IsReallyVisible() )
    1099           0 :                 Invalidate();
    1100           0 :             break;
    1101             :         }
    1102             :     }
    1103           0 : }
    1104             : 
    1105             : //------------------------------------------------------------------------------
    1106             : //This function is also called as a result of removing an extension.
    1107             : //see PackageManagerImpl::removePackage
    1108             : //The gui is a registered as listener on the package. Removing it will cause the
    1109             : //listeners to be notified an then this function is called. At this moment xPackage
    1110             : //is in the disposing state and all calls on it may result in a DisposedException.
    1111           0 : void ExtensionBox_Impl::removeEntry( const uno::Reference< deployment::XPackage > &xPackage )
    1112             : {
    1113           0 :    if ( ! m_bInDelete )
    1114             :     {
    1115           0 :         ::osl::ClearableMutexGuard aGuard( m_entriesMutex );
    1116             : 
    1117             :         typedef std::vector< TEntry_Impl >::iterator ITER;
    1118             : 
    1119           0 :         for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
    1120             :         {
    1121           0 :             if ( (*iIndex)->m_xPackage == xPackage )
    1122             :             {
    1123           0 :                 long nPos = iIndex - m_vEntries.begin();
    1124             : 
    1125             :                 // Entries mustn't removed here, because they contain a hyperlink control
    1126             :                 // which can only be deleted when the thread has the solar mutex. Therefor
    1127             :                 // the entry will be moved into the m_vRemovedEntries list which will be
    1128             :                 // cleared on the next paint event
    1129           0 :                 m_vRemovedEntries.push_back( *iIndex );
    1130           0 :                 (*iIndex)->m_xPackage->removeEventListener(
    1131           0 :                     uno::Reference<lang::XEventListener>(m_xRemoveListener, uno::UNO_QUERY));
    1132           0 :                 m_vEntries.erase( iIndex );
    1133             : 
    1134           0 :                 m_bNeedsRecalc = true;
    1135             : 
    1136           0 :                 if ( IsReallyVisible() )
    1137           0 :                     Invalidate();
    1138             : 
    1139           0 :                 if ( m_bHasActive )
    1140             :                 {
    1141           0 :                     if ( nPos < m_nActive )
    1142           0 :                         m_nActive -= 1;
    1143           0 :                     else if ( ( nPos == m_nActive ) &&
    1144           0 :                               ( nPos == (long) m_vEntries.size() ) )
    1145           0 :                         m_nActive -= 1;
    1146             : 
    1147           0 :                     m_bHasActive = false;
    1148             :                     //clear before calling out of this method
    1149           0 :                     aGuard.clear();
    1150           0 :                     selectEntry( m_nActive );
    1151             :                 }
    1152           0 :                 break;
    1153             :             }
    1154           0 :         }
    1155             :     }
    1156           0 : }
    1157             : 
    1158             : //------------------------------------------------------------------------------
    1159           0 : void ExtensionBox_Impl::RemoveUnlocked()
    1160             : {
    1161           0 :     bool bAllRemoved = false;
    1162             : 
    1163           0 :     while ( ! bAllRemoved )
    1164             :     {
    1165           0 :         bAllRemoved = true;
    1166             : 
    1167           0 :         ::osl::ClearableMutexGuard aGuard( m_entriesMutex );
    1168             : 
    1169             :         typedef std::vector< TEntry_Impl >::iterator ITER;
    1170             : 
    1171           0 :         for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
    1172             :         {
    1173           0 :             if ( !(*iIndex)->m_bLocked )
    1174             :             {
    1175           0 :                 bAllRemoved = false;
    1176           0 :                 uno::Reference< deployment::XPackage> xPackage = (*iIndex)->m_xPackage;
    1177           0 :                 aGuard.clear();
    1178           0 :                 removeEntry( xPackage );
    1179           0 :                 break;
    1180             :             }
    1181             :         }
    1182           0 :     }
    1183           0 : }
    1184             : 
    1185             : //------------------------------------------------------------------------------
    1186           0 : void ExtensionBox_Impl::prepareChecking()
    1187             : {
    1188           0 :     m_bInCheckMode = true;
    1189             :     typedef std::vector< TEntry_Impl >::iterator ITER;
    1190           0 :     for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
    1191             :     {
    1192           0 :         (*iIndex)->m_bChecked = false;
    1193           0 :         (*iIndex)->m_bNew = false;
    1194             :     }
    1195           0 : }
    1196             : 
    1197             : //------------------------------------------------------------------------------
    1198           0 : void ExtensionBox_Impl::checkEntries()
    1199             : {
    1200           0 :     long nNewPos = -1;
    1201           0 :     long nPos = 0;
    1202           0 :     bool bNeedsUpdate = false;
    1203             : 
    1204           0 :     ::osl::ClearableMutexGuard guard(m_entriesMutex);
    1205             :     typedef std::vector< TEntry_Impl >::iterator ITER;
    1206           0 :     ITER iIndex = m_vEntries.begin();
    1207           0 :     while ( iIndex < m_vEntries.end() )
    1208             :     {
    1209           0 :         if ( (*iIndex)->m_bChecked == false )
    1210             :         {
    1211           0 :             (*iIndex)->m_bChecked = true;
    1212           0 :             bNeedsUpdate = true;
    1213           0 :             nPos = iIndex-m_vEntries.begin();
    1214           0 :             if ( (*iIndex)->m_bNew )
    1215             :             { // add entry to list and correct active pos
    1216           0 :                 if ( nNewPos == - 1)
    1217           0 :                     nNewPos = nPos;
    1218           0 :                 if ( nPos <= m_nActive )
    1219           0 :                     m_nActive += 1;
    1220           0 :                 ++iIndex;
    1221             :             }
    1222             :             else
    1223             :             {   // remove entry from list
    1224           0 :                 if ( nPos < m_nActive )
    1225           0 :                     m_nActive -= 1;
    1226           0 :                 else if ( ( nPos == m_nActive ) && ( nPos == (long) m_vEntries.size() - 1 ) )
    1227           0 :                     m_nActive -= 1;
    1228           0 :                 m_vRemovedEntries.push_back( *iIndex );
    1229           0 :                 m_vEntries.erase( iIndex );
    1230           0 :                 iIndex = m_vEntries.begin() + nPos;
    1231             :             }
    1232             :         }
    1233             :         else
    1234           0 :             ++iIndex;
    1235             :     }
    1236           0 :     guard.clear();
    1237             : 
    1238           0 :     m_bInCheckMode = false;
    1239             : 
    1240           0 :     if ( nNewPos != - 1)
    1241           0 :         selectEntry( nNewPos );
    1242             : 
    1243           0 :     if ( bNeedsUpdate )
    1244             :     {
    1245           0 :         m_bNeedsRecalc = true;
    1246           0 :         if ( IsReallyVisible() )
    1247           0 :             Invalidate();
    1248           0 :     }
    1249           0 : }
    1250             : 
    1251             : //------------------------------------------------------------------------------
    1252           0 : void ExtensionBox_Impl::SetScrollHdl( const Link& rLink )
    1253             : {
    1254           0 :     if ( m_pScrollBar )
    1255           0 :         m_pScrollBar->SetScrollHdl( rLink );
    1256           0 : }
    1257             : 
    1258             : // -----------------------------------------------------------------------
    1259           0 : void ExtensionBox_Impl::DoScroll( long nDelta )
    1260             : {
    1261           0 :     m_nTopIndex += nDelta;
    1262           0 :     Point aNewSBPt( m_pScrollBar->GetPosPixel() );
    1263             : 
    1264           0 :     Rectangle aScrRect( Point(), GetOutputSizePixel() );
    1265           0 :     aScrRect.Right() -= m_pScrollBar->GetSizePixel().Width();
    1266           0 :     Scroll( 0, -nDelta, aScrRect );
    1267             : 
    1268           0 :     m_pScrollBar->SetPosPixel( aNewSBPt );
    1269           0 : }
    1270             : 
    1271             : // -----------------------------------------------------------------------
    1272           0 : IMPL_LINK( ExtensionBox_Impl, ScrollHdl, ScrollBar*, pScrBar )
    1273             : {
    1274           0 :     DoScroll( pScrBar->GetDelta() );
    1275             : 
    1276           0 :     return 1;
    1277             : }
    1278             : 
    1279           0 : } //namespace dp_gui
    1280             : 
    1281             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10