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

Generated by: LCOV version 1.10