LCOV - code coverage report
Current view: top level - libreoffice/svx/source/table - tablelayouter.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 304 521 58.3 %
Date: 2012-12-27 Functions: 20 32 62.5 %
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             : #include <com/sun/star/awt/XLayoutConstrains.hpp>
      23             : 
      24             : #include "cell.hxx"
      25             : #include "cellrange.hxx"
      26             : #include "tablemodel.hxx"
      27             : #include "tablerow.hxx"
      28             : #include "tablerows.hxx"
      29             : #include "tablecolumn.hxx"
      30             : #include "tablecolumns.hxx"
      31             : #include "tablelayouter.hxx"
      32             : #include "svx/svdotable.hxx"
      33             : #include "editeng/borderline.hxx"
      34             : #include "editeng/boxitem.hxx"
      35             : #include "svx/svdmodel.hxx"
      36             : #include "svx/svdstr.hrc"
      37             : #include "svx/svdglob.hxx"
      38             : 
      39             : using ::editeng::SvxBorderLine;
      40             : using ::rtl::OUString;
      41             : using ::com::sun::star::awt::XLayoutConstrains;
      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::table;
      48             : using namespace ::com::sun::star::text;
      49             : 
      50             : // -----------------------------------------------------------------------------
      51             : 
      52             : namespace sdr { namespace table {
      53             : 
      54             : // -----------------------------------------------------------------------------
      55             : 
      56          21 : static SvxBorderLine gEmptyBorder;
      57             : 
      58             : // -----------------------------------------------------------------------------
      59             : 
      60          35 : TableLayouter::TableLayouter( const TableModelRef& xTableModel )
      61             : : mxTable( xTableModel )
      62             : , meWritingMode( WritingMode_LR_TB )
      63          35 : , msSize( RTL_CONSTASCII_USTRINGPARAM( "Size" ) )
      64             : {
      65          35 : }
      66             : 
      67             : // -----------------------------------------------------------------------------
      68             : 
      69         105 : TableLayouter::~TableLayouter()
      70             : {
      71          35 :     ClearBorderLayout();
      72          70 : }
      73             : 
      74             : // -----------------------------------------------------------------------------
      75             : 
      76        2322 : basegfx::B2ITuple TableLayouter::getCellSize( const CellPos& rPos  ) const
      77             : {
      78        2322 :     sal_Int32 width = 0;
      79        2322 :     sal_Int32 height = 0;
      80             : 
      81             :     try
      82             :     {
      83        2322 :         CellRef xCell( getCell( rPos ) );
      84        2322 :         if( xCell.is() && !xCell->isMerged() )
      85             :         {
      86        2322 :             CellPos aPos( rPos );
      87             : 
      88        2322 :             sal_Int32 nRowCount = getRowCount();
      89        2322 :             sal_Int32 nRowSpan = std::max( xCell->getRowSpan(), (sal_Int32)1 );
      90        7022 :             while( nRowSpan && (aPos.mnRow < nRowCount) )
      91             :             {
      92        2378 :                 if( ((sal_Int32)maRows.size()) <= aPos.mnRow )
      93           0 :                     break;
      94             : 
      95        2378 :                 height += maRows[aPos.mnRow++].mnSize;
      96        2378 :                 nRowSpan--;
      97             :             }
      98             : 
      99        2322 :             sal_Int32 nColCount = getColumnCount();
     100        2322 :             sal_Int32 nColSpan = std::max( xCell->getColumnSpan(), (sal_Int32)1 );
     101        6966 :             while( nColSpan && (aPos.mnCol < nColCount ) )
     102             :             {
     103        2322 :                 if( ((sal_Int32)maColumns.size()) <= aPos.mnCol )
     104           0 :                     break;
     105             : 
     106        2322 :                 width += maColumns[aPos.mnCol++].mnSize;
     107        2322 :                 nColSpan--;
     108             :             }
     109        2322 :         }
     110             :     }
     111           0 :     catch( Exception& )
     112             :     {
     113             :         OSL_FAIL( "TableLayouter::getCellSize(), exception caught!" );
     114             :     }
     115             : 
     116        2322 :     return basegfx::B2ITuple( width, height );
     117             : }
     118             : 
     119             : // -----------------------------------------------------------------------------
     120             : 
     121        2378 : bool TableLayouter::getCellArea( const CellPos& rPos, basegfx::B2IRectangle& rArea ) const
     122             : {
     123             :     try
     124             :     {
     125        2378 :         CellRef xCell( getCell( rPos ) );
     126        2378 :         if( xCell.is() && !xCell->isMerged() && isValid(rPos) )
     127             :         {
     128        2322 :             const basegfx::B2ITuple aCellSize( getCellSize( rPos ) );
     129             : 
     130        2322 :             if( (rPos.mnCol < ((sal_Int32)maColumns.size()) && (rPos.mnRow < ((sal_Int32)maRows.size()) ) ) )
     131             :             {
     132        2322 :                 const sal_Int32 x = maColumns[rPos.mnCol].mnPos;
     133        2322 :                 const sal_Int32 y = maRows[rPos.mnRow].mnPos;
     134             : 
     135        2322 :                 rArea = basegfx::B2IRectangle( x, y, x + aCellSize.getX(), y + aCellSize.getY()  );
     136        2322 :                 return true;
     137        2322 :             }
     138        2378 :         }
     139             :     }
     140           0 :     catch( Exception& )
     141             :     {
     142             :         OSL_FAIL( "TableLayouter::getCellSize(), exception caught!" );
     143             :     }
     144          56 :     return false;
     145             : }
     146             : 
     147             : // -----------------------------------------------------------------------------
     148           0 : sal_Int32 TableLayouter::getRowHeight( sal_Int32 nRow ) const
     149             : {
     150           0 :     if( isValidRow(nRow) )
     151           0 :         return maRows[nRow].mnSize;
     152             :     else
     153           0 :         return 0;
     154             : }
     155             : 
     156             : // -----------------------------------------------------------------------------
     157           0 : sal_Int32 TableLayouter::getColumnWidth( sal_Int32 nColumn ) const
     158             : {
     159           0 :     if( isValidColumn(nColumn) )
     160           0 :         return maColumns[nColumn].mnSize;
     161             :     else
     162           0 :         return 0;
     163             : }
     164             : 
     165             : // -----------------------------------------------------------------------------
     166             : 
     167           0 : bool TableLayouter::isEdgeVisible( sal_Int32 nEdgeX, sal_Int32 nEdgeY, bool bHorizontal ) const
     168             : {
     169           0 :     const BorderLineMap& rMap = bHorizontal ? maHorizontalBorders : maVerticalBorders;
     170             : 
     171           0 :     if( (nEdgeX >= 0) && (nEdgeX < sal::static_int_cast<sal_Int32>(rMap.size())) &&
     172           0 :         (nEdgeY >= 0) && (nEdgeY < sal::static_int_cast<sal_Int32>(rMap[nEdgeX].size())) )
     173             :     {
     174           0 :         return rMap[nEdgeX][nEdgeY] != 0;
     175             :     }
     176             :     else
     177             :     {
     178             :         OSL_FAIL( "sdr::table::TableLayouter::getBorderLine(), invalid edge!" );
     179             :     }
     180             : 
     181           0 :     return false;
     182             : }
     183             : 
     184             : // -----------------------------------------------------------------------------
     185             : 
     186             : /** returns the requested borderline in rpBorderLine or a null pointer if there is no border at this edge */
     187           0 : SvxBorderLine* TableLayouter::getBorderLine( sal_Int32 nEdgeX, sal_Int32 nEdgeY, bool bHorizontal )const
     188             : {
     189           0 :     SvxBorderLine* pLine = 0;
     190             : 
     191           0 :     const BorderLineMap& rMap = bHorizontal ? maHorizontalBorders : maVerticalBorders;
     192             : 
     193           0 :     if( (nEdgeX >= 0) && (nEdgeX < sal::static_int_cast<sal_Int32>(rMap.size())) &&
     194           0 :         (nEdgeY >= 0) && (nEdgeY < sal::static_int_cast<sal_Int32>(rMap[nEdgeX].size())) )
     195             :     {
     196           0 :         pLine = rMap[nEdgeX][nEdgeY];
     197           0 :         if( pLine == &gEmptyBorder )
     198           0 :             pLine = 0;
     199             :     }
     200             :     else
     201             :     {
     202             :         OSL_FAIL( "sdr::table::TableLayouter::getBorderLine(), invalid edge!" );
     203             :     }
     204             : 
     205           0 :     return pLine;
     206             : }
     207             : 
     208             : // -----------------------------------------------------------------------------
     209             : 
     210           0 : sal_Int32 TableLayouter::getHorizontalEdge( int nEdgeY, sal_Int32* pnMin /*= 0*/, sal_Int32* pnMax /*= 0*/ )
     211             : {
     212           0 :     sal_Int32 nRet = 0;
     213           0 :     if( (nEdgeY >= 0) && (nEdgeY <= getRowCount() ) )
     214           0 :         nRet = maRows[std::min((sal_Int32)nEdgeY,getRowCount()-1)].mnPos;
     215             : 
     216           0 :     if( nEdgeY == getRowCount() )
     217           0 :         nRet += maRows[nEdgeY - 1].mnSize;
     218             : 
     219           0 :     if( pnMin )
     220             :     {
     221           0 :         if( (nEdgeY > 0) && (nEdgeY <= getRowCount() ) )
     222             :         {
     223           0 :             *pnMin = maRows[nEdgeY-1].mnPos + 600; // todo
     224             :         }
     225             :         else
     226             :         {
     227           0 :             *pnMin = nRet;
     228             :         }
     229             :     }
     230             : 
     231           0 :     if( pnMax )
     232             :     {
     233           0 :         *pnMax = 0x0fffffff;
     234             :     }
     235           0 :     return nRet;
     236             : }
     237             : 
     238             : // -----------------------------------------------------------------------------
     239             : 
     240           0 : sal_Int32 TableLayouter::getVerticalEdge( int nEdgeX, sal_Int32* pnMin /*= 0*/, sal_Int32* pnMax /*= 0*/ )
     241             : {
     242           0 :     sal_Int32 nRet = 0;
     243             : 
     244           0 :     const sal_Int32 nColCount = getColumnCount();
     245           0 :     if( (nEdgeX >= 0) && (nEdgeX <= nColCount ) )
     246           0 :         nRet = maColumns[std::min((sal_Int32)nEdgeX,nColCount-1)].mnPos;
     247             : 
     248           0 :     const bool bRTL = meWritingMode == WritingMode_RL_TB;
     249           0 :     if( bRTL )
     250             :     {
     251           0 :         if( (nEdgeX >= 0) && (nEdgeX < nColCount) )
     252           0 :             nRet += maColumns[nEdgeX].mnSize;
     253             :     }
     254             :     else
     255             :     {
     256           0 :         if( nEdgeX == getColumnCount() )
     257           0 :             nRet += maColumns[nEdgeX - 1].mnSize;
     258             :     }
     259             : 
     260           0 :     if( pnMin )
     261             :     {
     262           0 :         *pnMin = nRet;
     263           0 :         if( bRTL )
     264             :         {
     265           0 :             if( nEdgeX < nColCount )
     266           0 :                 *pnMin = nRet - maColumns[nEdgeX].mnSize + getMinimumColumnWidth(nEdgeX);
     267             :         }
     268             :         else
     269             :         {
     270           0 :             if( (nEdgeX > 0) && (nEdgeX <= nColCount ) )
     271           0 :                 *pnMin = maColumns[nEdgeX-1].mnPos + getMinimumColumnWidth( nEdgeX-1 );
     272             :         }
     273             :     }
     274             : 
     275           0 :     if( pnMax )
     276             :     {
     277           0 :         *pnMax = 0x0fffffff; // todo
     278           0 :         if( bRTL )
     279             :         {
     280           0 :             if( nEdgeX > 0 )
     281           0 :                 *pnMax = nRet + maColumns[nEdgeX-1].mnSize - getMinimumColumnWidth( nEdgeX-1 );
     282             :         }
     283             :         else
     284             :         {
     285           0 :             if( (nEdgeX >= 0) && (nEdgeX < nColCount ) )
     286           0 :                 *pnMax = maColumns[nEdgeX].mnPos + maColumns[nEdgeX].mnSize - getMinimumColumnWidth( nEdgeX );
     287             :         }
     288             :     }
     289             : 
     290           0 :     return nRet;
     291             : }
     292             : 
     293             : // -----------------------------------------------------------------------------
     294             : 
     295           0 : static bool checkMergeOrigin( const TableModelRef& xTable, sal_Int32 nMergedX, sal_Int32 nMergedY, sal_Int32 nCellX, sal_Int32 nCellY, bool& bRunning )
     296             : {
     297           0 :     Reference< XMergeableCell > xCell( xTable->getCellByPosition( nCellX, nCellY ), UNO_QUERY );
     298           0 :     if( xCell.is() && !xCell->isMerged() )
     299             :     {
     300           0 :         const sal_Int32 nRight = xCell->getColumnSpan() + nCellX;
     301           0 :         const sal_Int32 nBottom = xCell->getRowSpan() + nCellY;
     302           0 :         if( (nMergedX < nRight) && (nMergedY < nBottom) )
     303           0 :             return true;
     304             : 
     305           0 :         bRunning = false;
     306             :     }
     307           0 :     return false;
     308             : }
     309             : 
     310             : /** returns true if the cell(nMergedX,nMergedY) is merged with other cells.
     311             :     the returned cell( rOriginX, rOriginY ) is the origin( top left cell ) of the merge.
     312             : */
     313           0 : bool findMergeOrigin( const TableModelRef& xTable, sal_Int32 nMergedX, sal_Int32 nMergedY, sal_Int32& rOriginX, sal_Int32& rOriginY )
     314             : {
     315           0 :     rOriginX = nMergedX;
     316           0 :     rOriginY = nMergedY;
     317             : 
     318           0 :     if( xTable.is() ) try
     319             :     {
     320             :         // check if this cell already the origin or not merged at all
     321           0 :         Reference< XMergeableCell > xCell( xTable->getCellByPosition( nMergedX, nMergedY ), UNO_QUERY_THROW );
     322           0 :         if( !xCell.is() || !xCell->isMerged() )
     323           0 :             return true;
     324             : 
     325           0 :         bool bCheckVert = true;
     326           0 :         bool bCheckHorz = true;
     327             : 
     328           0 :         sal_Int32 nMinCol = 0;
     329           0 :         sal_Int32 nMinRow = 0;
     330             : 
     331           0 :         sal_Int32 nStep = 1, i;
     332             : 
     333             :         sal_Int32 nRow, nCol;
     334           0 :         do
     335             :         {
     336           0 :             if( bCheckVert )
     337             :             {
     338           0 :                 nRow = nMergedY - nStep;
     339           0 :                 if( nRow >= nMinRow )
     340             :                 {
     341           0 :                     nCol = nMergedX;
     342           0 :                     for( i = 0; (i <= nStep) && (nCol >= nMinCol); i++, nCol-- )
     343             :                     {
     344           0 :                         if( checkMergeOrigin( xTable, nMergedX, nMergedY, nCol, nRow, bCheckVert ) )
     345             :                         {
     346           0 :                             rOriginX = nCol; rOriginY = nRow;
     347           0 :                             return true;
     348             :                         }
     349             : 
     350           0 :                         if( !bCheckVert )
     351             :                         {
     352           0 :                             if( nCol == nMergedX )
     353             :                             {
     354           0 :                                 nMinRow = nRow+1;
     355             :                             }
     356             :                             else
     357             :                             {
     358           0 :                                 bCheckVert = true;
     359             :                             }
     360           0 :                             break;
     361             :                         }
     362             :                     }
     363             :                 }
     364             :                 else
     365             :                 {
     366           0 :                     bCheckVert = false;
     367             :                 }
     368             :             }
     369             : 
     370           0 :             if( bCheckHorz )
     371             :             {
     372           0 :                 nCol = nMergedX - nStep;
     373           0 :                 if( nCol >= nMinCol )
     374             :                 {
     375           0 :                     nRow = nMergedY;
     376           0 :                     for( i = 0; (i < nStep) && (nRow >= nMinRow); i++, nRow-- )
     377             :                     {
     378           0 :                         if( checkMergeOrigin( xTable, nMergedX, nMergedY, nCol, nRow, bCheckHorz ) )
     379             :                         {
     380           0 :                             rOriginX = nCol; rOriginY = nRow;
     381           0 :                             return true;
     382             :                         }
     383             : 
     384           0 :                         if( !bCheckHorz )
     385             :                         {
     386           0 :                             if( nRow == nMergedY )
     387             :                             {
     388           0 :                                 nMinCol = nCol+1;
     389             :                             }
     390             :                             else
     391             :                             {
     392           0 :                                 bCheckHorz = true;
     393             :                             }
     394           0 :                             break;
     395             :                         }
     396             :                     }
     397             :                 }
     398             :                 else
     399             :                 {
     400           0 :                     bCheckHorz = false;
     401             :                 }
     402             :             }
     403           0 :             nStep++;
     404             :         }
     405           0 :         while( bCheckVert || bCheckHorz );
     406             :     }
     407           0 :     catch( Exception& )
     408             :     {
     409             :         OSL_FAIL("sdr::table::TableLayouter::findMergeOrigin(), exception caught!");
     410             :     }
     411           0 :     return false;
     412             : }
     413             : 
     414             : // -----------------------------------------------------------------------------
     415             : 
     416           0 : sal_Int32 TableLayouter::getMinimumColumnWidth( sal_Int32 nColumn )
     417             : {
     418           0 :     if( isValidColumn( nColumn ) )
     419             :     {
     420           0 :         return maColumns[nColumn].mnMinSize;
     421             :     }
     422             :     else
     423             :     {
     424             :         OSL_FAIL( "TableLayouter::getMinimumColumnWidth(), column out of range!" );
     425           0 :         return 0;
     426             :     }
     427             : }
     428             : 
     429             : // -----------------------------------------------------------------------------
     430             : 
     431          94 : sal_Int32 TableLayouter::distribute( LayoutVector& rLayouts, sal_Int32 nDistribute )
     432             : {
     433             :     // break loops after 100 runs to avoid freezing office due to developer error
     434          94 :     sal_Int32 nSafe = 100;
     435             : 
     436          94 :     const sal_Size nCount = rLayouts.size();
     437             :     sal_Size nIndex;
     438             : 
     439          94 :     bool bConstrainsBroken = false;
     440             : 
     441          96 :     do
     442             :     {
     443             :         // first enforce minimum size constrains on all entities
     444         219 :         for( nIndex = 0; nIndex < nCount; ++nIndex )
     445             :         {
     446         123 :             Layout& rLayout = rLayouts[nIndex];
     447         123 :             if( rLayout.mnSize < rLayout.mnMinSize )
     448             :             {
     449           2 :                 nDistribute -= rLayout.mnMinSize - rLayout.mnSize;
     450           2 :                 rLayout.mnSize = rLayout.mnMinSize;
     451             :             }
     452             :         }
     453             : 
     454             :         // calculate current width
     455             :         // if nDistribute is < 0 (shrinking), entities that are already
     456             :         // at minimum width are not counted
     457          96 :         sal_Int32 nCurrentWidth = 0;
     458         219 :         for( nIndex = 0; nIndex < nCount; ++nIndex )
     459             :         {
     460         123 :             Layout& rLayout = rLayouts[nIndex];
     461         123 :             if( (nDistribute > 0) || (rLayout.mnSize > rLayout.mnMinSize) )
     462           9 :                 nCurrentWidth += rLayout.mnSize;
     463             :         }
     464             : 
     465          96 :         bConstrainsBroken = false;
     466             : 
     467             :         // now distribute over entities
     468          96 :         if( (nCurrentWidth != 0) && (nDistribute != 0) )
     469             :         {
     470           8 :             sal_Int32 nDistributed = nDistribute;
     471          28 :             for( nIndex = 0; nIndex < nCount; ++nIndex )
     472             :             {
     473          20 :                 Layout& rLayout = rLayouts[nIndex];
     474          20 :                 if( (nDistribute > 0) || (rLayout.mnSize > rLayout.mnMinSize) )
     475             :                 {
     476             :                     sal_Int32 n;
     477           9 :                     if( nIndex == (nCount-1) )
     478           3 :                         n = nDistributed; // for last entitie, use up rest
     479             :                     else
     480           6 :                         n  = (nDistribute * rLayout.mnSize) / nCurrentWidth; //
     481             : 
     482           9 :                     nDistributed -= n;
     483           9 :                     rLayout.mnSize += n;
     484             : 
     485           9 :                     if( rLayout.mnSize < rLayout.mnMinSize )
     486           2 :                         bConstrainsBroken = true;
     487             :                 }
     488             :             }
     489             :         }
     490             :     } while( bConstrainsBroken && --nSafe );
     491             : 
     492          94 :     sal_Int32 nSize = 0;
     493         215 :     for( nIndex = 0; nIndex < nCount; ++nIndex )
     494         121 :         nSize += rLayouts[nIndex].mnSize;
     495             : 
     496          94 :     return nSize;
     497             : }
     498             : 
     499             : // -----------------------------------------------------------------------------
     500             : 
     501             : typedef std::vector< CellRef > MergeableCellVector;
     502             : typedef std::vector< MergeableCellVector > MergeVector;
     503             : typedef std::vector< sal_Int32 > Int32Vector;
     504             : 
     505             : // -----------------------------------------------------------------------------
     506             : 
     507         182 : void TableLayouter::LayoutTableWidth( Rectangle& rArea, bool bFit )
     508             : {
     509         182 :     const sal_Int32 nColCount = getColumnCount();
     510         182 :     const sal_Int32 nRowCount = getRowCount();
     511         182 :     if( nColCount == 0 )
     512         182 :         return;
     513             : 
     514         182 :     MergeVector aMergedCells( nColCount );
     515         182 :     Int32Vector aOptimalColumns;
     516             : 
     517         182 :     const OUString sOptimalSize( RTL_CONSTASCII_USTRINGPARAM("OptimalSize") );
     518             : 
     519         182 :     if( sal::static_int_cast< sal_Int32 >( maColumns.size() ) != nColCount )
     520           0 :         maColumns.resize( nColCount );
     521             : 
     522         182 :     Reference< XTableColumns > xCols( mxTable->getColumns(), UNO_QUERY_THROW );
     523             : 
     524             :     // first calculate current width and initial minimum width per column,
     525             :     // merged cells will be counted later
     526         182 :     sal_Int32 nCurrentWidth = 0;
     527         182 :     sal_Int32 nCol = 0, nRow = 0;
     528         752 :     for( nCol = 0; nCol < nColCount; nCol++ )
     529             :     {
     530         570 :         sal_Int32 nMinWidth = 0;
     531             : 
     532         570 :         bool bIsEmpty = true; // check if all cells in this column are merged
     533             : 
     534        1751 :         for( nRow = 0; nRow < nRowCount; ++nRow )
     535             :         {
     536        1181 :             CellRef xCell( getCell( CellPos( nCol, nRow ) ) );
     537        1181 :             if( xCell.is() && !xCell->isMerged() )
     538             :             {
     539        1153 :                 bIsEmpty = false;
     540             : 
     541        1153 :                 sal_Int32 nColSpan = xCell->getColumnSpan();
     542        1153 :                 if( nColSpan > 1 )
     543             :                 {
     544             :                     // merged cells will be evaluated later
     545           0 :                     aMergedCells[nCol+nColSpan-1].push_back( xCell );
     546             :                 }
     547             :                 else
     548             :                 {
     549        1153 :                     nMinWidth = std::max( nMinWidth, xCell->getMinimumSize().Width );
     550             :                 }
     551             :             }
     552        1181 :         }
     553             : 
     554         570 :         maColumns[nCol].mnMinSize = nMinWidth;
     555             : 
     556         570 :         if( bIsEmpty )
     557             :         {
     558           0 :             maColumns[nCol].mnSize = 0;
     559             :         }
     560             :         else
     561             :         {
     562         570 :             sal_Int32 nColWidth = 0;
     563         570 :             Reference< XPropertySet > xColSet( xCols->getByIndex( nCol ), UNO_QUERY_THROW );
     564         570 :             sal_Bool bOptimal = sal_False;
     565         570 :             xColSet->getPropertyValue( sOptimalSize ) >>= bOptimal;
     566         570 :             if( bOptimal )
     567             :             {
     568          35 :                 aOptimalColumns.push_back(nCol);
     569             :             }
     570             :             else
     571             :             {
     572         535 :                 xColSet->getPropertyValue( msSize ) >>= nColWidth;
     573             :             }
     574             : 
     575         570 :             maColumns[nCol].mnSize = nColWidth;
     576             : 
     577         570 :             if( maColumns[nCol].mnSize < nMinWidth )
     578          49 :                 maColumns[nCol].mnSize = nMinWidth;
     579             : 
     580         570 :             nCurrentWidth += maColumns[nCol].mnSize;
     581             :         }
     582             :     }
     583             : 
     584             :     // if we have optimal sized rows, distribute what is given (left)
     585         182 :     if( !bFit && !aOptimalColumns.empty() && (nCurrentWidth < rArea.getWidth()) )
     586             :     {
     587           0 :         sal_Int32 nLeft = rArea.getWidth() - nCurrentWidth;
     588           0 :         sal_Int32 nDistribute = nLeft / aOptimalColumns.size();
     589             : 
     590           0 :         Int32Vector::iterator iter( aOptimalColumns.begin() );
     591           0 :         while( iter != aOptimalColumns.end() )
     592             :         {
     593           0 :             sal_Int32 nOptCol = (*iter++);
     594           0 :             if( iter == aOptimalColumns.end() )
     595           0 :                 nDistribute = nLeft;
     596             : 
     597           0 :             maColumns[nOptCol].mnSize += nDistribute;
     598           0 :             nLeft -= nDistribute;
     599             :         }
     600             : 
     601             :         DBG_ASSERT( nLeft == 0, "svx::TableLayouter::LayoutTableWidtht(), layouting failed!" );
     602             :     }
     603             : 
     604             :     // now check if merged cells fit
     605         570 :     for( nCol = 1; nCol < nColCount; ++nCol )
     606             :     {
     607         388 :         bool bChanges = false;
     608         388 :         MergeableCellVector::iterator iter( aMergedCells[nCol].begin() );
     609             : 
     610         388 :         const sal_Int32 nOldSize = maColumns[nCol].mnSize;
     611             : 
     612         776 :         while( iter != aMergedCells[nCol].end() )
     613             :         {
     614           0 :             CellRef xCell( (*iter++) );
     615           0 :             sal_Int32 nMinWidth = xCell->getMinimumSize().Width;
     616             : 
     617           0 :             for( sal_Int32 nMCol = nCol - xCell->getColumnSpan() + 1; (nMCol > 0) && (nMCol < nCol); ++nMCol )
     618           0 :                 nMinWidth -= maColumns[nMCol].mnSize;
     619             : 
     620           0 :             if( nMinWidth > maColumns[nCol].mnMinSize )
     621           0 :                 maColumns[nCol].mnMinSize = nMinWidth;
     622             : 
     623           0 :             if( nMinWidth > maColumns[nCol].mnSize )
     624             :             {
     625           0 :                 maColumns[nCol].mnSize = nMinWidth;
     626           0 :                 bChanges = true;
     627             :             }
     628           0 :         }
     629             : 
     630         388 :         if( bChanges )
     631           0 :             nCurrentWidth += maColumns[nCol].mnSize - nOldSize;
     632             :     }
     633             : 
     634             :     // now scale if wanted and needed
     635         182 :     if( bFit && (nCurrentWidth != rArea.getWidth()) )
     636          35 :         distribute( maColumns, rArea.getWidth() - nCurrentWidth );
     637             : 
     638             :     // last step, update left edges
     639         182 :     sal_Int32 nNewWidth = 0;
     640             : 
     641         182 :     const bool bRTL = meWritingMode == WritingMode_RL_TB;
     642         182 :     RangeIterator<sal_Int32> coliter( 0, nColCount, !bRTL );
     643         934 :     while( coliter.next(nCol ) )
     644             :     {
     645         570 :         maColumns[nCol].mnPos = nNewWidth;
     646         570 :         nNewWidth += maColumns[nCol].mnSize;
     647         570 :         if( bFit )
     648             :         {
     649         214 :             Reference< XPropertySet > xColSet( xCols->getByIndex(nCol), UNO_QUERY_THROW );
     650         214 :             xColSet->setPropertyValue( msSize, Any( maColumns[nCol].mnSize ) );
     651             :         }
     652             :     }
     653             : 
     654         182 :     rArea.SetSize( Size( nNewWidth, rArea.GetHeight() ) );
     655         182 :     updateCells( rArea );
     656             : }
     657             : 
     658             : // -----------------------------------------------------------------------------
     659             : 
     660         182 : void TableLayouter::LayoutTableHeight( Rectangle& rArea, bool bFit )
     661             : {
     662         182 :     const sal_Int32 nColCount = getColumnCount();
     663         182 :     const sal_Int32 nRowCount = getRowCount();
     664         182 :     if( nRowCount == 0 )
     665         182 :         return;
     666             : 
     667         182 :     Reference< XTableRows > xRows( mxTable->getRows() );
     668             : 
     669         182 :     MergeVector aMergedCells( nRowCount );
     670         182 :     Int32Vector aOptimalRows;
     671             : 
     672         182 :     const OUString sOptimalSize( RTL_CONSTASCII_USTRINGPARAM("OptimalSize") );
     673             : 
     674             :     // first calculate current height and initial minimum size per column,
     675             :     // merged cells will be counted later
     676         182 :     sal_Int32 nCurrentHeight = 0;
     677             :     sal_Int32 nCol, nRow;
     678         495 :     for( nRow = 0; nRow < nRowCount; ++nRow )
     679             :     {
     680         313 :         sal_Int32 nMinHeight = 0;
     681             : 
     682         313 :         bool bIsEmpty = true; // check if all cells in this row are merged
     683             : 
     684        1494 :         for( nCol = 0; nCol < nColCount; ++nCol )
     685             :         {
     686        1181 :             CellRef xCell( getCell( CellPos( nCol, nRow ) ) );
     687        1181 :             if( xCell.is() && !xCell->isMerged() )
     688             :             {
     689        1153 :                 bIsEmpty = false;
     690             : 
     691        1153 :                 sal_Int32 nRowSpan = xCell->getRowSpan();
     692        1153 :                 if( nRowSpan > 1 )
     693             :                 {
     694             :                     // merged cells will be evaluated later
     695          19 :                     aMergedCells[nRow+nRowSpan-1].push_back( xCell );
     696             :                 }
     697             :                 else
     698             :                 {
     699        1134 :                     nMinHeight = std::max( nMinHeight, xCell->getMinimumSize().Height );
     700             :                 }
     701             :             }
     702        1181 :         }
     703             : 
     704         313 :         maRows[nRow].mnMinSize = nMinHeight;
     705             : 
     706         313 :         if( bIsEmpty )
     707             :         {
     708           0 :             maRows[nRow].mnSize = 0;
     709             :         }
     710             :         else
     711             :         {
     712         313 :             sal_Int32 nRowHeight = 0;
     713         313 :             Reference< XPropertySet > xRowSet( xRows->getByIndex(nRow), UNO_QUERY_THROW );
     714             : 
     715         313 :             sal_Bool bOptimal = sal_False;
     716         313 :             xRowSet->getPropertyValue( sOptimalSize ) >>= bOptimal;
     717         313 :             if( bOptimal )
     718             :             {
     719          35 :                 aOptimalRows.push_back( nRow );
     720             :             }
     721             :             else
     722             :             {
     723         278 :                 xRowSet->getPropertyValue( msSize ) >>= nRowHeight;
     724             :             }
     725             : 
     726         313 :             maRows[nRow].mnSize = nRowHeight;
     727             : 
     728         313 :             if( maRows[nRow].mnSize < nMinHeight )
     729         156 :                 maRows[nRow].mnSize = nMinHeight;
     730             : 
     731         313 :             nCurrentHeight += maRows[nRow].mnSize;
     732             :         }
     733             :     }
     734             : 
     735             :     // if we have optimal sized rows, distribute what is given (left)
     736         182 :     if( !bFit && !aOptimalRows.empty() && (nCurrentHeight < rArea.getHeight()) )
     737             :     {
     738           0 :         sal_Int32 nLeft = rArea.getHeight() - nCurrentHeight;
     739           0 :         sal_Int32 nDistribute = nLeft / aOptimalRows.size();
     740             : 
     741           0 :         Int32Vector::iterator iter( aOptimalRows.begin() );
     742           0 :         while( iter != aOptimalRows.end() )
     743             :         {
     744           0 :             sal_Int32 nOptRow = (*iter++);
     745           0 :             if( iter == aOptimalRows.end() )
     746           0 :                 nDistribute = nLeft;
     747             : 
     748           0 :             maRows[nOptRow].mnSize += nDistribute;
     749           0 :             nLeft -= nDistribute;
     750             : 
     751             :         }
     752             : 
     753             :         DBG_ASSERT( nLeft == 0, "svx::TableLayouter::LayoutTableHeight(), layouting failed!" );
     754             :     }
     755             : 
     756             :     // now check if merged cells fit
     757         313 :     for( nRow = 1; nRow < nRowCount; ++nRow )
     758             :     {
     759         131 :         bool bChanges = false;
     760         131 :         sal_Int32 nOldSize = maRows[nRow].mnSize;
     761             : 
     762         131 :         MergeableCellVector::iterator iter( aMergedCells[nRow].begin() );
     763         281 :         while( iter != aMergedCells[nRow].end() )
     764             :         {
     765          19 :             CellRef xCell( (*iter++) );
     766          19 :             sal_Int32 nMinHeight = xCell->getMinimumSize().Height;
     767             : 
     768          19 :             for( sal_Int32 nMRow = nRow - xCell->getRowSpan() + 1; (nMRow > 0) && (nMRow < nRow); ++nMRow )
     769           0 :                 nMinHeight -= maRows[nMRow].mnSize;
     770             : 
     771          19 :             if( nMinHeight > maRows[nRow].mnMinSize )
     772           0 :                 maRows[nRow].mnMinSize = nMinHeight;
     773             : 
     774          19 :             if( nMinHeight > maRows[nRow].mnSize )
     775             :             {
     776           0 :                 maRows[nRow].mnSize = nMinHeight;
     777           0 :                 bChanges = true;
     778             :             }
     779          19 :         }
     780         131 :         if( bChanges )
     781           0 :             nCurrentHeight += maRows[nRow].mnSize - nOldSize;
     782             :     }
     783             : 
     784             :     // now scale if wanted and needed
     785         182 :     if( bFit && nCurrentHeight != rArea.getHeight() )
     786          59 :         distribute( maRows, rArea.getHeight() - nCurrentHeight );
     787             : 
     788             :     // last step, update left edges
     789         182 :     sal_Int32 nNewHeight = 0;
     790         495 :     for( nRow = 0; nRow < nRowCount; ++nRow )
     791             :     {
     792         313 :         maRows[nRow].mnPos = nNewHeight;
     793         313 :         nNewHeight += maRows[nRow].mnSize;
     794             : 
     795         313 :         if( bFit )
     796             :         {
     797         112 :             Reference< XPropertySet > xRowSet( xRows->getByIndex(nRow), UNO_QUERY_THROW );
     798         112 :             xRowSet->setPropertyValue( msSize, Any( maRows[nRow].mnSize ) );
     799             :         }
     800             :     }
     801             : 
     802         182 :     rArea.SetSize( Size( rArea.GetWidth(), nNewHeight ) );
     803         182 :     updateCells( rArea );
     804             : }
     805             : 
     806             : // -----------------------------------------------------------------------------
     807             : 
     808             : /** try to fit the table into the given rectangle.
     809             :     If the rectangle is to small, it will be grown to fit the table. */
     810         182 : void TableLayouter::LayoutTable( Rectangle& rRectangle, bool bFitWidth, bool bFitHeight )
     811             : {
     812         182 :     if( !mxTable.is() )
     813         182 :         return;
     814             : 
     815         182 :     const sal_Int32 nRowCount = mxTable->getRowCount();
     816         182 :     const sal_Int32 nColCount = mxTable->getColumnCount();
     817             : 
     818         182 :     if( (nRowCount != getRowCount()) || (nColCount != getColumnCount()) )
     819             :     {
     820          70 :         if( static_cast< sal_Int32 >( maRows.size() ) != nRowCount )
     821          59 :             maRows.resize( nRowCount );
     822             : 
     823          70 :         Reference< XTableRows > xRows( mxTable->getRows() );
     824         188 :         for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ )
     825         118 :             maRows[nRow].clear();
     826             : 
     827          70 :         if( static_cast< sal_Int32 >( maColumns.size() ) != nColCount )
     828          69 :             maColumns.resize( nColCount );
     829             : 
     830         288 :         for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ )
     831         288 :             maColumns[nCol].clear();
     832             :     }
     833             : 
     834         182 :     LayoutTableWidth( rRectangle, bFitWidth );
     835         182 :     LayoutTableHeight( rRectangle, bFitHeight );
     836         182 :     UpdateBorderLayout();
     837             : }
     838             : 
     839             : // -----------------------------------------------------------------------------
     840             : 
     841         366 : void TableLayouter::updateCells( Rectangle& rRectangle )
     842             : {
     843         366 :     const sal_Int32 nColCount = getColumnCount();
     844         366 :     const sal_Int32 nRowCount = getRowCount();
     845             : 
     846         366 :     CellPos aPos;
     847        1002 :     for( aPos.mnRow = 0; aPos.mnRow < nRowCount; aPos.mnRow++ )
     848             :     {
     849        3014 :         for( aPos.mnCol = 0; aPos.mnCol < nColCount; aPos.mnCol++ )
     850             :         {
     851        2378 :             CellRef xCell( getCell( aPos ) );
     852        2378 :             if( xCell.is() )
     853             :             {
     854        2378 :                 basegfx::B2IRectangle aCellArea;
     855        2378 :                 getCellArea( aPos, aCellArea );
     856             : 
     857        2378 :                 Rectangle aCellRect;
     858        2378 :                 aCellRect.Left() = aCellArea.getMinX();
     859        2378 :                 aCellRect.Right() = aCellArea.getMaxX();
     860        2378 :                 aCellRect.Top() = aCellArea.getMinY();
     861        2378 :                 aCellRect.Bottom() = aCellArea.getMaxY();
     862        2378 :                 aCellRect.Move( rRectangle.Left(), rRectangle.Top() );
     863        2378 :                 xCell->setCellRect( aCellRect );
     864             :             }
     865        2378 :         }
     866             :     }
     867         366 : }
     868             : 
     869             : // -----------------------------------------------------------------------------
     870             : 
     871       10621 : CellRef TableLayouter::getCell( const CellPos& rPos ) const
     872             : {
     873       10621 :     CellRef xCell;
     874       10621 :     if( mxTable.is() ) try
     875             :     {
     876       10621 :         xCell.set( dynamic_cast< Cell* >( mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ).get() ) );
     877             :     }
     878           0 :     catch( Exception& )
     879             :     {
     880             :         OSL_FAIL( "sdr::table::TableLayouter::getCell(), exception caught!" );
     881             :     }
     882       10621 :     return xCell;
     883             : }
     884             : 
     885             : // -----------------------------------------------------------------------------
     886             : 
     887        4668 : bool TableLayouter::HasPriority( const SvxBorderLine* pThis, const SvxBorderLine* pOther )
     888             : {
     889        4668 :     if (!pThis || ((pThis == &gEmptyBorder) && (pOther != 0)))
     890          62 :         return false;
     891        4606 :     if (!pOther || (pOther == &gEmptyBorder))
     892        3217 :         return true;
     893             : 
     894        1389 :     sal_uInt16 nThisSize = pThis->GetOutWidth() + pThis->GetDistance() + pThis->GetInWidth();
     895        1389 :     sal_uInt16 nOtherSize = pOther->GetOutWidth() + pOther->GetDistance() + pOther->GetInWidth();
     896             : 
     897        1389 :     if (nThisSize > nOtherSize)
     898           0 :         return true;
     899             : 
     900        1389 :     else if (nThisSize < nOtherSize)
     901             :     {
     902           0 :         return false;
     903             :     }
     904             :     else
     905             :     {
     906        1389 :         if ( pOther->GetInWidth() && !pThis->GetInWidth() )
     907             :         {
     908           0 :             return true;
     909             :         }
     910        1389 :         else if ( pThis->GetInWidth() && !pOther->GetInWidth() )
     911             :         {
     912           0 :             return false;
     913             :         }
     914             :         else
     915             :         {
     916        1389 :             return true;            //! ???
     917             :         }
     918             :     }
     919             : }
     920             : 
     921             : // -----------------------------------------------------------------------------
     922             : 
     923        4668 : void TableLayouter::SetBorder( sal_Int32 nCol, sal_Int32 nRow, bool bHorizontal, const SvxBorderLine* pLine )
     924             : {
     925        4668 :     if( pLine == 0 )
     926         547 :         pLine = &gEmptyBorder;
     927             : 
     928        4668 :     SvxBorderLine *pOld = bHorizontal ? maHorizontalBorders[nCol][nRow] : maVerticalBorders[nCol][nRow];
     929             : 
     930        4668 :     if( HasPriority( pLine, pOld ) )
     931             :     {
     932        4606 :         if( (pOld != 0) && (pOld != &gEmptyBorder) )
     933        1389 :             delete pOld;
     934             : 
     935        4606 :         SvxBorderLine* pNew = ( pLine != &gEmptyBorder ) ?  new SvxBorderLine(*pLine) : &gEmptyBorder;
     936             : 
     937        4606 :         if( bHorizontal )
     938        2280 :             maHorizontalBorders[nCol][nRow] = pNew;
     939             :         else
     940        2326 :             maVerticalBorders[nCol][nRow]  = pNew;
     941             :     }
     942        4668 : }
     943             : 
     944             : // -----------------------------------------------------------------------------
     945             : 
     946         217 : void TableLayouter::ClearBorderLayout()
     947             : {
     948         217 :     ClearBorderLayout(maHorizontalBorders);
     949         217 :     ClearBorderLayout(maVerticalBorders);
     950         217 : }
     951             : 
     952             : // -----------------------------------------------------------------------------
     953             : 
     954         434 : void TableLayouter::ClearBorderLayout(BorderLineMap& rMap)
     955             : {
     956         434 :     const sal_Int32 nColCount = rMap.size();
     957             : 
     958        1938 :     for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ )
     959             :     {
     960        1504 :         const sal_Int32 nRowCount = rMap[nCol].size();
     961        5996 :         for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ )
     962             :         {
     963        4492 :             SvxBorderLine* pLine = rMap[nCol][nRow];
     964        4492 :             if( pLine )
     965             :             {
     966        3217 :                 if( pLine != &gEmptyBorder )
     967        2732 :                     delete pLine;
     968             : 
     969        3217 :                 rMap[nCol][nRow] = 0;
     970             :             }
     971             :         }
     972             :     }
     973         434 : }
     974             : 
     975             : // -----------------------------------------------------------------------------
     976             : 
     977         182 : void TableLayouter::ResizeBorderLayout()
     978             : {
     979         182 :     ClearBorderLayout();
     980         182 :     ResizeBorderLayout(maHorizontalBorders);
     981         182 :     ResizeBorderLayout(maVerticalBorders);
     982         182 : }
     983             : 
     984             : // -----------------------------------------------------------------------------
     985             : 
     986         364 : void TableLayouter::ResizeBorderLayout( BorderLineMap& rMap )
     987             : {
     988         364 :     const sal_Int32 nColCount = getColumnCount() + 1;
     989         364 :     const sal_Int32 nRowCount = getRowCount() + 1;
     990             : 
     991         364 :     if( sal::static_int_cast<sal_Int32>(rMap.size()) != nColCount )
     992         138 :         rMap.resize( nColCount );
     993             : 
     994        1868 :     for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ )
     995             :     {
     996        1504 :         if( sal::static_int_cast<sal_Int32>(rMap[nCol].size()) != nRowCount )
     997         532 :             rMap[nCol].resize( nRowCount );
     998             :     }
     999         364 : }
    1000             : 
    1001             : // -----------------------------------------------------------------------------
    1002             : 
    1003         182 : void TableLayouter::UpdateBorderLayout()
    1004             : {
    1005             :     // make sure old border layout is cleared and border maps have correct size
    1006         182 :     ResizeBorderLayout();
    1007             : 
    1008         182 :     const sal_Int32 nColCount = getColumnCount();
    1009         182 :     const sal_Int32 nRowCount = getRowCount();
    1010             : 
    1011         182 :     CellPos aPos;
    1012         495 :     for( aPos.mnRow = 0; aPos.mnRow < nRowCount; aPos.mnRow++ )
    1013             :     {
    1014        1494 :         for( aPos.mnCol = 0; aPos.mnCol < nColCount; aPos.mnCol++ )
    1015             :         {
    1016        1181 :             CellRef xCell( getCell( aPos ) );
    1017        1181 :             if( !xCell.is() || xCell->isMerged() )
    1018          28 :                 continue;
    1019             : 
    1020        1153 :             const SvxBoxItem* pThisAttr = (const SvxBoxItem*)xCell->GetItemSet().GetItem( SDRATTR_TABLE_BORDER );
    1021             :             OSL_ENSURE(pThisAttr,"sdr::table::TableLayouter::UpdateBorderLayout(), no border attribute?");
    1022             : 
    1023        1153 :             if( !pThisAttr )
    1024           0 :                 continue;
    1025             : 
    1026        1153 :             const sal_Int32 nLastRow = xCell->getRowSpan() + aPos.mnRow;
    1027        1153 :             const sal_Int32 nLastCol = xCell->getColumnSpan() + aPos.mnCol;
    1028             : 
    1029        2334 :             for( sal_Int32 nRow = aPos.mnRow; nRow < nLastRow; nRow++ )
    1030             :             {
    1031        1181 :                 SetBorder( aPos.mnCol, nRow, false, pThisAttr->GetLeft() );
    1032        1181 :                 SetBorder( nLastCol, nRow, false, pThisAttr->GetRight() );
    1033             :             }
    1034             : 
    1035        2306 :             for( sal_Int32 nCol = aPos.mnCol; nCol < nLastCol; nCol++ )
    1036             :             {
    1037        1153 :                 SetBorder( nCol, aPos.mnRow, true, pThisAttr->GetTop() );
    1038        1153 :                 SetBorder( nCol, nLastRow, true, pThisAttr->GetBottom() );
    1039             :             }
    1040        1181 :         }
    1041             :     }
    1042         182 : }
    1043             : 
    1044             : // -----------------------------------------------------------------------------
    1045             : 
    1046           0 : void TableLayouter::DistributeColumns( ::Rectangle& rArea, sal_Int32 nFirstCol, sal_Int32 nLastCol )
    1047             : {
    1048           0 :     if( mxTable.is() ) try
    1049             :     {
    1050           0 :         const sal_Int32 nColCount = getColumnCount();
    1051             : 
    1052           0 :         if( (nFirstCol < 0) || (nFirstCol>= nLastCol) || (nLastCol >= nColCount) )
    1053           0 :             return;
    1054             : 
    1055           0 :         sal_Int32 nAllWidth = 0;
    1056           0 :         for( sal_Int32 nCol = nFirstCol; nCol <= nLastCol; ++nCol )
    1057           0 :             nAllWidth += getColumnWidth(nCol);
    1058             : 
    1059           0 :         sal_Int32 nWidth = nAllWidth / (nLastCol-nFirstCol+1);
    1060             : 
    1061           0 :         Reference< XTableColumns > xCols( mxTable->getColumns(), UNO_QUERY_THROW );
    1062             : 
    1063           0 :         for( sal_Int32 nCol = nFirstCol; nCol <= nLastCol; ++nCol )
    1064             :         {
    1065           0 :             if( nCol == nLastCol )
    1066           0 :                 nWidth = nAllWidth; // last column get round errors
    1067             : 
    1068           0 :             Reference< XPropertySet > xColSet( xCols->getByIndex( nCol ), UNO_QUERY_THROW );
    1069           0 :             xColSet->setPropertyValue( msSize, Any( nWidth ) );
    1070             : 
    1071           0 :             nAllWidth -= nWidth;
    1072           0 :         }
    1073             : 
    1074           0 :         LayoutTable( rArea, true, false );
    1075             :     }
    1076           0 :     catch( Exception& e )
    1077             :     {
    1078             :         (void)e;
    1079             :         OSL_FAIL("sdr::table::TableLayouter::DistributeColumns(), exception caught!");
    1080             :     }
    1081             : }
    1082             : 
    1083             : // -----------------------------------------------------------------------------
    1084             : 
    1085           0 : void TableLayouter::DistributeRows( ::Rectangle& rArea, sal_Int32 nFirstRow, sal_Int32 nLastRow )
    1086             : {
    1087           0 :     if( mxTable.is() ) try
    1088             :     {
    1089           0 :         const sal_Int32 nRowCount = mxTable->getRowCount();
    1090             : 
    1091           0 :         if( (nFirstRow < 0) || (nFirstRow>= nLastRow) || (nLastRow >= nRowCount) )
    1092           0 :             return;
    1093             : 
    1094           0 :         sal_Int32 nAllHeight = 0;
    1095           0 :         sal_Int32 nMinHeight = 0;
    1096             : 
    1097           0 :         for( sal_Int32 nRow = nFirstRow; nRow <= nLastRow; ++nRow )
    1098             :         {
    1099           0 :             nMinHeight = std::max( maRows[nRow].mnMinSize, nMinHeight );
    1100           0 :             nAllHeight += maRows[nRow].mnSize;
    1101             :         }
    1102             : 
    1103           0 :         const sal_Int32 nRows = (nLastRow-nFirstRow+1);
    1104           0 :         sal_Int32 nHeight = nAllHeight / nRows;
    1105             : 
    1106           0 :         if( nHeight < nMinHeight )
    1107             :         {
    1108           0 :             sal_Int32 nNeededHeight = nRows * nMinHeight;
    1109           0 :             rArea.Bottom() += nNeededHeight - nAllHeight;
    1110           0 :             nHeight = nMinHeight;
    1111           0 :             nAllHeight = nRows * nMinHeight;
    1112             :         }
    1113             : 
    1114           0 :         Reference< XTableRows > xRows( mxTable->getRows(), UNO_QUERY_THROW );
    1115           0 :         for( sal_Int32 nRow = nFirstRow; nRow <= nLastRow; ++nRow )
    1116             :         {
    1117           0 :             if( nRow == nLastRow )
    1118           0 :                 nHeight = nAllHeight; // last row get round errors
    1119             : 
    1120           0 :             Reference< XPropertySet > xRowSet( xRows->getByIndex( nRow ), UNO_QUERY_THROW );
    1121           0 :             xRowSet->setPropertyValue( msSize, Any( nHeight ) );
    1122             : 
    1123           0 :             nAllHeight -= nHeight;
    1124           0 :         }
    1125             : 
    1126           0 :         LayoutTable( rArea, false, true );
    1127             :     }
    1128           0 :     catch( Exception& e )
    1129             :     {
    1130             :         (void)e;
    1131             :         OSL_FAIL("sdr::table::TableLayouter::DistributeRows(), exception caught!");
    1132             :     }
    1133             : }
    1134             : 
    1135             : // -----------------------------------------------------------------------------
    1136           0 : void TableLayouter::SetWritingMode( com::sun::star::text::WritingMode eWritingMode )
    1137             : {
    1138           0 :     meWritingMode = eWritingMode;
    1139           0 : }
    1140             : 
    1141          63 : } }
    1142             : 
    1143             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10