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