update credits
[LibreOffice.git] / svtools / source / brwbox / brwbox2.cxx
bloba93d65bf12e09df99a1bcb14cee18b6b9fde9a5a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <tools/debug.hxx>
21 #include <svtools/brwbox.hxx>
22 #include "datwin.hxx"
23 #include <svtools/colorcfg.hxx>
24 #include <vcl/salgtype.hxx>
26 #include <tools/multisel.hxx>
27 #include <algorithm>
29 using namespace ::com::sun::star::datatransfer;
31 #define getDataWindow() ((BrowserDataWin*)pDataWin)
34 //===================================================================
36 DBG_NAMEEX(BrowseBox)
38 //===================================================================
40 extern const char* BrowseBoxCheckInvariants( const void * pVoid );
42 //===================================================================
44 void BrowseBox::StartDrag( sal_Int8 /* _nAction */, const Point& /* _rPosPixel */ )
46 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
47 // not interested in this event
50 //===================================================================
52 sal_Int8 BrowseBox::AcceptDrop( const AcceptDropEvent& _rEvt )
54 BrowserDataWin* pDataWindow = static_cast<BrowserDataWin*>(pDataWin);
55 AcceptDropEvent aTransformed( _rEvt );
56 aTransformed.maPosPixel = pDataWindow->ScreenToOutputPixel( OutputToScreenPixel( _rEvt.maPosPixel ) );
57 return pDataWindow->AcceptDrop( aTransformed );
60 //===================================================================
62 sal_Int8 BrowseBox::ExecuteDrop( const ExecuteDropEvent& _rEvt )
64 BrowserDataWin* pDataWindow = static_cast<BrowserDataWin*>(pDataWin);
65 ExecuteDropEvent aTransformed( _rEvt );
66 aTransformed.maPosPixel = pDataWindow->ScreenToOutputPixel( OutputToScreenPixel( _rEvt.maPosPixel ) );
67 return pDataWindow->ExecuteDrop( aTransformed );
70 //===================================================================
72 sal_Int8 BrowseBox::AcceptDrop( const BrowserAcceptDropEvent& )
74 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
75 // not interested in this event
76 return DND_ACTION_NONE;
79 //===================================================================
81 sal_Int8 BrowseBox::ExecuteDrop( const BrowserExecuteDropEvent& )
83 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
84 // not interested in this event
85 return DND_ACTION_NONE;
88 //===================================================================
90 void* BrowseBox::implGetDataFlavors() const
92 if (static_cast<BrowserDataWin*>(pDataWin)->bCallingDropCallback)
93 return &static_cast<BrowserDataWin*>(pDataWin)->GetDataFlavorExVector();
94 return &GetDataFlavorExVector();
97 //===================================================================
99 sal_Bool BrowseBox::IsDropFormatSupported( SotFormatStringId _nFormat )
101 if ( static_cast< BrowserDataWin* >( pDataWin )->bCallingDropCallback )
102 return static_cast< BrowserDataWin* >( pDataWin )->IsDropFormatSupported( _nFormat );
104 return DropTargetHelper::IsDropFormatSupported( _nFormat );
107 //===================================================================
109 sal_Bool BrowseBox::IsDropFormatSupported( SotFormatStringId _nFormat ) const
111 return const_cast< BrowseBox* >( this )->IsDropFormatSupported( _nFormat );
114 //===================================================================
116 sal_Bool BrowseBox::IsDropFormatSupported( const DataFlavor& _rFlavor )
118 if ( static_cast< BrowserDataWin* >( pDataWin )->bCallingDropCallback )
119 return static_cast< BrowserDataWin* >( pDataWin )->IsDropFormatSupported( _rFlavor );
121 return DropTargetHelper::IsDropFormatSupported( _rFlavor );
124 //===================================================================
126 sal_Bool BrowseBox::IsDropFormatSupported( const DataFlavor& _rFlavor ) const
128 return const_cast< BrowseBox* >( this )->IsDropFormatSupported( _rFlavor );
131 //===================================================================
133 void BrowseBox::Command( const CommandEvent& rEvt )
135 if ( !getDataWindow()->bInCommand )
136 Control::Command( rEvt );
139 //===================================================================
141 void BrowseBox::StateChanged( StateChangedType nStateChange )
143 Control::StateChanged( nStateChange );
145 if ( STATE_CHANGE_MIRRORING == nStateChange )
147 getDataWindow()->EnableRTL( IsRTLEnabled() );
149 HeaderBar* pHeaderBar = getDataWindow()->pHeaderBar;
150 if ( pHeaderBar )
151 pHeaderBar->EnableRTL( IsRTLEnabled() );
152 aHScroll.EnableRTL( IsRTLEnabled() );
153 if( pVScroll )
154 pVScroll->EnableRTL( IsRTLEnabled() );
155 Resize();
157 else if ( STATE_CHANGE_INITSHOW == nStateChange )
159 bBootstrapped = sal_True; // must be set first!
161 Resize();
162 if ( bMultiSelection )
163 uRow.pSel->SetTotalRange( Range( 0, nRowCount - 1 ) );
164 if ( nRowCount == 0 )
165 nCurRow = BROWSER_ENDOFSELECTION;
166 else if ( nCurRow == BROWSER_ENDOFSELECTION )
167 nCurRow = 0;
170 if ( HasFocus() )
172 bSelectionIsVisible = sal_True;
173 bHasFocus = sal_True;
175 UpdateScrollbars();
176 AutoSizeLastColumn();
177 CursorMoved();
179 else if (STATE_CHANGE_ZOOM == nStateChange)
181 pDataWin->SetZoom(GetZoom());
182 HeaderBar* pHeaderBar = getDataWindow()->pHeaderBar;
183 if (pHeaderBar)
184 pHeaderBar->SetZoom(GetZoom());
186 // let the columns calculate their new widths and adjust the header bar
187 for ( size_t nPos = 0; nPos < pCols->size(); ++nPos )
189 (*pCols)[ nPos ]->ZoomChanged(GetZoom());
190 if ( pHeaderBar )
191 pHeaderBar->SetItemSize( (*pCols)[ nPos ]->GetId(), (*pCols)[ nPos ]->Width() );
194 // all our controls have to be repositioned
195 Resize();
197 else if (STATE_CHANGE_ENABLE == nStateChange)
199 // do we have a handle column?
200 sal_Bool bHandleCol = !pCols->empty() && (0 == (*pCols)[ 0 ]->GetId());
201 // do we have a header bar?
202 sal_Bool bHeaderBar = (NULL != static_cast<BrowserDataWin&>(GetDataWindow()).pHeaderBar);
204 if ( nTitleLines
205 && ( !bHeaderBar
206 || bHandleCol
209 // we draw the text in our header bar in a color dependent on the enabled state. So if this state changed
210 // -> redraw
211 Invalidate(Rectangle(Point(0, 0), Size(GetOutputSizePixel().Width(), GetTitleHeight() - 1)));
215 //===================================================================
217 void BrowseBox::Select()
219 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
222 //-------------------------------------------------------------------
224 void BrowseBox::DoubleClick( const BrowserMouseEvent & )
226 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
229 //-------------------------------------------------------------------
231 long BrowseBox::QueryMinimumRowHeight()
233 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
234 return CalcZoom( 5 );
237 //-------------------------------------------------------------------
239 void BrowseBox::ImplStartTracking()
241 DBG_CHKTHIS( BrowseBox, BrowseBoxCheckInvariants );
244 //-------------------------------------------------------------------
246 void BrowseBox::ImplTracking()
248 DBG_CHKTHIS( BrowseBox, BrowseBoxCheckInvariants );
251 //-------------------------------------------------------------------
253 void BrowseBox::ImplEndTracking()
255 DBG_CHKTHIS( BrowseBox, BrowseBoxCheckInvariants );
258 //-------------------------------------------------------------------
260 void BrowseBox::RowHeightChanged()
262 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
265 //-------------------------------------------------------------------
267 long BrowseBox::QueryColumnResize( sal_uInt16, long nWidth )
269 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
270 return nWidth;
273 //-------------------------------------------------------------------
275 void BrowseBox::ColumnResized( sal_uInt16 )
277 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
280 //-------------------------------------------------------------------
282 void BrowseBox::ColumnMoved( sal_uInt16 )
284 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
287 //-------------------------------------------------------------------
289 void BrowseBox::StartScroll()
291 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
292 DoHideCursor( "StartScroll" );
295 //-------------------------------------------------------------------
297 void BrowseBox::EndScroll()
299 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
300 UpdateScrollbars();
301 AutoSizeLastColumn();
302 DoShowCursor( "EndScroll" );
305 //-------------------------------------------------------------------
307 void BrowseBox::ToggleSelection( sal_Bool bForce )
309 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
311 // selection highlight-toggling allowed?
312 if ( bHideSelect )
313 return;
314 if ( !bForce &&
315 ( bNotToggleSel || !IsUpdateMode() || !bSelectionIsVisible ) )
316 return;
318 // only highlight painted areas!
319 bNotToggleSel = sal_True;
320 if ( sal_False && !getDataWindow()->bInPaint )
321 pDataWin->Update();
323 // accumulate areas of rows to highlight
324 RectangleList aHighlightList;
325 long nLastRowInRect = 0; // for the CFront
327 // don't highlight handle column
328 BrowserColumn *pFirstCol = pCols->empty() ? NULL : (*pCols)[ 0 ];
329 long nOfsX = (!pFirstCol || pFirstCol->GetId()) ? 0 : pFirstCol->Width();
331 // accumulate old row selection
332 long nBottomRow = nTopRow +
333 pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight();
334 if ( nBottomRow > GetRowCount() && GetRowCount() )
335 nBottomRow = GetRowCount();
336 for ( long nRow = bMultiSelection ? uRow.pSel->FirstSelected() : uRow.nSel;
337 nRow != BROWSER_ENDOFSELECTION && nRow <= nBottomRow;
338 nRow = bMultiSelection ? uRow.pSel->NextSelected() : BROWSER_ENDOFSELECTION )
340 if ( nRow < nTopRow )
341 continue;
343 Rectangle aAddRect(
344 Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
345 Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
346 if ( aHighlightList.size() && nLastRowInRect == ( nRow - 1 ) )
347 aHighlightList[ 0 ]->Union( aAddRect );
348 else
349 aHighlightList.insert( aHighlightList.begin(), new Rectangle( aAddRect ) );
350 nLastRowInRect = nRow;
353 // unhighlight the old selection (if any)
354 for ( size_t i = aHighlightList.size(); i > 0; )
356 Rectangle *pRect = aHighlightList[ --i ];
357 pDataWin->Invalidate( *pRect );
358 delete pRect;
360 aHighlightList.clear();
362 // unhighlight old column selection (if any)
363 for ( long nColId = pColSel ? pColSel->FirstSelected() : BROWSER_ENDOFSELECTION;
364 nColId != BROWSER_ENDOFSELECTION;
365 nColId = pColSel->NextSelected() )
367 Rectangle aRect( GetFieldRectPixel(nCurRow,
368 (*pCols)[ nColId ]->GetId(),
369 sal_False ) );
370 aRect.Left() -= MIN_COLUMNWIDTH;
371 aRect.Right() += MIN_COLUMNWIDTH;
372 aRect.Top() = 0;
373 aRect.Bottom() = pDataWin->GetOutputSizePixel().Height();
374 pDataWin->Invalidate( aRect );
377 bNotToggleSel = sal_False;
380 //-------------------------------------------------------------------
382 void BrowseBox::DrawCursor()
384 sal_Bool bReallyHide = sal_False;
385 if ( SMART_CURSOR_HIDE == bHideCursor )
387 if ( !GetSelectRowCount() && !GetSelectColumnCount() )
388 bReallyHide = sal_True;
390 else if ( HARD_CURSOR_HIDE == bHideCursor )
392 bReallyHide = sal_True;
395 bReallyHide |= !bSelectionIsVisible || !IsUpdateMode() || bScrolling || nCurRow < 0;
397 if (PaintCursorIfHiddenOnce())
398 bReallyHide |= ( GetCursorHideCount() > 1 );
399 else
400 bReallyHide |= ( GetCursorHideCount() > 0 );
402 // no cursor on handle column
403 if ( nCurColId == HandleColumnId )
404 nCurColId = GetColumnId(1);
406 // calculate cursor rectangle
407 Rectangle aCursor;
408 if ( bColumnCursor )
410 aCursor = GetFieldRectPixel( nCurRow, nCurColId, sal_False );
411 aCursor.Left() -= MIN_COLUMNWIDTH;
412 aCursor.Right() += 1;
413 aCursor.Bottom() += 1;
415 else
416 aCursor = Rectangle(
417 Point( ( !pCols->empty() && (*pCols)[ 0 ]->GetId() == 0 ) ?
418 (*pCols)[ 0 ]->Width() : 0,
419 (nCurRow - nTopRow) * GetDataRowHeight() + 1 ),
420 Size( pDataWin->GetOutputSizePixel().Width() + 1,
421 GetDataRowHeight() - 2 ) );
422 if ( bHLines )
424 if ( !bMultiSelection )
425 --aCursor.Top();
426 --aCursor.Bottom();
429 if (m_aCursorColor == COL_TRANSPARENT)
431 // on these platforms, the StarView focus works correctly
432 if ( bReallyHide )
433 ((Control*)pDataWin)->HideFocus();
434 else
435 ((Control*)pDataWin)->ShowFocus( aCursor );
437 else
439 Color rCol = bReallyHide ? pDataWin->GetFillColor() : m_aCursorColor;
440 Color aOldFillColor = pDataWin->GetFillColor();
441 Color aOldLineColor = pDataWin->GetLineColor();
442 pDataWin->SetFillColor();
443 pDataWin->SetLineColor( rCol );
444 pDataWin->DrawRect( aCursor );
445 pDataWin->SetLineColor( aOldLineColor );
446 pDataWin->SetFillColor( aOldFillColor );
450 //-------------------------------------------------------------------
452 sal_uLong BrowseBox::GetColumnWidth( sal_uInt16 nId ) const
454 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
456 sal_uInt16 nItemPos = GetColumnPos( nId );
457 if ( nItemPos >= pCols->size() )
458 return 0;
459 return (*pCols)[ nItemPos ]->Width();
462 //-------------------------------------------------------------------
464 sal_uInt16 BrowseBox::GetColumnId( sal_uInt16 nPos ) const
466 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
468 if ( nPos >= pCols->size() )
469 return BROWSER_INVALIDID;
470 return (*pCols)[ nPos ]->GetId();
473 //-------------------------------------------------------------------
475 sal_uInt16 BrowseBox::GetColumnPos( sal_uInt16 nId ) const
477 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
479 for ( sal_uInt16 nPos = 0; nPos < pCols->size(); ++nPos )
480 if ( (*pCols)[ nPos ]->GetId() == nId )
481 return nPos;
482 return BROWSER_INVALIDID;
485 //-------------------------------------------------------------------
487 sal_Bool BrowseBox::IsFrozen( sal_uInt16 nColumnId ) const
489 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
491 for ( size_t nPos = 0; nPos < pCols->size(); ++nPos )
492 if ( (*pCols)[ nPos ]->GetId() == nColumnId )
493 return (*pCols)[ nPos ]->IsFrozen();
494 return sal_False;
497 //-------------------------------------------------------------------
499 void BrowseBox::ExpandRowSelection( const BrowserMouseEvent& rEvt )
501 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
503 DoHideCursor( "ExpandRowSelection" );
505 // expand the last selection
506 if ( bMultiSelection )
508 Range aJustifiedRange( aSelRange );
509 aJustifiedRange.Justify();
511 sal_Bool bSelectThis = ( bSelect != aJustifiedRange.IsInside( rEvt.GetRow() ) );
513 if ( aJustifiedRange.IsInside( rEvt.GetRow() ) )
515 // down and up
516 while ( rEvt.GetRow() < aSelRange.Max() )
517 { // ZTC/Mac bug - don't put these statements together!
518 SelectRow( aSelRange.Max(), bSelectThis, sal_True );
519 --aSelRange.Max();
521 while ( rEvt.GetRow() > aSelRange.Max() )
522 { // ZTC/Mac bug - don't put these statements together!
523 SelectRow( aSelRange.Max(), bSelectThis, sal_True );
524 ++aSelRange.Max();
527 else
529 // up and down
530 sal_Bool bOldSelecting = bSelecting;
531 bSelecting = sal_True;
532 while ( rEvt.GetRow() < aSelRange.Max() )
533 { // ZTC/Mac bug - don't put these statements together!
534 --aSelRange.Max();
535 if ( !IsRowSelected( aSelRange.Max() ) )
537 SelectRow( aSelRange.Max(), bSelectThis, sal_True );
538 bSelect = sal_True;
541 while ( rEvt.GetRow() > aSelRange.Max() )
542 { // ZTC/Mac bug - don't put these statements together!
543 ++aSelRange.Max();
544 if ( !IsRowSelected( aSelRange.Max() ) )
546 SelectRow( aSelRange.Max(), bSelectThis, sal_True );
547 bSelect = sal_True;
550 bSelecting = bOldSelecting;
551 if ( bSelect )
552 Select();
555 else
556 if ( !bMultiSelection || !IsRowSelected( rEvt.GetRow() ) )
557 SelectRow( rEvt.GetRow(), sal_True );
559 GoToRow( rEvt.GetRow(), sal_False );
560 DoShowCursor( "ExpandRowSelection" );
563 //-------------------------------------------------------------------
565 void BrowseBox::Resize()
567 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
568 if ( !bBootstrapped && IsReallyVisible() )
569 BrowseBox::StateChanged( STATE_CHANGE_INITSHOW );
570 if ( pCols->empty() )
572 getDataWindow()->bResizeOnPaint = sal_True;
573 return;
575 getDataWindow()->bResizeOnPaint = sal_False;
577 // calc the size of the scrollbars
578 // (we can't ask the scrollbars for their widths cause if we're zoomed they still have to be
579 // resized - which is done in UpdateScrollbars)
580 sal_uLong nSBSize = GetSettings().GetStyleSettings().GetScrollBarSize();
581 if (IsZoom())
582 nSBSize = (sal_uLong)(nSBSize * (double)GetZoom());
584 DoHideCursor( "Resize" );
585 sal_uInt16 nOldVisibleRows = 0;
586 //fdo#42694, post #i111125# GetDataRowHeight() can be 0
587 if (GetDataRowHeight())
588 nOldVisibleRows = (sal_uInt16)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
590 // did we need a horizontal scroll bar or is there a Control Area?
591 if ( !getDataWindow()->bNoHScroll &&
592 ( ( pCols->size() - FrozenColCount() ) > 1 ) )
593 aHScroll.Show();
594 else
595 aHScroll.Hide();
597 // calculate the size of the data window
598 long nDataHeight = GetOutputSizePixel().Height() - GetTitleHeight();
599 if ( aHScroll.IsVisible() || ( nControlAreaWidth != USHRT_MAX ) )
600 nDataHeight -= nSBSize;
602 long nDataWidth = GetOutputSizePixel().Width();
603 if ( pVScroll->IsVisible() )
604 nDataWidth -= nSBSize;
606 // adjust position and size of data window
607 pDataWin->SetPosSizePixel(
608 Point( 0, GetTitleHeight() ),
609 Size( nDataWidth, nDataHeight ) );
611 sal_uInt16 nVisibleRows = 0;
613 if (GetDataRowHeight())
614 nVisibleRows = (sal_uInt16)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
616 // TopRow is unchanged, but the number of visible lines has changed.
617 if ( nVisibleRows != nOldVisibleRows )
618 VisibleRowsChanged(nTopRow, nVisibleRows);
620 UpdateScrollbars();
622 // Control-Area
623 Rectangle aInvalidArea( GetControlArea() );
624 aInvalidArea.Right() = GetOutputSizePixel().Width();
625 aInvalidArea.Left() = 0;
626 Invalidate( aInvalidArea );
628 // external header-bar
629 HeaderBar* pHeaderBar = getDataWindow()->pHeaderBar;
630 if ( pHeaderBar )
632 // take the handle column into account
633 BrowserColumn *pFirstCol = (*pCols)[ 0 ];
634 long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
635 pHeaderBar->SetPosSizePixel( Point( nOfsX, 0 ), Size( GetOutputSizePixel().Width() - nOfsX, GetTitleHeight() ) );
638 AutoSizeLastColumn(); // adjust last column width
639 DoShowCursor( "Resize" );
642 //-------------------------------------------------------------------
644 void BrowseBox::Paint( const Rectangle& rRect )
646 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
648 // initializations
649 if ( !bBootstrapped && IsReallyVisible() )
650 BrowseBox::StateChanged( STATE_CHANGE_INITSHOW );
651 if ( pCols->empty() )
652 return;
654 BrowserColumn *pFirstCol = (*pCols)[ 0 ];
655 sal_Bool bHandleCol = pFirstCol && pFirstCol->GetId() == 0;
656 sal_Bool bHeaderBar = getDataWindow()->pHeaderBar != NULL;
658 // draw delimitational lines
659 if ( !getDataWindow()->bNoHScroll )
660 DrawLine( Point( 0, aHScroll.GetPosPixel().Y() ),
661 Point( GetOutputSizePixel().Width(),
662 aHScroll.GetPosPixel().Y() ) );
664 if ( nTitleLines )
666 if ( !bHeaderBar )
667 DrawLine( Point( 0, GetTitleHeight() - 1 ),
668 Point( GetOutputSizePixel().Width(),
669 GetTitleHeight() - 1 ) );
670 else if ( bHandleCol )
671 DrawLine( Point( 0, GetTitleHeight() - 1 ),
672 Point( pFirstCol->Width(), GetTitleHeight() - 1 ) );
675 // Title Bar
676 // If there is a handle column and if the header bar is available, only
677 // take the HandleColumn into account
678 if ( nTitleLines && (!bHeaderBar || bHandleCol) )
680 // iterate through columns to redraw
681 long nX = 0;
682 size_t nCol;
683 for ( nCol = 0;
684 nCol < pCols->size() && nX < rRect.Right();
685 ++nCol )
687 // skip invisible columns between frozen and scrollable area
688 if ( nCol < nFirstCol && !(*pCols)[ nCol ]->IsFrozen() )
689 nCol = nFirstCol;
691 // only the handle column?
692 if (bHeaderBar && bHandleCol && nCol > 0)
693 break;
695 BrowserColumn *pCol = (*pCols)[ nCol ];
697 // draw the column and increment position
698 if ( pCol->Width() > 4 )
700 ButtonFrame aButtonFrame( Point( nX, 0 ),
701 Size( pCol->Width()-1, GetTitleHeight()-1 ),
702 pCol->Title(), sal_False, sal_False, !IsEnabled());
703 aButtonFrame.Draw( *this );
704 DrawLine( Point( nX + pCol->Width() - 1, 0 ),
705 Point( nX + pCol->Width() - 1, GetTitleHeight()-1 ) );
707 else
709 Color aOldFillColor = GetFillColor();
710 SetFillColor( Color( COL_BLACK ) );
711 DrawRect( Rectangle( Point( nX, 0 ), Size( pCol->Width(), GetTitleHeight() - 1 ) ) );
712 SetFillColor( aOldFillColor );
715 // skip column
716 nX += pCol->Width();
719 // retouching
720 if ( !bHeaderBar && nCol == pCols->size() )
722 const StyleSettings &rSettings = GetSettings().GetStyleSettings();
723 Color aColFace( rSettings.GetFaceColor() );
724 Color aOldFillColor = GetFillColor();
725 Color aOldLineColor = GetLineColor();
726 SetFillColor( aColFace );
727 SetLineColor( aColFace );
728 DrawRect( Rectangle(
729 Point( nX, 0 ),
730 Point( rRect.Right(), GetTitleHeight() - 2 ) ) );
731 SetFillColor( aOldFillColor);
732 SetLineColor( aOldLineColor);
737 //-------------------------------------------------------------------
739 void BrowseBox::PaintRow( OutputDevice&, const Rectangle& )
743 //-------------------------------------------------------------------
745 void BrowseBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
747 sal_Bool bDrawSelection = (nFlags & WINDOW_DRAW_NOSELECTION) == 0;
749 // we need pixel coordinates
750 Size aRealSize = pDev->LogicToPixel(rSize);
751 Point aRealPos = pDev->LogicToPixel(rPos);
753 if ((rSize.Width() < 3) || (rSize.Height() < 3))
754 // we want to have two pixels frame ...
755 return;
757 Font aFont = GetDataWindow().GetDrawPixelFont( pDev );
758 // the 'normal' painting uses always the data window as device to output to, so we have to calc the new font
759 // relative to the data wins current settings
761 pDev->Push();
762 pDev->SetMapMode();
763 pDev->SetFont( aFont );
765 // draw a frame
766 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
767 pDev->SetLineColor(rStyleSettings.GetDarkShadowColor());
768 pDev->DrawLine(Point(aRealPos.X(), aRealPos.Y()),
769 Point(aRealPos.X(), aRealPos.Y() + aRealSize.Height() - 1));
770 pDev->DrawLine(Point(aRealPos.X(), aRealPos.Y()),
771 Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y()));
772 pDev->SetLineColor(rStyleSettings.GetShadowColor());
773 pDev->DrawLine(Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y() + 1),
774 Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y() + aRealSize.Height() - 1));
775 pDev->DrawLine(Point(aRealPos.X() + aRealSize.Width() - 1, aRealPos.Y() + aRealSize.Height() - 1),
776 Point(aRealPos.X() + 1, aRealPos.Y() + aRealSize.Height() - 1));
778 HeaderBar* pBar = getDataWindow()->pHeaderBar;
780 // we're drawing onto a foreign device, so we have to fake the DataRowHeight for the subsequent ImplPaintData
781 // (as it is based on the settings of our data window, not the foreign device)
782 if (!nDataRowHeight)
783 ImpGetDataRowHeight();
784 long nHeightLogic = PixelToLogic(Size(0, nDataRowHeight), MAP_10TH_MM).Height();
785 long nForeignHeightPixel = pDev->LogicToPixel(Size(0, nHeightLogic), MAP_10TH_MM).Height();
787 long nOriginalHeight = nDataRowHeight;
788 nDataRowHeight = nForeignHeightPixel;
790 // this counts for the column widths, too
791 size_t nPos;
792 for ( nPos = 0; nPos < pCols->size(); ++nPos )
794 BrowserColumn* pCurrent = (*pCols)[ nPos ];
796 long nWidthLogic = PixelToLogic(Size(pCurrent->Width(), 0), MAP_10TH_MM).Width();
797 long nForeignWidthPixel = pDev->LogicToPixel(Size(nWidthLogic, 0), MAP_10TH_MM).Width();
799 pCurrent->SetWidth(nForeignWidthPixel, GetZoom());
800 if ( pBar )
801 pBar->SetItemSize( pCurrent->GetId(), pCurrent->Width() );
804 // a smaller area for the content
805 ++aRealPos.X();
806 ++aRealPos.Y();
807 aRealSize.Width() -= 2;
808 aRealSize.Height() -= 2;
810 // let the header bar draw itself
811 if ( pBar )
813 // the title height with respect to the font set for the given device
814 long nTitleHeight = PixelToLogic(Size(0, GetTitleHeight()), MAP_10TH_MM).Height();
815 nTitleHeight = pDev->LogicToPixel(Size(0, nTitleHeight), MAP_10TH_MM).Height();
817 BrowserColumn* pFirstCol = !pCols->empty() ? (*pCols)[ 0 ] : NULL;
819 Point aHeaderPos(pFirstCol && (pFirstCol->GetId() == 0) ? pFirstCol->Width() : 0, 0);
820 Size aHeaderSize(aRealSize.Width() - aHeaderPos.X(), nTitleHeight);
822 aHeaderPos += aRealPos;
823 // do this before converting to logics !
825 // the header's draw expects logic coordinates, again
826 aHeaderPos = pDev->PixelToLogic(aHeaderPos);
827 aHeaderSize = pDev->PixelToLogic(aHeaderSize);
829 pBar->Draw(pDev, aHeaderPos, aHeaderSize, nFlags);
831 // draw the "upper left cell" (the intersection between the header bar and the handle column)
832 if (( pFirstCol->GetId() == 0 ) && ( pFirstCol->Width() > 4 ))
834 ButtonFrame aButtonFrame( aRealPos,
835 Size( pFirstCol->Width()-1, nTitleHeight-1 ),
836 pFirstCol->Title(), sal_False, sal_False, !IsEnabled());
837 aButtonFrame.Draw( *pDev );
839 pDev->Push( PUSH_LINECOLOR );
840 pDev->SetLineColor( Color( COL_BLACK ) );
842 pDev->DrawLine( Point( aRealPos.X(), aRealPos.Y() + nTitleHeight-1 ),
843 Point( aRealPos.X() + pFirstCol->Width() - 1, aRealPos.Y() + nTitleHeight-1 ) );
844 pDev->DrawLine( Point( aRealPos.X() + pFirstCol->Width() - 1, aRealPos.Y() ),
845 Point( aRealPos.X() + pFirstCol->Width() - 1, aRealPos.Y() + nTitleHeight-1 ) );
847 pDev->Pop();
850 aRealPos.Y() += aHeaderSize.Height();
851 aRealSize.Height() -= aHeaderSize.Height();
854 // draw our own content (with clipping)
855 Region aRegion(Rectangle(aRealPos, aRealSize));
856 pDev->SetClipRegion( pDev->PixelToLogic( aRegion ) );
858 // do we have to paint the background
859 sal_Bool bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && GetDataWindow().IsControlBackground();
860 if ( bBackground )
862 Rectangle aRect( aRealPos, aRealSize );
863 pDev->SetFillColor( GetDataWindow().GetControlBackground() );
864 pDev->DrawRect( aRect );
867 ImplPaintData( *pDev, Rectangle( aRealPos, aRealSize ), sal_True, bDrawSelection );
869 // restore the column widths/data row height
870 nDataRowHeight = nOriginalHeight;
871 for ( nPos = 0; nPos < pCols->size(); ++nPos )
873 BrowserColumn* pCurrent = (*pCols)[ nPos ];
875 long nForeignWidthLogic = pDev->PixelToLogic(Size(pCurrent->Width(), 0), MAP_10TH_MM).Width();
876 long nWidthPixel = LogicToPixel(Size(nForeignWidthLogic, 0), MAP_10TH_MM).Width();
878 pCurrent->SetWidth(nWidthPixel, GetZoom());
879 if ( pBar )
880 pBar->SetItemSize( pCurrent->GetId(), pCurrent->Width() );
883 pDev->Pop();
886 //-------------------------------------------------------------------
888 void BrowseBox::ImplPaintData(OutputDevice& _rOut, const Rectangle& _rRect, sal_Bool _bForeignDevice, sal_Bool _bDrawSelections)
890 Point aOverallAreaPos = _bForeignDevice ? _rRect.TopLeft() : Point(0,0);
891 Size aOverallAreaSize = _bForeignDevice ? _rRect.GetSize() : GetDataWindow().GetOutputSizePixel();
892 Point aOverallAreaBRPos = _bForeignDevice ? _rRect.BottomRight() : Point( aOverallAreaSize.Width(), aOverallAreaSize.Height() );
894 long nDataRowHeigt = GetDataRowHeight();
896 // compute relative rows to redraw
897 sal_uLong nRelTopRow = 0;
898 sal_uLong nRelBottomRow = aOverallAreaSize.Height();
899 if (!_bForeignDevice && nDataRowHeigt)
901 nRelTopRow = ((sal_uLong)_rRect.Top() / nDataRowHeigt);
902 nRelBottomRow = (sal_uLong)(_rRect.Bottom()) / nDataRowHeigt;
905 // cache frequently used values
906 Point aPos( aOverallAreaPos.X(), nRelTopRow * nDataRowHeigt + aOverallAreaPos.Y() );
907 _rOut.SetLineColor( Color( COL_WHITE ) );
908 const AllSettings& rAllSets = _rOut.GetSettings();
909 const StyleSettings &rSettings = rAllSets.GetStyleSettings();
910 const Color &rHighlightTextColor = rSettings.GetHighlightTextColor();
911 const Color &rHighlightFillColor = rSettings.GetHighlightColor();
912 Color aOldTextColor = _rOut.GetTextColor();
913 Color aOldFillColor = _rOut.GetFillColor();
914 Color aOldLineColor = _rOut.GetLineColor();
915 long nHLineX = 0 == (*pCols)[ 0 ]->GetId() ? (*pCols)[ 0 ]->Width() : 0;
916 nHLineX += aOverallAreaPos.X();
918 Color aDelimiterLineColor( ::svtools::ColorConfig().GetColorValue( ::svtools::CALCGRID ).nColor );
920 // redraw the invalid fields
921 for ( sal_uLong nRelRow = nRelTopRow;
922 nRelRow <= nRelBottomRow && (sal_uLong)nTopRow+nRelRow < (sal_uLong)nRowCount;
923 ++nRelRow, aPos.Y() += nDataRowHeigt )
925 // get row
926 // check valid area, to be on the safe side:
927 DBG_ASSERT( (sal_uInt16)(nTopRow+nRelRow) < nRowCount, "BrowseBox::ImplPaintData: invalid seek" );
928 if ( (nTopRow+long(nRelRow)) < 0 || (sal_uInt16)(nTopRow+nRelRow) >= nRowCount )
929 continue;
931 // prepare row
932 sal_uLong nRow = nTopRow+nRelRow;
933 if ( !SeekRow( nRow) ) {
934 OSL_FAIL("BrowseBox::ImplPaintData: SeekRow failed");
936 _rOut.SetClipRegion();
937 aPos.X() = aOverallAreaPos.X();
940 // #73325# don't paint the row outside the painting rectangle (DG)
941 // prepare auto-highlight
942 Rectangle aRowRect( Point( _rRect.TopLeft().X(), aPos.Y() ),
943 Size( _rRect.GetSize().Width(), nDataRowHeigt ) );
944 PaintRow( _rOut, aRowRect );
946 sal_Bool bRowSelected = _bDrawSelections
947 && !bHideSelect
948 && IsRowSelected( nRow );
949 if ( bRowSelected )
951 _rOut.SetTextColor( rHighlightTextColor );
952 _rOut.SetFillColor( rHighlightFillColor );
953 _rOut.SetLineColor();
954 _rOut.DrawRect( aRowRect );
957 // iterate through columns to redraw
958 size_t nCol;
959 for ( nCol = 0; nCol < pCols->size(); ++nCol )
961 // get column
962 BrowserColumn *pCol = (*pCols)[ nCol ];
964 // at end of invalid area
965 if ( aPos.X() >= _rRect.Right() )
966 break;
968 // skip invisible colums between frozen and scrollable area
969 if ( nCol < nFirstCol && !pCol->IsFrozen() )
971 nCol = nFirstCol;
972 pCol = (nCol < pCols->size() ) ? (*pCols)[ nCol ] : NULL;
973 if (!pCol)
974 { // FS - 21.05.99 - 66325
975 // actually this has been fixed elsewhere (in the right place),
976 // but let's make sure...
977 OSL_FAIL("BrowseBox::PaintData : nFirstCol is probably invalid !");
978 break;
982 // prepare Column-AutoHighlight
983 sal_Bool bColAutoHighlight = _bDrawSelections
984 && bColumnCursor
985 && IsColumnSelected( pCol->GetId() );
986 if ( bColAutoHighlight )
988 _rOut.SetClipRegion();
989 _rOut.SetTextColor( rHighlightTextColor );
990 _rOut.SetFillColor( rHighlightFillColor );
991 _rOut.SetLineColor();
992 Rectangle aFieldRect( aPos,
993 Size( pCol->Width(), nDataRowHeigt ) );
994 _rOut.DrawRect( aFieldRect );
997 if (!m_bFocusOnlyCursor && (pCol->GetId() == GetCurColumnId()) && (nRow == (sal_uLong)GetCurRow()))
998 DrawCursor();
1000 // draw a single field.
1001 // else something is drawn to, e.g. handle column
1002 if (pCol->Width())
1004 // clip the column's output to the field area
1005 if (_bForeignDevice)
1006 { // (not necessary if painting onto the data window)
1007 Size aFieldSize(pCol->Width(), nDataRowHeigt);
1009 if (aPos.X() + aFieldSize.Width() > aOverallAreaBRPos.X())
1010 aFieldSize.Width() = aOverallAreaBRPos.X() - aPos.X();
1012 if (aPos.Y() + aFieldSize.Height() > aOverallAreaBRPos.Y() + 1)
1014 // for non-handle cols we don't clip vertically : we just don't draw the cell if the line isn't completely visible
1015 if (pCol->GetId() != 0)
1016 continue;
1017 aFieldSize.Height() = aOverallAreaBRPos.Y() + 1 - aPos.Y();
1020 Region aClipToField(Rectangle(aPos, aFieldSize));
1021 _rOut.SetClipRegion(aClipToField);
1023 pCol->Draw( *this, _rOut, aPos, sal_False );
1024 if (_bForeignDevice)
1025 _rOut.SetClipRegion();
1028 // reset Column-auto-highlight
1029 if ( bColAutoHighlight )
1031 _rOut.SetTextColor( aOldTextColor );
1032 _rOut.SetFillColor( aOldFillColor );
1033 _rOut.SetLineColor( aOldLineColor );
1036 // skip column
1037 aPos.X() += pCol->Width();
1040 // reset auto-highlight
1041 if ( bRowSelected )
1043 _rOut.SetTextColor( aOldTextColor );
1044 _rOut.SetFillColor( aOldFillColor );
1045 _rOut.SetLineColor( aOldLineColor );
1048 if ( bHLines )
1050 // draw horizontal delimitation lines
1051 _rOut.SetClipRegion();
1052 _rOut.Push( PUSH_LINECOLOR );
1053 _rOut.SetLineColor( aDelimiterLineColor );
1054 long nY = aPos.Y() + nDataRowHeigt - 1;
1055 if (nY <= aOverallAreaBRPos.Y())
1056 _rOut.DrawLine( Point( nHLineX, nY ),
1057 Point( bVLines
1058 ? std::min(long(long(aPos.X()) - 1), aOverallAreaBRPos.X())
1059 : aOverallAreaBRPos.X(),
1060 nY ) );
1061 _rOut.Pop();
1065 if (aPos.Y() > aOverallAreaBRPos.Y() + 1)
1066 aPos.Y() = aOverallAreaBRPos.Y() + 1;
1067 // needed for some of the following drawing
1069 // retouching
1070 _rOut.SetClipRegion();
1071 aOldLineColor = _rOut.GetLineColor();
1072 aOldFillColor = _rOut.GetFillColor();
1073 _rOut.SetFillColor( rSettings.GetFaceColor() );
1074 if ( !pCols->empty() && ( (*pCols)[ 0 ]->GetId() == 0 ) && ( aPos.Y() <= _rRect.Bottom() ) )
1076 // fill rectangle gray below handle column
1077 // DG: fill it only until the end of the drawing rect and not to the end, as this may overpaint handle columns
1078 _rOut.SetLineColor( Color( COL_BLACK ) );
1079 _rOut.DrawRect( Rectangle(
1080 Point( aOverallAreaPos.X() - 1, aPos.Y() - 1 ),
1081 Point( aOverallAreaPos.X() + (*pCols)[ 0 ]->Width() - 1,
1082 _rRect.Bottom() + 1) ) );
1084 _rOut.SetFillColor( aOldFillColor );
1086 // draw vertical delimitational line between frozen and scrollable cols
1087 _rOut.SetLineColor( COL_BLACK );
1088 long nFrozenWidth = GetFrozenWidth()-1;
1089 _rOut.DrawLine( Point( aOverallAreaPos.X() + nFrozenWidth, aPos.Y() ),
1090 Point( aOverallAreaPos.X() + nFrozenWidth, bHLines
1091 ? aPos.Y() - 1
1092 : aOverallAreaBRPos.Y() ) );
1094 // draw vertical delimitational lines?
1095 if ( bVLines )
1097 _rOut.SetLineColor( aDelimiterLineColor );
1098 Point aVertPos( aOverallAreaPos.X() - 1, aOverallAreaPos.Y() );
1099 long nDeltaY = aOverallAreaBRPos.Y();
1100 for ( size_t nCol = 0; nCol < pCols->size(); ++nCol )
1102 // get column
1103 BrowserColumn *pCol = (*pCols)[ nCol ];
1105 // skip invisible columns between frozen and scrollable area
1106 if ( nCol < nFirstCol && !pCol->IsFrozen() )
1108 nCol = nFirstCol;
1109 pCol = (*pCols)[ nCol ];
1112 // skip column
1113 aVertPos.X() += pCol->Width();
1115 // at end of invalid area
1116 // invalid area is first reached when X > Right
1117 // and not >=
1118 if ( aVertPos.X() > _rRect.Right() )
1119 break;
1121 // draw a single line
1122 if ( pCol->GetId() != 0 )
1123 _rOut.DrawLine( aVertPos, Point( aVertPos.X(),
1124 bHLines
1125 ? aPos.Y() - 1
1126 : aPos.Y() + nDeltaY ) );
1130 _rOut.SetLineColor( aOldLineColor );
1133 //-------------------------------------------------------------------
1135 void BrowseBox::PaintData( Window& rWin, const Rectangle& rRect )
1137 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1138 if ( !bBootstrapped && IsReallyVisible() )
1139 BrowseBox::StateChanged( STATE_CHANGE_INITSHOW );
1141 // initializations
1142 if ( !pCols || pCols->empty() || !rWin.IsUpdateMode() )
1143 return;
1144 if ( getDataWindow()->bResizeOnPaint )
1145 Resize();
1146 // MI: who was that? Window::Update();
1148 ImplPaintData(rWin, rRect, sal_False, sal_True);
1151 //-------------------------------------------------------------------
1153 void BrowseBox::UpdateScrollbars()
1155 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1157 if ( !bBootstrapped || !IsUpdateMode() )
1158 return;
1160 // protect against recursion
1161 BrowserDataWin *pBDW = (BrowserDataWin*) pDataWin;
1162 if ( pBDW->bInUpdateScrollbars )
1164 pBDW->bHadRecursion = sal_True;
1165 return;
1167 pBDW->bInUpdateScrollbars = sal_True;
1169 // the size of the corner window (and the width of the VSB/height of the HSB)
1170 sal_uLong nCornerSize = GetSettings().GetStyleSettings().GetScrollBarSize();
1171 if (IsZoom())
1172 nCornerSize = (sal_uLong)(nCornerSize * (double)GetZoom());
1174 sal_Bool bNeedsVScroll = sal_False;
1175 long nMaxRows = 0;
1176 if (GetDataRowHeight())
1178 // needs VScroll?
1179 nMaxRows = (pDataWin->GetSizePixel().Height()) / GetDataRowHeight();
1180 bNeedsVScroll = getDataWindow()->bAutoVScroll
1181 ? nTopRow || ( nRowCount > nMaxRows )
1182 : !getDataWindow()->bNoVScroll;
1184 Size aDataWinSize = pDataWin->GetSizePixel();
1185 if ( !bNeedsVScroll )
1187 if ( pVScroll->IsVisible() )
1189 pVScroll->Hide();
1190 Size aNewSize( aDataWinSize );
1191 aNewSize.Width() = GetOutputSizePixel().Width();
1192 aDataWinSize = aNewSize;
1195 else if ( !pVScroll->IsVisible() )
1197 Size aNewSize( aDataWinSize );
1198 aNewSize.Width() = GetOutputSizePixel().Width() - nCornerSize;
1199 aDataWinSize = aNewSize;
1202 // needs HScroll?
1203 sal_uLong nLastCol = GetColumnAtXPosPixel( aDataWinSize.Width() - 1 );
1205 sal_uInt16 nFrozenCols = FrozenColCount();
1206 sal_Bool bNeedsHScroll = getDataWindow()->bAutoHScroll
1207 ? ( nFirstCol > nFrozenCols ) || ( nLastCol <= pCols->size() )
1208 : !getDataWindow()->bNoHScroll;
1209 if ( !bNeedsHScroll )
1211 if ( aHScroll.IsVisible() )
1213 aHScroll.Hide();
1215 aDataWinSize.Height() = GetOutputSizePixel().Height() - GetTitleHeight();
1216 if ( nControlAreaWidth != USHRT_MAX )
1217 aDataWinSize.Height() -= nCornerSize;
1219 else if ( !aHScroll.IsVisible() )
1221 Size aNewSize( aDataWinSize );
1222 aNewSize.Height() = GetOutputSizePixel().Height() - GetTitleHeight() - nCornerSize;
1223 aDataWinSize = aNewSize;
1226 // adjust position and Width of horizontal scrollbar
1227 sal_uLong nHScrX = nControlAreaWidth == USHRT_MAX
1229 : nControlAreaWidth;
1231 aHScroll.SetPosSizePixel(
1232 Point( nHScrX, GetOutputSizePixel().Height() - nCornerSize ),
1233 Size( aDataWinSize.Width() - nHScrX, nCornerSize ) );
1235 // total scrollable columns
1236 short nScrollCols = short(pCols->size()) - (short)nFrozenCols;
1238 // visible columns
1239 short nVisibleHSize = nLastCol == BROWSER_INVALIDID
1240 ? (short)( pCols->size() - nFirstCol )
1241 : (short)( nLastCol - nFirstCol );
1243 short nRange = std::max( nScrollCols, (short)0 );
1244 aHScroll.SetVisibleSize( nVisibleHSize );
1245 aHScroll.SetRange( Range( 0, nRange ));
1246 if ( bNeedsHScroll && !aHScroll.IsVisible() )
1247 aHScroll.Show();
1249 // adjust position and height of vertical scrollbar
1250 pVScroll->SetPageSize( nMaxRows );
1252 if ( nTopRow > nRowCount )
1254 nTopRow = nRowCount - 1;
1255 OSL_FAIL("BrowseBox: nTopRow > nRowCount");
1258 if ( pVScroll->GetThumbPos() != nTopRow )
1259 pVScroll->SetThumbPos( nTopRow );
1260 long nVisibleSize = std::min( std::min( nRowCount, nMaxRows ), long(nRowCount-nTopRow) );
1261 pVScroll->SetVisibleSize( nVisibleSize ? nVisibleSize : 1 );
1262 pVScroll->SetRange( Range( 0, nRowCount ) );
1263 pVScroll->SetPosSizePixel(
1264 Point( aDataWinSize.Width(), GetTitleHeight() ),
1265 Size( nCornerSize, aDataWinSize.Height()) );
1266 long nLclDataRowHeight = GetDataRowHeight();
1267 if ( nLclDataRowHeight > 0 && nRowCount < long( aDataWinSize.Height() / nLclDataRowHeight ) )
1268 ScrollRows( -nTopRow );
1269 if ( bNeedsVScroll && !pVScroll->IsVisible() )
1270 pVScroll->Show();
1272 pDataWin->SetPosSizePixel(
1273 Point( 0, GetTitleHeight() ),
1274 aDataWinSize );
1276 // needs corner-window?
1277 // (do that AFTER positioning BOTH scrollbars)
1278 sal_uLong nActualCorderWidth = 0;
1279 if (aHScroll.IsVisible() && pVScroll && pVScroll->IsVisible() )
1281 // if we have both scrollbars, the corner window fills the point of intersection of these two
1282 nActualCorderWidth = nCornerSize;
1284 else if ( !aHScroll.IsVisible() && ( nControlAreaWidth != USHRT_MAX ) )
1286 // if we have no horizontal scrollbar, but a control area, we need the corner window to
1287 // fill the space between the control are and the right border
1288 nActualCorderWidth = GetOutputSizePixel().Width() - nControlAreaWidth;
1290 if ( nActualCorderWidth )
1292 if ( !getDataWindow()->pCornerWin )
1293 getDataWindow()->pCornerWin = new ScrollBarBox( this, 0 );
1294 getDataWindow()->pCornerWin->SetPosSizePixel(
1295 Point( GetOutputSizePixel().Width() - nActualCorderWidth, aHScroll.GetPosPixel().Y() ),
1296 Size( nActualCorderWidth, nCornerSize ) );
1297 getDataWindow()->pCornerWin->Show();
1299 else
1300 DELETEZ( getDataWindow()->pCornerWin );
1302 // scroll headerbar, if necessary
1303 if ( getDataWindow()->pHeaderBar )
1305 long nWidth = 0;
1306 for ( size_t nCol = 0;
1307 nCol < pCols->size() && nCol < nFirstCol;
1308 ++nCol )
1310 // not the handle column
1311 if ( (*pCols)[ nCol ]->GetId() )
1312 nWidth += (*pCols)[ nCol ]->Width();
1315 getDataWindow()->pHeaderBar->SetOffset( nWidth );
1318 pBDW->bInUpdateScrollbars = sal_False;
1319 if ( pBDW->bHadRecursion )
1321 pBDW->bHadRecursion = sal_False;
1322 UpdateScrollbars();
1326 //-------------------------------------------------------------------
1328 void BrowseBox::SetUpdateMode( sal_Bool bUpdate )
1330 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1332 sal_Bool bWasUpdate = IsUpdateMode();
1333 if ( bWasUpdate == bUpdate )
1334 return;
1336 Control::SetUpdateMode( bUpdate );
1337 // If WB_CLIPCHILDREN is st at the BrowseBox (to minimize flicker),
1338 // the data window is not invalidated by SetUpdateMode.
1339 if( bUpdate )
1340 getDataWindow()->Invalidate();
1341 getDataWindow()->SetUpdateMode( bUpdate );
1344 if ( bUpdate )
1346 if ( bBootstrapped )
1348 UpdateScrollbars();
1349 AutoSizeLastColumn();
1351 DoShowCursor( "SetUpdateMode" );
1353 else
1354 DoHideCursor( "SetUpdateMode" );
1357 //-------------------------------------------------------------------
1359 sal_Bool BrowseBox::GetUpdateMode() const
1361 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1363 return getDataWindow()->IsUpdateMode();
1366 //-------------------------------------------------------------------
1368 long BrowseBox::GetFrozenWidth() const
1370 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1372 long nWidth = 0;
1373 for ( size_t nCol = 0;
1374 nCol < pCols->size() && (*pCols)[ nCol ]->IsFrozen();
1375 ++nCol )
1376 nWidth += (*pCols)[ nCol ]->Width();
1377 return nWidth;
1380 //-------------------------------------------------------------------
1382 void BrowseBox::ColumnInserted( sal_uInt16 nPos )
1384 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1386 if ( pColSel )
1387 pColSel->Insert( nPos );
1388 UpdateScrollbars();
1391 //-------------------------------------------------------------------
1393 sal_uInt16 BrowseBox::FrozenColCount() const
1395 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1396 sal_uInt16 nCol;
1397 for ( nCol = 0;
1398 nCol < pCols->size() && (*pCols)[ nCol ]->IsFrozen();
1399 ++nCol )
1400 /* empty loop */;
1401 return nCol;
1404 //-------------------------------------------------------------------
1406 IMPL_LINK(BrowseBox,ScrollHdl,ScrollBar*,pBar)
1408 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1410 if ( pBar->GetDelta() == 0 )
1411 return 0;
1413 if ( pBar->GetDelta() < 0 && getDataWindow()->bNoScrollBack )
1415 UpdateScrollbars();
1416 return 0;
1419 if ( pBar == &aHScroll )
1420 ScrollColumns( aHScroll.GetDelta() );
1421 if ( pBar == pVScroll )
1422 ScrollRows( pVScroll->GetDelta() );
1424 return 0;
1427 //-------------------------------------------------------------------
1429 IMPL_LINK_NOARG(BrowseBox, EndScrollHdl)
1431 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1433 if ( getDataWindow()->bNoScrollBack )
1435 EndScroll();
1436 return 0;
1439 return 0;
1442 //-------------------------------------------------------------------
1444 IMPL_LINK( BrowseBox, StartDragHdl, HeaderBar*, pBar )
1446 pBar->SetDragSize( pDataWin->GetOutputSizePixel().Height() );
1447 return 0;
1450 //-------------------------------------------------------------------
1451 // usually only the first column was resized
1453 void BrowseBox::MouseButtonDown( const MouseEvent& rEvt )
1455 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1457 GrabFocus();
1459 // only mouse events in the title-line are supported
1460 const Point &rEvtPos = rEvt.GetPosPixel();
1461 if ( rEvtPos.Y() >= GetTitleHeight() )
1462 return;
1464 long nX = 0;
1465 long nWidth = GetOutputSizePixel().Width();
1466 for ( size_t nCol = 0; nCol < pCols->size() && nX < nWidth; ++nCol )
1468 // is this column visible?
1469 BrowserColumn *pCol = (*pCols)[ nCol ];
1470 if ( pCol->IsFrozen() || nCol >= nFirstCol )
1472 // compute right end of column
1473 long nR = nX + pCol->Width() - 1;
1475 // at the end of a column (and not handle column)?
1476 if ( pCol->GetId() && std::abs( nR - rEvtPos.X() ) < 2 )
1478 // start resizing the column
1479 bResizing = sal_True;
1480 nResizeCol = nCol;
1481 nDragX = nResizeX = rEvtPos.X();
1482 SetPointer( Pointer( POINTER_HSPLIT ) );
1483 CaptureMouse();
1484 pDataWin->DrawLine( Point( nDragX, 0 ),
1485 Point( nDragX, pDataWin->GetSizePixel().Height() ) );
1486 nMinResizeX = nX + MIN_COLUMNWIDTH;
1487 return;
1489 else if ( nX < rEvtPos.X() && nR > rEvtPos.X() )
1491 MouseButtonDown( BrowserMouseEvent(
1492 this, rEvt, -1, nCol, pCol->GetId(), Rectangle() ) );
1493 return;
1495 nX = nR + 1;
1499 // event occurred out of data area
1500 if ( rEvt.IsRight() )
1501 pDataWin->Command(
1502 CommandEvent( Point( 1, LONG_MAX ), COMMAND_CONTEXTMENU, sal_True ) );
1503 else
1504 SetNoSelection();
1507 //-------------------------------------------------------------------
1509 void BrowseBox::MouseMove( const MouseEvent& rEvt )
1511 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1512 OSL_TRACE( "BrowseBox::MouseMove( MouseEvent )" );
1514 Pointer aNewPointer;
1516 sal_uInt16 nX = 0;
1517 for ( size_t nCol = 0;
1518 nCol < pCols->size() &&
1519 ( nX + (*pCols)[ nCol ]->Width() ) < sal_uInt16(GetOutputSizePixel().Width());
1520 ++nCol )
1521 // is this column visible?
1522 if ( (*pCols)[ nCol ]->IsFrozen() || nCol >= nFirstCol )
1524 // compute right end of column
1525 BrowserColumn *pCol = (*pCols)[ nCol ];
1526 sal_uInt16 nR = (sal_uInt16)(nX + pCol->Width() - 1);
1528 // show resize-pointer?
1529 if ( bResizing || ( pCol->GetId() &&
1530 std::abs( ((long) nR ) - rEvt.GetPosPixel().X() ) < MIN_COLUMNWIDTH ) )
1532 aNewPointer = Pointer( POINTER_HSPLIT );
1533 if ( bResizing )
1535 // delete old auxiliary line
1536 pDataWin->HideTracking() ;
1538 // check allowed width and new delta
1539 nDragX = std::max( rEvt.GetPosPixel().X(), nMinResizeX );
1540 long nDeltaX = nDragX - nResizeX;
1541 sal_uInt16 nId = GetColumnId(nResizeCol);
1542 sal_uLong nOldWidth = GetColumnWidth(nId);
1543 nDragX = QueryColumnResize( GetColumnId(nResizeCol),
1544 nOldWidth + nDeltaX )
1545 + nResizeX - nOldWidth;
1547 // draw new auxiliary line
1548 pDataWin->ShowTracking( Rectangle( Point( nDragX, 0 ),
1549 Size( 1, pDataWin->GetSizePixel().Height() ) ),
1550 SHOWTRACK_SPLIT|SHOWTRACK_WINDOW );
1555 nX = nR + 1;
1558 SetPointer( aNewPointer );
1561 //-------------------------------------------------------------------
1563 void BrowseBox::MouseButtonUp( const MouseEvent & rEvt )
1565 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1567 if ( bResizing )
1569 // delete auxiliary line
1570 pDataWin->HideTracking();
1572 // width changed?
1573 nDragX = std::max( rEvt.GetPosPixel().X(), nMinResizeX );
1574 if ( (nDragX - nResizeX) != (long)(*pCols)[ nResizeCol ]->Width() )
1576 // resize column
1577 long nMaxX = pDataWin->GetSizePixel().Width();
1578 nDragX = std::min( nDragX, nMaxX );
1579 long nDeltaX = nDragX - nResizeX;
1580 sal_uInt16 nId = GetColumnId(nResizeCol);
1581 SetColumnWidth( GetColumnId(nResizeCol), GetColumnWidth(nId) + nDeltaX );
1582 ColumnResized( nId );
1585 // end action
1586 SetPointer( Pointer() );
1587 ReleaseMouse();
1588 bResizing = sal_False;
1590 else
1591 MouseButtonUp( BrowserMouseEvent( (BrowserDataWin*)pDataWin,
1592 MouseEvent( Point( rEvt.GetPosPixel().X(),
1593 rEvt.GetPosPixel().Y() - pDataWin->GetPosPixel().Y() ),
1594 rEvt.GetClicks(), rEvt.GetMode(), rEvt.GetButtons(),
1595 rEvt.GetModifier() ) ) );
1598 //-------------------------------------------------------------------
1600 sal_Bool bExtendedMode = sal_False;
1601 sal_Bool bFieldMode = sal_False;
1603 void BrowseBox::MouseButtonDown( const BrowserMouseEvent& rEvt )
1605 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1607 GrabFocus();
1609 // adjust selection while and after double-click
1610 if ( rEvt.GetClicks() == 2 )
1612 SetNoSelection();
1613 if ( rEvt.GetRow() >= 0 )
1615 GoToRow( rEvt.GetRow() );
1616 SelectRow( rEvt.GetRow(), sal_True, sal_False );
1618 else
1620 if ( bColumnCursor && rEvt.GetColumn() != 0 )
1622 if ( rEvt.GetColumn() < pCols->size() )
1623 SelectColumnPos( rEvt.GetColumn(), sal_True, sal_False);
1626 DoubleClick( rEvt );
1628 // selections
1629 else if ( ( rEvt.GetMode() & ( MOUSE_SELECT | MOUSE_SIMPLECLICK ) ) &&
1630 ( bColumnCursor || rEvt.GetRow() >= 0 ) )
1632 if ( rEvt.GetClicks() == 1 )
1634 // initialise flags
1635 bHit = sal_False;
1636 a1stPoint =
1637 a2ndPoint = PixelToLogic( rEvt.GetPosPixel() );
1639 // selection out of range?
1640 if ( rEvt.GetRow() >= nRowCount ||
1641 rEvt.GetColumnId() == BROWSER_INVALIDID )
1643 SetNoSelection();
1644 return;
1647 // while selecting, no cursor
1648 bSelecting = sal_True;
1649 DoHideCursor( "MouseButtonDown" );
1651 // DataRow?
1652 if ( rEvt.GetRow() >= 0 )
1654 // line selection?
1655 if ( rEvt.GetColumnId() == HandleColumnId || !bColumnCursor )
1657 if ( bMultiSelection )
1659 // remove column-selection, if exists
1660 if ( pColSel && pColSel->GetSelectCount() )
1662 ToggleSelection();
1663 if ( bMultiSelection )
1664 uRow.pSel->SelectAll(sal_False);
1665 else
1666 uRow.nSel = BROWSER_ENDOFSELECTION;
1667 if ( pColSel )
1668 pColSel->SelectAll(sal_False);
1669 bSelect = sal_True;
1672 // expanding mode?
1673 if ( rEvt.GetMode() & MOUSE_RANGESELECT )
1675 // select the further touched rows too
1676 bSelect = sal_True;
1677 ExpandRowSelection( rEvt );
1678 return;
1681 // click in the selected area?
1682 else if ( IsRowSelected( rEvt.GetRow() ) )
1684 // wait for Drag&Drop
1685 bHit = sal_True;
1686 bExtendedMode = MOUSE_MULTISELECT ==
1687 ( rEvt.GetMode() & MOUSE_MULTISELECT );
1688 return;
1691 // extension mode?
1692 else if ( rEvt.GetMode() & MOUSE_MULTISELECT )
1694 // determine the new selection range
1695 // and selection/deselection
1696 aSelRange = Range( rEvt.GetRow(), rEvt.GetRow() );
1697 SelectRow( rEvt.GetRow(),
1698 !uRow.pSel->IsSelected( rEvt.GetRow() ) );
1699 bSelect = sal_True;
1700 return;
1704 // select directly
1705 SetNoSelection();
1706 GoToRow( rEvt.GetRow() );
1707 SelectRow( rEvt.GetRow(), sal_True );
1708 aSelRange = Range( rEvt.GetRow(), rEvt.GetRow() );
1709 bSelect = sal_True;
1711 else // Column/Field-Selection
1713 // click in selected column
1714 if ( IsColumnSelected( rEvt.GetColumn() ) ||
1715 IsRowSelected( rEvt.GetRow() ) )
1717 bHit = sal_True;
1718 bFieldMode = sal_True;
1719 return;
1722 SetNoSelection();
1723 GoToRowColumnId( rEvt.GetRow(), rEvt.GetColumnId() );
1724 bSelect = sal_True;
1727 else
1729 if ( bMultiSelection && rEvt.GetColumnId() == HandleColumnId )
1731 // toggle all-selection
1732 if ( uRow.pSel->GetSelectCount() > ( GetRowCount() / 2 ) )
1733 SetNoSelection();
1734 else
1735 SelectAll();
1737 else
1738 SelectColumnId( rEvt.GetColumnId(), sal_True, sal_False );
1741 // turn cursor on again, if necessary
1742 bSelecting = sal_False;
1743 DoShowCursor( "MouseButtonDown" );
1744 if ( bSelect )
1745 Select();
1750 //-------------------------------------------------------------------
1752 void BrowseBox::MouseMove( const BrowserMouseEvent& )
1754 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1757 //-------------------------------------------------------------------
1759 void BrowseBox::MouseButtonUp( const BrowserMouseEvent &rEvt )
1761 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1763 // D&D was possible, but did not occur
1764 if ( bHit )
1766 aSelRange = Range( rEvt.GetRow(), rEvt.GetRow() );
1767 if ( bExtendedMode )
1768 SelectRow( rEvt.GetRow(), sal_False );
1769 else
1771 SetNoSelection();
1772 if ( bFieldMode )
1773 GoToRowColumnId( rEvt.GetRow(), rEvt.GetColumnId() );
1774 else
1776 GoToRow( rEvt.GetRow() );
1777 SelectRow( rEvt.GetRow(), sal_True );
1780 bSelect = sal_True;
1781 bExtendedMode = sal_False;
1782 bFieldMode = sal_False;
1783 bHit = sal_False;
1786 // activate cursor
1787 if ( bSelecting )
1789 bSelecting = sal_False;
1790 DoShowCursor( "MouseButtonUp" );
1791 if ( bSelect )
1792 Select();
1796 //-------------------------------------------------------------------
1798 void BrowseBox::KeyInput( const KeyEvent& rEvt )
1800 if ( !ProcessKey( rEvt ) )
1801 Control::KeyInput( rEvt );
1804 //-------------------------------------------------------------------
1806 sal_Bool BrowseBox::ProcessKey( const KeyEvent& rEvt )
1808 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1810 sal_uInt16 nCode = rEvt.GetKeyCode().GetCode();
1811 sal_Bool bShift = rEvt.GetKeyCode().IsShift();
1812 sal_Bool bCtrl = rEvt.GetKeyCode().IsMod1();
1813 sal_Bool bAlt = rEvt.GetKeyCode().IsMod2();
1815 sal_uInt16 nId = BROWSER_NONE;
1817 if ( !bAlt && !bCtrl && !bShift )
1819 switch ( nCode )
1821 case KEY_DOWN: nId = BROWSER_CURSORDOWN; break;
1822 case KEY_UP: nId = BROWSER_CURSORUP; break;
1823 case KEY_HOME: nId = BROWSER_CURSORHOME; break;
1824 case KEY_END: nId = BROWSER_CURSOREND; break;
1825 case KEY_TAB:
1826 if ( !bColumnCursor )
1827 break;
1828 case KEY_RIGHT: nId = BROWSER_CURSORRIGHT; break;
1829 case KEY_LEFT: nId = BROWSER_CURSORLEFT; break;
1830 case KEY_SPACE: nId = BROWSER_SELECT; break;
1832 if ( BROWSER_NONE != nId )
1833 SetNoSelection();
1835 switch ( nCode )
1837 case KEY_PAGEDOWN: nId = BROWSER_CURSORPAGEDOWN; break;
1838 case KEY_PAGEUP: nId = BROWSER_CURSORPAGEUP; break;
1842 if ( !bAlt && !bCtrl && bShift )
1843 switch ( nCode )
1845 case KEY_DOWN: nId = BROWSER_SELECTDOWN; break;
1846 case KEY_UP: nId = BROWSER_SELECTUP; break;
1847 case KEY_TAB:
1848 if ( !bColumnCursor )
1849 break;
1850 nId = BROWSER_CURSORLEFT; break;
1851 case KEY_HOME: nId = BROWSER_SELECTHOME; break;
1852 case KEY_END: nId = BROWSER_SELECTEND; break;
1856 if ( !bAlt && bCtrl && !bShift )
1857 switch ( nCode )
1859 case KEY_DOWN: nId = BROWSER_CURSORDOWN; break;
1860 case KEY_UP: nId = BROWSER_CURSORUP; break;
1861 case KEY_PAGEDOWN: nId = BROWSER_CURSORENDOFFILE; break;
1862 case KEY_PAGEUP: nId = BROWSER_CURSORTOPOFFILE; break;
1863 case KEY_HOME: nId = BROWSER_CURSORTOPOFSCREEN; break;
1864 case KEY_END: nId = BROWSER_CURSORENDOFSCREEN; break;
1865 case KEY_SPACE: nId = BROWSER_ENHANCESELECTION; break;
1866 case KEY_LEFT: nId = BROWSER_MOVECOLUMNLEFT; break;
1867 case KEY_RIGHT: nId = BROWSER_MOVECOLUMNRIGHT; break;
1870 if ( nId != BROWSER_NONE )
1871 Dispatch( nId );
1872 return nId != BROWSER_NONE;
1875 //-------------------------------------------------------------------
1877 void BrowseBox::Dispatch( sal_uInt16 nId )
1879 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1881 long nRowsOnPage = pDataWin->GetSizePixel().Height() / GetDataRowHeight();
1882 sal_Bool bDone = sal_False;
1884 switch ( nId )
1886 case BROWSER_SELECTCOLUMN:
1887 if ( ColCount() )
1888 SelectColumnId( GetCurColumnId() );
1889 break;
1891 case BROWSER_CURSORDOWN:
1892 if ( ( GetCurRow() + 1 ) < nRowCount )
1893 bDone = GoToRow( GetCurRow() + 1, sal_False );
1894 break;
1895 case BROWSER_CURSORUP:
1896 if ( GetCurRow() > 0 )
1897 bDone = GoToRow( GetCurRow() - 1, sal_False );
1898 break;
1899 case BROWSER_SELECTHOME:
1900 if ( GetRowCount() )
1902 DoHideCursor( "BROWSER_SELECTHOME" );
1903 for ( long nRow = GetCurRow(); nRow >= 0; --nRow )
1904 SelectRow( nRow );
1905 GoToRow( 0, sal_True );
1906 DoShowCursor( "BROWSER_SELECTHOME" );
1908 break;
1909 case BROWSER_SELECTEND:
1910 if ( GetRowCount() )
1912 DoHideCursor( "BROWSER_SELECTEND" );
1913 long nRows = GetRowCount();
1914 for ( long nRow = GetCurRow(); nRow < nRows; ++nRow )
1915 SelectRow( nRow );
1916 GoToRow( GetRowCount() - 1, sal_True );
1917 DoShowCursor( "BROWSER_SELECTEND" );
1919 break;
1920 case BROWSER_SELECTDOWN:
1922 if ( GetRowCount() && ( GetCurRow() + 1 ) < nRowCount )
1924 // deselect the current row, if it isn't the first
1925 // and there is no other selected row above
1926 long nRow = GetCurRow();
1927 sal_Bool bLocalSelect = ( !IsRowSelected( nRow ) ||
1928 GetSelectRowCount() == 1 || IsRowSelected( nRow - 1 ) );
1929 SelectRow( nRow, bLocalSelect, sal_True );
1930 bDone = GoToRow( GetCurRow() + 1 , sal_False );
1931 if ( bDone )
1932 SelectRow( GetCurRow(), sal_True, sal_True );
1934 else
1935 bDone = ScrollRows( 1 ) != 0;
1936 break;
1938 case BROWSER_SELECTUP:
1939 if ( GetRowCount() )
1941 // deselect the current row, if it isn't the first
1942 // and there is no other selected row under
1943 long nRow = GetCurRow();
1944 sal_Bool bLocalSelect = ( !IsRowSelected( nRow ) ||
1945 GetSelectRowCount() == 1 || IsRowSelected( nRow + 1 ) );
1946 SelectRow( nCurRow, bLocalSelect, sal_True );
1947 bDone = GoToRow( nRow - 1 , sal_False );
1948 if ( bDone )
1949 SelectRow( GetCurRow(), sal_True, sal_True );
1951 break;
1952 case BROWSER_CURSORPAGEDOWN:
1953 bDone = (sal_Bool)ScrollRows( nRowsOnPage );
1954 break;
1955 case BROWSER_CURSORPAGEUP:
1956 bDone = (sal_Bool)ScrollRows( -nRowsOnPage );
1957 break;
1958 case BROWSER_CURSOREND:
1959 if ( bColumnCursor )
1961 sal_uInt16 nNewId = GetColumnId(ColCount() -1);
1962 bDone = nNewId != HandleColumnId && GoToColumnId( nNewId );
1963 break;
1965 case BROWSER_CURSORENDOFFILE:
1966 bDone = GoToRow( nRowCount - 1, sal_False );
1967 break;
1968 case BROWSER_CURSORRIGHT:
1969 if ( bColumnCursor )
1971 sal_uInt16 nNewPos = GetColumnPos( GetCurColumnId() ) + 1;
1972 sal_uInt16 nNewId = GetColumnId( nNewPos );
1973 if (nNewId != BROWSER_INVALIDID) // At end of row ?
1974 bDone = GoToColumnId( nNewId );
1975 else
1977 sal_uInt16 nColId = GetColumnId(0);
1978 if ( nColId == BROWSER_INVALIDID || nColId == HandleColumnId )
1979 nColId = GetColumnId(1);
1980 if ( GetRowCount() )
1981 bDone = ( nCurRow < GetRowCount() - 1 ) && GoToRowColumnId( nCurRow + 1, nColId );
1982 else if ( ColCount() )
1983 GoToColumnId( nColId );
1986 else
1987 bDone = ScrollColumns( 1 ) != 0;
1988 break;
1989 case BROWSER_CURSORHOME:
1990 if ( bColumnCursor )
1992 sal_uInt16 nNewId = GetColumnId(1);
1993 bDone = (nNewId != HandleColumnId) && GoToColumnId( nNewId );
1994 break;
1996 case BROWSER_CURSORTOPOFFILE:
1997 bDone = GoToRow( 0, sal_False );
1998 break;
1999 case BROWSER_CURSORLEFT:
2000 if ( bColumnCursor )
2002 sal_uInt16 nNewPos = GetColumnPos( GetCurColumnId() ) - 1;
2003 sal_uInt16 nNewId = GetColumnId( nNewPos );
2004 if (nNewId != HandleColumnId)
2005 bDone = GoToColumnId( nNewId );
2006 else
2008 if ( GetRowCount() )
2009 bDone = (nCurRow > 0) && GoToRowColumnId(nCurRow - 1, GetColumnId(ColCount() -1));
2010 else if ( ColCount() )
2011 GoToColumnId( GetColumnId(ColCount() -1) );
2014 else
2015 bDone = ScrollColumns( -1 ) != 0;
2016 break;
2017 case BROWSER_ENHANCESELECTION:
2018 if ( GetRowCount() )
2019 SelectRow( GetCurRow(), !IsRowSelected( GetCurRow() ), sal_True );
2020 bDone = sal_True;
2021 break;
2022 case BROWSER_SELECT:
2023 if ( GetRowCount() )
2024 SelectRow( GetCurRow(), !IsRowSelected( GetCurRow() ), sal_False );
2025 bDone = sal_True;
2026 break;
2027 case BROWSER_MOVECOLUMNLEFT:
2028 case BROWSER_MOVECOLUMNRIGHT:
2029 { // check if column moving is allowed
2030 BrowserHeader* pHeaderBar = getDataWindow()->pHeaderBar;
2031 if ( pHeaderBar && pHeaderBar->IsDragable() )
2033 sal_uInt16 nColId = GetCurColumnId();
2034 sal_Bool bColumnSelected = IsColumnSelected(nColId);
2035 sal_uInt16 nNewPos = GetColumnPos(nColId);
2036 sal_Bool bMoveAllowed = sal_False;
2037 if ( BROWSER_MOVECOLUMNLEFT == nId && nNewPos > 1 )
2038 --nNewPos,bMoveAllowed = sal_True;
2039 else if ( BROWSER_MOVECOLUMNRIGHT == nId && nNewPos < (ColCount()-1) )
2040 ++nNewPos,bMoveAllowed = sal_True;
2042 if ( bMoveAllowed )
2044 SetColumnPos( nColId, nNewPos );
2045 ColumnMoved( nColId );
2046 MakeFieldVisible(GetCurRow(),nColId,sal_True);
2047 if ( bColumnSelected )
2048 SelectColumnId(nColId);
2052 break;
2055 //! return bDone;
2058 //-------------------------------------------------------------------
2060 void BrowseBox::SetCursorColor(const Color& _rCol)
2062 if (_rCol == m_aCursorColor)
2063 return;
2065 // ensure the cursor is hidden
2066 DoHideCursor("SetCursorColor");
2067 if (!m_bFocusOnlyCursor)
2068 DoHideCursor("SetCursorColor - force");
2070 m_aCursorColor = _rCol;
2072 if (!m_bFocusOnlyCursor)
2073 DoShowCursor("SetCursorColor - force");
2074 DoShowCursor("SetCursorColor");
2076 // -----------------------------------------------------------------------------
2077 Rectangle BrowseBox::calcHeaderRect(sal_Bool _bIsColumnBar,sal_Bool _bOnScreen)
2079 Window* pParent = NULL;
2080 if ( !_bOnScreen )
2081 pParent = GetAccessibleParentWindow();
2083 Point aTopLeft;
2084 long nWidth;
2085 long nHeight;
2086 if ( _bIsColumnBar )
2088 nWidth = GetDataWindow().GetOutputSizePixel().Width();
2089 nHeight = GetDataRowHeight();
2091 else
2093 aTopLeft.Y() = GetDataRowHeight();
2094 nWidth = GetColumnWidth(0);
2095 nHeight = GetWindowExtentsRelative( pParent ).GetHeight() - aTopLeft.Y() - GetControlArea().GetSize().B();
2097 aTopLeft += GetWindowExtentsRelative( pParent ).TopLeft();
2098 return Rectangle(aTopLeft,Size(nWidth,nHeight));
2100 // -----------------------------------------------------------------------------
2101 Rectangle BrowseBox::calcTableRect(sal_Bool _bOnScreen)
2103 Window* pParent = NULL;
2104 if ( !_bOnScreen )
2105 pParent = GetAccessibleParentWindow();
2107 Rectangle aRect( GetWindowExtentsRelative( pParent ) );
2108 Rectangle aRowBar = calcHeaderRect(sal_False,pParent == NULL);
2110 long nX = aRowBar.Right() - aRect.Left();
2111 long nY = aRowBar.Top() - aRect.Top();
2112 Size aSize(aRect.GetSize());
2114 return Rectangle(aRowBar.TopRight(), Size(aSize.A() - nX, aSize.B() - nY - aHScroll.GetSizePixel().Height()) );
2116 // -----------------------------------------------------------------------------
2117 Rectangle BrowseBox::GetFieldRectPixelAbs( sal_Int32 _nRowId,sal_uInt16 _nColId, sal_Bool /*_bIsHeader*/, sal_Bool _bOnScreen )
2119 Window* pParent = NULL;
2120 if ( !_bOnScreen )
2121 pParent = GetAccessibleParentWindow();
2123 Rectangle aRect = GetFieldRectPixel(_nRowId,_nColId,_bOnScreen);
2125 Point aTopLeft = aRect.TopLeft();
2126 aTopLeft += GetWindowExtentsRelative( pParent ).TopLeft();
2128 return Rectangle(aTopLeft,aRect.GetSize());
2131 // ------------------------------------------------------------------------- EOF
2133 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */