summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorJustin Luth <justin_luth@sil.org>2018-10-06 12:48:49 +0300
committerMiklos Vajna <vmiklos@collabora.co.uk>2018-10-11 09:52:27 +0200
commit79bc165b6c906aa4f9efa6f4cdebb2f8a5f405b1 (patch)
treee70d722c77b7deed79f64e0805558be029800f90 /svx
parent048b8e45813f6a19a4ff56e1d676fe9450325cd2 (diff)
tdf#117721 draw ui: add .uno::SetMinimal[RowHeight|ColumnWidth]
Minimize column width: Adjusts the width of the selected columns to fit the selected content. The table can shrink if necessary, but will not grow. (Previously no way to minimize columns. Since minimizing really can mess up merged cells, enhance my new calcPreferredColumnWidth function.) Minimize row height: Adjusts the height of the selected rows to fit the content, causing the table to shrink. (The new optimize action functioned as minimize. So this change tweaks optimize so that it does not reduce the table size. A followup commit will make it distribute based on largest minimized row (still without reducing table size), and change distributed rows to work the way the document states - based on the largest row. Change-Id: I807a9cc9e9441a1215539e817b87158afe5a0604 Reviewed-on: https://gerrit.libreoffice.org/61472 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Diffstat (limited to 'svx')
-rw-r--r--svx/source/table/svdotable.cxx8
-rw-r--r--svx/source/table/tablecontroller.cxx25
-rw-r--r--svx/source/table/tablelayouter.cxx79
-rw-r--r--svx/source/table/tablelayouter.hxx12
4 files changed, 88 insertions, 36 deletions
diff --git a/svx/source/table/svdotable.cxx b/svx/source/table/svdotable.cxx
index 8c0ec5bbdf28..69cd8432c044 100644
--- a/svx/source/table/svdotable.cxx
+++ b/svx/source/table/svdotable.cxx
@@ -2409,22 +2409,22 @@ void SdrTableObj::CropTableModelToSelection(const CellPos& rStart, const CellPos
mpImpl->CropTableModelToSelection(rStart, rEnd);
}
-void SdrTableObj::DistributeColumns( sal_Int32 nFirstColumn, sal_Int32 nLastColumn, const bool bOptimize )
+void SdrTableObj::DistributeColumns( sal_Int32 nFirstColumn, sal_Int32 nLastColumn, const bool bOptimize, const bool bMinimize )
{
if( mpImpl.is() && mpImpl->mpLayouter )
{
TableModelNotifyGuard aGuard( mpImpl->mxTable.get() );
- mpImpl->mpLayouter->DistributeColumns( maRect, nFirstColumn, nLastColumn, bOptimize );
+ mpImpl->mpLayouter->DistributeColumns( maRect, nFirstColumn, nLastColumn, bOptimize, bMinimize );
}
}
-void SdrTableObj::DistributeRows( sal_Int32 nFirstRow, sal_Int32 nLastRow, const bool bOptimize )
+void SdrTableObj::DistributeRows( sal_Int32 nFirstRow, sal_Int32 nLastRow, const bool bOptimize, const bool bMinimize )
{
if( mpImpl.is() && mpImpl->mpLayouter )
{
TableModelNotifyGuard aGuard( mpImpl->mxTable.get() );
- mpImpl->mpLayouter->DistributeRows( maRect, nFirstRow, nLastRow, bOptimize );
+ mpImpl->mpLayouter->DistributeRows( maRect, nFirstRow, nLastRow, bOptimize, bMinimize );
}
}
diff --git a/svx/source/table/tablecontroller.cxx b/svx/source/table/tablecontroller.cxx
index 4aa3dfbc3358..cedf54732426 100644
--- a/svx/source/table/tablecontroller.cxx
+++ b/svx/source/table/tablecontroller.cxx
@@ -476,6 +476,7 @@ void SvxTableController::GetState( SfxItemSet& rSet )
rSet.DisableItem(SID_TABLE_SPLIT_CELLS);
break;
+ case SID_TABLE_OPTIMAL_ROW_HEIGHT:
case SID_TABLE_DISTRIBUTE_COLUMNS:
case SID_TABLE_DISTRIBUTE_ROWS:
{
@@ -1003,20 +1004,28 @@ void SvxTableController::Execute( SfxRequest& rReq )
SplitMarkedCells(rReq);
break;
+ case SID_TABLE_MINIMAL_COLUMN_WIDTH:
+ DistributeColumns(/*bOptimize=*/true, /*bMinimize=*/true);
+ break;
+
case SID_TABLE_OPTIMAL_COLUMN_WIDTH:
- DistributeColumns(/*bOptimize=*/true);
+ DistributeColumns(/*bOptimize=*/true, /*bMinimize=*/false);
break;
case SID_TABLE_DISTRIBUTE_COLUMNS:
- DistributeColumns(/*bOptimize=*/false);
+ DistributeColumns(/*bOptimize=*/false, /*bMinimize=*/false);
+ break;
+
+ case SID_TABLE_MINIMAL_ROW_HEIGHT:
+ DistributeRows(/*bOptimize=*/true, /*bMinimize=*/true);
break;
case SID_TABLE_OPTIMAL_ROW_HEIGHT:
- DistributeRows(/*bOptimize=*/true);
+ DistributeRows(/*bOptimize=*/true, /*bMinimize=*/false);
break;
case SID_TABLE_DISTRIBUTE_ROWS:
- DistributeRows(/*bOptimize=*/false);
+ DistributeRows(/*bOptimize=*/false, /*bMinimize=*/false);
break;
case SID_TABLE_VERT_BOTTOM:
@@ -1301,7 +1310,7 @@ void SvxTableController::SplitMarkedCells(const SfxRequest& rReq)
}
}
-void SvxTableController::DistributeColumns(const bool bOptimize)
+void SvxTableController::DistributeColumns(const bool bOptimize, const bool bMinimize)
{
if(!checkTableObject())
return;
@@ -1318,13 +1327,13 @@ void SvxTableController::DistributeColumns(const bool bOptimize)
CellPos aStart, aEnd;
getSelectedCells( aStart, aEnd );
- rTableObj.DistributeColumns( aStart.mnCol, aEnd.mnCol, bOptimize );
+ rTableObj.DistributeColumns( aStart.mnCol, aEnd.mnCol, bOptimize, bMinimize );
if( bUndo )
rModel.EndUndo();
}
-void SvxTableController::DistributeRows(const bool bOptimize)
+void SvxTableController::DistributeRows(const bool bOptimize, const bool bMinimize)
{
if(!checkTableObject())
return;
@@ -1341,7 +1350,7 @@ void SvxTableController::DistributeRows(const bool bOptimize)
CellPos aStart, aEnd;
getSelectedCells( aStart, aEnd );
- rTableObj.DistributeRows( aStart.mnRow, aEnd.mnRow, bOptimize );
+ rTableObj.DistributeRows( aStart.mnRow, aEnd.mnRow, bOptimize, bMinimize );
if( bUndo )
rModel.EndUndo();
diff --git a/svx/source/table/tablelayouter.cxx b/svx/source/table/tablelayouter.cxx
index c1189e2ebdb4..29cf6fe0253d 100644
--- a/svx/source/table/tablelayouter.cxx
+++ b/svx/source/table/tablelayouter.cxx
@@ -174,14 +174,37 @@ sal_Int32 TableLayouter::getColumnWidth( sal_Int32 nColumn ) const
sal_Int32 TableLayouter::calcPreferredColumnWidth( sal_Int32 nColumn, Size aSize ) const
{
sal_Int32 nRet = 0;
- if ( isValidColumn(nColumn) )
+ for ( sal_uInt32 nRow = 0; nRow < static_cast<sal_uInt32>(maRows.size()); ++nRow )
{
- for ( sal_uInt32 nRow = 0; nRow < static_cast<sal_uInt32>(maRows.size()); ++nRow )
+ // Account for the space desired by spanned columns.
+ // Only the last spanned cell will try to ensure sufficient space,
+ // by looping through the previous columns, subtracting their portion.
+ sal_Int32 nWish = 0;
+ sal_Int32 nSpannedColumn = nColumn;
+ bool bFindSpan = true;
+ while ( bFindSpan && isValidColumn(nSpannedColumn) )
{
- CellRef xCell( getCell( CellPos( nColumn, nRow ) ) );
- if ( xCell.is() && !xCell->isMerged() && xCell->getColumnSpan() == 1 )
- nRet = std::max( nRet, xCell->calcPreferredWidth(aSize) );
+ // recursive function call gets earlier portion of spanned column.
+ if ( nSpannedColumn < nColumn )
+ nWish -= calcPreferredColumnWidth( nSpannedColumn, aSize );
+
+ CellRef xCell( getCell( CellPos( nSpannedColumn, nRow ) ) );
+ if ( xCell.is() && !xCell->isMerged()
+ && (xCell->getColumnSpan() == 1 || nSpannedColumn < nColumn) )
+ {
+ nWish += xCell->calcPreferredWidth(aSize);
+ bFindSpan = false;
+ }
+ else if ( xCell.is() && xCell->isMerged()
+ && nColumn == nSpannedColumn
+ && isValidColumn(nColumn + 1) )
+ {
+ xCell = getCell( CellPos( nColumn + 1, nRow ) );
+ bFindSpan = xCell.is() && !xCell->isMerged();
+ }
+ nSpannedColumn--;
}
+ nRet = std::max( nRet, nWish );
}
return nRet;
}
@@ -1062,7 +1085,8 @@ void TableLayouter::UpdateBorderLayout()
void TableLayouter::DistributeColumns( ::tools::Rectangle& rArea,
sal_Int32 nFirstCol,
sal_Int32 nLastCol,
- const bool bOptimize )
+ const bool bOptimize,
+ const bool bMinimize )
{
if( mxTable.is() ) try
{
@@ -1071,7 +1095,7 @@ void TableLayouter::DistributeColumns( ::tools::Rectangle& rArea,
const Size aSize(0xffffff, 0xffffff);
//special case - optimize a single column
- if ( bOptimize && nFirstCol == nLastCol )
+ if ( (bOptimize || bMinimize) && nFirstCol == nLastCol )
{
const sal_Int32 nWish = calcPreferredColumnWidth(nFirstCol, aSize);
if ( nWish < getColumnWidth(nFirstCol) )
@@ -1080,7 +1104,7 @@ void TableLayouter::DistributeColumns( ::tools::Rectangle& rArea,
xColSet->setPropertyValue( gsSize, Any( nWish ) );
//FitWidth automatically distributes the new excess space
- LayoutTable( rArea, /*bFitWidth=*/true, /*bFitHeight=*/false );
+ LayoutTable( rArea, /*bFitWidth=*/!bMinimize, /*bFitHeight=*/false );
}
}
@@ -1098,7 +1122,7 @@ void TableLayouter::DistributeColumns( ::tools::Rectangle& rArea,
const sal_Int32 nEqualWidth = nAllWidth / (nLastCol-nFirstCol+1);
//pass 1 - collect unneeded space (from an equal width perspective)
- if ( bOptimize )
+ if ( bMinimize || bOptimize )
{
for( sal_Int32 nCol = nFirstCol; nCol <= nLastCol; ++nCol )
{
@@ -1114,9 +1138,9 @@ void TableLayouter::DistributeColumns( ::tools::Rectangle& rArea,
sal_Int32 nWidth = nEqualWidth;
for( sal_Int32 nCol = nFirstCol; nCol <= nLastCol; ++nCol )
{
- if( nCol == nLastCol )
+ if ( !bMinimize && nCol == nLastCol )
nWidth = nAllWidth; // last column gets rounding/logic errors
- else if ( bOptimize && fAllWish )
+ else if ( (bMinimize || bOptimize) && fAllWish )
{
//pass 2 - first come, first served when requesting from the
// unneeded pool, or proportionally allocate excess.
@@ -1132,7 +1156,7 @@ void TableLayouter::DistributeColumns( ::tools::Rectangle& rArea,
if ( aWish[nIndex] > nEqualWidth )
nUnused -= aWish[nIndex] - nEqualWidth;
- if ( nDistributeExcess > 0 )
+ if ( !bMinimize && nDistributeExcess > 0 )
nWidth += nWidth / fAllWish * nDistributeExcess;
}
}
@@ -1143,7 +1167,7 @@ void TableLayouter::DistributeColumns( ::tools::Rectangle& rArea,
nAllWidth -= nWidth;
}
- LayoutTable( rArea, true, false );
+ LayoutTable( rArea, !bMinimize, false );
}
catch( Exception& )
{
@@ -1155,17 +1179,32 @@ void TableLayouter::DistributeColumns( ::tools::Rectangle& rArea,
void TableLayouter::DistributeRows( ::tools::Rectangle& rArea,
sal_Int32 nFirstRow,
sal_Int32 nLastRow,
- const bool bOptimize )
+ const bool bOptimize,
+ const bool bMinimize )
{
if( mxTable.is() ) try
{
const sal_Int32 nRowCount = mxTable->getRowCount();
+ Reference< XTableRows > xRows( mxTable->getRows(), UNO_QUERY_THROW );
+ sal_Int32 nMinHeight = 0;
+
+ //special case - minimize a single row
+ if ( bMinimize && nFirstRow == nLastRow )
+ {
+ const sal_Int32 nWish = std::max( maRows[nFirstRow].mnMinSize, nMinHeight );
+ if ( nWish < getRowHeight(nFirstRow) )
+ {
+ Reference< XPropertySet > xRowSet( xRows->getByIndex( nFirstRow ), UNO_QUERY_THROW );
+ xRowSet->setPropertyValue( gsSize, Any( nWish ) );
+
+ LayoutTable( rArea, /*bFitWidth=*/false, /*bFitHeight=*/!bMinimize );
+ }
+ }
if( (nFirstRow < 0) || (nFirstRow>= nLastRow) || (nLastRow >= nRowCount) )
return;
sal_Int32 nAllHeight = 0;
- sal_Int32 nMinHeight = 0;
for( sal_Int32 nRow = nFirstRow; nRow <= nLastRow; ++nRow )
{
@@ -1176,7 +1215,7 @@ void TableLayouter::DistributeRows( ::tools::Rectangle& rArea,
const sal_Int32 nRows = (nLastRow-nFirstRow+1);
sal_Int32 nHeight = nAllHeight / nRows;
- if( nHeight < nMinHeight && !bOptimize )
+ if ( !(bMinimize || bOptimize) && nHeight < nMinHeight )
{
sal_Int32 nNeededHeight = nRows * nMinHeight;
rArea.AdjustBottom(nNeededHeight - nAllHeight );
@@ -1184,10 +1223,9 @@ void TableLayouter::DistributeRows( ::tools::Rectangle& rArea,
nAllHeight = nRows * nMinHeight;
}
- Reference< XTableRows > xRows( mxTable->getRows(), UNO_QUERY_THROW );
for( sal_Int32 nRow = nFirstRow; nRow <= nLastRow; ++nRow )
{
- if ( bOptimize )
+ if ( bMinimize || bOptimize )
nHeight = maRows[nRow].mnMinSize;
else if ( nRow == nLastRow )
nHeight = nAllHeight; // last row get round errors
@@ -1198,10 +1236,7 @@ void TableLayouter::DistributeRows( ::tools::Rectangle& rArea,
nAllHeight -= nHeight;
}
- if ( bOptimize )
- rArea.AdjustBottom( -nAllHeight );
-
- LayoutTable( rArea, false, true );
+ LayoutTable( rArea, false, !bMinimize );
}
catch( Exception& )
{
diff --git a/svx/source/table/tablelayouter.hxx b/svx/source/table/tablelayouter.hxx
index 701a1eaf66ee..b3e4f11a36eb 100644
--- a/svx/source/table/tablelayouter.hxx
+++ b/svx/source/table/tablelayouter.hxx
@@ -95,8 +95,16 @@ public:
sal_Int32 getHorizontalEdge( int nEdgeY, sal_Int32* pnMin, sal_Int32* pnMax );
sal_Int32 getVerticalEdge( int nEdgeX , sal_Int32* pnMin, sal_Int32* pnMax);
- void DistributeColumns( ::tools::Rectangle& rArea, sal_Int32 nFirstCol, sal_Int32 nLastCol, const bool bOptimize );
- void DistributeRows( ::tools::Rectangle& rArea, sal_Int32 nFirstRow, sal_Int32 nLastRow, const bool bOptimize );
+ void DistributeColumns( ::tools::Rectangle& rArea,
+ sal_Int32 nFirstCol,
+ sal_Int32 nLastCol,
+ const bool bOptimize,
+ const bool bMinimize );
+ void DistributeRows( ::tools::Rectangle& rArea,
+ sal_Int32 nFirstRow,
+ sal_Int32 nLastRow,
+ const bool bOptimize,
+ const bool bMinimize );
void dumpAsXml(struct _xmlTextWriter* pWriter) const;
private: