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

Generated by: LCOV version 1.10