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

Generated by: LCOV version 1.10