summaryrefslogtreecommitdiff
path: root/svtools
diff options
context:
space:
mode:
Diffstat (limited to 'svtools')
-rw-r--r--svtools/inc/svtools/table/tablecontrolinterface.hxx13
-rw-r--r--svtools/source/table/gridtablerenderer.cxx98
-rwxr-xr-xsvtools/source/table/mousefunction.cxx2
-rw-r--r--svtools/source/table/tablecontrol.cxx2
-rwxr-xr-xsvtools/source/table/tablecontrol_impl.cxx87
-rwxr-xr-xsvtools/source/table/tablecontrol_impl.hxx6
-rw-r--r--svtools/source/uno/svtxgridcontrol.cxx19
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() );