fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / svtools / source / brwbox / brwbox1.cxx
blob98b8904a4f2c93fb6d983fd0130cfcf48107a75c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svtools/brwbox.hxx>
21 #include <svtools/brwhead.hxx>
22 #include <o3tl/numeric.hxx>
23 #include "datwin.hxx"
24 #include <tools/debug.hxx>
25 #include <tools/stream.hxx>
26 #include <tools/fract.hxx>
28 #include <functional>
29 #include <algorithm>
30 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
31 #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
32 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
33 #include <com/sun/star/accessibility/XAccessible.hpp>
34 #include <tools/multisel.hxx>
35 #include "brwimpl.hxx"
38 #define SCROLL_FLAGS (SCROLL_CLIP | SCROLL_NOCHILDREN)
39 #define getDataWindow() (static_cast<BrowserDataWin*>(pDataWin.get()))
41 using namespace com::sun::star::accessibility::AccessibleEventId;
42 using namespace com::sun::star::accessibility::AccessibleTableModelChangeType;
43 using com::sun::star::accessibility::AccessibleTableModelChange;
44 using com::sun::star::lang::XComponent;
45 using namespace ::com::sun::star::uno;
46 using namespace svt;
48 namespace
50 void disposeAndClearHeaderCell(::svt::BrowseBoxImpl::THeaderCellMap& _rHeaderCell)
52 ::std::for_each(
53 _rHeaderCell.begin(),
54 _rHeaderCell.end(),
55 ::svt::BrowseBoxImpl::THeaderCellMapFunctorDispose()
57 _rHeaderCell.clear();
61 void BrowseBox::ConstructImpl( BrowserMode nMode )
63 OSL_TRACE( "BrowseBox: %p->ConstructImpl", this );
64 bMultiSelection = false;
65 pColSel = 0;
66 pDataWin = 0;
67 pVScroll = 0;
69 pDataWin = VclPtr<BrowserDataWin>::Create( this ).get();
70 pCols = new BrowserColumns;
71 m_pImpl.reset( new ::svt::BrowseBoxImpl() );
73 aGridLineColor = Color( COL_LIGHTGRAY );
74 InitSettings_Impl( this );
75 InitSettings_Impl( pDataWin );
77 bBootstrapped = false;
78 nDataRowHeight = 0;
79 nTitleLines = 1;
80 nFirstCol = 0;
81 nTopRow = 0;
82 nCurRow = BROWSER_ENDOFSELECTION;
83 nCurColId = 0;
84 bResizing = false;
85 bSelect = false;
86 bSelecting = false;
87 bScrolling = false;
88 bSelectionIsVisible = false;
89 bNotToggleSel = false;
90 bRowDividerDrag = false;
91 bHit = false;
92 mbInteractiveRowHeight = false;
93 bHideSelect = false;
94 bHideCursor = TRISTATE_FALSE;
95 nRowCount = 0;
96 m_bFocusOnlyCursor = true;
97 m_aCursorColor = COL_TRANSPARENT;
98 m_nCurrentMode = BrowserMode::NONE;
99 nControlAreaWidth = USHRT_MAX;
100 uRow.nSel = BROWSER_ENDOFSELECTION;
102 aHScroll->SetLineSize(1);
103 aHScroll->SetScrollHdl( LINK( this, BrowseBox, ScrollHdl ) );
104 aHScroll->SetEndScrollHdl( LINK( this, BrowseBox, EndScrollHdl ) );
105 pDataWin->Show();
107 SetMode( nMode );
108 bSelectionIsVisible = bKeepHighlight;
109 bHasFocus = HasChildPathFocus();
110 getDataWindow()->nCursorHidden =
111 ( bHasFocus ? 0 : 1 ) + ( GetUpdateMode() ? 0 : 1 );
116 BrowseBox::BrowseBox( vcl::Window* pParent, WinBits nBits, BrowserMode nMode )
117 :Control( pParent, nBits | WB_3DLOOK )
118 ,DragSourceHelper( this )
119 ,DropTargetHelper( this )
120 ,aHScroll( VclPtr<ScrollBar>::Create(this, WinBits( WB_HSCROLL )) )
122 ConstructImpl( nMode );
127 BrowseBox::BrowseBox( vcl::Window* pParent, const ResId& rId, BrowserMode nMode )
128 :Control( pParent, rId )
129 ,DragSourceHelper( this )
130 ,DropTargetHelper( this )
131 ,aHScroll( VclPtr<ScrollBar>::Create(this, WinBits(WB_HSCROLL)) )
133 ConstructImpl(nMode);
137 BrowseBox::~BrowseBox()
139 disposeOnce();
142 void BrowseBox::dispose()
144 OSL_TRACE( "BrowseBox: %p~", this );
146 if ( m_pImpl->m_pAccessible )
148 disposeAndClearHeaderCell(m_pImpl->m_aColHeaderCellMap);
149 disposeAndClearHeaderCell(m_pImpl->m_aRowHeaderCellMap);
150 m_pImpl->m_pAccessible->dispose();
153 Hide();
154 getDataWindow()->pHeaderBar.disposeAndClear();
155 getDataWindow()->pCornerWin.disposeAndClear();
156 pDataWin.disposeAndClear();
157 pVScroll.disposeAndClear();
158 aHScroll.disposeAndClear();
160 // free columns-space
161 for ( size_t i = 0, n = pCols->size(); i < n; ++i )
162 delete (*pCols)[ i ];
163 pCols->clear();
164 delete pCols;
165 delete pColSel;
166 if ( bMultiSelection )
167 delete uRow.pSel;
168 Control::dispose();
173 short BrowseBox::GetCursorHideCount() const
175 return getDataWindow()->nCursorHidden;
180 void BrowseBox::DoShowCursor( const char * )
182 if (!getDataWindow())
183 return;
184 short nHiddenCount = --getDataWindow()->nCursorHidden;
185 if (PaintCursorIfHiddenOnce())
187 if (1 == nHiddenCount)
188 DrawCursor();
190 else
192 if (0 == nHiddenCount)
193 DrawCursor();
199 void BrowseBox::DoHideCursor( const char * )
201 short nHiddenCount = ++getDataWindow()->nCursorHidden;
202 if (PaintCursorIfHiddenOnce())
204 if (2 == nHiddenCount)
205 DrawCursor();
207 else
209 if (1 == nHiddenCount)
210 DrawCursor();
216 void BrowseBox::SetRealRowCount( const OUString &rRealRowCount )
218 getDataWindow()->aRealRowCount = rRealRowCount;
223 void BrowseBox::SetFont( const vcl::Font& rNewFont )
225 pDataWin->SetFont( rNewFont );
226 ImpGetDataRowHeight();
231 sal_uLong BrowseBox::GetDefaultColumnWidth( const OUString& _rText ) const
233 return GetDataWindow().GetTextWidth( _rText ) + GetDataWindow().GetTextWidth(OUString('0')) * 4;
238 void BrowseBox::InsertHandleColumn( sal_uLong nWidth )
241 #if OSL_DEBUG_LEVEL > 0
242 OSL_ENSURE( ColCount() == 0 || (*pCols)[0]->GetId() != HandleColumnId , "BrowseBox::InsertHandleColumn: there is already a handle column" );
244 BrowserColumns::iterator iCol = pCols->begin();
245 const BrowserColumns::iterator colsEnd = pCols->end();
246 if ( iCol != colsEnd )
247 for (++iCol; iCol != colsEnd; ++iCol)
248 OSL_ENSURE( (*iCol)->GetId() != HandleColumnId, "BrowseBox::InsertHandleColumn: there is a non-Handle column with handle ID" );
250 #endif
252 pCols->insert( pCols->begin(), new BrowserColumn( 0, Image(), OUString(), nWidth, GetZoom() ) );
253 FreezeColumn( 0 );
255 // adjust headerbar
256 if ( getDataWindow()->pHeaderBar )
258 getDataWindow()->pHeaderBar->SetPosSizePixel(
259 Point(nWidth, 0),
260 Size( GetOutputSizePixel().Width() - nWidth, GetTitleHeight() )
264 ColumnInserted( 0 );
269 void BrowseBox::InsertDataColumn( sal_uInt16 nItemId, const OUString& rText,
270 long nWidth, HeaderBarItemBits nBits, sal_uInt16 nPos )
273 OSL_ENSURE( nItemId != HandleColumnId, "BrowseBox::InsertDataColumn: nItemId is HandleColumnId" );
274 OSL_ENSURE( nItemId != BROWSER_INVALIDID, "BrowseBox::InsertDataColumn: nItemId is reserved value BROWSER_INVALIDID" );
276 #if OSL_DEBUG_LEVEL > 0
278 const BrowserColumns::iterator colsEnd = pCols->end();
279 for (BrowserColumns::iterator iCol = pCols->begin(); iCol != colsEnd; ++iCol)
280 OSL_ENSURE( (*iCol)->GetId() != nItemId, "BrowseBox::InsertDataColumn: duplicate column Id" );
282 #endif
284 if ( nPos < pCols->size() )
286 BrowserColumns::iterator it = pCols->begin();
287 ::std::advance( it, nPos );
288 pCols->insert( it, new BrowserColumn( nItemId, Image(), rText, nWidth, GetZoom() ) );
290 else
292 pCols->push_back( new BrowserColumn( nItemId, Image(), rText, nWidth, GetZoom() ) );
294 if ( nCurColId == 0 )
295 nCurColId = nItemId;
297 if ( getDataWindow()->pHeaderBar )
299 // Handle column not in the header bar
300 sal_uInt16 nHeaderPos = nPos;
301 if (nHeaderPos != HEADERBAR_APPEND && GetColumnId(0) == HandleColumnId )
302 nHeaderPos--;
303 getDataWindow()->pHeaderBar->InsertItem(
304 nItemId, rText, nWidth, nBits, nHeaderPos );
306 ColumnInserted( nPos );
309 sal_uInt16 BrowseBox::ToggleSelectedColumn()
311 sal_uInt16 nSelectedColId = BROWSER_INVALIDID;
312 if ( pColSel && pColSel->GetSelectCount() )
314 DoHideCursor( "ToggleSelectedColumn" );
315 ToggleSelection();
316 long nSelected = pColSel->FirstSelected();
317 if (nSelected != static_cast<long>(SFX_ENDOFSELECTION))
318 nSelectedColId = (*pCols)[nSelected]->GetId();
319 pColSel->SelectAll(false);
321 return nSelectedColId;
324 void BrowseBox::SetToggledSelectedColumn(sal_uInt16 _nSelectedColumnId)
326 if ( pColSel && _nSelectedColumnId != BROWSER_INVALIDID )
328 pColSel->Select( GetColumnPos( _nSelectedColumnId ) );
329 ToggleSelection();
330 OSL_TRACE( "BrowseBox: %p->SetToggledSelectedColumn", this );
331 DoShowCursor( "SetToggledSelectedColumn" );
335 void BrowseBox::FreezeColumn( sal_uInt16 nItemId, bool bFreeze )
338 // never unfreeze the handle-column
339 if ( nItemId == HandleColumnId && !bFreeze )
340 return;
342 // get the position in the current array
343 size_t nItemPos = GetColumnPos( nItemId );
344 if ( nItemPos >= pCols->size() )
345 // not available!
346 return;
348 // doesn't the state change?
349 if ( (*pCols)[ nItemPos ]->IsFrozen() == bFreeze )
350 return;
352 // remark the column selection
353 sal_uInt16 nSelectedColId = ToggleSelectedColumn();
355 // freeze or unfreeze?
356 if ( bFreeze )
358 // to be moved?
359 if ( nItemPos != 0 && !(*pCols)[ nItemPos-1 ]->IsFrozen() )
361 // move to the right of the last frozen column
362 sal_uInt16 nFirstScrollable = FrozenColCount();
363 BrowserColumn *pColumn = (*pCols)[ nItemPos ];
364 BrowserColumns::iterator it = pCols->begin();
365 ::std::advance( it, nItemPos );
366 pCols->erase( it );
367 nItemPos = nFirstScrollable;
368 it = pCols->begin();
369 ::std::advance( it, nItemPos );
370 pCols->insert( it, pColumn );
373 // adjust the number of the first scrollable and visible column
374 if ( nFirstCol <= nItemPos )
375 nFirstCol = nItemPos + 1;
377 else
379 // to be moved?
380 if ( (sal_Int32)nItemPos != FrozenColCount()-1 )
382 // move to the leftmost scrollable column
383 sal_uInt16 nFirstScrollable = FrozenColCount();
384 BrowserColumn *pColumn = (*pCols)[ nItemPos ];
385 BrowserColumns::iterator it = pCols->begin();
386 ::std::advance( it, nItemPos );
387 pCols->erase( it );
388 nItemPos = nFirstScrollable;
389 it = pCols->begin();
390 ::std::advance( it, nItemPos );
391 pCols->insert( it, pColumn );
394 // adjust the number of the first scrollable and visible column
395 nFirstCol = nItemPos;
398 // toggle the freeze-state of the column
399 (*pCols)[ nItemPos ]->Freeze( bFreeze );
401 // align the scrollbar-range
402 UpdateScrollbars();
404 // repaint
405 Control::Invalidate();
406 getDataWindow()->Invalidate();
408 // remember the column selection
409 SetToggledSelectedColumn(nSelectedColId);
414 void BrowseBox::SetColumnPos( sal_uInt16 nColumnId, sal_uInt16 nPos )
416 // never set pos of the handle column
417 if ( nColumnId == HandleColumnId )
418 return;
420 // get the position in the current array
421 sal_uInt16 nOldPos = GetColumnPos( nColumnId );
422 if ( nOldPos >= pCols->size() )
423 // not available!
424 return;
426 // does the state change?
427 if (nOldPos != nPos)
429 // remark the column selection
430 sal_uInt16 nSelectedColId = ToggleSelectedColumn();
432 // determine old column area
433 Size aDataWinSize( pDataWin->GetSizePixel() );
434 if ( getDataWindow()->pHeaderBar )
435 aDataWinSize.Height() += getDataWindow()->pHeaderBar->GetSizePixel().Height();
437 Rectangle aFromRect( GetFieldRect( nColumnId) );
438 aFromRect.Right() += 2*MIN_COLUMNWIDTH;
440 sal_uInt16 nNextPos = nOldPos + 1;
441 if ( nOldPos > nPos )
442 nNextPos = nOldPos - 1;
444 BrowserColumn *pNextCol = (*pCols)[ nNextPos ];
445 Rectangle aNextRect(GetFieldRect( pNextCol->GetId() ));
447 // move column internally
449 BrowserColumns::iterator it = pCols->begin();
450 ::std::advance( it, nOldPos );
451 BrowserColumn* pTemp = *it;
452 pCols->erase( it );
453 it = pCols->begin();
454 ::std::advance( it, nPos );
455 pCols->insert( it, pTemp );
458 // determine new column area
459 Rectangle aToRect( GetFieldRect( nColumnId ) );
460 aToRect.Right() += 2*MIN_COLUMNWIDTH;
462 // do scroll, let redraw
463 if( pDataWin->GetBackground().IsScrollable() )
465 long nScroll = -aFromRect.GetWidth();
466 Rectangle aScrollArea;
467 if ( nOldPos > nPos )
469 long nFrozenWidth = GetFrozenWidth();
470 if ( aToRect.Left() < nFrozenWidth )
471 aToRect.Left() = nFrozenWidth;
472 aScrollArea = Rectangle(Point(aToRect.Left(),0),
473 Point(aNextRect.Right(),aDataWinSize.Height()));
474 nScroll *= -1; // reverse direction
476 else
477 aScrollArea = Rectangle(Point(aNextRect.Left(),0),
478 Point(aToRect.Right(),aDataWinSize.Height()));
480 pDataWin->Scroll( nScroll, 0, aScrollArea );
481 aToRect.Top() = 0;
482 aToRect.Bottom() = aScrollArea.Bottom();
483 Invalidate( aToRect );
485 else
486 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
488 // adjust header bar positions
489 if ( getDataWindow()->pHeaderBar )
491 sal_uInt16 nNewPos = nPos;
492 if ( GetColumnId(0) == HandleColumnId )
493 --nNewPos;
494 getDataWindow()->pHeaderBar->MoveItem(nColumnId,nNewPos);
496 // remember the column selection
497 SetToggledSelectedColumn(nSelectedColId);
499 if ( isAccessibleAlive() )
501 commitTableEvent(
502 TABLE_MODEL_CHANGED,
503 makeAny( AccessibleTableModelChange(
504 DELETE,
506 GetRowCount(),
507 nOldPos,
508 nOldPos
511 Any()
514 commitTableEvent(
515 TABLE_MODEL_CHANGED,
516 makeAny( AccessibleTableModelChange(
517 INSERT,
519 GetRowCount(),
520 nPos,
521 nPos
524 Any()
533 void BrowseBox::SetColumnTitle( sal_uInt16 nItemId, const OUString& rTitle )
536 // never set title of the handle-column
537 if ( nItemId == HandleColumnId )
538 return;
540 // get the position in the current array
541 sal_uInt16 nItemPos = GetColumnPos( nItemId );
542 if ( nItemPos >= pCols->size() )
543 // not available!
544 return;
546 // does the state change?
547 BrowserColumn *pCol = (*pCols)[ nItemPos ];
548 if ( pCol->Title() != rTitle )
550 OUString sNew(rTitle);
551 OUString sOld(pCol->Title());
553 pCol->Title() = rTitle;
555 // adjust headerbar column
556 if ( getDataWindow()->pHeaderBar )
557 getDataWindow()->pHeaderBar->SetItemText( nItemId, rTitle );
558 else
560 // redraw visible columns
561 if ( GetUpdateMode() && ( pCol->IsFrozen() || nItemPos > nFirstCol ) )
562 Invalidate( Rectangle( Point(0,0),
563 Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
566 if ( isAccessibleAlive() )
568 commitTableEvent( TABLE_COLUMN_DESCRIPTION_CHANGED,
569 makeAny( sNew ),
570 makeAny( sOld )
578 void BrowseBox::SetColumnWidth( sal_uInt16 nItemId, sal_uLong nWidth )
581 // get the position in the current array
582 size_t nItemPos = GetColumnPos( nItemId );
583 if ( nItemPos >= pCols->size() )
584 return;
586 // does the state change?
587 nWidth = QueryColumnResize( nItemId, nWidth );
588 if ( nWidth >= LONG_MAX || (*pCols)[ nItemPos ]->Width() != nWidth )
590 long nOldWidth = (*pCols)[ nItemPos ]->Width();
592 // adjust last column, if necessary
593 if ( IsVisible() && nItemPos == pCols->size() - 1 )
595 long nMaxWidth = pDataWin->GetSizePixel().Width();
596 nMaxWidth -= getDataWindow()->bAutoSizeLastCol
597 ? GetFieldRect(nItemId).Left()
598 : GetFrozenWidth();
599 if ( static_cast<BrowserDataWin*>( pDataWin.get() )->bAutoSizeLastCol || nWidth > (sal_uLong)nMaxWidth )
601 nWidth = nMaxWidth > 16 ? nMaxWidth : nOldWidth;
602 nWidth = QueryColumnResize( nItemId, nWidth );
606 // OV
607 // In AutoSizeLastColumn(), we call SetColumnWidth with nWidth==0xffff.
608 // Thus, check here, if the width has actually changed.
609 if( (sal_uLong)nOldWidth == nWidth )
610 return;
612 // do we want to display the change immediately?
613 bool bUpdate = GetUpdateMode() &&
614 ( (*pCols)[ nItemPos ]->IsFrozen() || nItemPos >= nFirstCol );
616 if ( bUpdate )
618 // Selection hidden
619 DoHideCursor( "SetColumnWidth" );
620 ToggleSelection();
621 //!getDataWindow()->Update();
622 //!Control::Update();
625 // set width
626 (*pCols)[ nItemPos ]->SetWidth(nWidth, GetZoom());
628 // scroll and invalidate
629 if ( bUpdate )
631 // get X-Pos of the column changed
632 long nX = 0;
633 for ( sal_uInt16 nCol = 0; nCol < nItemPos; ++nCol )
635 BrowserColumn *pCol = (*pCols)[ nCol ];
636 if ( pCol->IsFrozen() || nCol >= nFirstCol )
637 nX += pCol->Width();
640 // actually scroll+invalidate
641 pDataWin->SetClipRegion();
642 bool bSelVis = bSelectionIsVisible;
643 bSelectionIsVisible = false;
644 if( GetBackground().IsScrollable() )
647 Rectangle aScrRect( nX + std::min( (sal_uLong)nOldWidth, nWidth ), 0,
648 GetSizePixel().Width() , // the header is longer than the datawin
649 pDataWin->GetPosPixel().Y() - 1 );
650 Control::Scroll( nWidth-nOldWidth, 0, aScrRect, SCROLL_FLAGS );
651 aScrRect.Bottom() = pDataWin->GetSizePixel().Height();
652 getDataWindow()->Scroll( nWidth-nOldWidth, 0, aScrRect, SCROLL_FLAGS );
653 Rectangle aInvRect( nX, 0, nX + std::max( nWidth, (sal_uLong)nOldWidth ), USHRT_MAX );
654 Control::Invalidate( aInvRect, INVALIDATE_NOCHILDREN );
655 static_cast<BrowserDataWin*>( pDataWin.get() )->Invalidate( aInvRect );
657 else
659 Control::Invalidate( INVALIDATE_NOCHILDREN );
660 getDataWindow()->Window::Invalidate( INVALIDATE_NOCHILDREN );
664 //!getDataWindow()->Update();
665 //!Control::Update();
666 bSelectionIsVisible = bSelVis;
667 ToggleSelection();
668 DoShowCursor( "SetColumnWidth" );
670 UpdateScrollbars();
672 // adjust headerbar column
673 if ( getDataWindow()->pHeaderBar )
674 getDataWindow()->pHeaderBar->SetItemSize(
675 nItemId ? nItemId : USHRT_MAX - 1, nWidth );
677 // adjust last column
678 if ( nItemPos != pCols->size() - 1 )
679 AutoSizeLastColumn();
686 void BrowseBox::AutoSizeLastColumn()
688 if ( getDataWindow()->bAutoSizeLastCol &&
689 getDataWindow()->GetUpdateMode() )
691 sal_uInt16 nId = GetColumnId( (sal_uInt16)pCols->size() - 1 );
692 SetColumnWidth( nId, LONG_MAX );
693 ColumnResized( nId );
699 void BrowseBox::RemoveColumn( sal_uInt16 nItemId )
702 // get column position
703 sal_uInt16 nPos = GetColumnPos(nItemId);
704 if ( nPos >= ColCount() )
705 // not available
706 return;
708 // correct column selection
709 if ( pColSel )
710 pColSel->Remove( nPos );
712 // correct column cursor
713 if ( nCurColId == nItemId )
714 nCurColId = 0;
716 // delete column
717 BrowserColumns::iterator it = pCols->begin();
718 ::std::advance( it, nPos );
719 delete *it;
720 pCols->erase( it );
721 if ( nFirstCol >= nPos && nFirstCol > FrozenColCount() )
723 OSL_ENSURE(nFirstCol > 0,"FirstCol must be greater zero!");
724 --nFirstCol;
727 // handlecolumn not in headerbar
728 if (nItemId)
730 if ( getDataWindow()->pHeaderBar )
731 getDataWindow()->pHeaderBar->RemoveItem( nItemId );
733 else
735 // adjust headerbar
736 if ( getDataWindow()->pHeaderBar )
738 getDataWindow()->pHeaderBar->SetPosSizePixel(
739 Point(0, 0),
740 Size( GetOutputSizePixel().Width(), GetTitleHeight() )
745 // correct vertical scrollbar
746 UpdateScrollbars();
748 // trigger repaint, if necessary
749 if ( GetUpdateMode() )
751 getDataWindow()->Invalidate();
752 Control::Invalidate();
753 if ( getDataWindow()->bAutoSizeLastCol && nPos ==ColCount() )
754 SetColumnWidth( GetColumnId( nPos - 1 ), LONG_MAX );
757 if ( isAccessibleAlive() )
759 commitTableEvent(
760 TABLE_MODEL_CHANGED,
761 makeAny( AccessibleTableModelChange( DELETE,
763 GetRowCount(),
764 nPos,
765 nPos
768 Any()
771 commitHeaderBarEvent(
772 CHILD,
773 Any(),
774 makeAny( CreateAccessibleColumnHeader( nPos ) ),
775 true
782 void BrowseBox::RemoveColumns()
784 size_t nOldCount = pCols->size();
786 // remove all columns
787 for ( size_t i = 0; i < nOldCount; ++i )
788 delete (*pCols)[ i ];
789 pCols->clear();
791 // correct column selection
792 if ( pColSel )
794 pColSel->SelectAll(false);
795 pColSel->SetTotalRange( Range( 0, 0 ) );
798 // correct column cursor
799 nCurColId = 0;
800 nFirstCol = 0;
802 if ( getDataWindow()->pHeaderBar )
803 getDataWindow()->pHeaderBar->Clear( );
805 // correct vertical scrollbar
806 UpdateScrollbars();
808 // trigger repaint if necessary
809 if ( GetUpdateMode() )
811 getDataWindow()->Invalidate();
812 Control::Invalidate();
815 if ( isAccessibleAlive() )
817 if ( pCols->size() != nOldCount )
819 // all columns should be removed, so we remove the column header bar and append it again
820 // to avoid to notify every column remove
821 commitBrowseBoxEvent(
822 CHILD,
823 Any(),
824 makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_COLUMNHEADERBAR))
827 // and now append it again
828 commitBrowseBoxEvent(
829 CHILD,
830 makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_COLUMNHEADERBAR)),
831 Any()
834 // notify a table model change
835 commitTableEvent(
836 TABLE_MODEL_CHANGED,
837 makeAny ( AccessibleTableModelChange( DELETE,
839 GetRowCount(),
841 nOldCount
844 Any()
852 OUString BrowseBox::GetColumnTitle( sal_uInt16 nId ) const
855 sal_uInt16 nItemPos = GetColumnPos( nId );
856 if ( nItemPos >= pCols->size() )
857 return OUString();
858 return (*pCols)[ nItemPos ]->Title();
863 long BrowseBox::GetRowCount() const
865 return nRowCount;
870 sal_uInt16 BrowseBox::ColCount() const
873 return (sal_uInt16) pCols->size();
878 long BrowseBox::ImpGetDataRowHeight() const
881 BrowseBox *pThis = const_cast<BrowseBox*>(this);
882 pThis->nDataRowHeight = pThis->CalcReverseZoom(pDataWin->GetTextHeight() + 2);
883 pThis->Resize();
884 getDataWindow()->Invalidate();
885 return nDataRowHeight;
890 void BrowseBox::SetDataRowHeight( long nPixel )
893 nDataRowHeight = CalcReverseZoom(nPixel);
894 Resize();
895 getDataWindow()->Invalidate();
900 void BrowseBox::SetTitleLines( sal_uInt16 nLines )
903 nTitleLines = nLines;
908 long BrowseBox::ScrollColumns( long nCols )
911 if ( nFirstCol + nCols < 0 ||
912 nFirstCol + nCols >= (long)pCols->size() )
913 return 0;
915 // implicitly hides cursor while scrolling
916 StartScroll();
917 bScrolling = true;
918 bool bScrollable = pDataWin->GetBackground().IsScrollable();
919 bool bInvalidateView = false;
921 // scrolling one column to the right?
922 if ( nCols == 1 )
924 // update internal value and scrollbar
925 ++nFirstCol;
926 aHScroll->SetThumbPos( nFirstCol - FrozenColCount() );
928 if ( !bScrollable )
930 bInvalidateView = true;
932 else
934 long nDelta = (*pCols)[ nFirstCol-1 ]->Width();
935 long nFrozenWidth = GetFrozenWidth();
937 Rectangle aScrollRect( Point( nFrozenWidth + nDelta, 0 ),
938 Size ( GetOutputSizePixel().Width() - nFrozenWidth - nDelta,
939 GetTitleHeight() - 1
940 ) );
942 // scroll the header bar area (if there is no dedicated HeaderBar control)
943 if ( !getDataWindow()->pHeaderBar && nTitleLines )
945 // actually scroll
946 Scroll( -nDelta, 0, aScrollRect, SCROLL_FLAGS );
948 // invalidate the area of the column which was scrolled out to the left hand side
949 Rectangle aInvalidateRect( aScrollRect );
950 aInvalidateRect.Left() = nFrozenWidth;
951 aInvalidateRect.Right() = nFrozenWidth + nDelta - 1;
952 Invalidate( aInvalidateRect );
955 // scroll the data-area
956 aScrollRect.Bottom() = pDataWin->GetOutputSizePixel().Height();
958 // actually scroll
959 pDataWin->Scroll( -nDelta, 0, aScrollRect, SCROLL_FLAGS );
961 // invalidate the area of the column which was scrolled out to the left hand side
962 aScrollRect.Left() = nFrozenWidth;
963 aScrollRect.Right() = nFrozenWidth + nDelta - 1;
964 getDataWindow()->Invalidate( aScrollRect );
968 // scrolling one column to the left?
969 else if ( nCols == -1 )
971 --nFirstCol;
972 aHScroll->SetThumbPos( nFirstCol - FrozenColCount() );
974 if ( !bScrollable )
976 bInvalidateView = true;
978 else
980 long nDelta = (*pCols)[ nFirstCol ]->Width();
981 long nFrozenWidth = GetFrozenWidth();
983 Rectangle aScrollRect( Point( nFrozenWidth, 0 ),
984 Size ( GetOutputSizePixel().Width() - nFrozenWidth,
985 GetTitleHeight() - 1
986 ) );
988 // scroll the header bar area (if there is no dedicated HeaderBar control)
989 if ( !getDataWindow()->pHeaderBar && nTitleLines )
991 Scroll( nDelta, 0, aScrollRect, SCROLL_FLAGS );
994 // scroll the data-area
995 aScrollRect.Bottom() = pDataWin->GetOutputSizePixel().Height();
996 pDataWin->Scroll( nDelta, 0, aScrollRect, SCROLL_FLAGS );
999 else
1001 if ( GetUpdateMode() )
1003 Invalidate( Rectangle(
1004 Point( GetFrozenWidth(), 0 ),
1005 Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
1006 getDataWindow()->Invalidate( Rectangle(
1007 Point( GetFrozenWidth(), 0 ),
1008 pDataWin->GetSizePixel() ) );
1011 nFirstCol = nFirstCol + (sal_uInt16)nCols;
1012 aHScroll->SetThumbPos( nFirstCol - FrozenColCount() );
1015 // adjust external headerbar, if necessary
1016 if ( getDataWindow()->pHeaderBar )
1018 long nWidth = 0;
1019 for ( size_t nCol = 0;
1020 nCol < pCols->size() && nCol < nFirstCol;
1021 ++nCol )
1023 // not the handle column
1024 if ( (*pCols)[ nCol ]->GetId() )
1025 nWidth += (*pCols)[ nCol ]->Width();
1028 getDataWindow()->pHeaderBar->SetOffset( nWidth );
1031 if( bInvalidateView )
1033 Control::Invalidate( INVALIDATE_NOCHILDREN );
1034 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
1037 // implicitly show cursor after scrolling
1038 if ( nCols )
1040 getDataWindow()->Update();
1041 Update();
1043 bScrolling = false;
1044 EndScroll();
1046 return nCols;
1051 long BrowseBox::ScrollRows( long nRows )
1054 // out of range?
1055 if ( getDataWindow()->bNoScrollBack && nRows < 0 )
1056 return 0;
1058 // compute new top row
1059 long nTmpMin = std::min( (long)(nTopRow + nRows), (long)(nRowCount - 1) );
1061 long nNewTopRow = std::max( (long)nTmpMin, (long)0 );
1063 if ( nNewTopRow == nTopRow )
1064 return 0;
1066 sal_uInt16 nVisibleRows =
1067 (sal_uInt16)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
1069 VisibleRowsChanged(nNewTopRow, nVisibleRows);
1071 // compute new top row again (nTopRow might have changed!)
1072 nTmpMin = std::min( (long)(nTopRow + nRows), (long)(nRowCount - 1) );
1074 nNewTopRow = std::max( (long)nTmpMin, (long)0 );
1076 StartScroll();
1078 // scroll area on screen and/or repaint
1079 long nDeltaY = GetDataRowHeight() * ( nNewTopRow - nTopRow );
1080 long nOldTopRow = nTopRow;
1081 nTopRow = nNewTopRow;
1083 if ( GetUpdateMode() )
1085 pVScroll->SetRange( Range( 0L, nRowCount ) );
1086 pVScroll->SetThumbPos( nTopRow );
1088 if( pDataWin->GetBackground().IsScrollable() &&
1089 std::abs( nDeltaY ) > 0 &&
1090 std::abs( nDeltaY ) < pDataWin->GetSizePixel().Height() )
1092 pDataWin->Scroll( 0, (short)-nDeltaY, SCROLL_FLAGS );
1094 else
1095 getDataWindow()->Invalidate();
1097 if ( nTopRow - nOldTopRow )
1098 getDataWindow()->Update();
1101 EndScroll();
1103 return nTopRow - nOldTopRow;
1108 void BrowseBox::RowModified( long nRow, sal_uInt16 nColId )
1111 if ( !GetUpdateMode() )
1112 return;
1114 Rectangle aRect;
1115 if ( nColId == BROWSER_INVALIDID )
1116 // invalidate the whole row
1117 aRect = Rectangle( Point( 0, (nRow-nTopRow) * GetDataRowHeight() ),
1118 Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
1119 else
1121 // invalidate the specific field
1122 aRect = GetFieldRectPixel( nRow, nColId, false );
1124 getDataWindow()->Invalidate( aRect );
1129 void BrowseBox::Clear()
1132 // adjust the total number of rows
1133 DoHideCursor( "Clear" );
1134 long nOldRowCount = nRowCount;
1135 nRowCount = 0;
1136 if(bMultiSelection)
1138 assert(uRow.pSel);
1139 *uRow.pSel = MultiSelection();
1141 else
1142 uRow.nSel = BROWSER_ENDOFSELECTION;
1143 nCurRow = BROWSER_ENDOFSELECTION;
1144 nTopRow = 0;
1145 nCurColId = 0;
1147 // nFirstCol may not be reset, else the scrolling code will become confused.
1148 // nFirstCol may only be changed when adding or deleting columns
1149 // nFirstCol = 0; -> wrong!
1150 aHScroll->SetThumbPos( 0 );
1151 pVScroll->SetThumbPos( 0 );
1153 Invalidate();
1154 UpdateScrollbars();
1155 SetNoSelection();
1156 DoShowCursor( "Clear" );
1157 CursorMoved();
1159 if ( isAccessibleAlive() )
1161 // all rows should be removed, so we remove the row header bar and append it again
1162 // to avoid to notify every row remove
1163 if ( nOldRowCount != nRowCount )
1165 commitBrowseBoxEvent(
1166 CHILD,
1167 Any(),
1168 makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) )
1171 // and now append it again
1172 commitBrowseBoxEvent(
1173 CHILD,
1174 makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) ),
1175 Any()
1178 // notify a table model change
1179 commitTableEvent(
1180 TABLE_MODEL_CHANGED,
1181 makeAny( AccessibleTableModelChange( DELETE,
1183 nOldRowCount,
1185 GetColumnCount())
1187 Any()
1193 void BrowseBox::RowInserted( long nRow, long nNumRows, bool bDoPaint, bool bKeepSelection )
1196 if (nRow < 0)
1197 nRow = 0;
1198 else if (nRow > nRowCount) // maximal = nRowCount
1199 nRow = nRowCount;
1201 if ( nNumRows <= 0 )
1202 return;
1204 // adjust total row count
1205 bool bLastRow = nRow >= nRowCount;
1206 nRowCount += nNumRows;
1208 DoHideCursor( "RowInserted" );
1210 // must we paint the new rows?
1211 long nOldCurRow = nCurRow;
1212 Size aSz = pDataWin->GetOutputSizePixel();
1213 if ( bDoPaint && nRow >= nTopRow &&
1214 nRow <= nTopRow + aSz.Height() / GetDataRowHeight() )
1216 long nY = (nRow-nTopRow) * GetDataRowHeight();
1217 if ( !bLastRow )
1219 // scroll down the rows behind the new row
1220 pDataWin->SetClipRegion();
1221 if( pDataWin->GetBackground().IsScrollable() )
1223 pDataWin->Scroll( 0, GetDataRowHeight() * nNumRows,
1224 Rectangle( Point( 0, nY ),
1225 Size( aSz.Width(), aSz.Height() - nY ) ),
1226 SCROLL_FLAGS );
1228 else
1229 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
1231 else
1232 // scroll would cause a repaint, so we must explicitly invalidate
1233 pDataWin->Invalidate( Rectangle( Point( 0, nY ),
1234 Size( aSz.Width(), nNumRows * GetDataRowHeight() ) ) );
1237 // correct top row if necessary
1238 if ( nRow < nTopRow )
1239 nTopRow += nNumRows;
1241 // adjust the selection
1242 if ( bMultiSelection )
1243 uRow.pSel->Insert( nRow, nNumRows );
1244 else if ( uRow.nSel != BROWSER_ENDOFSELECTION && nRow <= uRow.nSel )
1245 uRow.nSel += nNumRows;
1247 // adjust the cursor
1248 if ( nCurRow == BROWSER_ENDOFSELECTION )
1249 GoToRow( 0, false, bKeepSelection );
1250 else if ( nRow <= nCurRow )
1251 GoToRow( nCurRow += nNumRows, false, bKeepSelection );
1253 // adjust the vertical scrollbar
1254 if ( bDoPaint )
1256 UpdateScrollbars();
1257 AutoSizeLastColumn();
1260 DoShowCursor( "RowInserted" );
1261 // notify accessible that rows were inserted
1262 if ( isAccessibleAlive() )
1264 commitTableEvent(
1265 TABLE_MODEL_CHANGED,
1266 makeAny( AccessibleTableModelChange(
1267 INSERT,
1268 nRow,
1269 nRow + nNumRows,
1271 GetColumnCount()
1274 Any()
1277 for (sal_Int32 i = nRow+1 ; i <= nRowCount ; ++i)
1279 commitHeaderBarEvent(
1280 CHILD,
1281 makeAny( CreateAccessibleRowHeader( i ) ),
1282 Any(),
1283 false
1288 if ( nCurRow != nOldCurRow )
1289 CursorMoved();
1291 DBG_ASSERT(nRowCount > 0,"BrowseBox: nRowCount <= 0");
1292 DBG_ASSERT(nCurRow >= 0,"BrowseBox: nCurRow < 0");
1293 DBG_ASSERT(nCurRow < nRowCount,"nCurRow >= nRowCount");
1298 void BrowseBox::RowRemoved( long nRow, long nNumRows, bool bDoPaint )
1301 if ( nRow < 0 )
1302 nRow = 0;
1303 else if ( nRow >= nRowCount )
1304 nRow = nRowCount - 1;
1306 if ( nNumRows <= 0 )
1307 return;
1309 if ( nRowCount <= 0 )
1310 return;
1312 if ( bDoPaint )
1314 // hide cursor and selection
1315 OSL_TRACE( "BrowseBox: %p->HideCursor", this );
1316 ToggleSelection();
1317 DoHideCursor( "RowRemoved" );
1320 // adjust total row count
1321 nRowCount -= nNumRows;
1322 if (nRowCount < 0) nRowCount = 0;
1323 long nOldCurRow = nCurRow;
1325 // adjust the selection
1326 if ( bMultiSelection )
1327 // uRow.pSel->Remove( nRow, nNumRows );
1328 for ( long i = 0; i < nNumRows; i++ )
1329 uRow.pSel->Remove( nRow );
1330 else if ( nRow < uRow.nSel && uRow.nSel >= nNumRows )
1331 uRow.nSel -= nNumRows;
1332 else if ( nRow <= uRow.nSel )
1333 uRow.nSel = BROWSER_ENDOFSELECTION;
1335 // adjust the cursor
1336 if ( nRowCount == 0 ) // don't compare nRowCount with nNumRows as nNumRows already was subtracted from nRowCount
1337 nCurRow = BROWSER_ENDOFSELECTION;
1338 else if ( nRow < nCurRow )
1340 nCurRow -= std::min( nCurRow - nRow, nNumRows );
1341 // with the above nCurRow points a) to the first row after the removed block or b) to the same line
1342 // as before, but moved up nNumRows
1343 // case a) needs an additional correction if the last n lines were deleted, as 'the first row after the
1344 // removed block' is an invalid position then
1345 // FS - 09/28/99 - 68429
1346 if (nCurRow == nRowCount)
1347 --nCurRow;
1349 else if( nRow == nCurRow && nCurRow == nRowCount )
1350 nCurRow = nRowCount-1;
1352 // is the deleted row visible?
1353 Size aSz = pDataWin->GetOutputSizePixel();
1354 if ( nRow >= nTopRow &&
1355 nRow <= nTopRow + aSz.Height() / GetDataRowHeight() )
1357 if ( bDoPaint )
1359 // scroll up the rows behind the deleted row
1360 // if there are Rows behind
1361 if (nRow < nRowCount)
1363 long nY = (nRow-nTopRow) * GetDataRowHeight();
1364 pDataWin->SetClipRegion();
1365 if( pDataWin->GetBackground().IsScrollable() )
1367 pDataWin->Scroll( 0, - (short) GetDataRowHeight() * nNumRows,
1368 Rectangle( Point( 0, nY ), Size( aSz.Width(),
1369 aSz.Height() - nY + nNumRows*GetDataRowHeight() ) ),
1370 SCROLL_FLAGS );
1372 else
1373 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
1375 else
1377 // Repaint the Rect of the deleted row
1378 Rectangle aRect(
1379 Point( 0, (nRow-nTopRow)*GetDataRowHeight() ),
1380 Size( pDataWin->GetSizePixel().Width(),
1381 nNumRows * GetDataRowHeight() ) );
1382 pDataWin->Invalidate( aRect );
1386 // is the deleted row above of the visible area?
1387 else if ( nRow < nTopRow )
1388 nTopRow = nTopRow >= nNumRows ? nTopRow-nNumRows : 0;
1390 if ( bDoPaint )
1392 // reshow cursor and selection
1393 ToggleSelection();
1394 OSL_TRACE( "BrowseBox: %p->ShowCursor", this );
1395 DoShowCursor( "RowRemoved" );
1397 // adjust the vertical scrollbar
1398 UpdateScrollbars();
1399 AutoSizeLastColumn();
1402 if ( isAccessibleAlive() )
1404 if ( nRowCount == 0 )
1406 // all columns should be removed, so we remove the column header bar and append it again
1407 // to avoid to notify every column remove
1408 commitBrowseBoxEvent(
1409 CHILD,
1410 Any(),
1411 makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) )
1414 // and now append it again
1415 commitBrowseBoxEvent(
1416 CHILD,
1417 makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_ROWHEADERBAR)),
1418 Any()
1420 commitBrowseBoxEvent(
1421 CHILD,
1422 Any(),
1423 makeAny( m_pImpl->getAccessibleTable() )
1426 // and now append it again
1427 commitBrowseBoxEvent(
1428 CHILD,
1429 makeAny( m_pImpl->getAccessibleTable() ),
1430 Any()
1433 else
1435 commitTableEvent(
1436 TABLE_MODEL_CHANGED,
1437 makeAny( AccessibleTableModelChange(
1438 DELETE,
1439 nRow,
1440 nRow + nNumRows,
1442 GetColumnCount()
1445 Any()
1448 for (sal_Int32 i = nRow+1 ; i <= (nRow+nNumRows) ; ++i)
1450 commitHeaderBarEvent(
1451 CHILD,
1452 Any(),
1453 makeAny( CreateAccessibleRowHeader( i ) ),
1454 false
1460 if ( nOldCurRow != nCurRow )
1461 CursorMoved();
1463 DBG_ASSERT(nRowCount >= 0,"BrowseBox: nRowCount < 0");
1464 DBG_ASSERT(nCurRow >= 0 || nRowCount == 0,"BrowseBox: nCurRow < 0 && nRowCount != 0");
1465 DBG_ASSERT(nCurRow < nRowCount,"nCurRow >= nRowCount");
1470 bool BrowseBox::GoToRow( long nRow)
1472 return GoToRow(nRow, false, false);
1477 bool BrowseBox::GoToRow( long nRow, bool bRowColMove, bool bKeepSelection )
1480 long nOldCurRow = nCurRow;
1482 // nothing to do?
1483 if ( nRow == nCurRow && ( bMultiSelection || uRow.nSel == nRow ) )
1484 return true;
1486 // out of range?
1487 if ( nRow < 0 || nRow >= nRowCount )
1488 return false;
1490 // not allowed?
1491 if ( ( !bRowColMove && !IsCursorMoveAllowed( nRow, nCurColId ) ) )
1492 return false;
1494 if ( getDataWindow()->bNoScrollBack && nRow < nTopRow )
1495 nRow = nTopRow;
1497 // compute the last visible row
1498 Size aSz( pDataWin->GetSizePixel() );
1499 sal_uInt16 nVisibleRows = sal_uInt16( aSz.Height() / GetDataRowHeight() - 1 );
1500 long nLastRow = nTopRow + nVisibleRows;
1502 // suspend Updates
1503 getDataWindow()->EnterUpdateLock();
1505 // remove old highlight, if necessary
1506 if ( !bMultiSelection && !bKeepSelection )
1507 ToggleSelection();
1508 DoHideCursor( "GoToRow" );
1510 // must we scroll?
1511 bool bWasVisible = bSelectionIsVisible;
1512 if (! bMultiSelection)
1514 if( !bKeepSelection )
1515 bSelectionIsVisible = false;
1517 if ( nRow < nTopRow )
1518 ScrollRows( nRow - nTopRow );
1519 else if ( nRow > nLastRow )
1520 ScrollRows( nRow - nLastRow );
1521 bSelectionIsVisible = bWasVisible;
1523 // adjust cursor (selection) and thumb
1524 if ( GetUpdateMode() )
1525 pVScroll->SetThumbPos( nTopRow );
1527 // relative positioning (because nCurRow might have changed in the meantime)!
1528 if (nCurRow != BROWSER_ENDOFSELECTION )
1529 nCurRow = nCurRow + (nRow - nOldCurRow);
1531 // make sure that the current position is valid
1532 if (nCurRow == BROWSER_ENDOFSELECTION && nRowCount > 0)
1533 nCurRow = 0;
1534 else if ( nCurRow >= nRowCount )
1535 nCurRow = nRowCount - 1;
1536 aSelRange = Range( nCurRow, nCurRow );
1538 // display new highlight if necessary
1539 if ( !bMultiSelection && !bKeepSelection )
1540 uRow.nSel = nRow;
1542 // resume Updates
1543 getDataWindow()->LeaveUpdateLock();
1545 // Cursor+Highlight
1546 if ( !bMultiSelection && !bKeepSelection)
1547 ToggleSelection();
1548 DoShowCursor( "GoToRow" );
1549 if ( !bRowColMove && nOldCurRow != nCurRow )
1550 CursorMoved();
1552 if ( !bMultiSelection && !bKeepSelection )
1554 if ( !bSelecting )
1555 Select();
1556 else
1557 bSelect = true;
1559 return true;
1564 bool BrowseBox::GoToColumnId( sal_uInt16 nColId)
1566 return GoToColumnId(nColId, true, false);
1570 bool BrowseBox::GoToColumnId( sal_uInt16 nColId, bool bMakeVisible, bool bRowColMove)
1572 if (!bColumnCursor)
1573 return false;
1575 // allowed?
1576 if (!bRowColMove && !IsCursorMoveAllowed( nCurRow, nColId ) )
1577 return false;
1579 if ( nColId != nCurColId || (bMakeVisible && !IsFieldVisible(nCurRow, nColId, true)))
1581 sal_uInt16 nNewPos = GetColumnPos(nColId);
1582 BrowserColumn* pColumn = (nNewPos < pCols->size()) ? (*pCols)[ nNewPos ] : NULL;
1583 DBG_ASSERT( pColumn, "no column object - invalid id?" );
1584 if ( !pColumn )
1585 return false;
1587 DoHideCursor( "GoToColumnId" );
1588 nCurColId = nColId;
1590 bool bScrolled = false;
1592 sal_uInt16 nFirstPos = nFirstCol;
1593 sal_uInt16 nWidth = (sal_uInt16)pColumn->Width();
1594 sal_uInt16 nLastPos = GetColumnAtXPosPixel(
1595 pDataWin->GetSizePixel().Width()-nWidth, false );
1596 sal_uInt16 nFrozen = FrozenColCount();
1597 if ( bMakeVisible && nLastPos &&
1598 nNewPos >= nFrozen && ( nNewPos < nFirstPos || nNewPos > nLastPos ) )
1600 if ( nNewPos < nFirstPos )
1601 ScrollColumns( nNewPos-nFirstPos );
1602 else if ( nNewPos > nLastPos )
1603 ScrollColumns( nNewPos-nLastPos );
1604 bScrolled = true;
1607 DoShowCursor( "GoToColumnId" );
1608 if (!bRowColMove)
1610 //try to move to nCurRow, nColId
1611 CursorMoveAttempt aAttempt(nCurRow, nColId, bScrolled);
1612 //Detect if we are already in a call to BrowseBox::GoToColumnId
1613 //but the attempt is impossible and we are simply recursing
1614 //into BrowseBox::GoToColumnId with the same impossible to
1615 //fulfill conditions
1616 if (m_aGotoStack.empty() || aAttempt != m_aGotoStack.top())
1618 m_aGotoStack.push(aAttempt);
1619 CursorMoved();
1620 m_aGotoStack.pop();
1623 return true;
1625 return true;
1630 bool BrowseBox::GoToRowColumnId( long nRow, sal_uInt16 nColId )
1633 // out of range?
1634 if ( nRow < 0 || nRow >= nRowCount )
1635 return false;
1637 if (!bColumnCursor)
1638 return false;
1640 // nothing to do ?
1641 if ( nRow == nCurRow && ( bMultiSelection || uRow.nSel == nRow ) &&
1642 nColId == nCurColId && IsFieldVisible(nCurRow, nColId, true))
1643 return true;
1645 // allowed?
1646 if (!IsCursorMoveAllowed(nRow, nColId))
1647 return false;
1649 DoHideCursor( "GoToRowColumnId" );
1650 bool bMoved = GoToRow(nRow, true) && GoToColumnId(nColId, true, true);
1651 DoShowCursor( "GoToRowColumnId" );
1653 if (bMoved)
1654 CursorMoved();
1656 return bMoved;
1661 void BrowseBox::SetNoSelection()
1664 // is there no selection
1665 if ( ( !pColSel || !pColSel->GetSelectCount() ) &&
1666 ( ( !bMultiSelection && uRow.nSel == BROWSER_ENDOFSELECTION ) ||
1667 ( bMultiSelection && !uRow.pSel->GetSelectCount() ) ) )
1668 // nothing to do
1669 return;
1671 OSL_TRACE( "BrowseBox: %p->HideCursor", this );
1672 ToggleSelection();
1674 // unselect all
1675 if ( bMultiSelection )
1676 uRow.pSel->SelectAll(false);
1677 else
1678 uRow.nSel = BROWSER_ENDOFSELECTION;
1679 if ( pColSel )
1680 pColSel->SelectAll(false);
1681 if ( !bSelecting )
1682 Select();
1683 else
1684 bSelect = true;
1686 // restore screen
1687 OSL_TRACE( "BrowseBox: %p->ShowCursor", this );
1689 if ( isAccessibleAlive() )
1691 commitTableEvent(
1692 SELECTION_CHANGED,
1693 Any(),
1694 Any()
1701 void BrowseBox::SelectAll()
1704 if ( !bMultiSelection )
1705 return;
1707 OSL_TRACE( "BrowseBox: %p->HideCursor", this );
1708 ToggleSelection();
1710 // select all rows
1711 if ( pColSel )
1712 pColSel->SelectAll(false);
1713 uRow.pSel->SelectAll(true);
1715 // don't highlight handle column
1716 BrowserColumn *pFirstCol = (*pCols)[ 0 ];
1717 long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
1719 // highlight the row selection
1720 if ( !bHideSelect )
1722 Rectangle aHighlightRect;
1723 sal_uInt16 nVisibleRows =
1724 (sal_uInt16)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
1725 for ( long nRow = std::max( nTopRow, uRow.pSel->FirstSelected() );
1726 nRow != BROWSER_ENDOFSELECTION && nRow < nTopRow + nVisibleRows;
1727 nRow = uRow.pSel->NextSelected() )
1728 aHighlightRect.Union( Rectangle(
1729 Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
1730 Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) ) );
1731 pDataWin->Invalidate( aHighlightRect );
1734 if ( !bSelecting )
1735 Select();
1736 else
1737 bSelect = true;
1739 // restore screen
1740 OSL_TRACE( "BrowseBox: %p->ShowCursor", this );
1742 if ( isAccessibleAlive() )
1744 commitTableEvent(
1745 SELECTION_CHANGED,
1746 Any(),
1747 Any()
1749 commitHeaderBarEvent(
1750 SELECTION_CHANGED,
1751 Any(),
1752 Any(),
1753 true
1754 ); // column header event
1756 commitHeaderBarEvent(
1757 SELECTION_CHANGED,
1758 Any(),
1759 Any(),
1760 false
1761 ); // row header event
1767 void BrowseBox::SelectRow( long nRow, bool _bSelect, bool bExpand )
1770 if ( !bMultiSelection )
1772 // deselecting is impossible, selecting via cursor
1773 if ( _bSelect )
1774 GoToRow(nRow, false);
1775 return;
1778 OSL_TRACE( "BrowseBox: %p->HideCursor", this );
1780 // remove old selection?
1781 if ( !bExpand || !bMultiSelection )
1783 ToggleSelection();
1784 if ( bMultiSelection )
1785 uRow.pSel->SelectAll(false);
1786 else
1787 uRow.nSel = BROWSER_ENDOFSELECTION;
1788 if ( pColSel )
1789 pColSel->SelectAll(false);
1792 // set new selection
1793 if ( !bHideSelect
1794 && ( ( bMultiSelection
1795 && uRow.pSel->GetTotalRange().Max() >= nRow
1796 && uRow.pSel->Select( nRow, _bSelect )
1798 || ( !bMultiSelection
1799 && ( uRow.nSel = nRow ) != BROWSER_ENDOFSELECTION )
1803 // don't highlight handle column
1804 BrowserColumn *pFirstCol = (*pCols)[ 0 ];
1805 long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
1807 // highlight only newly selected part
1808 Rectangle aRect(
1809 Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
1810 Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
1811 pDataWin->Invalidate( aRect );
1814 if ( !bSelecting )
1815 Select();
1816 else
1817 bSelect = true;
1819 // restore screen
1820 OSL_TRACE( "BrowseBox: %p->ShowCursor", this );
1822 if ( isAccessibleAlive() )
1824 commitTableEvent(
1825 SELECTION_CHANGED,
1826 Any(),
1827 Any()
1829 commitHeaderBarEvent(
1830 SELECTION_CHANGED,
1831 Any(),
1832 Any(),
1833 false
1834 ); // row header event
1840 long BrowseBox::GetSelectRowCount() const
1843 return bMultiSelection ? uRow.pSel->GetSelectCount() :
1844 uRow.nSel == BROWSER_ENDOFSELECTION ? 0 : 1;
1849 void BrowseBox::SelectColumnPos( sal_uInt16 nNewColPos, bool _bSelect, bool bMakeVisible )
1852 if ( !bColumnCursor || nNewColPos == BROWSER_INVALIDID )
1853 return;
1855 if ( !bMultiSelection )
1857 if ( _bSelect )
1858 GoToColumnId( (*pCols)[ nNewColPos ]->GetId(), bMakeVisible );
1859 return;
1861 else
1863 if ( !GoToColumnId( (*pCols)[ nNewColPos ]->GetId(), bMakeVisible ) )
1864 return;
1867 OSL_TRACE( "BrowseBox: %p->HideCursor", this );
1868 ToggleSelection();
1869 if ( bMultiSelection )
1870 uRow.pSel->SelectAll(false);
1871 else
1872 uRow.nSel = BROWSER_ENDOFSELECTION;
1873 pColSel->SelectAll(false);
1875 if ( pColSel->Select( nNewColPos, _bSelect ) )
1877 // GoToColumnId( pCols->GetObject(nNewColPos)->GetId(), bMakeVisible );
1879 // only highlight painted areas
1880 pDataWin->Update();
1881 Rectangle aFieldRectPix( GetFieldRectPixel( nCurRow, nCurColId, false ) );
1882 Rectangle aRect(
1883 Point( aFieldRectPix.Left() - MIN_COLUMNWIDTH, 0 ),
1884 Size( (*pCols)[ nNewColPos ]->Width(),
1885 pDataWin->GetOutputSizePixel().Height() ) );
1886 pDataWin->Invalidate( aRect );
1887 if ( !bSelecting )
1888 Select();
1889 else
1890 bSelect = true;
1892 if ( isAccessibleAlive() )
1894 commitTableEvent(
1895 SELECTION_CHANGED,
1896 Any(),
1897 Any()
1899 commitHeaderBarEvent(
1900 SELECTION_CHANGED,
1901 Any(),
1902 Any(),
1903 true
1904 ); // column header event
1908 // restore screen
1909 OSL_TRACE( "BrowseBox: %p->ShowCursor", this );
1914 sal_uInt16 BrowseBox::GetSelectColumnCount() const
1917 // while bAutoSelect (==!pColSel), 1 if any rows (yes rows!) else none
1918 return pColSel ? (sal_uInt16) pColSel->GetSelectCount() :
1919 nCurRow >= 0 ? 1 : 0;
1923 long BrowseBox::FirstSelectedColumn( ) const
1925 return pColSel ? pColSel->FirstSelected() : BROWSER_ENDOFSELECTION;
1930 long BrowseBox::FirstSelectedRow( bool bInverse )
1933 return bMultiSelection ? uRow.pSel->FirstSelected(bInverse) : uRow.nSel;
1938 long BrowseBox::NextSelectedRow()
1941 return bMultiSelection ? uRow.pSel->NextSelected() : BROWSER_ENDOFSELECTION;
1946 long BrowseBox::LastSelectedRow()
1949 return bMultiSelection ? uRow.pSel->LastSelected() : uRow.nSel;
1954 bool BrowseBox::IsRowSelected( long nRow ) const
1957 return bMultiSelection ? uRow.pSel->IsSelected(nRow) : nRow == uRow.nSel;
1962 bool BrowseBox::IsColumnSelected( sal_uInt16 nColumnId ) const
1965 return pColSel ? pColSel->IsSelected( GetColumnPos(nColumnId) ) :
1966 nCurColId == nColumnId;
1971 bool BrowseBox::MakeFieldVisible
1973 long nRow, // line number of the field (starting with 0)
1974 sal_uInt16 nColId, // column ID of the field
1975 bool bComplete // (== false), true => make visible in its entirety
1978 /* [Description]
1980 Makes visible the field described in 'nRow' and 'nColId' by scrolling
1981 accordingly. If 'bComplete' is set, the field should become visible in its
1982 entirety.
1984 [Returned Value]
1986 bool true
1987 The given field is already visible or was already visible.
1989 false
1990 The given field could not be made visible or in the case of
1991 'bComplete' could not be made visible in its entirety.
1995 Size aTestSize = pDataWin->GetSizePixel();
1997 if ( !bBootstrapped ||
1998 ( aTestSize.Width() == 0 && aTestSize.Height() == 0 ) )
1999 return false;
2001 // is it visible already?
2002 bool bVisible = IsFieldVisible( nRow, nColId, bComplete );
2003 if ( bVisible )
2004 return true;
2006 // calculate column position, field rectangle and painting area
2007 sal_uInt16 nColPos = GetColumnPos( nColId );
2008 Rectangle aFieldRect = GetFieldRectPixel( nRow, nColId, false );
2009 Rectangle aDataRect = Rectangle( Point(0, 0), pDataWin->GetSizePixel() );
2011 // positioned outside on the left?
2012 if ( nColPos >= FrozenColCount() && nColPos < nFirstCol )
2013 // => scroll to the right
2014 ScrollColumns( nColPos - nFirstCol );
2016 // while outside on the right
2017 while ( aDataRect.Right() < ( bComplete
2018 ? aFieldRect.Right()
2019 : aFieldRect.Left()+aFieldRect.GetWidth()/2 ) )
2021 // => scroll to the left
2022 if ( ScrollColumns( 1 ) != 1 )
2023 // no more need to scroll
2024 break;
2025 aFieldRect = GetFieldRectPixel( nRow, nColId, false );
2028 // positioned outside above?
2029 if ( nRow < nTopRow )
2030 // scroll further to the bottom
2031 ScrollRows( nRow - nTopRow );
2033 // positioned outside below?
2034 long nBottomRow = nTopRow + GetVisibleRows();
2035 // decrement nBottomRow to make it the number of the last visible line
2036 // (count starts with 0!).
2037 // Example: BrowseBox contains exactly one entry. nBottomRow := 0 + 1 - 1
2038 if( nBottomRow )
2039 nBottomRow--;
2041 if ( nRow > nBottomRow )
2042 // scroll further to the top
2043 ScrollRows( nRow - nBottomRow );
2045 // it might still not actually fit, e.g. if the window is too small
2046 return IsFieldVisible( nRow, nColId, bComplete );
2051 bool BrowseBox::IsFieldVisible( long nRow, sal_uInt16 nColumnId,
2052 bool bCompletely ) const
2055 // hidden by frozen column?
2056 sal_uInt16 nColPos = GetColumnPos( nColumnId );
2057 if ( nColPos >= FrozenColCount() && nColPos < nFirstCol )
2058 return false;
2060 Rectangle aRect( ImplFieldRectPixel( nRow, nColumnId ) );
2061 if ( aRect.IsEmpty() )
2062 return false;
2064 // get the visible area
2065 Rectangle aOutRect( Point(0, 0), pDataWin->GetOutputSizePixel() );
2067 if ( bCompletely )
2068 // test if the field is completely visible
2069 return aOutRect.IsInside( aRect );
2070 else
2071 // test if the field is partly of completely visible
2072 return !aOutRect.Intersection( aRect ).IsEmpty();
2077 Rectangle BrowseBox::GetFieldRectPixel( long nRow, sal_uInt16 nColumnId,
2078 bool bRelToBrowser) const
2081 // get the rectangle relative to DataWin
2082 Rectangle aRect( ImplFieldRectPixel( nRow, nColumnId ) );
2083 if ( aRect.IsEmpty() )
2084 return aRect;
2086 // adjust relative to BrowseBox's output area
2087 Point aTopLeft( aRect.TopLeft() );
2088 if ( bRelToBrowser )
2090 aTopLeft = pDataWin->OutputToScreenPixel( aTopLeft );
2091 aTopLeft = ScreenToOutputPixel( aTopLeft );
2094 return Rectangle( aTopLeft, aRect.GetSize() );
2099 Rectangle BrowseBox::GetRowRectPixel( long nRow, bool bRelToBrowser ) const
2102 // get the rectangle relative to DataWin
2103 Rectangle aRect;
2104 if ( nTopRow > nRow )
2105 // row is above visible area
2106 return aRect;
2107 aRect = Rectangle(
2108 Point( 0, GetDataRowHeight() * (nRow-nTopRow) ),
2109 Size( pDataWin->GetOutputSizePixel().Width(), GetDataRowHeight() ) );
2110 if ( aRect.TopLeft().Y() > pDataWin->GetOutputSizePixel().Height() )
2111 // row is below visible area
2112 return aRect;
2114 // adjust relative to BrowseBox's output area
2115 Point aTopLeft( aRect.TopLeft() );
2116 if ( bRelToBrowser )
2118 aTopLeft = pDataWin->OutputToScreenPixel( aTopLeft );
2119 aTopLeft = ScreenToOutputPixel( aTopLeft );
2122 return Rectangle( aTopLeft, aRect.GetSize() );
2127 Rectangle BrowseBox::ImplFieldRectPixel( long nRow, sal_uInt16 nColumnId ) const
2130 // compute the X-coordinate relative to DataWin by accumulation
2131 long nColX = 0;
2132 sal_uInt16 nFrozenCols = FrozenColCount();
2133 size_t nCol;
2134 for ( nCol = 0;
2135 nCol < pCols->size() && (*pCols)[ nCol ]->GetId() != nColumnId;
2136 ++nCol )
2137 if ( (*pCols)[ nCol ]->IsFrozen() || nCol >= nFirstCol )
2138 nColX += (*pCols)[ nCol ]->Width();
2140 if ( nCol >= pCols->size() || ( nCol >= nFrozenCols && nCol < nFirstCol ) )
2141 return Rectangle();
2143 // compute the Y-coordinate relative to DataWin
2144 long nRowY = GetDataRowHeight();
2145 if ( nRow != BROWSER_ENDOFSELECTION ) // #105497# OJ
2146 nRowY = ( nRow - nTopRow ) * GetDataRowHeight();
2148 // assemble the Rectangle relative to DataWin
2149 return Rectangle(
2150 Point( nColX + MIN_COLUMNWIDTH, nRowY ),
2151 Size( (*pCols)[ nCol ]->Width() - 2*MIN_COLUMNWIDTH,
2152 GetDataRowHeight() - 1 ) );
2157 long BrowseBox::GetRowAtYPosPixel( long nY, bool bRelToBrowser ) const
2160 // compute the Y-coordinate
2161 if ( bRelToBrowser )
2163 Point aDataTopLeft = pDataWin->OutputToScreenPixel( Point(0, 0) );
2164 Point aTopLeft = OutputToScreenPixel( Point(0, 0) );
2165 nY -= aDataTopLeft.Y() - aTopLeft.Y();
2168 // no row there (e.g. in the header)
2169 if ( nY < 0 || nY >= pDataWin->GetOutputSizePixel().Height() )
2170 return -1;
2172 return nY / GetDataRowHeight() + nTopRow;
2177 Rectangle BrowseBox::GetFieldRect( sal_uInt16 nColumnId ) const
2180 return GetFieldRectPixel( nCurRow, nColumnId );
2185 sal_uInt16 BrowseBox::GetColumnAtXPosPixel( long nX, bool ) const
2188 // accumulate the widths of the visible columns
2189 long nColX = 0;
2190 for ( size_t nCol = 0; nCol < pCols->size(); ++nCol )
2192 BrowserColumn *pCol = (*pCols)[ nCol ];
2193 if ( pCol->IsFrozen() || nCol >= nFirstCol )
2194 nColX += pCol->Width();
2196 if ( nColX > nX )
2197 return nCol;
2200 return BROWSER_INVALIDID;
2205 void BrowseBox::ReserveControlArea( sal_uInt16 nWidth )
2208 if ( nWidth != nControlAreaWidth )
2210 OSL_ENSURE(nWidth,"Control area of 0 is not allowed, Use USHRT_MAX instead!");
2211 nControlAreaWidth = nWidth;
2212 UpdateScrollbars();
2218 Rectangle BrowseBox::GetControlArea() const
2221 return Rectangle(
2222 Point( 0, GetOutputSizePixel().Height() - aHScroll->GetSizePixel().Height() ),
2223 Size( GetOutputSizePixel().Width() - aHScroll->GetSizePixel().Width(),
2224 aHScroll->GetSizePixel().Height() ) );
2229 void BrowseBox::SetMode( BrowserMode nMode )
2232 getDataWindow()->bAutoHScroll = BrowserMode::AUTO_HSCROLL == ( nMode & BrowserMode::AUTO_HSCROLL );
2233 getDataWindow()->bAutoVScroll = BrowserMode::AUTO_VSCROLL == ( nMode & BrowserMode::AUTO_VSCROLL );
2234 getDataWindow()->bNoHScroll = BrowserMode::NO_HSCROLL == ( nMode & BrowserMode::NO_HSCROLL );
2235 getDataWindow()->bNoVScroll = BrowserMode::NO_VSCROLL == ( nMode & BrowserMode::NO_VSCROLL );
2237 DBG_ASSERT( !( getDataWindow()->bAutoHScroll && getDataWindow()->bNoHScroll ),
2238 "BrowseBox::SetMode: AutoHScroll *and* NoHScroll?" );
2239 DBG_ASSERT( !( getDataWindow()->bAutoVScroll && getDataWindow()->bNoVScroll ),
2240 "BrowseBox::SetMode: AutoVScroll *and* NoVScroll?" );
2241 if ( getDataWindow()->bAutoHScroll )
2242 getDataWindow()->bNoHScroll = false;
2243 if ( getDataWindow()->bAutoVScroll )
2244 getDataWindow()->bNoVScroll = false;
2246 if ( getDataWindow()->bNoHScroll )
2247 aHScroll->Hide();
2249 nControlAreaWidth = USHRT_MAX;
2251 getDataWindow()->bNoScrollBack =
2252 BrowserMode::NO_SCROLLBACK == ( nMode & BrowserMode::NO_SCROLLBACK);
2254 long nOldRowSel = bMultiSelection ? uRow.pSel->FirstSelected() : uRow.nSel;
2255 MultiSelection *pOldRowSel = bMultiSelection ? uRow.pSel : 0;
2256 MultiSelection *pOldColSel = pColSel;
2258 pVScroll.disposeAndClear();
2260 bThumbDragging = ( nMode & BrowserMode::THUMBDRAGGING ) == BrowserMode::THUMBDRAGGING;
2261 bMultiSelection = ( nMode & BrowserMode::MULTISELECTION ) == BrowserMode::MULTISELECTION;
2262 bColumnCursor = ( nMode & BrowserMode::COLUMNSELECTION ) == BrowserMode::COLUMNSELECTION;
2263 bKeepHighlight = ( nMode & BrowserMode::KEEPHIGHLIGHT ) == BrowserMode::KEEPHIGHLIGHT;
2265 bHideSelect = ((nMode & BrowserMode::HIDESELECT) == BrowserMode::HIDESELECT);
2266 // default: do not hide the cursor at all (untaken scrolling and such)
2267 bHideCursor = TRISTATE_FALSE;
2269 if ( BrowserMode::SMART_HIDECURSOR == ( nMode & BrowserMode::SMART_HIDECURSOR ) )
2270 { // smart cursor hide overrules hard cursor hide
2271 bHideCursor = TRISTATE_INDET;
2273 else if ( BrowserMode::HIDECURSOR == ( nMode & BrowserMode::HIDECURSOR ) )
2275 bHideCursor = TRISTATE_TRUE;
2278 m_bFocusOnlyCursor = ((nMode & BrowserMode::CURSOR_WO_FOCUS) == BrowserMode::NONE);
2280 bHLines = ( nMode & BrowserMode::HLINES ) == BrowserMode::HLINES;
2281 bVLines = ( nMode & BrowserMode::VLINES ) == BrowserMode::VLINES;
2283 WinBits nVScrollWinBits =
2284 WB_VSCROLL | ( ( nMode & BrowserMode::THUMBDRAGGING ) ? WB_DRAG : 0 );
2285 pVScroll = VclPtr<ScrollBar>(
2286 ( nMode & BrowserMode::TRACKING_TIPS ) == BrowserMode::TRACKING_TIPS
2287 ? VclPtr<BrowserScrollBar>::Create( this, nVScrollWinBits,
2288 static_cast<BrowserDataWin*>( pDataWin.get() ) )
2289 : VclPtr<ScrollBar>::Create( this, nVScrollWinBits ));
2290 pVScroll->SetLineSize( 1 );
2291 pVScroll->SetPageSize(1);
2292 pVScroll->SetScrollHdl( LINK( this, BrowseBox, ScrollHdl ) );
2293 pVScroll->SetEndScrollHdl( LINK( this, BrowseBox, EndScrollHdl ) );
2295 getDataWindow()->bAutoSizeLastCol =
2296 BrowserMode::AUTOSIZE_LASTCOL == ( nMode & BrowserMode::AUTOSIZE_LASTCOL );
2297 getDataWindow()->bOwnDataChangedHdl =
2298 BrowserMode::OWN_DATACHANGED == ( nMode & BrowserMode::OWN_DATACHANGED );
2300 // create a headerbar. what happens, if a headerbar has to be created and
2301 // there already are columns?
2302 if ( BrowserMode::HEADERBAR_NEW == ( nMode & BrowserMode::HEADERBAR_NEW ) )
2304 if (!getDataWindow()->pHeaderBar)
2305 getDataWindow()->pHeaderBar = CreateHeaderBar( this );
2307 else
2309 getDataWindow()->pHeaderBar.disposeAndClear();
2312 if ( bColumnCursor )
2314 pColSel = pOldColSel ? pOldColSel : new MultiSelection;
2315 pColSel->SetTotalRange( Range( 0, pCols->size()-1 ) );
2317 else
2319 delete pColSel;
2320 pColSel = 0;
2323 if ( bMultiSelection )
2325 if ( pOldRowSel )
2326 uRow.pSel = pOldRowSel;
2327 else
2328 uRow.pSel = new MultiSelection;
2330 else
2332 uRow.nSel = nOldRowSel;
2333 delete pOldRowSel;
2336 if ( bBootstrapped )
2338 StateChanged( StateChangedType::InitShow );
2339 if ( bMultiSelection && !pOldRowSel &&
2340 nOldRowSel != BROWSER_ENDOFSELECTION )
2341 uRow.pSel->Select( nOldRowSel );
2344 if ( pDataWin )
2345 pDataWin->Invalidate();
2347 // no cursor on handle column
2348 if ( nCurColId == HandleColumnId )
2349 nCurColId = GetColumnId( 1 );
2351 m_nCurrentMode = nMode;
2356 void BrowseBox::VisibleRowsChanged( long, sal_uInt16 )
2359 // old behavior: automatically correct NumRows:
2360 if ( nRowCount < GetRowCount() )
2362 RowInserted(nRowCount,GetRowCount() - nRowCount, false);
2364 else if ( nRowCount > GetRowCount() )
2366 RowRemoved(nRowCount-(nRowCount - GetRowCount()),nRowCount - GetRowCount(), false);
2372 bool BrowseBox::IsCursorMoveAllowed( long, sal_uInt16 ) const
2374 /* [Description]
2376 This virtual method is always called before the cursor is moved directly.
2377 By means of 'return sal_False', we avoid doing this if e.g. a record
2378 contradicts any rules.
2380 This method is not called, if the cursor movement results from removing or
2381 deleting a row/column (thus, in cases where only a "cursor correction" happens).
2383 The base implementation currently always returns true.
2387 return true;
2392 long BrowseBox::GetDataRowHeight() const
2394 return CalcZoom(nDataRowHeight ? nDataRowHeight : ImpGetDataRowHeight());
2399 VclPtr<BrowserHeader> BrowseBox::CreateHeaderBar( BrowseBox* pParent )
2401 VclPtr<BrowserHeader> pNewBar = VclPtr<BrowserHeader>::Create( pParent );
2402 pNewBar->SetStartDragHdl( LINK( this, BrowseBox, StartDragHdl ) );
2403 return pNewBar;
2406 void BrowseBox::SetHeaderBar( BrowserHeader* pHeaderBar )
2408 static_cast<BrowserDataWin*>( pDataWin.get() )->pHeaderBar.disposeAndClear();
2409 static_cast<BrowserDataWin*>( pDataWin.get() )->pHeaderBar = pHeaderBar;
2410 static_cast<BrowserDataWin*>( pDataWin.get() )->pHeaderBar->SetStartDragHdl( LINK( this, BrowseBox, StartDragHdl ) );
2413 long BrowseBox::GetTitleHeight() const
2415 long nHeight;
2416 // ask the header bar for the text height (if possible), as the header bar's font is adjusted with
2417 // our (and the header's) zoom factor
2418 HeaderBar* pHeaderBar = static_cast<BrowserDataWin*>( pDataWin.get() )->pHeaderBar;
2419 if ( pHeaderBar )
2420 nHeight = pHeaderBar->GetTextHeight();
2421 else
2422 nHeight = GetTextHeight();
2424 return nTitleLines ? nTitleLines * nHeight + 4 : 0;
2427 long BrowseBox::CalcReverseZoom(long nVal)
2429 if (IsZoom())
2431 const Fraction& rZoom = GetZoom();
2432 double n = (double)nVal;
2433 n *= (double)rZoom.GetDenominator();
2434 if (!rZoom.GetNumerator())
2435 throw o3tl::divide_by_zero();
2436 n /= (double)rZoom.GetNumerator();
2437 nVal = n>0 ? (long)(n + 0.5) : -(long)(-n + 0.5);
2440 return nVal;
2443 void BrowseBox::CursorMoved()
2445 // before implementing more here, please adjust the EditBrowseBox
2447 if ( isAccessibleAlive() && HasFocus() )
2448 commitTableEvent(
2449 ACTIVE_DESCENDANT_CHANGED,
2450 makeAny( CreateAccessibleCell( GetCurRow(),GetColumnPos( GetCurColumnId() ) ) ),
2451 Any()
2455 void BrowseBox::LoseFocus()
2457 OSL_TRACE( "BrowseBox: %p->LoseFocus", this );
2459 if ( bHasFocus )
2461 OSL_TRACE( "BrowseBox: %p->HideCursor", this );
2462 DoHideCursor( "LoseFocus" );
2464 if ( !bKeepHighlight )
2466 ToggleSelection();
2467 bSelectionIsVisible = false;
2470 bHasFocus = false;
2472 Control::LoseFocus();
2477 void BrowseBox::GetFocus()
2479 OSL_TRACE( "BrowseBox: %p->GetFocus", this );
2481 if ( !bHasFocus )
2483 if ( !bSelectionIsVisible )
2485 bSelectionIsVisible = true;
2486 if ( bBootstrapped )
2487 ToggleSelection();
2490 bHasFocus = true;
2491 DoShowCursor( "GetFocus" );
2493 Control::GetFocus();
2497 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */