LCOV - code coverage report
Current view: top level - svx/source/table - tablemodel.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 280 540 51.9 %
Date: 2014-11-03 Functions: 36 63 57.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10