xref: /aoo41x/main/svtools/source/brwbox/brwbox2.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 #include <tools/debug.hxx>
31 #include <svtools/brwbox.hxx>
32 #include "datwin.hxx"
33 #include <svtools/colorcfg.hxx>
34 #include <vcl/salgtype.hxx>
35 
36 #ifndef GCC
37 #endif
38 #include <tools/multisel.hxx>
39 #include <algorithm>
40 
41 using namespace ::com::sun::star::datatransfer;
42 
43 #define getDataWindow() ((BrowserDataWin*)pDataWin)
44 
45 
46 //===================================================================
47 
48 DBG_NAMEEX(BrowseBox)
49 
50 //===================================================================
51 
52 extern const char* BrowseBoxCheckInvariants( const void * pVoid );
53 
54 DECLARE_LIST( BrowserColumns, BrowserColumn* )
55 
56 //===================================================================
57 
58 void BrowseBox::StartDrag( sal_Int8 /* _nAction */, const Point& /* _rPosPixel */ )
59 {
60 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
61 	// not interested in this event
62 }
63 
64 //===================================================================
65 
66 sal_Int8 BrowseBox::AcceptDrop( const AcceptDropEvent& _rEvt )
67 {
68 	BrowserDataWin* pDataWindow = static_cast<BrowserDataWin*>(pDataWin);
69 	AcceptDropEvent aTransformed( _rEvt );
70 	aTransformed.maPosPixel = pDataWindow->ScreenToOutputPixel( OutputToScreenPixel( _rEvt.maPosPixel ) );
71 	return pDataWindow->AcceptDrop( aTransformed );
72 }
73 
74 //===================================================================
75 
76 sal_Int8 BrowseBox::ExecuteDrop( const ExecuteDropEvent& _rEvt )
77 {
78 	BrowserDataWin* pDataWindow = static_cast<BrowserDataWin*>(pDataWin);
79 	ExecuteDropEvent aTransformed( _rEvt );
80 	aTransformed.maPosPixel = pDataWindow->ScreenToOutputPixel( OutputToScreenPixel( _rEvt.maPosPixel ) );
81 	return pDataWindow->ExecuteDrop( aTransformed );
82 }
83 
84 //===================================================================
85 
86 sal_Int8 BrowseBox::AcceptDrop( const BrowserAcceptDropEvent& )
87 {
88 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
89 	// not interested in this event
90 	return DND_ACTION_NONE;
91 }
92 
93 //===================================================================
94 
95 sal_Int8 BrowseBox::ExecuteDrop( const BrowserExecuteDropEvent& )
96 {
97 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
98 	// not interested in this event
99 	return DND_ACTION_NONE;
100 }
101 
102 //===================================================================
103 
104 void* BrowseBox::implGetDataFlavors() const
105 {
106 	if (static_cast<BrowserDataWin*>(pDataWin)->bCallingDropCallback)
107 		return &static_cast<BrowserDataWin*>(pDataWin)->GetDataFlavorExVector();
108 	return &GetDataFlavorExVector();
109 }
110 
111 //===================================================================
112 
113 sal_Bool BrowseBox::IsDropFormatSupported( SotFormatStringId _nFormat )
114 {
115 	if ( static_cast< BrowserDataWin* >( pDataWin )->bCallingDropCallback )
116 		return static_cast< BrowserDataWin* >( pDataWin )->IsDropFormatSupported( _nFormat );
117 
118 	return DropTargetHelper::IsDropFormatSupported( _nFormat );
119 }
120 
121 //===================================================================
122 
123 sal_Bool BrowseBox::IsDropFormatSupported( SotFormatStringId _nFormat ) const
124 {
125 	return const_cast< BrowseBox* >( this )->IsDropFormatSupported( _nFormat );
126 }
127 
128 //===================================================================
129 
130 sal_Bool BrowseBox::IsDropFormatSupported( const DataFlavor& _rFlavor )
131 {
132 	if ( static_cast< BrowserDataWin* >( pDataWin )->bCallingDropCallback )
133 		return static_cast< BrowserDataWin* >( pDataWin )->IsDropFormatSupported( _rFlavor );
134 
135 	return DropTargetHelper::IsDropFormatSupported( _rFlavor );
136 }
137 
138 //===================================================================
139 
140 sal_Bool BrowseBox::IsDropFormatSupported( const DataFlavor& _rFlavor ) const
141 {
142 	return const_cast< BrowseBox* >( this )->IsDropFormatSupported( _rFlavor );
143 }
144 
145 //===================================================================
146 
147 void BrowseBox::Command( const CommandEvent& rEvt )
148 {
149 	if ( !getDataWindow()->bInCommand )
150 		Control::Command( rEvt );
151 }
152 
153 //===================================================================
154 
155 bool BrowseBox::IsInCommandEvent() const
156 {
157 	return getDataWindow()->bInCommand;
158 }
159 
160 //===================================================================
161 
162 void BrowseBox::StateChanged( StateChangedType nStateChange )
163 {
164     Control::StateChanged( nStateChange );
165 
166     if ( STATE_CHANGE_MIRRORING == nStateChange )
167     {
168         getDataWindow()->EnableRTL( IsRTLEnabled() );
169 
170         HeaderBar* pHeaderBar = getDataWindow()->pHeaderBar;
171         if ( pHeaderBar )
172             pHeaderBar->EnableRTL( IsRTLEnabled() );
173         aHScroll.EnableRTL( IsRTLEnabled() );
174         if( pVScroll )
175             pVScroll->EnableRTL( IsRTLEnabled() );
176         Resize();
177     }
178 	else if ( STATE_CHANGE_INITSHOW == nStateChange )
179 	{
180 		bBootstrapped = sal_True; // muss zuerst gesetzt werden!
181 
182 		Resize();
183 		if ( bMultiSelection )
184 			uRow.pSel->SetTotalRange( Range( 0, nRowCount - 1 ) );
185 		if ( nRowCount == 0 )
186 			nCurRow = BROWSER_ENDOFSELECTION;
187 		else if ( nCurRow == BROWSER_ENDOFSELECTION )
188 			nCurRow = 0;
189 
190 
191 		if ( HasFocus() )
192 		{
193 			bSelectionIsVisible = sal_True;
194 			bHasFocus = sal_True;
195 		}
196 		UpdateScrollbars();
197 		AutoSizeLastColumn();
198 		CursorMoved();
199 	}
200 	else if (STATE_CHANGE_ZOOM == nStateChange)
201 	{
202 		pDataWin->SetZoom(GetZoom());
203 		HeaderBar* pHeaderBar = getDataWindow()->pHeaderBar;
204 		if (pHeaderBar)
205 			pHeaderBar->SetZoom(GetZoom());
206 
207 		// let the cols calc their new widths and adjust the header bar
208 		for ( sal_uInt16 nPos = 0; nPos < pCols->Count(); ++nPos )
209 		{
210 			pCols->GetObject(nPos)->ZoomChanged(GetZoom());
211 			if ( pHeaderBar )
212 				pHeaderBar->SetItemSize( pCols->GetObject(nPos)->GetId(), pCols->GetObject(nPos)->Width() );
213 		}
214 
215 		// all our controls have to be repositioned
216 		Resize();
217 	}
218 	else if (STATE_CHANGE_ENABLE == nStateChange)
219 	{
220 		// do we have a handle column?
221 		sal_Bool bHandleCol	= pCols->Count() && (0 == pCols->GetObject(0)->GetId());
222 		// do we have a header bar
223 		sal_Bool bHeaderBar = (NULL != static_cast<BrowserDataWin&>(GetDataWindow()).pHeaderBar);
224 
225 		if	(	nTitleLines
226 			&&	(	!bHeaderBar
227 				||	bHandleCol
228 				)
229 			)
230 			// we draw the text in our header bar in a color dependent on the enabled state. So if this state changed
231 			// -> redraw
232 			Invalidate(Rectangle(Point(0, 0), Size(GetOutputSizePixel().Width(), GetTitleHeight() - 1)));
233 	}
234 }
235 
236 //===================================================================
237 
238 void BrowseBox::Select()
239 {
240 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
241 }
242 
243 //-------------------------------------------------------------------
244 
245 void BrowseBox::DoubleClick( const BrowserMouseEvent & )
246 {
247 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
248 }
249 
250 //-------------------------------------------------------------------
251 
252 long BrowseBox::QueryMinimumRowHeight()
253 {
254 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
255     return CalcZoom( 5 );
256 }
257 
258 //-------------------------------------------------------------------
259 
260 void BrowseBox::ImplStartTracking()
261 {
262 	DBG_CHKTHIS( BrowseBox, BrowseBoxCheckInvariants );
263 }
264 
265 //-------------------------------------------------------------------
266 
267 void BrowseBox::ImplTracking()
268 {
269 	DBG_CHKTHIS( BrowseBox, BrowseBoxCheckInvariants );
270 }
271 
272 //-------------------------------------------------------------------
273 
274 void BrowseBox::ImplEndTracking()
275 {
276 	DBG_CHKTHIS( BrowseBox, BrowseBoxCheckInvariants );
277 }
278 
279 //-------------------------------------------------------------------
280 
281 void BrowseBox::RowHeightChanged()
282 {
283 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
284 }
285 
286 //-------------------------------------------------------------------
287 
288 long BrowseBox::QueryColumnResize( sal_uInt16, long nWidth )
289 {
290 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
291 	return nWidth;
292 }
293 
294 //-------------------------------------------------------------------
295 
296 void BrowseBox::ColumnResized( sal_uInt16 )
297 {
298 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
299 }
300 
301 //-------------------------------------------------------------------
302 
303 void BrowseBox::ColumnMoved( sal_uInt16 )
304 {
305 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
306 }
307 
308 //-------------------------------------------------------------------
309 
310 void BrowseBox::StartScroll()
311 {
312 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
313 	//((Control*)pDataWin)->HideFocus();
314 	DoHideCursor( "StartScroll" );
315 }
316 
317 //-------------------------------------------------------------------
318 
319 void BrowseBox::EndScroll()
320 {
321 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
322 	UpdateScrollbars();
323 	AutoSizeLastColumn();
324 	DoShowCursor( "EndScroll" );
325 }
326 
327 //-------------------------------------------------------------------
328 
329 #ifdef _MSC_VER
330 #pragma optimize( "", off )
331 #endif
332 
333 void BrowseBox::ToggleSelection( sal_Bool bForce )
334 {
335 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
336 
337 	// selection highlight-toggling allowed?
338 	if ( bHideSelect )
339 		return;
340 	if ( !bForce &&
341 		 ( bNotToggleSel || !IsUpdateMode() || !bSelectionIsVisible ) )
342 		return;
343 
344 	// only highlight painted areas!
345 	bNotToggleSel = sal_True;
346 	if ( sal_False && !getDataWindow()->bInPaint )
347 		pDataWin->Update();
348 
349 	// accumulate areas of rows to highlight
350 	RectangleList aHighlightList;
351 	long nLastRowInRect = 0; // fuer den CFront
352 
353 	// Handle-Column nicht highlighten
354 	BrowserColumn *pFirstCol = pCols->GetObject(0);
355 	long nOfsX = (!pFirstCol || pFirstCol->GetId()) ? 0 : pFirstCol->Width();
356 
357 	// accumulate old row selection
358 	long nBottomRow = nTopRow +
359 		pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight();
360 	if ( nBottomRow > GetRowCount() && GetRowCount() )
361 		nBottomRow = GetRowCount();
362 	for ( long nRow = bMultiSelection ? uRow.pSel->FirstSelected() : uRow.nSel;
363 		  nRow != BROWSER_ENDOFSELECTION && nRow <= nBottomRow;
364 		  nRow = bMultiSelection ? uRow.pSel->NextSelected() : BROWSER_ENDOFSELECTION )
365 	{
366 		if ( nRow < nTopRow )
367 			continue;
368 
369 		Rectangle aAddRect(
370 			Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
371 			Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
372 		if ( aHighlightList.Count() && nLastRowInRect == ( nRow - 1 ) )
373 			aHighlightList.First()->Union( aAddRect );
374 		else
375 			aHighlightList.Insert( new Rectangle( aAddRect ), (sal_uLong) 0 );
376 		nLastRowInRect = nRow;
377 	}
378 
379 	// unhighlight the old selection (if any)
380 	while ( aHighlightList.Count() )
381 	{
382 		Rectangle *pRect = aHighlightList.Remove( aHighlightList.Count() - 1 );
383 		pDataWin->Invalidate( *pRect );
384 		delete pRect;
385 	}
386 
387 	// unhighlight old column selection (if any)
388 	for ( long nColId = pColSel ? pColSel->FirstSelected() : BROWSER_ENDOFSELECTION;
389 		  nColId != BROWSER_ENDOFSELECTION;
390 		  nColId = pColSel->NextSelected() )
391 	{
392 		Rectangle aRect( GetFieldRectPixel(nCurRow,
393 										   pCols->GetObject(nColId)->GetId(),
394 										   sal_False ) );
395 		aRect.Left() -= MIN_COLUMNWIDTH;
396 		aRect.Right() += MIN_COLUMNWIDTH;
397 		aRect.Top() = 0;
398 		aRect.Bottom() = pDataWin->GetOutputSizePixel().Height();
399 		pDataWin->Invalidate( aRect );
400 	}
401 
402 	bNotToggleSel = sal_False;
403 }
404 
405 #ifdef _MSC_VER
406 #pragma optimize( "", on )
407 #endif
408 
409 //-------------------------------------------------------------------
410 
411 void BrowseBox::DrawCursor()
412 {
413 	sal_Bool bReallyHide = sal_False;
414 	if ( SMART_CURSOR_HIDE == bHideCursor )
415 	{
416 		if ( !GetSelectRowCount() && !GetSelectColumnCount() )
417 			bReallyHide = sal_True;
418 	}
419 	else if ( HARD_CURSOR_HIDE == bHideCursor )
420 	{
421 		bReallyHide = sal_True;
422 	}
423 
424 	bReallyHide |= !bSelectionIsVisible || !IsUpdateMode() || bScrolling || nCurRow < 0;
425 
426 	if (PaintCursorIfHiddenOnce())
427 		bReallyHide |= ( GetCursorHideCount() > 1 );
428 	else
429 		bReallyHide |= ( GetCursorHideCount() > 0 );
430 
431 	// keine Cursor auf Handle-Column
432 	if ( nCurColId == 0 )
433 		nCurColId = GetColumnId(1);
434 
435 	// Cursor-Rechteck berechnen
436 	Rectangle aCursor;
437 	if ( bColumnCursor )
438 	{
439 		aCursor = GetFieldRectPixel( nCurRow, nCurColId, sal_False );
440 		//! --aCursor.Bottom();
441 		aCursor.Left() -= MIN_COLUMNWIDTH;
442 		aCursor.Right() += 1;
443 		aCursor.Bottom() += 1;
444 	}
445 	else
446 		aCursor = Rectangle(
447 			Point( ( pCols->Count() && pCols->GetObject(0)->GetId() == 0 ) ?
448 						pCols->GetObject(0)->Width() : 0,
449 						(nCurRow - nTopRow) * GetDataRowHeight() + 1 ),
450 			Size( pDataWin->GetOutputSizePixel().Width() + 1,
451 				  GetDataRowHeight() - 2 ) );
452 	if ( bHLines )
453 	{
454 		if ( !bMultiSelection )
455 			--aCursor.Top();
456 		--aCursor.Bottom();
457 	}
458 
459 	//!mi_mac pDataWin->Update();
460 
461 	if (m_aCursorColor == COL_TRANSPARENT)
462 	{
463 		// auf diesem Plattformen funktioniert der StarView-Focus richtig
464 		if ( bReallyHide )
465 			((Control*)pDataWin)->HideFocus();
466 		else
467 			((Control*)pDataWin)->ShowFocus( aCursor );
468 	}
469 	else
470 	{
471 		Color rCol = bReallyHide ? pDataWin->GetFillColor() : m_aCursorColor;
472 		Color aOldFillColor = pDataWin->GetFillColor();
473 		Color aOldLineColor = pDataWin->GetLineColor();
474 		pDataWin->SetFillColor();
475 		pDataWin->SetLineColor( rCol );
476 		pDataWin->DrawRect( aCursor );
477 		pDataWin->SetLineColor( aOldLineColor );
478 		pDataWin->SetFillColor( aOldFillColor );
479 	}
480 }
481 
482 //-------------------------------------------------------------------
483 
484 sal_uLong BrowseBox::GetColumnWidth( sal_uInt16 nId ) const
485 {
486 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
487 
488 	sal_uInt16 nItemPos = GetColumnPos( nId );
489 	if ( nItemPos >= pCols->Count() )
490 		return 0;
491 	return pCols->GetObject(nItemPos)->Width();
492 }
493 
494 //-------------------------------------------------------------------
495 
496 sal_uInt16 BrowseBox::GetColumnId( sal_uInt16 nPos ) const
497 {
498 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
499 
500 	if ( nPos >= pCols->Count() )
501 		return 0;
502 	return pCols->GetObject(nPos)->GetId();
503 }
504 
505 //-------------------------------------------------------------------
506 
507 sal_uInt16 BrowseBox::GetColumnPos( sal_uInt16 nId ) const
508 {
509 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
510 
511 	for ( sal_uInt16 nPos = 0; nPos < pCols->Count(); ++nPos )
512 		if ( pCols->GetObject(nPos)->GetId() == nId )
513 			return nPos;
514 	return BROWSER_INVALIDID;
515 }
516 
517 //-------------------------------------------------------------------
518 
519 sal_Bool BrowseBox::IsFrozen( sal_uInt16 nColumnId ) const
520 {
521 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
522 
523 	for ( sal_uInt16 nPos = 0; nPos < pCols->Count(); ++nPos )
524 		if ( pCols->GetObject(nPos)->GetId() == nColumnId )
525 			return pCols->GetObject(nPos)->IsFrozen();
526 	return sal_False;
527 }
528 
529 //-------------------------------------------------------------------
530 
531 void BrowseBox::ExpandRowSelection( const BrowserMouseEvent& rEvt )
532 {
533 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
534 
535 	DoHideCursor( "ExpandRowSelection" );
536 
537 	// expand the last selection
538 	if ( bMultiSelection )
539 	{
540 		Range aJustifiedRange( aSelRange );
541 		aJustifiedRange.Justify();
542 
543         sal_Bool bSelectThis = ( bSelect != aJustifiedRange.IsInside( rEvt.GetRow() ) );
544 
545 		if ( aJustifiedRange.IsInside( rEvt.GetRow() ) )
546 		{
547 			// down and up
548 			while ( rEvt.GetRow() < aSelRange.Max() )
549 			{   // ZTC/Mac bug - dont put these statemants together!
550 				SelectRow( aSelRange.Max(), bSelectThis, sal_True );
551 				--aSelRange.Max();
552 			}
553 			while ( rEvt.GetRow() > aSelRange.Max() )
554 			{   // ZTC/Mac bug - dont put these statemants together!
555 				SelectRow( aSelRange.Max(), bSelectThis, sal_True );
556 				++aSelRange.Max();
557 			}
558 		}
559 		else
560 		{
561 			// up and down
562 			sal_Bool bOldSelecting = bSelecting;
563 			bSelecting = sal_True;
564 			while ( rEvt.GetRow() < aSelRange.Max() )
565 			{   // ZTC/Mac bug - dont put these statemants together!
566 				--aSelRange.Max();
567 				if ( !IsRowSelected( aSelRange.Max() ) )
568 				{
569 					SelectRow( aSelRange.Max(), bSelectThis, sal_True );
570 					bSelect = sal_True;
571 				}
572 			}
573 			while ( rEvt.GetRow() > aSelRange.Max() )
574 			{   // ZTC/Mac bug - dont put these statemants together!
575 				++aSelRange.Max();
576 				if ( !IsRowSelected( aSelRange.Max() ) )
577 				{
578 					SelectRow( aSelRange.Max(), bSelectThis, sal_True );
579 					bSelect = sal_True;
580 				}
581 			}
582 			bSelecting = bOldSelecting;
583 			if ( bSelect )
584 				Select();
585 		}
586 	}
587 	else
588 		if ( !bMultiSelection || !IsRowSelected( rEvt.GetRow() ) )
589 			SelectRow( rEvt.GetRow(), sal_True );
590 
591 	GoToRow( rEvt.GetRow(), sal_False );
592 	DoShowCursor( "ExpandRowSelection" );
593 }
594 
595 //-------------------------------------------------------------------
596 
597 void BrowseBox::Resize()
598 {
599 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
600 	if ( !bBootstrapped && IsReallyVisible() )
601 		BrowseBox::StateChanged( STATE_CHANGE_INITSHOW );
602 	if ( !pCols->Count() )
603 	{
604 		getDataWindow()->bResizeOnPaint = sal_True;
605 		return;
606 	}
607 	getDataWindow()->bResizeOnPaint = sal_False;
608 
609 	// calc the size of the scrollbars
610 	// (we can't ask the scrollbars for their widths cause if we're zoomed they still have to be
611 	// resized - which is done in UpdateScrollbars)
612 	sal_uLong nSBSize = GetSettings().GetStyleSettings().GetScrollBarSize();
613 	if (IsZoom())
614 		nSBSize = (sal_uLong)(nSBSize * (double)GetZoom());
615 
616 	DoHideCursor( "Resize" );
617 	sal_uInt16 nOldVisibleRows =
618 		(sal_uInt16)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
619 
620 	// did we need a horiz. scroll bar oder gibt es eine Control Area?
621 	if ( !getDataWindow()->bNoHScroll &&
622 		 ( ( pCols->Count() - FrozenColCount() ) > 1 ) )
623 		aHScroll.Show();
624 	else
625 		aHScroll.Hide();
626 
627 	// calculate the size of the data window
628 	long nDataHeight = GetOutputSizePixel().Height() - GetTitleHeight();
629 	if ( aHScroll.IsVisible() || ( nControlAreaWidth != USHRT_MAX ) )
630 		nDataHeight -= nSBSize;
631 
632 	long nDataWidth = GetOutputSizePixel().Width();
633 	if ( pVScroll->IsVisible() )
634 		nDataWidth -= nSBSize;
635 
636 	// adjust position and size of data window
637 	pDataWin->SetPosSizePixel(
638 		Point( 0, GetTitleHeight() ),
639 		Size( nDataWidth, nDataHeight ) );
640 
641 	sal_uInt16 nVisibleRows =
642 		(sal_uInt16)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
643 
644 	// TopRow ist unveraendert, aber die Anzahl sichtbarer Zeilen hat sich
645 	// geaendert
646 	if ( nVisibleRows != nOldVisibleRows )
647 		VisibleRowsChanged(nTopRow, nVisibleRows);
648 
649 	UpdateScrollbars();
650 
651 	// Control-Area
652 	Rectangle aInvalidArea( GetControlArea() );
653 	aInvalidArea.Right() = GetOutputSizePixel().Width();
654 	aInvalidArea.Left() = 0;
655 	Invalidate( aInvalidArea );
656 
657 	// external header-bar
658 	HeaderBar* pHeaderBar = getDataWindow()->pHeaderBar;
659 	if ( pHeaderBar )
660 	{
661 		// Handle-Column beruecksichtigen
662 		BrowserColumn *pFirstCol = pCols->GetObject(0);
663 		long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
664 		pHeaderBar->SetPosSizePixel( Point( nOfsX, 0 ), Size( GetOutputSizePixel().Width() - nOfsX, GetTitleHeight() ) );
665 	}
666 
667 	AutoSizeLastColumn(); // adjust last column width
668 	DoShowCursor( "Resize" );
669 }
670 
671 //-------------------------------------------------------------------
672 
673 void BrowseBox::Paint( const Rectangle& rRect )
674 {
675 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
676 
677 	// initializations
678 	if ( !bBootstrapped && IsReallyVisible() )
679 		BrowseBox::StateChanged( STATE_CHANGE_INITSHOW );
680 	if ( !pCols->Count() )
681 		return;
682 
683 	BrowserColumn *pFirstCol = pCols->GetObject(0);
684 	sal_Bool bHandleCol	= pFirstCol && pFirstCol->GetId() == 0;
685 	sal_Bool bHeaderBar = getDataWindow()->pHeaderBar != NULL;
686 
687 	// draw delimitational lines
688 	if ( !getDataWindow()->bNoHScroll )
689 		DrawLine( Point( 0, aHScroll.GetPosPixel().Y() ),
690 				  Point( GetOutputSizePixel().Width(),
691 						 aHScroll.GetPosPixel().Y() ) );
692 
693 	if ( nTitleLines )
694 	{
695 		if ( !bHeaderBar )
696 			DrawLine( Point( 0, GetTitleHeight() - 1 ),
697 					  Point( GetOutputSizePixel().Width(),
698 							 GetTitleHeight() - 1 ) );
699 		else if ( bHandleCol )
700 			DrawLine( Point( 0, GetTitleHeight() - 1 ),
701 					  Point( pFirstCol->Width(), GetTitleHeight() - 1 ) );
702 	}
703 
704 	// Title Bar
705 	// Wenn es eine Handle Column gibt und die Headerbar verfuegbar ist, dann nur
706 	// die HandleColumn
707 	// Handle-Column beruecksichtigen
708 	if ( nTitleLines && (!bHeaderBar || bHandleCol) )
709 	{
710 		// iterate through columns to redraw
711 		long nX = 0;
712 		sal_uInt16 nCol;
713 		for ( nCol = 0;
714 			  nCol < pCols->Count() && nX < rRect.Right();
715 			  ++nCol )
716 		{
717 			// skip invisible colums between frozen and scrollable area
718 			if ( nCol < nFirstCol && !pCols->GetObject(nCol)->IsFrozen() )
719 				nCol = nFirstCol;
720 
721 			// nur die HandleCol ?
722 			if (bHeaderBar && bHandleCol && nCol > 0)
723 				break;
724 
725 			BrowserColumn *pCol = pCols->GetObject(nCol);
726 
727 			// draw the column and increment position
728 			if ( pCol->Width() > 4 )
729 			{
730 				ButtonFrame aButtonFrame( Point( nX, 0 ),
731 					Size( pCol->Width()-1, GetTitleHeight()-1 ),
732 					pCol->Title(), sal_False, sal_False,
733 					0 != (BROWSER_COLUMN_TITLEABBREVATION&pCol->Flags()),
734 					!IsEnabled());
735 				aButtonFrame.Draw( *this );
736 				DrawLine( Point( nX + pCol->Width() - 1, 0 ),
737 				   Point( nX + pCol->Width() - 1, GetTitleHeight()-1 ) );
738 			}
739 			else
740 			{
741 				Color aOldFillColor = GetFillColor();
742 				SetFillColor( Color( COL_BLACK ) );
743 				DrawRect( Rectangle( Point( nX, 0 ), Size( pCol->Width(), GetTitleHeight() - 1 ) ) );
744 				SetFillColor( aOldFillColor );
745 			}
746 
747 			// skip column
748 			nX += pCol->Width();
749 		}
750 
751 		// retouching
752 		if ( !bHeaderBar && nCol == pCols->Count() )
753 		{
754 			const StyleSettings &rSettings = GetSettings().GetStyleSettings();
755 			Color aColFace( rSettings.GetFaceColor() );
756 			Color aOldFillColor = GetFillColor();
757 			Color aOldLineColor = GetLineColor();
758 			SetFillColor( aColFace );
759 			SetLineColor( aColFace );
760 			DrawRect( Rectangle(
761 				Point( nX, 0 ),
762 				Point( rRect.Right(), GetTitleHeight() - 2 ) ) );
763 			SetFillColor( aOldFillColor); // aOldLineColor );  oj 09.02.00 seems to be a copy&paste bug
764 			SetLineColor( aOldLineColor); // aOldFillColor );
765 		}
766 	}
767 }
768 
769 //-------------------------------------------------------------------
770 
771 void BrowseBox::PaintRow( OutputDevice&, const Rectangle& )
772 {
773 }
774 
775 //-------------------------------------------------------------------
776 
777 void BrowseBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
778 {
779 	sal_Bool bDrawSelection = (nFlags & WINDOW_DRAW_NOSELECTION) == 0;
780 
781 	// we need pixel coordinates
782 	Size aRealSize = pDev->LogicToPixel(rSize);
783 	Point aRealPos = pDev->LogicToPixel(rPos);
784 
785 	if ((rSize.Width() < 3) || (rSize.Height() < 3))
786 		// we want to have two pixels frame ...
787 		return;
788 
789 	Font aFont = GetDataWindow().GetDrawPixelFont( pDev );
790 		// the 'normal' painting uses always the data window as device to output to, so we have to calc the new font
791 		// relative to the data wins current settings
792 
793 	pDev->Push();
794 	pDev->SetMapMode();
795 	pDev->SetFont( aFont );
796 
797 	// draw a frame
798 	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
799 	pDev->SetLineColor(rStyleSettings.GetDarkShadowColor());
800 	pDev->DrawLine(Point(aRealPos.X(), aRealPos.Y()),
801 				   Point(aRealPos.X(), aRealPos.Y() + aRealSize.Height() - 1));
802 	pDev->DrawLine(Point(aRealPos.X(), aRealPos.Y()),
803 				   Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y()));
804 	pDev->SetLineColor(rStyleSettings.GetShadowColor());
805 	pDev->DrawLine(Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y() + 1),
806 				   Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y() + aRealSize.Height() - 1));
807 	pDev->DrawLine(Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y() + aRealSize.Height() - 1),
808 				   Point(aRealPos.X() + 1, aRealPos.Y() + aRealSize.Height() - 1));
809 
810 	HeaderBar* pBar = getDataWindow()->pHeaderBar;
811 
812 	// we're drawing onto a foreign device, so we have to fake the DataRowHeight for the subsequent ImplPaintData
813 	// (as it is based on the settings of our data window, not the foreign device)
814 	if (!nDataRowHeight)
815 		ImpGetDataRowHeight();
816 	long nHeightLogic = PixelToLogic(Size(0, nDataRowHeight), MAP_10TH_MM).Height();
817 	long nForeignHeightPixel = pDev->LogicToPixel(Size(0, nHeightLogic), MAP_10TH_MM).Height();
818 
819 	long nOriginalHeight = nDataRowHeight;
820 	nDataRowHeight = nForeignHeightPixel;
821 
822 	// this counts for the column widths, too
823 	sal_uInt16 nPos;
824 	for ( nPos = 0; nPos < pCols->Count(); ++nPos )
825 	{
826 		BrowserColumn* pCurrent = pCols->GetObject(nPos);
827 
828 		long nWidthLogic = PixelToLogic(Size(pCurrent->Width(), 0), MAP_10TH_MM).Width();
829 		long nForeignWidthPixel = pDev->LogicToPixel(Size(nWidthLogic, 0), MAP_10TH_MM).Width();
830 
831 		pCurrent->SetWidth(nForeignWidthPixel, GetZoom());
832 		if ( pBar )
833 			pBar->SetItemSize( pCurrent->GetId(), pCurrent->Width() );
834 	}
835 
836 	// a smaller area for the content
837 	++aRealPos.X();
838 	++aRealPos.Y();
839 	aRealSize.Width() -= 2;
840 	aRealSize.Height() -= 2;
841 
842 	// let the header bar draw itself
843 	if ( pBar )
844 	{
845 		// the title height with respect to the font set for the given device
846 		long nTitleHeight = PixelToLogic(Size(0, GetTitleHeight()), MAP_10TH_MM).Height();
847 		nTitleHeight = pDev->LogicToPixel(Size(0, nTitleHeight), MAP_10TH_MM).Height();
848 
849 		BrowserColumn* pFirstCol = pCols->Count() ? pCols->GetObject(0) : NULL;
850 
851 		Point aHeaderPos(pFirstCol && (pFirstCol->GetId() == 0) ? pFirstCol->Width() : 0, 0);
852 		Size aHeaderSize(aRealSize.Width() - aHeaderPos.X(), nTitleHeight);
853 
854 		aHeaderPos += aRealPos;
855 			// do this before converting to logics !
856 
857 		// the header's draw expects logic coordinates, again
858 		aHeaderPos = pDev->PixelToLogic(aHeaderPos);
859 		aHeaderSize = pDev->PixelToLogic(aHeaderSize);
860 
861 		pBar->Draw(pDev, aHeaderPos, aHeaderSize, nFlags);
862 
863 		// draw the "upper left cell" (the intersection between the header bar and the handle column)
864 		if (( pFirstCol->GetId() == 0 ) && ( pFirstCol->Width() > 4 ))
865 		{
866 			ButtonFrame aButtonFrame( aRealPos,
867 				Size( pFirstCol->Width()-1, nTitleHeight-1 ),
868 				pFirstCol->Title(), sal_False, sal_False, sal_False, !IsEnabled());
869 			aButtonFrame.Draw( *pDev );
870 
871             pDev->Push( PUSH_LINECOLOR );
872 			pDev->SetLineColor( Color( COL_BLACK ) );
873 
874 			pDev->DrawLine( Point( aRealPos.X(), aRealPos.Y() + nTitleHeight-1 ),
875 			   Point( aRealPos.X() + pFirstCol->Width() - 1, aRealPos.Y() + nTitleHeight-1 ) );
876 			pDev->DrawLine( Point( aRealPos.X() + pFirstCol->Width() - 1, aRealPos.Y() ),
877 			   Point( aRealPos.X() + pFirstCol->Width() - 1, aRealPos.Y() + nTitleHeight-1 ) );
878 
879             pDev->Pop();
880 		}
881 
882 		aRealPos.Y() += aHeaderSize.Height();
883 		aRealSize.Height() -= aHeaderSize.Height();
884 	}
885 
886 	// draw our own content (with clipping)
887 	Region aRegion(Rectangle(aRealPos, aRealSize));
888 	pDev->SetClipRegion( pDev->PixelToLogic( aRegion ) );
889 
890     // do we have to paint the background
891     sal_Bool bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && GetDataWindow().IsControlBackground();
892     if ( bBackground )
893     {
894         Rectangle aRect( aRealPos, aRealSize );
895         pDev->SetFillColor( GetDataWindow().GetControlBackground() );
896         pDev->DrawRect( aRect );
897     }
898 
899 	ImplPaintData( *pDev, Rectangle( aRealPos, aRealSize ), sal_True, bDrawSelection );
900 
901 	// restore the column widths/data row height
902 	nDataRowHeight = nOriginalHeight;
903 	for ( nPos = 0; nPos < pCols->Count(); ++nPos )
904 	{
905 		BrowserColumn* pCurrent = pCols->GetObject(nPos);
906 
907 		long nForeignWidthLogic = pDev->PixelToLogic(Size(pCurrent->Width(), 0), MAP_10TH_MM).Width();
908 		long nWidthPixel = LogicToPixel(Size(nForeignWidthLogic, 0), MAP_10TH_MM).Width();
909 
910 		pCurrent->SetWidth(nWidthPixel, GetZoom());
911 		if ( pBar )
912 			pBar->SetItemSize( pCurrent->GetId(), pCurrent->Width() );
913 	}
914 
915 	pDev->Pop();
916 }
917 
918 //-------------------------------------------------------------------
919 
920 void BrowseBox::ImplPaintData(OutputDevice& _rOut, const Rectangle& _rRect, sal_Bool _bForeignDevice, sal_Bool _bDrawSelections)
921 {
922 	Point aOverallAreaPos = _bForeignDevice ? _rRect.TopLeft() : Point(0,0);
923 	Size aOverallAreaSize = _bForeignDevice ? _rRect.GetSize() : GetDataWindow().GetOutputSizePixel();
924 	Point aOverallAreaBRPos = _bForeignDevice ? _rRect.BottomRight() : Point( aOverallAreaSize.Width(), aOverallAreaSize.Height() );
925 
926 	long nDataRowHeigt = GetDataRowHeight();
927 
928 	// compute relative rows to redraw
929 	sal_uLong nRelTopRow = _bForeignDevice ? 0 : ((sal_uLong)_rRect.Top() / nDataRowHeigt);
930 	sal_uLong nRelBottomRow = (sal_uLong)(_bForeignDevice ? aOverallAreaSize.Height() : _rRect.Bottom()) / nDataRowHeigt;
931 
932 	// cache frequently used values
933 	Point aPos( aOverallAreaPos.X(), nRelTopRow * nDataRowHeigt + aOverallAreaPos.Y() );
934 	_rOut.SetLineColor( Color( COL_WHITE ) );
935 	const AllSettings& rAllSets = _rOut.GetSettings();
936 	const StyleSettings &rSettings = rAllSets.GetStyleSettings();
937 	const Color &rHighlightTextColor = rSettings.GetHighlightTextColor();
938 	const Color &rHighlightFillColor = rSettings.GetHighlightColor();
939 	Color aOldTextColor = _rOut.GetTextColor();
940 	Color aOldFillColor = _rOut.GetFillColor();
941 	Color aOldLineColor = _rOut.GetLineColor();
942 	long nHLineX = 0 == pCols->GetObject(0)->GetId()
943 					? pCols->GetObject(0)->Width()
944 					: 0;
945 	nHLineX += aOverallAreaPos.X();
946 
947     Color aDelimiterLineColor( ::svtools::ColorConfig().GetColorValue( ::svtools::CALCGRID ).nColor );
948 
949     // redraw the invalid fields
950 	sal_Bool bRetouching = sal_False;
951 	for ( sal_uLong nRelRow = nRelTopRow;
952 		  nRelRow <= nRelBottomRow && (sal_uLong)nTopRow+nRelRow < (sal_uLong)nRowCount;
953 		  ++nRelRow, aPos.Y() += nDataRowHeigt )
954 	{
955 		// get row
956 		// Zur Sicherheit auf zul"assigen Bereich abfragen:
957 		DBG_ASSERT( (sal_uInt16)(nTopRow+nRelRow) < nRowCount, "BrowseBox::ImplPaintData: invalid seek" );
958 		if ( (nTopRow+long(nRelRow)) < 0 || (sal_uInt16)(nTopRow+nRelRow) >= nRowCount )
959 			continue;
960 
961 		// prepare row
962 		sal_uLong nRow = nTopRow+nRelRow;
963 		if ( !SeekRow( nRow) ) {
964 			DBG_ERROR("BrowseBox::ImplPaintData: SeekRow gescheitert");
965         }
966 		_rOut.SetClipRegion();
967 		aPos.X() = aOverallAreaPos.X();
968 
969 
970 		// #73325# don't paint the row outside the painting rectangle (DG)
971 		// prepare auto-highlight
972 		Rectangle aRowRect( Point( _rRect.TopLeft().X(), aPos.Y() ),
973 				Size( _rRect.GetSize().Width(), nDataRowHeigt ) );
974 		PaintRow( _rOut, aRowRect );
975 
976 		sal_Bool bRowSelected   =   _bDrawSelections
977 							&&  !bHideSelect
978 							&&  IsRowSelected( nRow );
979 		if ( bRowSelected )
980 		{
981 			_rOut.SetTextColor( rHighlightTextColor );
982 			_rOut.SetFillColor( rHighlightFillColor );
983 			_rOut.SetLineColor();
984 			_rOut.DrawRect( aRowRect );
985 		}
986 
987 		// iterate through columns to redraw
988 		sal_uInt16 nCol;
989 		for ( nCol = 0; nCol < pCols->Count(); ++nCol )
990 		{
991 			// get column
992 			BrowserColumn *pCol = pCols->GetObject(nCol);
993 
994 			// at end of invalid area
995 			if ( aPos.X() >= _rRect.Right() )
996 				break;
997 
998 			// skip invisible colums between frozen and scrollable area
999 			if ( nCol < nFirstCol && !pCol->IsFrozen() )
1000 			{
1001 				nCol = nFirstCol;
1002 				pCol = pCols->GetObject(nCol);
1003 				if (!pCol)
1004 				{	// FS - 21.05.99 - 66325
1005 					// ist zwar eigentlich woanders (an der richtigen Stelle) gefixt, aber sicher ist sicher ...
1006 					DBG_ERROR("BrowseBox::PaintData : nFirstCol is probably invalid !");
1007 					break;
1008 				}
1009 			}
1010 
1011 			// prepare Column-AutoHighlight
1012 			sal_Bool bColAutoHighlight	=	_bDrawSelections
1013 									&&	bColumnCursor
1014 									&&	IsColumnSelected( pCol->GetId() );
1015 			if ( bColAutoHighlight )
1016 			{
1017 				_rOut.SetClipRegion();
1018 				_rOut.SetTextColor( rHighlightTextColor );
1019 				_rOut.SetFillColor( rHighlightFillColor );
1020 				_rOut.SetLineColor();
1021 				Rectangle aFieldRect( aPos,
1022 						Size( pCol->Width(), nDataRowHeigt ) );
1023 				_rOut.DrawRect( aFieldRect );
1024 			}
1025 
1026 			if (!m_bFocusOnlyCursor && (pCol->GetId() == GetCurColumnId()) && (nRow == (sal_uLong)GetCurRow()))
1027 				DrawCursor();
1028 
1029 			// draw a single field
1030 			// #63864#, Sonst wird auch etwas gezeichnet, bsp Handle Column
1031 			if (pCol->Width())
1032 			{
1033 				// clip the column's output to the field area
1034 				if (_bForeignDevice)
1035 				{	// (not neccessary if painting onto the data window)
1036 					Size aFieldSize(pCol->Width(), nDataRowHeigt);
1037 
1038 					if (aPos.X() + aFieldSize.Width() > aOverallAreaBRPos.X())
1039 						aFieldSize.Width() = aOverallAreaBRPos.X() - aPos.X();
1040 
1041 					if (aPos.Y() + aFieldSize.Height() > aOverallAreaBRPos.Y() + 1)
1042 					{
1043 						// for non-handle cols we don't clip vertically : we just don't draw the cell if the line isn't completely visible
1044 						if (pCol->GetId() != 0)
1045 							continue;
1046 						aFieldSize.Height() = aOverallAreaBRPos.Y() + 1 - aPos.Y();
1047 					}
1048 
1049 					Region aClipToField(Rectangle(aPos, aFieldSize));
1050 					_rOut.SetClipRegion(aClipToField);
1051 				}
1052 				pCol->Draw( *this, _rOut, aPos, sal_False );
1053 				if (_bForeignDevice)
1054 					_rOut.SetClipRegion();
1055 			}
1056 
1057 			// reset Column-auto-highlight
1058 			if ( bColAutoHighlight )
1059 			{
1060 				_rOut.SetTextColor( aOldTextColor );
1061 				_rOut.SetFillColor( aOldFillColor );
1062 				_rOut.SetLineColor( aOldLineColor );
1063 			}
1064 
1065 			// skip column
1066 			aPos.X() += pCol->Width();
1067 		}
1068 
1069 		if ( nCol == pCols->Count() )
1070 			bRetouching = sal_True;
1071 
1072 		// reset auto-highlight
1073 		if ( bRowSelected )
1074 		{
1075 			_rOut.SetTextColor( aOldTextColor );
1076 			_rOut.SetFillColor( aOldFillColor );
1077 			_rOut.SetLineColor( aOldLineColor );
1078 		}
1079 
1080 		if ( bHLines )
1081 		{
1082 			// draw horizontal delimitation lines
1083 			_rOut.SetClipRegion();
1084             _rOut.Push( PUSH_LINECOLOR );
1085 			_rOut.SetLineColor( aDelimiterLineColor );
1086 			long nY = aPos.Y() + nDataRowHeigt - 1;
1087 			if (nY <= aOverallAreaBRPos.Y())
1088 				_rOut.DrawLine(	Point( nHLineX, nY ),
1089 								Point( bVLines
1090 										? std::min(long(long(aPos.X()) - 1), aOverallAreaBRPos.X())
1091 										: aOverallAreaBRPos.X(),
1092 									  nY ) );
1093             _rOut.Pop();
1094 		}
1095 	}
1096 
1097 	if (aPos.Y() > aOverallAreaBRPos.Y() + 1)
1098 		aPos.Y() = aOverallAreaBRPos.Y() + 1;
1099 		// needed for some of the following drawing
1100 
1101 	// retouching
1102 	_rOut.SetClipRegion();
1103 	aOldLineColor = _rOut.GetLineColor();
1104 	aOldFillColor = _rOut.GetFillColor();
1105 	_rOut.SetFillColor( rSettings.GetFaceColor() );
1106 	if ( pCols->Count() && ( pCols->GetObject(0)->GetId() == 0 ) && ( aPos.Y() <= _rRect.Bottom() ) )
1107 	{
1108 		// fill rectangle gray below handle column
1109 		// DG: fill it only until the end of the drawing rect and not to the end, as this may overpaint handle columns
1110 		_rOut.SetLineColor( Color( COL_BLACK ) );
1111 		_rOut.DrawRect( Rectangle(
1112 			Point( aOverallAreaPos.X() - 1, aPos.Y() - 1 ),
1113 			Point( aOverallAreaPos.X() + pCols->GetObject(0)->Width() - 1,
1114 				   _rRect.Bottom() + 1) ) );
1115 	}
1116 	_rOut.SetFillColor( aOldFillColor );
1117 
1118 	// draw vertical delimitational line between frozen and scrollable cols
1119 	_rOut.SetLineColor( COL_BLACK );
1120 	long nFrozenWidth = GetFrozenWidth()-1;
1121 	_rOut.DrawLine( Point( aOverallAreaPos.X() + nFrozenWidth, aPos.Y() ),
1122 				   Point( aOverallAreaPos.X() + nFrozenWidth, bHLines
1123 							? aPos.Y() - 1
1124 							: aOverallAreaBRPos.Y() ) );
1125 
1126 	// draw vertical delimitational lines?
1127 	if ( bVLines )
1128 	{
1129 		_rOut.SetLineColor( aDelimiterLineColor );
1130         Point aVertPos( aOverallAreaPos.X() - 1, aOverallAreaPos.Y() );
1131 		long nDeltaY = aOverallAreaBRPos.Y();
1132 		for ( sal_uInt16 nCol = 0; nCol < pCols->Count(); ++nCol )
1133 		{
1134 			// get column
1135 			BrowserColumn *pCol = pCols->GetObject(nCol);
1136 
1137 			// skip invisible colums between frozen and scrollable area
1138 			if ( nCol < nFirstCol && !pCol->IsFrozen() )
1139 			{
1140 				nCol = nFirstCol;
1141 				pCol = pCols->GetObject(nCol);
1142 			}
1143 
1144 			// skip column
1145 			aVertPos.X() += pCol->Width();
1146 
1147 			// at end of invalid area
1148 			// invalid area is first reached when X > Right
1149 			// and not >=
1150 			if ( aVertPos.X() > _rRect.Right() )
1151 				break;
1152 
1153 			// draw a single line
1154 			if ( pCol->GetId() != 0 )
1155 				_rOut.DrawLine( aVertPos, Point( aVertPos.X(),
1156 							   bHLines
1157 								? aPos.Y() - 1
1158 								: aPos.Y() + nDeltaY ) );
1159 		}
1160 	}
1161 
1162 	_rOut.SetLineColor( aOldLineColor );
1163 }
1164 
1165 //-------------------------------------------------------------------
1166 
1167 void BrowseBox::PaintData( Window& rWin, const Rectangle& rRect )
1168 {
1169 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1170 	if ( !bBootstrapped && IsReallyVisible() )
1171 		BrowseBox::StateChanged( STATE_CHANGE_INITSHOW );
1172 
1173 	// initializations
1174 	if ( !pCols || !pCols->Count() || !rWin.IsUpdateMode() )
1175 		return;
1176 	if ( getDataWindow()->bResizeOnPaint )
1177 		Resize();
1178 	// MI: wer war das denn? Window::Update();
1179 
1180 	ImplPaintData(rWin, rRect, sal_False, sal_True);
1181 }
1182 
1183 //-------------------------------------------------------------------
1184 
1185 void BrowseBox::UpdateScrollbars()
1186 {
1187 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1188 
1189 	if ( !bBootstrapped || !IsUpdateMode() )
1190 		return;
1191 
1192 	// Rekursionsschutz
1193 	BrowserDataWin *pBDW = (BrowserDataWin*) pDataWin;
1194 	if ( pBDW->bInUpdateScrollbars )
1195 	{
1196 		pBDW->bHadRecursion = sal_True;
1197 		return;
1198 	}
1199 	pBDW->bInUpdateScrollbars = sal_True;
1200 
1201 	// the size of the corner window (and the width of the VSB/height of the HSB)
1202 	sal_uLong nCornerSize = GetSettings().GetStyleSettings().GetScrollBarSize();
1203 	if (IsZoom())
1204 		nCornerSize = (sal_uLong)(nCornerSize * (double)GetZoom());
1205 
1206 	// needs VScroll?
1207 	long nMaxRows = (pDataWin->GetSizePixel().Height()) / GetDataRowHeight();
1208 	sal_Bool bNeedsVScroll =    getDataWindow()->bAutoVScroll
1209 						?   nTopRow || ( nRowCount > nMaxRows )
1210 						:   !getDataWindow()->bNoVScroll;
1211 	Size aDataWinSize = pDataWin->GetSizePixel();
1212 	if ( !bNeedsVScroll )
1213 	{
1214 		if ( pVScroll->IsVisible() )
1215 		{
1216 			pVScroll->Hide();
1217 			Size aNewSize( aDataWinSize );
1218 			aNewSize.Width() = GetOutputSizePixel().Width();
1219 			aDataWinSize = aNewSize;
1220 		}
1221 	}
1222 	else if ( !pVScroll->IsVisible() )
1223 	{
1224 		Size aNewSize( aDataWinSize );
1225 		aNewSize.Width() = GetOutputSizePixel().Width() - nCornerSize;
1226 		aDataWinSize = aNewSize;
1227 	}
1228 
1229 	// needs HScroll?
1230 	sal_uLong nLastCol = GetColumnAtXPosPixel( aDataWinSize.Width() - 1 );
1231 
1232 	sal_uInt16 nFrozenCols = FrozenColCount();
1233 	sal_Bool bNeedsHScroll =    getDataWindow()->bAutoHScroll
1234 		                ?   ( nFirstCol > nFrozenCols ) || ( nLastCol <= pCols->Count() )
1235 		                :   !getDataWindow()->bNoHScroll;
1236 	if ( !bNeedsHScroll )
1237 	{
1238 		if ( aHScroll.IsVisible() )
1239 		{
1240 			aHScroll.Hide();
1241 		}
1242         aDataWinSize.Height() = GetOutputSizePixel().Height() - GetTitleHeight();
1243         if ( nControlAreaWidth != USHRT_MAX )
1244             aDataWinSize.Height() -= nCornerSize;
1245 	}
1246 	else if ( !aHScroll.IsVisible() )
1247 	{
1248 		Size aNewSize( aDataWinSize );
1249 		aNewSize.Height() = GetOutputSizePixel().Height() - GetTitleHeight() - nCornerSize;
1250 		aDataWinSize = aNewSize;
1251 	}
1252 
1253 	// adjust position and Width of horizontal scrollbar
1254 	sal_uLong nHScrX = nControlAreaWidth == USHRT_MAX
1255 		? 0
1256 		: nControlAreaWidth;
1257 
1258 	aHScroll.SetPosSizePixel(
1259 		Point( nHScrX, GetOutputSizePixel().Height() - nCornerSize ),
1260 		Size( aDataWinSize.Width() - nHScrX, nCornerSize ) );
1261 
1262 	// Scrollable Columns insgesamt
1263 	short nScrollCols = short(pCols->Count()) - (short)nFrozenCols;
1264 	/*short nVisibleHSize= std::max(nLastCol == BROWSER_INVALIDID
1265 								? pCols->Count() - nFirstCol -1
1266 								: nLastCol - nFirstCol - 1, 0);
1267 
1268 	aHScroll.SetVisibleSize( nVisibleHSize );
1269 	aHScroll.SetRange( Range( 0, Max( std::min(nScrollCols, nVisibleHSize), (short)0 ) ) );
1270 	if ( bNeedsHScroll && !aHScroll.IsVisible() )
1271 		aHScroll.Show();*/
1272 
1273 	// Sichtbare Columns
1274 	short nVisibleHSize = nLastCol == BROWSER_INVALIDID
1275 		? (short)( pCols->Count() - nFirstCol )
1276 		: (short)( nLastCol - nFirstCol );
1277 
1278 	short nRange = Max( nScrollCols, (short)0 );
1279 	aHScroll.SetVisibleSize( nVisibleHSize );
1280 	aHScroll.SetRange( Range( 0, nRange ));
1281 	if ( bNeedsHScroll && !aHScroll.IsVisible() )
1282 		aHScroll.Show();
1283 
1284 	// adjust position and height of vertical scrollbar
1285 	pVScroll->SetPageSize( nMaxRows );
1286 
1287 	if ( nTopRow > nRowCount )
1288 	{
1289 		nTopRow = nRowCount - 1;
1290 		DBG_ERROR("BrowseBox: nTopRow > nRowCount");
1291 	}
1292 
1293 	if ( pVScroll->GetThumbPos() != nTopRow )
1294 		pVScroll->SetThumbPos( nTopRow );
1295 	long nVisibleSize = Min( Min( nRowCount, nMaxRows ), long(nRowCount-nTopRow) );
1296 	pVScroll->SetVisibleSize( nVisibleSize ? nVisibleSize : 1 );
1297 	pVScroll->SetRange( Range( 0, nRowCount ) );
1298 	pVScroll->SetPosSizePixel(
1299 		Point( aDataWinSize.Width(), GetTitleHeight() ),
1300 		Size( nCornerSize, aDataWinSize.Height()) );
1301 	if ( nRowCount <
1302 		 long( aDataWinSize.Height() / GetDataRowHeight() ) )
1303 		ScrollRows( -nTopRow );
1304 	if ( bNeedsVScroll && !pVScroll->IsVisible() )
1305 		pVScroll->Show();
1306 
1307 	pDataWin->SetPosSizePixel(
1308 		Point( 0, GetTitleHeight() ),
1309 		aDataWinSize );
1310 
1311 	// needs corner-window?
1312 	// (do that AFTER positioning BOTH scrollbars)
1313     sal_uLong nActualCorderWidth = 0;
1314     if (aHScroll.IsVisible() && pVScroll && pVScroll->IsVisible() )
1315     {
1316         // if we have both scrollbars, the corner window fills the point of intersection of these two
1317         nActualCorderWidth = nCornerSize;
1318     }
1319     else if ( !aHScroll.IsVisible() && ( nControlAreaWidth != USHRT_MAX ) )
1320     {
1321         // if we have no horizontal scrollbar, but a control area, we need the corner window to
1322         // fill the space between the control are and the right border
1323         nActualCorderWidth = GetOutputSizePixel().Width() - nControlAreaWidth;
1324     }
1325 	if ( nActualCorderWidth )
1326 	{
1327 		if ( !getDataWindow()->pCornerWin )
1328 			getDataWindow()->pCornerWin = new ScrollBarBox( this, 0 );
1329 		getDataWindow()->pCornerWin->SetPosSizePixel(
1330 			Point( GetOutputSizePixel().Width() - nActualCorderWidth, aHScroll.GetPosPixel().Y() ),
1331 			Size( nActualCorderWidth, nCornerSize ) );
1332 		getDataWindow()->pCornerWin->Show();
1333 	}
1334 	else
1335 		DELETEZ( getDataWindow()->pCornerWin );
1336 
1337 	// ggf. Headerbar mitscrollen
1338 	if ( getDataWindow()->pHeaderBar )
1339 	{
1340 		long nWidth = 0;
1341 		for ( sal_uInt16 nCol = 0;
1342 			  nCol < pCols->Count() && nCol < nFirstCol;
1343 			  ++nCol )
1344 		{
1345 			// HandleColumn nicht
1346 			if ( pCols->GetObject(nCol)->GetId() )
1347 				nWidth += pCols->GetObject(nCol)->Width();
1348 		}
1349 
1350 		getDataWindow()->pHeaderBar->SetOffset( nWidth );
1351 	}
1352 
1353 	pBDW->bInUpdateScrollbars = sal_False;
1354 	if ( pBDW->bHadRecursion )
1355 	{
1356 		pBDW->bHadRecursion = sal_False;
1357 		UpdateScrollbars();
1358 	}
1359 }
1360 
1361 //-------------------------------------------------------------------
1362 
1363 void BrowseBox::SetUpdateMode( sal_Bool bUpdate )
1364 {
1365 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1366 
1367 	sal_Bool bWasUpdate = IsUpdateMode();
1368 	if ( bWasUpdate == bUpdate )
1369 		return;
1370 
1371 	Control::SetUpdateMode( bUpdate );
1372 	// OV
1373 	// Wenn an der BrowseBox WB_CLIPCHILDREN gesetzt ist (wg. Flackerminimierung),
1374 	// wird das Datenfenster nicht von SetUpdateMode invalidiert.
1375 	if( bUpdate )
1376 		getDataWindow()->Invalidate();
1377 	getDataWindow()->SetUpdateMode( bUpdate );
1378 
1379 
1380 	if ( bUpdate )
1381 	{
1382 		if ( bBootstrapped )
1383 		{
1384 			UpdateScrollbars();
1385 			AutoSizeLastColumn();
1386 		}
1387 		DoShowCursor( "SetUpdateMode" );
1388 	}
1389 	else
1390 		DoHideCursor( "SetUpdateMode" );
1391 }
1392 
1393 //-------------------------------------------------------------------
1394 
1395 sal_Bool BrowseBox::GetUpdateMode() const
1396 {
1397 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1398 
1399 	return getDataWindow()->IsUpdateMode();
1400 }
1401 
1402 //-------------------------------------------------------------------
1403 
1404 long BrowseBox::GetFrozenWidth() const
1405 {
1406 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1407 
1408 	long nWidth = 0;
1409 	for ( sal_uInt16 nCol = 0;
1410 		  nCol < pCols->Count() && pCols->GetObject(nCol)->IsFrozen();
1411 		  ++nCol )
1412 		nWidth += pCols->GetObject(nCol)->Width();
1413 	return nWidth;
1414 }
1415 
1416 //-------------------------------------------------------------------
1417 
1418 void BrowseBox::ColumnInserted( sal_uInt16 nPos )
1419 {
1420 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1421 
1422 	if ( pColSel )
1423 		pColSel->Insert( nPos );
1424 	UpdateScrollbars();
1425 }
1426 
1427 //-------------------------------------------------------------------
1428 
1429 sal_uInt16 BrowseBox::FrozenColCount() const
1430 {
1431 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1432 	sal_uInt16 nCol;
1433 	for ( nCol = 0;
1434 		  nCol < pCols->Count() && pCols->GetObject(nCol)->IsFrozen();
1435 		  ++nCol )
1436 		/* empty loop */;
1437 	return nCol;
1438 }
1439 
1440 //-------------------------------------------------------------------
1441 
1442 IMPL_LINK(BrowseBox,ScrollHdl,ScrollBar*,pBar)
1443 {
1444 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1445 
1446 	if ( pBar->GetDelta() == 0 )
1447 		return 0;
1448 
1449 	if ( pBar->GetDelta() < 0 && getDataWindow()->bNoScrollBack )
1450 	{
1451 		UpdateScrollbars();
1452 		return 0;
1453 	}
1454 
1455 	if ( pBar == &aHScroll )
1456 		ScrollColumns( aHScroll.GetDelta() );
1457 	if ( pBar == pVScroll )
1458 		ScrollRows( pVScroll->GetDelta() );
1459 
1460 	return 0;
1461 }
1462 
1463 //-------------------------------------------------------------------
1464 
1465 IMPL_LINK( BrowseBox,EndScrollHdl,ScrollBar*, EMPTYARG )
1466 {
1467 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1468 
1469 	// kein Focus grabben!
1470 	/// GrabFocus();
1471 
1472 	if ( /*pBar->GetDelta() <= 0 &&*/ getDataWindow()->bNoScrollBack )
1473 	{
1474 		// UpdateScrollbars();
1475 		EndScroll();
1476 		return 0;
1477 	}
1478 
1479 	return 0;
1480 }
1481 
1482 //-------------------------------------------------------------------
1483 
1484 IMPL_LINK( BrowseBox, StartDragHdl, HeaderBar*, pBar )
1485 {
1486 	pBar->SetDragSize( pDataWin->GetOutputSizePixel().Height() );
1487 	return 0;
1488 }
1489 
1490 //-------------------------------------------------------------------
1491 // MI: es wurde immer nur die 1. Spalte resized
1492 #ifdef _MSC_VER
1493 #pragma optimize("",off)
1494 #endif
1495 
1496 void BrowseBox::MouseButtonDown( const MouseEvent& rEvt )
1497 {
1498 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1499 
1500 	GrabFocus();
1501 
1502 	// onl< mouse events in the title-line are supported
1503 	const Point &rEvtPos = rEvt.GetPosPixel();
1504 	if ( rEvtPos.Y() >= GetTitleHeight() )
1505 		return;
1506 
1507 	long nX = 0;
1508 	long nWidth = GetOutputSizePixel().Width();
1509 	for ( sal_uInt16 nCol = 0; nCol < pCols->Count() && nX < nWidth; ++nCol )
1510 	{
1511 		// is this column visible?
1512 		BrowserColumn *pCol = pCols->GetObject(nCol);
1513 		if ( pCol->IsFrozen() || nCol >= nFirstCol )
1514 		{
1515 			// compute right end of column
1516 			long nR = nX + pCol->Width() - 1;
1517 
1518 			// at the end of a column (and not handle column)?
1519 			if ( pCol->GetId() && Abs( nR - rEvtPos.X() ) < 2 )
1520 			{
1521 				// start resizing the column
1522 				bResizing = sal_True;
1523 				nResizeCol = nCol;
1524 				nDragX = nResizeX = rEvtPos.X();
1525 				SetPointer( Pointer( POINTER_HSPLIT ) );
1526 				CaptureMouse();
1527 				pDataWin->DrawLine( Point( nDragX, 0 ),
1528 					Point( nDragX, pDataWin->GetSizePixel().Height() ) );
1529 				nMinResizeX = nX + MIN_COLUMNWIDTH;
1530 				return;
1531 			}
1532 			else if ( nX < rEvtPos.X() && nR > rEvtPos.X() )
1533 			{
1534 				MouseButtonDown( BrowserMouseEvent(
1535 					this, rEvt, -1, nCol, pCol->GetId(), Rectangle() ) );
1536 				return;
1537 			}
1538 			nX = nR + 1;
1539 		}
1540 	}
1541 
1542 	// event occured out of data area
1543 	if ( rEvt.IsRight() )
1544 		pDataWin->Command(
1545 			CommandEvent( Point( 1, LONG_MAX ), COMMAND_CONTEXTMENU, sal_True ) );
1546 	else
1547 		SetNoSelection();
1548 }
1549 
1550 #ifdef _MSC_VER
1551 #pragma optimize("",on)
1552 #endif
1553 
1554 //-------------------------------------------------------------------
1555 
1556 void BrowseBox::MouseMove( const MouseEvent& rEvt )
1557 {
1558 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1559     DBG_TRACE( "BrowseBox::MouseMove( MouseEvent )" );
1560 
1561 	Pointer aNewPointer;
1562 
1563 	sal_uInt16 nX = 0;
1564 	for ( sal_uInt16 nCol = 0;
1565 		  nCol < sal_uInt16(pCols->Count()) &&
1566 			( nX + pCols->GetObject(nCol)->Width() ) < sal_uInt16(GetOutputSizePixel().Width());
1567 		  ++nCol )
1568 		// is this column visible?
1569 		if ( pCols->GetObject(nCol)->IsFrozen() || nCol >= nFirstCol )
1570 		{
1571 			// compute right end of column
1572 			BrowserColumn *pCol = pCols->GetObject(nCol);
1573 			sal_uInt16 nR = (sal_uInt16)(nX + pCol->Width() - 1);
1574 
1575 			// show resize-pointer?
1576 			if ( bResizing || ( pCol->GetId() &&
1577 				 Abs( ((long) nR ) - rEvt.GetPosPixel().X() ) < MIN_COLUMNWIDTH ) )
1578 			{
1579 				aNewPointer = Pointer( POINTER_HSPLIT );
1580 				if ( bResizing )
1581 				{
1582 					// alte Hilfslinie loeschen
1583 					pDataWin->HideTracking() ;
1584 
1585 					// erlaubte breite abholen und neues Delta
1586 					nDragX = Max( rEvt.GetPosPixel().X(), nMinResizeX );
1587 					long nDeltaX = nDragX - nResizeX;
1588 					sal_uInt16 nId = GetColumnId(nResizeCol);
1589 					sal_uLong nOldWidth = GetColumnWidth(nId);
1590 					nDragX = QueryColumnResize( GetColumnId(nResizeCol),
1591 									nOldWidth + nDeltaX )
1592 							 + nResizeX - nOldWidth;
1593 
1594 					// neue Hilfslinie zeichnen
1595 					pDataWin->ShowTracking( Rectangle( Point( nDragX, 0 ),
1596 							Size( 1, pDataWin->GetSizePixel().Height() ) ),
1597 							SHOWTRACK_SPLIT|SHOWTRACK_WINDOW );
1598 				}
1599 
1600 			}
1601 
1602 			nX = nR + 1;
1603 		}
1604 
1605 	SetPointer( aNewPointer );
1606 }
1607 
1608 //-------------------------------------------------------------------
1609 
1610 void BrowseBox::MouseButtonUp( const MouseEvent & rEvt )
1611 {
1612 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1613 
1614 	if ( bResizing )
1615 	{
1616 		// Hilfslinie loeschen
1617 		pDataWin->HideTracking();
1618 
1619 		// width changed?
1620 		nDragX = Max( rEvt.GetPosPixel().X(), nMinResizeX );
1621 		if ( (nDragX - nResizeX) != (long)pCols->GetObject(nResizeCol)->Width() )
1622 		{
1623 			// resize column
1624 			long nMaxX = pDataWin->GetSizePixel().Width();
1625 			nDragX = Min( nDragX, nMaxX );
1626 			long nDeltaX = nDragX - nResizeX;
1627 			sal_uInt16 nId = GetColumnId(nResizeCol);
1628 			SetColumnWidth( GetColumnId(nResizeCol), GetColumnWidth(nId) + nDeltaX );
1629 			ColumnResized( nId );
1630 		}
1631 
1632 		// end action
1633 		SetPointer( Pointer() );
1634 		ReleaseMouse();
1635 		bResizing = sal_False;
1636 	}
1637 	else
1638 		MouseButtonUp( BrowserMouseEvent( (BrowserDataWin*)pDataWin,
1639 				MouseEvent( Point( rEvt.GetPosPixel().X(),
1640 						rEvt.GetPosPixel().Y() - pDataWin->GetPosPixel().Y() ),
1641 					rEvt.GetClicks(), rEvt.GetMode(), rEvt.GetButtons(),
1642 					rEvt.GetModifier() ) ) );
1643 }
1644 
1645 //-------------------------------------------------------------------
1646 
1647 sal_Bool bExtendedMode = sal_False;
1648 sal_Bool bFieldMode = sal_False;
1649 
1650 void BrowseBox::MouseButtonDown( const BrowserMouseEvent& rEvt )
1651 {
1652 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1653 
1654 	GrabFocus();
1655 
1656 	// adjust selection while and after double-click
1657 	if ( rEvt.GetClicks() == 2 )
1658 	{
1659 		SetNoSelection();
1660 		if ( rEvt.GetRow() >= 0 )
1661 		{
1662 			GoToRow( rEvt.GetRow() );
1663 			SelectRow( rEvt.GetRow(), sal_True, sal_False );
1664 		}
1665 		else
1666 		{
1667 			if ( bColumnCursor && rEvt.GetColumn() != 0 )
1668 			{
1669 				if ( rEvt.GetColumn() < pCols->Count() )
1670 					SelectColumnPos( rEvt.GetColumn(), sal_True, sal_False);
1671 			}
1672 		}
1673 		DoubleClick( rEvt );
1674 	}
1675 	// selections
1676 	else if ( ( rEvt.GetMode() & ( MOUSE_SELECT | MOUSE_SIMPLECLICK ) ) &&
1677 		 ( bColumnCursor || rEvt.GetRow() >= 0 ) )
1678 	{
1679 		if ( rEvt.GetClicks() == 1 )
1680 		{
1681 			// initialise flags
1682 			bHit            = sal_False;
1683 			a1stPoint       =
1684 			a2ndPoint       = PixelToLogic( rEvt.GetPosPixel() );
1685 
1686 			// selection out of range?
1687 			if ( rEvt.GetRow() >= nRowCount ||
1688 				 rEvt.GetColumnId() == BROWSER_INVALIDID )
1689 			{
1690 				SetNoSelection();
1691 				return;
1692 			}
1693 
1694 			// while selecting, no cursor
1695 			bSelecting = sal_True;
1696 			DoHideCursor( "MouseButtonDown" );
1697 
1698 			// DataRow?
1699 			if ( rEvt.GetRow() >= 0 )
1700 			{
1701 				// Zeilenselektion?
1702 				if ( rEvt.GetColumnId() == 0 || !bColumnCursor )
1703 				{
1704 					if ( bMultiSelection )
1705 					{
1706 						// remove column-selection, if exists
1707 						if ( pColSel && pColSel->GetSelectCount() )
1708 						{
1709 							ToggleSelection();
1710 							if ( bMultiSelection )
1711 								uRow.pSel->SelectAll(sal_False);
1712 							else
1713 								uRow.nSel = BROWSER_ENDOFSELECTION;
1714 							if ( pColSel )
1715 								pColSel->SelectAll(sal_False);
1716 							bSelect = sal_True;
1717 						}
1718 
1719 						// expanding mode?
1720 						if ( rEvt.GetMode() & MOUSE_RANGESELECT )
1721 						{
1722 							// select the further touched rows too
1723 							bSelect = sal_True;
1724 							ExpandRowSelection( rEvt );
1725 							return;
1726 						}
1727 
1728 						// click in the selected area?
1729 						else if ( IsRowSelected( rEvt.GetRow() ) )
1730 						{
1731 							// auf Drag&Drop warten
1732 							bHit = sal_True;
1733 							bExtendedMode = MOUSE_MULTISELECT ==
1734 									( rEvt.GetMode() & MOUSE_MULTISELECT );
1735 							return;
1736 						}
1737 
1738 						// extension mode?
1739 						else if ( rEvt.GetMode() & MOUSE_MULTISELECT )
1740 						{
1741 							// determine the new selection range
1742 							// and selection/deselection
1743 							aSelRange = Range( rEvt.GetRow(), rEvt.GetRow() );
1744 							SelectRow( rEvt.GetRow(),
1745 									!uRow.pSel->IsSelected( rEvt.GetRow() ) );
1746 							bSelect = sal_True;
1747 							return;
1748 						}
1749 					}
1750 
1751 					// select directly
1752 					SetNoSelection();
1753 					GoToRow( rEvt.GetRow() );
1754 					SelectRow( rEvt.GetRow(), sal_True );
1755 					aSelRange = Range( rEvt.GetRow(), rEvt.GetRow() );
1756 					bSelect = sal_True;
1757 				}
1758 				else // Column/Field-Selection
1759 				{
1760 					// click in selected column
1761 					if ( IsColumnSelected( rEvt.GetColumn() ) ||
1762 						 IsRowSelected( rEvt.GetRow() ) )
1763 					{
1764 						bHit = sal_True;
1765 						bFieldMode = sal_True;
1766 						return;
1767 					}
1768 
1769 					SetNoSelection();
1770 					GoToRowColumnId( rEvt.GetRow(), rEvt.GetColumnId() );
1771 					bSelect = sal_True;
1772 				}
1773 			}
1774 			else
1775 			{
1776 				if ( bMultiSelection && rEvt.GetColumnId() == 0 )
1777 				{
1778 					// toggle all-selection
1779 					if ( uRow.pSel->GetSelectCount() > ( GetRowCount() / 2 ) )
1780 						SetNoSelection();
1781 					else
1782 						SelectAll();
1783 				}
1784 				else
1785 					SelectColumnId( rEvt.GetColumnId(), sal_True, sal_False );
1786 			}
1787 
1788 			// ggf. Cursor wieder an
1789 			bSelecting = sal_False;
1790 			DoShowCursor( "MouseButtonDown" );
1791 			if ( bSelect )
1792 				Select();
1793 		}
1794 	}
1795 }
1796 
1797 //-------------------------------------------------------------------
1798 
1799 void BrowseBox::MouseMove( const BrowserMouseEvent& )
1800 {
1801 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1802 }
1803 
1804 //-------------------------------------------------------------------
1805 
1806 void BrowseBox::MouseButtonUp( const BrowserMouseEvent &rEvt )
1807 {
1808 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1809 
1810 	// D&D was possible, but did not occur
1811 	if ( bHit )
1812 	{
1813 		aSelRange = Range( rEvt.GetRow(), rEvt.GetRow() );
1814 		if ( bExtendedMode )
1815 			SelectRow( rEvt.GetRow(), sal_False );
1816 		else
1817 		{
1818 			SetNoSelection();
1819 			if ( bFieldMode )
1820 				GoToRowColumnId( rEvt.GetRow(), rEvt.GetColumnId() );
1821 			else
1822 			{
1823 				GoToRow( rEvt.GetRow() );
1824 				SelectRow( rEvt.GetRow(), sal_True );
1825 			}
1826 		}
1827 		bSelect = sal_True;
1828 		bExtendedMode = sal_False;
1829 		bFieldMode = sal_False;
1830 		bHit = sal_False;
1831 	}
1832 
1833 	// activate cursor
1834 	if ( bSelecting )
1835 	{
1836 		bSelecting = sal_False;
1837 		DoShowCursor( "MouseButtonUp" );
1838 		if ( bSelect )
1839 			Select();
1840 	}
1841 }
1842 
1843 //-------------------------------------------------------------------
1844 
1845 void BrowseBox::KeyInput( const KeyEvent& rEvt )
1846 {
1847 	if ( !ProcessKey( rEvt ) )
1848 		Control::KeyInput( rEvt );
1849 }
1850 
1851 //-------------------------------------------------------------------
1852 
1853 sal_Bool BrowseBox::ProcessKey( const KeyEvent& rEvt )
1854 {
1855 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1856 
1857 	sal_uInt16 nCode = rEvt.GetKeyCode().GetCode();
1858 	sal_Bool   bShift = rEvt.GetKeyCode().IsShift();
1859 	sal_Bool   bCtrl = rEvt.GetKeyCode().IsMod1();
1860 	sal_Bool   bAlt = rEvt.GetKeyCode().IsMod2();
1861 
1862 	sal_uInt16 nId = BROWSER_NONE;
1863 
1864 	if ( !bAlt && !bCtrl && !bShift )
1865 	{
1866 		switch ( nCode )
1867 		{
1868 			case KEY_DOWN:          nId = BROWSER_CURSORDOWN; break;
1869 			case KEY_UP:            nId = BROWSER_CURSORUP; break;
1870 			case KEY_HOME:          nId = BROWSER_CURSORHOME; break;
1871 			case KEY_END:           nId = BROWSER_CURSOREND; break;
1872 			case KEY_TAB:
1873 				if ( !bColumnCursor )
1874 					break;
1875 			case KEY_RIGHT:         nId = BROWSER_CURSORRIGHT; break;
1876 			case KEY_LEFT:          nId = BROWSER_CURSORLEFT; break;
1877 			case KEY_SPACE:         nId = BROWSER_SELECT; break;
1878 		}
1879 		if ( BROWSER_NONE != nId )
1880 			SetNoSelection();
1881 
1882 		switch ( nCode )
1883 		{
1884 			case KEY_PAGEDOWN:      nId = BROWSER_CURSORPAGEDOWN; break;
1885 			case KEY_PAGEUP:        nId = BROWSER_CURSORPAGEUP; break;
1886 		}
1887 	}
1888 
1889 	if ( !bAlt && !bCtrl && bShift )
1890 		switch ( nCode )
1891 		{
1892 			case KEY_DOWN:          nId = BROWSER_SELECTDOWN; break;
1893 			case KEY_UP:            nId = BROWSER_SELECTUP; break;
1894 			case KEY_TAB:
1895 				if ( !bColumnCursor )
1896 					break;
1897 									nId = BROWSER_CURSORLEFT; break;
1898 			case KEY_HOME:          nId = BROWSER_SELECTHOME; break;
1899 			case KEY_END:           nId = BROWSER_SELECTEND; break;
1900 		}
1901 
1902 
1903 	if ( !bAlt && bCtrl && !bShift )
1904 		switch ( nCode )
1905 		{
1906 			case KEY_DOWN:          nId = BROWSER_CURSORDOWN; break;
1907 			case KEY_UP:            nId = BROWSER_CURSORUP; break;
1908 			case KEY_PAGEDOWN:      nId = BROWSER_CURSORENDOFFILE; break;
1909 			case KEY_PAGEUP:        nId = BROWSER_CURSORTOPOFFILE; break;
1910 			case KEY_HOME:          nId = BROWSER_CURSORTOPOFSCREEN; break;
1911 			case KEY_END:           nId = BROWSER_CURSORENDOFSCREEN; break;
1912 			case KEY_SPACE:         nId = BROWSER_ENHANCESELECTION; break;
1913 			case KEY_LEFT:          nId = BROWSER_MOVECOLUMNLEFT; break;
1914 			case KEY_RIGHT:         nId = BROWSER_MOVECOLUMNRIGHT; break;
1915 		}
1916 
1917 	if ( nId != BROWSER_NONE )
1918 		Dispatch( nId );
1919 	return nId != BROWSER_NONE;
1920 }
1921 
1922 //-------------------------------------------------------------------
1923 
1924 void BrowseBox::Dispatch( sal_uInt16 nId )
1925 {
1926 	DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1927 
1928 	long nRowsOnPage = pDataWin->GetSizePixel().Height() / GetDataRowHeight();
1929 	sal_Bool bDone = sal_False;
1930 
1931 	switch ( nId )
1932 	{
1933 		case BROWSER_SELECTCOLUMN:
1934 			if ( ColCount() )
1935 				SelectColumnId( GetCurColumnId() );
1936 			break;
1937 
1938 		case BROWSER_CURSORDOWN:
1939 			if ( ( GetCurRow() + 1 ) < nRowCount )
1940 				bDone = GoToRow( GetCurRow() + 1, sal_False );
1941 			break;
1942 		case BROWSER_CURSORUP:
1943 			if ( GetCurRow() > 0 )
1944 				bDone = GoToRow( GetCurRow() - 1, sal_False );
1945 			break;
1946 		case BROWSER_SELECTHOME:
1947 			if ( GetRowCount() )
1948 			{
1949 				DoHideCursor( "BROWSER_SELECTHOME" );
1950 				for ( long nRow = GetCurRow(); nRow >= 0; --nRow )
1951 					SelectRow( nRow );
1952 				GoToRow( 0, sal_True );
1953 				DoShowCursor( "BROWSER_SELECTHOME" );
1954 			}
1955 			break;
1956 		case BROWSER_SELECTEND:
1957 			if ( GetRowCount() )
1958 			{
1959 				DoHideCursor( "BROWSER_SELECTEND" );
1960 				long nRows = GetRowCount();
1961 				for ( long nRow = GetCurRow(); nRow < nRows; ++nRow )
1962 					SelectRow( nRow );
1963 				GoToRow( GetRowCount() - 1, sal_True );
1964 				DoShowCursor( "BROWSER_SELECTEND" );
1965 			}
1966 			break;
1967 		case BROWSER_SELECTDOWN:
1968 		{
1969 			if ( GetRowCount() && ( GetCurRow() + 1 ) < nRowCount )
1970 			{
1971 				// deselect the current row, if it isn't the first
1972 				// and there is no other selected row above
1973 				long nRow = GetCurRow();
1974 				sal_Bool bLocalSelect = ( !IsRowSelected( nRow ) ||
1975 								 GetSelectRowCount() == 1 || IsRowSelected( nRow - 1 ) );
1976 				SelectRow( nRow, bLocalSelect, sal_True );
1977 				bDone = GoToRow( GetCurRow() + 1 , sal_False );
1978 				if ( bDone )
1979 					SelectRow( GetCurRow(), sal_True, sal_True );
1980 			}
1981 			else
1982 				bDone = ScrollRows( 1 ) != 0;
1983 			break;
1984 		}
1985 		case BROWSER_SELECTUP:
1986 			if ( GetRowCount() )
1987 			{
1988 				// deselect the current row, if it isn't the first
1989 				// and there is no other selected row under
1990 				long nRow = GetCurRow();
1991 				sal_Bool bLocalSelect = ( !IsRowSelected( nRow ) ||
1992 								 GetSelectRowCount() == 1 || IsRowSelected( nRow + 1 ) );
1993 				SelectRow( nCurRow, bLocalSelect, sal_True );
1994                 bDone = GoToRow( nRow - 1 , sal_False );
1995 				if ( bDone )
1996 					SelectRow( GetCurRow(), sal_True, sal_True );
1997 			}
1998 			break;
1999 		case BROWSER_CURSORPAGEDOWN:
2000 			bDone = (sal_Bool)ScrollRows( nRowsOnPage );
2001 			break;
2002 		case BROWSER_CURSORPAGEUP:
2003 			bDone = (sal_Bool)ScrollRows( -nRowsOnPage );
2004 			break;
2005 		case BROWSER_CURSOREND:
2006 			if ( bColumnCursor )
2007 			{
2008 				sal_uInt16 nNewId = GetColumnId(ColCount() -1);
2009 				bDone = (nNewId != 0) && GoToColumnId( nNewId );
2010 				break;
2011 			}
2012 		case BROWSER_CURSORENDOFFILE:
2013 			bDone = GoToRow( nRowCount - 1, sal_False );
2014 			break;
2015 		case BROWSER_CURSORRIGHT:
2016 			if ( bColumnCursor )
2017 			{
2018 				sal_uInt16 nNewPos = GetColumnPos( GetCurColumnId() ) + 1;
2019 				sal_uInt16 nNewId = GetColumnId( nNewPos );
2020 				if (nNewId != 0)	// Am Zeilenende ?
2021 					bDone = GoToColumnId( nNewId );
2022 				else
2023 				{
2024 					sal_uInt16 nColId = ( GetColumnId(0) == 0 ) ? GetColumnId(1) : GetColumnId(0);
2025 					if ( GetRowCount() )
2026 						bDone = ( nCurRow < GetRowCount() - 1 ) && GoToRowColumnId( nCurRow + 1, nColId );
2027 					else if ( ColCount() )
2028 						GoToColumnId( nColId );
2029 				}
2030 			}
2031 			else
2032 				bDone = ScrollColumns( 1 ) != 0;
2033 			break;
2034 		case BROWSER_CURSORHOME:
2035 			if ( bColumnCursor )
2036 			{
2037 				sal_uInt16 nNewId = GetColumnId(1);
2038 				bDone = (nNewId != 0) && GoToColumnId( nNewId );
2039 				break;
2040 			}
2041 		case BROWSER_CURSORTOPOFFILE:
2042 			bDone = GoToRow( 0, sal_False );
2043 			break;
2044 		case BROWSER_CURSORLEFT:
2045 			if ( bColumnCursor )
2046 			{
2047 				sal_uInt16 nNewPos = GetColumnPos( GetCurColumnId() ) - 1;
2048 				sal_uInt16 nNewId = GetColumnId( nNewPos );
2049 				if (nNewId != 0)
2050 					bDone = GoToColumnId( nNewId );
2051 				else
2052 				{
2053 					if ( GetRowCount() )
2054 						bDone = (nCurRow > 0) && GoToRowColumnId(nCurRow - 1, GetColumnId(ColCount() -1));
2055 					else if ( ColCount() )
2056 						GoToColumnId( GetColumnId(ColCount() -1) );
2057 				}
2058 			}
2059 			else
2060 				bDone = ScrollColumns( -1 ) != 0;
2061 			break;
2062 		case BROWSER_ENHANCESELECTION:
2063 			if ( GetRowCount() )
2064 				SelectRow( GetCurRow(), !IsRowSelected( GetCurRow() ), sal_True );
2065 			bDone = sal_True;
2066 			break;
2067 		case BROWSER_SELECT:
2068 			if ( GetRowCount() )
2069 				SelectRow( GetCurRow(), !IsRowSelected( GetCurRow() ), sal_False );
2070 			bDone = sal_True;
2071 			break;
2072 		case BROWSER_MOVECOLUMNLEFT:
2073 		case BROWSER_MOVECOLUMNRIGHT:
2074 			{ // check if column moving is allowed
2075 				BrowserHeader* pHeaderBar = getDataWindow()->pHeaderBar;
2076 				if ( pHeaderBar && pHeaderBar->IsDragable() )
2077 				{
2078 					sal_uInt16 nColId = GetCurColumnId();
2079 					sal_Bool bColumnSelected = IsColumnSelected(nColId);
2080 					sal_uInt16 nNewPos = GetColumnPos(nColId);
2081 					sal_Bool bMoveAllowed = sal_False;
2082 					if ( BROWSER_MOVECOLUMNLEFT == nId && nNewPos > 1 )
2083 						--nNewPos,bMoveAllowed = sal_True;
2084 					else if ( BROWSER_MOVECOLUMNRIGHT == nId && nNewPos < (ColCount()-1) )
2085 						++nNewPos,bMoveAllowed = sal_True;
2086 
2087 					if ( bMoveAllowed )
2088 					{
2089 						SetColumnPos( nColId, nNewPos );
2090 						ColumnMoved( nColId );
2091 						MakeFieldVisible(GetCurRow(),nColId,sal_True);
2092 						if ( bColumnSelected )
2093 							SelectColumnId(nColId);
2094 					}
2095 				}
2096 			}
2097 			break;
2098 	}
2099 
2100 	//! return bDone;
2101 }
2102 
2103 //-------------------------------------------------------------------
2104 
2105 void BrowseBox::SetCursorColor(const Color& _rCol)
2106 {
2107 	if (_rCol == m_aCursorColor)
2108 		return;
2109 
2110 	// ensure the cursor is hidden
2111 	DoHideCursor("SetCursorColor");
2112 	if (!m_bFocusOnlyCursor)
2113 		DoHideCursor("SetCursorColor - force");
2114 
2115 	m_aCursorColor = _rCol;
2116 
2117 	if (!m_bFocusOnlyCursor)
2118 		DoShowCursor("SetCursorColor - force");
2119 	DoShowCursor("SetCursorColor");
2120 }
2121 // -----------------------------------------------------------------------------
2122 Rectangle BrowseBox::calcHeaderRect(sal_Bool _bIsColumnBar,sal_Bool _bOnScreen)
2123 {
2124 	Window* pParent = NULL;
2125 	if ( !_bOnScreen )
2126 		pParent = GetAccessibleParentWindow();
2127 
2128 	Point aTopLeft;
2129 	long nWidth;
2130 	long nHeight;
2131 	if ( _bIsColumnBar )
2132 	{
2133 		nWidth = GetDataWindow().GetOutputSizePixel().Width();
2134 		nHeight = GetDataRowHeight();
2135 	}
2136 	else
2137 	{
2138 		aTopLeft.Y() = GetDataRowHeight();
2139 		nWidth = GetColumnWidth(0);
2140 		nHeight = GetWindowExtentsRelative( pParent ).GetHeight() - aTopLeft.Y() - GetControlArea().GetSize().B();
2141 	}
2142 	aTopLeft += GetWindowExtentsRelative( pParent ).TopLeft();
2143 	return Rectangle(aTopLeft,Size(nWidth,nHeight));
2144 }
2145 // -----------------------------------------------------------------------------
2146 Rectangle BrowseBox::calcTableRect(sal_Bool _bOnScreen)
2147 {
2148 	Window* pParent = NULL;
2149 	if ( !_bOnScreen )
2150 		pParent = GetAccessibleParentWindow();
2151 
2152 	Rectangle aRect( GetWindowExtentsRelative( pParent ) );
2153 	Rectangle aRowBar = calcHeaderRect(sal_False,pParent == NULL);
2154 
2155 	long nX = aRowBar.Right() - aRect.Left();
2156 	long nY = aRowBar.Top() - aRect.Top();
2157 	Size aSize(aRect.GetSize());
2158 
2159 	return Rectangle(aRowBar.TopRight(), Size(aSize.A() - nX, aSize.B() - nY - aHScroll.GetSizePixel().Height()) );
2160 }
2161 // -----------------------------------------------------------------------------
2162 Rectangle BrowseBox::GetFieldRectPixelAbs( sal_Int32 _nRowId,sal_uInt16 _nColId, sal_Bool /*_bIsHeader*/, sal_Bool _bOnScreen )
2163 {
2164 	Window* pParent = NULL;
2165 	if ( !_bOnScreen )
2166 		pParent = GetAccessibleParentWindow();
2167 
2168 	Rectangle aRect = GetFieldRectPixel(_nRowId,_nColId,_bOnScreen);
2169 
2170 	Point aTopLeft = aRect.TopLeft();
2171 	aTopLeft += GetWindowExtentsRelative( pParent ).TopLeft();
2172 
2173 	return Rectangle(aTopLeft,aRect.GetSize());
2174 }
2175 
2176 // ------------------------------------------------------------------------- EOF
2177 
2178