xref: /aoo41x/main/svtools/source/brwbox/datwin.cxx (revision cdf0e10c)
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