xref: /trunk/main/svtools/source/brwbox/datwin.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 
31 #include "datwin.hxx"
32 
33 #ifndef GCC
34 #endif
35 
36 #ifndef _APP_HXX //autogen
37 #include <vcl/svapp.hxx>
38 #endif
39 
40 #ifndef _HELP_HXX
41 #include <vcl/help.hxx>
42 #endif
43 #ifndef _IMAGE_HXX
44 #include <vcl/image.hxx>
45 #endif
46 
47 #include <tools/debug.hxx>
48 
49 DECLARE_LIST( BrowserColumns, BrowserColumn* )
50 
51 //===================================================================
52 void ButtonFrame::Draw( OutputDevice& rDev )
53 {
54     Color aOldFillColor = rDev.GetFillColor();
55     Color aOldLineColor = rDev.GetLineColor();
56 
57     const StyleSettings &rSettings = rDev.GetSettings().GetStyleSettings();
58     Color aColLight( rSettings.GetLightColor() );
59     Color aColShadow( rSettings.GetShadowColor() );
60     Color aColFace( rSettings.GetFaceColor() );
61 
62     rDev.SetLineColor( aColFace );
63     rDev.SetFillColor( aColFace );
64     rDev.DrawRect( aRect );
65 
66     if( rDev.GetOutDevType() == OUTDEV_WINDOW )
67     {
68         Window *pWin = (Window*) &rDev;
69         if( bPressed )
70             pWin->DrawSelectionBackground( aRect, 0, sal_True, sal_False, sal_False );
71     }
72     else
73     {
74         rDev.SetLineColor( bPressed ? aColShadow : aColLight );
75         rDev.DrawLine( aRect.TopLeft(), Point( aRect.Right(), aRect.Top() ) );
76         rDev.DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom() - 1 ) );
77         rDev.SetLineColor( bPressed ? aColLight : aColShadow );
78         rDev.DrawLine( aRect.BottomRight(), Point( aRect.Right(), aRect.Top() ) );
79         rDev.DrawLine( aRect.BottomRight(), Point( aRect.Left(), aRect.Bottom() ) );
80     }
81 
82     if ( aText.Len() )
83     {
84         String aVal = rDev.GetEllipsisString(aText,aInnerRect.GetWidth() - 2*MIN_COLUMNWIDTH);
85 
86         Font aFont( rDev.GetFont() );
87         sal_Bool bOldTransp = aFont.IsTransparent();
88         if ( !bOldTransp )
89         {
90             aFont.SetTransparent( sal_True );
91             rDev.SetFont( aFont );
92         }
93 
94         Color aOldColor = rDev.GetTextColor();
95         if (m_bDrawDisabled)
96             rDev.SetTextColor(rSettings.GetDisableColor());
97 
98         rDev.DrawText( Point(
99             ( aInnerRect.Left() + aInnerRect.Right() ) / 2 - ( rDev.GetTextWidth(aVal) / 2 ),
100             aInnerRect.Top() ), aVal );
101 
102         // restore settings
103         if ( !bOldTransp )
104         {
105             aFont.SetTransparent(sal_False);
106             rDev.SetFont( aFont );
107         }
108         if (m_bDrawDisabled)
109             rDev.SetTextColor(aOldColor);
110     }
111 
112     if ( bCurs )
113     {
114         rDev.SetLineColor( Color( COL_BLACK ) );
115         rDev.SetFillColor();
116         rDev.DrawRect( Rectangle(
117             Point( aRect.Left(), aRect.Top() ), Point( aRect.Right(), aRect.Bottom() ) ) );
118     }
119 
120     rDev.SetLineColor( aOldLineColor );
121     rDev.SetFillColor( aOldFillColor );
122 }
123 
124 //-------------------------------------------------------------------
125 
126 BrowserColumn::BrowserColumn( sal_uInt16 nItemId, const class Image &rImage,
127                               const String& rTitle, sal_uLong nWidthPixel, const Fraction& rCurrentZoom,
128                               HeaderBarItemBits nFlags )
129 :   _nId( nItemId ),
130     _nWidth( nWidthPixel ),
131     _aImage( rImage ),
132     _aTitle( rTitle ),
133     _bFrozen( sal_False ),
134     _nFlags( nFlags )
135 {
136     double n = (double)_nWidth;
137     n *= (double)rCurrentZoom.GetDenominator();
138     n /= (double)rCurrentZoom.GetNumerator();
139     _nOriginalWidth = n>0 ? (long)(n+0.5) : -(long)(-n+0.5);
140 }
141 
142 BrowserColumn::~BrowserColumn()
143 {
144 }
145 
146 //-------------------------------------------------------------------
147 
148 void BrowserColumn::SetWidth(sal_uLong nNewWidthPixel, const Fraction& rCurrentZoom)
149 {
150     _nWidth = nNewWidthPixel;
151     double n = (double)_nWidth;
152     n *= (double)rCurrentZoom.GetDenominator();
153     n /= (double)rCurrentZoom.GetNumerator();
154     _nOriginalWidth = n>0 ? (long)(n+0.5) : -(long)(-n+0.5);
155 }
156 
157 //-------------------------------------------------------------------
158 
159 void BrowserColumn::Draw( BrowseBox& rBox, OutputDevice& rDev, const Point& rPos, sal_Bool bCurs  )
160 {
161     if ( _nId == 0 )
162     {
163         // paint handle column
164         ButtonFrame( rPos, Size( Width()-1, rBox.GetDataRowHeight()-1 ),
165                      String(), sal_False, bCurs,
166                      0 != (BROWSER_COLUMN_TITLEABBREVATION&_nFlags) ).Draw( rDev );
167         Color aOldLineColor = rDev.GetLineColor();
168         rDev.SetLineColor( Color( COL_BLACK ) );
169         rDev.DrawLine(
170             Point( rPos.X(), rPos.Y()+rBox.GetDataRowHeight()-1 ),
171             Point( rPos.X() + Width() - 1, rPos.Y()+rBox.GetDataRowHeight()-1 ) );
172         rDev.DrawLine(
173             Point( rPos.X() + Width() - 1, rPos.Y() ),
174             Point( rPos.X() + Width() - 1, rPos.Y()+rBox.GetDataRowHeight()-1 ) );
175         rDev.SetLineColor( aOldLineColor );
176 
177         rBox.DoPaintField( rDev,
178             Rectangle(
179                 Point( rPos.X() + 2, rPos.Y() + 2 ),
180                 Size( Width()-1, rBox.GetDataRowHeight()-1 ) ),
181             GetId(),
182             BrowseBox::BrowserColumnAccess() );
183     }
184     else
185     {
186         // paint data column
187         long nWidth = Width() == LONG_MAX ? rBox.GetDataWindow().GetSizePixel().Width() : Width();
188 
189         rBox.DoPaintField( rDev,
190             Rectangle(
191                 Point( rPos.X() + MIN_COLUMNWIDTH, rPos.Y() ),
192                 Size( nWidth-2*MIN_COLUMNWIDTH, rBox.GetDataRowHeight()-1 ) ),
193             GetId(),
194             BrowseBox::BrowserColumnAccess() );
195     }
196 }
197 
198 //-------------------------------------------------------------------
199 
200 void BrowserColumn::ZoomChanged(const Fraction& rNewZoom)
201 {
202     double n = (double)_nOriginalWidth;
203     n *= (double)rNewZoom.GetNumerator();
204     n /= (double)rNewZoom.GetDenominator();
205 
206     _nWidth = n>0 ? (long)(n+0.5) : -(long)(-n+0.5);
207 }
208 
209 //-------------------------------------------------------------------
210 
211 BrowserDataWin::BrowserDataWin( BrowseBox* pParent )
212     :Control( pParent, WinBits(WB_CLIPCHILDREN) )
213     ,DragSourceHelper( this )
214     ,DropTargetHelper( this )
215     ,pHeaderBar( 0 )
216     ,pEventWin( pParent )
217     ,pCornerWin( 0 )
218     ,pDtorNotify( 0 )
219     ,bInPaint( sal_False )
220     ,bInCommand( sal_False )
221     ,bNoScrollBack( sal_False )
222     ,bNoHScroll( sal_False )
223     ,bNoVScroll( sal_False )
224     ,bUpdateMode( sal_True )
225     ,bResizeOnPaint( sal_False )
226     ,bUpdateOnUnlock( sal_False )
227     ,bInUpdateScrollbars( sal_False )
228     ,bHadRecursion( sal_False )
229     ,bOwnDataChangedHdl( sal_False )
230     ,bCallingDropCallback( sal_False )
231     ,nUpdateLock( 0 )
232     ,nCursorHidden( 0 )
233     ,m_nDragRowDividerLimit( 0 )
234     ,m_nDragRowDividerOffset( 0 )
235 {
236     aMouseTimer.SetTimeoutHdl( LINK( this, BrowserDataWin, RepeatedMouseMove ) );
237     aMouseTimer.SetTimeout( 100 );
238 }
239 
240 //-------------------------------------------------------------------
241 BrowserDataWin::~BrowserDataWin()
242 {
243     if( pDtorNotify )
244         *pDtorNotify = sal_True;
245 }
246 
247 //-------------------------------------------------------------------
248 void BrowserDataWin::LeaveUpdateLock()
249 {
250     if ( !--nUpdateLock )
251     {
252         DoOutstandingInvalidations();
253         if (bUpdateOnUnlock )
254         {
255             Control::Update();
256             bUpdateOnUnlock = sal_False;
257         }
258     }
259 }
260 
261 //-------------------------------------------------------------------
262 void InitSettings_Impl( Window *pWin,
263                      sal_Bool bFont, sal_Bool bForeground, sal_Bool bBackground )
264 {
265     const StyleSettings& rStyleSettings =
266             pWin->GetSettings().GetStyleSettings();
267 
268     if ( bFont )
269     {
270         Font aFont = rStyleSettings.GetFieldFont();
271         if ( pWin->IsControlFont() )
272             aFont.Merge( pWin->GetControlFont() );
273         pWin->SetZoomedPointFont( aFont );
274     }
275 
276     if ( bFont || bForeground )
277     {
278         Color aTextColor = rStyleSettings.GetWindowTextColor();
279         if ( pWin->IsControlForeground() )
280             aTextColor = pWin->GetControlForeground();
281         pWin->SetTextColor( aTextColor );
282     }
283 
284     if ( bBackground )
285     {
286         if( pWin->IsControlBackground() )
287             pWin->SetBackground( pWin->GetControlBackground() );
288         else
289             pWin->SetBackground( rStyleSettings.GetWindowColor() );
290     }
291 }
292 
293 //-------------------------------------------------------------------
294 void BrowserDataWin::Update()
295 {
296     if ( !nUpdateLock )
297         Control::Update();
298     else
299         bUpdateOnUnlock = sal_True;
300 }
301 
302 //-------------------------------------------------------------------
303 void BrowserDataWin::DataChanged( const DataChangedEvent& rDCEvt )
304 {
305     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
306          (rDCEvt.GetFlags() & SETTINGS_STYLE) )
307     {
308         if( !bOwnDataChangedHdl )
309         {
310             InitSettings_Impl( this, sal_True, sal_True, sal_True );
311             Invalidate();
312             InitSettings_Impl( GetParent(), sal_True, sal_True, sal_True );
313             GetParent()->Invalidate();
314             GetParent()->Resize();
315         }
316     }
317     else
318         Control::DataChanged( rDCEvt );
319 }
320 
321 //-------------------------------------------------------------------
322 void BrowserDataWin::Paint( const Rectangle& rRect )
323 {
324     if ( !nUpdateLock && GetUpdateMode() )
325     {
326         if ( bInPaint )
327         {
328             aInvalidRegion.Insert( new Rectangle( rRect ) );
329             return;
330         }
331         bInPaint = sal_True;
332         ( (BrowseBox*) GetParent() )->PaintData( *this, rRect );
333         bInPaint = sal_False;
334         DoOutstandingInvalidations();
335     }
336     else
337         aInvalidRegion.Insert( new Rectangle( rRect ) );
338 }
339 
340 //-------------------------------------------------------------------
341 
342 BrowseEvent BrowserDataWin::CreateBrowseEvent( const Point& rPosPixel )
343 {
344     BrowseBox *pBox = GetParent();
345 
346     // seek to row under mouse
347     long nRelRow = rPosPixel.Y() < 0
348             ? -1
349             : rPosPixel.Y() / pBox->GetDataRowHeight();
350     long nRow = nRelRow < 0 ? -1 : nRelRow + pBox->nTopRow;
351 
352     // find column under mouse
353     long nMouseX = rPosPixel.X();
354     long nColX = 0;
355     sal_uInt16 nCol;
356     for ( nCol = 0;
357           nCol < pBox->pCols->Count() && nColX < GetSizePixel().Width();
358           ++nCol )
359         if ( pBox->pCols->GetObject(nCol)->IsFrozen() || nCol >= pBox->nFirstCol )
360         {
361             nColX += pBox->pCols->GetObject(nCol)->Width();
362             if ( nMouseX < nColX )
363                 break;
364         }
365     sal_uInt16 nColId = BROWSER_INVALIDID;
366     if ( nCol < pBox->pCols->Count() )
367         nColId = pBox->pCols->GetObject(nCol)->GetId();
368 
369     // compute the field rectangle and field relative MouseEvent
370     Rectangle aFieldRect;
371     if ( nCol < pBox->pCols->Count() )
372     {
373         nColX -= pBox->pCols->GetObject(nCol)->Width();
374         aFieldRect = Rectangle(
375             Point( nColX, nRelRow * pBox->GetDataRowHeight() ),
376             Size( pBox->pCols->GetObject(nCol)->Width(),
377                   pBox->GetDataRowHeight() ) );
378     }
379 
380     // assemble and return the BrowseEvent
381     return BrowseEvent( this, nRow, nCol, nColId, aFieldRect );
382 }
383 
384 //-------------------------------------------------------------------
385 sal_Int8 BrowserDataWin::AcceptDrop( const AcceptDropEvent& _rEvt )
386 {
387     bCallingDropCallback = sal_True;
388     sal_Int8 nReturn = DND_ACTION_NONE;
389     nReturn = GetParent()->AcceptDrop( BrowserAcceptDropEvent( this, _rEvt ) );
390     bCallingDropCallback = sal_False;
391     return nReturn;
392 }
393 
394 //-------------------------------------------------------------------
395 sal_Int8 BrowserDataWin::ExecuteDrop( const ExecuteDropEvent& _rEvt )
396 {
397     bCallingDropCallback = sal_True;
398     sal_Int8 nReturn = DND_ACTION_NONE;
399     nReturn = GetParent()->ExecuteDrop( BrowserExecuteDropEvent( this, _rEvt ) );
400     bCallingDropCallback = sal_False;
401     return nReturn;
402 }
403 
404 //-------------------------------------------------------------------
405 void BrowserDataWin::StartDrag( sal_Int8 _nAction, const Point& _rPosPixel )
406 {
407     if ( !GetParent()->bRowDividerDrag )
408     {
409         Point aEventPos( _rPosPixel );
410         aEventPos.Y() += GetParent()->GetTitleHeight();
411         GetParent()->StartDrag( _nAction, aEventPos );
412     }
413 }
414 
415 //-------------------------------------------------------------------
416 void BrowserDataWin::Command( const CommandEvent& rEvt )
417 {
418     // Scrollmaus-Event?
419     BrowseBox *pBox = GetParent();
420     if ( ( (rEvt.GetCommand() == COMMAND_WHEEL) ||
421            (rEvt.GetCommand() == COMMAND_STARTAUTOSCROLL) ||
422            (rEvt.GetCommand() == COMMAND_AUTOSCROLL) ) &&
423          ( HandleScrollCommand( rEvt, &pBox->aHScroll, pBox->pVScroll ) ) )
424       return;
425 
426     Point aEventPos( rEvt.GetMousePosPixel() );
427     long nRow = pBox->GetRowAtYPosPixel( aEventPos.Y(), sal_False);
428     MouseEvent aMouseEvt( aEventPos, 1, MOUSE_SELECT, MOUSE_LEFT );
429     if ( COMMAND_CONTEXTMENU == rEvt.GetCommand() && rEvt.IsMouseEvent() &&
430          nRow < pBox->GetRowCount() && !pBox->IsRowSelected(nRow) )
431     {
432         sal_Bool bDeleted = sal_False;
433         pDtorNotify = &bDeleted;
434         bInCommand = sal_True;
435         MouseButtonDown( aMouseEvt );
436         if( bDeleted )
437             return;
438         MouseButtonUp( aMouseEvt );
439         if( bDeleted )
440             return;
441         pDtorNotify = 0;
442         bInCommand = sal_False;
443     }
444 
445     aEventPos.Y() += GetParent()->GetTitleHeight();
446     CommandEvent aEvt( aEventPos, rEvt.GetCommand(),
447                         rEvt.IsMouseEvent(), rEvt.GetData() );
448     bInCommand = sal_True;
449     sal_Bool bDeleted = sal_False;
450     pDtorNotify = &bDeleted;
451     GetParent()->Command( aEvt );
452     if( bDeleted )
453         return;
454     pDtorNotify = 0;
455     bInCommand = sal_False;
456 
457     if ( COMMAND_STARTDRAG == rEvt.GetCommand() )
458         MouseButtonUp( aMouseEvt );
459 
460     Control::Command( rEvt );
461 }
462 
463 //-------------------------------------------------------------------
464 
465 sal_Bool BrowserDataWin::ImplRowDividerHitTest( const BrowserMouseEvent& _rEvent )
466 {
467     if ( ! (  GetParent()->IsInteractiveRowHeightEnabled()
468            && ( _rEvent.GetRow() >= 0 )
469            && ( _rEvent.GetRow() < GetParent()->GetRowCount() )
470            && ( _rEvent.GetColumnId() == 0 )
471            )
472        )
473        return sal_False;
474 
475     long nDividerDistance = GetParent()->GetDataRowHeight() - ( _rEvent.GetPosPixel().Y() % GetParent()->GetDataRowHeight() );
476     return ( nDividerDistance <= 4 );
477 }
478 
479 //-------------------------------------------------------------------
480 
481 void BrowserDataWin::MouseButtonDown( const MouseEvent& rEvt )
482 {
483     aLastMousePos = OutputToScreenPixel( rEvt.GetPosPixel() );
484 
485     BrowserMouseEvent aBrowserEvent( this, rEvt );
486     if ( ( aBrowserEvent.GetClicks() == 1 ) && ImplRowDividerHitTest( aBrowserEvent ) )
487     {
488         StartRowDividerDrag( aBrowserEvent.GetPosPixel() );
489         return;
490     }
491 
492     GetParent()->MouseButtonDown( BrowserMouseEvent( this, rEvt ) );
493 }
494 
495 //-------------------------------------------------------------------
496 
497 void BrowserDataWin::MouseMove( const MouseEvent& rEvt )
498 {
499     // Pseudo MouseMoves verhindern
500     Point aNewPos = OutputToScreenPixel( rEvt.GetPosPixel() );
501     if ( ( aNewPos == aLastMousePos ) )
502         return;
503     aLastMousePos = aNewPos;
504 
505     // transform to a BrowseEvent
506     BrowserMouseEvent aBrowserEvent( this, rEvt );
507     GetParent()->MouseMove( aBrowserEvent );
508 
509     // pointer shape
510     PointerStyle ePointerStyle = POINTER_ARROW;
511     if ( ImplRowDividerHitTest( aBrowserEvent ) )
512         ePointerStyle = POINTER_VSIZEBAR;
513     SetPointer( Pointer( ePointerStyle ) );
514 
515     // dragging out of the visible area?
516     if ( rEvt.IsLeft() &&
517          ( rEvt.GetPosPixel().Y() > GetSizePixel().Height() ||
518            rEvt.GetPosPixel().Y() < 0 ) )
519     {
520         // repeat the event
521         aRepeatEvt = rEvt;
522         aMouseTimer.Start();
523     }
524     else
525         // killing old repeat-event
526         if ( aMouseTimer.IsActive() )
527             aMouseTimer.Stop();
528 }
529 
530 //-------------------------------------------------------------------
531 
532 IMPL_LINK_INLINE_START( BrowserDataWin, RepeatedMouseMove, void *, EMPTYARG )
533 {
534     GetParent()->MouseMove( BrowserMouseEvent( this, aRepeatEvt ) );
535     return 0;
536 }
537 IMPL_LINK_INLINE_END( BrowserDataWin, RepeatedMouseMove, void *, EMPTYARG )
538 
539 //-------------------------------------------------------------------
540 
541 void BrowserDataWin::MouseButtonUp( const MouseEvent& rEvt )
542 {
543     // Pseudo MouseMoves verhindern
544     Point aNewPos = OutputToScreenPixel( rEvt.GetPosPixel() );
545     aLastMousePos = aNewPos;
546 
547     // Move an die aktuelle Position simulieren
548     MouseMove( rEvt );
549 
550     // eigentliches Up-Handling
551     ReleaseMouse();
552     if ( aMouseTimer.IsActive() )
553         aMouseTimer.Stop();
554     GetParent()->MouseButtonUp( BrowserMouseEvent( this, rEvt ) );
555 }
556 
557 //-------------------------------------------------------------------
558 
559 void BrowserDataWin::StartRowDividerDrag( const Point& _rStartPos )
560 {
561     long nDataRowHeight = GetParent()->GetDataRowHeight();
562     // the exact separation pos of the two rows
563     long nDragRowDividerCurrentPos = _rStartPos.Y();
564     if ( ( nDragRowDividerCurrentPos % nDataRowHeight ) > nDataRowHeight / 2 )
565         nDragRowDividerCurrentPos += nDataRowHeight;
566     nDragRowDividerCurrentPos /= nDataRowHeight;
567     nDragRowDividerCurrentPos *= nDataRowHeight;
568 
569     m_nDragRowDividerOffset = nDragRowDividerCurrentPos - _rStartPos.Y();
570 
571     m_nDragRowDividerLimit = nDragRowDividerCurrentPos - nDataRowHeight;
572 
573     GetParent()->bRowDividerDrag = sal_True;
574     GetParent()->ImplStartTracking();
575 
576     Rectangle aDragSplitRect( 0, m_nDragRowDividerLimit, GetOutputSizePixel().Width(), nDragRowDividerCurrentPos );
577     ShowTracking( aDragSplitRect, SHOWTRACK_SMALL );
578 
579     StartTracking();
580 }
581 
582 //-------------------------------------------------------------------
583 
584 void BrowserDataWin::Tracking( const TrackingEvent& rTEvt )
585 {
586     if ( !GetParent()->bRowDividerDrag )
587         return;
588 
589     Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
590     // stop resizing at our bottom line
591     if ( aMousePos.Y() > GetOutputSizePixel().Height() )
592         aMousePos.Y() = GetOutputSizePixel().Height();
593 
594     if ( rTEvt.IsTrackingEnded() )
595     {
596         HideTracking();
597         GetParent()->bRowDividerDrag = sal_False;
598         GetParent()->ImplEndTracking();
599 
600         if ( !rTEvt.IsTrackingCanceled() )
601         {
602             long nNewRowHeight = aMousePos.Y() + m_nDragRowDividerOffset - m_nDragRowDividerLimit;
603 
604             // care for minimum row height
605             if ( nNewRowHeight < GetParent()->QueryMinimumRowHeight() )
606                 nNewRowHeight = GetParent()->QueryMinimumRowHeight();
607 
608             GetParent()->SetDataRowHeight( nNewRowHeight );
609             GetParent()->RowHeightChanged();
610         }
611     }
612     else
613     {
614         GetParent()->ImplTracking();
615 
616         long nDragRowDividerCurrentPos = aMousePos.Y() + m_nDragRowDividerOffset;
617 
618         // care for minimum row height
619         if ( nDragRowDividerCurrentPos < m_nDragRowDividerLimit + GetParent()->QueryMinimumRowHeight() )
620             nDragRowDividerCurrentPos = m_nDragRowDividerLimit + GetParent()->QueryMinimumRowHeight();
621 
622         Rectangle aDragSplitRect( 0, m_nDragRowDividerLimit, GetOutputSizePixel().Width(), nDragRowDividerCurrentPos );
623         ShowTracking( aDragSplitRect, SHOWTRACK_SMALL );
624     }
625 }
626 
627 //-------------------------------------------------------------------
628 
629 void BrowserDataWin::KeyInput( const KeyEvent& rEvt )
630 {
631     // pass to parent window
632     if ( !GetParent()->ProcessKey( rEvt ) )
633         Control::KeyInput( rEvt );
634 }
635 
636 //-------------------------------------------------------------------
637 
638 void BrowserDataWin::RequestHelp( const HelpEvent& rHEvt )
639 {
640     pEventWin = this;
641     GetParent()->RequestHelp( rHEvt );
642     pEventWin = GetParent();
643 }
644 
645 //===================================================================
646 
647 BrowseEvent::BrowseEvent( Window* pWindow,
648                           long nAbsRow, sal_uInt16 nColumn, sal_uInt16 nColumnId,
649                           const Rectangle& rRect ):
650     pWin(pWindow),
651     nRow(nAbsRow),
652     aRect(rRect),
653     nCol(nColumn),
654     nColId(nColumnId)
655 {
656 }
657 
658 //===================================================================
659 BrowserMouseEvent::BrowserMouseEvent( BrowserDataWin *pWindow,
660                           const MouseEvent& rEvt ):
661     MouseEvent(rEvt),
662     BrowseEvent( pWindow->CreateBrowseEvent( rEvt.GetPosPixel() ) )
663 {
664 }
665 
666 //-------------------------------------------------------------------
667 
668 BrowserMouseEvent::BrowserMouseEvent( Window *pWindow, const MouseEvent& rEvt,
669                           long nAbsRow, sal_uInt16 nColumn, sal_uInt16 nColumnId,
670                           const Rectangle& rRect ):
671     MouseEvent(rEvt),
672     BrowseEvent( pWindow, nAbsRow, nColumn, nColumnId, rRect )
673 {
674 }
675 
676 //===================================================================
677 
678 BrowserAcceptDropEvent::BrowserAcceptDropEvent( BrowserDataWin *pWindow, const AcceptDropEvent& rEvt )
679     :AcceptDropEvent(rEvt)
680     ,BrowseEvent( pWindow->CreateBrowseEvent( rEvt.maPosPixel ) )
681 {
682 }
683 
684 //===================================================================
685 
686 BrowserExecuteDropEvent::BrowserExecuteDropEvent( BrowserDataWin *pWindow, const ExecuteDropEvent& rEvt )
687     :ExecuteDropEvent(rEvt)
688     ,BrowseEvent( pWindow->CreateBrowseEvent( rEvt.maPosPixel ) )
689 {
690 }
691 
692 //===================================================================
693 
694 //-------------------------------------------------------------------
695 
696 void BrowserDataWin::SetUpdateMode( sal_Bool bMode )
697 {
698     DBG_ASSERT( !bUpdateMode || aInvalidRegion.Count() == 0,
699                 "invalid region not empty" );
700     if ( bMode == bUpdateMode )
701         return;
702 
703     bUpdateMode = bMode;
704     if ( bMode )
705         DoOutstandingInvalidations();
706 }
707 
708 //-------------------------------------------------------------------
709 void BrowserDataWin::DoOutstandingInvalidations()
710 {
711     for ( Rectangle* pRect = aInvalidRegion.First();
712           pRect;
713           pRect = aInvalidRegion.Next() )
714     {
715         Control::Invalidate( *pRect );
716         delete pRect;
717     }
718     aInvalidRegion.Clear();
719 }
720 
721 //-------------------------------------------------------------------
722 
723 void BrowserDataWin::Invalidate( sal_uInt16 nFlags )
724 {
725     if ( !GetUpdateMode() )
726     {
727         for ( Rectangle* pRect = aInvalidRegion.First();
728               pRect;
729               pRect = aInvalidRegion.Next() )
730             delete pRect;
731         aInvalidRegion.Clear();
732         aInvalidRegion.Insert( new Rectangle( Point( 0, 0 ), GetOutputSizePixel() ) );
733     }
734     else
735         Window::Invalidate( nFlags );
736 }
737 
738 //-------------------------------------------------------------------
739 
740 void BrowserDataWin::Invalidate( const Rectangle& rRect, sal_uInt16 nFlags )
741 {
742     if ( !GetUpdateMode() )
743         aInvalidRegion.Insert( new Rectangle( rRect ) );
744     else
745         Window::Invalidate( rRect, nFlags );
746 }
747 
748 //===================================================================
749 
750 void BrowserScrollBar::Tracking( const TrackingEvent& rTEvt )
751 {
752     sal_uLong nPos = GetThumbPos();
753     if ( nPos != _nLastPos )
754     {
755         String aTip( String::CreateFromInt32(nPos) );
756         aTip += '/';
757         if ( _pDataWin->GetRealRowCount().Len() )
758             aTip += _pDataWin->GetRealRowCount();
759         else
760             aTip += String::CreateFromInt32(GetRangeMax());
761 
762         Rectangle aRect( GetPointerPosPixel(), Size( GetTextHeight(), GetTextWidth( aTip ) ) );
763         if ( _nTip )
764             Help::UpdateTip( _nTip, this, aRect, aTip );
765         else
766             _nTip = Help::ShowTip( this, aRect, aTip );
767         _nLastPos = nPos;
768     }
769 
770     ScrollBar::Tracking( rTEvt );
771 }
772 
773 //-------------------------------------------------------------------
774 
775 void BrowserScrollBar::EndScroll()
776 {
777     if ( _nTip )
778         Help::HideTip( _nTip );
779     _nTip = 0;
780     ScrollBar::EndScroll();
781 }
782 
783 
784