1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
23 #include <svtools/colorcfg.hxx>
24 #include <vcl/salgtype.hxx>
25 #include <vcl/settings.hxx>
27 #include <tools/multisel.hxx>
28 #include <tools/fract.hxx>
31 using namespace ::com::sun::star::datatransfer
;
33 #define getDataWindow() (static_cast<BrowserDataWin*>(pDataWin.get()))
37 void BrowseBox::StartDrag( sal_Int8
/* _nAction */, const Point
& /* _rPosPixel */ )
39 // not interested in this event
44 sal_Int8
BrowseBox::AcceptDrop( const AcceptDropEvent
& _rEvt
)
46 BrowserDataWin
* pDataWindow
= static_cast<BrowserDataWin
*>(pDataWin
.get());
47 AcceptDropEvent
aTransformed( _rEvt
);
48 aTransformed
.maPosPixel
= pDataWindow
->ScreenToOutputPixel( OutputToScreenPixel( _rEvt
.maPosPixel
) );
49 return pDataWindow
->AcceptDrop( aTransformed
);
54 sal_Int8
BrowseBox::ExecuteDrop( const ExecuteDropEvent
& _rEvt
)
56 BrowserDataWin
* pDataWindow
= static_cast<BrowserDataWin
*>(pDataWin
.get());
57 ExecuteDropEvent
aTransformed( _rEvt
);
58 aTransformed
.maPosPixel
= pDataWindow
->ScreenToOutputPixel( OutputToScreenPixel( _rEvt
.maPosPixel
) );
59 return pDataWindow
->ExecuteDrop( aTransformed
);
64 sal_Int8
BrowseBox::AcceptDrop( const BrowserAcceptDropEvent
& )
66 // not interested in this event
67 return DND_ACTION_NONE
;
72 sal_Int8
BrowseBox::ExecuteDrop( const BrowserExecuteDropEvent
& )
74 // not interested in this event
75 return DND_ACTION_NONE
;
80 void* BrowseBox::implGetDataFlavors() const
82 if (static_cast<BrowserDataWin
*>(pDataWin
.get())->bCallingDropCallback
)
83 return &static_cast<BrowserDataWin
*>(pDataWin
.get())->GetDataFlavorExVector();
84 return &GetDataFlavorExVector();
89 bool BrowseBox::IsDropFormatSupported( SotClipboardFormatId _nFormat
)
91 if ( static_cast< BrowserDataWin
* >( pDataWin
.get() )->bCallingDropCallback
)
92 return static_cast< BrowserDataWin
* >( pDataWin
.get() )->IsDropFormatSupported( _nFormat
);
94 return DropTargetHelper::IsDropFormatSupported( _nFormat
);
99 bool BrowseBox::IsDropFormatSupported( SotClipboardFormatId _nFormat
) const
101 return const_cast< BrowseBox
* >( this )->IsDropFormatSupported( _nFormat
);
106 bool BrowseBox::IsDropFormatSupported( const DataFlavor
& _rFlavor
)
108 if ( static_cast< BrowserDataWin
* >( pDataWin
.get() )->bCallingDropCallback
)
109 return static_cast< BrowserDataWin
* >( pDataWin
.get() )->IsDropFormatSupported( _rFlavor
);
111 return DropTargetHelper::IsDropFormatSupported( _rFlavor
);
116 bool BrowseBox::IsDropFormatSupported( const DataFlavor
& _rFlavor
) const
118 return const_cast< BrowseBox
* >( this )->IsDropFormatSupported( _rFlavor
);
123 void BrowseBox::Command( const CommandEvent
& rEvt
)
125 if ( !getDataWindow()->bInCommand
)
126 Control::Command( rEvt
);
131 void BrowseBox::StateChanged( StateChangedType nStateChange
)
133 Control::StateChanged( nStateChange
);
135 if ( StateChangedType::Mirroring
== nStateChange
)
137 getDataWindow()->EnableRTL( IsRTLEnabled() );
139 HeaderBar
* pHeaderBar
= getDataWindow()->pHeaderBar
;
141 pHeaderBar
->EnableRTL( IsRTLEnabled() );
142 aHScroll
->EnableRTL( IsRTLEnabled() );
144 pVScroll
->EnableRTL( IsRTLEnabled() );
147 else if ( StateChangedType::InitShow
== nStateChange
)
149 bBootstrapped
= true; // must be set first!
152 if ( bMultiSelection
)
153 uRow
.pSel
->SetTotalRange( Range( 0, nRowCount
- 1 ) );
154 if ( nRowCount
== 0 )
155 nCurRow
= BROWSER_ENDOFSELECTION
;
156 else if ( nCurRow
== BROWSER_ENDOFSELECTION
)
162 bSelectionIsVisible
= true;
166 AutoSizeLastColumn();
169 else if (StateChangedType::Zoom
== nStateChange
)
171 pDataWin
->SetZoom(GetZoom());
172 HeaderBar
* pHeaderBar
= getDataWindow()->pHeaderBar
;
174 pHeaderBar
->SetZoom(GetZoom());
176 // let the columns calculate their new widths and adjust the header bar
177 for ( size_t nPos
= 0; nPos
< pCols
->size(); ++nPos
)
179 (*pCols
)[ nPos
]->ZoomChanged(GetZoom());
181 pHeaderBar
->SetItemSize( (*pCols
)[ nPos
]->GetId(), (*pCols
)[ nPos
]->Width() );
184 // all our controls have to be repositioned
187 else if (StateChangedType::Enable
== nStateChange
)
189 // do we have a handle column?
190 bool bHandleCol
= !pCols
->empty() && (0 == (*pCols
)[ 0 ]->GetId());
191 // do we have a header bar?
192 bool bHeaderBar
= (NULL
!= static_cast<BrowserDataWin
&>(GetDataWindow()).pHeaderBar
.get());
199 // we draw the text in our header bar in a color dependent on the enabled state. So if this state changed
201 Invalidate(Rectangle(Point(0, 0), Size(GetOutputSizePixel().Width(), GetTitleHeight() - 1)));
207 void BrowseBox::Select()
213 void BrowseBox::DoubleClick( const BrowserMouseEvent
& )
219 long BrowseBox::QueryMinimumRowHeight()
221 return CalcZoom( 5 );
226 void BrowseBox::ImplStartTracking()
232 void BrowseBox::ImplTracking()
238 void BrowseBox::ImplEndTracking()
244 void BrowseBox::RowHeightChanged()
250 long BrowseBox::QueryColumnResize( sal_uInt16
, long nWidth
)
257 void BrowseBox::ColumnResized( sal_uInt16
)
263 void BrowseBox::ColumnMoved( sal_uInt16
)
269 void BrowseBox::StartScroll()
271 DoHideCursor( "StartScroll" );
276 void BrowseBox::EndScroll()
279 AutoSizeLastColumn();
280 DoShowCursor( "EndScroll" );
285 void BrowseBox::ToggleSelection( bool bForce
)
288 // selection highlight-toggling allowed?
292 ( bNotToggleSel
|| !IsUpdateMode() || !bSelectionIsVisible
) )
295 // only highlight painted areas!
296 bNotToggleSel
= true;
297 if ( false && !getDataWindow()->bInPaint
)
300 // accumulate areas of rows to highlight
301 RectangleList aHighlightList
;
302 long nLastRowInRect
= 0; // for the CFront
304 // don't highlight handle column
305 BrowserColumn
*pFirstCol
= pCols
->empty() ? NULL
: (*pCols
)[ 0 ];
306 long nOfsX
= (!pFirstCol
|| pFirstCol
->GetId()) ? 0 : pFirstCol
->Width();
308 // accumulate old row selection
309 long nBottomRow
= nTopRow
+
310 pDataWin
->GetOutputSizePixel().Height() / GetDataRowHeight();
311 if ( nBottomRow
> GetRowCount() && GetRowCount() )
312 nBottomRow
= GetRowCount();
313 for ( long nRow
= bMultiSelection
? uRow
.pSel
->FirstSelected() : uRow
.nSel
;
314 nRow
!= BROWSER_ENDOFSELECTION
&& nRow
<= nBottomRow
;
315 nRow
= bMultiSelection
? uRow
.pSel
->NextSelected() : BROWSER_ENDOFSELECTION
)
317 if ( nRow
< nTopRow
)
321 Point( nOfsX
, (nRow
-nTopRow
)*GetDataRowHeight() ),
322 Size( pDataWin
->GetSizePixel().Width(), GetDataRowHeight() ) );
323 if ( aHighlightList
.size() && nLastRowInRect
== ( nRow
- 1 ) )
324 aHighlightList
[ 0 ]->Union( aAddRect
);
326 aHighlightList
.insert( aHighlightList
.begin(), new Rectangle( aAddRect
) );
327 nLastRowInRect
= nRow
;
330 // unhighlight the old selection (if any)
331 for ( size_t i
= aHighlightList
.size(); i
> 0; )
333 Rectangle
*pRect
= aHighlightList
[ --i
];
334 pDataWin
->Invalidate( *pRect
);
337 aHighlightList
.clear();
339 // unhighlight old column selection (if any)
340 for ( long nColId
= pColSel
? pColSel
->FirstSelected() : BROWSER_ENDOFSELECTION
;
341 nColId
!= BROWSER_ENDOFSELECTION
;
342 nColId
= pColSel
->NextSelected() )
344 Rectangle
aRect( GetFieldRectPixel(nCurRow
,
345 (*pCols
)[ nColId
]->GetId(),
347 aRect
.Left() -= MIN_COLUMNWIDTH
;
348 aRect
.Right() += MIN_COLUMNWIDTH
;
350 aRect
.Bottom() = pDataWin
->GetOutputSizePixel().Height();
351 pDataWin
->Invalidate( aRect
);
354 bNotToggleSel
= false;
359 void BrowseBox::DrawCursor()
361 bool bReallyHide
= false;
362 if ( bHideCursor
== TRISTATE_INDET
)
364 if ( !GetSelectRowCount() && !GetSelectColumnCount() )
367 else if ( bHideCursor
== TRISTATE_TRUE
)
372 bReallyHide
|= !bSelectionIsVisible
|| !IsUpdateMode() || bScrolling
|| nCurRow
< 0;
374 if (PaintCursorIfHiddenOnce())
375 bReallyHide
|= ( GetCursorHideCount() > 1 );
377 bReallyHide
|= ( GetCursorHideCount() > 0 );
379 // no cursor on handle column
380 if ( nCurColId
== HandleColumnId
)
381 nCurColId
= GetColumnId(1);
383 // calculate cursor rectangle
387 aCursor
= GetFieldRectPixel( nCurRow
, nCurColId
, false );
388 aCursor
.Left() -= MIN_COLUMNWIDTH
;
389 aCursor
.Right() += 1;
390 aCursor
.Bottom() += 1;
394 Point( ( !pCols
->empty() && (*pCols
)[ 0 ]->GetId() == 0 ) ?
395 (*pCols
)[ 0 ]->Width() : 0,
396 (nCurRow
- nTopRow
) * GetDataRowHeight() + 1 ),
397 Size( pDataWin
->GetOutputSizePixel().Width() + 1,
398 GetDataRowHeight() - 2 ) );
401 if ( !bMultiSelection
)
406 if (m_aCursorColor
== COL_TRANSPARENT
)
408 // on these platforms, the StarView focus works correctly
410 static_cast<Control
*>(pDataWin
.get())->HideFocus();
412 static_cast<Control
*>(pDataWin
.get())->ShowFocus( aCursor
);
416 Color rCol
= bReallyHide
? pDataWin
->GetFillColor() : m_aCursorColor
;
417 Color aOldFillColor
= pDataWin
->GetFillColor();
418 Color aOldLineColor
= pDataWin
->GetLineColor();
419 pDataWin
->SetFillColor();
420 pDataWin
->SetLineColor( rCol
);
421 pDataWin
->DrawRect( aCursor
);
422 pDataWin
->SetLineColor( aOldLineColor
);
423 pDataWin
->SetFillColor( aOldFillColor
);
429 sal_uLong
BrowseBox::GetColumnWidth( sal_uInt16 nId
) const
432 sal_uInt16 nItemPos
= GetColumnPos( nId
);
433 if ( nItemPos
>= pCols
->size() )
435 return (*pCols
)[ nItemPos
]->Width();
440 sal_uInt16
BrowseBox::GetColumnId( sal_uInt16 nPos
) const
443 if ( nPos
>= pCols
->size() )
444 return BROWSER_INVALIDID
;
445 return (*pCols
)[ nPos
]->GetId();
450 sal_uInt16
BrowseBox::GetColumnPos( sal_uInt16 nId
) const
453 for ( sal_uInt16 nPos
= 0; nPos
< pCols
->size(); ++nPos
)
454 if ( (*pCols
)[ nPos
]->GetId() == nId
)
456 return BROWSER_INVALIDID
;
461 bool BrowseBox::IsFrozen( sal_uInt16 nColumnId
) const
464 for ( size_t nPos
= 0; nPos
< pCols
->size(); ++nPos
)
465 if ( (*pCols
)[ nPos
]->GetId() == nColumnId
)
466 return (*pCols
)[ nPos
]->IsFrozen();
472 void BrowseBox::ExpandRowSelection( const BrowserMouseEvent
& rEvt
)
475 DoHideCursor( "ExpandRowSelection" );
477 // expand the last selection
478 if ( bMultiSelection
)
480 Range
aJustifiedRange( aSelRange
);
481 aJustifiedRange
.Justify();
483 bool bSelectThis
= ( bSelect
!= aJustifiedRange
.IsInside( rEvt
.GetRow() ) );
485 if ( aJustifiedRange
.IsInside( rEvt
.GetRow() ) )
488 while ( rEvt
.GetRow() < aSelRange
.Max() )
489 { // ZTC/Mac bug - don't put these statements together!
490 SelectRow( aSelRange
.Max(), bSelectThis
, true );
493 while ( rEvt
.GetRow() > aSelRange
.Max() )
494 { // ZTC/Mac bug - don't put these statements together!
495 SelectRow( aSelRange
.Max(), bSelectThis
, true );
502 bool bOldSelecting
= bSelecting
;
504 while ( rEvt
.GetRow() < aSelRange
.Max() )
505 { // ZTC/Mac bug - don't put these statements together!
507 if ( !IsRowSelected( aSelRange
.Max() ) )
509 SelectRow( aSelRange
.Max(), bSelectThis
, true );
513 while ( rEvt
.GetRow() > aSelRange
.Max() )
514 { // ZTC/Mac bug - don't put these statements together!
516 if ( !IsRowSelected( aSelRange
.Max() ) )
518 SelectRow( aSelRange
.Max(), bSelectThis
, true );
522 bSelecting
= bOldSelecting
;
528 if ( !bMultiSelection
|| !IsRowSelected( rEvt
.GetRow() ) )
529 SelectRow( rEvt
.GetRow(), true );
531 GoToRow( rEvt
.GetRow(), false );
532 DoShowCursor( "ExpandRowSelection" );
537 void BrowseBox::Resize()
539 if ( !bBootstrapped
&& IsReallyVisible() )
540 BrowseBox::StateChanged( StateChangedType::InitShow
);
541 if ( pCols
->empty() )
543 getDataWindow()->bResizeOnPaint
= true;
546 getDataWindow()->bResizeOnPaint
= false;
548 // calc the size of the scrollbars
549 // (we can't ask the scrollbars for their widths cause if we're zoomed they still have to be
550 // resized - which is done in UpdateScrollbars)
551 sal_uLong nSBSize
= GetSettings().GetStyleSettings().GetScrollBarSize();
553 nSBSize
= (sal_uLong
)(nSBSize
* (double)GetZoom());
555 DoHideCursor( "Resize" );
556 sal_uInt16 nOldVisibleRows
= 0;
557 //fdo#42694, post #i111125# GetDataRowHeight() can be 0
558 if (GetDataRowHeight())
559 nOldVisibleRows
= (sal_uInt16
)(pDataWin
->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
561 // did we need a horizontal scroll bar or is there a Control Area?
562 if ( !getDataWindow()->bNoHScroll
&&
563 ( ( pCols
->size() - FrozenColCount() ) > 1 ) )
568 // calculate the size of the data window
569 long nDataHeight
= GetOutputSizePixel().Height() - GetTitleHeight();
570 if ( aHScroll
->IsVisible() || ( nControlAreaWidth
!= USHRT_MAX
) )
571 nDataHeight
-= nSBSize
;
573 long nDataWidth
= GetOutputSizePixel().Width();
574 if ( pVScroll
->IsVisible() )
575 nDataWidth
-= nSBSize
;
577 // adjust position and size of data window
578 pDataWin
->SetPosSizePixel(
579 Point( 0, GetTitleHeight() ),
580 Size( nDataWidth
, nDataHeight
) );
582 sal_uInt16 nVisibleRows
= 0;
584 if (GetDataRowHeight())
585 nVisibleRows
= (sal_uInt16
)(pDataWin
->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
587 // TopRow is unchanged, but the number of visible lines has changed.
588 if ( nVisibleRows
!= nOldVisibleRows
)
589 VisibleRowsChanged(nTopRow
, nVisibleRows
);
594 Rectangle
aInvalidArea( GetControlArea() );
595 aInvalidArea
.Right() = GetOutputSizePixel().Width();
596 aInvalidArea
.Left() = 0;
597 Invalidate( aInvalidArea
);
599 // external header-bar
600 HeaderBar
* pHeaderBar
= getDataWindow()->pHeaderBar
;
603 // take the handle column into account
604 BrowserColumn
*pFirstCol
= (*pCols
)[ 0 ];
605 long nOfsX
= pFirstCol
->GetId() ? 0 : pFirstCol
->Width();
606 pHeaderBar
->SetPosSizePixel( Point( nOfsX
, 0 ), Size( GetOutputSizePixel().Width() - nOfsX
, GetTitleHeight() ) );
609 AutoSizeLastColumn(); // adjust last column width
610 DoShowCursor( "Resize" );
615 void BrowseBox::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
& rRect
)
619 if (!bBootstrapped
&& IsReallyVisible())
620 BrowseBox::StateChanged(StateChangedType::InitShow
);
624 BrowserColumn
*pFirstCol
= (*pCols
)[ 0 ];
625 bool bHandleCol
= pFirstCol
&& pFirstCol
->GetId() == 0;
626 bool bHeaderBar
= getDataWindow()->pHeaderBar
.get() != NULL
;
628 // draw delimitational lines
629 if (!getDataWindow()->bNoHScroll
)
630 rRenderContext
.DrawLine(Point(0, aHScroll
->GetPosPixel().Y()),
631 Point(GetOutputSizePixel().Width(),
632 aHScroll
->GetPosPixel().Y()));
638 rRenderContext
.DrawLine(Point(0, GetTitleHeight() - 1),
639 Point(GetOutputSizePixel().Width(), GetTitleHeight() - 1));
643 rRenderContext
.DrawLine(Point(0, GetTitleHeight() - 1),
644 Point(pFirstCol
->Width(), GetTitleHeight() - 1));
649 // If there is a handle column and if the header bar is available, only
650 // take the HandleColumn into account
651 if (nTitleLines
&& (!bHeaderBar
|| bHandleCol
))
653 // iterate through columns to redraw
656 for (nCol
= 0; nCol
< pCols
->size() && nX
< rRect
.Right(); ++nCol
)
658 // skip invisible columns between frozen and scrollable area
659 if (nCol
< nFirstCol
&& !(*pCols
)[nCol
]->IsFrozen())
662 // only the handle column?
663 if (bHeaderBar
&& bHandleCol
&& nCol
> 0)
666 BrowserColumn
* pCol
= (*pCols
)[nCol
];
668 // draw the column and increment position
669 if ( pCol
->Width() > 4 )
671 ButtonFrame
aButtonFrame( Point( nX
, 0 ),
672 Size( pCol
->Width()-1, GetTitleHeight()-1 ),
673 pCol
->Title(), false, false, !IsEnabled());
674 aButtonFrame
.Draw(rRenderContext
);
675 rRenderContext
.DrawLine(Point(nX
+ pCol
->Width() - 1, 0),
676 Point(nX
+ pCol
->Width() - 1, GetTitleHeight() - 1));
680 rRenderContext
.Push(PushFlags::FILLCOLOR
);
681 rRenderContext
.SetFillColor(Color(COL_BLACK
));
682 rRenderContext
.DrawRect(Rectangle(Point(nX
, 0), Size(pCol
->Width(), GetTitleHeight() - 1)));
683 rRenderContext
.Pop();
691 if ( !bHeaderBar
&& nCol
== pCols
->size() )
693 const StyleSettings
&rSettings
= rRenderContext
.GetSettings().GetStyleSettings();
694 Color
aColFace(rSettings
.GetFaceColor());
695 rRenderContext
.Push(PushFlags::FILLCOLOR
| PushFlags::LINECOLOR
);
696 rRenderContext
.SetFillColor(aColFace
);
697 rRenderContext
.SetLineColor(aColFace
);
698 rRenderContext
.DrawRect(Rectangle(Point(nX
, 0),
699 Point(rRect
.Right(), GetTitleHeight() - 2 )));
700 rRenderContext
.Pop();
707 void BrowseBox::Draw( OutputDevice
* pDev
, const Point
& rPos
, const Size
& rSize
, sal_uLong nFlags
)
709 bool bDrawSelection
= (nFlags
& WINDOW_DRAW_NOSELECTION
) == 0;
711 // we need pixel coordinates
712 Size aRealSize
= pDev
->LogicToPixel(rSize
);
713 Point aRealPos
= pDev
->LogicToPixel(rPos
);
715 if ((rSize
.Width() < 3) || (rSize
.Height() < 3))
716 // we want to have two pixels frame ...
719 vcl::Font aFont
= GetDataWindow().GetDrawPixelFont( pDev
);
720 // the 'normal' painting uses always the data window as device to output to, so we have to calc the new font
721 // relative to the data wins current settings
725 pDev
->SetFont( aFont
);
728 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
729 pDev
->SetLineColor(rStyleSettings
.GetDarkShadowColor());
730 pDev
->DrawLine(Point(aRealPos
.X(), aRealPos
.Y()),
731 Point(aRealPos
.X(), aRealPos
.Y() + aRealSize
.Height() - 1));
732 pDev
->DrawLine(Point(aRealPos
.X(), aRealPos
.Y()),
733 Point(aRealPos
.X() + aRealSize
.Width() - 1, aRealPos
.Y()));
734 pDev
->SetLineColor(rStyleSettings
.GetShadowColor());
735 pDev
->DrawLine(Point(aRealPos
.X() + aRealSize
.Width() - 1, aRealPos
.Y() + 1),
736 Point(aRealPos
.X() + aRealSize
.Width() - 1, aRealPos
.Y() + aRealSize
.Height() - 1));
737 pDev
->DrawLine(Point(aRealPos
.X() + aRealSize
.Width() - 1, aRealPos
.Y() + aRealSize
.Height() - 1),
738 Point(aRealPos
.X() + 1, aRealPos
.Y() + aRealSize
.Height() - 1));
740 HeaderBar
* pBar
= getDataWindow()->pHeaderBar
;
742 // we're drawing onto a foreign device, so we have to fake the DataRowHeight for the subsequent ImplPaintData
743 // (as it is based on the settings of our data window, not the foreign device)
745 ImpGetDataRowHeight();
746 long nHeightLogic
= PixelToLogic(Size(0, nDataRowHeight
), MAP_10TH_MM
).Height();
747 long nForeignHeightPixel
= pDev
->LogicToPixel(Size(0, nHeightLogic
), MAP_10TH_MM
).Height();
749 long nOriginalHeight
= nDataRowHeight
;
750 nDataRowHeight
= nForeignHeightPixel
;
752 // this counts for the column widths, too
754 for ( nPos
= 0; nPos
< pCols
->size(); ++nPos
)
756 BrowserColumn
* pCurrent
= (*pCols
)[ nPos
];
758 long nWidthLogic
= PixelToLogic(Size(pCurrent
->Width(), 0), MAP_10TH_MM
).Width();
759 long nForeignWidthPixel
= pDev
->LogicToPixel(Size(nWidthLogic
, 0), MAP_10TH_MM
).Width();
761 pCurrent
->SetWidth(nForeignWidthPixel
, GetZoom());
763 pBar
->SetItemSize( pCurrent
->GetId(), pCurrent
->Width() );
766 // a smaller area for the content
769 aRealSize
.Width() -= 2;
770 aRealSize
.Height() -= 2;
772 // let the header bar draw itself
775 // the title height with respect to the font set for the given device
776 long nTitleHeight
= PixelToLogic(Size(0, GetTitleHeight()), MAP_10TH_MM
).Height();
777 nTitleHeight
= pDev
->LogicToPixel(Size(0, nTitleHeight
), MAP_10TH_MM
).Height();
779 BrowserColumn
* pFirstCol
= !pCols
->empty() ? (*pCols
)[ 0 ] : NULL
;
781 Point
aHeaderPos(pFirstCol
&& (pFirstCol
->GetId() == 0) ? pFirstCol
->Width() : 0, 0);
782 Size
aHeaderSize(aRealSize
.Width() - aHeaderPos
.X(), nTitleHeight
);
784 aHeaderPos
+= aRealPos
;
785 // do this before converting to logics !
787 // the header's draw expects logic coordinates, again
788 aHeaderPos
= pDev
->PixelToLogic(aHeaderPos
);
789 aHeaderSize
= pDev
->PixelToLogic(aHeaderSize
);
791 pBar
->Draw(pDev
, aHeaderPos
, aHeaderSize
, nFlags
);
793 // draw the "upper left cell" (the intersection between the header bar and the handle column)
794 if (pFirstCol
&& (pFirstCol
->GetId() == 0) && (pFirstCol
->Width() > 4))
796 ButtonFrame
aButtonFrame( aRealPos
,
797 Size( pFirstCol
->Width()-1, nTitleHeight
-1 ),
798 pFirstCol
->Title(), false, false, !IsEnabled());
799 aButtonFrame
.Draw( *pDev
);
801 pDev
->Push( PushFlags::LINECOLOR
);
802 pDev
->SetLineColor( Color( COL_BLACK
) );
804 pDev
->DrawLine( Point( aRealPos
.X(), aRealPos
.Y() + nTitleHeight
-1 ),
805 Point( aRealPos
.X() + pFirstCol
->Width() - 1, aRealPos
.Y() + nTitleHeight
-1 ) );
806 pDev
->DrawLine( Point( aRealPos
.X() + pFirstCol
->Width() - 1, aRealPos
.Y() ),
807 Point( aRealPos
.X() + pFirstCol
->Width() - 1, aRealPos
.Y() + nTitleHeight
-1 ) );
812 aRealPos
.Y() += aHeaderSize
.Height();
813 aRealSize
.Height() -= aHeaderSize
.Height();
816 // draw our own content (with clipping)
817 vcl::Region
aRegion(Rectangle(aRealPos
, aRealSize
));
818 pDev
->SetClipRegion( pDev
->PixelToLogic( aRegion
) );
820 // do we have to paint the background
821 bool bBackground
= !(nFlags
& WINDOW_DRAW_NOBACKGROUND
) && GetDataWindow().IsControlBackground();
824 Rectangle
aRect( aRealPos
, aRealSize
);
825 pDev
->SetFillColor( GetDataWindow().GetControlBackground() );
826 pDev
->DrawRect( aRect
);
829 ImplPaintData( *pDev
, Rectangle( aRealPos
, aRealSize
), true, bDrawSelection
);
831 // restore the column widths/data row height
832 nDataRowHeight
= nOriginalHeight
;
833 for ( nPos
= 0; nPos
< pCols
->size(); ++nPos
)
835 BrowserColumn
* pCurrent
= (*pCols
)[ nPos
];
837 long nForeignWidthLogic
= pDev
->PixelToLogic(Size(pCurrent
->Width(), 0), MAP_10TH_MM
).Width();
838 long nWidthPixel
= LogicToPixel(Size(nForeignWidthLogic
, 0), MAP_10TH_MM
).Width();
840 pCurrent
->SetWidth(nWidthPixel
, GetZoom());
842 pBar
->SetItemSize( pCurrent
->GetId(), pCurrent
->Width() );
850 void BrowseBox::ImplPaintData(OutputDevice
& _rOut
, const Rectangle
& _rRect
, bool _bForeignDevice
, bool _bDrawSelections
)
852 Point aOverallAreaPos
= _bForeignDevice
? _rRect
.TopLeft() : Point(0,0);
853 Size aOverallAreaSize
= _bForeignDevice
? _rRect
.GetSize() : GetDataWindow().GetOutputSizePixel();
854 Point aOverallAreaBRPos
= _bForeignDevice
? _rRect
.BottomRight() : Point( aOverallAreaSize
.Width(), aOverallAreaSize
.Height() );
856 long nDataRowHeigt
= GetDataRowHeight();
858 // compute relative rows to redraw
859 sal_uLong nRelTopRow
= 0;
860 sal_uLong nRelBottomRow
= aOverallAreaSize
.Height();
861 if (!_bForeignDevice
&& nDataRowHeigt
)
863 nRelTopRow
= ((sal_uLong
)_rRect
.Top() / nDataRowHeigt
);
864 nRelBottomRow
= (sal_uLong
)(_rRect
.Bottom()) / nDataRowHeigt
;
867 // cache frequently used values
868 Point
aPos( aOverallAreaPos
.X(), nRelTopRow
* nDataRowHeigt
+ aOverallAreaPos
.Y() );
869 _rOut
.SetLineColor( Color( COL_WHITE
) );
870 const AllSettings
& rAllSets
= _rOut
.GetSettings();
871 const StyleSettings
&rSettings
= rAllSets
.GetStyleSettings();
872 const Color
&rHighlightTextColor
= rSettings
.GetHighlightTextColor();
873 const Color
&rHighlightFillColor
= rSettings
.GetHighlightColor();
874 Color aOldTextColor
= _rOut
.GetTextColor();
875 Color aOldFillColor
= _rOut
.GetFillColor();
876 Color aOldLineColor
= _rOut
.GetLineColor();
877 long nHLineX
= 0 == (*pCols
)[ 0 ]->GetId() ? (*pCols
)[ 0 ]->Width() : 0;
878 nHLineX
+= aOverallAreaPos
.X();
880 Color
aDelimiterLineColor( ::svtools::ColorConfig().GetColorValue( ::svtools::CALCGRID
).nColor
);
882 // redraw the invalid fields
883 for ( sal_uLong nRelRow
= nRelTopRow
;
884 nRelRow
<= nRelBottomRow
&& (sal_uLong
)nTopRow
+nRelRow
< (sal_uLong
)nRowCount
;
885 ++nRelRow
, aPos
.Y() += nDataRowHeigt
)
888 // check valid area, to be on the safe side:
889 DBG_ASSERT( (sal_uInt16
)(nTopRow
+nRelRow
) < nRowCount
, "BrowseBox::ImplPaintData: invalid seek" );
890 if ( (nTopRow
+long(nRelRow
)) < 0 || (sal_uInt16
)(nTopRow
+nRelRow
) >= nRowCount
)
894 sal_uLong nRow
= nTopRow
+nRelRow
;
895 if ( !SeekRow( nRow
) ) {
896 OSL_FAIL("BrowseBox::ImplPaintData: SeekRow failed");
898 _rOut
.SetClipRegion();
899 aPos
.X() = aOverallAreaPos
.X();
902 // #73325# don't paint the row outside the painting rectangle (DG)
903 // prepare auto-highlight
904 Rectangle
aRowRect( Point( _rRect
.TopLeft().X(), aPos
.Y() ),
905 Size( _rRect
.GetSize().Width(), nDataRowHeigt
) );
907 bool bRowSelected
= _bDrawSelections
909 && IsRowSelected( nRow
);
912 _rOut
.SetTextColor( rHighlightTextColor
);
913 _rOut
.SetFillColor( rHighlightFillColor
);
914 _rOut
.SetLineColor();
915 _rOut
.DrawRect( aRowRect
);
918 // iterate through columns to redraw
920 for ( nCol
= 0; nCol
< pCols
->size(); ++nCol
)
923 BrowserColumn
*pCol
= (*pCols
)[ nCol
];
925 // at end of invalid area
926 if ( aPos
.X() >= _rRect
.Right() )
929 // skip invisible columns between frozen and scrollable area
930 if ( nCol
< nFirstCol
&& !pCol
->IsFrozen() )
933 pCol
= (nCol
< pCols
->size() ) ? (*pCols
)[ nCol
] : NULL
;
935 { // FS - 21.05.99 - 66325
936 // actually this has been fixed elsewhere (in the right place),
937 // but let's make sure...
938 OSL_FAIL("BrowseBox::PaintData : nFirstCol is probably invalid !");
943 // prepare Column-AutoHighlight
944 bool bColAutoHighlight
= _bDrawSelections
946 && IsColumnSelected( pCol
->GetId() );
947 if ( bColAutoHighlight
)
949 _rOut
.SetClipRegion();
950 _rOut
.SetTextColor( rHighlightTextColor
);
951 _rOut
.SetFillColor( rHighlightFillColor
);
952 _rOut
.SetLineColor();
953 Rectangle
aFieldRect( aPos
,
954 Size( pCol
->Width(), nDataRowHeigt
) );
955 _rOut
.DrawRect( aFieldRect
);
958 if (!m_bFocusOnlyCursor
&& (pCol
->GetId() == GetCurColumnId()) && (nRow
== (sal_uLong
)GetCurRow()))
961 // draw a single field.
962 // else something is drawn to, e.g. handle column
965 // clip the column's output to the field area
967 { // (not necessary if painting onto the data window)
968 Size
aFieldSize(pCol
->Width(), nDataRowHeigt
);
970 if (aPos
.X() + aFieldSize
.Width() > aOverallAreaBRPos
.X())
971 aFieldSize
.Width() = aOverallAreaBRPos
.X() - aPos
.X();
973 if (aPos
.Y() + aFieldSize
.Height() > aOverallAreaBRPos
.Y() + 1)
975 // for non-handle cols we don't clip vertically : we just don't draw the cell if the line isn't completely visible
976 if (pCol
->GetId() != 0)
978 aFieldSize
.Height() = aOverallAreaBRPos
.Y() + 1 - aPos
.Y();
981 vcl::Region
aClipToField(Rectangle(aPos
, aFieldSize
));
982 _rOut
.SetClipRegion(aClipToField
);
984 pCol
->Draw( *this, _rOut
, aPos
, false );
986 _rOut
.SetClipRegion();
989 // reset Column-auto-highlight
990 if ( bColAutoHighlight
)
992 _rOut
.SetTextColor( aOldTextColor
);
993 _rOut
.SetFillColor( aOldFillColor
);
994 _rOut
.SetLineColor( aOldLineColor
);
998 aPos
.X() += pCol
->Width();
1001 // reset auto-highlight
1004 _rOut
.SetTextColor( aOldTextColor
);
1005 _rOut
.SetFillColor( aOldFillColor
);
1006 _rOut
.SetLineColor( aOldLineColor
);
1011 // draw horizontal delimitation lines
1012 _rOut
.SetClipRegion();
1013 _rOut
.Push( PushFlags::LINECOLOR
);
1014 _rOut
.SetLineColor( aDelimiterLineColor
);
1015 long nY
= aPos
.Y() + nDataRowHeigt
- 1;
1016 if (nY
<= aOverallAreaBRPos
.Y())
1017 _rOut
.DrawLine( Point( nHLineX
, nY
),
1019 ? std::min(long(long(aPos
.X()) - 1), aOverallAreaBRPos
.X())
1020 : aOverallAreaBRPos
.X(),
1026 if (aPos
.Y() > aOverallAreaBRPos
.Y() + 1)
1027 aPos
.Y() = aOverallAreaBRPos
.Y() + 1;
1028 // needed for some of the following drawing
1031 _rOut
.SetClipRegion();
1032 aOldLineColor
= _rOut
.GetLineColor();
1033 aOldFillColor
= _rOut
.GetFillColor();
1034 _rOut
.SetFillColor( rSettings
.GetFaceColor() );
1035 if ( !pCols
->empty() && ( (*pCols
)[ 0 ]->GetId() == 0 ) && ( aPos
.Y() <= _rRect
.Bottom() ) )
1037 // fill rectangle gray below handle column
1038 // DG: fill it only until the end of the drawing rect and not to the end, as this may overpaint handle columns
1039 _rOut
.SetLineColor( Color( COL_BLACK
) );
1040 _rOut
.DrawRect( Rectangle(
1041 Point( aOverallAreaPos
.X() - 1, aPos
.Y() - 1 ),
1042 Point( aOverallAreaPos
.X() + (*pCols
)[ 0 ]->Width() - 1,
1043 _rRect
.Bottom() + 1) ) );
1045 _rOut
.SetFillColor( aOldFillColor
);
1047 // draw vertical delimitational line between frozen and scrollable cols
1048 _rOut
.SetLineColor( COL_BLACK
);
1049 long nFrozenWidth
= GetFrozenWidth()-1;
1050 _rOut
.DrawLine( Point( aOverallAreaPos
.X() + nFrozenWidth
, aPos
.Y() ),
1051 Point( aOverallAreaPos
.X() + nFrozenWidth
, bHLines
1053 : aOverallAreaBRPos
.Y() ) );
1055 // draw vertical delimitational lines?
1058 _rOut
.SetLineColor( aDelimiterLineColor
);
1059 Point
aVertPos( aOverallAreaPos
.X() - 1, aOverallAreaPos
.Y() );
1060 long nDeltaY
= aOverallAreaBRPos
.Y();
1061 for ( size_t nCol
= 0; nCol
< pCols
->size(); ++nCol
)
1064 BrowserColumn
*pCol
= (*pCols
)[ nCol
];
1066 // skip invisible columns between frozen and scrollable area
1067 if ( nCol
< nFirstCol
&& !pCol
->IsFrozen() )
1070 pCol
= (*pCols
)[ nCol
];
1074 aVertPos
.X() += pCol
->Width();
1076 // at end of invalid area
1077 // invalid area is first reached when X > Right
1079 if ( aVertPos
.X() > _rRect
.Right() )
1082 // draw a single line
1083 if ( pCol
->GetId() != 0 )
1084 _rOut
.DrawLine( aVertPos
, Point( aVertPos
.X(),
1087 : aPos
.Y() + nDeltaY
) );
1091 _rOut
.SetLineColor( aOldLineColor
);
1094 void BrowseBox::PaintData( vcl::Window
& rWin
, vcl::RenderContext
& rRenderContext
, const Rectangle
& rRect
)
1096 if (!bBootstrapped
&& IsReallyVisible())
1097 BrowseBox::StateChanged(StateChangedType::InitShow
);
1100 if (!pCols
|| pCols
->empty() || !rWin
.IsUpdateMode())
1102 if (getDataWindow()->bResizeOnPaint
)
1104 // MI: who was that? Window::Update();
1106 ImplPaintData(rRenderContext
, rRect
, false, true);
1109 void BrowseBox::UpdateScrollbars()
1112 if ( !bBootstrapped
|| !IsUpdateMode() )
1115 // protect against recursion
1116 BrowserDataWin
*pBDW
= static_cast<BrowserDataWin
*>( pDataWin
.get() );
1117 if ( pBDW
->bInUpdateScrollbars
)
1119 pBDW
->bHadRecursion
= true;
1122 pBDW
->bInUpdateScrollbars
= true;
1124 // the size of the corner window (and the width of the VSB/height of the HSB)
1125 sal_uLong nCornerSize
= GetSettings().GetStyleSettings().GetScrollBarSize();
1127 nCornerSize
= (sal_uLong
)(nCornerSize
* (double)GetZoom());
1129 bool bNeedsVScroll
= false;
1131 if (GetDataRowHeight())
1134 nMaxRows
= (pDataWin
->GetSizePixel().Height()) / GetDataRowHeight();
1135 bNeedsVScroll
= getDataWindow()->bAutoVScroll
1136 ? nTopRow
|| ( nRowCount
> nMaxRows
)
1137 : !getDataWindow()->bNoVScroll
;
1139 Size aDataWinSize
= pDataWin
->GetSizePixel();
1140 if ( !bNeedsVScroll
)
1142 if ( pVScroll
->IsVisible() )
1145 Size
aNewSize( aDataWinSize
);
1146 aNewSize
.Width() = GetOutputSizePixel().Width();
1147 aDataWinSize
= aNewSize
;
1150 else if ( !pVScroll
->IsVisible() )
1152 Size
aNewSize( aDataWinSize
);
1153 aNewSize
.Width() = GetOutputSizePixel().Width() - nCornerSize
;
1154 aDataWinSize
= aNewSize
;
1158 sal_uLong nLastCol
= GetColumnAtXPosPixel( aDataWinSize
.Width() - 1 );
1160 sal_uInt16 nFrozenCols
= FrozenColCount();
1161 bool bNeedsHScroll
= getDataWindow()->bAutoHScroll
1162 ? ( nFirstCol
> nFrozenCols
) || ( nLastCol
<= pCols
->size() )
1163 : !getDataWindow()->bNoHScroll
;
1164 if ( !bNeedsHScroll
)
1166 if ( aHScroll
->IsVisible() )
1170 aDataWinSize
.Height() = GetOutputSizePixel().Height() - GetTitleHeight();
1171 if ( nControlAreaWidth
!= USHRT_MAX
)
1172 aDataWinSize
.Height() -= nCornerSize
;
1174 else if ( !aHScroll
->IsVisible() )
1176 Size
aNewSize( aDataWinSize
);
1177 aNewSize
.Height() = GetOutputSizePixel().Height() - GetTitleHeight() - nCornerSize
;
1178 aDataWinSize
= aNewSize
;
1181 // adjust position and Width of horizontal scrollbar
1182 sal_uLong nHScrX
= nControlAreaWidth
== USHRT_MAX
1184 : nControlAreaWidth
;
1186 aHScroll
->SetPosSizePixel(
1187 Point( nHScrX
, GetOutputSizePixel().Height() - nCornerSize
),
1188 Size( aDataWinSize
.Width() - nHScrX
, nCornerSize
) );
1190 // total scrollable columns
1191 short nScrollCols
= short(pCols
->size()) - (short)nFrozenCols
;
1194 short nVisibleHSize
= nLastCol
== BROWSER_INVALIDID
1195 ? (short)( pCols
->size() - nFirstCol
)
1196 : (short)( nLastCol
- nFirstCol
);
1198 short nRange
= std::max( nScrollCols
, (short)0 );
1199 aHScroll
->SetVisibleSize( nVisibleHSize
);
1200 aHScroll
->SetRange( Range( 0, nRange
));
1201 if ( bNeedsHScroll
&& !aHScroll
->IsVisible() )
1204 // adjust position and height of vertical scrollbar
1205 pVScroll
->SetPageSize( nMaxRows
);
1207 if ( nTopRow
> nRowCount
)
1209 nTopRow
= nRowCount
- 1;
1210 OSL_FAIL("BrowseBox: nTopRow > nRowCount");
1213 if ( pVScroll
->GetThumbPos() != nTopRow
)
1214 pVScroll
->SetThumbPos( nTopRow
);
1215 long nVisibleSize
= std::min( std::min( nRowCount
, nMaxRows
), long(nRowCount
-nTopRow
) );
1216 pVScroll
->SetVisibleSize( nVisibleSize
? nVisibleSize
: 1 );
1217 pVScroll
->SetRange( Range( 0, nRowCount
) );
1218 pVScroll
->SetPosSizePixel(
1219 Point( aDataWinSize
.Width(), GetTitleHeight() ),
1220 Size( nCornerSize
, aDataWinSize
.Height()) );
1221 long nLclDataRowHeight
= GetDataRowHeight();
1222 if ( nLclDataRowHeight
> 0 && nRowCount
< long( aDataWinSize
.Height() / nLclDataRowHeight
) )
1223 ScrollRows( -nTopRow
);
1224 if ( bNeedsVScroll
&& !pVScroll
->IsVisible() )
1227 pDataWin
->SetPosSizePixel(
1228 Point( 0, GetTitleHeight() ),
1231 // needs corner-window?
1232 // (do that AFTER positioning BOTH scrollbars)
1233 sal_uLong nActualCorderWidth
= 0;
1234 if (aHScroll
->IsVisible() && pVScroll
&& pVScroll
->IsVisible() )
1236 // if we have both scrollbars, the corner window fills the point of intersection of these two
1237 nActualCorderWidth
= nCornerSize
;
1239 else if ( !aHScroll
->IsVisible() && ( nControlAreaWidth
!= USHRT_MAX
) )
1241 // if we have no horizontal scrollbar, but a control area, we need the corner window to
1242 // fill the space between the control are and the right border
1243 nActualCorderWidth
= GetOutputSizePixel().Width() - nControlAreaWidth
;
1245 if ( nActualCorderWidth
)
1247 if ( !getDataWindow()->pCornerWin
)
1248 getDataWindow()->pCornerWin
= VclPtr
<ScrollBarBox
>::Create( this, 0 );
1249 getDataWindow()->pCornerWin
->SetPosSizePixel(
1250 Point( GetOutputSizePixel().Width() - nActualCorderWidth
, aHScroll
->GetPosPixel().Y() ),
1251 Size( nActualCorderWidth
, nCornerSize
) );
1252 getDataWindow()->pCornerWin
->Show();
1255 getDataWindow()->pCornerWin
.disposeAndClear();
1257 // scroll headerbar, if necessary
1258 if ( getDataWindow()->pHeaderBar
)
1261 for ( size_t nCol
= 0;
1262 nCol
< pCols
->size() && nCol
< nFirstCol
;
1265 // not the handle column
1266 if ( (*pCols
)[ nCol
]->GetId() )
1267 nWidth
+= (*pCols
)[ nCol
]->Width();
1270 getDataWindow()->pHeaderBar
->SetOffset( nWidth
);
1273 pBDW
->bInUpdateScrollbars
= false;
1274 if ( pBDW
->bHadRecursion
)
1276 pBDW
->bHadRecursion
= false;
1283 void BrowseBox::SetUpdateMode( bool bUpdate
)
1286 bool bWasUpdate
= IsUpdateMode();
1287 if ( bWasUpdate
== bUpdate
)
1290 Control::SetUpdateMode( bUpdate
);
1291 // If WB_CLIPCHILDREN is st at the BrowseBox (to minimize flicker),
1292 // the data window is not invalidated by SetUpdateMode.
1294 getDataWindow()->Invalidate();
1295 getDataWindow()->SetUpdateMode( bUpdate
);
1300 if ( bBootstrapped
)
1303 AutoSizeLastColumn();
1305 DoShowCursor( "SetUpdateMode" );
1308 DoHideCursor( "SetUpdateMode" );
1313 bool BrowseBox::GetUpdateMode() const
1316 return getDataWindow()->IsUpdateMode();
1321 long BrowseBox::GetFrozenWidth() const
1325 for ( size_t nCol
= 0;
1326 nCol
< pCols
->size() && (*pCols
)[ nCol
]->IsFrozen();
1328 nWidth
+= (*pCols
)[ nCol
]->Width();
1334 void BrowseBox::ColumnInserted( sal_uInt16 nPos
)
1338 pColSel
->Insert( nPos
);
1344 sal_uInt16
BrowseBox::FrozenColCount() const
1348 nCol
< pCols
->size() && (*pCols
)[ nCol
]->IsFrozen();
1356 IMPL_LINK(BrowseBox
,ScrollHdl
,ScrollBar
*,pBar
)
1359 if ( pBar
->GetDelta() == 0 )
1362 if ( pBar
->GetDelta() < 0 && getDataWindow()->bNoScrollBack
)
1368 if ( pBar
== aHScroll
.get() )
1369 ScrollColumns( aHScroll
->GetDelta() );
1370 if ( pBar
== pVScroll
)
1371 ScrollRows( pVScroll
->GetDelta() );
1378 IMPL_LINK_NOARG(BrowseBox
, EndScrollHdl
)
1381 if ( getDataWindow()->bNoScrollBack
)
1392 IMPL_LINK( BrowseBox
, StartDragHdl
, HeaderBar
*, pBar
)
1394 pBar
->SetDragSize( pDataWin
->GetOutputSizePixel().Height() );
1399 // usually only the first column was resized
1401 void BrowseBox::MouseButtonDown( const MouseEvent
& rEvt
)
1406 // only mouse events in the title-line are supported
1407 const Point
&rEvtPos
= rEvt
.GetPosPixel();
1408 if ( rEvtPos
.Y() >= GetTitleHeight() )
1412 long nWidth
= GetOutputSizePixel().Width();
1413 for ( size_t nCol
= 0; nCol
< pCols
->size() && nX
< nWidth
; ++nCol
)
1415 // is this column visible?
1416 BrowserColumn
*pCol
= (*pCols
)[ nCol
];
1417 if ( pCol
->IsFrozen() || nCol
>= nFirstCol
)
1419 // compute right end of column
1420 long nR
= nX
+ pCol
->Width() - 1;
1422 // at the end of a column (and not handle column)?
1423 if ( pCol
->GetId() && std::abs( nR
- rEvtPos
.X() ) < 2 )
1425 // start resizing the column
1428 nDragX
= nResizeX
= rEvtPos
.X();
1429 SetPointer( Pointer( PointerStyle::HSplit
) );
1431 pDataWin
->DrawLine( Point( nDragX
, 0 ),
1432 Point( nDragX
, pDataWin
->GetSizePixel().Height() ) );
1433 nMinResizeX
= nX
+ MIN_COLUMNWIDTH
;
1436 else if ( nX
< rEvtPos
.X() && nR
> rEvtPos
.X() )
1438 MouseButtonDown( BrowserMouseEvent(
1439 this, rEvt
, -1, nCol
, pCol
->GetId(), Rectangle() ) );
1446 // event occurred out of data area
1447 if ( rEvt
.IsRight() )
1449 CommandEvent( Point( 1, LONG_MAX
), CommandEventId::ContextMenu
, true ) );
1456 void BrowseBox::MouseMove( const MouseEvent
& rEvt
)
1458 OSL_TRACE( "BrowseBox::MouseMove( MouseEvent )" );
1460 Pointer aNewPointer
;
1463 for ( size_t nCol
= 0;
1464 nCol
< pCols
->size() &&
1465 ( nX
+ (*pCols
)[ nCol
]->Width() ) < sal_uInt16(GetOutputSizePixel().Width());
1467 // is this column visible?
1468 if ( (*pCols
)[ nCol
]->IsFrozen() || nCol
>= nFirstCol
)
1470 // compute right end of column
1471 BrowserColumn
*pCol
= (*pCols
)[ nCol
];
1472 sal_uInt16 nR
= (sal_uInt16
)(nX
+ pCol
->Width() - 1);
1474 // show resize-pointer?
1475 if ( bResizing
|| ( pCol
->GetId() &&
1476 std::abs( ((long) nR
) - rEvt
.GetPosPixel().X() ) < MIN_COLUMNWIDTH
) )
1478 aNewPointer
= Pointer( PointerStyle::HSplit
);
1481 // delete old auxiliary line
1482 pDataWin
->HideTracking() ;
1484 // check allowed width and new delta
1485 nDragX
= std::max( rEvt
.GetPosPixel().X(), nMinResizeX
);
1486 long nDeltaX
= nDragX
- nResizeX
;
1487 sal_uInt16 nId
= GetColumnId(nResizeCol
);
1488 sal_uLong nOldWidth
= GetColumnWidth(nId
);
1489 nDragX
= QueryColumnResize( GetColumnId(nResizeCol
),
1490 nOldWidth
+ nDeltaX
)
1491 + nResizeX
- nOldWidth
;
1493 // draw new auxiliary line
1494 pDataWin
->ShowTracking( Rectangle( Point( nDragX
, 0 ),
1495 Size( 1, pDataWin
->GetSizePixel().Height() ) ),
1496 SHOWTRACK_SPLIT
|SHOWTRACK_WINDOW
);
1504 SetPointer( aNewPointer
);
1509 void BrowseBox::MouseButtonUp( const MouseEvent
& rEvt
)
1514 // delete auxiliary line
1515 pDataWin
->HideTracking();
1518 nDragX
= std::max( rEvt
.GetPosPixel().X(), nMinResizeX
);
1519 if ( (nDragX
- nResizeX
) != (long)(*pCols
)[ nResizeCol
]->Width() )
1522 long nMaxX
= pDataWin
->GetSizePixel().Width();
1523 nDragX
= std::min( nDragX
, nMaxX
);
1524 long nDeltaX
= nDragX
- nResizeX
;
1525 sal_uInt16 nId
= GetColumnId(nResizeCol
);
1526 SetColumnWidth( GetColumnId(nResizeCol
), GetColumnWidth(nId
) + nDeltaX
);
1527 ColumnResized( nId
);
1531 SetPointer( Pointer() );
1536 MouseButtonUp( BrowserMouseEvent( static_cast<BrowserDataWin
*>(pDataWin
.get()),
1537 MouseEvent( Point( rEvt
.GetPosPixel().X(),
1538 rEvt
.GetPosPixel().Y() - pDataWin
->GetPosPixel().Y() ),
1539 rEvt
.GetClicks(), rEvt
.GetMode(), rEvt
.GetButtons(),
1540 rEvt
.GetModifier() ) ) );
1545 bool bExtendedMode
= false;
1546 bool bFieldMode
= false;
1548 void BrowseBox::MouseButtonDown( const BrowserMouseEvent
& rEvt
)
1553 // adjust selection while and after double-click
1554 if ( rEvt
.GetClicks() == 2 )
1557 if ( rEvt
.GetRow() >= 0 )
1559 GoToRow( rEvt
.GetRow() );
1560 SelectRow( rEvt
.GetRow(), true, false );
1564 if ( bColumnCursor
&& rEvt
.GetColumn() != 0 )
1566 if ( rEvt
.GetColumn() < pCols
->size() )
1567 SelectColumnPos( rEvt
.GetColumn(), true, false);
1570 DoubleClick( rEvt
);
1573 else if ( ( rEvt
.GetMode() & ( MouseEventModifiers::SELECT
| MouseEventModifiers::SIMPLECLICK
) ) &&
1574 ( bColumnCursor
|| rEvt
.GetRow() >= 0 ) )
1576 if ( rEvt
.GetClicks() == 1 )
1581 a2ndPoint
= PixelToLogic( rEvt
.GetPosPixel() );
1583 // selection out of range?
1584 if ( rEvt
.GetRow() >= nRowCount
||
1585 rEvt
.GetColumnId() == BROWSER_INVALIDID
)
1591 // while selecting, no cursor
1593 DoHideCursor( "MouseButtonDown" );
1596 if ( rEvt
.GetRow() >= 0 )
1599 if ( rEvt
.GetColumnId() == HandleColumnId
|| !bColumnCursor
)
1601 if ( bMultiSelection
)
1603 // remove column-selection, if exists
1604 if ( pColSel
&& pColSel
->GetSelectCount() )
1607 if ( bMultiSelection
)
1608 uRow
.pSel
->SelectAll(false);
1610 uRow
.nSel
= BROWSER_ENDOFSELECTION
;
1612 pColSel
->SelectAll(false);
1617 if ( rEvt
.GetMode() & MouseEventModifiers::RANGESELECT
)
1619 // select the further touched rows too
1621 ExpandRowSelection( rEvt
);
1625 // click in the selected area?
1626 else if ( IsRowSelected( rEvt
.GetRow() ) )
1628 // wait for Drag&Drop
1630 bExtendedMode
= bool( rEvt
.GetMode() & MouseEventModifiers::MULTISELECT
);
1635 else if ( rEvt
.GetMode() & MouseEventModifiers::MULTISELECT
)
1637 // determine the new selection range
1638 // and selection/deselection
1639 aSelRange
= Range( rEvt
.GetRow(), rEvt
.GetRow() );
1640 SelectRow( rEvt
.GetRow(),
1641 !uRow
.pSel
->IsSelected( rEvt
.GetRow() ) );
1649 GoToRow( rEvt
.GetRow() );
1650 SelectRow( rEvt
.GetRow(), true );
1651 aSelRange
= Range( rEvt
.GetRow(), rEvt
.GetRow() );
1654 else // Column/Field-Selection
1656 // click in selected column
1657 if ( IsColumnSelected( rEvt
.GetColumn() ) ||
1658 IsRowSelected( rEvt
.GetRow() ) )
1666 GoToRowColumnId( rEvt
.GetRow(), rEvt
.GetColumnId() );
1672 if ( bMultiSelection
&& rEvt
.GetColumnId() == HandleColumnId
)
1674 // toggle all-selection
1675 if ( uRow
.pSel
->GetSelectCount() > ( GetRowCount() / 2 ) )
1681 SelectColumnId( rEvt
.GetColumnId(), true, false );
1684 // turn cursor on again, if necessary
1686 DoShowCursor( "MouseButtonDown" );
1695 void BrowseBox::MouseButtonUp( const BrowserMouseEvent
&rEvt
)
1698 // D&D was possible, but did not occur
1701 aSelRange
= Range( rEvt
.GetRow(), rEvt
.GetRow() );
1702 if ( bExtendedMode
)
1703 SelectRow( rEvt
.GetRow(), false );
1708 GoToRowColumnId( rEvt
.GetRow(), rEvt
.GetColumnId() );
1711 GoToRow( rEvt
.GetRow() );
1712 SelectRow( rEvt
.GetRow(), true );
1716 bExtendedMode
= false;
1725 DoShowCursor( "MouseButtonUp" );
1733 void BrowseBox::KeyInput( const KeyEvent
& rEvt
)
1735 if ( !ProcessKey( rEvt
) )
1736 Control::KeyInput( rEvt
);
1741 bool BrowseBox::ProcessKey( const KeyEvent
& rEvt
)
1744 sal_uInt16 nCode
= rEvt
.GetKeyCode().GetCode();
1745 bool bShift
= rEvt
.GetKeyCode().IsShift();
1746 bool bCtrl
= rEvt
.GetKeyCode().IsMod1();
1747 bool bAlt
= rEvt
.GetKeyCode().IsMod2();
1749 sal_uInt16 nId
= BROWSER_NONE
;
1751 if ( !bAlt
&& !bCtrl
&& !bShift
)
1755 case KEY_DOWN
: nId
= BROWSER_CURSORDOWN
; break;
1756 case KEY_UP
: nId
= BROWSER_CURSORUP
; break;
1757 case KEY_HOME
: nId
= BROWSER_CURSORHOME
; break;
1758 case KEY_END
: nId
= BROWSER_CURSOREND
; break;
1760 if ( !bColumnCursor
)
1762 case KEY_RIGHT
: nId
= BROWSER_CURSORRIGHT
; break;
1763 case KEY_LEFT
: nId
= BROWSER_CURSORLEFT
; break;
1764 case KEY_SPACE
: nId
= BROWSER_SELECT
; break;
1766 if ( BROWSER_NONE
!= nId
)
1771 case KEY_PAGEDOWN
: nId
= BROWSER_CURSORPAGEDOWN
; break;
1772 case KEY_PAGEUP
: nId
= BROWSER_CURSORPAGEUP
; break;
1776 if ( !bAlt
&& !bCtrl
&& bShift
)
1779 case KEY_DOWN
: nId
= BROWSER_SELECTDOWN
; break;
1780 case KEY_UP
: nId
= BROWSER_SELECTUP
; break;
1782 if ( !bColumnCursor
)
1784 nId
= BROWSER_CURSORLEFT
; break;
1785 case KEY_HOME
: nId
= BROWSER_SELECTHOME
; break;
1786 case KEY_END
: nId
= BROWSER_SELECTEND
; break;
1790 if ( !bAlt
&& bCtrl
&& !bShift
)
1793 case KEY_DOWN
: nId
= BROWSER_CURSORDOWN
; break;
1794 case KEY_UP
: nId
= BROWSER_CURSORUP
; break;
1795 case KEY_PAGEDOWN
: nId
= BROWSER_CURSORENDOFFILE
; break;
1796 case KEY_PAGEUP
: nId
= BROWSER_CURSORTOPOFFILE
; break;
1797 case KEY_HOME
: nId
= BROWSER_CURSORTOPOFSCREEN
; break;
1798 case KEY_END
: nId
= BROWSER_CURSORENDOFSCREEN
; break;
1799 case KEY_SPACE
: nId
= BROWSER_ENHANCESELECTION
; break;
1800 case KEY_LEFT
: nId
= BROWSER_MOVECOLUMNLEFT
; break;
1801 case KEY_RIGHT
: nId
= BROWSER_MOVECOLUMNRIGHT
; break;
1804 if ( nId
!= BROWSER_NONE
)
1806 return nId
!= BROWSER_NONE
;
1811 void BrowseBox::Dispatch( sal_uInt16 nId
)
1814 long nRowsOnPage
= pDataWin
->GetSizePixel().Height() / GetDataRowHeight();
1819 case BROWSER_SELECTCOLUMN
:
1821 SelectColumnId( GetCurColumnId() );
1824 case BROWSER_CURSORDOWN
:
1825 if ( ( GetCurRow() + 1 ) < nRowCount
)
1826 bDone
= GoToRow( GetCurRow() + 1, false );
1828 case BROWSER_CURSORUP
:
1829 if ( GetCurRow() > 0 )
1830 bDone
= GoToRow( GetCurRow() - 1, false );
1832 case BROWSER_SELECTHOME
:
1833 if ( GetRowCount() )
1835 DoHideCursor( "BROWSER_SELECTHOME" );
1836 for ( long nRow
= GetCurRow(); nRow
>= 0; --nRow
)
1839 DoShowCursor( "BROWSER_SELECTHOME" );
1842 case BROWSER_SELECTEND
:
1843 if ( GetRowCount() )
1845 DoHideCursor( "BROWSER_SELECTEND" );
1846 long nRows
= GetRowCount();
1847 for ( long nRow
= GetCurRow(); nRow
< nRows
; ++nRow
)
1849 GoToRow( GetRowCount() - 1, true );
1850 DoShowCursor( "BROWSER_SELECTEND" );
1853 case BROWSER_SELECTDOWN
:
1855 if ( GetRowCount() && ( GetCurRow() + 1 ) < nRowCount
)
1857 // deselect the current row, if it isn't the first
1858 // and there is no other selected row above
1859 long nRow
= GetCurRow();
1860 bool bLocalSelect
= ( !IsRowSelected( nRow
) ||
1861 GetSelectRowCount() == 1 || IsRowSelected( nRow
- 1 ) );
1862 SelectRow( nRow
, bLocalSelect
, true );
1863 bDone
= GoToRow( GetCurRow() + 1, false );
1865 SelectRow( GetCurRow(), true, true );
1868 bDone
= ScrollRows( 1 ) != 0;
1871 case BROWSER_SELECTUP
:
1872 if ( GetRowCount() )
1874 // deselect the current row, if it isn't the first
1875 // and there is no other selected row under
1876 long nRow
= GetCurRow();
1877 bool bLocalSelect
= ( !IsRowSelected( nRow
) ||
1878 GetSelectRowCount() == 1 || IsRowSelected( nRow
+ 1 ) );
1879 SelectRow( nCurRow
, bLocalSelect
, true );
1880 bDone
= GoToRow( nRow
- 1, false );
1882 SelectRow( GetCurRow(), true, true );
1885 case BROWSER_CURSORPAGEDOWN
:
1886 bDone
= ScrollRows( nRowsOnPage
);
1888 case BROWSER_CURSORPAGEUP
:
1889 bDone
= ScrollRows( -nRowsOnPage
);
1891 case BROWSER_CURSOREND
:
1892 if ( bColumnCursor
)
1894 sal_uInt16 nNewId
= GetColumnId(ColCount() -1);
1895 bDone
= nNewId
!= HandleColumnId
&& GoToColumnId( nNewId
);
1898 case BROWSER_CURSORENDOFFILE
:
1899 bDone
= GoToRow( nRowCount
- 1, false );
1901 case BROWSER_CURSORRIGHT
:
1902 if ( bColumnCursor
)
1904 sal_uInt16 nNewPos
= GetColumnPos( GetCurColumnId() ) + 1;
1905 sal_uInt16 nNewId
= GetColumnId( nNewPos
);
1906 if (nNewId
!= BROWSER_INVALIDID
) // At end of row ?
1907 bDone
= GoToColumnId( nNewId
);
1910 sal_uInt16 nColId
= GetColumnId(0);
1911 if ( nColId
== BROWSER_INVALIDID
|| nColId
== HandleColumnId
)
1912 nColId
= GetColumnId(1);
1913 if ( GetRowCount() )
1914 bDone
= ( nCurRow
< GetRowCount() - 1 ) && GoToRowColumnId( nCurRow
+ 1, nColId
);
1915 else if ( ColCount() )
1916 GoToColumnId( nColId
);
1920 bDone
= ScrollColumns( 1 ) != 0;
1922 case BROWSER_CURSORHOME
:
1923 if ( bColumnCursor
)
1925 sal_uInt16 nNewId
= GetColumnId(1);
1926 bDone
= (nNewId
!= HandleColumnId
) && GoToColumnId( nNewId
);
1929 case BROWSER_CURSORTOPOFFILE
:
1930 bDone
= GoToRow( 0, false );
1932 case BROWSER_CURSORLEFT
:
1933 if ( bColumnCursor
)
1935 sal_uInt16 nNewPos
= GetColumnPos( GetCurColumnId() ) - 1;
1936 sal_uInt16 nNewId
= GetColumnId( nNewPos
);
1937 if (nNewId
!= HandleColumnId
)
1938 bDone
= GoToColumnId( nNewId
);
1941 if ( GetRowCount() )
1942 bDone
= (nCurRow
> 0) && GoToRowColumnId(nCurRow
- 1, GetColumnId(ColCount() -1));
1943 else if ( ColCount() )
1944 GoToColumnId( GetColumnId(ColCount() -1) );
1948 bDone
= ScrollColumns( -1 ) != 0;
1950 case BROWSER_ENHANCESELECTION
:
1951 if ( GetRowCount() )
1952 SelectRow( GetCurRow(), !IsRowSelected( GetCurRow() ), true );
1955 case BROWSER_SELECT
:
1956 if ( GetRowCount() )
1957 SelectRow( GetCurRow(), !IsRowSelected( GetCurRow() ), false );
1960 case BROWSER_MOVECOLUMNLEFT
:
1961 case BROWSER_MOVECOLUMNRIGHT
:
1962 { // check if column moving is allowed
1963 BrowserHeader
* pHeaderBar
= getDataWindow()->pHeaderBar
;
1964 if ( pHeaderBar
&& pHeaderBar
->IsDragable() )
1966 sal_uInt16 nColId
= GetCurColumnId();
1967 bool bColumnSelected
= IsColumnSelected(nColId
);
1968 sal_uInt16 nNewPos
= GetColumnPos(nColId
);
1969 bool bMoveAllowed
= false;
1970 if ( BROWSER_MOVECOLUMNLEFT
== nId
&& nNewPos
> 1 )
1971 --nNewPos
,bMoveAllowed
= true;
1972 else if ( BROWSER_MOVECOLUMNRIGHT
== nId
&& nNewPos
< (ColCount()-1) )
1973 ++nNewPos
,bMoveAllowed
= true;
1977 SetColumnPos( nColId
, nNewPos
);
1978 ColumnMoved( nColId
);
1979 MakeFieldVisible(GetCurRow(), nColId
, true);
1980 if ( bColumnSelected
)
1981 SelectColumnId(nColId
);
1993 void BrowseBox::SetCursorColor(const Color
& _rCol
)
1995 if (_rCol
== m_aCursorColor
)
1998 // ensure the cursor is hidden
1999 DoHideCursor("SetCursorColor");
2000 if (!m_bFocusOnlyCursor
)
2001 DoHideCursor("SetCursorColor - force");
2003 m_aCursorColor
= _rCol
;
2005 if (!m_bFocusOnlyCursor
)
2006 DoShowCursor("SetCursorColor - force");
2007 DoShowCursor("SetCursorColor");
2010 Rectangle
BrowseBox::calcHeaderRect(bool _bIsColumnBar
, bool _bOnScreen
)
2012 vcl::Window
* pParent
= NULL
;
2014 pParent
= GetAccessibleParentWindow();
2019 if ( _bIsColumnBar
)
2021 nWidth
= GetDataWindow().GetOutputSizePixel().Width();
2022 nHeight
= GetDataRowHeight();
2026 aTopLeft
.Y() = GetDataRowHeight();
2027 nWidth
= GetColumnWidth(0);
2028 nHeight
= GetWindowExtentsRelative( pParent
).GetHeight() - aTopLeft
.Y() - GetControlArea().GetSize().B();
2030 aTopLeft
+= GetWindowExtentsRelative( pParent
).TopLeft();
2031 return Rectangle(aTopLeft
,Size(nWidth
,nHeight
));
2034 Rectangle
BrowseBox::calcTableRect(bool _bOnScreen
)
2036 vcl::Window
* pParent
= NULL
;
2038 pParent
= GetAccessibleParentWindow();
2040 Rectangle
aRect( GetWindowExtentsRelative( pParent
) );
2041 Rectangle aRowBar
= calcHeaderRect(false, pParent
== NULL
);
2043 long nX
= aRowBar
.Right() - aRect
.Left();
2044 long nY
= aRowBar
.Top() - aRect
.Top();
2045 Size
aSize(aRect
.GetSize());
2047 return Rectangle(aRowBar
.TopRight(), Size(aSize
.A() - nX
, aSize
.B() - nY
- aHScroll
->GetSizePixel().Height()) );
2050 Rectangle
BrowseBox::GetFieldRectPixelAbs( sal_Int32 _nRowId
, sal_uInt16 _nColId
, bool /*_bIsHeader*/, bool _bOnScreen
)
2052 vcl::Window
* pParent
= NULL
;
2054 pParent
= GetAccessibleParentWindow();
2056 Rectangle aRect
= GetFieldRectPixel(_nRowId
,_nColId
,_bOnScreen
);
2058 Point aTopLeft
= aRect
.TopLeft();
2059 aTopLeft
+= GetWindowExtentsRelative( pParent
).TopLeft();
2061 return Rectangle(aTopLeft
,aRect
.GetSize());
2064 // ------------------------------------------------------------------------- EOF
2066 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */