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