summaryrefslogtreecommitdiff
path: root/desktop/source/deployment/gui/dp_gui_extlistbox.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/source/deployment/gui/dp_gui_extlistbox.cxx')
-rw-r--r--desktop/source/deployment/gui/dp_gui_extlistbox.cxx2350
1 files changed, 1175 insertions, 1175 deletions
diff --git a/desktop/source/deployment/gui/dp_gui_extlistbox.cxx b/desktop/source/deployment/gui/dp_gui_extlistbox.cxx
index 36f08dbf5b32..b95a7e5f8cfb 100644
--- a/desktop/source/deployment/gui/dp_gui_extlistbox.cxx
+++ b/desktop/source/deployment/gui/dp_gui_extlistbox.cxx
@@ -1,1175 +1,1175 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2009 by Sun Microsystems, Inc.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_desktop.hxx"
-
-#include "svtools/controldims.hrc"
-
-#include "dp_gui.h"
-#include "dp_gui_extlistbox.hxx"
-#include "dp_gui_theextmgr.hxx"
-#include "dp_gui_dialog2.hxx"
-#include "dp_dependencies.hxx"
-
-#include "comphelper/processfactory.hxx"
-#include "com/sun/star/i18n/CollatorOptions.hpp"
-#include "com/sun/star/deployment/DependencyException.hpp"
-#include "com/sun/star/deployment/DeploymentException.hpp"
-
-
-#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
-
-using namespace ::com::sun::star;
-
-namespace dp_gui {
-
-//------------------------------------------------------------------------------
-// struct Entry_Impl
-//------------------------------------------------------------------------------
-Entry_Impl::Entry_Impl( const uno::Reference< deployment::XPackage > &xPackage,
- const uno::Reference< deployment::XPackageManager > &xPackageManager,
- PackageState eState ) :
- m_bActive( false ),
- m_bLocked( false ),
- m_bHasOptions( false ),
- m_bShared( false ),
- m_bNew( false ),
- m_bChecked( false ),
- m_bMissingDeps( false ),
- m_eState( eState ),
- m_pPublisher( NULL ),
- m_xPackage( xPackage ),
- m_xPackageManager( xPackageManager )
-{
- m_sTitle = xPackage->getDisplayName();
- m_sVersion = xPackage->getVersion();
- m_sDescription = xPackage->getDescription();
-
- beans::StringPair aInfo( m_xPackage->getPublisherInfo() );
- m_sPublisher = aInfo.First;
- m_sPublisherURL = aInfo.Second;
-
- // get the icons for the package if there are any
- uno::Reference< graphic::XGraphic > xGraphic = xPackage->getIcon( false );
- if ( xGraphic.is() )
- m_aIcon = Image( xGraphic );
-
- xGraphic = xPackage->getIcon( true );
- if ( xGraphic.is() )
- m_aIconHC = Image( xGraphic );
- else
- m_aIconHC = m_aIcon;
-
- m_bLocked = m_xPackageManager->isReadOnly();
-
- if ( eState == AMBIGUOUS )
- m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS );
- else if ( eState == NOT_REGISTERED )
- checkDependencies();
-}
-
-//------------------------------------------------------------------------------
-Entry_Impl::~Entry_Impl()
-{}
-
-//------------------------------------------------------------------------------
-StringCompare Entry_Impl::CompareTo( const CollatorWrapper *pCollator, const TEntry_Impl pEntry ) const
-{
- StringCompare eCompare = (StringCompare) pCollator->compareString( m_sTitle, pEntry->m_sTitle );
- if ( eCompare == COMPARE_EQUAL )
- {
- eCompare = m_sVersion.CompareTo( pEntry->m_sVersion );
- if ( eCompare == COMPARE_EQUAL )
- {
- if ( m_xPackageManager != pEntry->m_xPackageManager )
- {
- sal_Int32 nCompare = m_xPackageManager->getContext().compareTo( pEntry->m_xPackageManager->getContext() );
- if ( nCompare < 0 )
- eCompare = COMPARE_LESS;
- else if ( nCompare > 0 )
- eCompare = COMPARE_GREATER;
- }
- }
- }
- return eCompare;
-}
-
-//------------------------------------------------------------------------------
-void Entry_Impl::checkDependencies()
-{
- try {
- m_xPackage->checkDependencies( uno::Reference< ucb::XCommandEnvironment >() );
- }
- catch ( deployment::DeploymentException &e )
- {
- deployment::DependencyException depExc;
- if ( e.Cause >>= depExc )
- {
- rtl::OUString aMissingDep( DialogHelper::getResourceString( RID_STR_ERROR_MISSING_DEPENDENCIES ) );
- for ( sal_Int32 i = 0; i < depExc.UnsatisfiedDependencies.getLength(); ++i )
- {
- aMissingDep += OUSTR("\n");
- aMissingDep += dp_misc::Dependencies::getErrorText( depExc.UnsatisfiedDependencies[i]);
- }
- aMissingDep += OUSTR("\n");
- m_sErrorText = aMissingDep;
- m_bMissingDeps = true;
- }
- }
-}
-//------------------------------------------------------------------------------
-// ExtensionRemovedListener
-//------------------------------------------------------------------------------
-void ExtensionRemovedListener::disposing( lang::EventObject const & rEvt )
- throw ( uno::RuntimeException )
-{
- uno::Reference< deployment::XPackage > xPackage( rEvt.Source, uno::UNO_QUERY );
-
- if ( xPackage.is() )
- {
- m_pParent->removeEntry( xPackage );
- }
-}
-
-//------------------------------------------------------------------------------
-ExtensionRemovedListener::~ExtensionRemovedListener()
-{
-}
-
-//------------------------------------------------------------------------------
-// ExtensionBox_Impl
-//------------------------------------------------------------------------------
-ExtensionBox_Impl::ExtensionBox_Impl( Dialog* pParent, TheExtensionManager *pManager ) :
- IExtensionListBox( pParent, WB_BORDER | WB_TABSTOP | WB_CHILDDLGCTRL ),
- m_bHasScrollBar( false ),
- m_bHasActive( false ),
- m_bNeedsRecalc( true ),
- m_bHasNew( false ),
- m_bInCheckMode( false ),
- m_bAdjustActive( false ),
- m_bInDelete( false ),
- m_nActive( 0 ),
- m_nTopIndex( 0 ),
- m_nActiveHeight( 0 ),
- m_nExtraHeight( 2 ),
- m_aLockedImage( DialogHelper::getResId( RID_IMG_LOCKED ) ),
- m_aLockedImageHC( DialogHelper::getResId( RID_IMG_LOCKED_HC ) ),
- m_aWarningImage( DialogHelper::getResId( RID_IMG_WARNING ) ),
- m_aWarningImageHC( DialogHelper::getResId( RID_IMG_WARNING_HC ) ),
- m_aDefaultImage( DialogHelper::getResId( RID_IMG_EXTENSION ) ),
- m_aDefaultImageHC( DialogHelper::getResId( RID_IMG_EXTENSION_HC ) ),
- m_pScrollBar( NULL ),
- m_pManager( pManager )
-{
- SetHelpId( HID_EXTENSION_MANAGER_LISTBOX );
-
- m_pScrollBar = new ScrollBar( this, WB_VERT );
- m_pScrollBar->SetScrollHdl( LINK( this, ExtensionBox_Impl, ScrollHdl ) );
- m_pScrollBar->EnableDrag();
-
- SetPaintTransparent( true );
- SetPosPixel( Point( RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP ) );
- long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
- long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
- if ( nIconHeight < nTitleHeight )
- m_nStdHeight = nTitleHeight;
- else
- m_nStdHeight = nIconHeight;
- m_nStdHeight += GetTextHeight() + TOP_OFFSET;
-
- nIconHeight = ICON_HEIGHT + 2*TOP_OFFSET + 1;
- if ( m_nStdHeight < nIconHeight )
- m_nStdHeight = nIconHeight;
-
- m_nActiveHeight = m_nStdHeight;
-
- const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
- if( IsControlBackground() )
- SetBackground( GetControlBackground() );
- else
- SetBackground( rStyleSettings.GetFieldColor() );
-
- m_xRemoveListener = new ExtensionRemovedListener( this );
-
- m_pLocale = new lang::Locale( Application::GetSettings().GetLocale() );
- m_pCollator = new CollatorWrapper( ::comphelper::getProcessServiceFactory() );
- m_pCollator->loadDefaultCollator( *m_pLocale, i18n::CollatorOptions::CollatorOptions_IGNORE_CASE );
-
- Show();
-}
-
-//------------------------------------------------------------------------------
-ExtensionBox_Impl::~ExtensionBox_Impl()
-{
- if ( ! m_bInDelete )
- DeleteRemoved();
-
- m_bInDelete = true;
-
- typedef std::vector< TEntry_Impl >::iterator ITER;
-
- for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
- {
- if ( (*iIndex)->m_pPublisher )
- {
- delete (*iIndex)->m_pPublisher;
- (*iIndex)->m_pPublisher = NULL;
- }
- (*iIndex)->m_xPackage->removeEventListener( uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
- }
-
- m_vEntries.clear();
-
- delete m_pScrollBar;
-
- m_xRemoveListener.clear();
-
- delete m_pLocale;
- delete m_pCollator;
-}
-
-//------------------------------------------------------------------------------
-sal_Int32 ExtensionBox_Impl::getItemCount() const
-{
- return static_cast< sal_Int32 >( m_vEntries.size() );
-}
-
-//------------------------------------------------------------------------------
-sal_Int32 ExtensionBox_Impl::getSelIndex() const
-{
- if ( m_bHasActive )
- {
- OSL_ASSERT( m_nActive >= -1);
- return static_cast< sal_Int32 >( m_nActive );
- }
- else
- return static_cast< sal_Int32 >( EXTENSION_LISTBOX_ENTRY_NOTFOUND );
-}
-
-//------------------------------------------------------------------------------
-void ExtensionBox_Impl::checkIndex( sal_Int32 nIndex ) const
-{
- if ( nIndex < 0 )
- throw lang::IllegalArgumentException( OUSTR("The list index starts with 0"),0, 0 );
- if ( static_cast< sal_uInt32 >( nIndex ) >= m_vEntries.size())
- throw lang::IllegalArgumentException( OUSTR("There is no element at the provided position."
- "The position exceeds the number of available list entries"),0, 0 );
-}
-
-//------------------------------------------------------------------------------
-rtl::OUString ExtensionBox_Impl::getItemName( sal_Int32 nIndex ) const
-{
- const ::osl::MutexGuard aGuard( m_entriesMutex );
- checkIndex( nIndex );
- return m_vEntries[ nIndex ]->m_sTitle;
-}
-
-//------------------------------------------------------------------------------
-rtl::OUString ExtensionBox_Impl::getItemVersion( sal_Int32 nIndex ) const
-{
- const ::osl::MutexGuard aGuard( m_entriesMutex );
- checkIndex( nIndex );
- return m_vEntries[ nIndex ]->m_sVersion;
-}
-
-//------------------------------------------------------------------------------
-rtl::OUString ExtensionBox_Impl::getItemDescription( sal_Int32 nIndex ) const
-{
- const ::osl::MutexGuard aGuard( m_entriesMutex );
- checkIndex( nIndex );
- return m_vEntries[ nIndex ]->m_sDescription;
-}
-
-//------------------------------------------------------------------------------
-rtl::OUString ExtensionBox_Impl::getItemPublisher( sal_Int32 nIndex ) const
-{
- const ::osl::MutexGuard aGuard( m_entriesMutex );
- checkIndex( nIndex );
- return m_vEntries[ nIndex ]->m_sPublisher;
-}
-
-//------------------------------------------------------------------------------
-rtl::OUString ExtensionBox_Impl::getItemPublisherLink( sal_Int32 nIndex ) const
-{
- const ::osl::MutexGuard aGuard( m_entriesMutex );
- checkIndex( nIndex );
- return m_vEntries[ nIndex ]->m_sPublisherURL;
-}
-
-//------------------------------------------------------------------------------
-void ExtensionBox_Impl::select( sal_Int32 nIndex )
-{
- const ::osl::MutexGuard aGuard( m_entriesMutex );
- checkIndex( nIndex );
- selectEntry( nIndex );
-}
-
-//------------------------------------------------------------------------------
-void ExtensionBox_Impl::select( const rtl::OUString & sName )
-{
- const ::osl::MutexGuard aGuard( m_entriesMutex );
- typedef ::std::vector< TEntry_Impl >::const_iterator It;
-
- for ( It iIter = m_vEntries.begin(); iIter < m_vEntries.end(); iIter++ )
- {
- if ( sName.equals( (*iIter)->m_sTitle ) )
- {
- long nPos = iIter - m_vEntries.begin();
- selectEntry( nPos );
- break;
- }
- }
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-// Title + description
-void ExtensionBox_Impl::CalcActiveHeight( const long nPos )
-{
- const ::osl::MutexGuard aGuard( m_entriesMutex );
-
- // get title height
- long aTextHeight;
- long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
- long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
- if ( nIconHeight < nTitleHeight )
- aTextHeight = nTitleHeight;
- else
- aTextHeight = nIconHeight;
-
- // calc description height
- Size aSize = GetOutputSizePixel();
- if ( m_bHasScrollBar )
- aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
-
- aSize.Width() -= ICON_OFFSET;
- aSize.Height() = 10000;
-
- rtl::OUString aText( m_vEntries[ nPos ]->m_sErrorText );
- aText += m_vEntries[ nPos ]->m_sDescription;
-
- Rectangle aRect = GetTextRect( Rectangle( Point(), aSize ), aText,
- TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
- aTextHeight += aRect.GetHeight();
-
- if ( aTextHeight < m_nStdHeight )
- aTextHeight = m_nStdHeight;
-
- m_nActiveHeight = aTextHeight + m_nExtraHeight;
-}
-
-//------------------------------------------------------------------------------
-const Size ExtensionBox_Impl::GetMinOutputSizePixel() const
-{
- return Size( 200, 80 );
-}
-
-//------------------------------------------------------------------------------
-Rectangle ExtensionBox_Impl::GetEntryRect( const long nPos ) const
-{
- const ::osl::MutexGuard aGuard( m_entriesMutex );
-
- Size aSize( GetOutputSizePixel() );
-
- if ( m_bHasScrollBar )
- aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
-
- if ( m_vEntries[ nPos ]->m_bActive )
- aSize.Height() = m_nActiveHeight;
- else
- aSize.Height() = m_nStdHeight;
-
- Point aPos( 0, -m_nTopIndex + nPos * m_nStdHeight );
- if ( m_bHasActive && ( nPos < m_nActive ) )
- aPos.Y() += m_nActiveHeight - m_nStdHeight;
-
- return Rectangle( aPos, aSize );
-}
-
-//------------------------------------------------------------------------------
-void ExtensionBox_Impl::DeleteRemoved()
-{
- const ::osl::MutexGuard aGuard( m_entriesMutex );
-
- m_bInDelete = true;
-
- if ( ! m_vRemovedEntries.empty() )
- {
- typedef std::vector< TEntry_Impl >::iterator ITER;
-
- for ( ITER iIndex = m_vRemovedEntries.begin(); iIndex < m_vRemovedEntries.end(); ++iIndex )
- {
- if ( (*iIndex)->m_pPublisher )
- {
- delete (*iIndex)->m_pPublisher;
- (*iIndex)->m_pPublisher = NULL;
- }
- }
-
- m_vRemovedEntries.clear();
- }
-
- m_bInDelete = false;
-}
-
-//------------------------------------------------------------------------------
-//This function may be called with nPos < 0
-void ExtensionBox_Impl::selectEntry( const long nPos )
-{
- //ToDo whe should not use the guard at such a big scope here.
- //Currently it is used to gard m_vEntries and m_nActive. m_nActive will be
- //modified in this function.
- //It would be probably best to always use a copy of m_vEntries
- //and some other state variables from ExtensionBox_Impl for
- //the whole painting operation. See issue i86993
- ::osl::ClearableMutexGuard guard(m_entriesMutex);
-
- if ( m_bInCheckMode )
- return;
-
- if ( m_bHasActive )
- {
- if ( nPos == m_nActive )
- return;
-
- m_bHasActive = false;
- m_vEntries[ m_nActive ]->m_bActive = false;
- }
-
- if ( ( nPos >= 0 ) && ( nPos < (long) m_vEntries.size() ) )
- {
- m_bHasActive = true;
- m_nActive = nPos;
- m_vEntries[ nPos ]->m_bActive = true;
-
- if ( IsReallyVisible() )
- {
- m_bNeedsRecalc = true;
- m_bAdjustActive = true;
- }
- }
-
- if ( IsReallyVisible() )
- Invalidate();
-
- guard.clear();
-}
-
-// -----------------------------------------------------------------------
-void ExtensionBox_Impl::DrawRow( const Rectangle& rRect, const TEntry_Impl pEntry )
-{
- const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
-
- if ( pEntry->m_bActive )
- SetTextColor( rStyleSettings.GetHighlightTextColor() );
- else if ( ( pEntry->m_eState != REGISTERED ) && ( pEntry->m_eState != NOT_AVAILABLE ) )
- SetTextColor( rStyleSettings.GetDisableColor() );
- else if ( IsControlForeground() )
- SetTextColor( GetControlForeground() );
- else
- SetTextColor( rStyleSettings.GetFieldTextColor() );
-
- if ( pEntry->m_bActive )
- {
- SetLineColor();
- SetFillColor( rStyleSettings.GetHighlightColor() );
- DrawRect( rRect );
- }
- else
- {
- if( IsControlBackground() )
- SetBackground( GetControlBackground() );
- else
- SetBackground( rStyleSettings.GetFieldColor() );
-
- SetTextFillColor();
- Erase( rRect );
- }
-
- // Draw extension icon
- Point aPos( rRect.TopLeft() );
- aPos += Point( TOP_OFFSET, TOP_OFFSET );
- Image aImage;
- if ( ! pEntry->m_aIcon )
- aImage = isHCMode() ? m_aDefaultImageHC : m_aDefaultImage;
- else
- aImage = isHCMode() ? pEntry->m_aIconHC : pEntry->m_aIcon;
- Size aImageSize = aImage.GetSizePixel();
- if ( ( aImageSize.Width() <= ICON_HEIGHT ) && ( aImageSize.Height() <= ICON_HEIGHT ) )
- DrawImage( Point( aPos.X()+((ICON_HEIGHT-aImageSize.Width())/2), aPos.Y()+((ICON_HEIGHT-aImageSize.Height())/2) ), aImage );
- else
- DrawImage( aPos, Size( ICON_HEIGHT, ICON_HEIGHT ), aImage );
-
- // Setup fonts
- Font aStdFont( GetFont() );
- Font aBoldFont( aStdFont );
- aBoldFont.SetWeight( WEIGHT_BOLD );
- SetFont( aBoldFont );
- long aTextHeight = GetTextHeight();
-
- // Init publisher link here
- if ( !pEntry->m_pPublisher && pEntry->m_sPublisher.Len() )
- {
- pEntry->m_pPublisher = new svt::FixedHyperlink( this );
- pEntry->m_pPublisher->SetBackground();
- pEntry->m_pPublisher->SetPaintTransparent( true );
- pEntry->m_pPublisher->SetURL( pEntry->m_sPublisherURL );
- pEntry->m_pPublisher->SetDescription( pEntry->m_sPublisher );
- Size aSize = FixedText::CalcMinimumTextSize( pEntry->m_pPublisher );
- pEntry->m_pPublisher->SetSizePixel( aSize );
-
- if ( m_aClickHdl.IsSet() )
- pEntry->m_pPublisher->SetClickHdl( m_aClickHdl );
- }
-
- // Get max title width
- long nMaxTitleWidth = rRect.GetWidth() - ICON_OFFSET;
- nMaxTitleWidth -= ( 2 * SMALL_ICON_SIZE ) + ( 4 * SPACE_BETWEEN );
- if ( pEntry->m_pPublisher )
- {
- nMaxTitleWidth -= pEntry->m_pPublisher->GetSizePixel().Width() + (2*SPACE_BETWEEN);
- }
-
- long aVersionWidth = GetTextWidth( pEntry->m_sVersion );
- long aTitleWidth = GetTextWidth( pEntry->m_sTitle ) + (aTextHeight / 3);
-
- aPos = rRect.TopLeft() + Point( ICON_OFFSET, TOP_OFFSET );
-
- if ( aTitleWidth > nMaxTitleWidth - aVersionWidth )
- {
- aTitleWidth = nMaxTitleWidth - aVersionWidth - (aTextHeight / 3);
- String aShortTitle = GetEllipsisString( pEntry->m_sTitle, aTitleWidth );
- DrawText( aPos, aShortTitle );
- aTitleWidth += (aTextHeight / 3);
- }
- else
- DrawText( aPos, pEntry->m_sTitle );
-
- SetFont( aStdFont );
- DrawText( Point( aPos.X() + aTitleWidth, aPos.Y() ), pEntry->m_sVersion );
-
- long nIconHeight = TOP_OFFSET + SMALL_ICON_SIZE;
- long nTitleHeight = TOP_OFFSET + GetTextHeight();
- if ( nIconHeight < nTitleHeight )
- aTextHeight = nTitleHeight;
- else
- aTextHeight = nIconHeight;
-
- // draw description
- String sDescription;
- if ( pEntry->m_sErrorText.Len() )
- {
- if ( pEntry->m_bActive )
- sDescription = pEntry->m_sErrorText + OUSTR("\n") + pEntry->m_sDescription;
- else
- sDescription = pEntry->m_sErrorText;
- }
- else
- sDescription = pEntry->m_sDescription;
-
- aPos.Y() += aTextHeight;
- if ( pEntry->m_bActive )
- {
- DrawText( Rectangle( aPos.X(), aPos.Y(), rRect.Right(), rRect.Bottom() - m_nExtraHeight ),
- sDescription, TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
- }
- else
- {
- const long nWidth = GetTextWidth( sDescription );
- if ( nWidth > rRect.GetWidth() - aPos.X() )
- sDescription = GetEllipsisString( sDescription, rRect.GetWidth() - aPos.X() );
- DrawText( aPos, sDescription );
- }
-
- // Draw publisher link
- if ( pEntry->m_pPublisher )
- {
- pEntry->m_pPublisher->Show();
- aPos = rRect.TopLeft() + Point( ICON_OFFSET + nMaxTitleWidth + (2*SPACE_BETWEEN), TOP_OFFSET );
- pEntry->m_pPublisher->SetPosPixel( aPos );
- }
-
- // Draw status icons
- if ( pEntry->m_bShared )
- {
- aPos = rRect.TopRight() + Point( -(RIGHT_ICON_OFFSET + SMALL_ICON_SIZE), TOP_OFFSET );
- DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), isHCMode() ? m_aLockedImageHC : m_aLockedImage );
- }
- if ( ( pEntry->m_eState == AMBIGUOUS ) || pEntry->m_bMissingDeps )
- {
- aPos = rRect.TopRight() + Point( -(RIGHT_ICON_OFFSET + SPACE_BETWEEN + 2*SMALL_ICON_SIZE), TOP_OFFSET );
- DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), isHCMode() ? m_aWarningImageHC : m_aWarningImage );
- }
-
- SetLineColor( Color( COL_LIGHTGRAY ) );
- DrawLine( rRect.BottomLeft(), rRect.BottomRight() );
-}
-
-// -----------------------------------------------------------------------
-void ExtensionBox_Impl::RecalcAll()
-{
- if ( m_bHasActive )
- CalcActiveHeight( m_nActive );
-
- SetupScrollBar();
-
- if ( m_bHasActive )
- {
- Rectangle aEntryRect = GetEntryRect( m_nActive );
-
- if ( m_bAdjustActive )
- {
- m_bAdjustActive = false;
-
- // If the top of the selected entry isn't visible, make it visible
- if ( aEntryRect.Top() < 0 )
- {
- m_nTopIndex += aEntryRect.Top();
- aEntryRect.Move( 0, -aEntryRect.Top() );
- }
-
- // If the bottom of the selected entry isn't visible, make it visible even if now the top
- // isn't visible any longer ( the buttons are more important )
- Size aOutputSize = GetOutputSizePixel();
- if ( aEntryRect.Bottom() > aOutputSize.Height() )
- {
- m_nTopIndex += ( aEntryRect.Bottom() - aOutputSize.Height() );
- aEntryRect.Move( 0, -( aEntryRect.Bottom() - aOutputSize.Height() ) );
- }
-
- // If there is unused space below the last entry but all entries don't fit into the box,
- // move the content down to use the whole space
- const long nTotalHeight = GetTotalHeight();
- if ( m_bHasScrollBar && ( aOutputSize.Height() + m_nTopIndex > nTotalHeight ) )
- {
- long nOffset = m_nTopIndex;
- m_nTopIndex = nTotalHeight - aOutputSize.Height();
- nOffset -= m_nTopIndex;
- aEntryRect.Move( 0, nOffset );
- }
-
- if ( m_bHasScrollBar )
- m_pScrollBar->SetThumbPos( m_nTopIndex );
- }
- }
-
- m_bNeedsRecalc = false;
-}
-
-// -----------------------------------------------------------------------
-bool ExtensionBox_Impl::HandleTabKey( bool )
-{
- return false;
-}
-
-// -----------------------------------------------------------------------
-bool ExtensionBox_Impl::HandleCursorKey( USHORT nKeyCode )
-{
- if ( m_vEntries.empty() )
- return true;
-
- long nSelect = 0;
-
- if ( m_bHasActive )
- {
- long nPageSize = GetOutputSizePixel().Height() / m_nStdHeight;
- if ( nPageSize < 2 )
- nPageSize = 2;
-
- if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_RIGHT ) )
- nSelect = m_nActive + 1;
- else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_LEFT ) )
- nSelect = m_nActive - 1;
- else if ( nKeyCode == KEY_HOME )
- nSelect = 0;
- else if ( nKeyCode == KEY_END )
- nSelect = m_vEntries.size() - 1;
- else if ( nKeyCode == KEY_PAGEUP )
- nSelect = m_nActive - nPageSize + 1;
- else if ( nKeyCode == KEY_PAGEDOWN )
- nSelect = m_nActive + nPageSize - 1;
- }
- else // when there is no selected entry, we will select the first or the last.
- {
- if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_PAGEDOWN ) || ( nKeyCode == KEY_HOME ) )
- nSelect = 0;
- else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_PAGEUP ) || ( nKeyCode == KEY_END ) )
- nSelect = m_vEntries.size() - 1;
- }
-
- if ( nSelect < 0 )
- nSelect = 0;
- if ( nSelect >= (long) m_vEntries.size() )
- nSelect = m_vEntries.size() - 1;
-
- selectEntry( nSelect );
-
- return true;
-}
-
-// -----------------------------------------------------------------------
-void ExtensionBox_Impl::Paint( const Rectangle &/*rPaintRect*/ )
-{
- if ( !m_bInDelete )
- DeleteRemoved();
-
- if ( m_bNeedsRecalc )
- RecalcAll();
-
- Point aStart( 0, -m_nTopIndex );
- Size aSize( GetOutputSizePixel() );
-
- if ( m_bHasScrollBar )
- aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
-
- const ::osl::MutexGuard aGuard( m_entriesMutex );
-
- typedef std::vector< TEntry_Impl >::iterator ITER;
- for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
- {
- aSize.Height() = (*iIndex)->m_bActive ? m_nActiveHeight : m_nStdHeight;
- Rectangle aEntryRect( aStart, aSize );
- DrawRow( aEntryRect, *iIndex );
- aStart.Y() += aSize.Height();
- }
-}
-
-// -----------------------------------------------------------------------
-long ExtensionBox_Impl::GetTotalHeight() const
-{
- long nHeight = m_vEntries.size() * m_nStdHeight;
-
- if ( m_bHasActive )
- {
- nHeight += m_nActiveHeight - m_nStdHeight;
- }
-
- return nHeight;
-}
-
-// -----------------------------------------------------------------------
-void ExtensionBox_Impl::SetupScrollBar()
-{
- const Size aSize = GetOutputSizePixel();
- const long nScrBarSize = GetSettings().GetStyleSettings().GetScrollBarSize();
- const long nTotalHeight = GetTotalHeight();
- const bool bNeedsScrollBar = ( nTotalHeight > aSize.Height() );
-
- if ( bNeedsScrollBar )
- {
- if ( m_nTopIndex + aSize.Height() > nTotalHeight )
- m_nTopIndex = nTotalHeight - aSize.Height();
-
- m_pScrollBar->SetPosSizePixel( Point( aSize.Width() - nScrBarSize, 0 ),
- Size( nScrBarSize, aSize.Height() ) );
- m_pScrollBar->SetRangeMax( nTotalHeight );
- m_pScrollBar->SetVisibleSize( aSize.Height() );
- m_pScrollBar->SetPageSize( ( aSize.Height() * 4 ) / 5 );
- m_pScrollBar->SetLineSize( m_nStdHeight );
- m_pScrollBar->SetThumbPos( m_nTopIndex );
-
- if ( !m_bHasScrollBar )
- m_pScrollBar->Show();
- }
- else if ( m_bHasScrollBar )
- {
- m_pScrollBar->Hide();
- m_nTopIndex = 0;
- }
-
- m_bHasScrollBar = bNeedsScrollBar;
-}
-
-// -----------------------------------------------------------------------
-void ExtensionBox_Impl::Resize()
-{
- RecalcAll();
-}
-
-//------------------------------------------------------------------------------
-long ExtensionBox_Impl::PointToPos( const Point& rPos )
-{
- long nPos = ( rPos.Y() + m_nTopIndex ) / m_nStdHeight;
-
- if ( m_bHasActive && ( nPos > m_nActive ) )
- {
- if ( rPos.Y() + m_nTopIndex <= m_nActive*m_nStdHeight + m_nActiveHeight )
- nPos = m_nActive;
- else
- nPos = ( rPos.Y() + m_nTopIndex - (m_nActiveHeight - m_nStdHeight) ) / m_nStdHeight;
- }
-
- return nPos;
-}
-
-//------------------------------------------------------------------------------
-void ExtensionBox_Impl::MouseButtonDown( const MouseEvent& rMEvt )
-{
- long nPos = PointToPos( rMEvt.GetPosPixel() );
-
- if ( rMEvt.IsLeft() )
- {
- if ( rMEvt.IsMod1() && m_bHasActive )
- selectEntry( m_vEntries.size() ); // Selecting an not existing entry will deselect the current one
- else
- selectEntry( nPos );
- }
-}
-
-//------------------------------------------------------------------------------
-long ExtensionBox_Impl::Notify( NotifyEvent& rNEvt )
-{
- if ( !m_bInDelete )
- DeleteRemoved();
-
- bool bHandled = false;
-
- if ( rNEvt.GetType() == EVENT_KEYINPUT )
- {
- const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
- KeyCode aKeyCode = pKEvt->GetKeyCode();
- USHORT nKeyCode = aKeyCode.GetCode();
-
- if ( nKeyCode == KEY_TAB )
- bHandled = HandleTabKey( aKeyCode.IsShift() );
- else if ( aKeyCode.GetGroup() == KEYGROUP_CURSOR )
- bHandled = HandleCursorKey( nKeyCode );
- }
-
- if ( rNEvt.GetType() == EVENT_COMMAND )
- {
- if ( m_bHasScrollBar &&
- ( rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL ) )
- {
- const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
- if ( pData->GetMode() == COMMAND_WHEEL_SCROLL )
- {
- long nThumbPos = m_pScrollBar->GetThumbPos();
- if ( pData->GetDelta() < 0 )
- m_pScrollBar->DoScroll( nThumbPos + m_nStdHeight );
- else
- m_pScrollBar->DoScroll( nThumbPos - m_nStdHeight );
- bHandled = true;
- }
- }
- }
-
- if ( !bHandled )
- return Control::Notify( rNEvt );
- else
- return true;
-}
-
-//------------------------------------------------------------------------------
-bool ExtensionBox_Impl::FindEntryPos( const TEntry_Impl pEntry, const long nStart,
- const long nEnd, long &nPos )
-{
- nPos = nStart;
- if ( nStart > nEnd )
- return false;
-
- StringCompare eCompare;
-
- if ( nStart == nEnd )
- {
- eCompare = pEntry->CompareTo( m_pCollator, m_vEntries[ nStart ] );
- if ( eCompare == COMPARE_LESS )
- return false;
- else if ( eCompare == COMPARE_EQUAL )
- {
- //Workaround. See i86963.
- if (pEntry->m_xPackage != m_vEntries[nStart]->m_xPackage)
- return false;
-
- if ( m_bInCheckMode )
- m_vEntries[ nStart ]->m_bChecked = true;
- return true;
- }
- else
- {
- nPos = nStart + 1;
- return false;
- }
- }
-
- const long nMid = nStart + ( ( nEnd - nStart ) / 2 );
- eCompare = pEntry->CompareTo( m_pCollator, m_vEntries[ nMid ] );
-
- if ( eCompare == COMPARE_LESS )
- return FindEntryPos( pEntry, nStart, nMid-1, nPos );
- else if ( eCompare == COMPARE_GREATER )
- return FindEntryPos( pEntry, nMid+1, nEnd, nPos );
- else
- {
- //Workaround.See i86963.
- if (pEntry->m_xPackage != m_vEntries[nMid]->m_xPackage)
- return false;
-
- if ( m_bInCheckMode )
- m_vEntries[ nMid ]->m_bChecked = true;
- nPos = nMid;
- return true;
- }
-}
-
-//------------------------------------------------------------------------------
-long ExtensionBox_Impl::addEntry( const uno::Reference< deployment::XPackage > &xPackage,
- const uno::Reference< deployment::XPackageManager > &xPackageManager )
-{
- long nPos = 0;
- PackageState eState = m_pManager->getPackageState( xPackage );
-
- TEntry_Impl pEntry( new Entry_Impl( xPackage, xPackageManager, eState ) );
- xPackage->addEventListener( uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
-
- ::osl::ClearableMutexGuard guard(m_entriesMutex);
- if ( m_vEntries.empty() )
- {
- pEntry->m_bHasOptions = m_pManager->supportsOptions( xPackage );
- pEntry->m_bShared = ( m_pManager->getSharedPkgMgr() == xPackageManager );
- pEntry->m_bNew = m_bInCheckMode;
- m_vEntries.push_back( pEntry );
- }
- else
- {
- if ( !FindEntryPos( pEntry, 0, m_vEntries.size()-1, nPos ) )
- {
- pEntry->m_bHasOptions = m_pManager->supportsOptions( xPackage );
- pEntry->m_bShared = ( m_pManager->getSharedPkgMgr() == xPackageManager );
- pEntry->m_bNew = m_bInCheckMode;
- m_vEntries.insert( m_vEntries.begin()+nPos, pEntry );
- }
- else if ( !m_bInCheckMode )
- {
- OSL_ENSURE( 0, "ExtensionBox_Impl::addEntry(): Will not add duplicate entries" );
- }
- }
- //access to m_nActive must be guarded
- if ( !m_bInCheckMode && m_bHasActive && ( m_nActive >= nPos ) )
- m_nActive += 1;
-
- guard.clear();
-
- if ( IsReallyVisible() )
- Invalidate();
-
- m_bNeedsRecalc = true;
-
- return nPos;
-}
-
-//------------------------------------------------------------------------------
-void ExtensionBox_Impl::updateEntry( const uno::Reference< deployment::XPackage > &xPackage )
-{
- typedef std::vector< TEntry_Impl >::iterator ITER;
- for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
- {
- if ( (*iIndex)->m_xPackage == xPackage )
- {
- PackageState eState = m_pManager->getPackageState( xPackage );
- (*iIndex)->m_bHasOptions = m_pManager->supportsOptions( xPackage );
- (*iIndex)->m_eState = eState;
- (*iIndex)->m_sTitle = xPackage->getDisplayName();
- (*iIndex)->m_sVersion = xPackage->getVersion();
- (*iIndex)->m_sDescription = xPackage->getDescription();
-
- if ( eState == AMBIGUOUS )
- (*iIndex)->m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS );
- else
- (*iIndex)->m_sErrorText = String();
-
- if ( IsReallyVisible() )
- Invalidate();
- break;
- }
- }
-}
-
-//------------------------------------------------------------------------------
-void ExtensionBox_Impl::removeEntry( const uno::Reference< deployment::XPackage > &xPackage )
-{
- if ( ! m_bInDelete )
- {
- ::osl::ClearableMutexGuard aGuard( m_entriesMutex );
-
- typedef std::vector< TEntry_Impl >::iterator ITER;
-
- for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
- {
- if ( (*iIndex)->m_xPackage == xPackage )
- {
- long nPos = iIndex - m_vEntries.begin();
-
- // Entries mustn't removed here, because they contain a hyperlink control
- // which can only be deleted when the thread has the solar mutex. Therefor
- // the entry will be moved into the m_vRemovedEntries list which will be
- // cleared on the next paint event
- m_vRemovedEntries.push_back( *iIndex );
- m_vEntries.erase( iIndex );
-
- m_bNeedsRecalc = true;
-
- if ( IsReallyVisible() )
- Invalidate();
-
- if ( m_bHasActive )
- {
- if ( nPos < m_nActive )
- m_nActive -= 1;
- else if ( ( nPos == m_nActive ) &&
- ( nPos == (long) m_vEntries.size() ) )
- m_nActive -= 1;
-
- m_bHasActive = false;
- //clear before calling out of this method
- aGuard.clear();
- selectEntry( m_nActive );
- }
- break;
- }
- }
- }
-}
-
-//------------------------------------------------------------------------------
-void ExtensionBox_Impl::RemoveUnlocked()
-{
- bool bAllRemoved = false;
-
- while ( ! bAllRemoved )
- {
- bAllRemoved = true;
-
- ::osl::ClearableMutexGuard aGuard( m_entriesMutex );
-
- typedef std::vector< TEntry_Impl >::iterator ITER;
-
- for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
- {
- if ( !(*iIndex)->m_bLocked )
- {
- bAllRemoved = false;
- uno::Reference< deployment::XPackage> xPackage = (*iIndex)->m_xPackage;
- aGuard.clear();
- removeEntry( xPackage );
- break;
- }
- }
- }
-}
-
-//------------------------------------------------------------------------------
-void ExtensionBox_Impl::prepareChecking( const uno::Reference< deployment::XPackageManager > &xPackageMgr )
-{
- m_bInCheckMode = true;
- typedef std::vector< TEntry_Impl >::iterator ITER;
- for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
- {
- if ( (*iIndex)->m_xPackageManager == xPackageMgr )
- (*iIndex)->m_bChecked = false;
- else
- (*iIndex)->m_bChecked = true;
- (*iIndex)->m_bNew = false;
- }
-}
-
-//------------------------------------------------------------------------------
-void ExtensionBox_Impl::checkEntries()
-{
- long nNewPos = -1;
- long nPos = 0;
- bool bNeedsUpdate = false;
-
- ::osl::ClearableMutexGuard guard(m_entriesMutex);
- typedef std::vector< TEntry_Impl >::iterator ITER;
- ITER iIndex = m_vEntries.begin();
- while ( iIndex < m_vEntries.end() )
- {
- if ( (*iIndex)->m_bChecked == false )
- {
- bNeedsUpdate = true;
- nPos = iIndex-m_vEntries.begin();
- if ( (*iIndex)->m_bNew )
- {
- if ( nNewPos == - 1)
- nNewPos = nPos;
- if ( nPos <= m_nActive )
- m_nActive += 1;
- }
- }
- iIndex++;
- }
- guard.clear();
-
- m_bInCheckMode = false;
-
- if ( nNewPos != - 1)
- selectEntry( nNewPos );
-
- if ( bNeedsUpdate )
- {
- m_bNeedsRecalc = true;
- if ( IsReallyVisible() )
- Invalidate();
- }
-}
-//------------------------------------------------------------------------------
-bool ExtensionBox_Impl::isHCMode()
-{
- return (bool)GetSettings().GetStyleSettings().GetHighContrastMode();
-}
-
-//------------------------------------------------------------------------------
-void ExtensionBox_Impl::SetScrollHdl( const Link& rLink )
-{
- if ( m_pScrollBar )
- m_pScrollBar->SetScrollHdl( rLink );
-}
-
-// -----------------------------------------------------------------------
-void ExtensionBox_Impl::DoScroll( long nDelta )
-{
- m_nTopIndex += nDelta;
- Point aNewSBPt( m_pScrollBar->GetPosPixel() );
-
- Rectangle aScrRect( Point(), GetOutputSizePixel() );
- aScrRect.Right() -= m_pScrollBar->GetSizePixel().Width();
- Scroll( 0, -nDelta, aScrRect );
-
- m_pScrollBar->SetPosPixel( aNewSBPt );
-}
-
-// -----------------------------------------------------------------------
-IMPL_LINK( ExtensionBox_Impl, ScrollHdl, ScrollBar*, pScrBar )
-{
- DoScroll( pScrBar->GetDelta() );
-
- return 1;
-}
-
-} //namespace dp_gui
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "svtools/controldims.hrc"
+
+#include "dp_gui.h"
+#include "dp_gui_extlistbox.hxx"
+#include "dp_gui_theextmgr.hxx"
+#include "dp_gui_dialog2.hxx"
+#include "dp_dependencies.hxx"
+
+#include "comphelper/processfactory.hxx"
+#include "com/sun/star/i18n/CollatorOptions.hpp"
+#include "com/sun/star/deployment/DependencyException.hpp"
+#include "com/sun/star/deployment/DeploymentException.hpp"
+
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+using namespace ::com::sun::star;
+
+namespace dp_gui {
+
+//------------------------------------------------------------------------------
+// struct Entry_Impl
+//------------------------------------------------------------------------------
+Entry_Impl::Entry_Impl( const uno::Reference< deployment::XPackage > &xPackage,
+ const uno::Reference< deployment::XPackageManager > &xPackageManager,
+ PackageState eState ) :
+ m_bActive( false ),
+ m_bLocked( false ),
+ m_bHasOptions( false ),
+ m_bShared( false ),
+ m_bNew( false ),
+ m_bChecked( false ),
+ m_bMissingDeps( false ),
+ m_eState( eState ),
+ m_pPublisher( NULL ),
+ m_xPackage( xPackage ),
+ m_xPackageManager( xPackageManager )
+{
+ m_sTitle = xPackage->getDisplayName();
+ m_sVersion = xPackage->getVersion();
+ m_sDescription = xPackage->getDescription();
+
+ beans::StringPair aInfo( m_xPackage->getPublisherInfo() );
+ m_sPublisher = aInfo.First;
+ m_sPublisherURL = aInfo.Second;
+
+ // get the icons for the package if there are any
+ uno::Reference< graphic::XGraphic > xGraphic = xPackage->getIcon( false );
+ if ( xGraphic.is() )
+ m_aIcon = Image( xGraphic );
+
+ xGraphic = xPackage->getIcon( true );
+ if ( xGraphic.is() )
+ m_aIconHC = Image( xGraphic );
+ else
+ m_aIconHC = m_aIcon;
+
+ m_bLocked = m_xPackageManager->isReadOnly();
+
+ if ( eState == AMBIGUOUS )
+ m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS );
+ else if ( eState == NOT_REGISTERED )
+ checkDependencies();
+}
+
+//------------------------------------------------------------------------------
+Entry_Impl::~Entry_Impl()
+{}
+
+//------------------------------------------------------------------------------
+StringCompare Entry_Impl::CompareTo( const CollatorWrapper *pCollator, const TEntry_Impl pEntry ) const
+{
+ StringCompare eCompare = (StringCompare) pCollator->compareString( m_sTitle, pEntry->m_sTitle );
+ if ( eCompare == COMPARE_EQUAL )
+ {
+ eCompare = m_sVersion.CompareTo( pEntry->m_sVersion );
+ if ( eCompare == COMPARE_EQUAL )
+ {
+ if ( m_xPackageManager != pEntry->m_xPackageManager )
+ {
+ sal_Int32 nCompare = m_xPackageManager->getContext().compareTo( pEntry->m_xPackageManager->getContext() );
+ if ( nCompare < 0 )
+ eCompare = COMPARE_LESS;
+ else if ( nCompare > 0 )
+ eCompare = COMPARE_GREATER;
+ }
+ }
+ }
+ return eCompare;
+}
+
+//------------------------------------------------------------------------------
+void Entry_Impl::checkDependencies()
+{
+ try {
+ m_xPackage->checkDependencies( uno::Reference< ucb::XCommandEnvironment >() );
+ }
+ catch ( deployment::DeploymentException &e )
+ {
+ deployment::DependencyException depExc;
+ if ( e.Cause >>= depExc )
+ {
+ rtl::OUString aMissingDep( DialogHelper::getResourceString( RID_STR_ERROR_MISSING_DEPENDENCIES ) );
+ for ( sal_Int32 i = 0; i < depExc.UnsatisfiedDependencies.getLength(); ++i )
+ {
+ aMissingDep += OUSTR("\n");
+ aMissingDep += dp_misc::Dependencies::getErrorText( depExc.UnsatisfiedDependencies[i]);
+ }
+ aMissingDep += OUSTR("\n");
+ m_sErrorText = aMissingDep;
+ m_bMissingDeps = true;
+ }
+ }
+}
+//------------------------------------------------------------------------------
+// ExtensionRemovedListener
+//------------------------------------------------------------------------------
+void ExtensionRemovedListener::disposing( lang::EventObject const & rEvt )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< deployment::XPackage > xPackage( rEvt.Source, uno::UNO_QUERY );
+
+ if ( xPackage.is() )
+ {
+ m_pParent->removeEntry( xPackage );
+ }
+}
+
+//------------------------------------------------------------------------------
+ExtensionRemovedListener::~ExtensionRemovedListener()
+{
+}
+
+//------------------------------------------------------------------------------
+// ExtensionBox_Impl
+//------------------------------------------------------------------------------
+ExtensionBox_Impl::ExtensionBox_Impl( Dialog* pParent, TheExtensionManager *pManager ) :
+ IExtensionListBox( pParent, WB_BORDER | WB_TABSTOP | WB_CHILDDLGCTRL ),
+ m_bHasScrollBar( false ),
+ m_bHasActive( false ),
+ m_bNeedsRecalc( true ),
+ m_bHasNew( false ),
+ m_bInCheckMode( false ),
+ m_bAdjustActive( false ),
+ m_bInDelete( false ),
+ m_nActive( 0 ),
+ m_nTopIndex( 0 ),
+ m_nActiveHeight( 0 ),
+ m_nExtraHeight( 2 ),
+ m_aLockedImage( DialogHelper::getResId( RID_IMG_LOCKED ) ),
+ m_aLockedImageHC( DialogHelper::getResId( RID_IMG_LOCKED_HC ) ),
+ m_aWarningImage( DialogHelper::getResId( RID_IMG_WARNING ) ),
+ m_aWarningImageHC( DialogHelper::getResId( RID_IMG_WARNING_HC ) ),
+ m_aDefaultImage( DialogHelper::getResId( RID_IMG_EXTENSION ) ),
+ m_aDefaultImageHC( DialogHelper::getResId( RID_IMG_EXTENSION_HC ) ),
+ m_pScrollBar( NULL ),
+ m_pManager( pManager )
+{
+ SetHelpId( HID_EXTENSION_MANAGER_LISTBOX );
+
+ m_pScrollBar = new ScrollBar( this, WB_VERT );
+ m_pScrollBar->SetScrollHdl( LINK( this, ExtensionBox_Impl, ScrollHdl ) );
+ m_pScrollBar->EnableDrag();
+
+ SetPaintTransparent( true );
+ SetPosPixel( Point( RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP ) );
+ long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
+ long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
+ if ( nIconHeight < nTitleHeight )
+ m_nStdHeight = nTitleHeight;
+ else
+ m_nStdHeight = nIconHeight;
+ m_nStdHeight += GetTextHeight() + TOP_OFFSET;
+
+ nIconHeight = ICON_HEIGHT + 2*TOP_OFFSET + 1;
+ if ( m_nStdHeight < nIconHeight )
+ m_nStdHeight = nIconHeight;
+
+ m_nActiveHeight = m_nStdHeight;
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ if( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( rStyleSettings.GetFieldColor() );
+
+ m_xRemoveListener = new ExtensionRemovedListener( this );
+
+ m_pLocale = new lang::Locale( Application::GetSettings().GetLocale() );
+ m_pCollator = new CollatorWrapper( ::comphelper::getProcessServiceFactory() );
+ m_pCollator->loadDefaultCollator( *m_pLocale, i18n::CollatorOptions::CollatorOptions_IGNORE_CASE );
+
+ Show();
+}
+
+//------------------------------------------------------------------------------
+ExtensionBox_Impl::~ExtensionBox_Impl()
+{
+ if ( ! m_bInDelete )
+ DeleteRemoved();
+
+ m_bInDelete = true;
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_pPublisher )
+ {
+ delete (*iIndex)->m_pPublisher;
+ (*iIndex)->m_pPublisher = NULL;
+ }
+ (*iIndex)->m_xPackage->removeEventListener( uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
+ }
+
+ m_vEntries.clear();
+
+ delete m_pScrollBar;
+
+ m_xRemoveListener.clear();
+
+ delete m_pLocale;
+ delete m_pCollator;
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 ExtensionBox_Impl::getItemCount() const
+{
+ return static_cast< sal_Int32 >( m_vEntries.size() );
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 ExtensionBox_Impl::getSelIndex() const
+{
+ if ( m_bHasActive )
+ {
+ OSL_ASSERT( m_nActive >= -1);
+ return static_cast< sal_Int32 >( m_nActive );
+ }
+ else
+ return static_cast< sal_Int32 >( EXTENSION_LISTBOX_ENTRY_NOTFOUND );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::checkIndex( sal_Int32 nIndex ) const
+{
+ if ( nIndex < 0 )
+ throw lang::IllegalArgumentException( OUSTR("The list index starts with 0"),0, 0 );
+ if ( static_cast< sal_uInt32 >( nIndex ) >= m_vEntries.size())
+ throw lang::IllegalArgumentException( OUSTR("There is no element at the provided position."
+ "The position exceeds the number of available list entries"),0, 0 );
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemName( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sTitle;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemVersion( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sVersion;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemDescription( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sDescription;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemPublisher( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sPublisher;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemPublisherLink( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sPublisherURL;
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::select( sal_Int32 nIndex )
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ selectEntry( nIndex );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::select( const rtl::OUString & sName )
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ typedef ::std::vector< TEntry_Impl >::const_iterator It;
+
+ for ( It iIter = m_vEntries.begin(); iIter < m_vEntries.end(); iIter++ )
+ {
+ if ( sName.equals( (*iIter)->m_sTitle ) )
+ {
+ long nPos = iIter - m_vEntries.begin();
+ selectEntry( nPos );
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+// Title + description
+void ExtensionBox_Impl::CalcActiveHeight( const long nPos )
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ // get title height
+ long aTextHeight;
+ long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
+ long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
+ if ( nIconHeight < nTitleHeight )
+ aTextHeight = nTitleHeight;
+ else
+ aTextHeight = nIconHeight;
+
+ // calc description height
+ Size aSize = GetOutputSizePixel();
+ if ( m_bHasScrollBar )
+ aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
+
+ aSize.Width() -= ICON_OFFSET;
+ aSize.Height() = 10000;
+
+ rtl::OUString aText( m_vEntries[ nPos ]->m_sErrorText );
+ aText += m_vEntries[ nPos ]->m_sDescription;
+
+ Rectangle aRect = GetTextRect( Rectangle( Point(), aSize ), aText,
+ TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
+ aTextHeight += aRect.GetHeight();
+
+ if ( aTextHeight < m_nStdHeight )
+ aTextHeight = m_nStdHeight;
+
+ m_nActiveHeight = aTextHeight + m_nExtraHeight;
+}
+
+//------------------------------------------------------------------------------
+const Size ExtensionBox_Impl::GetMinOutputSizePixel() const
+{
+ return Size( 200, 80 );
+}
+
+//------------------------------------------------------------------------------
+Rectangle ExtensionBox_Impl::GetEntryRect( const long nPos ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ Size aSize( GetOutputSizePixel() );
+
+ if ( m_bHasScrollBar )
+ aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
+
+ if ( m_vEntries[ nPos ]->m_bActive )
+ aSize.Height() = m_nActiveHeight;
+ else
+ aSize.Height() = m_nStdHeight;
+
+ Point aPos( 0, -m_nTopIndex + nPos * m_nStdHeight );
+ if ( m_bHasActive && ( nPos < m_nActive ) )
+ aPos.Y() += m_nActiveHeight - m_nStdHeight;
+
+ return Rectangle( aPos, aSize );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::DeleteRemoved()
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ m_bInDelete = true;
+
+ if ( ! m_vRemovedEntries.empty() )
+ {
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vRemovedEntries.begin(); iIndex < m_vRemovedEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_pPublisher )
+ {
+ delete (*iIndex)->m_pPublisher;
+ (*iIndex)->m_pPublisher = NULL;
+ }
+ }
+
+ m_vRemovedEntries.clear();
+ }
+
+ m_bInDelete = false;
+}
+
+//------------------------------------------------------------------------------
+//This function may be called with nPos < 0
+void ExtensionBox_Impl::selectEntry( const long nPos )
+{
+ //ToDo whe should not use the guard at such a big scope here.
+ //Currently it is used to gard m_vEntries and m_nActive. m_nActive will be
+ //modified in this function.
+ //It would be probably best to always use a copy of m_vEntries
+ //and some other state variables from ExtensionBox_Impl for
+ //the whole painting operation. See issue i86993
+ ::osl::ClearableMutexGuard guard(m_entriesMutex);
+
+ if ( m_bInCheckMode )
+ return;
+
+ if ( m_bHasActive )
+ {
+ if ( nPos == m_nActive )
+ return;
+
+ m_bHasActive = false;
+ m_vEntries[ m_nActive ]->m_bActive = false;
+ }
+
+ if ( ( nPos >= 0 ) && ( nPos < (long) m_vEntries.size() ) )
+ {
+ m_bHasActive = true;
+ m_nActive = nPos;
+ m_vEntries[ nPos ]->m_bActive = true;
+
+ if ( IsReallyVisible() )
+ {
+ m_bNeedsRecalc = true;
+ m_bAdjustActive = true;
+ }
+ }
+
+ if ( IsReallyVisible() )
+ Invalidate();
+
+ guard.clear();
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::DrawRow( const Rectangle& rRect, const TEntry_Impl pEntry )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( pEntry->m_bActive )
+ SetTextColor( rStyleSettings.GetHighlightTextColor() );
+ else if ( ( pEntry->m_eState != REGISTERED ) && ( pEntry->m_eState != NOT_AVAILABLE ) )
+ SetTextColor( rStyleSettings.GetDisableColor() );
+ else if ( IsControlForeground() )
+ SetTextColor( GetControlForeground() );
+ else
+ SetTextColor( rStyleSettings.GetFieldTextColor() );
+
+ if ( pEntry->m_bActive )
+ {
+ SetLineColor();
+ SetFillColor( rStyleSettings.GetHighlightColor() );
+ DrawRect( rRect );
+ }
+ else
+ {
+ if( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( rStyleSettings.GetFieldColor() );
+
+ SetTextFillColor();
+ Erase( rRect );
+ }
+
+ // Draw extension icon
+ Point aPos( rRect.TopLeft() );
+ aPos += Point( TOP_OFFSET, TOP_OFFSET );
+ Image aImage;
+ if ( ! pEntry->m_aIcon )
+ aImage = isHCMode() ? m_aDefaultImageHC : m_aDefaultImage;
+ else
+ aImage = isHCMode() ? pEntry->m_aIconHC : pEntry->m_aIcon;
+ Size aImageSize = aImage.GetSizePixel();
+ if ( ( aImageSize.Width() <= ICON_HEIGHT ) && ( aImageSize.Height() <= ICON_HEIGHT ) )
+ DrawImage( Point( aPos.X()+((ICON_HEIGHT-aImageSize.Width())/2), aPos.Y()+((ICON_HEIGHT-aImageSize.Height())/2) ), aImage );
+ else
+ DrawImage( aPos, Size( ICON_HEIGHT, ICON_HEIGHT ), aImage );
+
+ // Setup fonts
+ Font aStdFont( GetFont() );
+ Font aBoldFont( aStdFont );
+ aBoldFont.SetWeight( WEIGHT_BOLD );
+ SetFont( aBoldFont );
+ long aTextHeight = GetTextHeight();
+
+ // Init publisher link here
+ if ( !pEntry->m_pPublisher && pEntry->m_sPublisher.Len() )
+ {
+ pEntry->m_pPublisher = new svt::FixedHyperlink( this );
+ pEntry->m_pPublisher->SetBackground();
+ pEntry->m_pPublisher->SetPaintTransparent( true );
+ pEntry->m_pPublisher->SetURL( pEntry->m_sPublisherURL );
+ pEntry->m_pPublisher->SetDescription( pEntry->m_sPublisher );
+ Size aSize = FixedText::CalcMinimumTextSize( pEntry->m_pPublisher );
+ pEntry->m_pPublisher->SetSizePixel( aSize );
+
+ if ( m_aClickHdl.IsSet() )
+ pEntry->m_pPublisher->SetClickHdl( m_aClickHdl );
+ }
+
+ // Get max title width
+ long nMaxTitleWidth = rRect.GetWidth() - ICON_OFFSET;
+ nMaxTitleWidth -= ( 2 * SMALL_ICON_SIZE ) + ( 4 * SPACE_BETWEEN );
+ if ( pEntry->m_pPublisher )
+ {
+ nMaxTitleWidth -= pEntry->m_pPublisher->GetSizePixel().Width() + (2*SPACE_BETWEEN);
+ }
+
+ long aVersionWidth = GetTextWidth( pEntry->m_sVersion );
+ long aTitleWidth = GetTextWidth( pEntry->m_sTitle ) + (aTextHeight / 3);
+
+ aPos = rRect.TopLeft() + Point( ICON_OFFSET, TOP_OFFSET );
+
+ if ( aTitleWidth > nMaxTitleWidth - aVersionWidth )
+ {
+ aTitleWidth = nMaxTitleWidth - aVersionWidth - (aTextHeight / 3);
+ String aShortTitle = GetEllipsisString( pEntry->m_sTitle, aTitleWidth );
+ DrawText( aPos, aShortTitle );
+ aTitleWidth += (aTextHeight / 3);
+ }
+ else
+ DrawText( aPos, pEntry->m_sTitle );
+
+ SetFont( aStdFont );
+ DrawText( Point( aPos.X() + aTitleWidth, aPos.Y() ), pEntry->m_sVersion );
+
+ long nIconHeight = TOP_OFFSET + SMALL_ICON_SIZE;
+ long nTitleHeight = TOP_OFFSET + GetTextHeight();
+ if ( nIconHeight < nTitleHeight )
+ aTextHeight = nTitleHeight;
+ else
+ aTextHeight = nIconHeight;
+
+ // draw description
+ String sDescription;
+ if ( pEntry->m_sErrorText.Len() )
+ {
+ if ( pEntry->m_bActive )
+ sDescription = pEntry->m_sErrorText + OUSTR("\n") + pEntry->m_sDescription;
+ else
+ sDescription = pEntry->m_sErrorText;
+ }
+ else
+ sDescription = pEntry->m_sDescription;
+
+ aPos.Y() += aTextHeight;
+ if ( pEntry->m_bActive )
+ {
+ DrawText( Rectangle( aPos.X(), aPos.Y(), rRect.Right(), rRect.Bottom() - m_nExtraHeight ),
+ sDescription, TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
+ }
+ else
+ {
+ const long nWidth = GetTextWidth( sDescription );
+ if ( nWidth > rRect.GetWidth() - aPos.X() )
+ sDescription = GetEllipsisString( sDescription, rRect.GetWidth() - aPos.X() );
+ DrawText( aPos, sDescription );
+ }
+
+ // Draw publisher link
+ if ( pEntry->m_pPublisher )
+ {
+ pEntry->m_pPublisher->Show();
+ aPos = rRect.TopLeft() + Point( ICON_OFFSET + nMaxTitleWidth + (2*SPACE_BETWEEN), TOP_OFFSET );
+ pEntry->m_pPublisher->SetPosPixel( aPos );
+ }
+
+ // Draw status icons
+ if ( pEntry->m_bShared )
+ {
+ aPos = rRect.TopRight() + Point( -(RIGHT_ICON_OFFSET + SMALL_ICON_SIZE), TOP_OFFSET );
+ DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), isHCMode() ? m_aLockedImageHC : m_aLockedImage );
+ }
+ if ( ( pEntry->m_eState == AMBIGUOUS ) || pEntry->m_bMissingDeps )
+ {
+ aPos = rRect.TopRight() + Point( -(RIGHT_ICON_OFFSET + SPACE_BETWEEN + 2*SMALL_ICON_SIZE), TOP_OFFSET );
+ DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), isHCMode() ? m_aWarningImageHC : m_aWarningImage );
+ }
+
+ SetLineColor( Color( COL_LIGHTGRAY ) );
+ DrawLine( rRect.BottomLeft(), rRect.BottomRight() );
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::RecalcAll()
+{
+ if ( m_bHasActive )
+ CalcActiveHeight( m_nActive );
+
+ SetupScrollBar();
+
+ if ( m_bHasActive )
+ {
+ Rectangle aEntryRect = GetEntryRect( m_nActive );
+
+ if ( m_bAdjustActive )
+ {
+ m_bAdjustActive = false;
+
+ // If the top of the selected entry isn't visible, make it visible
+ if ( aEntryRect.Top() < 0 )
+ {
+ m_nTopIndex += aEntryRect.Top();
+ aEntryRect.Move( 0, -aEntryRect.Top() );
+ }
+
+ // If the bottom of the selected entry isn't visible, make it visible even if now the top
+ // isn't visible any longer ( the buttons are more important )
+ Size aOutputSize = GetOutputSizePixel();
+ if ( aEntryRect.Bottom() > aOutputSize.Height() )
+ {
+ m_nTopIndex += ( aEntryRect.Bottom() - aOutputSize.Height() );
+ aEntryRect.Move( 0, -( aEntryRect.Bottom() - aOutputSize.Height() ) );
+ }
+
+ // If there is unused space below the last entry but all entries don't fit into the box,
+ // move the content down to use the whole space
+ const long nTotalHeight = GetTotalHeight();
+ if ( m_bHasScrollBar && ( aOutputSize.Height() + m_nTopIndex > nTotalHeight ) )
+ {
+ long nOffset = m_nTopIndex;
+ m_nTopIndex = nTotalHeight - aOutputSize.Height();
+ nOffset -= m_nTopIndex;
+ aEntryRect.Move( 0, nOffset );
+ }
+
+ if ( m_bHasScrollBar )
+ m_pScrollBar->SetThumbPos( m_nTopIndex );
+ }
+ }
+
+ m_bNeedsRecalc = false;
+}
+
+// -----------------------------------------------------------------------
+bool ExtensionBox_Impl::HandleTabKey( bool )
+{
+ return false;
+}
+
+// -----------------------------------------------------------------------
+bool ExtensionBox_Impl::HandleCursorKey( USHORT nKeyCode )
+{
+ if ( m_vEntries.empty() )
+ return true;
+
+ long nSelect = 0;
+
+ if ( m_bHasActive )
+ {
+ long nPageSize = GetOutputSizePixel().Height() / m_nStdHeight;
+ if ( nPageSize < 2 )
+ nPageSize = 2;
+
+ if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_RIGHT ) )
+ nSelect = m_nActive + 1;
+ else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_LEFT ) )
+ nSelect = m_nActive - 1;
+ else if ( nKeyCode == KEY_HOME )
+ nSelect = 0;
+ else if ( nKeyCode == KEY_END )
+ nSelect = m_vEntries.size() - 1;
+ else if ( nKeyCode == KEY_PAGEUP )
+ nSelect = m_nActive - nPageSize + 1;
+ else if ( nKeyCode == KEY_PAGEDOWN )
+ nSelect = m_nActive + nPageSize - 1;
+ }
+ else // when there is no selected entry, we will select the first or the last.
+ {
+ if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_PAGEDOWN ) || ( nKeyCode == KEY_HOME ) )
+ nSelect = 0;
+ else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_PAGEUP ) || ( nKeyCode == KEY_END ) )
+ nSelect = m_vEntries.size() - 1;
+ }
+
+ if ( nSelect < 0 )
+ nSelect = 0;
+ if ( nSelect >= (long) m_vEntries.size() )
+ nSelect = m_vEntries.size() - 1;
+
+ selectEntry( nSelect );
+
+ return true;
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::Paint( const Rectangle &/*rPaintRect*/ )
+{
+ if ( !m_bInDelete )
+ DeleteRemoved();
+
+ if ( m_bNeedsRecalc )
+ RecalcAll();
+
+ Point aStart( 0, -m_nTopIndex );
+ Size aSize( GetOutputSizePixel() );
+
+ if ( m_bHasScrollBar )
+ aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
+
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ aSize.Height() = (*iIndex)->m_bActive ? m_nActiveHeight : m_nStdHeight;
+ Rectangle aEntryRect( aStart, aSize );
+ DrawRow( aEntryRect, *iIndex );
+ aStart.Y() += aSize.Height();
+ }
+}
+
+// -----------------------------------------------------------------------
+long ExtensionBox_Impl::GetTotalHeight() const
+{
+ long nHeight = m_vEntries.size() * m_nStdHeight;
+
+ if ( m_bHasActive )
+ {
+ nHeight += m_nActiveHeight - m_nStdHeight;
+ }
+
+ return nHeight;
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::SetupScrollBar()
+{
+ const Size aSize = GetOutputSizePixel();
+ const long nScrBarSize = GetSettings().GetStyleSettings().GetScrollBarSize();
+ const long nTotalHeight = GetTotalHeight();
+ const bool bNeedsScrollBar = ( nTotalHeight > aSize.Height() );
+
+ if ( bNeedsScrollBar )
+ {
+ if ( m_nTopIndex + aSize.Height() > nTotalHeight )
+ m_nTopIndex = nTotalHeight - aSize.Height();
+
+ m_pScrollBar->SetPosSizePixel( Point( aSize.Width() - nScrBarSize, 0 ),
+ Size( nScrBarSize, aSize.Height() ) );
+ m_pScrollBar->SetRangeMax( nTotalHeight );
+ m_pScrollBar->SetVisibleSize( aSize.Height() );
+ m_pScrollBar->SetPageSize( ( aSize.Height() * 4 ) / 5 );
+ m_pScrollBar->SetLineSize( m_nStdHeight );
+ m_pScrollBar->SetThumbPos( m_nTopIndex );
+
+ if ( !m_bHasScrollBar )
+ m_pScrollBar->Show();
+ }
+ else if ( m_bHasScrollBar )
+ {
+ m_pScrollBar->Hide();
+ m_nTopIndex = 0;
+ }
+
+ m_bHasScrollBar = bNeedsScrollBar;
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::Resize()
+{
+ RecalcAll();
+}
+
+//------------------------------------------------------------------------------
+long ExtensionBox_Impl::PointToPos( const Point& rPos )
+{
+ long nPos = ( rPos.Y() + m_nTopIndex ) / m_nStdHeight;
+
+ if ( m_bHasActive && ( nPos > m_nActive ) )
+ {
+ if ( rPos.Y() + m_nTopIndex <= m_nActive*m_nStdHeight + m_nActiveHeight )
+ nPos = m_nActive;
+ else
+ nPos = ( rPos.Y() + m_nTopIndex - (m_nActiveHeight - m_nStdHeight) ) / m_nStdHeight;
+ }
+
+ return nPos;
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ long nPos = PointToPos( rMEvt.GetPosPixel() );
+
+ if ( rMEvt.IsLeft() )
+ {
+ if ( rMEvt.IsMod1() && m_bHasActive )
+ selectEntry( m_vEntries.size() ); // Selecting an not existing entry will deselect the current one
+ else
+ selectEntry( nPos );
+ }
+}
+
+//------------------------------------------------------------------------------
+long ExtensionBox_Impl::Notify( NotifyEvent& rNEvt )
+{
+ if ( !m_bInDelete )
+ DeleteRemoved();
+
+ bool bHandled = false;
+
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ KeyCode aKeyCode = pKEvt->GetKeyCode();
+ USHORT nKeyCode = aKeyCode.GetCode();
+
+ if ( nKeyCode == KEY_TAB )
+ bHandled = HandleTabKey( aKeyCode.IsShift() );
+ else if ( aKeyCode.GetGroup() == KEYGROUP_CURSOR )
+ bHandled = HandleCursorKey( nKeyCode );
+ }
+
+ if ( rNEvt.GetType() == EVENT_COMMAND )
+ {
+ if ( m_bHasScrollBar &&
+ ( rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL ) )
+ {
+ const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
+ if ( pData->GetMode() == COMMAND_WHEEL_SCROLL )
+ {
+ long nThumbPos = m_pScrollBar->GetThumbPos();
+ if ( pData->GetDelta() < 0 )
+ m_pScrollBar->DoScroll( nThumbPos + m_nStdHeight );
+ else
+ m_pScrollBar->DoScroll( nThumbPos - m_nStdHeight );
+ bHandled = true;
+ }
+ }
+ }
+
+ if ( !bHandled )
+ return Control::Notify( rNEvt );
+ else
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool ExtensionBox_Impl::FindEntryPos( const TEntry_Impl pEntry, const long nStart,
+ const long nEnd, long &nPos )
+{
+ nPos = nStart;
+ if ( nStart > nEnd )
+ return false;
+
+ StringCompare eCompare;
+
+ if ( nStart == nEnd )
+ {
+ eCompare = pEntry->CompareTo( m_pCollator, m_vEntries[ nStart ] );
+ if ( eCompare == COMPARE_LESS )
+ return false;
+ else if ( eCompare == COMPARE_EQUAL )
+ {
+ //Workaround. See i86963.
+ if (pEntry->m_xPackage != m_vEntries[nStart]->m_xPackage)
+ return false;
+
+ if ( m_bInCheckMode )
+ m_vEntries[ nStart ]->m_bChecked = true;
+ return true;
+ }
+ else
+ {
+ nPos = nStart + 1;
+ return false;
+ }
+ }
+
+ const long nMid = nStart + ( ( nEnd - nStart ) / 2 );
+ eCompare = pEntry->CompareTo( m_pCollator, m_vEntries[ nMid ] );
+
+ if ( eCompare == COMPARE_LESS )
+ return FindEntryPos( pEntry, nStart, nMid-1, nPos );
+ else if ( eCompare == COMPARE_GREATER )
+ return FindEntryPos( pEntry, nMid+1, nEnd, nPos );
+ else
+ {
+ //Workaround.See i86963.
+ if (pEntry->m_xPackage != m_vEntries[nMid]->m_xPackage)
+ return false;
+
+ if ( m_bInCheckMode )
+ m_vEntries[ nMid ]->m_bChecked = true;
+ nPos = nMid;
+ return true;
+ }
+}
+
+//------------------------------------------------------------------------------
+long ExtensionBox_Impl::addEntry( const uno::Reference< deployment::XPackage > &xPackage,
+ const uno::Reference< deployment::XPackageManager > &xPackageManager )
+{
+ long nPos = 0;
+ PackageState eState = m_pManager->getPackageState( xPackage );
+
+ TEntry_Impl pEntry( new Entry_Impl( xPackage, xPackageManager, eState ) );
+ xPackage->addEventListener( uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
+
+ ::osl::ClearableMutexGuard guard(m_entriesMutex);
+ if ( m_vEntries.empty() )
+ {
+ pEntry->m_bHasOptions = m_pManager->supportsOptions( xPackage );
+ pEntry->m_bShared = ( m_pManager->getSharedPkgMgr() == xPackageManager );
+ pEntry->m_bNew = m_bInCheckMode;
+ m_vEntries.push_back( pEntry );
+ }
+ else
+ {
+ if ( !FindEntryPos( pEntry, 0, m_vEntries.size()-1, nPos ) )
+ {
+ pEntry->m_bHasOptions = m_pManager->supportsOptions( xPackage );
+ pEntry->m_bShared = ( m_pManager->getSharedPkgMgr() == xPackageManager );
+ pEntry->m_bNew = m_bInCheckMode;
+ m_vEntries.insert( m_vEntries.begin()+nPos, pEntry );
+ }
+ else if ( !m_bInCheckMode )
+ {
+ OSL_ENSURE( 0, "ExtensionBox_Impl::addEntry(): Will not add duplicate entries" );
+ }
+ }
+ //access to m_nActive must be guarded
+ if ( !m_bInCheckMode && m_bHasActive && ( m_nActive >= nPos ) )
+ m_nActive += 1;
+
+ guard.clear();
+
+ if ( IsReallyVisible() )
+ Invalidate();
+
+ m_bNeedsRecalc = true;
+
+ return nPos;
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::updateEntry( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_xPackage == xPackage )
+ {
+ PackageState eState = m_pManager->getPackageState( xPackage );
+ (*iIndex)->m_bHasOptions = m_pManager->supportsOptions( xPackage );
+ (*iIndex)->m_eState = eState;
+ (*iIndex)->m_sTitle = xPackage->getDisplayName();
+ (*iIndex)->m_sVersion = xPackage->getVersion();
+ (*iIndex)->m_sDescription = xPackage->getDescription();
+
+ if ( eState == AMBIGUOUS )
+ (*iIndex)->m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS );
+ else
+ (*iIndex)->m_sErrorText = String();
+
+ if ( IsReallyVisible() )
+ Invalidate();
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::removeEntry( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( ! m_bInDelete )
+ {
+ ::osl::ClearableMutexGuard aGuard( m_entriesMutex );
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_xPackage == xPackage )
+ {
+ long nPos = iIndex - m_vEntries.begin();
+
+ // Entries mustn't removed here, because they contain a hyperlink control
+ // which can only be deleted when the thread has the solar mutex. Therefor
+ // the entry will be moved into the m_vRemovedEntries list which will be
+ // cleared on the next paint event
+ m_vRemovedEntries.push_back( *iIndex );
+ m_vEntries.erase( iIndex );
+
+ m_bNeedsRecalc = true;
+
+ if ( IsReallyVisible() )
+ Invalidate();
+
+ if ( m_bHasActive )
+ {
+ if ( nPos < m_nActive )
+ m_nActive -= 1;
+ else if ( ( nPos == m_nActive ) &&
+ ( nPos == (long) m_vEntries.size() ) )
+ m_nActive -= 1;
+
+ m_bHasActive = false;
+ //clear before calling out of this method
+ aGuard.clear();
+ selectEntry( m_nActive );
+ }
+ break;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::RemoveUnlocked()
+{
+ bool bAllRemoved = false;
+
+ while ( ! bAllRemoved )
+ {
+ bAllRemoved = true;
+
+ ::osl::ClearableMutexGuard aGuard( m_entriesMutex );
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( !(*iIndex)->m_bLocked )
+ {
+ bAllRemoved = false;
+ uno::Reference< deployment::XPackage> xPackage = (*iIndex)->m_xPackage;
+ aGuard.clear();
+ removeEntry( xPackage );
+ break;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::prepareChecking( const uno::Reference< deployment::XPackageManager > &xPackageMgr )
+{
+ m_bInCheckMode = true;
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_xPackageManager == xPackageMgr )
+ (*iIndex)->m_bChecked = false;
+ else
+ (*iIndex)->m_bChecked = true;
+ (*iIndex)->m_bNew = false;
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::checkEntries()
+{
+ long nNewPos = -1;
+ long nPos = 0;
+ bool bNeedsUpdate = false;
+
+ ::osl::ClearableMutexGuard guard(m_entriesMutex);
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ ITER iIndex = m_vEntries.begin();
+ while ( iIndex < m_vEntries.end() )
+ {
+ if ( (*iIndex)->m_bChecked == false )
+ {
+ bNeedsUpdate = true;
+ nPos = iIndex-m_vEntries.begin();
+ if ( (*iIndex)->m_bNew )
+ {
+ if ( nNewPos == - 1)
+ nNewPos = nPos;
+ if ( nPos <= m_nActive )
+ m_nActive += 1;
+ }
+ }
+ iIndex++;
+ }
+ guard.clear();
+
+ m_bInCheckMode = false;
+
+ if ( nNewPos != - 1)
+ selectEntry( nNewPos );
+
+ if ( bNeedsUpdate )
+ {
+ m_bNeedsRecalc = true;
+ if ( IsReallyVisible() )
+ Invalidate();
+ }
+}
+//------------------------------------------------------------------------------
+bool ExtensionBox_Impl::isHCMode()
+{
+ return (bool)GetSettings().GetStyleSettings().GetHighContrastMode();
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::SetScrollHdl( const Link& rLink )
+{
+ if ( m_pScrollBar )
+ m_pScrollBar->SetScrollHdl( rLink );
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::DoScroll( long nDelta )
+{
+ m_nTopIndex += nDelta;
+ Point aNewSBPt( m_pScrollBar->GetPosPixel() );
+
+ Rectangle aScrRect( Point(), GetOutputSizePixel() );
+ aScrRect.Right() -= m_pScrollBar->GetSizePixel().Width();
+ Scroll( 0, -nDelta, aScrRect );
+
+ m_pScrollBar->SetPosPixel( aNewSBPt );
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtensionBox_Impl, ScrollHdl, ScrollBar*, pScrBar )
+{
+ DoScroll( pScrBar->GetDelta() );
+
+ return 1;
+}
+
+} //namespace dp_gui