diff options
author | Frank Schoenheit [fs] <frank.schoenheit@oracle.com> | 2011-01-06 16:28:45 +0100 |
---|---|---|
committer | Frank Schoenheit [fs] <frank.schoenheit@oracle.com> | 2011-01-06 16:28:45 +0100 |
commit | f167cee01ffd13e949e68f8395050dc1264f9ab5 (patch) | |
tree | de4839acdc4879637c2b445eec55dd69846b2eef /svtools | |
parent | 9a402704663a1ec0ea241517cffc8f26efc6dbfa (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.cxx | 94 | ||||
-rw-r--r-- | svtools/source/uno/unocontroltablemodel.cxx | 152 | ||||
-rw-r--r-- | svtools/source/uno/unocontroltablemodel.hxx | 11 |
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); |