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