1f6e50924SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3f6e50924SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4f6e50924SAndrew Rist * or more contributor license agreements. See the NOTICE file 5f6e50924SAndrew Rist * distributed with this work for additional information 6f6e50924SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7f6e50924SAndrew Rist * to you under the Apache License, Version 2.0 (the 8f6e50924SAndrew Rist * "License"); you may not use this file except in compliance 9f6e50924SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11f6e50924SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13f6e50924SAndrew Rist * Unless required by applicable law or agreed to in writing, 14f6e50924SAndrew Rist * software distributed under the License is distributed on an 15f6e50924SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16f6e50924SAndrew Rist * KIND, either express or implied. See the License for the 17f6e50924SAndrew Rist * specific language governing permissions and limitations 18f6e50924SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20f6e50924SAndrew Rist *************************************************************/ 21f6e50924SAndrew Rist 22f6e50924SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_svx.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <com/sun/star/table/XMergeableCell.hpp> 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include <algorithm> 30cdf0e10cSrcweir #include <boost/bind.hpp> 31cdf0e10cSrcweir 32cdf0e10cSrcweir #include <vcl/svapp.hxx> 33cdf0e10cSrcweir #include <vos/mutex.hxx> 34cdf0e10cSrcweir 35cdf0e10cSrcweir #include "cell.hxx" 36cdf0e10cSrcweir #include "cellcursor.hxx" 37cdf0e10cSrcweir #include "tablemodel.hxx" 38cdf0e10cSrcweir #include "tablerow.hxx" 39cdf0e10cSrcweir #include "tablerows.hxx" 40cdf0e10cSrcweir #include "tablecolumn.hxx" 41cdf0e10cSrcweir #include "tablecolumns.hxx" 42cdf0e10cSrcweir #include "tableundo.hxx" 43cdf0e10cSrcweir #include "svx/svdotable.hxx" 44cdf0e10cSrcweir #include "svx/svdmodel.hxx" 45cdf0e10cSrcweir #include "svx/svdstr.hrc" 46cdf0e10cSrcweir #include "svx/svdglob.hxx" 47cdf0e10cSrcweir 48cdf0e10cSrcweir //#define PLEASE_DEBUG_THE_TABLES 1 49cdf0e10cSrcweir 50cdf0e10cSrcweir using ::rtl::OUString; 51cdf0e10cSrcweir using namespace ::osl; 52cdf0e10cSrcweir using namespace ::vos; 53cdf0e10cSrcweir using namespace ::com::sun::star::uno; 54cdf0e10cSrcweir using namespace ::com::sun::star::table; 55cdf0e10cSrcweir using namespace ::com::sun::star::lang; 56cdf0e10cSrcweir using namespace ::com::sun::star::container; 57cdf0e10cSrcweir using namespace ::com::sun::star::beans; 58cdf0e10cSrcweir using namespace ::com::sun::star::util; 59cdf0e10cSrcweir 60cdf0e10cSrcweir // ----------------------------------------------------------------------------- 61cdf0e10cSrcweir 62cdf0e10cSrcweir namespace sdr { namespace table { 63cdf0e10cSrcweir 64cdf0e10cSrcweir // ----------------------------------------------------------------------------- 65cdf0e10cSrcweir 66cdf0e10cSrcweir // removes the given range from a vector 67cdf0e10cSrcweir template< class Vec, class Iter > void remove_range( Vec& rVector, sal_Int32 nIndex, sal_Int32 nCount ) 68cdf0e10cSrcweir { 69cdf0e10cSrcweir const sal_Int32 nSize = static_cast<sal_Int32>(rVector.size()); 70cdf0e10cSrcweir if( nCount && (nIndex >= 0) && (nIndex < nSize) ) 71cdf0e10cSrcweir { 72cdf0e10cSrcweir if( (nIndex + nCount) >= nSize ) 73cdf0e10cSrcweir { 74cdf0e10cSrcweir // remove at end 75cdf0e10cSrcweir rVector.resize( nIndex ); 76cdf0e10cSrcweir } 77cdf0e10cSrcweir else 78cdf0e10cSrcweir { 79cdf0e10cSrcweir Iter aBegin( rVector.begin() ); 80cdf0e10cSrcweir while( nIndex-- ) 81cdf0e10cSrcweir aBegin++; 82cdf0e10cSrcweir if( nCount == 1 ) 83cdf0e10cSrcweir { 84cdf0e10cSrcweir rVector.erase( aBegin ); 85cdf0e10cSrcweir } 86cdf0e10cSrcweir else 87cdf0e10cSrcweir { 88cdf0e10cSrcweir Iter aEnd( aBegin ); 89cdf0e10cSrcweir 90cdf0e10cSrcweir while( nCount-- ) 91cdf0e10cSrcweir aEnd++; 92cdf0e10cSrcweir rVector.erase( aBegin, aEnd ); 93cdf0e10cSrcweir } 94cdf0e10cSrcweir } 95cdf0e10cSrcweir } 96cdf0e10cSrcweir } 97cdf0e10cSrcweir 98cdf0e10cSrcweir // ----------------------------------------------------------------------------- 99cdf0e10cSrcweir 100cdf0e10cSrcweir /** inserts a range into a vector */ 101cdf0e10cSrcweir template< class Vec, class Iter, class Entry > sal_Int32 insert_range( Vec& rVector, sal_Int32 nIndex, sal_Int32 nCount ) 102cdf0e10cSrcweir { 103cdf0e10cSrcweir if( nCount ) 104cdf0e10cSrcweir { 105cdf0e10cSrcweir if( nIndex >= static_cast< sal_Int32 >( rVector.size() ) ) 106cdf0e10cSrcweir { 107cdf0e10cSrcweir // append at end 108cdf0e10cSrcweir nIndex = static_cast< sal_Int32 >( rVector.size() ); // cap to end 109cdf0e10cSrcweir rVector.resize( nIndex + nCount ); 110cdf0e10cSrcweir } 111cdf0e10cSrcweir else 112cdf0e10cSrcweir { 113cdf0e10cSrcweir // insert 114cdf0e10cSrcweir sal_Int32 nFind = nIndex; 115cdf0e10cSrcweir Iter aIter( rVector.begin() ); 116cdf0e10cSrcweir while( nFind-- ) 117cdf0e10cSrcweir aIter++; 118cdf0e10cSrcweir 119cdf0e10cSrcweir Entry aEmpty; 120cdf0e10cSrcweir rVector.insert( aIter, nCount, aEmpty ); 121cdf0e10cSrcweir } 122cdf0e10cSrcweir } 123cdf0e10cSrcweir return nIndex; 124cdf0e10cSrcweir } 125cdf0e10cSrcweir 126cdf0e10cSrcweir // ----------------------------------------------------------------------------- 127cdf0e10cSrcweir 128cdf0e10cSrcweir TableModel::TableModel( SdrTableObj* pTableObj ) 129cdf0e10cSrcweir : TableModelBase( m_aMutex ) 130cdf0e10cSrcweir , mpTableObj( pTableObj ) 131cdf0e10cSrcweir , mbModified( sal_False ) 132cdf0e10cSrcweir , mbNotifyPending( false ) 133cdf0e10cSrcweir , mnNotifyLock( 0 ) 134cdf0e10cSrcweir { 135cdf0e10cSrcweir } 136cdf0e10cSrcweir 137cdf0e10cSrcweir TableModel::TableModel( SdrTableObj* pTableObj, const TableModelRef& xSourceTable ) 138cdf0e10cSrcweir : TableModelBase( m_aMutex ) 139cdf0e10cSrcweir , mpTableObj( pTableObj ) 140cdf0e10cSrcweir , mbModified( sal_False ) 141cdf0e10cSrcweir , mbNotifyPending( false ) 142cdf0e10cSrcweir , mnNotifyLock( 0 ) 143cdf0e10cSrcweir { 144cdf0e10cSrcweir if( xSourceTable.is() ) 145cdf0e10cSrcweir { 146cdf0e10cSrcweir const sal_Int32 nColCount = xSourceTable->getColumnCountImpl(); 147cdf0e10cSrcweir const sal_Int32 nRowCount = xSourceTable->getRowCountImpl(); 148cdf0e10cSrcweir 149cdf0e10cSrcweir init( nColCount, nRowCount ); 150cdf0e10cSrcweir 151cdf0e10cSrcweir sal_Int32 nRows = nRowCount; 152cdf0e10cSrcweir while( nRows-- ) 153cdf0e10cSrcweir (*maRows[nRows]) = (*xSourceTable->maRows[nRows]); 154cdf0e10cSrcweir 155cdf0e10cSrcweir sal_Int32 nColumns = nColCount; 156cdf0e10cSrcweir while( nColumns-- ) 157cdf0e10cSrcweir (*maColumns[nColumns]) = (*xSourceTable->maColumns[nColumns]); 158cdf0e10cSrcweir 159cdf0e10cSrcweir // copy cells 160cdf0e10cSrcweir for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol ) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow ) 163cdf0e10cSrcweir { 164cdf0e10cSrcweir CellRef xTargetCell( getCell( nCol, nRow ) ); 165cdf0e10cSrcweir if( xTargetCell.is() ) 166cdf0e10cSrcweir xTargetCell->cloneFrom( xSourceTable->getCell( nCol, nRow ) ); 167cdf0e10cSrcweir } 168cdf0e10cSrcweir } 169cdf0e10cSrcweir } 170cdf0e10cSrcweir } 171cdf0e10cSrcweir 172cdf0e10cSrcweir // ----------------------------------------------------------------------------- 173cdf0e10cSrcweir 174cdf0e10cSrcweir TableModel::~TableModel() 175cdf0e10cSrcweir { 176cdf0e10cSrcweir } 177cdf0e10cSrcweir 178cdf0e10cSrcweir // ----------------------------------------------------------------------------- 179cdf0e10cSrcweir 180cdf0e10cSrcweir void TableModel::init( sal_Int32 nColumns, sal_Int32 nRows ) 181cdf0e10cSrcweir { 182cdf0e10cSrcweir if( nRows < 20 ) 183cdf0e10cSrcweir maRows.reserve( 20 ); 184cdf0e10cSrcweir 185cdf0e10cSrcweir if( nColumns < 20 ) 186cdf0e10cSrcweir maColumns.reserve( 20 ); 187cdf0e10cSrcweir 188cdf0e10cSrcweir if( nRows && nColumns ) 189cdf0e10cSrcweir { 190cdf0e10cSrcweir maColumns.resize( nColumns ); 191cdf0e10cSrcweir maRows.resize( nRows ); 192cdf0e10cSrcweir 193cdf0e10cSrcweir while( nRows-- ) 194cdf0e10cSrcweir maRows[nRows].set( new TableRow( this, nRows, nColumns ) ); 195cdf0e10cSrcweir 196cdf0e10cSrcweir while( nColumns-- ) 197cdf0e10cSrcweir maColumns[nColumns].set( new TableColumn( this, nColumns ) ); 198cdf0e10cSrcweir } 199cdf0e10cSrcweir } 200cdf0e10cSrcweir 201cdf0e10cSrcweir // ----------------------------------------------------------------------------- 202cdf0e10cSrcweir // ICellRange 203cdf0e10cSrcweir // ----------------------------------------------------------------------------- 204cdf0e10cSrcweir 205cdf0e10cSrcweir sal_Int32 TableModel::getLeft() 206cdf0e10cSrcweir { 207cdf0e10cSrcweir return 0; 208cdf0e10cSrcweir } 209cdf0e10cSrcweir 210cdf0e10cSrcweir // ----------------------------------------------------------------------------- 211cdf0e10cSrcweir 212cdf0e10cSrcweir sal_Int32 TableModel::getTop() 213cdf0e10cSrcweir { 214cdf0e10cSrcweir return 0; 215cdf0e10cSrcweir } 216cdf0e10cSrcweir 217cdf0e10cSrcweir // ----------------------------------------------------------------------------- 218cdf0e10cSrcweir 219cdf0e10cSrcweir sal_Int32 TableModel::getRight() 220cdf0e10cSrcweir { 221cdf0e10cSrcweir return getColumnCount(); 222cdf0e10cSrcweir } 223cdf0e10cSrcweir 224cdf0e10cSrcweir // ----------------------------------------------------------------------------- 225cdf0e10cSrcweir 226cdf0e10cSrcweir sal_Int32 TableModel::getBottom() 227cdf0e10cSrcweir { 228cdf0e10cSrcweir return getRowCount(); 229cdf0e10cSrcweir } 230cdf0e10cSrcweir 231cdf0e10cSrcweir // ----------------------------------------------------------------------------- 232cdf0e10cSrcweir 233cdf0e10cSrcweir Reference< XTable > TableModel::getTable() 234cdf0e10cSrcweir { 235cdf0e10cSrcweir return this; 236cdf0e10cSrcweir } 237cdf0e10cSrcweir 238cdf0e10cSrcweir // ----------------------------------------------------------------------------- 239cdf0e10cSrcweir 240cdf0e10cSrcweir void TableModel::UndoInsertRows( sal_Int32 nIndex, sal_Int32 nCount ) 241cdf0e10cSrcweir { 242cdf0e10cSrcweir TableModelNotifyGuard aGuard( this ); 243cdf0e10cSrcweir 244cdf0e10cSrcweir // remove the rows 245cdf0e10cSrcweir remove_range<RowVector,RowVector::iterator>( maRows, nIndex, nCount ); 246cdf0e10cSrcweir updateRows(); 247cdf0e10cSrcweir setModified(sal_True); 248cdf0e10cSrcweir } 249cdf0e10cSrcweir 250cdf0e10cSrcweir // ----------------------------------------------------------------------------- 251cdf0e10cSrcweir 252cdf0e10cSrcweir void TableModel::UndoRemoveRows( sal_Int32 nIndex, RowVector& aRows ) 253cdf0e10cSrcweir { 254cdf0e10cSrcweir TableModelNotifyGuard aGuard( this ); 255cdf0e10cSrcweir 256cdf0e10cSrcweir const sal_Int32 nCount = sal::static_int_cast< sal_Int32 >( aRows.size() ); 257cdf0e10cSrcweir 258cdf0e10cSrcweir nIndex = insert_range<RowVector,RowVector::iterator,TableRowRef>( maRows, nIndex, nCount ); 259cdf0e10cSrcweir 260cdf0e10cSrcweir for( sal_Int32 nOffset = 0; nOffset < nCount; ++nOffset ) 261cdf0e10cSrcweir maRows[nIndex+nOffset] = aRows[nOffset]; 262cdf0e10cSrcweir 263cdf0e10cSrcweir updateRows(); 264cdf0e10cSrcweir setModified(sal_True); 265cdf0e10cSrcweir } 266cdf0e10cSrcweir 267cdf0e10cSrcweir // ----------------------------------------------------------------------------- 268cdf0e10cSrcweir 269cdf0e10cSrcweir void TableModel::UndoInsertColumns( sal_Int32 nIndex, sal_Int32 nCount ) 270cdf0e10cSrcweir { 271cdf0e10cSrcweir TableModelNotifyGuard aGuard( this ); 272cdf0e10cSrcweir 273cdf0e10cSrcweir // now remove the columns 274cdf0e10cSrcweir remove_range<ColumnVector,ColumnVector::iterator>( maColumns, nIndex, nCount ); 275cdf0e10cSrcweir sal_Int32 nRows = getRowCountImpl(); 276cdf0e10cSrcweir while( nRows-- ) 277cdf0e10cSrcweir maRows[nRows]->removeColumns( nIndex, nCount ); 278cdf0e10cSrcweir 279cdf0e10cSrcweir updateColumns(); 280cdf0e10cSrcweir setModified(sal_True); 281cdf0e10cSrcweir } 282cdf0e10cSrcweir 283cdf0e10cSrcweir // ----------------------------------------------------------------------------- 284cdf0e10cSrcweir 285cdf0e10cSrcweir void TableModel::UndoRemoveColumns( sal_Int32 nIndex, ColumnVector& aCols, CellVector& aCells ) 286cdf0e10cSrcweir { 287cdf0e10cSrcweir TableModelNotifyGuard aGuard( this ); 288cdf0e10cSrcweir 289cdf0e10cSrcweir const sal_Int32 nCount = sal::static_int_cast< sal_Int32 >( aCols.size() ); 290cdf0e10cSrcweir 291cdf0e10cSrcweir // assert if there are not enough cells saved 292cdf0e10cSrcweir DBG_ASSERT( (aCols.size() * maRows.size()) == aCells.size(), "sdr::table::TableModel::UndoRemoveColumns(), invalid undo data!" ); 293cdf0e10cSrcweir 294cdf0e10cSrcweir nIndex = insert_range<ColumnVector,ColumnVector::iterator,TableColumnRef>( maColumns, nIndex, nCount ); 295cdf0e10cSrcweir for( sal_Int32 nOffset = 0; nOffset < nCount; ++nOffset ) 296cdf0e10cSrcweir maColumns[nIndex+nOffset] = aCols[nOffset]; 297cdf0e10cSrcweir 298cdf0e10cSrcweir CellVector::iterator aIter( aCells.begin() ); 299cdf0e10cSrcweir 300cdf0e10cSrcweir sal_Int32 nRows = getRowCountImpl(); 301cdf0e10cSrcweir for( sal_Int32 nRow = 0; nRow < nRows; ++nRow ) 30204f4019cSWang Lei { 30304f4019cSWang Lei CellVector::iterator aIter2 = aIter + nRow * nCount; 30404f4019cSWang Lei DBG_ASSERT(aIter2 < aCells.end(), "sdr::table::TableModel::UndoRemoveColumns(), invalid iterator!"); 30504f4019cSWang Lei maRows[nRow]->insertColumns( nIndex, nCount, &aIter2 ); 30604f4019cSWang Lei } 307cdf0e10cSrcweir 308cdf0e10cSrcweir updateColumns(); 309cdf0e10cSrcweir setModified(sal_True); 310cdf0e10cSrcweir } 311cdf0e10cSrcweir 312cdf0e10cSrcweir // ----------------------------------------------------------------------------- 313cdf0e10cSrcweir // XTable 314cdf0e10cSrcweir // ----------------------------------------------------------------------------- 315cdf0e10cSrcweir 316cdf0e10cSrcweir Reference< XCellCursor > SAL_CALL TableModel::createCursor() throw (RuntimeException) 317cdf0e10cSrcweir { 318cdf0e10cSrcweir OGuard aGuard( Application::GetSolarMutex() ); 319cdf0e10cSrcweir return createCursorByRange( Reference< XCellRange >( this ) ); 320cdf0e10cSrcweir } 321cdf0e10cSrcweir 322cdf0e10cSrcweir // ----------------------------------------------------------------------------- 323cdf0e10cSrcweir 324cdf0e10cSrcweir Reference< XCellCursor > SAL_CALL TableModel::createCursorByRange( const Reference< XCellRange >& Range ) throw (IllegalArgumentException, RuntimeException) 325cdf0e10cSrcweir { 326cdf0e10cSrcweir OGuard aGuard( Application::GetSolarMutex() ); 327cdf0e10cSrcweir 328cdf0e10cSrcweir ICellRange* pRange = dynamic_cast< ICellRange* >( Range.get() ); 329cdf0e10cSrcweir if( (pRange == 0) || (pRange->getTable().get() != this) ) 330cdf0e10cSrcweir throw IllegalArgumentException(); 331cdf0e10cSrcweir 332cdf0e10cSrcweir TableModelRef xModel( this ); 333cdf0e10cSrcweir return new CellCursor( xModel, pRange->getLeft(), pRange->getTop(), pRange->getRight(), pRange->getBottom() ); 334cdf0e10cSrcweir } 335cdf0e10cSrcweir 336cdf0e10cSrcweir // ----------------------------------------------------------------------------- 337cdf0e10cSrcweir 338cdf0e10cSrcweir sal_Int32 SAL_CALL TableModel::getRowCount() throw (RuntimeException) 339cdf0e10cSrcweir { 340cdf0e10cSrcweir OGuard aGuard( Application::GetSolarMutex() ); 341cdf0e10cSrcweir return getRowCountImpl(); 342cdf0e10cSrcweir } 343cdf0e10cSrcweir 344cdf0e10cSrcweir // ----------------------------------------------------------------------------- 345cdf0e10cSrcweir 346cdf0e10cSrcweir sal_Int32 SAL_CALL TableModel::getColumnCount() throw (RuntimeException) 347cdf0e10cSrcweir { 348cdf0e10cSrcweir OGuard aGuard( Application::GetSolarMutex() ); 349cdf0e10cSrcweir return getColumnCountImpl(); 350cdf0e10cSrcweir } 351cdf0e10cSrcweir 352cdf0e10cSrcweir // ----------------------------------------------------------------------------- 353cdf0e10cSrcweir // XComponent 354cdf0e10cSrcweir // ----------------------------------------------------------------------------- 355cdf0e10cSrcweir 356cdf0e10cSrcweir void TableModel::dispose() throw (RuntimeException) 357cdf0e10cSrcweir { 358cdf0e10cSrcweir OGuard aGuard( Application::GetSolarMutex() ); 359cdf0e10cSrcweir TableModelBase::dispose(); 360cdf0e10cSrcweir } 361cdf0e10cSrcweir 362cdf0e10cSrcweir // ----------------------------------------------------------------------------- 363cdf0e10cSrcweir 364cdf0e10cSrcweir void SAL_CALL TableModel::addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) 365cdf0e10cSrcweir { 366cdf0e10cSrcweir TableModelBase::addEventListener( xListener ); 367cdf0e10cSrcweir } 368cdf0e10cSrcweir 369cdf0e10cSrcweir // ----------------------------------------------------------------------------- 370cdf0e10cSrcweir 371cdf0e10cSrcweir void SAL_CALL TableModel::removeEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) 372cdf0e10cSrcweir { 373cdf0e10cSrcweir TableModelBase::removeEventListener( xListener ); 374cdf0e10cSrcweir } 375cdf0e10cSrcweir 376cdf0e10cSrcweir // ----------------------------------------------------------------------------- 377cdf0e10cSrcweir // XModifiable 378cdf0e10cSrcweir // ----------------------------------------------------------------------------- 379cdf0e10cSrcweir 380cdf0e10cSrcweir sal_Bool SAL_CALL TableModel::isModified( ) throw (RuntimeException) 381cdf0e10cSrcweir { 382cdf0e10cSrcweir OGuard aGuard( Application::GetSolarMutex() ); 383cdf0e10cSrcweir return mbModified; 384cdf0e10cSrcweir } 385cdf0e10cSrcweir 386cdf0e10cSrcweir // ----------------------------------------------------------------------------- 387cdf0e10cSrcweir 388cdf0e10cSrcweir void SAL_CALL TableModel::setModified( sal_Bool bModified ) throw (PropertyVetoException, RuntimeException) 389cdf0e10cSrcweir { 390cdf0e10cSrcweir { 391cdf0e10cSrcweir OGuard aGuard( Application::GetSolarMutex() ); 392cdf0e10cSrcweir mbModified = bModified; 393cdf0e10cSrcweir } 394cdf0e10cSrcweir if( bModified ) 395cdf0e10cSrcweir notifyModification(); 396cdf0e10cSrcweir } 397cdf0e10cSrcweir 398cdf0e10cSrcweir // ----------------------------------------------------------------------------- 399cdf0e10cSrcweir // XModifyBroadcaster 400cdf0e10cSrcweir // ----------------------------------------------------------------------------- 401cdf0e10cSrcweir 402cdf0e10cSrcweir void SAL_CALL TableModel::addModifyListener( const Reference< XModifyListener >& xListener ) throw (RuntimeException) 403cdf0e10cSrcweir { 404cdf0e10cSrcweir rBHelper.addListener( XModifyListener::static_type() , xListener ); 405cdf0e10cSrcweir } 406cdf0e10cSrcweir 407cdf0e10cSrcweir // ----------------------------------------------------------------------------- 408cdf0e10cSrcweir 409cdf0e10cSrcweir void SAL_CALL TableModel::removeModifyListener( const Reference< XModifyListener >& xListener ) throw (RuntimeException) 410cdf0e10cSrcweir { 411cdf0e10cSrcweir rBHelper.removeListener( XModifyListener::static_type() , xListener ); 412cdf0e10cSrcweir } 413cdf0e10cSrcweir 414cdf0e10cSrcweir // ----------------------------------------------------------------------------- 415cdf0e10cSrcweir // XColumnRowRange 416cdf0e10cSrcweir // ----------------------------------------------------------------------------- 417cdf0e10cSrcweir 418cdf0e10cSrcweir Reference< XTableColumns > SAL_CALL TableModel::getColumns() throw (RuntimeException) 419cdf0e10cSrcweir { 420cdf0e10cSrcweir OGuard aGuard( Application::GetSolarMutex() ); 421cdf0e10cSrcweir 422cdf0e10cSrcweir if( !mxTableColumns.is() ) 423cdf0e10cSrcweir mxTableColumns.set( new TableColumns( this ) ); 424cdf0e10cSrcweir return mxTableColumns.get(); 425cdf0e10cSrcweir } 426cdf0e10cSrcweir 427cdf0e10cSrcweir // ----------------------------------------------------------------------------- 428cdf0e10cSrcweir 429cdf0e10cSrcweir Reference< XTableRows > SAL_CALL TableModel::getRows() throw (RuntimeException) 430cdf0e10cSrcweir { 431cdf0e10cSrcweir OGuard aGuard( Application::GetSolarMutex() ); 432cdf0e10cSrcweir 433cdf0e10cSrcweir if( !mxTableRows.is() ) 434cdf0e10cSrcweir mxTableRows.set( new TableRows( this ) ); 435cdf0e10cSrcweir return mxTableRows.get(); 436cdf0e10cSrcweir } 437cdf0e10cSrcweir 438cdf0e10cSrcweir // ----------------------------------------------------------------------------- 439cdf0e10cSrcweir // XCellRange 440cdf0e10cSrcweir // ----------------------------------------------------------------------------- 441cdf0e10cSrcweir 442cdf0e10cSrcweir Reference< XCell > SAL_CALL TableModel::getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow ) throw ( IndexOutOfBoundsException, RuntimeException) 443cdf0e10cSrcweir { 444cdf0e10cSrcweir OGuard aGuard( Application::GetSolarMutex() ); 445cdf0e10cSrcweir 446cdf0e10cSrcweir CellRef xCell( getCell( nColumn, nRow ) ); 447cdf0e10cSrcweir if( xCell.is() ) 448cdf0e10cSrcweir return xCell.get(); 449cdf0e10cSrcweir 450cdf0e10cSrcweir throw IndexOutOfBoundsException(); 451cdf0e10cSrcweir } 452cdf0e10cSrcweir 453cdf0e10cSrcweir // ----------------------------------------------------------------------------- 454cdf0e10cSrcweir 455cdf0e10cSrcweir Reference< XCellRange > SAL_CALL TableModel::getCellRangeByPosition( sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ) throw (IndexOutOfBoundsException, RuntimeException) 456cdf0e10cSrcweir { 457cdf0e10cSrcweir OGuard aGuard( Application::GetSolarMutex() ); 458cdf0e10cSrcweir 459cdf0e10cSrcweir if( (nLeft >= 0) && (nTop >= 0) && (nRight >= nLeft) && (nBottom >= nTop) && (nRight < getColumnCountImpl()) && (nBottom < getRowCountImpl() ) ) 460cdf0e10cSrcweir { 461cdf0e10cSrcweir TableModelRef xModel( this ); 462cdf0e10cSrcweir return new CellRange( xModel, nLeft, nTop, nRight, nBottom ); 463cdf0e10cSrcweir } 464cdf0e10cSrcweir 465cdf0e10cSrcweir throw IndexOutOfBoundsException(); 466cdf0e10cSrcweir } 467cdf0e10cSrcweir 468cdf0e10cSrcweir // ----------------------------------------------------------------------------- 469cdf0e10cSrcweir 470cdf0e10cSrcweir Reference< XCellRange > SAL_CALL TableModel::getCellRangeByName( const OUString& /*aRange*/ ) throw (RuntimeException) 471cdf0e10cSrcweir { 472cdf0e10cSrcweir return Reference< XCellRange >(); 473cdf0e10cSrcweir } 474cdf0e10cSrcweir 475cdf0e10cSrcweir // ----------------------------------------------------------------------------- 476cdf0e10cSrcweir // XPropertySet 477cdf0e10cSrcweir // ----------------------------------------------------------------------------- 478cdf0e10cSrcweir 479cdf0e10cSrcweir Reference< XPropertySetInfo > SAL_CALL TableModel::getPropertySetInfo( ) throw (RuntimeException) 480cdf0e10cSrcweir { 481cdf0e10cSrcweir Reference< XPropertySetInfo > xInfo; 482cdf0e10cSrcweir return xInfo; 483cdf0e10cSrcweir } 484cdf0e10cSrcweir 485cdf0e10cSrcweir // ----------------------------------------------------------------------------- 486cdf0e10cSrcweir 487cdf0e10cSrcweir void SAL_CALL TableModel::setPropertyValue( const ::rtl::OUString& /*aPropertyName*/, const Any& /*aValue*/ ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) 488cdf0e10cSrcweir { 489cdf0e10cSrcweir } 490cdf0e10cSrcweir 491cdf0e10cSrcweir // ----------------------------------------------------------------------------- 492cdf0e10cSrcweir 493cdf0e10cSrcweir Any SAL_CALL TableModel::getPropertyValue( const OUString& /*PropertyName*/ ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) 494cdf0e10cSrcweir { 495cdf0e10cSrcweir return Any(); 496cdf0e10cSrcweir } 497cdf0e10cSrcweir 498cdf0e10cSrcweir // ----------------------------------------------------------------------------- 499cdf0e10cSrcweir 500cdf0e10cSrcweir void SAL_CALL TableModel::addPropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*xListener*/ ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) 501cdf0e10cSrcweir { 502cdf0e10cSrcweir } 503cdf0e10cSrcweir 504cdf0e10cSrcweir // ----------------------------------------------------------------------------- 505cdf0e10cSrcweir 506cdf0e10cSrcweir void SAL_CALL TableModel::removePropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*xListener*/ ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) 507cdf0e10cSrcweir { 508cdf0e10cSrcweir } 509cdf0e10cSrcweir 510cdf0e10cSrcweir // ----------------------------------------------------------------------------- 511cdf0e10cSrcweir 512cdf0e10cSrcweir void SAL_CALL TableModel::addVetoableChangeListener( const OUString& /*aPropertyName*/, const Reference< XVetoableChangeListener >& /*xListener*/ ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) 513cdf0e10cSrcweir { 514cdf0e10cSrcweir } 515cdf0e10cSrcweir 516cdf0e10cSrcweir // ----------------------------------------------------------------------------- 517cdf0e10cSrcweir 518cdf0e10cSrcweir void SAL_CALL TableModel::removeVetoableChangeListener( const OUString& /*aPropertyName*/, const Reference< XVetoableChangeListener >& /*xListener*/ ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) 519cdf0e10cSrcweir { 520cdf0e10cSrcweir } 521cdf0e10cSrcweir 522cdf0e10cSrcweir // ----------------------------------------------------------------------------- 523cdf0e10cSrcweir // XFastPropertySet 524cdf0e10cSrcweir // ----------------------------------------------------------------------------- 525cdf0e10cSrcweir 526cdf0e10cSrcweir void SAL_CALL TableModel::setFastPropertyValue( ::sal_Int32 /*nHandle*/, const Any& /*aValue*/ ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) 527cdf0e10cSrcweir { 528cdf0e10cSrcweir } 529cdf0e10cSrcweir 530cdf0e10cSrcweir // ----------------------------------------------------------------------------- 531cdf0e10cSrcweir 532cdf0e10cSrcweir Any SAL_CALL TableModel::getFastPropertyValue( ::sal_Int32 /*nHandle*/ ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) 533cdf0e10cSrcweir { 534cdf0e10cSrcweir Any aAny; 535cdf0e10cSrcweir return aAny; 536cdf0e10cSrcweir } 537cdf0e10cSrcweir 538cdf0e10cSrcweir // ----------------------------------------------------------------------------- 539cdf0e10cSrcweir // internals 540cdf0e10cSrcweir // ----------------------------------------------------------------------------- 541cdf0e10cSrcweir 542cdf0e10cSrcweir sal_Int32 TableModel::getRowCountImpl() const 543cdf0e10cSrcweir { 544cdf0e10cSrcweir return static_cast< sal_Int32 >( maRows.size() ); 545cdf0e10cSrcweir } 546cdf0e10cSrcweir 547cdf0e10cSrcweir // ----------------------------------------------------------------------------- 548cdf0e10cSrcweir 549cdf0e10cSrcweir sal_Int32 TableModel::getColumnCountImpl() const 550cdf0e10cSrcweir { 551cdf0e10cSrcweir return static_cast< sal_Int32 >( maColumns.size() ); 552cdf0e10cSrcweir } 553cdf0e10cSrcweir 554cdf0e10cSrcweir // ----------------------------------------------------------------------------- 555cdf0e10cSrcweir 556cdf0e10cSrcweir void TableModel::disposing() 557cdf0e10cSrcweir { 558cdf0e10cSrcweir if( !maRows.empty() ) 559cdf0e10cSrcweir { 560cdf0e10cSrcweir RowVector::iterator aIter( maRows.begin() ); 561cdf0e10cSrcweir while( aIter != maRows.end() ) 562cdf0e10cSrcweir (*aIter++)->dispose(); 563cdf0e10cSrcweir RowVector().swap(maRows); 564cdf0e10cSrcweir } 565cdf0e10cSrcweir 566cdf0e10cSrcweir if( !maColumns.empty() ) 567cdf0e10cSrcweir { 568cdf0e10cSrcweir ColumnVector::iterator aIter( maColumns.begin() ); 569cdf0e10cSrcweir while( aIter != maColumns.end() ) 570cdf0e10cSrcweir (*aIter++)->dispose(); 571cdf0e10cSrcweir ColumnVector().swap(maColumns); 572cdf0e10cSrcweir } 573cdf0e10cSrcweir 574cdf0e10cSrcweir if( mxTableColumns.is() ) 575cdf0e10cSrcweir { 576cdf0e10cSrcweir mxTableColumns->dispose(); 577cdf0e10cSrcweir mxTableColumns.clear(); 578cdf0e10cSrcweir } 579cdf0e10cSrcweir 580cdf0e10cSrcweir if( mxTableRows.is() ) 581cdf0e10cSrcweir { 582cdf0e10cSrcweir mxTableRows->dispose(); 583cdf0e10cSrcweir mxTableRows.clear(); 584cdf0e10cSrcweir } 585cdf0e10cSrcweir 586cdf0e10cSrcweir mpTableObj = 0; 587cdf0e10cSrcweir } 588cdf0e10cSrcweir 589cdf0e10cSrcweir // ----------------------------------------------------------------------------- 590cdf0e10cSrcweir // XBroadcaster 591cdf0e10cSrcweir // ----------------------------------------------------------------------------- 592cdf0e10cSrcweir 593cdf0e10cSrcweir void TableModel::lockBroadcasts() throw (RuntimeException) 594cdf0e10cSrcweir { 595cdf0e10cSrcweir OGuard aGuard( Application::GetSolarMutex() ); 596cdf0e10cSrcweir ++mnNotifyLock; 597cdf0e10cSrcweir } 598cdf0e10cSrcweir // ----------------------------------------------------------------------------- 599cdf0e10cSrcweir 600cdf0e10cSrcweir void TableModel::unlockBroadcasts() throw (RuntimeException) 601cdf0e10cSrcweir { 602cdf0e10cSrcweir OGuard aGuard( Application::GetSolarMutex() ); 603cdf0e10cSrcweir --mnNotifyLock; 604cdf0e10cSrcweir if( mnNotifyLock <= 0 ) 605cdf0e10cSrcweir { 606cdf0e10cSrcweir mnNotifyLock = 0; 607cdf0e10cSrcweir if( mbNotifyPending ) 608cdf0e10cSrcweir notifyModification(); 609cdf0e10cSrcweir } 610cdf0e10cSrcweir } 611cdf0e10cSrcweir 612cdf0e10cSrcweir // ----------------------------------------------------------------------------- 613cdf0e10cSrcweir #ifdef PLEASE_DEBUG_THE_TABLES 614cdf0e10cSrcweir #include <stdio.h> 615cdf0e10cSrcweir #endif 616cdf0e10cSrcweir 617cdf0e10cSrcweir void TableModel::notifyModification() 618cdf0e10cSrcweir { 619cdf0e10cSrcweir ::osl::MutexGuard guard( m_aMutex ); 620cdf0e10cSrcweir if( (mnNotifyLock == 0) && mpTableObj && mpTableObj->GetModel() ) 621cdf0e10cSrcweir { 622cdf0e10cSrcweir mbNotifyPending = false; 623cdf0e10cSrcweir 624cdf0e10cSrcweir ::cppu::OInterfaceContainerHelper * pModifyListeners = rBHelper.getContainer( XModifyListener::static_type() ); 625cdf0e10cSrcweir if( pModifyListeners ) 626cdf0e10cSrcweir { 627cdf0e10cSrcweir EventObject aSource; 628cdf0e10cSrcweir aSource.Source = static_cast< ::cppu::OWeakObject* >(this); 629cdf0e10cSrcweir pModifyListeners->notifyEach( &XModifyListener::modified, aSource); 630cdf0e10cSrcweir } 631cdf0e10cSrcweir } 632cdf0e10cSrcweir else 633cdf0e10cSrcweir { 634cdf0e10cSrcweir mbNotifyPending = true; 635cdf0e10cSrcweir } 636cdf0e10cSrcweir 637cdf0e10cSrcweir #ifdef PLEASE_DEBUG_THE_TABLES 638cdf0e10cSrcweir FILE* file = fopen( "c:\\table.xml","w" ); 639cdf0e10cSrcweir 640cdf0e10cSrcweir const sal_Int32 nColCount = getColumnCountImpl(); 641cdf0e10cSrcweir const sal_Int32 nRowCount = getRowCountImpl(); 642cdf0e10cSrcweir 643cdf0e10cSrcweir fprintf( file, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\r" ); 644cdf0e10cSrcweir fprintf( file, "<table columns=\"%ld\" rows=\"%ld\" updated=\"%s\">\n\r", nColCount, nRowCount, mbNotifyPending ? "false" : "true"); 645cdf0e10cSrcweir 646cdf0e10cSrcweir for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol ) 647cdf0e10cSrcweir { 648cdf0e10cSrcweir fprintf( file, "<column this=\"%lx\"/>\n\r", maColumns[nCol].get() ); 649cdf0e10cSrcweir } 650cdf0e10cSrcweir 651cdf0e10cSrcweir // first check merged cells before and inside the removed rows 652cdf0e10cSrcweir for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow ) 653cdf0e10cSrcweir { 654cdf0e10cSrcweir fprintf( file, "<row this=\"%lx\">\n\r", maRows[nRow].get() ); 655cdf0e10cSrcweir for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol ) 656cdf0e10cSrcweir { 657cdf0e10cSrcweir CellRef xCell( getCell( nCol, nRow ) ); 658cdf0e10cSrcweir fprintf( file, "<cell this=\"%lx\"", xCell.get() ); 659cdf0e10cSrcweir 660cdf0e10cSrcweir sal_Int32 nRowSpan = xCell->getRowSpan(); 661cdf0e10cSrcweir sal_Int32 nColSpan = xCell->getColumnSpan(); 662cdf0e10cSrcweir sal_Bool bMerged = xCell->isMerged(); 663cdf0e10cSrcweir 664cdf0e10cSrcweir if( nColSpan != 1 ) 665cdf0e10cSrcweir fprintf( file, " column-span=\"%ld\"", nColSpan ); 666cdf0e10cSrcweir if( nRowSpan != 1 ) 667cdf0e10cSrcweir fprintf( file, " row-span=\"%ld\"", nRowSpan ); 668cdf0e10cSrcweir 669cdf0e10cSrcweir if( bMerged ) 670cdf0e10cSrcweir fprintf( file, " merged=\"true\"" ); 671cdf0e10cSrcweir 672cdf0e10cSrcweir fprintf( file, "/>" ); 673cdf0e10cSrcweir } 674cdf0e10cSrcweir fprintf( file, "\n\r</row>\n\r" ); 675cdf0e10cSrcweir } 676cdf0e10cSrcweir 677cdf0e10cSrcweir fprintf( file, "</table>\n\r" ); 678cdf0e10cSrcweir fclose( file ); 679cdf0e10cSrcweir #endif 680cdf0e10cSrcweir } 681cdf0e10cSrcweir 682cdf0e10cSrcweir // ----------------------------------------------------------------------------- 683cdf0e10cSrcweir 684cdf0e10cSrcweir CellRef TableModel::getCell( sal_Int32 nCol, sal_Int32 nRow ) const 685cdf0e10cSrcweir { 686cdf0e10cSrcweir if( ((nRow >= 0) && (nRow < getRowCountImpl())) && (nCol >= 0) && (nCol < getColumnCountImpl()) ) 687cdf0e10cSrcweir { 688cdf0e10cSrcweir return maRows[nRow]->maCells[nCol]; 689cdf0e10cSrcweir } 690cdf0e10cSrcweir else 691cdf0e10cSrcweir { 692cdf0e10cSrcweir CellRef xRet; 693cdf0e10cSrcweir return xRet; 694cdf0e10cSrcweir } 695cdf0e10cSrcweir } 696cdf0e10cSrcweir 697cdf0e10cSrcweir // ----------------------------------------------------------------------------- 698cdf0e10cSrcweir /* 699cdf0e10cSrcweir bool TableModel::getCellPos( const CellRef& xCell, ::sal_Int32& rnCol, ::sal_Int32& rnRow ) const 700cdf0e10cSrcweir { 701cdf0e10cSrcweir const sal_Int32 nRowCount = getRowCount(); 702cdf0e10cSrcweir const sal_Int32 nColCount = getColumnCount(); 703cdf0e10cSrcweir for( rnRow = 0; rnRow < nRowCount; rnRow++ ) 704cdf0e10cSrcweir { 705cdf0e10cSrcweir for( rnCol = 0; rnCol < nColCount; rnCol++ ) 706cdf0e10cSrcweir { 707cdf0e10cSrcweir if( maRows[rnRow]->maCells[rnCol] == xCell ) 708cdf0e10cSrcweir { 709cdf0e10cSrcweir return true; 710cdf0e10cSrcweir } 711cdf0e10cSrcweir } 712cdf0e10cSrcweir } 713cdf0e10cSrcweir return false; 714cdf0e10cSrcweir } 715cdf0e10cSrcweir */ 716cdf0e10cSrcweir 717cdf0e10cSrcweir // ----------------------------------------------------------------------------- 718cdf0e10cSrcweir 719cdf0e10cSrcweir CellRef TableModel::createCell() 720cdf0e10cSrcweir { 721cdf0e10cSrcweir CellRef xCell; 722cdf0e10cSrcweir if( mpTableObj ) 723cdf0e10cSrcweir mpTableObj->createCell( xCell ); 724cdf0e10cSrcweir return xCell; 725cdf0e10cSrcweir } 726cdf0e10cSrcweir 727cdf0e10cSrcweir // ----------------------------------------------------------------------------- 728cdf0e10cSrcweir 729cdf0e10cSrcweir void TableModel::insertColumns( sal_Int32 nIndex, sal_Int32 nCount ) 730cdf0e10cSrcweir { 731cdf0e10cSrcweir if( nCount && mpTableObj ) 732cdf0e10cSrcweir { 733cdf0e10cSrcweir try 734cdf0e10cSrcweir { 735cdf0e10cSrcweir SdrModel* pModel = mpTableObj->GetModel(); 736cdf0e10cSrcweir 737cdf0e10cSrcweir TableModelNotifyGuard aGuard( this ); 738cdf0e10cSrcweir nIndex = insert_range<ColumnVector,ColumnVector::iterator,TableColumnRef>( maColumns, nIndex, nCount ); 739cdf0e10cSrcweir 740cdf0e10cSrcweir sal_Int32 nRows = getRowCountImpl(); 741cdf0e10cSrcweir while( nRows-- ) 742cdf0e10cSrcweir maRows[nRows]->insertColumns( nIndex, nCount ); 743cdf0e10cSrcweir 744cdf0e10cSrcweir ColumnVector aNewColumns(nCount); 745cdf0e10cSrcweir for( sal_Int32 nOffset = 0; nOffset < nCount; ++nOffset ) 746cdf0e10cSrcweir { 747cdf0e10cSrcweir TableColumnRef xNewCol( new TableColumn( this, nIndex+nOffset ) ); 748cdf0e10cSrcweir maColumns[nIndex+nOffset] = xNewCol; 749cdf0e10cSrcweir aNewColumns[nOffset] = xNewCol; 750cdf0e10cSrcweir } 751cdf0e10cSrcweir 752cdf0e10cSrcweir const bool bUndo = pModel && mpTableObj->IsInserted() && pModel->IsUndoEnabled(); 753cdf0e10cSrcweir if( bUndo ) 754cdf0e10cSrcweir { 755cdf0e10cSrcweir pModel->BegUndo( ImpGetResStr(STR_TABLE_INSCOL) ); 756cdf0e10cSrcweir pModel->AddUndo( pModel->GetSdrUndoFactory().CreateUndoGeoObject(*mpTableObj) ); 757cdf0e10cSrcweir 758cdf0e10cSrcweir TableModelRef xThis( this ); 759cdf0e10cSrcweir 760cdf0e10cSrcweir nRows = getRowCountImpl(); 761cdf0e10cSrcweir CellVector aNewCells( nCount * nRows ); 762cdf0e10cSrcweir CellVector::iterator aCellIter( aNewCells.begin() ); 763cdf0e10cSrcweir 764cdf0e10cSrcweir nRows = getRowCountImpl(); 765cdf0e10cSrcweir for( sal_Int32 nRow = 0; nRow < nRows; ++nRow ) 766cdf0e10cSrcweir { 767cdf0e10cSrcweir for( sal_Int32 nOffset = 0; nOffset < nCount; ++nOffset ) 768cdf0e10cSrcweir (*aCellIter++) = getCell( nIndex + nOffset, nRow ); 769cdf0e10cSrcweir } 770cdf0e10cSrcweir 771cdf0e10cSrcweir pModel->AddUndo( new InsertColUndo( xThis, nIndex, aNewColumns, aNewCells ) ); 772cdf0e10cSrcweir } 773cdf0e10cSrcweir 774cdf0e10cSrcweir const sal_Int32 nRowCount = getRowCountImpl(); 775cdf0e10cSrcweir // check if cells merge over new columns 776cdf0e10cSrcweir for( sal_Int32 nCol = 0; nCol < nIndex; ++nCol ) 777cdf0e10cSrcweir { 778cdf0e10cSrcweir for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow ) 779cdf0e10cSrcweir { 780cdf0e10cSrcweir CellRef xCell( getCell( nCol, nRow ) ); 781cdf0e10cSrcweir sal_Int32 nColSpan = (xCell.is() && !xCell->isMerged()) ? xCell->getColumnSpan() : 1; 782cdf0e10cSrcweir if( (nColSpan != 1) && ((nColSpan + nCol ) > nIndex) ) 783cdf0e10cSrcweir { 784cdf0e10cSrcweir // cell merges over newly created columns, so add the new columns to the merged cell 785cdf0e10cSrcweir const sal_Int32 nRowSpan = xCell->getRowSpan(); 786cdf0e10cSrcweir nColSpan += nCount; 787cdf0e10cSrcweir merge( nCol, nRow, nColSpan, nRowSpan ); 788cdf0e10cSrcweir } 789cdf0e10cSrcweir } 790cdf0e10cSrcweir } 791cdf0e10cSrcweir 792cdf0e10cSrcweir if( bUndo ) 793cdf0e10cSrcweir pModel->EndUndo(); 794cdf0e10cSrcweir 795cdf0e10cSrcweir if( pModel ) 796cdf0e10cSrcweir pModel->SetChanged(); 797cdf0e10cSrcweir 798cdf0e10cSrcweir } 799cdf0e10cSrcweir catch( Exception& ) 800cdf0e10cSrcweir { 801cdf0e10cSrcweir DBG_ERROR("sdr::table::TableModel::insertColumns(), exception caught!"); 802cdf0e10cSrcweir } 803cdf0e10cSrcweir updateColumns(); 804cdf0e10cSrcweir setModified(sal_True); 805cdf0e10cSrcweir } 806cdf0e10cSrcweir } 807cdf0e10cSrcweir 808cdf0e10cSrcweir // ----------------------------------------------------------------------------- 809cdf0e10cSrcweir 810cdf0e10cSrcweir void TableModel::removeColumns( sal_Int32 nIndex, sal_Int32 nCount ) 811cdf0e10cSrcweir { 812cdf0e10cSrcweir sal_Int32 nColCount = getColumnCountImpl(); 813cdf0e10cSrcweir 814cdf0e10cSrcweir if( mpTableObj && nCount && (nIndex >= 0) && (nIndex < nColCount) ) 815cdf0e10cSrcweir { 816cdf0e10cSrcweir try 817cdf0e10cSrcweir { 818cdf0e10cSrcweir TableModelNotifyGuard aGuard( this ); 819cdf0e10cSrcweir 820cdf0e10cSrcweir // clip removed columns to columns actually avalaible 821cdf0e10cSrcweir if( (nIndex + nCount) > nColCount ) 822cdf0e10cSrcweir nCount = nColCount - nIndex; 823cdf0e10cSrcweir 824cdf0e10cSrcweir sal_Int32 nRows = getRowCountImpl(); 825cdf0e10cSrcweir 826cdf0e10cSrcweir SdrModel* pModel = mpTableObj->GetModel(); 827cdf0e10cSrcweir 828cdf0e10cSrcweir const bool bUndo = pModel && mpTableObj->IsInserted() && pModel->IsUndoEnabled(); 829cdf0e10cSrcweir if( bUndo ) 830cdf0e10cSrcweir { 831cdf0e10cSrcweir pModel->BegUndo( ImpGetResStr(STR_UNDO_COL_DELETE) ); 832cdf0e10cSrcweir pModel->AddUndo( pModel->GetSdrUndoFactory().CreateUndoGeoObject(*mpTableObj) ); 833cdf0e10cSrcweir 834cdf0e10cSrcweir TableModelRef xThis( this ); 835cdf0e10cSrcweir ColumnVector aRemovedCols( nCount ); 836cdf0e10cSrcweir sal_Int32 nOffset; 837cdf0e10cSrcweir for( nOffset = 0; nOffset < nCount; ++nOffset ) 838cdf0e10cSrcweir { 839cdf0e10cSrcweir aRemovedCols[nOffset] = maColumns[nIndex+nOffset]; 840cdf0e10cSrcweir } 841cdf0e10cSrcweir 842cdf0e10cSrcweir CellVector aRemovedCells( nCount * nRows ); 843cdf0e10cSrcweir CellVector::iterator aCellIter( aRemovedCells.begin() ); 844cdf0e10cSrcweir for( sal_Int32 nRow = 0; nRow < nRows; ++nRow ) 845cdf0e10cSrcweir { 846cdf0e10cSrcweir for( nOffset = 0; nOffset < nCount; ++nOffset ) 847cdf0e10cSrcweir (*aCellIter++) = getCell( nIndex + nOffset, nRow ); 848cdf0e10cSrcweir } 849cdf0e10cSrcweir 850cdf0e10cSrcweir pModel->AddUndo( new RemoveColUndo( xThis, nIndex, aRemovedCols, aRemovedCells ) ); 851cdf0e10cSrcweir } 852cdf0e10cSrcweir 853cdf0e10cSrcweir // only rows before and inside the removed rows are considered 854cdf0e10cSrcweir nColCount = nIndex + nCount + 1; 855cdf0e10cSrcweir 856cdf0e10cSrcweir const sal_Int32 nRowCount = getRowCountImpl(); 857cdf0e10cSrcweir 858cdf0e10cSrcweir // first check merged cells before and inside the removed rows 859cdf0e10cSrcweir for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol ) 860cdf0e10cSrcweir { 861cdf0e10cSrcweir for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow ) 862cdf0e10cSrcweir { 863cdf0e10cSrcweir CellRef xCell( getCell( nCol, nRow ) ); 864cdf0e10cSrcweir sal_Int32 nColSpan = (xCell.is() && !xCell->isMerged()) ? xCell->getColumnSpan() : 1; 865cdf0e10cSrcweir if( nColSpan <= 1 ) 866cdf0e10cSrcweir continue; 867cdf0e10cSrcweir 868cdf0e10cSrcweir if( nCol >= nIndex ) 869cdf0e10cSrcweir { 870cdf0e10cSrcweir // current cell is inside the removed columns 871cdf0e10cSrcweir if( (nCol + nColSpan) > ( nIndex + nCount ) ) 872cdf0e10cSrcweir { 873cdf0e10cSrcweir // current cells merges with columns after the removed columns 874cdf0e10cSrcweir const sal_Int32 nRemove = nCount - nCol + nIndex; 875cdf0e10cSrcweir 876cdf0e10cSrcweir CellRef xTargetCell( getCell( nIndex + nCount, nRow ) ); 877cdf0e10cSrcweir if( xTargetCell.is() ) 878cdf0e10cSrcweir { 879cdf0e10cSrcweir if( bUndo ) 880cdf0e10cSrcweir xTargetCell->AddUndo(); 881cdf0e10cSrcweir xTargetCell->merge( nColSpan - nRemove, xCell->getRowSpan() ); 882*06fb39a1SJohn Bampton xTargetCell->replaceContentAndFormatting( xCell ); 883cdf0e10cSrcweir } 884cdf0e10cSrcweir } 885cdf0e10cSrcweir } 886cdf0e10cSrcweir else if( nColSpan > (nIndex - nCol) ) 887cdf0e10cSrcweir { 888cdf0e10cSrcweir // current cells spans inside the removed columns, so adjust 889cdf0e10cSrcweir const sal_Int32 nRemove = ::std::min( nCount, nCol + nColSpan - nIndex ); 890cdf0e10cSrcweir if( bUndo ) 891cdf0e10cSrcweir xCell->AddUndo(); 892cdf0e10cSrcweir xCell->merge( nColSpan - nRemove, xCell->getRowSpan() ); 893cdf0e10cSrcweir } 894cdf0e10cSrcweir } 895cdf0e10cSrcweir } 896cdf0e10cSrcweir 897cdf0e10cSrcweir // now remove the columns 898cdf0e10cSrcweir remove_range<ColumnVector,ColumnVector::iterator>( maColumns, nIndex, nCount ); 899cdf0e10cSrcweir while( nRows-- ) 900cdf0e10cSrcweir maRows[nRows]->removeColumns( nIndex, nCount ); 901cdf0e10cSrcweir 902cdf0e10cSrcweir if( bUndo ) 903cdf0e10cSrcweir pModel->EndUndo(); 904cdf0e10cSrcweir 905cdf0e10cSrcweir if( pModel ) 906cdf0e10cSrcweir pModel->SetChanged(); 907cdf0e10cSrcweir } 908cdf0e10cSrcweir catch( Exception& ) 909cdf0e10cSrcweir { 910cdf0e10cSrcweir DBG_ERROR("sdr::table::TableModel::removeColumns(), exception caught!"); 911cdf0e10cSrcweir } 912cdf0e10cSrcweir 913cdf0e10cSrcweir updateColumns(); 914cdf0e10cSrcweir setModified(sal_True); 915cdf0e10cSrcweir } 916cdf0e10cSrcweir } 917cdf0e10cSrcweir 918cdf0e10cSrcweir // ----------------------------------------------------------------------------- 919cdf0e10cSrcweir 920cdf0e10cSrcweir void TableModel::insertRows( sal_Int32 nIndex, sal_Int32 nCount ) 921cdf0e10cSrcweir { 922cdf0e10cSrcweir if( nCount && mpTableObj ) 923cdf0e10cSrcweir { 924cdf0e10cSrcweir SdrModel* pModel = mpTableObj->GetModel(); 925cdf0e10cSrcweir const bool bUndo = pModel && mpTableObj->IsInserted() && pModel->IsUndoEnabled(); 926cdf0e10cSrcweir try 927cdf0e10cSrcweir { 928cdf0e10cSrcweir TableModelNotifyGuard aGuard( this ); 929cdf0e10cSrcweir 930cdf0e10cSrcweir nIndex = insert_range<RowVector,RowVector::iterator,TableRowRef>( maRows, nIndex, nCount ); 931cdf0e10cSrcweir 932cdf0e10cSrcweir RowVector aNewRows(nCount); 933cdf0e10cSrcweir const sal_Int32 nColCount = getColumnCountImpl(); 934cdf0e10cSrcweir for( sal_Int32 nOffset = 0; nOffset < nCount; ++nOffset ) 935cdf0e10cSrcweir { 936cdf0e10cSrcweir TableRowRef xNewRow( new TableRow( this, nIndex+nOffset, nColCount ) ); 937cdf0e10cSrcweir maRows[nIndex+nOffset] = xNewRow; 938cdf0e10cSrcweir aNewRows[nOffset] = xNewRow; 939cdf0e10cSrcweir } 940cdf0e10cSrcweir 941cdf0e10cSrcweir if( bUndo ) 942cdf0e10cSrcweir { 943cdf0e10cSrcweir pModel->BegUndo( ImpGetResStr(STR_TABLE_INSROW) ); 944cdf0e10cSrcweir pModel->AddUndo( pModel->GetSdrUndoFactory().CreateUndoGeoObject(*mpTableObj) ); 945cdf0e10cSrcweir TableModelRef xThis( this ); 946cdf0e10cSrcweir pModel->AddUndo( new InsertRowUndo( xThis, nIndex, aNewRows ) ); 947cdf0e10cSrcweir } 948cdf0e10cSrcweir 949cdf0e10cSrcweir // check if cells merge over new columns 950cdf0e10cSrcweir for( sal_Int32 nRow = 0; nRow < nIndex; ++nRow ) 951cdf0e10cSrcweir { 952cdf0e10cSrcweir for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol ) 953cdf0e10cSrcweir { 954cdf0e10cSrcweir CellRef xCell( getCell( nCol, nRow ) ); 955cdf0e10cSrcweir sal_Int32 nRowSpan = (xCell.is() && !xCell->isMerged()) ? xCell->getRowSpan() : 1; 956cdf0e10cSrcweir if( (nRowSpan > 1) && ((nRowSpan + nRow) > nIndex) ) 957cdf0e10cSrcweir { 958cdf0e10cSrcweir // cell merges over newly created columns, so add the new columns to the merged cell 959cdf0e10cSrcweir const sal_Int32 nColSpan = xCell->getColumnSpan(); 960cdf0e10cSrcweir nRowSpan += nCount; 961cdf0e10cSrcweir merge( nCol, nRow, nColSpan, nRowSpan ); 962cdf0e10cSrcweir } 963cdf0e10cSrcweir } 964cdf0e10cSrcweir } 965cdf0e10cSrcweir } 966cdf0e10cSrcweir catch( Exception& ) 967cdf0e10cSrcweir { 968cdf0e10cSrcweir DBG_ERROR("sdr::table::TableModel::insertRows(), exception caught!"); 969cdf0e10cSrcweir } 970cdf0e10cSrcweir if( bUndo ) 971cdf0e10cSrcweir pModel->EndUndo(); 972cdf0e10cSrcweir 973cdf0e10cSrcweir if( pModel ) 974cdf0e10cSrcweir pModel->SetChanged(); 975cdf0e10cSrcweir 976cdf0e10cSrcweir updateRows(); 977cdf0e10cSrcweir setModified(sal_True); 978cdf0e10cSrcweir } 979cdf0e10cSrcweir } 980cdf0e10cSrcweir 981cdf0e10cSrcweir // ----------------------------------------------------------------------------- 982cdf0e10cSrcweir 983cdf0e10cSrcweir void TableModel::removeRows( sal_Int32 nIndex, sal_Int32 nCount ) 984cdf0e10cSrcweir { 985cdf0e10cSrcweir sal_Int32 nRowCount = getRowCountImpl(); 986cdf0e10cSrcweir 987cdf0e10cSrcweir if( mpTableObj && nCount && (nIndex >= 0) && (nIndex < nRowCount) ) 988cdf0e10cSrcweir { 989cdf0e10cSrcweir SdrModel* pModel = mpTableObj->GetModel(); 990cdf0e10cSrcweir const bool bUndo = pModel && mpTableObj->IsInserted()&& pModel->IsUndoEnabled(); 991cdf0e10cSrcweir 992cdf0e10cSrcweir try 993cdf0e10cSrcweir { 994cdf0e10cSrcweir TableModelNotifyGuard aGuard( this ); 995cdf0e10cSrcweir 996cdf0e10cSrcweir // clip removed rows to rows actually avalaible 997cdf0e10cSrcweir if( (nIndex + nCount) > nRowCount ) 998cdf0e10cSrcweir nCount = nRowCount - nIndex; 999cdf0e10cSrcweir 1000cdf0e10cSrcweir if( bUndo ) 1001cdf0e10cSrcweir { 1002cdf0e10cSrcweir pModel->BegUndo( ImpGetResStr(STR_UNDO_ROW_DELETE) ); 1003cdf0e10cSrcweir pModel->AddUndo( pModel->GetSdrUndoFactory().CreateUndoGeoObject(*mpTableObj) ); 1004cdf0e10cSrcweir 1005cdf0e10cSrcweir TableModelRef xThis( this ); 1006cdf0e10cSrcweir 1007cdf0e10cSrcweir RowVector aRemovedRows( nCount ); 1008cdf0e10cSrcweir for( sal_Int32 nOffset = 0; nOffset < nCount; ++nOffset ) 1009cdf0e10cSrcweir aRemovedRows[nOffset] = maRows[nIndex+nOffset]; 1010cdf0e10cSrcweir 1011cdf0e10cSrcweir pModel->AddUndo( new RemoveRowUndo( xThis, nIndex, aRemovedRows ) ); 1012cdf0e10cSrcweir } 1013cdf0e10cSrcweir 1014cdf0e10cSrcweir // only rows before and inside the removed rows are considered 1015cdf0e10cSrcweir nRowCount = nIndex + nCount + 1; 1016cdf0e10cSrcweir 1017cdf0e10cSrcweir const sal_Int32 nColCount = getColumnCountImpl(); 1018cdf0e10cSrcweir 1019cdf0e10cSrcweir // first check merged cells before and inside the removed rows 1020cdf0e10cSrcweir for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow ) 1021cdf0e10cSrcweir { 1022cdf0e10cSrcweir for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol ) 1023cdf0e10cSrcweir { 1024cdf0e10cSrcweir CellRef xCell( getCell( nCol, nRow ) ); 1025cdf0e10cSrcweir sal_Int32 nRowSpan = (xCell.is() && !xCell->isMerged()) ? xCell->getRowSpan() : 1; 1026cdf0e10cSrcweir if( nRowSpan <= 1 ) 1027cdf0e10cSrcweir continue; 1028cdf0e10cSrcweir 1029cdf0e10cSrcweir if( nRow >= nIndex ) 1030cdf0e10cSrcweir { 1031cdf0e10cSrcweir // current cell is inside the removed rows 1032cdf0e10cSrcweir if( (nRow + nRowSpan) > (nIndex + nCount) ) 1033cdf0e10cSrcweir { 1034cdf0e10cSrcweir // current cells merges with rows after the removed rows 1035cdf0e10cSrcweir const sal_Int32 nRemove = nCount - nRow + nIndex; 1036cdf0e10cSrcweir 1037cdf0e10cSrcweir CellRef xTargetCell( getCell( nCol, nIndex + nCount ) ); 1038cdf0e10cSrcweir if( xTargetCell.is() ) 1039cdf0e10cSrcweir { 1040cdf0e10cSrcweir if( bUndo ) 1041cdf0e10cSrcweir xTargetCell->AddUndo(); 1042cdf0e10cSrcweir xTargetCell->merge( xCell->getColumnSpan(), nRowSpan - nRemove ); 1043*06fb39a1SJohn Bampton xTargetCell->replaceContentAndFormatting( xCell ); 1044cdf0e10cSrcweir } 1045cdf0e10cSrcweir } 1046cdf0e10cSrcweir } 1047cdf0e10cSrcweir else if( nRowSpan > (nIndex - nRow) ) 1048cdf0e10cSrcweir { 1049cdf0e10cSrcweir // current cells spans inside the removed rows, so adjust 1050cdf0e10cSrcweir const sal_Int32 nRemove = ::std::min( nCount, nRow + nRowSpan - nIndex ); 1051cdf0e10cSrcweir if( bUndo ) 1052cdf0e10cSrcweir xCell->AddUndo(); 1053cdf0e10cSrcweir xCell->merge( xCell->getColumnSpan(), nRowSpan - nRemove ); 1054cdf0e10cSrcweir } 1055cdf0e10cSrcweir } 1056cdf0e10cSrcweir } 1057cdf0e10cSrcweir 1058cdf0e10cSrcweir // now remove the rows 1059cdf0e10cSrcweir remove_range<RowVector,RowVector::iterator>( maRows, nIndex, nCount ); 1060cdf0e10cSrcweir 1061cdf0e10cSrcweir if( bUndo ) 1062cdf0e10cSrcweir pModel->EndUndo(); 1063cdf0e10cSrcweir 1064cdf0e10cSrcweir if( pModel ) 1065cdf0e10cSrcweir pModel->SetChanged(); 1066cdf0e10cSrcweir } 1067cdf0e10cSrcweir catch( Exception& ) 1068cdf0e10cSrcweir { 1069cdf0e10cSrcweir DBG_ERROR("sdr::table::TableModel::removeRows(), exception caught!"); 1070cdf0e10cSrcweir } 1071cdf0e10cSrcweir 1072cdf0e10cSrcweir updateRows(); 1073cdf0e10cSrcweir setModified(sal_True); 1074cdf0e10cSrcweir } 1075cdf0e10cSrcweir } 1076cdf0e10cSrcweir 1077cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1078cdf0e10cSrcweir 1079cdf0e10cSrcweir TableRowRef TableModel::getRow( sal_Int32 nRow ) const throw (IndexOutOfBoundsException) 1080cdf0e10cSrcweir { 1081cdf0e10cSrcweir if( (nRow >= 0) && (nRow < getRowCountImpl()) ) 1082cdf0e10cSrcweir return maRows[nRow]; 1083cdf0e10cSrcweir 1084cdf0e10cSrcweir throw IndexOutOfBoundsException(); 1085cdf0e10cSrcweir } 1086cdf0e10cSrcweir 1087cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1088cdf0e10cSrcweir 1089cdf0e10cSrcweir TableColumnRef TableModel::getColumn( sal_Int32 nColumn ) const throw (IndexOutOfBoundsException) 1090cdf0e10cSrcweir { 1091cdf0e10cSrcweir if( (nColumn >= 0) && (nColumn < getColumnCountImpl()) ) 1092cdf0e10cSrcweir return maColumns[nColumn]; 1093cdf0e10cSrcweir 1094cdf0e10cSrcweir throw IndexOutOfBoundsException(); 1095cdf0e10cSrcweir } 1096cdf0e10cSrcweir 1097cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1098cdf0e10cSrcweir 1099cdf0e10cSrcweir /** deletes rows and columns that are completly merged. Must be called between BegUndo/EndUndo! */ 1100cdf0e10cSrcweir void TableModel::optimize() 1101cdf0e10cSrcweir { 1102cdf0e10cSrcweir TableModelNotifyGuard aGuard( this ); 1103cdf0e10cSrcweir 1104cdf0e10cSrcweir bool bWasModified = false; 1105cdf0e10cSrcweir 1106cdf0e10cSrcweir if( !maRows.empty() && !maColumns.empty() ) 1107cdf0e10cSrcweir { 1108cdf0e10cSrcweir sal_Int32 nCol = getColumnCountImpl() - 1; 1109cdf0e10cSrcweir while( nCol > 0 ) 1110cdf0e10cSrcweir { 1111cdf0e10cSrcweir bool bEmpty = true; 1112cdf0e10cSrcweir for( sal_Int32 nRow = 0; (nRow < getRowCountImpl()) && bEmpty; nRow++ ) 1113cdf0e10cSrcweir { 1114cdf0e10cSrcweir Reference< XMergeableCell > xCell( getCellByPosition( nCol, nRow ), UNO_QUERY ); 1115cdf0e10cSrcweir if( xCell.is() && !xCell->isMerged() ) 1116cdf0e10cSrcweir bEmpty = false; 1117cdf0e10cSrcweir } 1118cdf0e10cSrcweir 1119cdf0e10cSrcweir if( bEmpty ) 1120cdf0e10cSrcweir { 1121cdf0e10cSrcweir if( nCol > 0 ) try 1122cdf0e10cSrcweir { 1123cdf0e10cSrcweir const OUString sWidth( RTL_CONSTASCII_USTRINGPARAM("Width") ); 1124cdf0e10cSrcweir sal_Int32 nWidth1 = 0, nWidth2 = 0; 1125cdf0e10cSrcweir Reference< XPropertySet > xSet1( static_cast< XCellRange* >( maColumns[nCol].get() ), UNO_QUERY_THROW ); 1126cdf0e10cSrcweir Reference< XPropertySet > xSet2( static_cast< XCellRange* >( maColumns[nCol-1].get() ), UNO_QUERY_THROW ); 1127cdf0e10cSrcweir xSet1->getPropertyValue( sWidth ) >>= nWidth1; 1128cdf0e10cSrcweir xSet2->getPropertyValue( sWidth ) >>= nWidth2; 1129cdf0e10cSrcweir nWidth1 += nWidth2; 1130cdf0e10cSrcweir xSet2->setPropertyValue( sWidth, Any( nWidth1 ) ); 1131cdf0e10cSrcweir } 1132cdf0e10cSrcweir catch( Exception& e ) 1133cdf0e10cSrcweir { 1134cdf0e10cSrcweir (void)e; 1135cdf0e10cSrcweir DBG_ERROR("svx::TableModel::optimize(), exception caught!"); 1136cdf0e10cSrcweir } 1137cdf0e10cSrcweir 1138cdf0e10cSrcweir removeColumns( nCol, 1 ); 1139cdf0e10cSrcweir bWasModified = true; 1140cdf0e10cSrcweir } 1141cdf0e10cSrcweir 1142cdf0e10cSrcweir nCol--; 1143cdf0e10cSrcweir } 1144cdf0e10cSrcweir 1145cdf0e10cSrcweir sal_Int32 nRow = getRowCountImpl() - 1; 1146cdf0e10cSrcweir while( nRow > 0 ) 1147cdf0e10cSrcweir { 1148cdf0e10cSrcweir bool bEmpty = true; 1149cdf0e10cSrcweir for( nCol = 0; (nCol < getColumnCountImpl()) && bEmpty; nCol++ ) 1150cdf0e10cSrcweir { 1151cdf0e10cSrcweir Reference< XMergeableCell > xCell( getCellByPosition( nCol, nRow ), UNO_QUERY ); 1152cdf0e10cSrcweir if( xCell.is() && !xCell->isMerged() ) 1153cdf0e10cSrcweir bEmpty = false; 1154cdf0e10cSrcweir } 1155cdf0e10cSrcweir 1156cdf0e10cSrcweir if( bEmpty ) 1157cdf0e10cSrcweir { 1158cdf0e10cSrcweir if( nRow > 0 ) try 1159cdf0e10cSrcweir { 1160cdf0e10cSrcweir const OUString sHeight( RTL_CONSTASCII_USTRINGPARAM("Height") ); 1161cdf0e10cSrcweir sal_Int32 nHeight1 = 0, nHeight2 = 0; 1162cdf0e10cSrcweir Reference< XPropertySet > xSet1( static_cast< XCellRange* >( maRows[nRow].get() ), UNO_QUERY_THROW ); 1163cdf0e10cSrcweir Reference< XPropertySet > xSet2( static_cast< XCellRange* >( maRows[nRow-1].get() ), UNO_QUERY_THROW ); 1164cdf0e10cSrcweir xSet1->getPropertyValue( sHeight ) >>= nHeight1; 1165cdf0e10cSrcweir xSet2->getPropertyValue( sHeight ) >>= nHeight2; 1166cdf0e10cSrcweir nHeight1 += nHeight2; 1167cdf0e10cSrcweir xSet2->setPropertyValue( sHeight, Any( nHeight1 ) ); 1168cdf0e10cSrcweir } 1169cdf0e10cSrcweir catch( Exception& e ) 1170cdf0e10cSrcweir { 1171cdf0e10cSrcweir (void)e; 1172cdf0e10cSrcweir DBG_ERROR("svx::TableModel::optimize(), exception caught!"); 1173cdf0e10cSrcweir } 1174cdf0e10cSrcweir 1175cdf0e10cSrcweir removeRows( nRow, 1 ); 1176cdf0e10cSrcweir bWasModified = true; 1177cdf0e10cSrcweir } 1178cdf0e10cSrcweir 1179cdf0e10cSrcweir nRow--; 1180cdf0e10cSrcweir } 1181cdf0e10cSrcweir } 1182cdf0e10cSrcweir if( bWasModified ) 1183cdf0e10cSrcweir setModified(sal_True); 1184cdf0e10cSrcweir } 1185cdf0e10cSrcweir 1186cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1187cdf0e10cSrcweir 1188cdf0e10cSrcweir void TableModel::merge( sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nColSpan, sal_Int32 nRowSpan ) 1189cdf0e10cSrcweir { 1190cdf0e10cSrcweir SdrModel* pModel = mpTableObj->GetModel(); 1191cdf0e10cSrcweir 1192cdf0e10cSrcweir const bool bUndo = pModel && mpTableObj->IsInserted() && pModel->IsUndoEnabled(); 1193cdf0e10cSrcweir 1194cdf0e10cSrcweir const sal_Int32 nLastRow = nRow + nRowSpan; 1195cdf0e10cSrcweir const sal_Int32 nLastCol = nCol + nColSpan; 1196cdf0e10cSrcweir 1197cdf0e10cSrcweir if( (nLastRow > getRowCount()) || (nLastCol > getRowCount() ) ) 1198cdf0e10cSrcweir { 1199cdf0e10cSrcweir DBG_ERROR("TableModel::merge(), merge beyound the table!"); 1200cdf0e10cSrcweir } 1201cdf0e10cSrcweir 1202cdf0e10cSrcweir // merge first cell 1203cdf0e10cSrcweir CellRef xOriginCell( dynamic_cast< Cell* >( getCellByPosition( nCol, nRow ).get() ) ); 1204cdf0e10cSrcweir if( xOriginCell.is() ) 1205cdf0e10cSrcweir { 1206cdf0e10cSrcweir if( bUndo ) 1207cdf0e10cSrcweir xOriginCell->AddUndo(); 1208cdf0e10cSrcweir xOriginCell->merge( nColSpan, nRowSpan ); 1209cdf0e10cSrcweir } 1210cdf0e10cSrcweir 1211cdf0e10cSrcweir sal_Int32 nTempCol = nCol + 1; 1212cdf0e10cSrcweir 1213cdf0e10cSrcweir // merge remaining cells 1214cdf0e10cSrcweir for( ; nRow < nLastRow; nRow++ ) 1215cdf0e10cSrcweir { 1216cdf0e10cSrcweir for( ; nTempCol < nLastCol; nTempCol++ ) 1217cdf0e10cSrcweir { 1218cdf0e10cSrcweir CellRef xCell( dynamic_cast< Cell* >( getCellByPosition( nTempCol, nRow ).get() ) ); 1219cdf0e10cSrcweir if( xCell.is() && !xCell->isMerged() ) 1220cdf0e10cSrcweir { 1221cdf0e10cSrcweir if( bUndo ) 1222cdf0e10cSrcweir xCell->AddUndo(); 1223cdf0e10cSrcweir xCell->setMerged(); 1224cdf0e10cSrcweir xOriginCell->mergeContent( xCell ); 1225cdf0e10cSrcweir } 1226cdf0e10cSrcweir } 1227cdf0e10cSrcweir nTempCol = nCol; 1228cdf0e10cSrcweir } 1229cdf0e10cSrcweir } 1230cdf0e10cSrcweir 1231cdf0e10cSrcweir 1232cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1233cdf0e10cSrcweir 1234cdf0e10cSrcweir void TableModel::updateRows() 1235cdf0e10cSrcweir { 1236cdf0e10cSrcweir sal_Int32 nRow = 0; 1237cdf0e10cSrcweir RowVector::iterator iter = maRows.begin(); 1238cdf0e10cSrcweir while( iter != maRows.end() ) 1239cdf0e10cSrcweir { 1240cdf0e10cSrcweir (*iter++)->mnRow = nRow++; 1241cdf0e10cSrcweir } 1242cdf0e10cSrcweir } 1243cdf0e10cSrcweir 1244cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1245cdf0e10cSrcweir 1246cdf0e10cSrcweir void TableModel::updateColumns() 1247cdf0e10cSrcweir { 1248cdf0e10cSrcweir sal_Int32 nColumn = 0; 1249cdf0e10cSrcweir ColumnVector::iterator iter = maColumns.begin(); 1250cdf0e10cSrcweir while( iter != maColumns.end() ) 1251cdf0e10cSrcweir { 1252cdf0e10cSrcweir (*iter++)->mnColumn = nColumn++; 1253cdf0e10cSrcweir } 1254cdf0e10cSrcweir } 1255cdf0e10cSrcweir 1256cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1257cdf0e10cSrcweir 1258cdf0e10cSrcweir } } 1259