xref: /trunk/main/svtools/source/brwbox/brwbox2.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 #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