1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
22 #include <o3tl/numeric.hxx>
23 #include <vcl/svapp.hxx>
24 #include <vcl/help.hxx>
25 #include <vcl/image.hxx>
26 #include <vcl/settings.hxx>
27 #include <rtl/string.hxx>
28 #include <tools/debug.hxx>
29 #include <tools/fract.hxx>
32 void ButtonFrame::Draw( OutputDevice
& rDev
)
34 Color aOldFillColor
= rDev
.GetFillColor();
35 Color aOldLineColor
= rDev
.GetLineColor();
37 const StyleSettings
&rSettings
= rDev
.GetSettings().GetStyleSettings();
38 Color
aColLight( rSettings
.GetLightColor() );
39 Color
aColShadow( rSettings
.GetShadowColor() );
40 Color
aColFace( rSettings
.GetFaceColor() );
42 rDev
.SetLineColor( aColFace
);
43 rDev
.SetFillColor( aColFace
);
44 rDev
.DrawRect( aRect
);
46 if( rDev
.GetOutDevType() == OUTDEV_WINDOW
)
48 vcl::Window
*pWin
= static_cast<vcl::Window
*>( &rDev
);
50 pWin
->DrawSelectionBackground( aRect
, 0, true, false, false );
54 rDev
.SetLineColor( bPressed
? aColShadow
: aColLight
);
55 rDev
.DrawLine( aRect
.TopLeft(), Point( aRect
.Right(), aRect
.Top() ) );
56 rDev
.DrawLine( aRect
.TopLeft(), Point( aRect
.Left(), aRect
.Bottom() - 1 ) );
57 rDev
.SetLineColor( bPressed
? aColLight
: aColShadow
);
58 rDev
.DrawLine( aRect
.BottomRight(), Point( aRect
.Right(), aRect
.Top() ) );
59 rDev
.DrawLine( aRect
.BottomRight(), Point( aRect
.Left(), aRect
.Bottom() ) );
62 if ( !aText
.isEmpty() )
64 OUString aVal
= rDev
.GetEllipsisString(aText
,aInnerRect
.GetWidth() - 2*MIN_COLUMNWIDTH
);
66 vcl::Font
aFont( rDev
.GetFont() );
67 bool bOldTransp
= aFont
.IsTransparent();
70 aFont
.SetTransparent( true );
71 rDev
.SetFont( aFont
);
74 Color aOldColor
= rDev
.GetTextColor();
76 rDev
.SetTextColor(rSettings
.GetDisableColor());
79 ( aInnerRect
.Left() + aInnerRect
.Right() ) / 2 - ( rDev
.GetTextWidth(aVal
) / 2 ),
80 aInnerRect
.Top() ), aVal
);
85 aFont
.SetTransparent(false);
86 rDev
.SetFont( aFont
);
89 rDev
.SetTextColor(aOldColor
);
94 rDev
.SetLineColor( Color( COL_BLACK
) );
96 rDev
.DrawRect( Rectangle(
97 Point( aRect
.Left(), aRect
.Top() ), Point( aRect
.Right(), aRect
.Bottom() ) ) );
100 rDev
.SetLineColor( aOldLineColor
);
101 rDev
.SetFillColor( aOldFillColor
);
104 BrowserColumn::BrowserColumn( sal_uInt16 nItemId
, const class Image
&rImage
,
105 const OUString
& rTitle
, sal_uLong nWidthPixel
, const Fraction
& rCurrentZoom
)
107 _nWidth( nWidthPixel
),
112 double n
= (double)_nWidth
;
113 n
*= (double)rCurrentZoom
.GetDenominator();
114 if (!rCurrentZoom
.GetNumerator())
115 throw o3tl::divide_by_zero();
116 n
/= (double)rCurrentZoom
.GetNumerator();
117 _nOriginalWidth
= n
>0 ? (long)(n
+0.5) : -(long)(-n
+0.5);
120 BrowserColumn::~BrowserColumn()
124 void BrowserColumn::SetWidth(sal_uLong nNewWidthPixel
, const Fraction
& rCurrentZoom
)
126 _nWidth
= nNewWidthPixel
;
127 // Avoid overflow when called with LONG_MAX from
128 // BrowseBox::AutoSizeLastColumn:
129 if (_nWidth
== LONG_MAX
)
131 _nOriginalWidth
= _nWidth
;
135 double n
= (double)_nWidth
;
136 n
*= (double)rCurrentZoom
.GetDenominator();
137 if (!rCurrentZoom
.GetNumerator())
138 throw o3tl::divide_by_zero();
139 n
/= (double)rCurrentZoom
.GetNumerator();
140 _nOriginalWidth
= n
>0 ? (long)(n
+0.5) : -(long)(-n
+0.5);
144 void BrowserColumn::Draw( BrowseBox
& rBox
, OutputDevice
& rDev
, const Point
& rPos
, bool bCurs
)
148 // paint handle column
149 ButtonFrame( rPos
, Size( Width()-1, rBox
.GetDataRowHeight()-1 ),
150 "", false, bCurs
, false ).Draw( rDev
);
151 Color aOldLineColor
= rDev
.GetLineColor();
152 rDev
.SetLineColor( Color( COL_BLACK
) );
154 Point( rPos
.X(), rPos
.Y()+rBox
.GetDataRowHeight()-1 ),
155 Point( rPos
.X() + Width() - 1, rPos
.Y()+rBox
.GetDataRowHeight()-1 ) );
157 Point( rPos
.X() + Width() - 1, rPos
.Y() ),
158 Point( rPos
.X() + Width() - 1, rPos
.Y()+rBox
.GetDataRowHeight()-1 ) );
159 rDev
.SetLineColor( aOldLineColor
);
161 rBox
.DoPaintField( rDev
,
163 Point( rPos
.X() + 2, rPos
.Y() + 2 ),
164 Size( Width()-1, rBox
.GetDataRowHeight()-1 ) ),
166 BrowseBox::BrowserColumnAccess() );
171 long nWidth
= Width() == LONG_MAX
? rBox
.GetDataWindow().GetSizePixel().Width() : Width();
173 rBox
.DoPaintField( rDev
,
175 Point( rPos
.X() + MIN_COLUMNWIDTH
, rPos
.Y() ),
176 Size( nWidth
-2*MIN_COLUMNWIDTH
, rBox
.GetDataRowHeight()-1 ) ),
178 BrowseBox::BrowserColumnAccess() );
184 void BrowserColumn::ZoomChanged(const Fraction
& rNewZoom
)
186 double n
= (double)_nOriginalWidth
;
187 n
*= (double)rNewZoom
.GetNumerator();
188 n
/= (double)rNewZoom
.GetDenominator();
190 _nWidth
= n
>0 ? (long)(n
+0.5) : -(long)(-n
+0.5);
195 BrowserDataWin::BrowserDataWin( BrowseBox
* pParent
)
196 :Control( pParent
, WinBits(WB_CLIPCHILDREN
) )
197 ,DragSourceHelper( this )
198 ,DropTargetHelper( this )
200 ,pEventWin( pParent
)
205 ,bNoScrollBack( false )
211 ,bAutoSizeLastCol(false)
212 ,bResizeOnPaint( false )
213 ,bUpdateOnUnlock( false )
214 ,bInUpdateScrollbars( false )
215 ,bHadRecursion( false )
216 ,bOwnDataChangedHdl( false )
217 ,bCallingDropCallback( false )
220 ,m_nDragRowDividerLimit( 0 )
221 ,m_nDragRowDividerOffset( 0 )
223 aMouseTimer
.SetTimeoutHdl( LINK( this, BrowserDataWin
, RepeatedMouseMove
) );
224 aMouseTimer
.SetTimeout( 100 );
228 BrowserDataWin::~BrowserDataWin()
233 void BrowserDataWin::dispose()
237 for ( size_t i
= 0, n
= aInvalidRegion
.size(); i
< n
; ++i
)
238 delete aInvalidRegion
[ i
];
239 aInvalidRegion
.clear();
247 void BrowserDataWin::LeaveUpdateLock()
249 if ( !--nUpdateLock
)
251 DoOutstandingInvalidations();
252 if (bUpdateOnUnlock
)
255 bUpdateOnUnlock
= false;
260 void InitSettings_Impl(vcl::Window
* pWin
, bool bFont
, bool bForeground
, bool bBackground
)
262 const StyleSettings
& rStyleSettings
= pWin
->GetSettings().GetStyleSettings();
265 pWin
->ApplyControlFont(*pWin
, rStyleSettings
.GetFieldFont());
267 if (bFont
|| bForeground
)
268 pWin
->ApplyControlForeground(*pWin
, rStyleSettings
.GetWindowTextColor());
271 pWin
->ApplyControlBackground(*pWin
, rStyleSettings
.GetWindowColor());
275 void BrowserDataWin::Update()
280 bUpdateOnUnlock
= true;
284 void BrowserDataWin::DataChanged( const DataChangedEvent
& rDCEvt
)
286 if ( (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
287 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
289 if( !bOwnDataChangedHdl
)
291 InitSettings_Impl(this, true, true, true);
293 InitSettings_Impl(GetParent(), true, true, true);
294 GetParent()->Invalidate();
295 GetParent()->Resize();
299 Control::DataChanged( rDCEvt
);
303 void BrowserDataWin::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
& rRect
)
305 if (!nUpdateLock
&& GetUpdateMode())
309 aInvalidRegion
.push_back(new Rectangle(rRect
));
313 GetParent()->PaintData(*this, rRenderContext
, rRect
);
315 DoOutstandingInvalidations();
319 aInvalidRegion
.push_back(new Rectangle(rRect
));
325 BrowseEvent
BrowserDataWin::CreateBrowseEvent( const Point
& rPosPixel
)
327 BrowseBox
*pBox
= GetParent();
329 // seek to row under mouse
330 long nRelRow
= rPosPixel
.Y() < 0
332 : rPosPixel
.Y() / pBox
->GetDataRowHeight();
333 long nRow
= nRelRow
< 0 ? -1 : nRelRow
+ pBox
->nTopRow
;
335 // find column under mouse
336 long nMouseX
= rPosPixel
.X();
340 nCol
< pBox
->pCols
->size() && nColX
< GetSizePixel().Width();
342 if ( (*pBox
->pCols
)[ nCol
]->IsFrozen() || nCol
>= pBox
->nFirstCol
)
344 nColX
+= (*pBox
->pCols
)[ nCol
]->Width();
345 if ( nMouseX
< nColX
)
348 sal_uInt16 nColId
= BROWSER_INVALIDID
;
349 if ( nCol
< pBox
->pCols
->size() )
350 nColId
= (*pBox
->pCols
)[ nCol
]->GetId();
352 // compute the field rectangle and field relative MouseEvent
353 Rectangle aFieldRect
;
354 if ( nCol
< pBox
->pCols
->size() )
356 nColX
-= (*pBox
->pCols
)[ nCol
]->Width();
357 aFieldRect
= Rectangle(
358 Point( nColX
, nRelRow
* pBox
->GetDataRowHeight() ),
359 Size( (*pBox
->pCols
)[ nCol
]->Width(),
360 pBox
->GetDataRowHeight() ) );
363 // assemble and return the BrowseEvent
364 return BrowseEvent( this, nRow
, nCol
, nColId
, aFieldRect
);
368 sal_Int8
BrowserDataWin::AcceptDrop( const AcceptDropEvent
& _rEvt
)
370 bCallingDropCallback
= true;
371 sal_Int8 nReturn
= GetParent()->AcceptDrop( BrowserAcceptDropEvent( this, _rEvt
) );
372 bCallingDropCallback
= false;
377 sal_Int8
BrowserDataWin::ExecuteDrop( const ExecuteDropEvent
& _rEvt
)
379 bCallingDropCallback
= true;
380 sal_Int8 nReturn
= GetParent()->ExecuteDrop( BrowserExecuteDropEvent( this, _rEvt
) );
381 bCallingDropCallback
= false;
386 void BrowserDataWin::StartDrag( sal_Int8 _nAction
, const Point
& _rPosPixel
)
388 if ( !GetParent()->bRowDividerDrag
)
390 Point
aEventPos( _rPosPixel
);
391 aEventPos
.Y() += GetParent()->GetTitleHeight();
392 GetParent()->StartDrag( _nAction
, aEventPos
);
397 void BrowserDataWin::Command( const CommandEvent
& rEvt
)
399 // scroll mouse event?
400 BrowseBox
*pBox
= GetParent();
401 if ( ( (rEvt
.GetCommand() == CommandEventId::Wheel
) ||
402 (rEvt
.GetCommand() == CommandEventId::StartAutoScroll
) ||
403 (rEvt
.GetCommand() == CommandEventId::AutoScroll
) ) &&
404 ( HandleScrollCommand( rEvt
, pBox
->aHScroll
.get(), pBox
->pVScroll
) ) )
407 Point
aEventPos( rEvt
.GetMousePosPixel() );
408 long nRow
= pBox
->GetRowAtYPosPixel( aEventPos
.Y(), false);
409 MouseEvent
aMouseEvt( aEventPos
, 1, MouseEventModifiers::SELECT
, MOUSE_LEFT
);
410 if ( CommandEventId::ContextMenu
== rEvt
.GetCommand() && rEvt
.IsMouseEvent() &&
411 nRow
< pBox
->GetRowCount() && !pBox
->IsRowSelected(nRow
) )
414 MouseButtonDown( aMouseEvt
);
417 MouseButtonUp( aMouseEvt
);
423 aEventPos
.Y() += GetParent()->GetTitleHeight();
424 CommandEvent
aEvt( aEventPos
, rEvt
.GetCommand(),
425 rEvt
.IsMouseEvent(), rEvt
.GetEventData() );
427 GetParent()->Command( aEvt
);
432 if ( CommandEventId::StartDrag
== rEvt
.GetCommand() )
433 MouseButtonUp( aMouseEvt
);
435 Control::Command( rEvt
);
440 bool BrowserDataWin::ImplRowDividerHitTest( const BrowserMouseEvent
& _rEvent
)
442 if ( ! ( GetParent()->IsInteractiveRowHeightEnabled()
443 && ( _rEvent
.GetRow() >= 0 )
444 && ( _rEvent
.GetRow() < GetParent()->GetRowCount() )
445 && ( _rEvent
.GetColumnId() == BrowseBox::HandleColumnId
)
450 long nDividerDistance
= GetParent()->GetDataRowHeight() - ( _rEvent
.GetPosPixel().Y() % GetParent()->GetDataRowHeight() );
451 return ( nDividerDistance
<= 4 );
456 void BrowserDataWin::MouseButtonDown( const MouseEvent
& rEvt
)
458 aLastMousePos
= OutputToScreenPixel( rEvt
.GetPosPixel() );
460 BrowserMouseEvent
aBrowserEvent( this, rEvt
);
461 if ( ( aBrowserEvent
.GetClicks() == 1 ) && ImplRowDividerHitTest( aBrowserEvent
) )
463 StartRowDividerDrag( aBrowserEvent
.GetPosPixel() );
467 GetParent()->MouseButtonDown( BrowserMouseEvent( this, rEvt
) );
472 void BrowserDataWin::MouseMove( const MouseEvent
& rEvt
)
474 // avoid pseudo MouseMoves
475 Point aNewPos
= OutputToScreenPixel( rEvt
.GetPosPixel() );
476 if ( ( aNewPos
== aLastMousePos
) )
478 aLastMousePos
= aNewPos
;
480 // transform to a BrowseEvent
481 BrowserMouseEvent
aBrowserEvent( this, rEvt
);
482 GetParent()->MouseMove( aBrowserEvent
);
485 PointerStyle ePointerStyle
= PointerStyle::Arrow
;
486 if ( ImplRowDividerHitTest( aBrowserEvent
) )
487 ePointerStyle
= PointerStyle::VSizeBar
;
488 SetPointer( Pointer( ePointerStyle
) );
490 // dragging out of the visible area?
491 if ( rEvt
.IsLeft() &&
492 ( rEvt
.GetPosPixel().Y() > GetSizePixel().Height() ||
493 rEvt
.GetPosPixel().Y() < 0 ) )
500 // killing old repeat-event
501 if ( aMouseTimer
.IsActive() )
507 IMPL_LINK_NOARG_TYPED(BrowserDataWin
, RepeatedMouseMove
, Timer
*, void)
509 GetParent()->MouseMove( BrowserMouseEvent( this, aRepeatEvt
) );
512 void BrowserDataWin::MouseButtonUp( const MouseEvent
& rEvt
)
514 // avoid pseudo MouseMoves
515 Point aNewPos
= OutputToScreenPixel( rEvt
.GetPosPixel() );
516 aLastMousePos
= aNewPos
;
518 // simulate a move to the current position
521 // actual button up handling
523 if ( aMouseTimer
.IsActive() )
525 GetParent()->MouseButtonUp( BrowserMouseEvent( this, rEvt
) );
530 void BrowserDataWin::StartRowDividerDrag( const Point
& _rStartPos
)
532 long nDataRowHeight
= GetParent()->GetDataRowHeight();
533 // the exact separation pos of the two rows
534 long nDragRowDividerCurrentPos
= _rStartPos
.Y();
535 if ( ( nDragRowDividerCurrentPos
% nDataRowHeight
) > nDataRowHeight
/ 2 )
536 nDragRowDividerCurrentPos
+= nDataRowHeight
;
537 nDragRowDividerCurrentPos
/= nDataRowHeight
;
538 nDragRowDividerCurrentPos
*= nDataRowHeight
;
540 m_nDragRowDividerOffset
= nDragRowDividerCurrentPos
- _rStartPos
.Y();
542 m_nDragRowDividerLimit
= nDragRowDividerCurrentPos
- nDataRowHeight
;
544 GetParent()->bRowDividerDrag
= true;
545 GetParent()->ImplStartTracking();
547 Rectangle
aDragSplitRect( 0, m_nDragRowDividerLimit
, GetOutputSizePixel().Width(), nDragRowDividerCurrentPos
);
548 ShowTracking( aDragSplitRect
, SHOWTRACK_SMALL
);
555 void BrowserDataWin::Tracking( const TrackingEvent
& rTEvt
)
557 if ( !GetParent()->bRowDividerDrag
)
560 Point aMousePos
= rTEvt
.GetMouseEvent().GetPosPixel();
561 // stop resizing at our bottom line
562 if ( aMousePos
.Y() > GetOutputSizePixel().Height() )
563 aMousePos
.Y() = GetOutputSizePixel().Height();
565 if ( rTEvt
.IsTrackingEnded() )
568 GetParent()->bRowDividerDrag
= false;
569 GetParent()->ImplEndTracking();
571 if ( !rTEvt
.IsTrackingCanceled() )
573 long nNewRowHeight
= aMousePos
.Y() + m_nDragRowDividerOffset
- m_nDragRowDividerLimit
;
575 // care for minimum row height
576 if ( nNewRowHeight
< GetParent()->QueryMinimumRowHeight() )
577 nNewRowHeight
= GetParent()->QueryMinimumRowHeight();
579 GetParent()->SetDataRowHeight( nNewRowHeight
);
580 GetParent()->RowHeightChanged();
585 GetParent()->ImplTracking();
587 long nDragRowDividerCurrentPos
= aMousePos
.Y() + m_nDragRowDividerOffset
;
589 // care for minimum row height
590 if ( nDragRowDividerCurrentPos
< m_nDragRowDividerLimit
+ GetParent()->QueryMinimumRowHeight() )
591 nDragRowDividerCurrentPos
= m_nDragRowDividerLimit
+ GetParent()->QueryMinimumRowHeight();
593 Rectangle
aDragSplitRect( 0, m_nDragRowDividerLimit
, GetOutputSizePixel().Width(), nDragRowDividerCurrentPos
);
594 ShowTracking( aDragSplitRect
, SHOWTRACK_SMALL
);
600 void BrowserDataWin::KeyInput( const KeyEvent
& rEvt
)
602 // pass to parent window
603 if ( !GetParent()->ProcessKey( rEvt
) )
604 Control::KeyInput( rEvt
);
609 void BrowserDataWin::RequestHelp( const HelpEvent
& rHEvt
)
612 GetParent()->RequestHelp( rHEvt
);
613 pEventWin
= GetParent();
618 BrowseEvent::BrowseEvent( vcl::Window
* pWindow
,
619 long nAbsRow
, sal_uInt16 nColumn
, sal_uInt16 nColumnId
,
620 const Rectangle
& rRect
):
630 BrowserMouseEvent::BrowserMouseEvent( BrowserDataWin
*pWindow
,
631 const MouseEvent
& rEvt
):
633 BrowseEvent( pWindow
->CreateBrowseEvent( rEvt
.GetPosPixel() ) )
639 BrowserMouseEvent::BrowserMouseEvent( vcl::Window
*pWindow
, const MouseEvent
& rEvt
,
640 long nAbsRow
, sal_uInt16 nColumn
, sal_uInt16 nColumnId
,
641 const Rectangle
& rRect
):
643 BrowseEvent( pWindow
, nAbsRow
, nColumn
, nColumnId
, rRect
)
649 BrowserAcceptDropEvent::BrowserAcceptDropEvent( BrowserDataWin
*pWindow
, const AcceptDropEvent
& rEvt
)
650 :AcceptDropEvent(rEvt
)
651 ,BrowseEvent( pWindow
->CreateBrowseEvent( rEvt
.maPosPixel
) )
657 BrowserExecuteDropEvent::BrowserExecuteDropEvent( BrowserDataWin
*pWindow
, const ExecuteDropEvent
& rEvt
)
658 :ExecuteDropEvent(rEvt
)
659 ,BrowseEvent( pWindow
->CreateBrowseEvent( rEvt
.maPosPixel
) )
667 void BrowserDataWin::SetUpdateMode( bool bMode
)
669 DBG_ASSERT( !bUpdateMode
|| aInvalidRegion
.empty(), "invalid region not empty" );
670 if ( (bool) bMode
== bUpdateMode
)
675 DoOutstandingInvalidations();
679 void BrowserDataWin::DoOutstandingInvalidations()
681 for ( size_t i
= 0, n
= aInvalidRegion
.size(); i
< n
; ++i
) {
682 Control::Invalidate( *aInvalidRegion
[ i
] );
683 delete aInvalidRegion
[ i
];
685 aInvalidRegion
.clear();
690 void BrowserDataWin::Invalidate( sal_uInt16 nFlags
)
692 if ( !GetUpdateMode() )
694 for ( size_t i
= 0, n
= aInvalidRegion
.size(); i
< n
; ++i
)
695 delete aInvalidRegion
[ i
];
696 aInvalidRegion
.clear();
697 aInvalidRegion
.push_back( new Rectangle( Point( 0, 0 ), GetOutputSizePixel() ) );
700 Window::Invalidate( nFlags
);
705 void BrowserDataWin::Invalidate( const Rectangle
& rRect
, sal_uInt16 nFlags
)
707 if ( !GetUpdateMode() )
708 aInvalidRegion
.push_back( new Rectangle( rRect
) );
710 Window::Invalidate( rRect
, nFlags
);
713 BrowserScrollBar::~BrowserScrollBar()
718 void BrowserScrollBar::dispose()
721 ScrollBar::dispose();
724 void BrowserScrollBar::Tracking( const TrackingEvent
& rTEvt
)
726 sal_uLong nPos
= GetThumbPos();
727 if ( nPos
!= _nLastPos
)
729 OUString
aTip( OUString::number(nPos
) );
731 if ( !_pDataWin
->GetRealRowCount().isEmpty() )
732 aTip
+= _pDataWin
->GetRealRowCount();
734 aTip
+= OUString::number(GetRangeMax());
736 Rectangle
aRect(GetPointerPosPixel(), Size(GetTextWidth(aTip
), GetTextHeight()));
738 Help::UpdateTip( _nTip
, this, aRect
, aTip
);
740 _nTip
= Help::ShowTip( this, aRect
, aTip
);
744 ScrollBar::Tracking( rTEvt
);
749 void BrowserScrollBar::EndScroll()
752 Help::HideTip( _nTip
);
754 ScrollBar::EndScroll();
758 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */