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 <svtools/brwbox.hxx>
21 #include <svtools/brwhead.hxx>
23 #include <tools/debug.hxx>
24 #include <tools/stream.hxx>
28 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
29 #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
30 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
31 #include <com/sun/star/accessibility/XAccessible.hpp>
32 #include <tools/multisel.hxx>
33 #include "brwimpl.hxx"
37 extern const char* BrowseBoxCheckInvariants( const void* pVoid
);
39 #define SCROLL_FLAGS (SCROLL_CLIP | SCROLL_NOCHILDREN)
40 #define getDataWindow() ((BrowserDataWin*)pDataWin)
42 using namespace com::sun::star::accessibility::AccessibleEventId
;
43 using namespace com::sun::star::accessibility::AccessibleTableModelChangeType
;
44 using com::sun::star::accessibility::AccessibleTableModelChange
;
45 using com::sun::star::lang::XComponent
;
46 using namespace ::com::sun::star::uno
;
49 //-------------------------------------------------------------------
53 void disposeAndClearHeaderCell(::svt::BrowseBoxImpl::THeaderCellMap
& _rHeaderCell
)
58 ::svt::BrowseBoxImpl::THeaderCellMapFunctorDispose()
64 //===================================================================
66 void BrowseBox::ConstructImpl( BrowserMode nMode
)
68 OSL_TRACE( "BrowseBox: %p->ConstructImpl", this );
69 bMultiSelection
= sal_False
;
74 pDataWin
= new BrowserDataWin( this );
75 pCols
= new BrowserColumns
;
76 m_pImpl
.reset( new ::svt::BrowseBoxImpl() );
78 aGridLineColor
= Color( COL_LIGHTGRAY
);
79 InitSettings_Impl( this );
80 InitSettings_Impl( pDataWin
);
82 bBootstrapped
= sal_False
;
87 nCurRow
= BROWSER_ENDOFSELECTION
;
89 bResizing
= sal_False
;
91 bSelecting
= sal_False
;
92 bScrolling
= sal_False
;
93 bSelectionIsVisible
= sal_False
;
94 bNotToggleSel
= sal_False
;
95 bRowDividerDrag
= sal_False
;
97 mbInteractiveRowHeight
= sal_False
;
98 bHideSelect
= sal_False
;
99 bHideCursor
= NO_CURSOR_HIDE
;
101 m_bFocusOnlyCursor
= sal_True
;
102 m_aCursorColor
= COL_TRANSPARENT
;
104 nControlAreaWidth
= USHRT_MAX
;
105 uRow
.nSel
= BROWSER_ENDOFSELECTION
;
107 aHScroll
.SetLineSize(1);
108 aHScroll
.SetScrollHdl( LINK( this, BrowseBox
, ScrollHdl
) );
109 aHScroll
.SetEndScrollHdl( LINK( this, BrowseBox
, EndScrollHdl
) );
113 bSelectionIsVisible
= bKeepHighlight
;
114 bHasFocus
= HasChildPathFocus();
115 getDataWindow()->nCursorHidden
=
116 ( bHasFocus
? 0 : 1 ) + ( GetUpdateMode() ? 0 : 1 );
119 //-------------------------------------------------------------------
121 BrowseBox::BrowseBox( Window
* pParent
, WinBits nBits
, BrowserMode nMode
)
122 :Control( pParent
, nBits
| WB_3DLOOK
)
123 ,DragSourceHelper( this )
124 ,DropTargetHelper( this )
125 ,aHScroll( this, WinBits( WB_HSCROLL
) )
127 DBG_CTOR( BrowseBox
, NULL
);
128 ConstructImpl( nMode
);
131 //-------------------------------------------------------------------
133 BrowseBox::BrowseBox( Window
* pParent
, const ResId
& rId
, BrowserMode nMode
)
134 :Control( pParent
, rId
)
135 ,DragSourceHelper( this )
136 ,DropTargetHelper( this )
137 ,aHScroll( this, WinBits(WB_HSCROLL
) )
139 DBG_CTOR( BrowseBox
, NULL
);
140 ConstructImpl(nMode
);
142 //-------------------------------------------------------------------
144 BrowseBox::~BrowseBox()
146 DBG_DTOR(BrowseBox
,BrowseBoxCheckInvariants
);
147 OSL_TRACE( "BrowseBox: %p~", this );
149 if ( m_pImpl
->m_pAccessible
)
151 disposeAndClearHeaderCell(m_pImpl
->m_aColHeaderCellMap
);
152 disposeAndClearHeaderCell(m_pImpl
->m_aRowHeaderCellMap
);
153 m_pImpl
->m_pAccessible
->dispose();
157 delete getDataWindow()->pHeaderBar
;
158 delete getDataWindow()->pCornerWin
;
162 // free columns-space
163 for ( size_t i
= 0, n
= pCols
->size(); i
< n
; ++i
)
164 delete (*pCols
)[ i
];
168 if ( bMultiSelection
)
172 //-------------------------------------------------------------------
174 short BrowseBox::GetCursorHideCount() const
176 return getDataWindow()->nCursorHidden
;
179 //-------------------------------------------------------------------
181 void BrowseBox::DoShowCursor( const char * )
183 short nHiddenCount
= --getDataWindow()->nCursorHidden
;
184 if (PaintCursorIfHiddenOnce())
186 if (1 == nHiddenCount
)
191 if (0 == nHiddenCount
)
196 //-------------------------------------------------------------------
198 void BrowseBox::DoHideCursor( const char * )
200 short nHiddenCount
= ++getDataWindow()->nCursorHidden
;
201 if (PaintCursorIfHiddenOnce())
203 if (2 == nHiddenCount
)
208 if (1 == nHiddenCount
)
213 //-------------------------------------------------------------------
215 void BrowseBox::SetRealRowCount( const String
&rRealRowCount
)
217 getDataWindow()->aRealRowCount
= rRealRowCount
;
220 //-------------------------------------------------------------------
222 void BrowseBox::SetFont( const Font
& rNewFont
)
224 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
225 pDataWin
->SetFont( rNewFont
);
226 ImpGetDataRowHeight();
229 //-------------------------------------------------------------------
231 sal_uLong
BrowseBox::GetDefaultColumnWidth( const String
& _rText
) const
233 return GetDataWindow().GetTextWidth( _rText
) + GetDataWindow().GetTextWidth(OUString('0')) * 4;
236 //-------------------------------------------------------------------
238 void BrowseBox::InsertHandleColumn( sal_uLong nWidth
)
240 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
242 #if OSL_DEBUG_LEVEL > 0
243 OSL_ENSURE( ColCount() == 0 || (*pCols
)[0]->GetId() != HandleColumnId
, "BrowseBox::InsertHandleColumn: there is already a handle column" );
245 BrowserColumns::iterator iCol
= pCols
->begin();
246 const BrowserColumns::iterator colsEnd
= pCols
->end();
247 if ( iCol
< colsEnd
)
248 for (++iCol
; iCol
< colsEnd
; ++iCol
)
249 OSL_ENSURE( (*iCol
)->GetId() != HandleColumnId
, "BrowseBox::InsertHandleColumn: there is a non-Handle column with handle ID" );
253 pCols
->insert( pCols
->begin(), new BrowserColumn( 0, Image(), String(), nWidth
, GetZoom() ) );
257 if ( getDataWindow()->pHeaderBar
)
259 getDataWindow()->pHeaderBar
->SetPosSizePixel(
261 Size( GetOutputSizePixel().Width() - nWidth
, GetTitleHeight() )
268 //-------------------------------------------------------------------
270 void BrowseBox::InsertDataColumn( sal_uInt16 nItemId
, const XubString
& rText
,
271 long nWidth
, HeaderBarItemBits nBits
, sal_uInt16 nPos
)
273 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
275 OSL_ENSURE( nItemId
!= HandleColumnId
, "BrowseBox::InsertDataColumn: nItemId is HandleColumnId" );
276 OSL_ENSURE( nItemId
!= BROWSER_INVALIDID
, "BrowseBox::InsertDataColumn: nItemId is reserved value BROWSER_INVALIDID" );
278 #if OSL_DEBUG_LEVEL > 0
280 const BrowserColumns::iterator colsEnd
= pCols
->end();
281 for (BrowserColumns::iterator iCol
= pCols
->begin(); iCol
< colsEnd
; ++iCol
)
282 OSL_ENSURE( (*iCol
)->GetId() != nItemId
, "BrowseBox::InsertDataColumn: duplicate column Id" );
286 if ( nPos
< pCols
->size() )
288 BrowserColumns::iterator it
= pCols
->begin();
289 ::std::advance( it
, nPos
);
290 pCols
->insert( it
, new BrowserColumn( nItemId
, Image(), rText
, nWidth
, GetZoom() ) );
294 pCols
->push_back( new BrowserColumn( nItemId
, Image(), rText
, nWidth
, GetZoom() ) );
296 if ( nCurColId
== 0 )
299 if ( getDataWindow()->pHeaderBar
)
301 // Handle column not in the header bar
302 sal_uInt16 nHeaderPos
= nPos
;
303 if (nHeaderPos
!= HEADERBAR_APPEND
&& GetColumnId(0) == HandleColumnId
)
305 getDataWindow()->pHeaderBar
->InsertItem(
306 nItemId
, rText
, nWidth
, nBits
, nHeaderPos
);
308 ColumnInserted( nPos
);
311 //-------------------------------------------------------------------
312 sal_uInt16
BrowseBox::ToggleSelectedColumn()
314 sal_uInt16 nSelectedColId
= BROWSER_INVALIDID
;
315 if ( pColSel
&& pColSel
->GetSelectCount() )
317 DoHideCursor( "ToggleSelectedColumn" );
319 nSelectedColId
= (*pCols
)[ pColSel
->FirstSelected() ]->GetId();
320 pColSel
->SelectAll(sal_False
);
322 return nSelectedColId
;
324 // -----------------------------------------------------------------------------
325 void BrowseBox::SetToggledSelectedColumn(sal_uInt16 _nSelectedColumnId
)
327 if ( pColSel
&& _nSelectedColumnId
!= BROWSER_INVALIDID
)
329 pColSel
->Select( GetColumnPos( _nSelectedColumnId
) );
331 OSL_TRACE( "BrowseBox: %p->SetToggledSelectedColumn", this );
332 DoShowCursor( "SetToggledSelectedColumn" );
335 // -----------------------------------------------------------------------------
336 void BrowseBox::FreezeColumn( sal_uInt16 nItemId
, sal_Bool bFreeze
)
338 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
340 // never unfreeze the handle-column
341 if ( nItemId
== HandleColumnId
&& !bFreeze
)
344 // get the position in the current array
345 size_t nItemPos
= GetColumnPos( nItemId
);
346 if ( nItemPos
>= pCols
->size() )
350 // doesn't the state change?
351 if ( (*pCols
)[ nItemPos
]->IsFrozen() == bFreeze
)
354 // remark the column selection
355 sal_uInt16 nSelectedColId
= ToggleSelectedColumn();
357 // freeze or unfreeze?
361 if ( nItemPos
!= 0 && !(*pCols
)[ nItemPos
-1 ]->IsFrozen() )
363 // move to the right of the last frozen column
364 sal_uInt16 nFirstScrollable
= FrozenColCount();
365 BrowserColumn
*pColumn
= (*pCols
)[ nItemPos
];
366 BrowserColumns::iterator it
= pCols
->begin();
367 ::std::advance( it
, nItemPos
);
369 nItemPos
= nFirstScrollable
;
371 ::std::advance( it
, nItemPos
);
372 pCols
->insert( it
, pColumn
);
375 // adjust the number of the first scrollable and visible column
376 if ( nFirstCol
<= nItemPos
)
377 nFirstCol
= nItemPos
+ 1;
382 if ( (sal_Int32
)nItemPos
!= FrozenColCount()-1 )
384 // move to the leftmost scrollable colum
385 sal_uInt16 nFirstScrollable
= FrozenColCount();
386 BrowserColumn
*pColumn
= (*pCols
)[ nItemPos
];
387 BrowserColumns::iterator it
= pCols
->begin();
388 ::std::advance( it
, nItemPos
);
390 nItemPos
= nFirstScrollable
;
392 ::std::advance( it
, nItemPos
);
393 pCols
->insert( it
, pColumn
);
396 // adjust the number of the first scrollable and visible column
397 nFirstCol
= nItemPos
;
400 // toggle the freeze-state of the column
401 (*pCols
)[ nItemPos
]->Freeze( bFreeze
);
403 // align the scrollbar-range
407 Control::Invalidate();
408 getDataWindow()->Invalidate();
410 // remember the column selection
411 SetToggledSelectedColumn(nSelectedColId
);
414 //-------------------------------------------------------------------
416 void BrowseBox::SetColumnPos( sal_uInt16 nColumnId
, sal_uInt16 nPos
)
418 // never set pos of the handle column
419 if ( nColumnId
== HandleColumnId
)
422 // get the position in the current array
423 sal_uInt16 nOldPos
= GetColumnPos( nColumnId
);
424 if ( nOldPos
>= pCols
->size() )
428 // does the state change?
431 // remark the column selection
432 sal_uInt16 nSelectedColId
= ToggleSelectedColumn();
434 // determine old column area
435 Size
aDataWinSize( pDataWin
->GetSizePixel() );
436 if ( getDataWindow()->pHeaderBar
)
437 aDataWinSize
.Height() += getDataWindow()->pHeaderBar
->GetSizePixel().Height();
439 Rectangle
aFromRect( GetFieldRect( nColumnId
) );
440 aFromRect
.Right() += 2*MIN_COLUMNWIDTH
;
442 sal_uInt16 nNextPos
= nOldPos
+ 1;
443 if ( nOldPos
> nPos
)
444 nNextPos
= nOldPos
- 1;
446 BrowserColumn
*pNextCol
= (*pCols
)[ nNextPos
];
447 Rectangle
aNextRect(GetFieldRect( pNextCol
->GetId() ));
449 // move column internally
451 BrowserColumns::iterator it
= pCols
->begin();
452 ::std::advance( it
, nOldPos
);
453 BrowserColumn
* pTemp
= *it
;
456 ::std::advance( it
, nPos
);
457 pCols
->insert( it
, pTemp
);
460 // determine new column area
461 Rectangle
aToRect( GetFieldRect( nColumnId
) );
462 aToRect
.Right() += 2*MIN_COLUMNWIDTH
;
464 // do scroll, let redraw
465 if( pDataWin
->GetBackground().IsScrollable() )
467 long nScroll
= -aFromRect
.GetWidth();
468 Rectangle aScrollArea
;
469 if ( nOldPos
> nPos
)
471 long nFrozenWidth
= GetFrozenWidth();
472 if ( aToRect
.Left() < nFrozenWidth
)
473 aToRect
.Left() = nFrozenWidth
;
474 aScrollArea
= Rectangle(Point(aToRect
.Left(),0),
475 Point(aNextRect
.Right(),aDataWinSize
.Height()));
476 nScroll
*= -1; // reverse direction
479 aScrollArea
= Rectangle(Point(aNextRect
.Left(),0),
480 Point(aToRect
.Right(),aDataWinSize
.Height()));
482 pDataWin
->Scroll( nScroll
, 0, aScrollArea
);
484 aToRect
.Bottom() = aScrollArea
.Bottom();
485 Invalidate( aToRect
);
488 pDataWin
->Window::Invalidate( INVALIDATE_NOCHILDREN
);
490 // adjust header bar positions
491 if ( getDataWindow()->pHeaderBar
)
493 sal_uInt16 nNewPos
= nPos
;
494 if ( GetColumnId(0) == HandleColumnId
)
496 getDataWindow()->pHeaderBar
->MoveItem(nColumnId
,nNewPos
);
498 // remember the column selection
499 SetToggledSelectedColumn(nSelectedColId
);
501 if ( isAccessibleAlive() )
505 makeAny( AccessibleTableModelChange(
518 makeAny( AccessibleTableModelChange(
533 //-------------------------------------------------------------------
535 void BrowseBox::SetColumnTitle( sal_uInt16 nItemId
, const String
& rTitle
)
537 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
539 // never set title of the handle-column
540 if ( nItemId
== HandleColumnId
)
543 // get the position in the current array
544 sal_uInt16 nItemPos
= GetColumnPos( nItemId
);
545 if ( nItemPos
>= pCols
->size() )
549 // does the state change?
550 BrowserColumn
*pCol
= (*pCols
)[ nItemPos
];
551 if ( pCol
->Title() != rTitle
)
553 OUString
sNew(rTitle
);
554 OUString
sOld(pCol
->Title());
556 pCol
->Title() = rTitle
;
558 // adjust headerbar column
559 if ( getDataWindow()->pHeaderBar
)
560 getDataWindow()->pHeaderBar
->SetItemText( nItemId
, rTitle
);
563 // redraw visible columns
564 if ( GetUpdateMode() && ( pCol
->IsFrozen() || nItemPos
> nFirstCol
) )
565 Invalidate( Rectangle( Point(0,0),
566 Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
569 if ( isAccessibleAlive() )
571 commitTableEvent( TABLE_COLUMN_DESCRIPTION_CHANGED
,
579 //-------------------------------------------------------------------
581 void BrowseBox::SetColumnWidth( sal_uInt16 nItemId
, sal_uLong nWidth
)
583 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
585 // get the position in the current array
586 size_t nItemPos
= GetColumnPos( nItemId
);
587 if ( nItemPos
>= pCols
->size() )
590 // does the state change?
591 nWidth
= QueryColumnResize( nItemId
, nWidth
);
592 if ( nWidth
>= LONG_MAX
|| (*pCols
)[ nItemPos
]->Width() != nWidth
)
594 long nOldWidth
= (*pCols
)[ nItemPos
]->Width();
596 // adjust last column, if necessary
597 if ( IsVisible() && nItemPos
== pCols
->size() - 1 )
599 long nMaxWidth
= pDataWin
->GetSizePixel().Width();
600 nMaxWidth
-= getDataWindow()->bAutoSizeLastCol
601 ? GetFieldRect(nItemId
).Left()
603 if ( ( (BrowserDataWin
*)pDataWin
)->bAutoSizeLastCol
|| nWidth
> (sal_uLong
)nMaxWidth
)
605 nWidth
= nMaxWidth
> 16 ? nMaxWidth
: nOldWidth
;
606 nWidth
= QueryColumnResize( nItemId
, nWidth
);
611 // In AutoSizeLastColumn(), we call SetColumnWidth with nWidth==0xffff.
612 // Thus, check here, if the width has actually changed.
613 if( (sal_uLong
)nOldWidth
== nWidth
)
616 // do we want to display the change immediately?
617 sal_Bool bUpdate
= GetUpdateMode() &&
618 ( (*pCols
)[ nItemPos
]->IsFrozen() || nItemPos
>= nFirstCol
);
623 DoHideCursor( "SetColumnWidth" );
625 //!getDataWindow()->Update();
626 //!Control::Update();
630 (*pCols
)[ nItemPos
]->SetWidth(nWidth
, GetZoom());
632 // scroll and invalidate
635 // get X-Pos of the column changed
637 for ( sal_uInt16 nCol
= 0; nCol
< nItemPos
; ++nCol
)
639 BrowserColumn
*pCol
= (*pCols
)[ nCol
];
640 if ( pCol
->IsFrozen() || nCol
>= nFirstCol
)
644 // actually scroll+invalidate
645 pDataWin
->SetClipRegion();
646 sal_Bool bSelVis
= bSelectionIsVisible
;
647 bSelectionIsVisible
= sal_False
;
648 if( GetBackground().IsScrollable() )
651 Rectangle
aScrRect( nX
+ std::min( (sal_uLong
)nOldWidth
, nWidth
), 0,
652 GetSizePixel().Width() , // the header is longer than the datawin
653 pDataWin
->GetPosPixel().Y() - 1 );
654 Control::Scroll( nWidth
-nOldWidth
, 0, aScrRect
, SCROLL_FLAGS
);
655 aScrRect
.Bottom() = pDataWin
->GetSizePixel().Height();
656 getDataWindow()->Scroll( nWidth
-nOldWidth
, 0, aScrRect
, SCROLL_FLAGS
);
657 Rectangle
aInvRect( nX
, 0, nX
+ std::max( nWidth
, (sal_uLong
)nOldWidth
), USHRT_MAX
);
658 Control::Invalidate( aInvRect
, INVALIDATE_NOCHILDREN
);
659 ( (BrowserDataWin
*)pDataWin
)->Invalidate( aInvRect
);
663 Control::Invalidate( INVALIDATE_NOCHILDREN
);
664 getDataWindow()->Window::Invalidate( INVALIDATE_NOCHILDREN
);
668 //!getDataWindow()->Update();
669 //!Control::Update();
670 bSelectionIsVisible
= bSelVis
;
672 DoShowCursor( "SetColumnWidth" );
676 // adjust headerbar column
677 if ( getDataWindow()->pHeaderBar
)
678 getDataWindow()->pHeaderBar
->SetItemSize(
679 nItemId
? nItemId
: USHRT_MAX
- 1, nWidth
);
681 // adjust last column
682 if ( nItemPos
!= pCols
->size() - 1 )
683 AutoSizeLastColumn();
688 //-------------------------------------------------------------------
690 void BrowseBox::AutoSizeLastColumn()
692 if ( getDataWindow()->bAutoSizeLastCol
&&
693 getDataWindow()->GetUpdateMode() )
695 sal_uInt16 nId
= GetColumnId( (sal_uInt16
)pCols
->size() - 1 );
696 SetColumnWidth( nId
, LONG_MAX
);
697 ColumnResized( nId
);
701 //-------------------------------------------------------------------
703 void BrowseBox::RemoveColumn( sal_uInt16 nItemId
)
705 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
707 // get column position
708 sal_uInt16 nPos
= GetColumnPos(nItemId
);
709 if ( nPos
>= ColCount() )
713 // correct column selection
715 pColSel
->Remove( nPos
);
717 // correct column cursor
718 if ( nCurColId
== nItemId
)
722 BrowserColumns::iterator it
= pCols
->begin();
723 ::std::advance( it
, nPos
);
726 if ( nFirstCol
>= nPos
&& nFirstCol
> FrozenColCount() )
728 OSL_ENSURE(nFirstCol
> 0,"FirstCol must be greater zero!");
732 // handlecolumn not in headerbar
735 if ( getDataWindow()->pHeaderBar
)
736 getDataWindow()->pHeaderBar
->RemoveItem( nItemId
);
741 if ( getDataWindow()->pHeaderBar
)
743 getDataWindow()->pHeaderBar
->SetPosSizePixel(
745 Size( GetOutputSizePixel().Width(), GetTitleHeight() )
750 // correct vertical scrollbar
753 // trigger repaint, if necessary
754 if ( GetUpdateMode() )
756 getDataWindow()->Invalidate();
757 Control::Invalidate();
758 if ( getDataWindow()->bAutoSizeLastCol
&& nPos
==ColCount() )
759 SetColumnWidth( GetColumnId( nPos
- 1 ), LONG_MAX
);
762 if ( isAccessibleAlive() )
766 makeAny( AccessibleTableModelChange( DELETE
,
776 commitHeaderBarEvent(
779 makeAny( CreateAccessibleColumnHeader( nPos
) ),
785 //-------------------------------------------------------------------
787 void BrowseBox::RemoveColumns()
789 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
791 size_t nOldCount
= pCols
->size();
793 // remove all columns
794 for ( size_t i
= 0; i
< nOldCount
; ++i
)
795 delete (*pCols
)[ i
];
798 // correct column selection
801 pColSel
->SelectAll(sal_False
);
802 pColSel
->SetTotalRange( Range( 0, 0 ) );
805 // correct column cursor
809 if ( getDataWindow()->pHeaderBar
)
810 getDataWindow()->pHeaderBar
->Clear( );
812 // correct vertical scrollbar
815 // trigger repaint if necessary
816 if ( GetUpdateMode() )
818 getDataWindow()->Invalidate();
819 Control::Invalidate();
822 if ( isAccessibleAlive() )
824 if ( pCols
->size() != nOldCount
)
826 // all columns should be removed, so we remove the column header bar and append it again
827 // to avoid to notify every column remove
828 commitBrowseBoxEvent(
831 makeAny(m_pImpl
->getAccessibleHeaderBar(BBTYPE_COLUMNHEADERBAR
))
834 // and now append it again
835 commitBrowseBoxEvent(
837 makeAny(m_pImpl
->getAccessibleHeaderBar(BBTYPE_COLUMNHEADERBAR
)),
841 // notify a table model change
844 makeAny ( AccessibleTableModelChange( DELETE
,
857 //-------------------------------------------------------------------
859 String
BrowseBox::GetColumnTitle( sal_uInt16 nId
) const
861 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
863 sal_uInt16 nItemPos
= GetColumnPos( nId
);
864 if ( nItemPos
>= pCols
->size() )
866 return (*pCols
)[ nItemPos
]->Title();
869 //-------------------------------------------------------------------
871 long BrowseBox::GetRowCount() const
876 //-------------------------------------------------------------------
878 sal_uInt16
BrowseBox::ColCount() const
880 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
882 return (sal_uInt16
) pCols
->size();
885 //-------------------------------------------------------------------
887 long BrowseBox::ImpGetDataRowHeight() const
889 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
891 BrowseBox
*pThis
= (BrowseBox
*)this;
892 pThis
->nDataRowHeight
= pThis
->CalcReverseZoom(pDataWin
->GetTextHeight() + 2);
894 getDataWindow()->Invalidate();
895 return nDataRowHeight
;
898 //-------------------------------------------------------------------
900 void BrowseBox::SetDataRowHeight( long nPixel
)
902 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
904 nDataRowHeight
= CalcReverseZoom(nPixel
);
906 getDataWindow()->Invalidate();
909 //-------------------------------------------------------------------
911 void BrowseBox::SetTitleLines( sal_uInt16 nLines
)
913 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
915 nTitleLines
= nLines
;
918 //-------------------------------------------------------------------
920 long BrowseBox::ScrollColumns( long nCols
)
922 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
924 if ( nFirstCol
+ nCols
< 0 ||
925 nFirstCol
+ nCols
>= (long)pCols
->size() )
928 // implicitly hides cursor while scrolling
930 bScrolling
= sal_True
;
931 sal_Bool bScrollable
= pDataWin
->GetBackground().IsScrollable();
932 sal_Bool bInvalidateView
= sal_False
;
934 // scrolling one column to the right?
937 // update internal value and scrollbar
939 aHScroll
.SetThumbPos( nFirstCol
- FrozenColCount() );
943 bInvalidateView
= sal_True
;
947 long nDelta
= (*pCols
)[ nFirstCol
-1 ]->Width();
948 long nFrozenWidth
= GetFrozenWidth();
950 Rectangle
aScrollRect( Point( nFrozenWidth
+ nDelta
, 0 ),
951 Size ( GetOutputSizePixel().Width() - nFrozenWidth
- nDelta
,
955 // scroll the header bar area (if there is no dedicated HeaderBar control)
956 if ( !getDataWindow()->pHeaderBar
&& nTitleLines
)
959 Scroll( -nDelta
, 0, aScrollRect
, SCROLL_FLAGS
);
961 // invalidate the area of the column which was scrolled out to the left hand side
962 Rectangle
aInvalidateRect( aScrollRect
);
963 aInvalidateRect
.Left() = nFrozenWidth
;
964 aInvalidateRect
.Right() = nFrozenWidth
+ nDelta
- 1;
965 Invalidate( aInvalidateRect
);
968 // scroll the data-area
969 aScrollRect
.Bottom() = pDataWin
->GetOutputSizePixel().Height();
972 pDataWin
->Scroll( -nDelta
, 0, aScrollRect
, SCROLL_FLAGS
);
974 // invalidate the area of the column which was scrolled out to the left hand side
975 aScrollRect
.Left() = nFrozenWidth
;
976 aScrollRect
.Right() = nFrozenWidth
+ nDelta
- 1;
977 getDataWindow()->Invalidate( aScrollRect
);
981 // scrolling one column to the left?
982 else if ( nCols
== -1 )
985 aHScroll
.SetThumbPos( nFirstCol
- FrozenColCount() );
989 bInvalidateView
= sal_True
;
993 long nDelta
= (*pCols
)[ nFirstCol
]->Width();
994 long nFrozenWidth
= GetFrozenWidth();
996 Rectangle
aScrollRect( Point( nFrozenWidth
, 0 ),
997 Size ( GetOutputSizePixel().Width() - nFrozenWidth
,
1001 // scroll the header bar area (if there is no dedicated HeaderBar control)
1002 if ( !getDataWindow()->pHeaderBar
&& nTitleLines
)
1004 Scroll( nDelta
, 0, aScrollRect
, SCROLL_FLAGS
);
1007 // scroll the data-area
1008 aScrollRect
.Bottom() = pDataWin
->GetOutputSizePixel().Height();
1009 pDataWin
->Scroll( nDelta
, 0, aScrollRect
, SCROLL_FLAGS
);
1014 if ( GetUpdateMode() )
1016 Invalidate( Rectangle(
1017 Point( GetFrozenWidth(), 0 ),
1018 Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
1019 getDataWindow()->Invalidate( Rectangle(
1020 Point( GetFrozenWidth(), 0 ),
1021 pDataWin
->GetSizePixel() ) );
1024 nFirstCol
= nFirstCol
+ (sal_uInt16
)nCols
;
1025 aHScroll
.SetThumbPos( nFirstCol
- FrozenColCount() );
1028 // adjust external headerbar, if necessary
1029 if ( getDataWindow()->pHeaderBar
)
1032 for ( size_t nCol
= 0;
1033 nCol
< pCols
->size() && nCol
< nFirstCol
;
1036 // not the handle column
1037 if ( (*pCols
)[ nCol
]->GetId() )
1038 nWidth
+= (*pCols
)[ nCol
]->Width();
1041 getDataWindow()->pHeaderBar
->SetOffset( nWidth
);
1044 if( bInvalidateView
)
1046 Control::Invalidate( INVALIDATE_NOCHILDREN
);
1047 pDataWin
->Window::Invalidate( INVALIDATE_NOCHILDREN
);
1050 // implicitly show cursor after scrolling
1053 getDataWindow()->Update();
1056 bScrolling
= sal_False
;
1062 //-------------------------------------------------------------------
1064 long BrowseBox::ScrollRows( long nRows
)
1066 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1069 if ( getDataWindow()->bNoScrollBack
&& nRows
< 0 )
1072 // compute new top row
1073 long nTmpMin
= std::min( (long)(nTopRow
+ nRows
), (long)(nRowCount
- 1) );
1075 long nNewTopRow
= std::max( (long)nTmpMin
, (long)0 );
1077 if ( nNewTopRow
== nTopRow
)
1080 sal_uInt16 nVisibleRows
=
1081 (sal_uInt16
)(pDataWin
->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
1083 VisibleRowsChanged(nNewTopRow
, nVisibleRows
);
1085 // compute new top row again (nTopRow might have changed!)
1086 nTmpMin
= std::min( (long)(nTopRow
+ nRows
), (long)(nRowCount
- 1) );
1088 nNewTopRow
= std::max( (long)nTmpMin
, (long)0 );
1092 // scroll area on screen and/or repaint
1093 long nDeltaY
= GetDataRowHeight() * ( nNewTopRow
- nTopRow
);
1094 long nOldTopRow
= nTopRow
;
1095 nTopRow
= nNewTopRow
;
1097 if ( GetUpdateMode() )
1099 pVScroll
->SetRange( Range( 0L, nRowCount
) );
1100 pVScroll
->SetThumbPos( nTopRow
);
1102 if( pDataWin
->GetBackground().IsScrollable() &&
1103 std::abs( nDeltaY
) > 0 &&
1104 std::abs( nDeltaY
) < pDataWin
->GetSizePixel().Height() )
1106 pDataWin
->Scroll( 0, (short)-nDeltaY
, SCROLL_FLAGS
);
1109 getDataWindow()->Invalidate();
1111 if ( nTopRow
- nOldTopRow
)
1112 getDataWindow()->Update();
1117 return nTopRow
- nOldTopRow
;
1120 //-------------------------------------------------------------------
1122 void BrowseBox::RowModified( long nRow
, sal_uInt16 nColId
)
1124 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1126 if ( !GetUpdateMode() )
1130 if ( nColId
== BROWSER_INVALIDID
)
1131 // invalidate the whole row
1132 aRect
= Rectangle( Point( 0, (nRow
-nTopRow
) * GetDataRowHeight() ),
1133 Size( pDataWin
->GetSizePixel().Width(), GetDataRowHeight() ) );
1136 // invalidate the specific field
1137 aRect
= GetFieldRectPixel( nRow
, nColId
, sal_False
);
1139 getDataWindow()->Invalidate( aRect
);
1142 //-------------------------------------------------------------------
1144 void BrowseBox::Clear()
1146 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1148 // adjust the total number of rows
1149 DoHideCursor( "Clear" );
1150 long nOldRowCount
= nRowCount
;
1155 *uRow
.pSel
= MultiSelection();
1158 uRow
.nSel
= BROWSER_ENDOFSELECTION
;
1159 nCurRow
= BROWSER_ENDOFSELECTION
;
1163 // nFirstCol may not be reset, else the scrolling code will become confused.
1164 // nFirstCol may only be changed when adding or deleting columns
1165 // nFirstCol = 0; -> wrong!
1166 aHScroll
.SetThumbPos( 0 );
1167 pVScroll
->SetThumbPos( 0 );
1172 DoShowCursor( "Clear" );
1175 if ( isAccessibleAlive() )
1177 // all rows should be removed, so we remove the row header bar and append it again
1178 // to avoid to notify every row remove
1179 if ( nOldRowCount
!= nRowCount
)
1181 commitBrowseBoxEvent(
1184 makeAny( m_pImpl
->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR
) )
1187 // and now append it again
1188 commitBrowseBoxEvent(
1190 makeAny( m_pImpl
->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR
) ),
1194 // notify a table model change
1196 TABLE_MODEL_CHANGED
,
1197 makeAny( AccessibleTableModelChange( DELETE
,
1208 // -----------------------------------------------------------------------------
1209 void BrowseBox::RowInserted( long nRow
, long nNumRows
, sal_Bool bDoPaint
, sal_Bool bKeepSelection
)
1211 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1215 else if (nRow
> nRowCount
) // maximal = nRowCount
1218 if ( nNumRows
<= 0 )
1221 // adjust total row count
1222 sal_Bool bLastRow
= nRow
>= nRowCount
;
1223 nRowCount
+= nNumRows
;
1225 DoHideCursor( "RowInserted" );
1227 // must we paint the new rows?
1228 long nOldCurRow
= nCurRow
;
1229 Size aSz
= pDataWin
->GetOutputSizePixel();
1230 if ( bDoPaint
&& nRow
>= nTopRow
&&
1231 nRow
<= nTopRow
+ aSz
.Height() / GetDataRowHeight() )
1233 long nY
= (nRow
-nTopRow
) * GetDataRowHeight();
1236 // scroll down the rows behind the new row
1237 pDataWin
->SetClipRegion();
1238 if( pDataWin
->GetBackground().IsScrollable() )
1240 pDataWin
->Scroll( 0, GetDataRowHeight() * nNumRows
,
1241 Rectangle( Point( 0, nY
),
1242 Size( aSz
.Width(), aSz
.Height() - nY
) ),
1246 pDataWin
->Window::Invalidate( INVALIDATE_NOCHILDREN
);
1249 // scroll would cause a repaint, so we must explicitly invalidate
1250 pDataWin
->Invalidate( Rectangle( Point( 0, nY
),
1251 Size( aSz
.Width(), nNumRows
* GetDataRowHeight() ) ) );
1254 // correct top row if necessary
1255 if ( nRow
< nTopRow
)
1256 nTopRow
+= nNumRows
;
1258 // adjust the selection
1259 if ( bMultiSelection
)
1260 uRow
.pSel
->Insert( nRow
, nNumRows
);
1261 else if ( uRow
.nSel
!= BROWSER_ENDOFSELECTION
&& nRow
<= uRow
.nSel
)
1262 uRow
.nSel
+= nNumRows
;
1264 // adjust the cursor
1265 if ( nCurRow
== BROWSER_ENDOFSELECTION
)
1266 GoToRow( 0, sal_False
, bKeepSelection
);
1267 else if ( nRow
<= nCurRow
)
1268 GoToRow( nCurRow
+= nNumRows
, sal_False
, bKeepSelection
);
1270 // adjust the vertical scrollbar
1274 AutoSizeLastColumn();
1277 DoShowCursor( "RowInserted" );
1278 // notify accessible that rows were inserted
1279 if ( isAccessibleAlive() )
1282 TABLE_MODEL_CHANGED
,
1283 makeAny( AccessibleTableModelChange(
1294 for (sal_Int32 i
= nRow
+1 ; i
<= nRowCount
; ++i
)
1296 commitHeaderBarEvent(
1298 makeAny( CreateAccessibleRowHeader( i
) ),
1305 if ( nCurRow
!= nOldCurRow
)
1308 DBG_ASSERT(nRowCount
> 0,"BrowseBox: nRowCount <= 0");
1309 DBG_ASSERT(nCurRow
>= 0,"BrowseBox: nCurRow < 0");
1310 DBG_ASSERT(nCurRow
< nRowCount
,"nCurRow >= nRowCount");
1313 //-------------------------------------------------------------------
1315 void BrowseBox::RowRemoved( long nRow
, long nNumRows
, sal_Bool bDoPaint
)
1317 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1321 else if ( nRow
>= nRowCount
)
1322 nRow
= nRowCount
- 1;
1324 if ( nNumRows
<= 0 )
1327 if ( nRowCount
<= 0 )
1332 // hide cursor and selection
1333 OSL_TRACE( "BrowseBox: %p->HideCursor", this );
1335 DoHideCursor( "RowRemoved" );
1338 // adjust total row count
1339 nRowCount
-= nNumRows
;
1340 if (nRowCount
< 0) nRowCount
= 0;
1341 long nOldCurRow
= nCurRow
;
1343 // adjust the selection
1344 if ( bMultiSelection
)
1345 // uRow.pSel->Remove( nRow, nNumRows );
1346 for ( long i
= 0; i
< nNumRows
; i
++ )
1347 uRow
.pSel
->Remove( nRow
);
1348 else if ( nRow
< uRow
.nSel
&& uRow
.nSel
>= nNumRows
)
1349 uRow
.nSel
-= nNumRows
;
1350 else if ( nRow
<= uRow
.nSel
)
1351 uRow
.nSel
= BROWSER_ENDOFSELECTION
;
1353 // adjust the cursor
1354 if ( nRowCount
== 0 ) // don't compare nRowCount with nNumRows as nNumRows already was subtracted from nRowCount
1355 nCurRow
= BROWSER_ENDOFSELECTION
;
1356 else if ( nRow
< nCurRow
)
1358 nCurRow
-= std::min( nCurRow
- nRow
, nNumRows
);
1359 // with the above nCurRow points a) to the first row after the removed block or b) to the same line
1360 // as before, but moved up nNumRows
1361 // case a) needs an additional correction if the last n lines were deleted, as 'the first row after the
1362 // removed block' is an invalid position then
1363 // FS - 09/28/99 - 68429
1364 if (nCurRow
== nRowCount
)
1367 else if( nRow
== nCurRow
&& nCurRow
== nRowCount
)
1368 nCurRow
= nRowCount
-1;
1370 // is the deleted row visible?
1371 Size aSz
= pDataWin
->GetOutputSizePixel();
1372 if ( nRow
>= nTopRow
&&
1373 nRow
<= nTopRow
+ aSz
.Height() / GetDataRowHeight() )
1377 // scroll up the rows behind the deleted row
1378 // if there are Rows behind
1379 if (nRow
< nRowCount
)
1381 long nY
= (nRow
-nTopRow
) * GetDataRowHeight();
1382 pDataWin
->SetClipRegion();
1383 if( pDataWin
->GetBackground().IsScrollable() )
1385 pDataWin
->Scroll( 0, - (short) GetDataRowHeight() * nNumRows
,
1386 Rectangle( Point( 0, nY
), Size( aSz
.Width(),
1387 aSz
.Height() - nY
+ nNumRows
*GetDataRowHeight() ) ),
1391 pDataWin
->Window::Invalidate( INVALIDATE_NOCHILDREN
);
1395 // Repaint the Rect of the deleted row
1397 Point( 0, (nRow
-nTopRow
)*GetDataRowHeight() ),
1398 Size( pDataWin
->GetSizePixel().Width(),
1399 nNumRows
* GetDataRowHeight() ) );
1400 pDataWin
->Invalidate( aRect
);
1404 // is the deleted row above of the visible area?
1405 else if ( nRow
< nTopRow
)
1406 nTopRow
= nTopRow
>= nNumRows
? nTopRow
-nNumRows
: 0;
1410 // reshow cursor and selection
1412 OSL_TRACE( "BrowseBox: %p->ShowCursor", this );
1413 DoShowCursor( "RowRemoved" );
1415 // adjust the vertical scrollbar
1417 AutoSizeLastColumn();
1420 if ( isAccessibleAlive() )
1422 if ( nRowCount
== 0 )
1424 // all columns should be removed, so we remove the column header bar and append it again
1425 // to avoid to notify every column remove
1426 commitBrowseBoxEvent(
1429 makeAny( m_pImpl
->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR
) )
1432 // and now append it again
1433 commitBrowseBoxEvent(
1435 makeAny(m_pImpl
->getAccessibleHeaderBar(BBTYPE_ROWHEADERBAR
)),
1438 commitBrowseBoxEvent(
1441 makeAny( m_pImpl
->getAccessibleTable() )
1444 // and now append it again
1445 commitBrowseBoxEvent(
1447 makeAny( m_pImpl
->getAccessibleTable() ),
1454 TABLE_MODEL_CHANGED
,
1455 makeAny( AccessibleTableModelChange(
1466 for (sal_Int32 i
= nRow
+1 ; i
<= (nRow
+nNumRows
) ; ++i
)
1468 commitHeaderBarEvent(
1471 makeAny( CreateAccessibleRowHeader( i
) ),
1478 if ( nOldCurRow
!= nCurRow
)
1481 DBG_ASSERT(nRowCount
>= 0,"BrowseBox: nRowCount < 0");
1482 DBG_ASSERT(nCurRow
>= 0 || nRowCount
== 0,"BrowseBox: nCurRow < 0 && nRowCount != 0");
1483 DBG_ASSERT(nCurRow
< nRowCount
,"nCurRow >= nRowCount");
1486 //-------------------------------------------------------------------
1488 sal_Bool
BrowseBox::GoToRow( long nRow
)
1490 return GoToRow(nRow
, sal_False
, sal_False
);
1493 //-------------------------------------------------------------------
1495 sal_Bool
BrowseBox::GoToRow( long nRow
, sal_Bool bRowColMove
, sal_Bool bKeepSelection
)
1497 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1499 long nOldCurRow
= nCurRow
;
1502 if ( nRow
== nCurRow
&& ( bMultiSelection
|| uRow
.nSel
== nRow
) )
1506 if ( nRow
< 0 || nRow
>= nRowCount
)
1510 if ( ( !bRowColMove
&& !IsCursorMoveAllowed( nRow
, nCurColId
) ) )
1513 if ( getDataWindow()->bNoScrollBack
&& nRow
< nTopRow
)
1516 // compute the last visible row
1517 Size
aSz( pDataWin
->GetSizePixel() );
1518 sal_uInt16 nVisibleRows
= sal_uInt16( aSz
.Height() / GetDataRowHeight() - 1 );
1519 long nLastRow
= nTopRow
+ nVisibleRows
;
1522 getDataWindow()->EnterUpdateLock();
1524 // remove old highlight, if necessary
1525 if ( !bMultiSelection
&& !bKeepSelection
)
1527 DoHideCursor( "GoToRow" );
1530 sal_Bool bWasVisible
= bSelectionIsVisible
;
1531 if (! bMultiSelection
)
1533 if( !bKeepSelection
)
1534 bSelectionIsVisible
= sal_False
;
1536 if ( nRow
< nTopRow
)
1537 ScrollRows( nRow
- nTopRow
);
1538 else if ( nRow
> nLastRow
)
1539 ScrollRows( nRow
- nLastRow
);
1540 bSelectionIsVisible
= bWasVisible
;
1542 // adjust cursor (selection) and thumb
1543 if ( GetUpdateMode() )
1544 pVScroll
->SetThumbPos( nTopRow
);
1546 // relative positioning (because nCurRow might have changed in the meantime)!
1547 if (nCurRow
!= BROWSER_ENDOFSELECTION
)
1548 nCurRow
= nCurRow
+ (nRow
- nOldCurRow
);
1550 // make sure that the current position is valid
1551 if (nCurRow
== BROWSER_ENDOFSELECTION
&& nRowCount
> 0)
1553 else if ( nCurRow
>= nRowCount
)
1554 nCurRow
= nRowCount
- 1;
1555 aSelRange
= Range( nCurRow
, nCurRow
);
1557 // display new highlight if necessary
1558 if ( !bMultiSelection
&& !bKeepSelection
)
1562 getDataWindow()->LeaveUpdateLock();
1565 if ( !bMultiSelection
&& !bKeepSelection
)
1567 DoShowCursor( "GoToRow" );
1568 if ( !bRowColMove
&& nOldCurRow
!= nCurRow
)
1571 if ( !bMultiSelection
&& !bKeepSelection
)
1581 //-------------------------------------------------------------------
1583 sal_Bool
BrowseBox::GoToColumnId( sal_uInt16 nColId
)
1585 return GoToColumnId(nColId
,sal_True
,sal_False
);
1589 sal_Bool
BrowseBox::GoToColumnId( sal_uInt16 nColId
, sal_Bool bMakeVisible
, sal_Bool bRowColMove
)
1591 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1597 if (!bRowColMove
&& !IsCursorMoveAllowed( nCurRow
, nColId
) )
1600 if ( nColId
!= nCurColId
|| (bMakeVisible
&& !IsFieldVisible(nCurRow
, nColId
, sal_True
)))
1602 sal_uInt16 nNewPos
= GetColumnPos(nColId
);
1603 BrowserColumn
* pColumn
= (nNewPos
< pCols
->size()) ? (*pCols
)[ nNewPos
] : NULL
;
1604 DBG_ASSERT( pColumn
, "no column object - invalid id?" );
1608 DoHideCursor( "GoToColumnId" );
1611 sal_uInt16 nFirstPos
= nFirstCol
;
1612 sal_uInt16 nWidth
= (sal_uInt16
)pColumn
->Width();
1613 sal_uInt16 nLastPos
= GetColumnAtXPosPixel(
1614 pDataWin
->GetSizePixel().Width()-nWidth
, sal_False
);
1615 sal_uInt16 nFrozen
= FrozenColCount();
1616 if ( bMakeVisible
&& nLastPos
&&
1617 nNewPos
>= nFrozen
&& ( nNewPos
< nFirstPos
|| nNewPos
> nLastPos
) )
1619 if ( nNewPos
< nFirstPos
)
1620 ScrollColumns( nNewPos
-nFirstPos
);
1621 else if ( nNewPos
> nLastPos
)
1622 ScrollColumns( nNewPos
-nLastPos
);
1625 DoShowCursor( "GoToColumnId" );
1633 //-------------------------------------------------------------------
1635 sal_Bool
BrowseBox::GoToRowColumnId( long nRow
, sal_uInt16 nColId
)
1637 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1640 if ( nRow
< 0 || nRow
>= nRowCount
)
1647 if ( nRow
== nCurRow
&& ( bMultiSelection
|| uRow
.nSel
== nRow
) &&
1648 nColId
== nCurColId
&& IsFieldVisible(nCurRow
, nColId
, sal_True
))
1652 if (!IsCursorMoveAllowed(nRow
, nColId
))
1655 DoHideCursor( "GoToRowColumnId" );
1656 sal_Bool bMoved
= GoToRow(nRow
, sal_True
) && GoToColumnId(nColId
, sal_True
, sal_True
);
1657 DoShowCursor( "GoToRowColumnId" );
1665 //-------------------------------------------------------------------
1667 void BrowseBox::SetNoSelection()
1669 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1671 // is there no selection
1672 if ( ( !pColSel
|| !pColSel
->GetSelectCount() ) &&
1673 ( ( !bMultiSelection
&& uRow
.nSel
== BROWSER_ENDOFSELECTION
) ||
1674 ( bMultiSelection
&& !uRow
.pSel
->GetSelectCount() ) ) )
1678 OSL_TRACE( "BrowseBox: %p->HideCursor", this );
1682 if ( bMultiSelection
)
1683 uRow
.pSel
->SelectAll(sal_False
);
1685 uRow
.nSel
= BROWSER_ENDOFSELECTION
;
1687 pColSel
->SelectAll(sal_False
);
1694 OSL_TRACE( "BrowseBox: %p->ShowCursor", this );
1696 if ( isAccessibleAlive() )
1706 //-------------------------------------------------------------------
1708 void BrowseBox::SelectAll()
1710 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1712 if ( !bMultiSelection
)
1715 OSL_TRACE( "BrowseBox: %p->HideCursor", this );
1720 pColSel
->SelectAll(sal_False
);
1721 uRow
.pSel
->SelectAll(sal_True
);
1723 // don't highlight handle column
1724 BrowserColumn
*pFirstCol
= (*pCols
)[ 0 ];
1725 long nOfsX
= pFirstCol
->GetId() ? 0 : pFirstCol
->Width();
1727 // highlight the row selection
1730 Rectangle aHighlightRect
;
1731 sal_uInt16 nVisibleRows
=
1732 (sal_uInt16
)(pDataWin
->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
1733 for ( long nRow
= std::max( nTopRow
, uRow
.pSel
->FirstSelected() );
1734 nRow
!= BROWSER_ENDOFSELECTION
&& nRow
< nTopRow
+ nVisibleRows
;
1735 nRow
= uRow
.pSel
->NextSelected() )
1736 aHighlightRect
.Union( Rectangle(
1737 Point( nOfsX
, (nRow
-nTopRow
)*GetDataRowHeight() ),
1738 Size( pDataWin
->GetSizePixel().Width(), GetDataRowHeight() ) ) );
1739 pDataWin
->Invalidate( aHighlightRect
);
1748 OSL_TRACE( "BrowseBox: %p->ShowCursor", this );
1750 if ( isAccessibleAlive() )
1757 commitHeaderBarEvent(
1762 ); // column header event
1764 commitHeaderBarEvent(
1769 ); // row header event
1773 //-------------------------------------------------------------------
1775 void BrowseBox::SelectRow( long nRow
, sal_Bool _bSelect
, sal_Bool bExpand
)
1777 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1779 if ( !bMultiSelection
)
1781 // deselecting is impossible, selecting via cursor
1783 GoToRow(nRow
, sal_False
);
1787 OSL_TRACE( "BrowseBox: %p->HideCursor", this );
1789 // remove old selection?
1790 if ( !bExpand
|| !bMultiSelection
)
1793 if ( bMultiSelection
)
1794 uRow
.pSel
->SelectAll(sal_False
);
1796 uRow
.nSel
= BROWSER_ENDOFSELECTION
;
1798 pColSel
->SelectAll(sal_False
);
1801 // set new selection
1803 && ( ( bMultiSelection
1804 && uRow
.pSel
->GetTotalRange().Max() >= nRow
1805 && uRow
.pSel
->Select( nRow
, _bSelect
)
1807 || ( !bMultiSelection
1808 && ( uRow
.nSel
= nRow
) != BROWSER_ENDOFSELECTION
)
1812 // don't highlight handle column
1813 BrowserColumn
*pFirstCol
= (*pCols
)[ 0 ];
1814 long nOfsX
= pFirstCol
->GetId() ? 0 : pFirstCol
->Width();
1816 // highlight only newly selected part
1818 Point( nOfsX
, (nRow
-nTopRow
)*GetDataRowHeight() ),
1819 Size( pDataWin
->GetSizePixel().Width(), GetDataRowHeight() ) );
1820 pDataWin
->Invalidate( aRect
);
1829 OSL_TRACE( "BrowseBox: %p->ShowCursor", this );
1831 if ( isAccessibleAlive() )
1838 commitHeaderBarEvent(
1843 ); // row header event
1847 //-------------------------------------------------------------------
1849 long BrowseBox::GetSelectRowCount() const
1851 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1853 return bMultiSelection
? uRow
.pSel
->GetSelectCount() :
1854 uRow
.nSel
== BROWSER_ENDOFSELECTION
? 0 : 1;
1857 //-------------------------------------------------------------------
1859 void BrowseBox::SelectColumnPos( sal_uInt16 nNewColPos
, sal_Bool _bSelect
, sal_Bool bMakeVisible
)
1861 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1863 if ( !bColumnCursor
|| nNewColPos
== BROWSER_INVALIDID
)
1866 if ( !bMultiSelection
)
1869 GoToColumnId( (*pCols
)[ nNewColPos
]->GetId(), bMakeVisible
);
1874 if ( !GoToColumnId( (*pCols
)[ nNewColPos
]->GetId(), bMakeVisible
) )
1878 OSL_TRACE( "BrowseBox: %p->HideCursor", this );
1880 if ( bMultiSelection
)
1881 uRow
.pSel
->SelectAll(sal_False
);
1883 uRow
.nSel
= BROWSER_ENDOFSELECTION
;
1884 pColSel
->SelectAll(sal_False
);
1886 if ( pColSel
->Select( nNewColPos
, _bSelect
) )
1888 // GoToColumnId( pCols->GetObject(nNewColPos)->GetId(), bMakeVisible );
1890 // only highlight painted areas
1892 Rectangle
aFieldRectPix( GetFieldRectPixel( nCurRow
, nCurColId
, sal_False
) );
1894 Point( aFieldRectPix
.Left() - MIN_COLUMNWIDTH
, 0 ),
1895 Size( (*pCols
)[ nNewColPos
]->Width(),
1896 pDataWin
->GetOutputSizePixel().Height() ) );
1897 pDataWin
->Invalidate( aRect
);
1903 if ( isAccessibleAlive() )
1910 commitHeaderBarEvent(
1915 ); // column header event
1920 OSL_TRACE( "BrowseBox: %p->ShowCursor", this );
1923 //-------------------------------------------------------------------
1925 sal_uInt16
BrowseBox::GetSelectColumnCount() const
1927 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1929 // while bAutoSelect (==!pColSel), 1 if any rows (yes rows!) else none
1930 return pColSel
? (sal_uInt16
) pColSel
->GetSelectCount() :
1931 nCurRow
>= 0 ? 1 : 0;
1934 //-------------------------------------------------------------------
1935 long BrowseBox::FirstSelectedColumn( ) const
1937 return pColSel
? pColSel
->FirstSelected() : BROWSER_ENDOFSELECTION
;
1940 //-------------------------------------------------------------------
1942 long BrowseBox::FirstSelectedRow( sal_Bool bInverse
)
1944 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1946 return bMultiSelection
? uRow
.pSel
->FirstSelected(bInverse
) : uRow
.nSel
;
1949 //-------------------------------------------------------------------
1951 long BrowseBox::NextSelectedRow()
1953 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1955 return bMultiSelection
? uRow
.pSel
->NextSelected() : BROWSER_ENDOFSELECTION
;
1958 //-------------------------------------------------------------------
1960 long BrowseBox::LastSelectedRow()
1962 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1964 return bMultiSelection
? uRow
.pSel
->LastSelected() : uRow
.nSel
;
1967 //-------------------------------------------------------------------
1969 bool BrowseBox::IsRowSelected( long nRow
) const
1971 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1973 return bMultiSelection
? uRow
.pSel
->IsSelected(nRow
) : nRow
== uRow
.nSel
;
1976 //-------------------------------------------------------------------
1978 bool BrowseBox::IsColumnSelected( sal_uInt16 nColumnId
) const
1980 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
1982 return pColSel
? pColSel
->IsSelected( GetColumnPos(nColumnId
) ) :
1983 nCurColId
== nColumnId
;
1986 //-------------------------------------------------------------------
1988 sal_Bool
BrowseBox::MakeFieldVisible
1990 long nRow
, // line number of the field (starting with 0)
1991 sal_uInt16 nColId
, // column ID of the field
1992 sal_Bool bComplete
// (== sal_False), sal_True => make visible in its entirety
1997 Makes visible the field described in 'nRow' and 'nColId' by scrolling
1998 accordingly. If 'bComplete' is set, the field should become visible in its
2004 The given field is already visible or was already visible.
2007 The given field could not be made visible or in the case of
2008 'bComplete' could not be made visible in its entirety.
2012 Size aTestSize
= pDataWin
->GetSizePixel();
2014 if ( !bBootstrapped
||
2015 ( aTestSize
.Width() == 0 && aTestSize
.Height() == 0 ) )
2018 // is it visible already?
2019 sal_Bool bVisible
= IsFieldVisible( nRow
, nColId
, bComplete
);
2023 // calculate column position, field rectangle and painting area
2024 sal_uInt16 nColPos
= GetColumnPos( nColId
);
2025 Rectangle aFieldRect
= GetFieldRectPixel( nRow
, nColId
, sal_False
);
2026 Rectangle aDataRect
= Rectangle( Point(0, 0), pDataWin
->GetSizePixel() );
2028 // positioned outside on the left?
2029 if ( nColPos
>= FrozenColCount() && nColPos
< nFirstCol
)
2030 // => scroll to the right
2031 ScrollColumns( nColPos
- nFirstCol
);
2033 // while outside on the right
2034 while ( aDataRect
.Right() < ( bComplete
2035 ? aFieldRect
.Right()
2036 : aFieldRect
.Left()+aFieldRect
.GetWidth()/2 ) )
2038 // => scroll to the left
2039 if ( ScrollColumns( 1 ) != 1 )
2040 // no more need to scroll
2042 aFieldRect
= GetFieldRectPixel( nRow
, nColId
, sal_False
);
2045 // positioned outside above?
2046 if ( nRow
< nTopRow
)
2047 // scroll further to the bottom
2048 ScrollRows( nRow
- nTopRow
);
2050 // positioned outside below?
2051 long nBottomRow
= nTopRow
+ GetVisibleRows();
2052 // decrement nBottomRow to make it the number of the last visible line
2053 // (count starts with 0!).
2054 // Example: BrowseBox contains exactly one entry. nBottomRow := 0 + 1 - 1
2058 if ( nRow
> nBottomRow
)
2059 // scroll further to the top
2060 ScrollRows( nRow
- nBottomRow
);
2062 // it might still not actually fit, e.g. if the window is too small
2063 return IsFieldVisible( nRow
, nColId
, bComplete
);
2066 //-------------------------------------------------------------------
2068 sal_Bool
BrowseBox::IsFieldVisible( long nRow
, sal_uInt16 nColumnId
,
2069 sal_Bool bCompletely
) const
2071 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
2073 // hidden by frozen column?
2074 sal_uInt16 nColPos
= GetColumnPos( nColumnId
);
2075 if ( nColPos
>= FrozenColCount() && nColPos
< nFirstCol
)
2078 Rectangle
aRect( ImplFieldRectPixel( nRow
, nColumnId
) );
2079 if ( aRect
.IsEmpty() )
2082 // get the visible area
2083 Rectangle
aOutRect( Point(0, 0), pDataWin
->GetOutputSizePixel() );
2086 // test if the field is completely visible
2087 return aOutRect
.IsInside( aRect
);
2089 // test if the field is partly of completely visible
2090 return !aOutRect
.Intersection( aRect
).IsEmpty();
2093 //-------------------------------------------------------------------
2095 Rectangle
BrowseBox::GetFieldRectPixel( long nRow
, sal_uInt16 nColumnId
,
2096 sal_Bool bRelToBrowser
) const
2098 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
2100 // get the rectangle relative to DataWin
2101 Rectangle
aRect( ImplFieldRectPixel( nRow
, nColumnId
) );
2102 if ( aRect
.IsEmpty() )
2105 // adjust relative to BrowseBox's output area
2106 Point
aTopLeft( aRect
.TopLeft() );
2107 if ( bRelToBrowser
)
2109 aTopLeft
= pDataWin
->OutputToScreenPixel( aTopLeft
);
2110 aTopLeft
= ScreenToOutputPixel( aTopLeft
);
2113 return Rectangle( aTopLeft
, aRect
.GetSize() );
2116 //-------------------------------------------------------------------
2118 Rectangle
BrowseBox::GetRowRectPixel( long nRow
, sal_Bool bRelToBrowser
) const
2120 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
2122 // get the rectangle relative to DataWin
2124 if ( nTopRow
> nRow
)
2125 // row is above visible area
2128 Point( 0, GetDataRowHeight() * (nRow
-nTopRow
) ),
2129 Size( pDataWin
->GetOutputSizePixel().Width(), GetDataRowHeight() ) );
2130 if ( aRect
.TopLeft().Y() > pDataWin
->GetOutputSizePixel().Height() )
2131 // row is below visible area
2134 // adjust relative to BrowseBox's output area
2135 Point
aTopLeft( aRect
.TopLeft() );
2136 if ( bRelToBrowser
)
2138 aTopLeft
= pDataWin
->OutputToScreenPixel( aTopLeft
);
2139 aTopLeft
= ScreenToOutputPixel( aTopLeft
);
2142 return Rectangle( aTopLeft
, aRect
.GetSize() );
2145 //-------------------------------------------------------------------
2147 Rectangle
BrowseBox::ImplFieldRectPixel( long nRow
, sal_uInt16 nColumnId
) const
2149 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
2151 // compute the X-coordinate relative to DataWin by accumulation
2153 sal_uInt16 nFrozenCols
= FrozenColCount();
2156 nCol
< pCols
->size() && (*pCols
)[ nCol
]->GetId() != nColumnId
;
2158 if ( (*pCols
)[ nCol
]->IsFrozen() || nCol
>= nFirstCol
)
2159 nColX
+= (*pCols
)[ nCol
]->Width();
2161 if ( nCol
>= pCols
->size() || ( nCol
>= nFrozenCols
&& nCol
< nFirstCol
) )
2164 // compute the Y-coordinate relative to DataWin
2165 long nRowY
= GetDataRowHeight();
2166 if ( nRow
!= BROWSER_ENDOFSELECTION
) // #105497# OJ
2167 nRowY
= ( nRow
- nTopRow
) * GetDataRowHeight();
2169 // assemble the Rectangle relative to DataWin
2171 Point( nColX
+ MIN_COLUMNWIDTH
, nRowY
),
2172 Size( (*pCols
)[ nCol
]->Width() - 2*MIN_COLUMNWIDTH
,
2173 GetDataRowHeight() - 1 ) );
2176 //-------------------------------------------------------------------
2178 long BrowseBox::GetRowAtYPosPixel( long nY
, sal_Bool bRelToBrowser
) const
2180 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
2182 // compute the Y-coordinate
2183 if ( bRelToBrowser
)
2185 Point aDataTopLeft
= pDataWin
->OutputToScreenPixel( Point(0, 0) );
2186 Point aTopLeft
= OutputToScreenPixel( Point(0, 0) );
2187 nY
-= aDataTopLeft
.Y() - aTopLeft
.Y();
2190 // no row there (e.g. in the header)
2191 if ( nY
< 0 || nY
>= pDataWin
->GetOutputSizePixel().Height() )
2194 return nY
/ GetDataRowHeight() + nTopRow
;
2197 //-------------------------------------------------------------------
2199 Rectangle
BrowseBox::GetFieldRect( sal_uInt16 nColumnId
) const
2201 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
2203 return GetFieldRectPixel( nCurRow
, nColumnId
);
2206 //-------------------------------------------------------------------
2208 sal_uInt16
BrowseBox::GetColumnAtXPosPixel( long nX
, sal_Bool
) const
2210 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
2212 // accumulate the widths of the visible columns
2214 for ( size_t nCol
= 0; nCol
< pCols
->size(); ++nCol
)
2216 BrowserColumn
*pCol
= (*pCols
)[ nCol
];
2217 if ( pCol
->IsFrozen() || nCol
>= nFirstCol
)
2218 nColX
+= pCol
->Width();
2224 return BROWSER_INVALIDID
;
2227 //-------------------------------------------------------------------
2229 void BrowseBox::ReserveControlArea( sal_uInt16 nWidth
)
2231 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
2233 if ( nWidth
!= nControlAreaWidth
)
2235 OSL_ENSURE(nWidth
,"Control area of 0 is not allowed, Use USHRT_MAX instead!");
2236 nControlAreaWidth
= nWidth
;
2241 //-------------------------------------------------------------------
2243 Rectangle
BrowseBox::GetControlArea() const
2245 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
2248 Point( 0, GetOutputSizePixel().Height() - aHScroll
.GetSizePixel().Height() ),
2249 Size( GetOutputSizePixel().Width() - aHScroll
.GetSizePixel().Width(),
2250 aHScroll
.GetSizePixel().Height() ) );
2253 //-------------------------------------------------------------------
2255 void BrowseBox::SetMode( BrowserMode nMode
)
2257 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
2259 getDataWindow()->bAutoHScroll
= BROWSER_AUTO_HSCROLL
== ( nMode
& BROWSER_AUTO_HSCROLL
);
2260 getDataWindow()->bAutoVScroll
= BROWSER_AUTO_VSCROLL
== ( nMode
& BROWSER_AUTO_VSCROLL
);
2261 getDataWindow()->bNoHScroll
= BROWSER_NO_HSCROLL
== ( nMode
& BROWSER_NO_HSCROLL
);
2262 getDataWindow()->bNoVScroll
= BROWSER_NO_VSCROLL
== ( nMode
& BROWSER_NO_VSCROLL
);
2264 DBG_ASSERT( !( getDataWindow()->bAutoHScroll
&& getDataWindow()->bNoHScroll
),
2265 "BrowseBox::SetMode: AutoHScroll *and* NoHScroll?" );
2266 DBG_ASSERT( !( getDataWindow()->bAutoVScroll
&& getDataWindow()->bNoVScroll
),
2267 "BrowseBox::SetMode: AutoVScroll *and* NoVScroll?" );
2268 if ( getDataWindow()->bAutoHScroll
)
2269 getDataWindow()->bNoHScroll
= sal_False
;
2270 if ( getDataWindow()->bAutoVScroll
)
2271 getDataWindow()->bNoVScroll
= sal_False
;
2273 if ( getDataWindow()->bNoHScroll
)
2276 nControlAreaWidth
= USHRT_MAX
;
2278 getDataWindow()->bNoScrollBack
=
2279 BROWSER_NO_SCROLLBACK
== ( nMode
& BROWSER_NO_SCROLLBACK
);
2281 long nOldRowSel
= bMultiSelection
? uRow
.pSel
->FirstSelected() : uRow
.nSel
;
2282 MultiSelection
*pOldRowSel
= bMultiSelection
? uRow
.pSel
: 0;
2283 MultiSelection
*pOldColSel
= pColSel
;
2287 bThumbDragging
= ( nMode
& BROWSER_THUMBDRAGGING
) == BROWSER_THUMBDRAGGING
;
2288 bMultiSelection
= ( nMode
& BROWSER_MULTISELECTION
) == BROWSER_MULTISELECTION
;
2289 bColumnCursor
= ( nMode
& BROWSER_COLUMNSELECTION
) == BROWSER_COLUMNSELECTION
;
2290 bKeepHighlight
= ( nMode
& BROWSER_KEEPSELECTION
) == BROWSER_KEEPSELECTION
;
2292 bHideSelect
= ((nMode
& BROWSER_HIDESELECT
) == BROWSER_HIDESELECT
);
2293 // default: do not hide the cursor at all (untaken scrolling and such)
2294 bHideCursor
= NO_CURSOR_HIDE
;
2296 if ( BROWSER_SMART_HIDECURSOR
== ( nMode
& BROWSER_SMART_HIDECURSOR
) )
2297 { // smart cursor hide overrules hard cursor hide
2298 bHideCursor
= SMART_CURSOR_HIDE
;
2300 else if ( BROWSER_HIDECURSOR
== ( nMode
& BROWSER_HIDECURSOR
) )
2302 bHideCursor
= HARD_CURSOR_HIDE
;
2305 m_bFocusOnlyCursor
= ((nMode
& BROWSER_CURSOR_WO_FOCUS
) == 0);
2307 bHLines
= ( nMode
& BROWSER_HLINESFULL
) == BROWSER_HLINESFULL
;
2308 bVLines
= ( nMode
& BROWSER_VLINESFULL
) == BROWSER_VLINESFULL
;
2309 bHDots
= ( nMode
& BROWSER_HLINESDOTS
) == BROWSER_HLINESDOTS
;
2310 bVDots
= ( nMode
& BROWSER_VLINESDOTS
) == BROWSER_VLINESDOTS
;
2312 WinBits nVScrollWinBits
=
2313 WB_VSCROLL
| ( ( nMode
& BROWSER_THUMBDRAGGING
) ? WB_DRAG
: 0 );
2314 pVScroll
= ( nMode
& BROWSER_TRACKING_TIPS
) == BROWSER_TRACKING_TIPS
2315 ? new BrowserScrollBar( this, nVScrollWinBits
,
2316 (BrowserDataWin
*) pDataWin
)
2317 : new ScrollBar( this, nVScrollWinBits
);
2318 pVScroll
->SetLineSize( 1 );
2319 pVScroll
->SetPageSize(1);
2320 pVScroll
->SetScrollHdl( LINK( this, BrowseBox
, ScrollHdl
) );
2321 pVScroll
->SetEndScrollHdl( LINK( this, BrowseBox
, EndScrollHdl
) );
2323 getDataWindow()->bAutoSizeLastCol
=
2324 BROWSER_AUTOSIZE_LASTCOL
== ( nMode
& BROWSER_AUTOSIZE_LASTCOL
);
2325 getDataWindow()->bOwnDataChangedHdl
=
2326 BROWSER_OWN_DATACHANGED
== ( nMode
& BROWSER_OWN_DATACHANGED
);
2328 // create a headerbar. what happens, if a headerbar has to be created and
2329 // there already are columns?
2330 if ( BROWSER_HEADERBAR_NEW
== ( nMode
& BROWSER_HEADERBAR_NEW
) )
2332 if (!getDataWindow()->pHeaderBar
)
2333 getDataWindow()->pHeaderBar
= CreateHeaderBar( this );
2337 DELETEZ(getDataWindow()->pHeaderBar
);
2342 if ( bColumnCursor
)
2344 pColSel
= pOldColSel
? pOldColSel
: new MultiSelection
;
2345 pColSel
->SetTotalRange( Range( 0, pCols
->size()-1 ) );
2353 if ( bMultiSelection
)
2356 uRow
.pSel
= pOldRowSel
;
2358 uRow
.pSel
= new MultiSelection
;
2362 uRow
.nSel
= nOldRowSel
;
2366 if ( bBootstrapped
)
2368 StateChanged( STATE_CHANGE_INITSHOW
);
2369 if ( bMultiSelection
&& !pOldRowSel
&&
2370 nOldRowSel
!= BROWSER_ENDOFSELECTION
)
2371 uRow
.pSel
->Select( nOldRowSel
);
2375 pDataWin
->Invalidate();
2377 // no cursor on handle column
2378 if ( nCurColId
== HandleColumnId
)
2379 nCurColId
= GetColumnId( 1 );
2381 m_nCurrentMode
= nMode
;
2384 //-------------------------------------------------------------------
2386 void BrowseBox::VisibleRowsChanged( long, sal_uInt16
)
2388 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
2390 // old behavior: automatically correct NumRows:
2391 if ( nRowCount
< GetRowCount() )
2393 RowInserted(nRowCount
,GetRowCount() - nRowCount
,sal_False
);
2395 else if ( nRowCount
> GetRowCount() )
2397 RowRemoved(nRowCount
-(nRowCount
- GetRowCount()),nRowCount
- GetRowCount(),sal_False
);
2401 //-------------------------------------------------------------------
2403 sal_Bool
BrowseBox::IsCursorMoveAllowed( long, sal_uInt16
) const
2407 This virtual method is always called before the cursor is moved directly.
2408 By means of 'return sal_False', we avoid doing this if e.g. a record
2409 contradicts any rules.
2411 This method is not called, if the cursor movement results from removing or
2412 deleting a row/column (thus, in cases where only a "cursor correction" happens).
2414 The base implementation currently always returns sal_True.
2421 //-------------------------------------------------------------------
2423 long BrowseBox::GetDataRowHeight() const
2425 return CalcZoom(nDataRowHeight
? nDataRowHeight
: ImpGetDataRowHeight());
2428 //-------------------------------------------------------------------
2430 BrowserHeader
* BrowseBox::CreateHeaderBar( BrowseBox
* pParent
)
2432 BrowserHeader
* pNewBar
= new BrowserHeader( pParent
);
2433 pNewBar
->SetStartDragHdl( LINK( this, BrowseBox
, StartDragHdl
) );
2437 void BrowseBox::SetHeaderBar( BrowserHeader
* pHeaderBar
)
2439 delete ( (BrowserDataWin
*)pDataWin
)->pHeaderBar
;
2440 ( (BrowserDataWin
*)pDataWin
)->pHeaderBar
= pHeaderBar
;
2441 ( (BrowserDataWin
*)pDataWin
)->pHeaderBar
->SetStartDragHdl( LINK( this, BrowseBox
, StartDragHdl
) );
2443 //-------------------------------------------------------------------
2446 const char* BrowseBoxCheckInvariants( const void * pVoid
)
2448 const BrowseBox
* p
= (const BrowseBox
*)pVoid
;
2450 if (p
->nRowCount
< 0) return "BrowseBox: nRowCount < 0";
2451 if (p
->nTopRow
< 0) return "BrowseBox: nTopRow < 0";
2452 if (p
->nTopRow
>= p
->nRowCount
&& p
->nRowCount
!= 0) return "BrowseBox: nTopRow >= nRowCount && nRowCount != 0";
2453 if (p
->nCurRow
< -1) return "BrowseBox: nCurRow < -1";
2454 if (p
->nCurRow
> p
->nRowCount
) return "BrowseBox: nCurRow > nRowCount";
2456 // Sadly not always the case when editing:
2457 //if (p->nCurRow < 0 && p->nRowCount != 0) return "nCurRow < 0 && nRowCount != 0";
2458 //if (p->nCurRow >= p->nRowCount && p->nRowCount != 0) return "nCurRow >= nRowCount && nRowCount != 0";
2464 //-------------------------------------------------------------------
2465 long BrowseBox::GetTitleHeight() const
2468 // ask the header bar for the text height (if possible), as the header bar's font is adjusted with
2469 // our (and the header's) zoom factor
2470 HeaderBar
* pHeaderBar
= ( (BrowserDataWin
*)pDataWin
)->pHeaderBar
;
2472 nHeight
= pHeaderBar
->GetTextHeight();
2474 nHeight
= GetTextHeight();
2476 return nTitleLines
? nTitleLines
* nHeight
+ 4 : 0;
2479 //-------------------------------------------------------------------
2480 long BrowseBox::CalcReverseZoom(long nVal
)
2484 const Fraction
& rZoom
= GetZoom();
2485 double n
= (double)nVal
;
2486 n
*= (double)rZoom
.GetDenominator();
2487 n
/= (double)rZoom
.GetNumerator();
2488 nVal
= n
>0 ? (long)(n
+ 0.5) : -(long)(-n
+ 0.5);
2494 void BrowseBox::CursorMoved()
2496 // before implementing more here, please adjust the EditBrowseBox
2497 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
2499 if ( isAccessibleAlive() && HasFocus() )
2501 ACTIVE_DESCENDANT_CHANGED
,
2502 makeAny( CreateAccessibleCell( GetCurRow(),GetColumnPos( GetCurColumnId() ) ) ),
2507 //-------------------------------------------------------------------
2509 void BrowseBox::LoseFocus()
2511 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
2512 OSL_TRACE( "BrowseBox: %p->LoseFocus", this );
2516 OSL_TRACE( "BrowseBox: %p->HideCursor", this );
2517 DoHideCursor( "LoseFocus" );
2519 if ( !bKeepHighlight
)
2522 bSelectionIsVisible
= sal_False
;
2525 bHasFocus
= sal_False
;
2527 Control::LoseFocus();
2530 //-------------------------------------------------------------------
2532 void BrowseBox::GetFocus()
2534 DBG_CHKTHIS(BrowseBox
,BrowseBoxCheckInvariants
);
2535 OSL_TRACE( "BrowseBox: %p->GetFocus", this );
2539 if ( !bSelectionIsVisible
)
2541 bSelectionIsVisible
= sal_True
;
2542 if ( bBootstrapped
)
2546 bHasFocus
= sal_True
;
2547 DoShowCursor( "GetFocus" );
2549 Control::GetFocus();
2553 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */