Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <vector>
21 :
22 : #include "svtools/controldims.hrc"
23 :
24 : #include "RemoteDialogClientBox.hxx"
25 : #include "RemoteServer.hxx"
26 :
27 : #include "comphelper/processfactory.hxx"
28 : #include "com/sun/star/i18n/CollatorOptions.hpp"
29 : #include "com/sun/star/deployment/DependencyException.hpp"
30 : #include "com/sun/star/deployment/DeploymentException.hpp"
31 : #include <vcl/settings.hxx>
32 : #include <vcl/builderfactory.hxx>
33 :
34 : #include "glob.hrc"
35 :
36 : using namespace std;
37 :
38 : using namespace ::com::sun::star;
39 :
40 : namespace sd {
41 :
42 : // struct ClientBoxEntry
43 :
44 0 : ClientBoxEntry::ClientBoxEntry( ::boost::shared_ptr<ClientInfo> pClientInfo ) :
45 : m_bActive( false ),
46 0 : m_pClientInfo( pClientInfo )
47 : {
48 0 : }
49 :
50 0 : ClientBoxEntry::~ClientBoxEntry()
51 0 : {}
52 :
53 0 : void ClientRemovedListener::disposing( lang::EventObject const & rEvt )
54 : throw ( uno::RuntimeException, std::exception )
55 : {
56 : (void) rEvt;
57 0 : }
58 :
59 0 : ClientRemovedListener::~ClientRemovedListener()
60 : {
61 0 : }
62 :
63 : // ClientBox
64 :
65 0 : ClientBox::ClientBox( vcl::Window* pParent, WinBits nStyle ) :
66 : Control( pParent, nStyle ),
67 : m_bHasScrollBar( false ),
68 : m_bHasActive( false ),
69 : m_bNeedsRecalc( true ),
70 : m_bInCheckMode( false ),
71 : m_bAdjustActive( false ),
72 : m_bInDelete( false ),
73 : m_nActive( 0 ),
74 : m_nTopIndex( 0 ),
75 : m_nActiveHeight( 0 ),
76 : m_nExtraHeight( 2 ),
77 : m_aPinBox( VclPtr<NumericBox>::Create( this, 0 ) ),
78 : m_aDeauthoriseButton( VclPtr<PushButton>::Create( this ) ),
79 0 : m_aScrollBar( VclPtr<ScrollBar>::Create( this, WB_VERT ) )
80 : {
81 0 : m_aScrollBar->SetScrollHdl( LINK( this, ClientBox, ScrollHdl ) );
82 0 : m_aScrollBar->EnableDrag();
83 :
84 0 : m_aPinBox->SetUseThousandSep(false);
85 0 : m_aDeauthoriseButton->SetText( SD_RESSTR(STR_DEAUTHORISE_CLIENT) );
86 0 : m_aDeauthoriseButton->SetClickHdl( LINK( this, ClientBox, DeauthoriseHdl ) );
87 :
88 0 : SetPosPixel( Point( RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP ) );
89 0 : long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
90 0 : long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
91 0 : if ( nIconHeight < nTitleHeight )
92 0 : m_nStdHeight = nTitleHeight;
93 : else
94 0 : m_nStdHeight = nIconHeight;
95 0 : m_nStdHeight += GetTextHeight() + TOP_OFFSET;
96 :
97 0 : m_nActiveHeight = m_nStdHeight;
98 :
99 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
100 0 : if( IsControlBackground() )
101 0 : SetBackground( GetControlBackground() );
102 : else
103 0 : SetBackground( rStyleSettings.GetFieldColor() );
104 :
105 0 : m_xRemoveListener = new ClientRemovedListener( this );
106 :
107 0 : populateEntries();
108 :
109 0 : Show();
110 0 : }
111 :
112 0 : VCL_BUILDER_DECL_FACTORY(ClientBox)
113 : {
114 0 : WinBits nWinStyle = WB_TABSTOP;
115 0 : OString sBorder = VclBuilder::extractCustomProperty(rMap);
116 0 : if (!sBorder.isEmpty())
117 0 : nWinStyle |= WB_BORDER;
118 0 : rRet = VclPtr<ClientBox>::Create(pParent, nWinStyle);
119 0 : }
120 :
121 0 : Size ClientBox::GetOptimalSize() const
122 : {
123 0 : return LogicToPixel(Size(200, 140), MAP_APPFONT);
124 : }
125 :
126 0 : ClientBox::~ClientBox()
127 : {
128 0 : disposeOnce();
129 0 : }
130 :
131 0 : void ClientBox::dispose()
132 : {
133 0 : if ( ! m_bInDelete )
134 0 : DeleteRemoved();
135 :
136 0 : m_bInDelete = true;
137 :
138 0 : m_vEntries.clear();
139 :
140 0 : m_xRemoveListener.clear();
141 :
142 0 : m_aPinBox.disposeAndClear();
143 0 : m_aDeauthoriseButton.disposeAndClear();
144 0 : m_aScrollBar.disposeAndClear();
145 0 : Control::dispose();
146 0 : }
147 :
148 : // Title + description
149 0 : void ClientBox::CalcActiveHeight( const long nPos )
150 : {
151 : (void) nPos;
152 0 : const ::osl::MutexGuard aGuard( m_entriesMutex );
153 :
154 : // get title height
155 : long aTextHeight;
156 0 : long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
157 0 : long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
158 0 : if ( nIconHeight < nTitleHeight )
159 0 : aTextHeight = nTitleHeight;
160 : else
161 0 : aTextHeight = nIconHeight;
162 :
163 : // Text entry height
164 0 : Size aSize = GetOutputSizePixel();
165 0 : if ( m_bHasScrollBar )
166 0 : aSize.Width() -= m_aScrollBar->GetSizePixel().Width();
167 :
168 0 : aSize.Width() -= ICON_OFFSET;
169 :
170 : aSize = LogicToPixel( Size( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ),
171 0 : MapMode( MAP_APPFONT ) );
172 0 : aTextHeight += aSize.Height();
173 :
174 0 : if ( aTextHeight < m_nStdHeight )
175 0 : aTextHeight = m_nStdHeight;
176 :
177 0 : m_nActiveHeight = aTextHeight + 2;
178 0 : }
179 :
180 0 : Rectangle ClientBox::GetEntryRect( const long nPos ) const
181 : {
182 0 : const ::osl::MutexGuard aGuard( m_entriesMutex );
183 :
184 0 : Size aSize( GetOutputSizePixel() );
185 :
186 0 : if ( m_bHasScrollBar )
187 0 : aSize.Width() -= m_aScrollBar->GetSizePixel().Width();
188 :
189 0 : if ( m_vEntries[ nPos ]->m_bActive )
190 0 : aSize.Height() = m_nActiveHeight;
191 : else
192 0 : aSize.Height() = m_nStdHeight;
193 :
194 0 : Point aPos( 0, -m_nTopIndex + nPos * m_nStdHeight );
195 0 : if ( m_bHasActive && ( nPos < m_nActive ) )
196 0 : aPos.Y() += m_nActiveHeight - m_nStdHeight;
197 :
198 0 : return Rectangle( aPos, aSize );
199 : }
200 :
201 0 : void ClientBox::DeleteRemoved()
202 : {
203 0 : const ::osl::MutexGuard aGuard( m_entriesMutex );
204 :
205 0 : m_bInDelete = true;
206 :
207 0 : if ( ! m_vRemovedEntries.empty() )
208 : {
209 0 : m_vRemovedEntries.clear();
210 : }
211 :
212 0 : m_bInDelete = false;
213 0 : }
214 :
215 0 : long ClientBox::GetActiveEntryIndex()
216 : {
217 0 : if ( m_bHasActive )
218 0 : return m_nActive;
219 : else
220 0 : return -1;
221 : }
222 :
223 : //This function may be called with nPos < 0
224 0 : void ClientBox::selectEntry( const long nPos )
225 : {
226 : //ToDo whe should not use the guard at such a big scope here.
227 : //Currently it is used to guard m_vEntries and m_nActive. m_nActive will be
228 : //modified in this function.
229 : //It would be probably best to always use a copy of m_vEntries
230 : //and some other state variables from ClientBox for
231 : //the whole painting operation. See issue i86993
232 0 : ::osl::ClearableMutexGuard guard(m_entriesMutex);
233 :
234 0 : if ( m_bInCheckMode )
235 0 : return;
236 :
237 0 : if ( m_bHasActive )
238 : {
239 0 : if ( nPos == m_nActive )
240 0 : return;
241 :
242 0 : m_bHasActive = false;
243 0 : m_vEntries[ m_nActive ]->m_bActive = false;
244 : }
245 :
246 0 : if ( ( nPos >= 0 ) && ( nPos < (long) m_vEntries.size() ) )
247 : {
248 0 : m_bHasActive = true;
249 0 : m_nActive = nPos;
250 0 : m_vEntries[ nPos ]->m_bActive = true;
251 :
252 0 : if ( IsReallyVisible() )
253 : {
254 0 : m_bAdjustActive = true;
255 : }
256 : }
257 :
258 : // We empty the pin box now too, just in case the user previously
259 : // entered a pin, but then changed their selected device.
260 0 : m_aPinBox->SetText( "" );
261 0 : if ( m_bHasActive )
262 : {
263 : bool bAlreadyAuthorised =
264 0 : m_vEntries[ m_nActive ]->m_pClientInfo->mbIsAlreadyAuthorised;
265 :
266 0 : if ( bAlreadyAuthorised )
267 : {
268 0 : m_aDeauthoriseButton->GetFocus();
269 : }
270 : else
271 : {
272 0 : m_aPinBox->GetFocus();
273 : }
274 : }
275 :
276 0 : if ( IsReallyVisible() )
277 : {
278 0 : m_bNeedsRecalc = true;
279 0 : Invalidate();
280 : }
281 :
282 0 : guard.clear();
283 : }
284 :
285 0 : void ClientBox::DrawRow(vcl::RenderContext& rRenderContext, const Rectangle& rRect, const TClientBoxEntry& rEntry)
286 : {
287 0 : const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
288 :
289 0 : if (rEntry->m_bActive)
290 0 : SetTextColor(rStyleSettings.GetHighlightTextColor());
291 : else
292 0 : SetTextColor(rStyleSettings.GetFieldTextColor());
293 :
294 0 : if (rEntry->m_bActive)
295 : {
296 0 : rRenderContext.SetLineColor();
297 0 : rRenderContext.SetFillColor(rStyleSettings.GetHighlightColor());
298 0 : rRenderContext.DrawRect(rRect);
299 : }
300 : else
301 : {
302 0 : if(IsControlBackground())
303 0 : SetBackground(GetControlBackground());
304 : else
305 0 : SetBackground(rStyleSettings.GetFieldColor());
306 :
307 0 : rRenderContext.SetTextFillColor();
308 0 : rRenderContext.Erase(rRect);
309 : }
310 :
311 : // FIXME: draw bluetooth or wifi icon
312 0 : Point aPos(rRect.TopLeft());
313 :
314 : // Setup fonts
315 0 : vcl::Font aStdFont(rRenderContext.GetFont());
316 0 : vcl::Font aBoldFont(aStdFont);
317 0 : aBoldFont.SetWeight(WEIGHT_BOLD);
318 0 : rRenderContext.SetFont(aBoldFont);
319 0 : long aTextHeight = rRenderContext.GetTextHeight();
320 :
321 : // Get max title width
322 0 : long nMaxTitleWidth = rRect.GetWidth() - ICON_OFFSET;
323 0 : nMaxTitleWidth -= ( 2 * SMALL_ICON_SIZE ) + ( 4 * SPACE_BETWEEN );
324 :
325 0 : long aTitleWidth = rRenderContext.GetTextWidth(rEntry->m_pClientInfo->mName) + (aTextHeight / 3);
326 :
327 0 : aPos = rRect.TopLeft() + Point(ICON_OFFSET, TOP_OFFSET);
328 :
329 0 : if (aTitleWidth > nMaxTitleWidth)
330 : {
331 0 : aTitleWidth = nMaxTitleWidth - (aTextHeight / 3);
332 0 : OUString aShortTitle = rRenderContext.GetEllipsisString(rEntry->m_pClientInfo->mName, aTitleWidth );
333 0 : rRenderContext.DrawText(aPos, aShortTitle);
334 0 : aTitleWidth += (aTextHeight / 3);
335 : }
336 : else
337 0 : rRenderContext.DrawText(aPos, rEntry->m_pClientInfo->mName);
338 :
339 0 : SetFont(aStdFont);
340 :
341 0 : aPos.Y() += aTextHeight;
342 0 : if (rEntry->m_bActive)
343 : {
344 0 : OUString sPinText(SD_RESSTR(STR_ENTER_PIN));
345 0 : DrawText(m_sPinTextRect, sPinText);
346 : }
347 :
348 0 : rRenderContext.SetLineColor(Color(COL_LIGHTGRAY));
349 0 : rRenderContext.DrawLine(rRect.BottomLeft(), rRect.BottomRight());
350 0 : }
351 :
352 0 : void ClientBox::RecalcAll()
353 : {
354 0 : if ( m_bHasActive )
355 0 : CalcActiveHeight( m_nActive );
356 :
357 0 : SetupScrollBar();
358 :
359 : Size aPBSize = LogicToPixel(
360 : Size( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ),
361 0 : MapMode( MAP_APPFONT ) );
362 0 : m_aPinBox->SetSizePixel( aPBSize );
363 0 : m_aDeauthoriseButton->SetSizePixel( m_aDeauthoriseButton->GetOptimalSize() );
364 :
365 0 : if ( !m_bHasActive )
366 : {
367 0 : m_aPinBox->Show( false );
368 0 : m_aDeauthoriseButton->Show( false );
369 : }
370 : else
371 : {
372 0 : Rectangle aEntryRect = GetEntryRect( m_nActive );
373 :
374 0 : Size aPinBoxSize( m_aPinBox->GetSizePixel() );
375 0 : Point aPos( aEntryRect.Left(),
376 0 : aEntryRect.Bottom() - TOP_OFFSET - aPinBoxSize.Height() );
377 :
378 0 : bool bAlreadyAuthorised = m_vEntries[ m_nActive ]->m_pClientInfo->mbIsAlreadyAuthorised;
379 :
380 0 : if ( !bAlreadyAuthorised )
381 : {
382 0 : m_sPinTextRect = Rectangle( aPos.X(), aPos.Y(),
383 0 : aEntryRect.Right(),
384 0 : aEntryRect.Bottom() - TOP_OFFSET);
385 :
386 0 : OUString sPinText(SD_RESSTR(STR_ENTER_PIN));
387 :
388 0 : aPos = Point( aEntryRect.Left() + GetTextWidth( sPinText ),
389 0 : aEntryRect.Bottom() - TOP_OFFSET - aPinBoxSize.Height() );
390 0 : m_aPinBox->SetPosPixel( aPos );
391 : // The text would have it's TOP aligned with the top of
392 : // the pin box -- hence we push it down to align baselines.
393 0 : m_sPinTextRect += Point( 0, 4 );
394 : }
395 : else
396 : {
397 0 : aPos += Point( 20, 0 );
398 0 : m_aDeauthoriseButton->SetPosPixel( aPos );
399 : }
400 :
401 0 : m_aPinBox->Show( !bAlreadyAuthorised );
402 0 : m_aDeauthoriseButton->Show( bAlreadyAuthorised );
403 :
404 0 : if ( m_bAdjustActive )
405 : {
406 0 : m_bAdjustActive = false;
407 :
408 : // If the top of the selected entry isn't visible, make it visible
409 0 : if ( aEntryRect.Top() < 0 )
410 : {
411 0 : m_nTopIndex += aEntryRect.Top();
412 0 : aEntryRect.Move( 0, -aEntryRect.Top() );
413 : }
414 :
415 : // If the bottom of the selected entry isn't visible, make it visible even if now the top
416 : // isn't visible any longer ( the buttons are more important )
417 0 : Size aOutputSize = GetOutputSizePixel();
418 0 : if ( aEntryRect.Bottom() > aOutputSize.Height() )
419 : {
420 0 : m_nTopIndex += ( aEntryRect.Bottom() - aOutputSize.Height() );
421 0 : aEntryRect.Move( 0, -( aEntryRect.Bottom() - aOutputSize.Height() ) );
422 : }
423 :
424 : // If there is unused space below the last entry but all entries don't fit into the box,
425 : // move the content down to use the whole space
426 0 : const long nTotalHeight = GetTotalHeight();
427 0 : if ( m_bHasScrollBar && ( aOutputSize.Height() + m_nTopIndex > nTotalHeight ) )
428 : {
429 0 : long nOffset = m_nTopIndex;
430 0 : m_nTopIndex = nTotalHeight - aOutputSize.Height();
431 0 : nOffset -= m_nTopIndex;
432 0 : aEntryRect.Move( 0, nOffset );
433 : }
434 :
435 0 : if ( m_bHasScrollBar )
436 0 : m_aScrollBar->SetThumbPos( m_nTopIndex );
437 : }
438 : }
439 :
440 0 : m_bNeedsRecalc = false;
441 0 : }
442 :
443 0 : bool ClientBox::HandleCursorKey( sal_uInt16 nKeyCode )
444 : {
445 0 : if ( m_vEntries.empty() )
446 0 : return true;
447 :
448 0 : long nSelect = 0;
449 :
450 0 : if ( m_bHasActive )
451 : {
452 0 : long nPageSize = GetOutputSizePixel().Height() / m_nStdHeight;
453 0 : if ( nPageSize < 2 )
454 0 : nPageSize = 2;
455 :
456 0 : if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_RIGHT ) )
457 0 : nSelect = m_nActive + 1;
458 0 : else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_LEFT ) )
459 0 : nSelect = m_nActive - 1;
460 0 : else if ( nKeyCode == KEY_HOME )
461 0 : nSelect = 0;
462 0 : else if ( nKeyCode == KEY_END )
463 0 : nSelect = m_vEntries.size() - 1;
464 0 : else if ( nKeyCode == KEY_PAGEUP )
465 0 : nSelect = m_nActive - nPageSize + 1;
466 0 : else if ( nKeyCode == KEY_PAGEDOWN )
467 0 : nSelect = m_nActive + nPageSize - 1;
468 : }
469 : else // when there is no selected entry, we will select the first or the last.
470 : {
471 0 : if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_PAGEDOWN ) || ( nKeyCode == KEY_HOME ) )
472 0 : nSelect = 0;
473 0 : else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_PAGEUP ) || ( nKeyCode == KEY_END ) )
474 0 : nSelect = m_vEntries.size() - 1;
475 : }
476 :
477 0 : if ( nSelect < 0 )
478 0 : nSelect = 0;
479 0 : if ( nSelect >= (long) m_vEntries.size() )
480 0 : nSelect = m_vEntries.size() - 1;
481 :
482 0 : selectEntry( nSelect );
483 :
484 0 : return true;
485 : }
486 :
487 0 : void ClientBox::Paint(vcl::RenderContext& rRenderContext, const Rectangle &/*rPaintRect*/)
488 : {
489 0 : if (!m_bInDelete)
490 0 : DeleteRemoved();
491 :
492 0 : if (m_bNeedsRecalc)
493 0 : RecalcAll();
494 :
495 0 : Point aStart(0, -m_nTopIndex);
496 0 : Size aSize(rRenderContext.GetOutputSizePixel());
497 :
498 0 : if (m_bHasScrollBar)
499 0 : aSize.Width() -= m_aScrollBar->GetSizePixel().Width();
500 :
501 0 : const ::osl::MutexGuard aGuard(m_entriesMutex);
502 :
503 : typedef std::vector< TClientBoxEntry >::iterator ITER;
504 0 : for (ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex)
505 : {
506 0 : aSize.Height() = (*iIndex)->m_bActive ? m_nActiveHeight : m_nStdHeight;
507 0 : Rectangle aEntryRect(aStart, aSize);
508 0 : DrawRow(rRenderContext, aEntryRect, *iIndex);
509 0 : aStart.Y() += aSize.Height();
510 0 : }
511 0 : }
512 :
513 0 : long ClientBox::GetTotalHeight() const
514 : {
515 0 : long nHeight = m_vEntries.size() * m_nStdHeight;
516 :
517 0 : if ( m_bHasActive )
518 : {
519 0 : nHeight += m_nActiveHeight - m_nStdHeight;
520 : }
521 :
522 0 : return nHeight;
523 : }
524 :
525 0 : void ClientBox::SetupScrollBar()
526 : {
527 0 : const Size aSize = GetOutputSizePixel();
528 0 : const long nScrBarSize = GetSettings().GetStyleSettings().GetScrollBarSize();
529 0 : const long nTotalHeight = GetTotalHeight();
530 0 : const bool bNeedsScrollBar = ( nTotalHeight > aSize.Height() );
531 :
532 0 : if ( bNeedsScrollBar )
533 : {
534 0 : if ( m_nTopIndex + aSize.Height() > nTotalHeight )
535 0 : m_nTopIndex = nTotalHeight - aSize.Height();
536 :
537 0 : m_aScrollBar->SetPosSizePixel( Point( aSize.Width() - nScrBarSize, 0 ),
538 0 : Size( nScrBarSize, aSize.Height() ) );
539 0 : m_aScrollBar->SetRangeMax( nTotalHeight );
540 0 : m_aScrollBar->SetVisibleSize( aSize.Height() );
541 0 : m_aScrollBar->SetPageSize( ( aSize.Height() * 4 ) / 5 );
542 0 : m_aScrollBar->SetLineSize( m_nStdHeight );
543 0 : m_aScrollBar->SetThumbPos( m_nTopIndex );
544 :
545 0 : if ( !m_bHasScrollBar )
546 0 : m_aScrollBar->Show();
547 : }
548 0 : else if ( m_bHasScrollBar )
549 : {
550 0 : m_aScrollBar->Hide();
551 0 : m_nTopIndex = 0;
552 : }
553 :
554 0 : m_bHasScrollBar = bNeedsScrollBar;
555 0 : }
556 :
557 0 : void ClientBox::Resize()
558 : {
559 0 : RecalcAll();
560 0 : }
561 :
562 0 : long ClientBox::PointToPos( const Point& rPos )
563 : {
564 0 : long nPos = ( rPos.Y() + m_nTopIndex ) / m_nStdHeight;
565 :
566 0 : if ( m_bHasActive && ( nPos > m_nActive ) )
567 : {
568 0 : if ( rPos.Y() + m_nTopIndex <= m_nActive*m_nStdHeight + m_nActiveHeight )
569 0 : nPos = m_nActive;
570 : else
571 0 : nPos = ( rPos.Y() + m_nTopIndex - (m_nActiveHeight - m_nStdHeight) ) / m_nStdHeight;
572 : }
573 :
574 0 : return nPos;
575 : }
576 :
577 0 : OUString ClientBox::getPin()
578 : {
579 0 : return OUString::number( m_aPinBox->GetValue() );
580 : }
581 :
582 0 : void ClientBox::MouseButtonDown( const MouseEvent& rMEvt )
583 : {
584 0 : long nPos = PointToPos( rMEvt.GetPosPixel() );
585 :
586 0 : if ( rMEvt.IsLeft() )
587 : {
588 0 : if ( rMEvt.IsMod1() && m_bHasActive )
589 0 : selectEntry( m_vEntries.size() ); // Selecting an not existing entry will deselect the current one
590 : else
591 0 : selectEntry( nPos );
592 : }
593 0 : }
594 :
595 0 : bool ClientBox::Notify( NotifyEvent& rNEvt )
596 : {
597 0 : if ( !m_bInDelete )
598 0 : DeleteRemoved();
599 :
600 0 : bool bHandled = false;
601 :
602 0 : if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
603 : {
604 0 : const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
605 0 : vcl::KeyCode aKeyCode = pKEvt->GetKeyCode();
606 0 : sal_uInt16 nKeyCode = aKeyCode.GetCode();
607 :
608 0 : if ( aKeyCode.GetGroup() == KEYGROUP_CURSOR )
609 0 : bHandled = HandleCursorKey( nKeyCode );
610 : }
611 :
612 0 : if ( rNEvt.GetType() == MouseNotifyEvent::COMMAND )
613 : {
614 0 : if ( m_bHasScrollBar &&
615 0 : ( rNEvt.GetCommandEvent()->GetCommand() == CommandEventId::Wheel ) )
616 : {
617 0 : const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
618 0 : if ( pData->GetMode() == CommandWheelMode::SCROLL )
619 : {
620 0 : long nThumbPos = m_aScrollBar->GetThumbPos();
621 0 : if ( pData->GetDelta() < 0 )
622 0 : m_aScrollBar->DoScroll( nThumbPos + m_nStdHeight );
623 : else
624 0 : m_aScrollBar->DoScroll( nThumbPos - m_nStdHeight );
625 0 : bHandled = true;
626 : }
627 : }
628 : }
629 :
630 0 : if ( !bHandled )
631 0 : return Control::Notify( rNEvt );
632 : else
633 0 : return true;
634 : }
635 :
636 0 : long ClientBox::addEntry( ::boost::shared_ptr<ClientInfo> pClientInfo )
637 : {
638 0 : long nPos = 0;
639 :
640 0 : TClientBoxEntry xEntry( new ClientBoxEntry( pClientInfo ) );
641 :
642 0 : ::osl::ClearableMutexGuard guard(m_entriesMutex);
643 0 : if ( m_vEntries.empty() )
644 : {
645 0 : m_vEntries.push_back( xEntry );
646 : }
647 : else
648 : {
649 : // if ( !FindEntryPos( xEntry, 0, m_vEntries.size()-1, nPos ) )
650 : // {
651 0 : m_vEntries.insert( m_vEntries.begin()+nPos, xEntry );
652 : // }
653 : // else if ( !m_bInCheckMode )
654 : // {
655 : // OSL_FAIL( "ClientBox::addEntry(): Will not add duplicate entries" );
656 : // }
657 : }
658 :
659 : //access to m_nActive must be guarded
660 0 : if ( !m_bInCheckMode && m_bHasActive && ( m_nActive >= nPos ) )
661 0 : m_nActive += 1;
662 :
663 0 : guard.clear();
664 :
665 0 : if ( IsReallyVisible() )
666 0 : Invalidate();
667 :
668 0 : m_bNeedsRecalc = true;
669 :
670 0 : return nPos;
671 : }
672 :
673 0 : void ClientBox::clearEntries()
674 : {
675 0 : selectEntry( -1 );
676 0 : m_bHasActive = false;
677 :
678 0 : const ::osl::MutexGuard aGuard( m_entriesMutex );
679 :
680 0 : m_vEntries.clear();
681 0 : if ( IsReallyVisible() )
682 0 : Invalidate();
683 0 : m_bNeedsRecalc = true;
684 0 : }
685 :
686 0 : void ClientBox::populateEntries()
687 : {
688 0 : const ::osl::MutexGuard aGuard( m_entriesMutex );
689 :
690 0 : clearEntries();
691 :
692 : #ifdef ENABLE_SDREMOTE
693 0 : RemoteServer::ensureDiscoverable();
694 :
695 0 : vector< ::boost::shared_ptr< ClientInfo > > aClients( RemoteServer::getClients() );
696 :
697 0 : const vector< ::boost::shared_ptr<ClientInfo > >::const_iterator aEnd( aClients.end() );
698 :
699 0 : for ( vector< ::boost::shared_ptr< ClientInfo > >::const_iterator aIt( aClients.begin() );
700 : aIt != aEnd; ++aIt )
701 : {
702 0 : addEntry( *aIt );
703 : }
704 : #endif
705 :
706 0 : if ( IsReallyVisible() )
707 0 : Invalidate();
708 0 : m_bNeedsRecalc = true;
709 0 : }
710 :
711 0 : void ClientBox::DoScroll( long nDelta )
712 : {
713 0 : m_nTopIndex += nDelta;
714 0 : Point aNewSBPt( m_aScrollBar->GetPosPixel() );
715 :
716 0 : Rectangle aScrRect( Point(), GetOutputSizePixel() );
717 0 : aScrRect.Right() -= m_aScrollBar->GetSizePixel().Width();
718 0 : Scroll( 0, -nDelta, aScrRect );
719 :
720 0 : m_aScrollBar->SetPosPixel( aNewSBPt );
721 0 : }
722 :
723 0 : IMPL_LINK( ClientBox, ScrollHdl, ScrollBar*, pScrBar )
724 : {
725 0 : DoScroll( pScrBar->GetDelta() );
726 :
727 0 : return 1;
728 : }
729 :
730 0 : IMPL_LINK_NOARG( ClientBox, DeauthoriseHdl )
731 : {
732 0 : long aSelected = GetActiveEntryIndex();
733 0 : if ( aSelected < 0 )
734 0 : return 1;
735 0 : TClientBoxEntry aEntry = GetEntryData(aSelected);
736 :
737 : #ifdef ENABLE_SDREMOTE
738 0 : RemoteServer::deauthoriseClient( aEntry->m_pClientInfo );
739 : #endif
740 0 : populateEntries();
741 0 : return 1;
742 : }
743 :
744 0 : } //namespace dp_gui
745 :
746 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|