LCOV - code coverage report
Current view: top level - desktop/source/deployment/gui - dp_gui_extlistbox.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 624 0.0 %
Date: 2012-08-25 Functions: 0 47 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

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

Generated by: LCOV version 1.10