Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "svtools/controldims.hrc"
30 : :
31 : : #include "RemoteDialogClientBox.hxx"
32 : : #include "RemoteDialog.hrc"
33 : :
34 : : #include "comphelper/processfactory.hxx"
35 : : #include "com/sun/star/i18n/CollatorOptions.hpp"
36 : : #include "com/sun/star/deployment/DependencyException.hpp"
37 : : #include "com/sun/star/deployment/DeploymentException.hpp"
38 : :
39 : : #define USER_PACKAGE_MANAGER "user"
40 : : #define SHARED_PACKAGE_MANAGER "shared"
41 : : #define BUNDLED_PACKAGE_MANAGER "bundled"
42 : :
43 : : using namespace ::com::sun::star;
44 : :
45 : : namespace sd {
46 : :
47 : : //------------------------------------------------------------------------------
48 : : // struct ClientBoxEntry
49 : : //------------------------------------------------------------------------------
50 : 0 : ClientBoxEntry::ClientBoxEntry( ClientInfo* pClientInfo ) :
51 : : m_bActive( false ),
52 : 0 : m_pClientInfo( pClientInfo )
53 : : {
54 : 0 : }
55 : :
56 : : //------------------------------------------------------------------------------
57 : 0 : ClientBoxEntry::~ClientBoxEntry()
58 : 0 : {}
59 : :
60 : :
61 : : //------------------------------------------------------------------------------
62 : : // ClientRemovedListener
63 : : //------------------------------------------------------------------------------
64 : 0 : void ClientRemovedListener::disposing( lang::EventObject const & rEvt )
65 : : throw ( uno::RuntimeException )
66 : : {
67 : : (void) rEvt;
68 : 0 : }
69 : :
70 : : //------------------------------------------------------------------------------
71 : 0 : ClientRemovedListener::~ClientRemovedListener()
72 : : {
73 : 0 : }
74 : :
75 : : //------------------------------------------------------------------------------
76 : : // ClientBox
77 : : //------------------------------------------------------------------------------
78 : 0 : ClientBox::ClientBox( Dialog* pParent, RemoteServer *pServer,
79 : : const SdResId& aId ) :
80 : : Control( pParent, aId ),
81 : : m_bHasScrollBar( false ),
82 : : m_bHasActive( false ),
83 : : m_bNeedsRecalc( true ),
84 : : m_bHasNew( false ),
85 : : m_bInCheckMode( false ),
86 : : m_bAdjustActive( false ),
87 : : m_bInDelete( false ),
88 : : m_nActive( 0 ),
89 : : m_nTopIndex( 0 ),
90 : : m_nActiveHeight( 0 ),
91 : : m_nExtraHeight( 2 ),
92 : : m_aPinBox( this, SdResId( INPUT_PIN ) ),
93 : : m_aPinDescription( this, SdResId( TEXT_PIN ) ),
94 : 0 : m_pScrollBar( new ScrollBar( this, WB_VERT ) ),
95 : 0 : m_pServer( pServer )
96 : : {
97 : 0 : m_pScrollBar->SetScrollHdl( LINK( this, ClientBox, ScrollHdl ) );
98 : 0 : m_pScrollBar->EnableDrag();
99 : :
100 : 0 : m_aPinBox.SetUseThousandSep(false);
101 : : // m_aPinDescription.SetText( String( SdResId( STR_ENTER_PIN ) ) );
102 : :
103 : 0 : SetPaintTransparent( true );
104 : 0 : SetPosPixel( Point( RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP ) );
105 : 0 : long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
106 : 0 : long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
107 : 0 : if ( nIconHeight < nTitleHeight )
108 : 0 : m_nStdHeight = nTitleHeight;
109 : : else
110 : 0 : m_nStdHeight = nIconHeight;
111 : 0 : m_nStdHeight += GetTextHeight() + TOP_OFFSET;
112 : :
113 : : // nIconHeight = ICON_HEIGHT + 2*TOP_OFFSET + 1;
114 : : // if ( m_nStdHeight < nIconHeight )
115 : : // m_nStdHeight = nIconHeight;
116 : :
117 : 0 : m_nActiveHeight = m_nStdHeight;
118 : :
119 : 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
120 : 0 : if( IsControlBackground() )
121 : 0 : SetBackground( GetControlBackground() );
122 : : else
123 : 0 : SetBackground( rStyleSettings.GetFieldColor() );
124 : :
125 : 0 : m_xRemoveListener = new ClientRemovedListener( this );
126 : :
127 : 0 : Show();
128 : 0 : }
129 : :
130 : : //------------------------------------------------------------------------------
131 : 0 : ClientBox::~ClientBox()
132 : : {
133 : 0 : if ( ! m_bInDelete )
134 : 0 : DeleteRemoved();
135 : :
136 : 0 : m_bInDelete = true;
137 : :
138 : : typedef std::vector< TClientBoxEntry >::iterator ITER;
139 : :
140 : 0 : for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
141 : : {
142 : : // (*iIndex)->m_xPackage->removeEventListener( uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
143 : : }
144 : :
145 : 0 : m_vEntries.clear();
146 : :
147 : 0 : m_xRemoveListener.clear();
148 : 0 : }
149 : :
150 : :
151 : : //------------------------------------------------------------------------------
152 : 0 : void ClientBox::checkIndex( sal_Int32 nIndex ) const
153 : : {
154 : 0 : if ( nIndex < 0 )
155 : 0 : throw lang::IllegalArgumentException( "The list index starts with 0",0, 0 );
156 : 0 : if ( static_cast< sal_uInt32 >( nIndex ) >= m_vEntries.size())
157 : : throw lang::IllegalArgumentException( "There is no element at the provided position."
158 : 0 : "The position exceeds the number of available list entries",0, 0 );
159 : 0 : }
160 : :
161 : : //------------------------------------------------------------------------------
162 : : // Title + description
163 : 0 : void ClientBox::CalcActiveHeight( const long nPos )
164 : : {
165 : : (void) nPos;
166 : 0 : const ::osl::MutexGuard aGuard( m_entriesMutex );
167 : :
168 : : // get title height
169 : : long aTextHeight;
170 : 0 : long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
171 : 0 : long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
172 : 0 : if ( nIconHeight < nTitleHeight )
173 : 0 : aTextHeight = nTitleHeight;
174 : : else
175 : 0 : aTextHeight = nIconHeight;
176 : :
177 : : // Text entry height
178 : 0 : Size aSize = GetOutputSizePixel();
179 : 0 : if ( m_bHasScrollBar )
180 : 0 : aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
181 : :
182 : 0 : aSize.Width() -= ICON_OFFSET;
183 : :
184 : : aSize = LogicToPixel( Size( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ),
185 : 0 : MapMode( MAP_APPFONT ) );
186 : 0 : aTextHeight += aSize.Height();
187 : :
188 : 0 : if ( aTextHeight < m_nStdHeight )
189 : 0 : aTextHeight = m_nStdHeight;
190 : :
191 : 0 : m_nActiveHeight = aTextHeight + 2;
192 : 0 : }
193 : :
194 : : //------------------------------------------------------------------------------
195 : 0 : const Size ClientBox::GetMinOutputSizePixel() const
196 : : {
197 : 0 : return Size( 200, 80 );
198 : : }
199 : :
200 : : //------------------------------------------------------------------------------
201 : 0 : Rectangle ClientBox::GetEntryRect( const long nPos ) const
202 : : {
203 : 0 : const ::osl::MutexGuard aGuard( m_entriesMutex );
204 : :
205 : 0 : Size aSize( GetOutputSizePixel() );
206 : :
207 : 0 : if ( m_bHasScrollBar )
208 : 0 : aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
209 : :
210 : 0 : if ( m_vEntries[ nPos ]->m_bActive )
211 : 0 : aSize.Height() = m_nActiveHeight;
212 : : else
213 : 0 : aSize.Height() = m_nStdHeight;
214 : :
215 : 0 : Point aPos( 0, -m_nTopIndex + nPos * m_nStdHeight );
216 : 0 : if ( m_bHasActive && ( nPos < m_nActive ) )
217 : 0 : aPos.Y() += m_nActiveHeight - m_nStdHeight;
218 : :
219 : 0 : return Rectangle( aPos, aSize );
220 : : }
221 : :
222 : : //------------------------------------------------------------------------------
223 : 0 : void ClientBox::DeleteRemoved()
224 : : {
225 : 0 : const ::osl::MutexGuard aGuard( m_entriesMutex );
226 : :
227 : 0 : m_bInDelete = true;
228 : :
229 : 0 : if ( ! m_vRemovedEntries.empty() )
230 : : {
231 : : typedef std::vector< TClientBoxEntry >::iterator ITER;
232 : :
233 : 0 : m_vRemovedEntries.clear();
234 : : }
235 : :
236 : 0 : m_bInDelete = false;
237 : 0 : }
238 : :
239 : 0 : long ClientBox::GetActiveEntryIndex()
240 : : {
241 : 0 : if ( m_bHasActive )
242 : 0 : return m_nActive;
243 : : else
244 : 0 : return -1;
245 : : }
246 : :
247 : : //------------------------------------------------------------------------------
248 : : //This function may be called with nPos < 0
249 : 0 : void ClientBox::selectEntry( const long nPos )
250 : : {
251 : : //ToDo whe should not use the guard at such a big scope here.
252 : : //Currently it is used to gard m_vEntries and m_nActive. m_nActive will be
253 : : //modified in this function.
254 : : //It would be probably best to always use a copy of m_vEntries
255 : : //and some other state variables from ClientBox for
256 : : //the whole painting operation. See issue i86993
257 : 0 : ::osl::ClearableMutexGuard guard(m_entriesMutex);
258 : :
259 : 0 : if ( m_bInCheckMode )
260 : : return;
261 : :
262 : 0 : if ( m_bHasActive )
263 : : {
264 : 0 : if ( nPos == m_nActive )
265 : : return;
266 : :
267 : 0 : m_bHasActive = false;
268 : 0 : m_vEntries[ m_nActive ]->m_bActive = false;
269 : : }
270 : :
271 : 0 : if ( ( nPos >= 0 ) && ( nPos < (long) m_vEntries.size() ) )
272 : : {
273 : 0 : m_bHasActive = true;
274 : 0 : m_nActive = nPos;
275 : 0 : m_vEntries[ nPos ]->m_bActive = true;
276 : :
277 : 0 : if ( IsReallyVisible() )
278 : : {
279 : 0 : m_bAdjustActive = true;
280 : : }
281 : : }
282 : :
283 : 0 : if ( IsReallyVisible() )
284 : : {
285 : 0 : m_bNeedsRecalc = true;
286 : 0 : Invalidate();
287 : : }
288 : :
289 : 0 : guard.clear();
290 : : }
291 : :
292 : : // -----------------------------------------------------------------------
293 : 0 : void ClientBox::DrawRow( const Rectangle& rRect, const TClientBoxEntry pEntry )
294 : : {
295 : 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
296 : :
297 : 0 : if ( pEntry->m_bActive )
298 : 0 : SetTextColor( rStyleSettings.GetHighlightTextColor() );
299 : : else
300 : 0 : SetTextColor( rStyleSettings.GetFieldTextColor() );
301 : :
302 : 0 : if ( pEntry->m_bActive )
303 : : {
304 : 0 : SetLineColor();
305 : 0 : SetFillColor( rStyleSettings.GetHighlightColor() );
306 : 0 : DrawRect( rRect );
307 : : }
308 : : else
309 : : {
310 : 0 : if( IsControlBackground() )
311 : 0 : SetBackground( GetControlBackground() );
312 : : else
313 : 0 : SetBackground( rStyleSettings.GetFieldColor() );
314 : :
315 : 0 : SetTextFillColor();
316 : 0 : Erase( rRect );
317 : : }
318 : :
319 : : // FIXME: draw bluetooth or wifi icon
320 : 0 : Point aPos( rRect.TopLeft() );
321 : : // aPos += Point( TOP_OFFSET, TOP_OFFSET );
322 : : // Image aImage;
323 : : // if ( ! pEntry->m_aIcon )
324 : : // aImage = m_aDefaultImage;
325 : : // else
326 : : // aImage = pEntry->m_aIcon;
327 : : // Size aImageSize = aImage.GetSizePixel();
328 : : // if ( ( aImageSize.Width() <= ICON_WIDTH ) && ( aImageSize.Height() <= ICON_HEIGHT ) )
329 : : // DrawImage( Point( aPos.X()+((ICON_WIDTH-aImageSize.Width())/2), aPos.Y()+((ICON_HEIGHT-aImageSize.Height())/2) ), aImage );
330 : : // else
331 : : // DrawImage( aPos, Size( ICON_WIDTH, ICON_HEIGHT ), aImage );
332 : :
333 : : // Setup fonts
334 : 0 : Font aStdFont( GetFont() );
335 : 0 : Font aBoldFont( aStdFont );
336 : 0 : aBoldFont.SetWeight( WEIGHT_BOLD );
337 : 0 : SetFont( aBoldFont );
338 : 0 : long aTextHeight = GetTextHeight();
339 : :
340 : : // Get max title width
341 : 0 : long nMaxTitleWidth = rRect.GetWidth() - ICON_OFFSET;
342 : 0 : nMaxTitleWidth -= ( 2 * SMALL_ICON_SIZE ) + ( 4 * SPACE_BETWEEN );
343 : :
344 : 0 : long aTitleWidth = GetTextWidth( String( pEntry->m_pClientInfo->mName ) ) + (aTextHeight / 3);
345 : :
346 : 0 : aPos = rRect.TopLeft() + Point( ICON_OFFSET, TOP_OFFSET );
347 : :
348 : 0 : if ( aTitleWidth > nMaxTitleWidth )
349 : : {
350 : 0 : aTitleWidth = nMaxTitleWidth - (aTextHeight / 3);
351 : 0 : String aShortTitle = GetEllipsisString( pEntry->m_pClientInfo->mName,
352 : 0 : aTitleWidth );
353 : 0 : DrawText( aPos, aShortTitle );
354 : 0 : aTitleWidth += (aTextHeight / 3);
355 : : }
356 : : else
357 : 0 : DrawText( aPos, pEntry->m_pClientInfo->mName );
358 : :
359 : 0 : SetFont( aStdFont );
360 : :
361 : 0 : aPos.Y() += aTextHeight;
362 : 0 : if ( pEntry->m_bActive )
363 : : {
364 : : Size aSize = LogicToPixel( Size( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ),
365 : 0 : MapMode( MAP_APPFONT ) );
366 : 0 : m_aPinBox.SetSizePixel( aSize );
367 : 0 : const Rectangle aRect( GetEntryRect( m_nActive ) );
368 : 0 : Size aBtnSize( m_aPinBox.GetSizePixel() );
369 : : Point aBtnPos( aRect.Left(),
370 : 0 : aRect.Bottom() - TOP_OFFSET - aBtnSize.Height() );
371 : : // m_aPinDescription.SetPosPixel( aBtnPos );
372 : 0 : DrawText( Rectangle( aBtnPos.X(), aBtnPos.Y(), rRect.Right(), rRect.Bottom() - TOP_OFFSET),
373 : 0 : String( SdResId( STR_ENTER_PIN ) ), 0 );
374 : :
375 : 0 : aBtnPos = Point( aRect.Left() + GetTextWidth( String( SdResId( STR_ENTER_PIN ) ) ),
376 : 0 : aRect.Bottom() - TOP_OFFSET - aBtnSize.Height() );
377 : :
378 : 0 : m_aPinBox.SetPosPixel( aBtnPos );
379 : :
380 : :
381 : :
382 : :
383 : :
384 : : // long nExtraHeight = 0;
385 : : //
386 : : // if ( pEntry->m_bHasButtons )
387 : : // nExtraHeight = m_nExtraHeight;
388 : : //
389 : : // DrawText( Rectangle( aPos.X(), aPos.Y(), rRect.Right(), rRect.Bottom() - nExtraHeight ),
390 : : // sDescription, TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
391 : : }
392 : : else
393 : : {
394 : : }
395 : :
396 : 0 : SetLineColor( Color( COL_LIGHTGRAY ) );
397 : 0 : DrawLine( rRect.BottomLeft(), rRect.BottomRight() );
398 : 0 : }
399 : :
400 : : // -----------------------------------------------------------------------
401 : 0 : void ClientBox::RecalcAll()
402 : : {
403 : 0 : if ( m_bHasActive )
404 : 0 : CalcActiveHeight( m_nActive );
405 : :
406 : 0 : SetupScrollBar();
407 : :
408 : 0 : if ( m_bHasActive )
409 : : {
410 : 0 : Rectangle aEntryRect = GetEntryRect( m_nActive );
411 : :
412 : 0 : if ( m_bAdjustActive )
413 : : {
414 : 0 : m_bAdjustActive = false;
415 : :
416 : : // If the top of the selected entry isn't visible, make it visible
417 : 0 : if ( aEntryRect.Top() < 0 )
418 : : {
419 : 0 : m_nTopIndex += aEntryRect.Top();
420 : 0 : aEntryRect.Move( 0, -aEntryRect.Top() );
421 : : }
422 : :
423 : : // If the bottom of the selected entry isn't visible, make it visible even if now the top
424 : : // isn't visible any longer ( the buttons are more important )
425 : 0 : Size aOutputSize = GetOutputSizePixel();
426 : 0 : if ( aEntryRect.Bottom() > aOutputSize.Height() )
427 : : {
428 : 0 : m_nTopIndex += ( aEntryRect.Bottom() - aOutputSize.Height() );
429 : 0 : aEntryRect.Move( 0, -( aEntryRect.Bottom() - aOutputSize.Height() ) );
430 : : }
431 : :
432 : : // If there is unused space below the last entry but all entries don't fit into the box,
433 : : // move the content down to use the whole space
434 : 0 : const long nTotalHeight = GetTotalHeight();
435 : 0 : if ( m_bHasScrollBar && ( aOutputSize.Height() + m_nTopIndex > nTotalHeight ) )
436 : : {
437 : 0 : long nOffset = m_nTopIndex;
438 : 0 : m_nTopIndex = nTotalHeight - aOutputSize.Height();
439 : 0 : nOffset -= m_nTopIndex;
440 : 0 : aEntryRect.Move( 0, nOffset );
441 : : }
442 : :
443 : 0 : if ( m_bHasScrollBar )
444 : 0 : m_pScrollBar->SetThumbPos( m_nTopIndex );
445 : : }
446 : : }
447 : :
448 : 0 : m_bNeedsRecalc = false;
449 : 0 : }
450 : :
451 : : // -----------------------------------------------------------------------
452 : 0 : bool ClientBox::HandleTabKey( bool )
453 : : {
454 : 0 : return false;
455 : : }
456 : :
457 : : // -----------------------------------------------------------------------
458 : 0 : bool ClientBox::HandleCursorKey( sal_uInt16 nKeyCode )
459 : : {
460 : 0 : if ( m_vEntries.empty() )
461 : 0 : return true;
462 : :
463 : 0 : long nSelect = 0;
464 : :
465 : 0 : if ( m_bHasActive )
466 : : {
467 : 0 : long nPageSize = GetOutputSizePixel().Height() / m_nStdHeight;
468 : 0 : if ( nPageSize < 2 )
469 : 0 : nPageSize = 2;
470 : :
471 : 0 : if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_RIGHT ) )
472 : 0 : nSelect = m_nActive + 1;
473 : 0 : else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_LEFT ) )
474 : 0 : nSelect = m_nActive - 1;
475 : 0 : else if ( nKeyCode == KEY_HOME )
476 : 0 : nSelect = 0;
477 : 0 : else if ( nKeyCode == KEY_END )
478 : 0 : nSelect = m_vEntries.size() - 1;
479 : 0 : else if ( nKeyCode == KEY_PAGEUP )
480 : 0 : nSelect = m_nActive - nPageSize + 1;
481 : 0 : else if ( nKeyCode == KEY_PAGEDOWN )
482 : 0 : nSelect = m_nActive + nPageSize - 1;
483 : : }
484 : : else // when there is no selected entry, we will select the first or the last.
485 : : {
486 : 0 : if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_PAGEDOWN ) || ( nKeyCode == KEY_HOME ) )
487 : 0 : nSelect = 0;
488 : 0 : else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_PAGEUP ) || ( nKeyCode == KEY_END ) )
489 : 0 : nSelect = m_vEntries.size() - 1;
490 : : }
491 : :
492 : 0 : if ( nSelect < 0 )
493 : 0 : nSelect = 0;
494 : 0 : if ( nSelect >= (long) m_vEntries.size() )
495 : 0 : nSelect = m_vEntries.size() - 1;
496 : :
497 : 0 : selectEntry( nSelect );
498 : :
499 : 0 : return true;
500 : : }
501 : :
502 : : // -----------------------------------------------------------------------
503 : 0 : void ClientBox::Paint( const Rectangle &/*rPaintRect*/ )
504 : : {
505 : 0 : if ( !m_bInDelete )
506 : 0 : DeleteRemoved();
507 : :
508 : 0 : if ( m_bNeedsRecalc )
509 : 0 : RecalcAll();
510 : :
511 : 0 : Point aStart( 0, -m_nTopIndex );
512 : 0 : Size aSize( GetOutputSizePixel() );
513 : :
514 : 0 : if ( m_bHasScrollBar )
515 : 0 : aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
516 : :
517 : 0 : const ::osl::MutexGuard aGuard( m_entriesMutex );
518 : :
519 : : typedef std::vector< TClientBoxEntry >::iterator ITER;
520 : 0 : for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
521 : : {
522 : 0 : aSize.Height() = (*iIndex)->m_bActive ? m_nActiveHeight : m_nStdHeight;
523 : 0 : Rectangle aEntryRect( aStart, aSize );
524 : 0 : DrawRow( aEntryRect, *iIndex );
525 : 0 : aStart.Y() += aSize.Height();
526 : 0 : }
527 : 0 : }
528 : :
529 : : // -----------------------------------------------------------------------
530 : 0 : long ClientBox::GetTotalHeight() const
531 : : {
532 : 0 : long nHeight = m_vEntries.size() * m_nStdHeight;
533 : :
534 : 0 : if ( m_bHasActive )
535 : : {
536 : 0 : nHeight += m_nActiveHeight - m_nStdHeight;
537 : : }
538 : :
539 : 0 : return nHeight;
540 : : }
541 : :
542 : : // -----------------------------------------------------------------------
543 : 0 : void ClientBox::SetupScrollBar()
544 : : {
545 : 0 : const Size aSize = GetOutputSizePixel();
546 : 0 : const long nScrBarSize = GetSettings().GetStyleSettings().GetScrollBarSize();
547 : 0 : const long nTotalHeight = GetTotalHeight();
548 : 0 : const bool bNeedsScrollBar = ( nTotalHeight > aSize.Height() );
549 : :
550 : 0 : if ( bNeedsScrollBar )
551 : : {
552 : 0 : if ( m_nTopIndex + aSize.Height() > nTotalHeight )
553 : 0 : m_nTopIndex = nTotalHeight - aSize.Height();
554 : :
555 : 0 : m_pScrollBar->SetPosSizePixel( Point( aSize.Width() - nScrBarSize, 0 ),
556 : 0 : Size( nScrBarSize, aSize.Height() ) );
557 : 0 : m_pScrollBar->SetRangeMax( nTotalHeight );
558 : 0 : m_pScrollBar->SetVisibleSize( aSize.Height() );
559 : 0 : m_pScrollBar->SetPageSize( ( aSize.Height() * 4 ) / 5 );
560 : 0 : m_pScrollBar->SetLineSize( m_nStdHeight );
561 : 0 : m_pScrollBar->SetThumbPos( m_nTopIndex );
562 : :
563 : 0 : if ( !m_bHasScrollBar )
564 : 0 : m_pScrollBar->Show();
565 : : }
566 : 0 : else if ( m_bHasScrollBar )
567 : : {
568 : 0 : m_pScrollBar->Hide();
569 : 0 : m_nTopIndex = 0;
570 : : }
571 : :
572 : 0 : m_bHasScrollBar = bNeedsScrollBar;
573 : 0 : }
574 : :
575 : : // -----------------------------------------------------------------------
576 : 0 : void ClientBox::Resize()
577 : : {
578 : 0 : RecalcAll();
579 : 0 : }
580 : :
581 : : //------------------------------------------------------------------------------
582 : 0 : long ClientBox::PointToPos( const Point& rPos )
583 : : {
584 : 0 : long nPos = ( rPos.Y() + m_nTopIndex ) / m_nStdHeight;
585 : :
586 : 0 : if ( m_bHasActive && ( nPos > m_nActive ) )
587 : : {
588 : 0 : if ( rPos.Y() + m_nTopIndex <= m_nActive*m_nStdHeight + m_nActiveHeight )
589 : 0 : nPos = m_nActive;
590 : : else
591 : 0 : nPos = ( rPos.Y() + m_nTopIndex - (m_nActiveHeight - m_nStdHeight) ) / m_nStdHeight;
592 : : }
593 : :
594 : 0 : return nPos;
595 : : }
596 : :
597 : 0 : OUString ClientBox::getPin()
598 : : {
599 : 0 : return OUString::valueOf( m_aPinBox.GetValue() );
600 : : }
601 : :
602 : : //------------------------------------------------------------------------------
603 : 0 : void ClientBox::MouseButtonDown( const MouseEvent& rMEvt )
604 : : {
605 : 0 : long nPos = PointToPos( rMEvt.GetPosPixel() );
606 : :
607 : 0 : if ( rMEvt.IsLeft() )
608 : : {
609 : 0 : if ( rMEvt.IsMod1() && m_bHasActive )
610 : 0 : selectEntry( m_vEntries.size() ); // Selecting an not existing entry will deselect the current one
611 : : else
612 : 0 : selectEntry( nPos );
613 : : }
614 : 0 : }
615 : :
616 : : //------------------------------------------------------------------------------
617 : 0 : long ClientBox::Notify( NotifyEvent& rNEvt )
618 : : {
619 : 0 : if ( !m_bInDelete )
620 : 0 : DeleteRemoved();
621 : :
622 : 0 : bool bHandled = false;
623 : :
624 : 0 : if ( rNEvt.GetType() == EVENT_KEYINPUT )
625 : : {
626 : 0 : const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
627 : 0 : KeyCode aKeyCode = pKEvt->GetKeyCode();
628 : 0 : sal_uInt16 nKeyCode = aKeyCode.GetCode();
629 : :
630 : 0 : if ( nKeyCode == KEY_TAB )
631 : 0 : bHandled = HandleTabKey( aKeyCode.IsShift() );
632 : 0 : else if ( aKeyCode.GetGroup() == KEYGROUP_CURSOR )
633 : 0 : bHandled = HandleCursorKey( nKeyCode );
634 : : }
635 : :
636 : 0 : if ( rNEvt.GetType() == EVENT_COMMAND )
637 : : {
638 : 0 : if ( m_bHasScrollBar &&
639 : 0 : ( rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL ) )
640 : : {
641 : 0 : const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
642 : 0 : if ( pData->GetMode() == COMMAND_WHEEL_SCROLL )
643 : : {
644 : 0 : long nThumbPos = m_pScrollBar->GetThumbPos();
645 : 0 : if ( pData->GetDelta() < 0 )
646 : 0 : m_pScrollBar->DoScroll( nThumbPos + m_nStdHeight );
647 : : else
648 : 0 : m_pScrollBar->DoScroll( nThumbPos - m_nStdHeight );
649 : 0 : bHandled = true;
650 : : }
651 : : }
652 : : }
653 : :
654 : 0 : if ( !bHandled )
655 : 0 : return Control::Notify( rNEvt );
656 : : else
657 : 0 : return true;
658 : : }
659 : :
660 : :
661 : : //------------------------------------------------------------------------------
662 : 0 : long ClientBox::addEntry( ClientInfo* pClientInfo )
663 : : {
664 : 0 : long nPos = 0;
665 : : // PackageState eState = m_pManager->getPackageState( xPackage );
666 : : // bool bLocked = m_pManager->isReadOnly( xPackage );
667 : :
668 : 0 : TClientBoxEntry pEntry( new ClientBoxEntry( pClientInfo ) );
669 : :
670 : 0 : bool bNewEntryInserted = false;
671 : :
672 : 0 : ::osl::ClearableMutexGuard guard(m_entriesMutex);
673 : 0 : if ( m_vEntries.empty() )
674 : : {
675 : 0 : m_vEntries.push_back( pEntry );
676 : 0 : bNewEntryInserted = true;
677 : : }
678 : : else
679 : : {
680 : : // if ( !FindEntryPos( pEntry, 0, m_vEntries.size()-1, nPos ) )
681 : : // {
682 : 0 : m_vEntries.insert( m_vEntries.begin()+nPos, pEntry );
683 : 0 : bNewEntryInserted = true;
684 : : // }
685 : : // else if ( !m_bInCheckMode )
686 : : // {
687 : : // OSL_FAIL( "ClientBox::addEntry(): Will not add duplicate entries" );
688 : : // }
689 : : }
690 : :
691 : : //Related: rhbz#702833 Only add a Listener if we're adding a new entry, to
692 : : //keep in sync with removeEventListener logic
693 : : if (bNewEntryInserted)
694 : : {
695 : :
696 : : // pEntry->m_xPackage->addEventListener(uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
697 : : }
698 : :
699 : :
700 : : // pEntry->m_bHasOptions = m_pManager->supportsOptions( xPackage );
701 : : // pEntry->m_bUser = xPackage->getRepositoryName().equals( USER_PACKAGE_MANAGER );
702 : : // pEntry->m_bShared = xPackage->getRepositoryName().equals( SHARED_PACKAGE_MANAGER );
703 : : // pEntry->m_bNew = m_bInCheckMode;
704 : : // pEntry->m_bMissingLic = bLicenseMissing;
705 : :
706 : : // if ( bLicenseMissing )
707 : : // pEntry->m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_MISSING_LICENSE );
708 : :
709 : : //access to m_nActive must be guarded
710 : 0 : if ( !m_bInCheckMode && m_bHasActive && ( m_nActive >= nPos ) )
711 : 0 : m_nActive += 1;
712 : :
713 : 0 : guard.clear();
714 : :
715 : 0 : if ( IsReallyVisible() )
716 : 0 : Invalidate();
717 : :
718 : 0 : m_bNeedsRecalc = true;
719 : :
720 : 0 : return nPos;
721 : : }
722 : :
723 : : //------------------------------------------------------------------------------
724 : 0 : void ClientBox::updateEntry( const ClientInfo* pClientInfo )
725 : : {
726 : : (void) pClientInfo;
727 : : // typedef std::vector< TClientBoxEntry >::iterator ITER;
728 : : // for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
729 : : // {
730 : : // if ( (*iIndex)->m_xPackage == xPackage )
731 : : // {
732 : : // PackageState eState = m_pManager->getPackageState( xPackage );
733 : : // (*iIndex)->m_bHasOptions = m_pManager->supportsOptions( xPackage );
734 : : // (*iIndex)->m_eState = eState;
735 : : // (*iIndex)->m_sTitle = xPackage->getDisplayName();
736 : : // (*iIndex)->m_sVersion = xPackage->getVersion();
737 : : // (*iIndex)->m_sDescription = xPackage->getDescription();
738 : : //
739 : : // if ( eState == REGISTERED )
740 : : // (*iIndex)->m_bMissingLic = false;
741 : : //
742 : : // if ( eState == AMBIGUOUS )
743 : : // (*iIndex)->m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS );
744 : : // else if ( ! (*iIndex)->m_bMissingLic )
745 : : // (*iIndex)->m_sErrorText = String();
746 : : //
747 : : // if ( IsReallyVisible() )
748 : : // Invalidate();
749 : : // break;
750 : : // }
751 : : // }
752 : 0 : }
753 : :
754 : : //------------------------------------------------------------------------------
755 : 0 : void ClientBox::removeEntry( const ClientInfo* pClientInfo )
756 : : {
757 : : (void) pClientInfo;
758 : : // if ( ! m_bInDelete )
759 : : // {
760 : : // ::osl::ClearableMutexGuard aGuard( m_entriesMutex );
761 : : //
762 : : // typedef std::vector< TClientBoxEntry >::iterator ITER;
763 : : //
764 : : // for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
765 : : // {
766 : : // if ( (*iIndex)->m_xPackage == xPackage )
767 : : // {
768 : : // long nPos = iIndex - m_vEntries.begin();
769 : : //
770 : : // // Entries mustn't removed here, because they contain a hyperlink control
771 : : // // which can only be deleted when the thread has the solar mutex. Therefor
772 : : // // the entry will be moved into the m_vRemovedEntries list which will be
773 : : // // cleared on the next paint event
774 : : // m_vRemovedEntries.push_back( *iIndex );
775 : : // m_vEntries.erase( iIndex );
776 : : //
777 : : // m_bNeedsRecalc = true;
778 : : //
779 : : // if ( IsReallyVisible() )
780 : : // Invalidate();
781 : : //
782 : : // if ( m_bHasActive )
783 : : // {
784 : : // if ( nPos < m_nActive )
785 : : // m_nActive -= 1;
786 : : // else if ( ( nPos == m_nActive ) &&
787 : : // ( nPos == (long) m_vEntries.size() ) )
788 : : // m_nActive -= 1;
789 : : //
790 : : // m_bHasActive = false;
791 : : // //clear before calling out of this method
792 : : // aGuard.clear();
793 : : // selectEntry( m_nActive );
794 : : // }
795 : : // break;
796 : : // }
797 : : // }
798 : : // }
799 : 0 : }
800 : :
801 : : //------------------------------------------------------------------------------
802 : 0 : void ClientBox::RemoveUnlocked()
803 : : {
804 : : // bool bAllRemoved = false;
805 : : //
806 : : // while ( ! bAllRemoved )
807 : : // {
808 : : // bAllRemoved = true;
809 : : //
810 : : // ::osl::ClearableMutexGuard aGuard( m_entriesMutex );
811 : : //
812 : : // typedef std::vector< TClientBoxEntry >::iterator ITER;
813 : : //
814 : : // for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
815 : : // {
816 : : // if ( !(*iIndex)->m_bLocked )
817 : : // {
818 : : // bAllRemoved = false;
819 : : // uno::Reference< deployment::XPackage> xPackage = (*iIndex)->m_xPackage;
820 : : // aGuard.clear();
821 : : // removeEntry( xPackage );
822 : : // break;
823 : : // }
824 : : // }
825 : : // }
826 : 0 : }
827 : :
828 : : //------------------------------------------------------------------------------
829 : 0 : void ClientBox::prepareChecking()
830 : : {
831 : 0 : m_bInCheckMode = true;
832 : : typedef std::vector< TClientBoxEntry >::iterator ITER;
833 : 0 : for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
834 : : {
835 : : // (*iIndex)->m_bChecked = false;
836 : : // (*iIndex)->m_bNew = false;
837 : : }
838 : 0 : }
839 : :
840 : : //------------------------------------------------------------------------------
841 : 0 : void ClientBox::checkEntries()
842 : : {
843 : 0 : long nNewPos = -1;
844 : : // long nPos = 0;
845 : 0 : bool bNeedsUpdate = false;
846 : :
847 : 0 : ::osl::ClearableMutexGuard guard(m_entriesMutex);
848 : : typedef std::vector< TClientBoxEntry >::iterator ITER;
849 : 0 : ITER iIndex = m_vEntries.begin();
850 : 0 : while ( iIndex < m_vEntries.end() )
851 : : {
852 : : // if ( (*iIndex)->m_bChecked == false )
853 : : // {
854 : : // (*iIndex)->m_bChecked = true;
855 : : // bNeedsUpdate = true;
856 : : // nPos = iIndex-m_vEntries.begin();
857 : : // if ( (*iIndex)->m_bNew )
858 : : // { // add entry to list and correct active pos
859 : : // if ( nNewPos == - 1)
860 : : // nNewPos = nPos;
861 : : // if ( nPos <= m_nActive )
862 : : // m_nActive += 1;
863 : : // ++iIndex;
864 : : // }
865 : : // else
866 : : // { // remove entry from list
867 : : // if ( nPos < m_nActive )
868 : : // m_nActive -= 1;
869 : : // else if ( ( nPos == m_nActive ) && ( nPos == (long) m_vEntries.size() - 1 ) )
870 : : // m_nActive -= 1;
871 : : // m_vRemovedEntries.push_back( *iIndex );
872 : : // m_vEntries.erase( iIndex );
873 : : // iIndex = m_vEntries.begin() + nPos;
874 : : // }
875 : : // }
876 : : // else
877 : 0 : ++iIndex;
878 : : }
879 : 0 : guard.clear();
880 : :
881 : 0 : m_bInCheckMode = false;
882 : :
883 : 0 : if ( nNewPos != - 1)
884 : 0 : selectEntry( nNewPos );
885 : :
886 : 0 : if ( bNeedsUpdate )
887 : : {
888 : 0 : m_bNeedsRecalc = true;
889 : 0 : if ( IsReallyVisible() )
890 : 0 : Invalidate();
891 : 0 : }
892 : 0 : }
893 : :
894 : : //------------------------------------------------------------------------------
895 : 0 : void ClientBox::SetScrollHdl( const Link& rLink )
896 : : {
897 : 0 : m_pScrollBar->SetScrollHdl( rLink );
898 : 0 : }
899 : :
900 : : // -----------------------------------------------------------------------
901 : 0 : void ClientBox::DoScroll( long nDelta )
902 : : {
903 : 0 : m_nTopIndex += nDelta;
904 : 0 : Point aNewSBPt( m_pScrollBar->GetPosPixel() );
905 : :
906 : 0 : Rectangle aScrRect( Point(), GetOutputSizePixel() );
907 : 0 : aScrRect.Right() -= m_pScrollBar->GetSizePixel().Width();
908 : 0 : Scroll( 0, -nDelta, aScrRect );
909 : :
910 : 0 : m_pScrollBar->SetPosPixel( aNewSBPt );
911 : 0 : }
912 : :
913 : : // -----------------------------------------------------------------------
914 : 0 : IMPL_LINK( ClientBox, ScrollHdl, ScrollBar*, pScrBar )
915 : : {
916 : 0 : DoScroll( pScrBar->GetDelta() );
917 : :
918 : 0 : return 1;
919 : : }
920 : :
921 : : } //namespace dp_gui
922 : :
923 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|