diff options
author | Frank Schoenheit [fs] <frank.schoenheit@oracle.com> | 2011-01-19 11:11:29 +0100 |
---|---|---|
committer | Frank Schoenheit [fs] <frank.schoenheit@oracle.com> | 2011-01-19 11:11:29 +0100 |
commit | e8f649b5ad64a2a3f07dfab1a52033d126da211b (patch) | |
tree | 9015cddba0832bf60328d0f804150c1373f40253 /svtools | |
parent | 37b53c32ec5320838721ee209d259f41427f8335 (diff) |
gridsort: render indicator for current column sort
Diffstat (limited to 'svtools')
-rw-r--r-- | svtools/inc/svtools/table/tablecontrolinterface.hxx | 13 | ||||
-rw-r--r-- | svtools/source/table/gridtablerenderer.cxx | 98 | ||||
-rwxr-xr-x | svtools/source/table/mousefunction.cxx | 2 | ||||
-rw-r--r-- | svtools/source/table/tablecontrol.cxx | 2 | ||||
-rwxr-xr-x | svtools/source/table/tablecontrol_impl.cxx | 87 | ||||
-rwxr-xr-x | svtools/source/table/tablecontrol_impl.hxx | 6 | ||||
-rw-r--r-- | svtools/source/uno/svtxgridcontrol.cxx | 19 |
7 files changed, 175 insertions, 52 deletions
diff --git a/svtools/inc/svtools/table/tablecontrolinterface.hxx b/svtools/inc/svtools/table/tablecontrolinterface.hxx index 6ff2b07e84ed..74e9688d01db 100644 --- a/svtools/inc/svtools/table/tablecontrolinterface.hxx +++ b/svtools/inc/svtools/table/tablecontrolinterface.hxx @@ -147,6 +147,17 @@ namespace svt { namespace table }; //================================================================================================================== + //= TableArea + //================================================================================================================== + enum TableArea + { + TableAreaColumnHeaders, + TableAreaRowHeaders, + TableAreaDataArea, + TableAreaAll + }; + + //================================================================================================================== //= ITableControl //================================================================================================================== /** defines a callback interface to be implemented by a concrete table control @@ -213,7 +224,7 @@ namespace svt { namespace table virtual void releaseMouse() = 0; /// invalidates the table window - virtual void invalidate() = 0; + virtual void invalidate( TableArea const i_what ) = 0; /// calculates a width, given in pixels, into a AppFont-based width virtual long pixelWidthToAppFont( long const i_pixels ) const = 0; diff --git a/svtools/source/table/gridtablerenderer.cxx b/svtools/source/table/gridtablerenderer.cxx index 5fa7e0ab6f8d..91f78ff7fbc5 100644 --- a/svtools/source/table/gridtablerenderer.cxx +++ b/svtools/source/table/gridtablerenderer.cxx @@ -39,6 +39,8 @@ #include <tools/diagnose_ex.h> #include <vcl/window.hxx> #include <vcl/image.hxx> +#include <vcl/virdev.hxx> +#include <vcl/decoview.hxx> //...................................................................................................................... namespace svt { namespace table @@ -60,11 +62,65 @@ namespace svt { namespace table using ::com::sun::star::style::VerticalAlignment_BOTTOM; /** === end UNO using === **/ + //================================================================================================================== + //= CachedSortIndicator + //================================================================================================================== + class CachedSortIndicator + { + public: + CachedSortIndicator() + :m_lastHeaderHeight( 0 ) + ,m_lastArrowColor( COL_TRANSPARENT ) + { + } + + BitmapEx const & getBitmapFor( OutputDevice const & i_device, long const i_headerHeight, StyleSettings const & i_style, bool const i_sortAscending ); + + private: + long m_lastHeaderHeight; + Color m_lastArrowColor; + BitmapEx m_sortAscending; + BitmapEx m_sortDescending; + }; + + //------------------------------------------------------------------------------------------------------------------ + BitmapEx const & CachedSortIndicator::getBitmapFor( OutputDevice const & i_device, long const i_headerHeight, + StyleSettings const & i_style, bool const i_sortAscending ) + { + BitmapEx & rBitmap( i_sortAscending ? m_sortAscending : m_sortDescending ); + if ( !rBitmap || ( i_headerHeight != m_lastHeaderHeight ) || ( i_style.GetActiveColor() != m_lastArrowColor ) ) + { + long const nSortIndicatorWidth = 2 * i_headerHeight / 3; + long const nSortIndicatorHeight = 2 * nSortIndicatorWidth / 3; + + Point const aBitmapPos( 0, 0 ); + Size const aBitmapSize( nSortIndicatorWidth, nSortIndicatorHeight ); + VirtualDevice aDevice( i_device, 0, 0 ); + aDevice.SetOutputSizePixel( aBitmapSize ); + + DecorationView aDecoView( &aDevice ); + aDecoView.DrawSymbol( + Rectangle( aBitmapPos, aBitmapSize ), + i_sortAscending ? SYMBOL_SPIN_DOWN : SYMBOL_SPIN_UP, + i_style.GetActiveColor() + ); + + rBitmap = aDevice.GetBitmapEx( aBitmapPos, aBitmapSize ); + m_lastHeaderHeight = i_headerHeight; + m_lastArrowColor = i_style.GetActiveColor(); + } + return rBitmap; + } + + //================================================================================================================== + //= GridTableRenderer_Impl + //================================================================================================================== struct GridTableRenderer_Impl { - ITableModel& rModel; - RowPos nCurrentRow; - bool bUseGridLines; + ITableModel& rModel; + RowPos nCurrentRow; + bool bUseGridLines; + CachedSortIndicator aSortIndicator; GridTableRenderer_Impl( ITableModel& _rModel ) :rModel( _rModel ) @@ -73,6 +129,10 @@ namespace svt { namespace table { } }; + + //================================================================================================================== + //= helper + //================================================================================================================== namespace { static Rectangle lcl_getContentArea( GridTableRenderer_Impl const & i_impl, Rectangle const & i_cellArea ) @@ -220,6 +280,38 @@ namespace svt { namespace table _rDevice.DrawLine( _rArea.BottomRight(), _rArea.TopRight()); _rDevice.DrawLine( _rArea.BottomLeft(), _rArea.BottomRight() ); + // draw sort indicator if the model data is sorted by the given column + ITableDataSort const * pSortAdapter = m_pImpl->rModel.getSortAdapter(); + ColumnSort aCurrentSortOrder; + if ( pSortAdapter != NULL ) + aCurrentSortOrder = pSortAdapter->getCurrentSortOrder(); + if ( aCurrentSortOrder.nColumnPos == _nCol ) + { + long const nHeaderHeight( _rArea.GetHeight() ); + BitmapEx const aIndicatorBitmap = m_pImpl->aSortIndicator.getBitmapFor( _rDevice, nHeaderHeight, _rStyle, + aCurrentSortOrder.eSortDirection == ColumnSortAscending ); + Size const aBitmapSize( aIndicatorBitmap.GetSizePixel() ); + long const nSortIndicatorPaddingX = 2; + long const nSortIndicatorPaddingY = ( nHeaderHeight - aBitmapSize.Height() ) / 2; + + if ( ( nDrawTextFlags & TEXT_DRAW_RIGHT ) != 0 ) + { + // text is right aligned => draw the sort indicator at the left hand side + _rDevice.DrawBitmapEx( + Point( nSortIndicatorPaddingX, nSortIndicatorPaddingY ), + aIndicatorBitmap + ); + } + else + { + // text is left-aligned or centered => draw the sort indicator at the right hand side + _rDevice.DrawBitmapEx( + Point( _rArea.Right() - nSortIndicatorPaddingX - aBitmapSize.Width(), nSortIndicatorPaddingY ), + aIndicatorBitmap + ); + } + } + _rDevice.Pop(); (void)_bActive; diff --git a/svtools/source/table/mousefunction.cxx b/svtools/source/table/mousefunction.cxx index e3a47057423f..6d37e35b7a4c 100755 --- a/svtools/source/table/mousefunction.cxx +++ b/svtools/source/table/mousefunction.cxx @@ -178,7 +178,7 @@ namespace svt { namespace table requestedWidthLogical = maxWidthLogical; } pColumn->setWidth( requestedWidthLogical ); - i_tableControl.invalidate(); + i_tableControl.invalidate( TableAreaAll ); } i_tableControl.setPointer( Pointer() ); diff --git a/svtools/source/table/tablecontrol.cxx b/svtools/source/table/tablecontrol.cxx index c448af323b8b..448da7c9395b 100644 --- a/svtools/source/table/tablecontrol.cxx +++ b/svtools/source/table/tablecontrol.cxx @@ -564,7 +564,7 @@ namespace svt { namespace table Rectangle TableControl::calcHeaderRect(sal_Bool _bIsColumnBar,BOOL _bOnScreen) { (void)_bOnScreen; - return m_pImpl->calcHeaderRect(_bIsColumnBar); + return m_pImpl->calcHeaderRect( _bIsColumnBar ? false : true ); } //------------------------------------------------------------------------------------------------------------------ diff --git a/svtools/source/table/tablecontrol_impl.cxx b/svtools/source/table/tablecontrol_impl.cxx index e085fc45a990..53ff00756d98 100755 --- a/svtools/source/table/tablecontrol_impl.cxx +++ b/svtools/source/table/tablecontrol_impl.cxx @@ -693,8 +693,7 @@ namespace svt { namespace table { DBG_CHECK_ME(); - Rectangle aAllCellsArea; - impl_getAllVisibleCellsArea( aAllCellsArea ); + Rectangle const aAllCellsArea( impl_getAllVisibleCellsArea() ); const TableColumnGeometry aColumn( *this, aAllCellsArea, i_column ); if ( aColumn.isValid() ) @@ -727,16 +726,15 @@ namespace svt { namespace table } //------------------------------------------------------------------------------------------------------------------ - void TableControl_Impl::impl_getAllVisibleCellsArea( Rectangle& _rCellArea ) const + Rectangle TableControl_Impl::impl_getAllVisibleCellsArea() const { DBG_CHECK_ME(); - _rCellArea.Left() = 0; - _rCellArea.Top() = 0; + Rectangle aArea( Point( 0, 0 ), Size( 0, 0 ) ); // determine the right-most border of the last column which is // at least partially visible - _rCellArea.Right() = m_nRowHeaderWidthPixel; + aArea.Right() = m_nRowHeaderWidthPixel; if ( !m_aColumnWidths.empty() ) { // the number of pixels which are scrolled out of the left hand @@ -746,31 +744,34 @@ namespace svt { namespace table ColumnPositions::const_reverse_iterator loop = m_aColumnWidths.rbegin(); do { - _rCellArea.Right() = loop->getEnd() - nScrolledOutLeft + m_nRowHeaderWidthPixel; + aArea.Right() = loop->getEnd() - nScrolledOutLeft + m_nRowHeaderWidthPixel; ++loop; } while ( ( loop != m_aColumnWidths.rend() ) - && ( loop->getEnd() - nScrolledOutLeft >= _rCellArea.Right() ) + && ( loop->getEnd() - nScrolledOutLeft >= aArea.Right() ) ); } - // so far, _rCellArea.Right() denotes the first pixel *after* the cell area - --_rCellArea.Right(); + // so far, aArea.Right() denotes the first pixel *after* the cell area + --aArea.Right(); // determine the last row which is at least partially visible - _rCellArea.Bottom() = + aArea.Bottom() = m_nColHeaderHeightPixel + impl_getVisibleRows( true ) * m_nRowHeightPixel - 1; + + return aArea; } //------------------------------------------------------------------------------------------------------------------ - void TableControl_Impl::impl_getAllVisibleDataCellArea( Rectangle& _rCellArea ) const + Rectangle TableControl_Impl::impl_getAllVisibleDataCellArea() const { DBG_CHECK_ME(); - impl_getAllVisibleCellsArea( _rCellArea ); - _rCellArea.Left() = m_nRowHeaderWidthPixel; - _rCellArea.Top() = m_nColHeaderHeightPixel; + Rectangle aArea( impl_getAllVisibleCellsArea() ); + aArea.Left() = m_nRowHeaderWidthPixel; + aArea.Top() = m_nColHeaderHeightPixel; + return aArea; } //------------------------------------------------------------------------------------------------------------------ @@ -1244,8 +1245,7 @@ namespace svt { namespace table m_nRowCount = m_pModel->getRowCount(); // the area occupied by all (at least partially) visible cells, including // headers - Rectangle aAllCellsWithHeaders; - impl_getAllVisibleCellsArea( aAllCellsWithHeaders ); + Rectangle const aAllCellsWithHeaders( impl_getAllVisibleCellsArea() ); // ............................ // draw the header column area @@ -1310,8 +1310,7 @@ namespace svt { namespace table TableSize colCount = getModel()->getColumnCount(); // paint all rows - Rectangle aAllDataCellsArea; - impl_getAllVisibleDataCellArea( aAllDataCellsArea ); + Rectangle const aAllDataCellsArea( impl_getAllVisibleDataCellArea() ); for ( TableRowGeometry aRowIterator( *this, aAllCellsWithHeaders, getTopRow() ); aRowIterator.isValid(); aRowIterator.moveDown() ) @@ -1792,10 +1791,7 @@ namespace svt { namespace table return; } - Rectangle aAllCells; - impl_getAllVisibleCellsArea( aAllCells ); - - TableCellGeometry aCell( *this, aAllCells, _nColumn, _nRow ); + TableCellGeometry aCell( *this, impl_getAllVisibleCellsArea(), _nColumn, _nRow ); _rCellRect = aCell.getRect(); } @@ -1886,9 +1882,26 @@ namespace svt { namespace table } //------------------------------------------------------------------------------------------------------------------ - void TableControl_Impl::invalidate() + void TableControl_Impl::invalidate( TableArea const i_what ) { - m_pDataWindow->Invalidate(); + switch ( i_what ) + { + case TableAreaColumnHeaders: + m_pDataWindow->Invalidate( calcHeaderRect( true ) ); + break; + + case TableAreaRowHeaders: + m_pDataWindow->Invalidate( calcHeaderRect( false ) ); + break; + + case TableAreaDataArea: + m_pDataWindow->Invalidate( impl_getAllVisibleDataCellArea() ); + break; + + case TableAreaAll: + m_pDataWindow->Invalidate(); + break; + } } //------------------------------------------------------------------------------------------------------------------ @@ -1920,9 +1933,8 @@ namespace svt { namespace table void TableControl_Impl::invalidateSelectedRegion(RowPos _nPrevRow, RowPos _nCurRow, Rectangle& _rCellRect) { DBG_CHECK_ME(); - Rectangle aAllCells; //get the visible area of the table control and set the Left and right border of the region to be repainted - impl_getAllVisibleCellsArea( aAllCells ); + Rectangle const aAllCells( impl_getAllVisibleCellsArea() ); _rCellRect.Left() = aAllCells.Left(); _rCellRect.Right() = aAllCells.Right(); //if only one row is selected @@ -1967,9 +1979,7 @@ namespace svt { namespace table Rectangle aInvalidateRect; - Rectangle aVisibleCellsArea; - impl_getAllVisibleCellsArea( aVisibleCellsArea ); - + Rectangle const aVisibleCellsArea( impl_getAllVisibleCellsArea() ); TableRowGeometry aRow( *this, aVisibleCellsArea, firstRow, true ); while ( aRow.isValid() && ( aRow.getRow() <= lastRow ) ) { @@ -2409,23 +2419,18 @@ namespace svt { namespace table //-------------------------------------------------------------------- Rectangle TableControl_Impl::calcHeaderRect(bool bColHeader) { - Rectangle aRectTable, aRectTableWithHeaders; - impl_getAllVisibleDataCellArea(aRectTable); - impl_getAllVisibleCellsArea(aRectTableWithHeaders); - Size aSizeTable(aRectTable.GetSize()); - Size aSizeTableWithHeaders(aRectTableWithHeaders.GetSize()); - if(bColHeader) - return Rectangle(aRectTableWithHeaders.TopLeft(),Size(aSizeTableWithHeaders.Width()-aSizeTable.Width(), aSizeTableWithHeaders.Height())); + Rectangle const aRectTableWithHeaders( impl_getAllVisibleCellsArea() ); + Size const aSizeTableWithHeaders( aRectTableWithHeaders.GetSize() ); + if ( bColHeader ) + return Rectangle( aRectTableWithHeaders.TopLeft(), Size( aSizeTableWithHeaders.Width(), m_nColHeaderHeightPixel ) ); else - return Rectangle(aRectTableWithHeaders.TopLeft(),Size(aSizeTableWithHeaders.Width(), aSizeTableWithHeaders.Height()-aSizeTable.Height())); + return Rectangle( aRectTableWithHeaders.TopLeft(), Size( m_nRowHeaderWidthPixel, aSizeTableWithHeaders.Height() ) ); } //-------------------------------------------------------------------- Rectangle TableControl_Impl::calcTableRect() { - Rectangle aRect; - impl_getAllVisibleDataCellArea(aRect); - return aRect; + return impl_getAllVisibleDataCellArea(); } //-------------------------------------------------------------------- diff --git a/svtools/source/table/tablecontrol_impl.hxx b/svtools/source/table/tablecontrol_impl.hxx index 0975368a88a2..747ffc8a36fa 100755 --- a/svtools/source/table/tablecontrol_impl.hxx +++ b/svtools/source/table/tablecontrol_impl.hxx @@ -282,7 +282,7 @@ namespace svt { namespace table virtual void setPointer( Pointer const & i_pointer ); virtual void captureMouse(); virtual void releaseMouse(); - virtual void invalidate(); + virtual void invalidate( TableArea const i_what ); virtual long pixelWidthToAppFont( long const i_pixels ) const; virtual void hideTracking(); virtual void showTracking( Rectangle const & i_location, sal_uInt16 const i_flags ); @@ -429,14 +429,14 @@ namespace svt { namespace table As a result of respecting the partial visibility of rows and columns, the returned area might be larger than the data window's output size. */ - void impl_getAllVisibleCellsArea( Rectangle& _rCellArea ) const; + Rectangle impl_getAllVisibleCellsArea() const; /** retrieves the area occupied by all (at least partially) visible data cells. Effectively, the returned area is the same as returned by ->impl_getAllVisibleCellsArea, minus the row and column header areas. */ - void impl_getAllVisibleDataCellArea( Rectangle& _rCellArea ) const; + Rectangle impl_getAllVisibleDataCellArea() const; /** retrieves the column which covers the given ordinate */ diff --git a/svtools/source/uno/svtxgridcontrol.cxx b/svtools/source/uno/svtxgridcontrol.cxx index ef9b10030230..14ac857179b1 100644 --- a/svtools/source/uno/svtxgridcontrol.cxx +++ b/svtools/source/uno/svtxgridcontrol.cxx @@ -524,7 +524,8 @@ void SAL_CALL SVTXGridControl::rowsInserted( const GridDataEvent& i_event ) thro } //---------------------------------------------------------------------------------------------------------------------- -void SAL_CALL SVTXGridControl::rowsRemoved( const GridDataEvent& i_event ) throw (RuntimeException) +void SAL_CALL//---------------------------------------------------------------------------------------------------------------------- + SVTXGridControl::rowsRemoved( const GridDataEvent& i_event ) throw (RuntimeException) { ::vos::OGuard aGuard( GetMutex() ); m_pTableModel->notifyRowsRemoved( i_event ); @@ -544,6 +545,10 @@ void SAL_CALL SVTXGridControl::dataChanged( const GridDataEvent& i_event ) throw pTable->InvalidateDataWindow( 0, m_pTableModel->getRowCount() ); else pTable->InvalidateDataWindow( i_event.FirstRow, i_event.LastRow ); + + // if the data model is sortable, a dataChanged event is also fired in case the sort order changed. + // So, invalidate the column header area, too. + pTable->getTableControlInterface().invalidate( TableAreaColumnHeaders ); } //---------------------------------------------------------------------------------------------------------------------- @@ -556,7 +561,7 @@ void SAL_CALL SVTXGridControl::rowHeadingChanged( const GridDataEvent& i_event ) ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::rowHeadingChanged: no control (anymore)!" ); // TODO: we could do better than this - invalidate the header area only - pTable->Invalidate(); + pTable->getTableControlInterface().invalidate( TableAreaRowHeaders ); } @@ -609,6 +614,7 @@ void SAL_CALL SVTXGridControl::selectRow( ::sal_Int32 i_rowIndex ) throw (::com: pTable->SelectRow( i_rowIndex, true ); } +//---------------------------------------------------------------------------------------------------------------------- void SAL_CALL SVTXGridControl::selectAllRows() throw (::com::sun::star::uno::RuntimeException) { ::vos::OGuard aGuard( GetMutex() ); @@ -619,6 +625,7 @@ void SAL_CALL SVTXGridControl::selectAllRows() throw (::com::sun::star::uno::Run pTable->SelectAllRows( true ); } +//---------------------------------------------------------------------------------------------------------------------- void SAL_CALL SVTXGridControl::deselectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException) { ::vos::OGuard aGuard( GetMutex() ); @@ -629,6 +636,7 @@ void SAL_CALL SVTXGridControl::deselectRow( ::sal_Int32 i_rowIndex ) throw (::co pTable->SelectRow( i_rowIndex, false ); } +//---------------------------------------------------------------------------------------------------------------------- void SAL_CALL SVTXGridControl::deselectAllRows() throw (::com::sun::star::uno::RuntimeException) { ::vos::OGuard aGuard( GetMutex() ); @@ -639,6 +647,7 @@ void SAL_CALL SVTXGridControl::deselectAllRows() throw (::com::sun::star::uno::R pTable->SelectAllRows( false ); } +//---------------------------------------------------------------------------------------------------------------------- ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL SVTXGridControl::getSelection() throw (::com::sun::star::uno::RuntimeException) { ::vos::OGuard aGuard( GetMutex() ); @@ -653,6 +662,7 @@ void SAL_CALL SVTXGridControl::deselectAllRows() throw (::com::sun::star::uno::R return selectedRows; } +//---------------------------------------------------------------------------------------------------------------------- ::sal_Bool SAL_CALL SVTXGridControl::isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException) { ::vos::OGuard aGuard( GetMutex() ); @@ -663,6 +673,7 @@ void SAL_CALL SVTXGridControl::deselectAllRows() throw (::com::sun::star::uno::R return pTable->GetSelectedRowCount() > 0; } +//---------------------------------------------------------------------------------------------------------------------- ::sal_Bool SAL_CALL SVTXGridControl::isSelectedIndex( ::sal_Int32 index ) throw (::com::sun::star::uno::RuntimeException) { ::vos::OGuard aGuard( GetMutex() ); @@ -673,6 +684,7 @@ void SAL_CALL SVTXGridControl::deselectAllRows() throw (::com::sun::star::uno::R return pTable->IsRowSelected( index ); } +//---------------------------------------------------------------------------------------------------------------------- void SVTXGridControl::dispose() throw(::com::sun::star::uno::RuntimeException) { ::com::sun::star::lang::EventObject aObj; @@ -681,6 +693,7 @@ void SVTXGridControl::dispose() throw(::com::sun::star::uno::RuntimeException) VCLXWindow::dispose(); } +//---------------------------------------------------------------------------------------------------------------------- void SVTXGridControl::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) { ::vos::OGuard aGuard( GetMutex() ); @@ -703,6 +716,7 @@ void SVTXGridControl::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent } } +//---------------------------------------------------------------------------------------------------------------------- void SVTXGridControl::ImplCallItemListeners() { TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); @@ -750,6 +764,7 @@ void SVTXGridControl::ImplCallItemListeners() } } +//---------------------------------------------------------------------------------------------------------------------- void SVTXGridControl::impl_updateColumnsFromModel_nothrow() { Reference< XGridColumnModel > const xColumnModel( m_pTableModel->getColumnModel() ); |