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