summaryrefslogtreecommitdiff
path: root/svtools
diff options
context:
space:
mode:
authorFrank Schoenheit [fs] <frank.schoenheit@oracle.com>2011-01-06 16:28:45 +0100
committerFrank Schoenheit [fs] <frank.schoenheit@oracle.com>2011-01-06 16:28:45 +0100
commitf167cee01ffd13e949e68f8395050dc1264f9ab5 (patch)
treede4839acdc4879637c2b445eec55dd69846b2eef /svtools
parent9a402704663a1ec0ea241517cffc8f26efc6dbfa (diff)
gridsort: XGridDataModel: do not provide access to all data at once, instead use cell-based access
Diffstat (limited to 'svtools')
-rw-r--r--svtools/source/uno/svtxgridcontrol.cxx94
-rw-r--r--svtools/source/uno/unocontroltablemodel.cxx152
-rw-r--r--svtools/source/uno/unocontroltablemodel.hxx11
3 files changed, 64 insertions, 193 deletions
diff --git a/svtools/source/uno/svtxgridcontrol.cxx b/svtools/source/uno/svtxgridcontrol.cxx
index 805cff7aca98..06b0576d169b 100644
--- a/svtools/source/uno/svtxgridcontrol.cxx
+++ b/svtools/source/uno/svtxgridcontrol.cxx
@@ -268,48 +268,13 @@ void SVTXGridControl::setProperty( const ::rtl::OUString& PropertyName, const An
if ( !m_xDataModel.is() )
throw GridInvalidDataException( ::rtl::OUString::createFromAscii("The data model isn't set!"), *this );
- Sequence< Sequence< Any > > cellData = m_xDataModel->getData();
- if ( cellData.getLength() != 0 )
- {
- const sal_Int32 nDataRowCount = cellData.getLength();
-
- const Sequence< ::rtl::OUString > rowHeaders = m_xDataModel->getRowHeaders();
- const sal_Int32 nRowHeaderCount = rowHeaders.getLength();
-
- if ( ( nRowHeaderCount != 0 ) && ( nRowHeaderCount != nDataRowCount ) )
- throw GridInvalidDataException(
- ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "row header / content data inconsistency" ) ), *this );
-
- // check data consistency
- sal_Int32 nDataColumnCount = 0;
- for ( sal_Int32 i=0; i<nDataRowCount; ++i )
- {
- const Sequence< Any >& rRawRowData = cellData[i];
- if ( ( i > 0 ) && ( rRawRowData.getLength() != nDataColumnCount ) )
- throw GridInvalidDataException(
- ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "inconsistent column counts in the row data" ) ), *this );
- nDataColumnCount = rRawRowData.getLength();
- }
-
- // ensure default columns exist, if they have not previously been added
- if ( ( nDataColumnCount > 0 ) && ( m_xColumnModel->getColumnCount() == 0 ) )
- m_xColumnModel->setDefaultColumns( nDataColumnCount );
- // this will trigger notifications, which in turn will let us update our m_pTableModel
-
- // ensure the row data has as much columns as indicate by our model
- if ( nDataColumnCount != m_pTableModel->getColumnCount() )
- throw GridInvalidDataException(
- ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Grid model's column count doesn't match the row data's column count." ) ),
- *this );
-
- // finally add the rows
- // TODO: suspend the model's notifications for the single rows, do one notification after all
- // rows have been inserted
- for ( TableSize i = 0; i < nDataRowCount; ++i )
- {
- m_pTableModel->appendRow( cellData[i], rowHeaders[i] );
- }
- }
+ m_pTableModel->setDataModel( m_xDataModel );
+
+ // ensure default columns exist, if they have not previously been added
+ sal_Int32 const nDataColumnCount = m_xDataModel->getColumnCount();
+ if ( ( nDataColumnCount > 0 ) && ( m_xColumnModel->getColumnCount() == 0 ) )
+ m_xColumnModel->setDefaultColumns( nDataColumnCount );
+ // this will trigger notifications, which in turn will let us update our m_pTableModel
sal_Int32 fontHeight = pTable->PixelToLogic( Size( 0, pTable->GetTextHeight()+3 ), MAP_APPFONT ).Height();
if ( m_xDataModel->getRowHeight() == 0 )
@@ -413,8 +378,6 @@ void SAL_CALL SVTXGridControl::rowAdded(const ::com::sun::star::awt::grid::GridD
if ( rowDataLength != colCount )
throw GridInvalidDataException( ::rtl::OUString::createFromAscii("The column count doesn't match with the length of row data"), *this );
- m_pTableModel->appendRow( Event.RowData, Event.HeaderName );
-
TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::rowAdded: no control (anymore)!" );
@@ -449,8 +412,6 @@ void SAL_CALL SVTXGridControl::rowRemoved(const ::com::sun::star::awt::grid::Gri
if ( !isSelectionEmpty() )
deselectAllRows();
- m_pTableModel->clearAllRows();
-
pTable->clearSelection();
if ( pTable->isAccessibleAlive() )
@@ -468,10 +429,10 @@ void SAL_CALL SVTXGridControl::rowRemoved(const ::com::sun::star::awt::grid::Gri
selected[0]=Event.RowIndex;
deselectRows( selected );
}
- m_pTableModel->removeRow( Event.RowIndex );
}
- pTable->InvalidateDataWindow(Event.RowIndex, Event.RowIndex, true);
- if(pTable->isAccessibleAlive())
+
+ pTable->InvalidateDataWindow( Event.RowIndex, Event.RowIndex, true );
+ if ( pTable->isAccessibleAlive() )
{
pTable->commitGridControlEvent(TABLE_MODEL_CHANGED,
makeAny( AccessibleTableModelChange(DELETE, Event.RowIndex, Event.RowIndex+1, 0, m_pTableModel->getColumnCount())),
@@ -502,38 +463,15 @@ void SAL_CALL SVTXGridControl::dataChanged(const ::com::sun::star::awt::grid::Gr
}
else if ( Event.AttributeName.equalsAscii( "RowHeaders" ) )
{
- Sequence< rtl::OUString > rowHeaders;
- OSL_VERIFY( Event.NewValue >>= rowHeaders );
- m_pTableModel->setRowHeaderNames( rowHeaders );
+ // TODO: we could do better than this - invalidate the header area only
pTable->Invalidate();
}
- else if ( Event.AttributeName.equalsAscii( "CellUpdated" ) )
+ else if ( ( Event.AttributeName.equalsAscii( "CellUpdated" ) )
+ || ( Event.AttributeName.equalsAscii( "RowUpdated" ) )
+ )
{
- sal_Int32 col = -1;
- OSL_VERIFY( Event.OldValue >>= col );
-
- m_pTableModel->updateCellContent( Event.RowIndex, col, Event.NewValue );
- pTable->InvalidateDataWindow( Event.RowIndex, Event.RowIndex, false );
- }
- else if ( Event.AttributeName.equalsAscii( "RowUpdated" ) )
- {
- Sequence< sal_Int32 > cols;
- OSL_VERIFY( Event.OldValue >>= cols );
-
- Sequence< Any > values;
- OSL_VERIFY( Event.NewValue >>= values );
-
- ENSURE_OR_RETURN_VOID( cols.getLength() == values.getLength(), "SVTXGridControl::dataChanged: inconsistent array lengths!" );
-
- const TableSize columnCount = m_pTableModel->getColumnCount();
- // TODO: suspend listener notification, so that the table model doesn't notify |cols.size()| different events.
- // Instead, only one event should be broadcasted.
- for ( ColPos i = 0; i< cols.getLength(); ++i )
- {
- ENSURE_OR_CONTINUE( ( cols[i] >= 0 ) && ( cols[i] < columnCount ), "illegal column index" );
- m_pTableModel->updateCellContent( Event.RowIndex, cols[i], values[i] );
- }
-
+ // TODO: Our UnoControlTableModel should be a listener at the data model, and multiplex those events,
+ // so the TableControl/_Impl can react on it.
pTable->InvalidateDataWindow( Event.RowIndex, Event.RowIndex, false );
}
}
diff --git a/svtools/source/uno/unocontroltablemodel.cxx b/svtools/source/uno/unocontroltablemodel.cxx
index 8bfc1d1400f2..4bdfa0ebdabd 100644
--- a/svtools/source/uno/unocontroltablemodel.cxx
+++ b/svtools/source/uno/unocontroltablemodel.cxx
@@ -41,6 +41,7 @@
/** === end UNO includes === **/
#include <comphelper/stlunosequence.hxx>
+#include <cppuhelper/weakref.hxx>
#include <tools/debug.hxx>
#include <tools/diagnose_ex.h>
#include <vcl/svapp.hxx>
@@ -63,9 +64,11 @@ namespace svt { namespace table
using ::com::sun::star::awt::grid::XGridColumnListener;
using ::com::sun::star::lang::EventObject;
using ::com::sun::star::awt::grid::GridColumnEvent;
+ using ::com::sun::star::awt::grid::XGridDataModel;
using ::com::sun::star::uno::Any;
using ::com::sun::star::style::HorizontalAlignment_LEFT;
using ::com::sun::star::style::HorizontalAlignment;
+ using ::com::sun::star::uno::WeakReference;
/** === end UNO using === **/
//==================================================================================================================
@@ -76,7 +79,6 @@ namespace svt { namespace table
struct UnoControlTableModel_Impl
{
ColumnModels aColumns;
- TableSize nRowCount;
bool bHasColumnHeaders;
bool bHasRowHeaders;
ScrollbarVisibility eVScrollMode;
@@ -86,8 +88,6 @@ namespace svt { namespace table
TableMetrics nRowHeight;
TableMetrics nColumnHeaderHeight;
TableMetrics nRowHeaderWidth;
- ::std::vector< ::rtl::OUString > aRowHeadersTitle;
- ::std::vector< ::std::vector< Any > > aCellContent;
::com::sun::star::util::Color m_nLineColor;
::com::sun::star::util::Color m_nHeaderColor;
::com::sun::star::util::Color m_nTextColor;
@@ -95,10 +95,10 @@ namespace svt { namespace table
::com::sun::star::util::Color m_nRowColor2;
::com::sun::star::style::VerticalAlignment m_eVerticalAlign;
ModellListeners m_aListeners;
+ WeakReference< XGridDataModel > m_aDataModel;
UnoControlTableModel_Impl()
:aColumns ( )
- ,nRowCount ( 0 )
,bHasColumnHeaders ( true )
,bHasRowHeaders ( false )
,eVScrollMode ( ScrollbarShowNever )
@@ -108,8 +108,6 @@ namespace svt { namespace table
,nRowHeight ( 10 )
,nColumnHeaderHeight( 10 )
,nRowHeaderWidth ( 10 )
- ,aRowHeadersTitle ( )
- ,aCellContent ( )
,m_nLineColor ( COL_TRANSPARENT )
,m_nHeaderColor ( COL_TRANSPARENT )
,m_nTextColor ( 0 )//black as default
@@ -132,8 +130,9 @@ namespace svt { namespace table
//------------------------------------------------------------------------------------------------------------------
const char* UnoControlTableModel::checkInvariants() const
{
- if ( m_pImpl->aRowHeadersTitle.size() != m_pImpl->aCellContent.size() )
- return "inconsistency between data and row header arrays";
+ Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel );
+ if ( !xDataModel.is() )
+ return "data model anymore";
// TODO: more?
@@ -175,7 +174,19 @@ namespace svt { namespace table
TableSize UnoControlTableModel::getRowCount() const
{
DBG_CHECK_ME();
- return m_pImpl->nRowCount;
+
+ TableSize nRowCount = 0;
+ try
+ {
+ Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel );
+ ENSURE_OR_THROW( xDataModel.is(), "no data model anymore!" );
+ nRowCount = xDataModel->getRowCount();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return nRowCount;
}
//------------------------------------------------------------------------------------------------------------------
@@ -413,122 +424,53 @@ namespace svt { namespace table
}
//------------------------------------------------------------------------------------------------------------------
- void UnoControlTableModel::setCellContent(const std::vector<std::vector< Any > >& cellContent)
+ void UnoControlTableModel::setDataModel( Reference< XGridDataModel > const & i_gridDataModel )
{
DBG_CHECK_ME();
- m_pImpl->aCellContent = cellContent;
+ m_pImpl->m_aDataModel = i_gridDataModel;
+ // TODO: register as listener, so we're notified of row/data changes, and can multiplex them to our
+ // own listeners
}
//------------------------------------------------------------------------------------------------------------------
void UnoControlTableModel::getCellContent( ColPos const i_col, RowPos const i_row, Any& o_cellContent )
{
DBG_CHECK_ME();
- ENSURE_OR_RETURN_VOID( ( i_row >= 0 ) && ( size_t( i_row ) < m_pImpl->aCellContent.size() ),
- "UnoControlTableModel::getCellContent: illegal row index!" );
- ::std::vector< Any >& rRowContent( m_pImpl->aCellContent[ i_row ] );
- ENSURE_OR_RETURN_VOID( ( i_col >= 0 ) && ( size_t( i_col ) < rRowContent.size() ),
- "UnoControlTableModel::getCellContent: illegal column index" );
- o_cellContent = rRowContent[ i_col ];
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void UnoControlTableModel::updateCellContent( RowPos const i_row, ColPos const i_col, Any const & i_cellContent )
- {
- DBG_CHECK_ME();
- ENSURE_OR_RETURN_VOID( ( i_row >= 0 ) && ( size_t( i_row ) < m_pImpl->aCellContent.size() ),
- "UnoControlTableModel::updateCellContent: illegal row index!" );
- ::std::vector< Any >& rRowContent( m_pImpl->aCellContent[ i_row ] );
- ENSURE_OR_RETURN_VOID( ( i_col >= 0 ) && ( size_t( i_col ) < rRowContent.size() ),
- "UnoControlTableModel::updateCellContent: illegal column index" );
- rRowContent[ i_col ] = i_cellContent;
-
- // TODO: listener notification
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void UnoControlTableModel::setRowHeaderNames( const Sequence< ::rtl::OUString >& i_rowHeaders )
- {
- DBG_CHECK_ME();
- ENSURE_OR_RETURN_VOID( size_t( i_rowHeaders.getLength() ) == m_pImpl->aRowHeadersTitle.size(),
- "UnoControlTableModel::setRowHeaderNames: illegal number of row headers!" );
- // this method is not intended to set a new row count, but only to modify the existing row headers
-
- ::std::copy(
- ::comphelper::stl_begin( i_rowHeaders ),
- ::comphelper::stl_end( i_rowHeaders ),
- m_pImpl->aRowHeadersTitle.begin()
- );
- // TODO: listener notification
+ try
+ {
+ Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel );
+ ENSURE_OR_THROW( xDataModel.is(), "no data model anymore!" );
+ o_cellContent = xDataModel->getCellData( i_col, i_row );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
}
//------------------------------------------------------------------------------------------------------------------
::rtl::OUString UnoControlTableModel::getRowHeader( RowPos const i_rowPos ) const
{
DBG_CHECK_ME();
- ENSURE_OR_RETURN( ( i_rowPos >= 0 ) && ( size_t( i_rowPos ) < m_pImpl->aRowHeadersTitle.size() ),
- "UnoControlTableModel::getRowHeader: illegal row position!", ::rtl::OUString() );
- return m_pImpl->aRowHeadersTitle[ i_rowPos ];
- }
- //------------------------------------------------------------------------------------------------------------------
- void UnoControlTableModel::appendRow( Sequence< Any > const & i_rowData, ::rtl::OUString const & i_rowHeader )
- {
- DBG_CHECK_ME();
- ENSURE_OR_RETURN_VOID( i_rowData.getLength() == getColumnCount(), "UnoControlTableModel::appendRow: invalid row data!" );
-
- // add row data
- ::std::vector< Any > newRow( i_rowData.getLength() );
- if ( !newRow.empty() )
- ::std::copy(
- ::comphelper::stl_begin( i_rowData ),
- ::comphelper::stl_end( i_rowData ),
- newRow.begin()
- );
-
- m_pImpl->aCellContent.push_back( newRow );
-
- if ( hasRowHeaders() )
- m_pImpl->aRowHeadersTitle.push_back( i_rowHeader );
-
- ++m_pImpl->nRowCount;
-
- // TODO: listener notification
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void UnoControlTableModel::removeRow( RowPos const i_rowPos )
- {
- DBG_CHECK_ME();
- ENSURE_OR_RETURN_VOID( ( i_rowPos >= 0 ) && ( i_rowPos < getRowCount() ), "UnoControlTableModel::removeRow: illegal row position!" );
-
- if ( hasRowHeaders() )
- m_pImpl->aRowHeadersTitle.erase( m_pImpl->aRowHeadersTitle.begin() + i_rowPos );
+ ::rtl::OUString sRowHeader;
- const ::std::vector< ::std::vector< Any > >::iterator contentPos = m_pImpl->aCellContent.begin() + i_rowPos;
- m_pImpl->aCellContent.erase( contentPos );
+ Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel );
+ ENSURE_OR_RETURN( xDataModel.is(), "UnoControlTableModel::getRowHeader: no data model anymore!", sRowHeader );
- --m_pImpl->nRowCount;
-
- // TODO: listener notification
- }
-
- //------------------------------------------------------------------------------------------------------------------
- void UnoControlTableModel::clearAllRows()
- {
- DBG_CHECK_ME();
- if ( hasRowHeaders() )
+ try
{
- ::std::vector< ::rtl::OUString > aEmpty;
- m_pImpl->aRowHeadersTitle.swap( aEmpty );
+ Sequence< ::rtl::OUString > const aRowHeaders( xDataModel->getRowHeaders() );
+ ENSURE_OR_RETURN( ( i_rowPos >= 0 ) && ( i_rowPos < aRowHeaders.getLength() ),
+ "UnoControlTableModel::getRowHeader: illegal row position!", sRowHeader );
+ sRowHeader = aRowHeaders[ i_rowPos ];
}
-
- ::std::vector< ::std::vector< Any > > aEmptyContent;
- m_pImpl->aCellContent.swap( aEmptyContent );
-
- m_pImpl->nRowCount = 0;
-
- // TODO: listener notification
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return sRowHeader;
}
//------------------------------------------------------------------------------------------------------------------
diff --git a/svtools/source/uno/unocontroltablemodel.hxx b/svtools/source/uno/unocontroltablemodel.hxx
index d6dcf138ccf2..2cb107b3551d 100644
--- a/svtools/source/uno/unocontroltablemodel.hxx
+++ b/svtools/source/uno/unocontroltablemodel.hxx
@@ -117,19 +117,10 @@ namespace svt { namespace table
void insertColumn( ColPos const i_position, ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > const & i_column );
void removeAllColumns();
- // row write access
- void setRowHeaderNames( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& i_rowHeaders );
- void appendRow( ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > const & i_rowData, ::rtl::OUString const & i_rowHeader );
- void removeRow( RowPos const i_rowPos );
- void clearAllRows();
-
- // cell data write access
- void updateCellContent( RowPos const i_rowPos, ColPos const i_colPos, ::com::sun::star::uno::Any const & i_cellContent );
-
// other operations
void setVerticalScrollbarVisibility( ScrollbarVisibility const i_visibility ) const;
void setHorizontalScrollbarVisibility( ScrollbarVisibility const i_visibility ) const;
- void setCellContent(const std::vector<std::vector< ::com::sun::star::uno::Any > >& cellContent);
+ void setDataModel( ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel > const & i_gridDataModel );
void setRowHeaders(bool _bRowHeaders);
void setColumnHeaders(bool _bColumnHeaders);
void setLineColor(::com::sun::star::util::Color _rColor);