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

Generated by: LCOV version 1.11