sc/qa/unit/uicalc/uicalc2.cxx | 86 +++++++++++++++++++++++++++++++++++++++++ sc/sdi/scalc.sdi | 2 sc/source/ui/inc/viewfunc.hxx | 2 sc/source/ui/view/cellsh3.cxx | 29 ++++++++++++- sc/source/ui/view/viewfunc.cxx | 5 -- 5 files changed, 116 insertions(+), 8 deletions(-)
New commits: commit 1437e7b66e6fe389257d55dc618c9c18c14b3e86 Author: Mike Kaganski <[email protected]> AuthorDate: Fri Oct 24 19:19:39 2025 +0500 Commit: Mike Kaganski <[email protected]> CommitDate: Thu Oct 30 10:53:31 2025 +0100 cool#13279: Add Column parameter to .uno:SetOptimalColumnWidth Allows to pass the column where the click happened. The argument takes a 16-bit unsigned integer, using the same convention as .uno:ColumnWidth: column A is 1. Change-Id: Ia0bcacdea5e6c672eb506b338c461ea263e5a7cf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192950 Tested-by: Jenkins Reviewed-by: Mike Kaganski <[email protected]> diff --git a/sc/qa/unit/uicalc/uicalc2.cxx b/sc/qa/unit/uicalc/uicalc2.cxx index dc69d435d524..e9b88101310b 100644 --- a/sc/qa/unit/uicalc/uicalc2.cxx +++ b/sc/qa/unit/uicalc/uicalc2.cxx @@ -17,6 +17,7 @@ #include <comphelper/processfactory.hxx> #include <comphelper/propertysequence.hxx> +#include <comphelper/propertyvalue.hxx> #include <comphelper/servicehelper.hxx> #include <com/sun/star/awt/Key.hpp> #include <com/sun/star/sheet/GlobalSheetSettings.hpp> @@ -1678,6 +1679,91 @@ CPPUNIT_TEST_FIXTURE(ScUiCalcTest2, testTdf140027) CPPUNIT_ASSERT(ScPatternAttr::areSame(pPattern, &aDefPattern)); } +CPPUNIT_TEST_FIXTURE(ScUiCalcTest2, testcommand_SetOptimalColumnWidth) +{ + createScDoc(); + ScDocument* pDoc = getScDoc(); + + // Set columns' width to 10 cm: + for (SCCOL col = 0; col <= 4; ++col) + pDoc->SetColWidth(col, 0, o3tl::toTwips(10, o3tl::Length::cm)); + + // Add strings + pDoc->SetString(0, 0, 0, u"WWW"_ustr); // A1 + pDoc->SetString(1, 0, 0, u"WWW"_ustr); // B1 + pDoc->SetString(2, 0, 0, u"WWW"_ustr); // C1 + pDoc->SetString(3, 0, 0, u"WWW"_ustr); // D1 + pDoc->SetString(4, 0, 0, u"WWW"_ustr); // E1 + pDoc->SetString(4, 1, 0, u"WWWWW"_ustr); // E2 + pDoc->SetString(4, 2, 0, u"WWWWWWW"_ustr); // E3 + + // Store the initial values of the widths: + auto nWidthA = pDoc->GetColWidth(0, 0); + auto nWidthB = pDoc->GetColWidth(1, 0); + auto nWidthC = pDoc->GetColWidth(2, 0); + auto nWidthD = pDoc->GetColWidth(3, 0); + auto nWidthE = pDoc->GetColWidth(4, 0); + + auto pViewShell = pDoc->GetDocumentShell()->GetBestViewShell(); + + // Select C1:E2: + pViewShell->GetViewData().GetMarkData().SetMarkArea(ScRange(2, 0, 0, 4, 1, 0)); + + // .uno:SetOptimalColumnWidth must take selection into account: + dispatchCommand(mxComponent, u".uno:SetOptimalColumnWidth"_ustr, + { comphelper::makePropertyValue(u"aExtraWidth"_ustr, sal_uInt16(0)) }); + + // Columns A and B must not change width + CPPUNIT_ASSERT_EQUAL(nWidthA, pDoc->GetColWidth(0, 0)); + CPPUNIT_ASSERT_EQUAL(nWidthB, pDoc->GetColWidth(1, 0)); + + // Columns C to E must become narrower + CPPUNIT_ASSERT_LESS(nWidthC, pDoc->GetColWidth(2, 0)); + CPPUNIT_ASSERT_LESS(nWidthD, pDoc->GetColWidth(3, 0)); + CPPUNIT_ASSERT_LESS(nWidthE, pDoc->GetColWidth(4, 0)); + + // Width of column C must be same as D, and smaller than E (in E, a wider string is selected): + CPPUNIT_ASSERT_EQUAL(pDoc->GetColWidth(2, 0), pDoc->GetColWidth(3, 0)); // D == C + CPPUNIT_ASSERT_GREATER(pDoc->GetColWidth(2, 0), pDoc->GetColWidth(4, 0)); // E > C + + // Store updated width: + nWidthE = pDoc->GetColWidth(4, 0); + + // Select E3: + pViewShell->GetViewData().GetMarkData().SetMarkArea(ScRange(4, 2, 0)); + + // .uno:SetOptimalColumnWidth must take selection into account: + dispatchCommand(mxComponent, u".uno:SetOptimalColumnWidth"_ustr, + { comphelper::makePropertyValue(u"aExtraWidth"_ustr, sal_uInt16(0)) }); + + // Width of E must increase (in E, even wider string is selected): + CPPUNIT_ASSERT_GREATER(nWidthE, pDoc->GetColWidth(4, 0)); + + // Select A1:B1: + pViewShell->GetViewData().GetMarkData().SetMarkArea(ScRange(0, 0, 0, 1, 0, 0)); + // Set width of column E to 10 cm: + pDoc->SetColWidth(4, 0, o3tl::toTwips(10, o3tl::Length::cm)); + // Store it: + nWidthE = pDoc->GetColWidth(4, 0); + + // .uno:SetOptimalColumnWidth with Column E must not change widths of columns A:B, only C: + dispatchCommand(mxComponent, u".uno:SetOptimalColumnWidth"_ustr, + { comphelper::makePropertyValue(u"aExtraWidth"_ustr, sal_uInt16(0)), + comphelper::makePropertyValue(u"Column"_ustr, sal_uInt16(5)) }); + + CPPUNIT_ASSERT_EQUAL(nWidthA, pDoc->GetColWidth(0, 0)); + CPPUNIT_ASSERT_EQUAL(nWidthB, pDoc->GetColWidth(1, 0)); + CPPUNIT_ASSERT_LESS(nWidthE, pDoc->GetColWidth(4, 0)); + + // .uno:SetOptimalColumnWidth with Column A must change width of column A: + dispatchCommand(mxComponent, u".uno:SetOptimalColumnWidth"_ustr, + { comphelper::makePropertyValue(u"aExtraWidth"_ustr, sal_uInt16(0)), + comphelper::makePropertyValue(u"Column"_ustr, sal_uInt16(1)) }); + + CPPUNIT_ASSERT_LESS(nWidthA, pDoc->GetColWidth(0, 0)); + CPPUNIT_ASSERT_EQUAL(nWidthB, pDoc->GetColWidth(1, 0)); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi index 06c9bd1093b2..a241c6c15086 100644 --- a/sc/sdi/scalc.sdi +++ b/sc/sdi/scalc.sdi @@ -5042,7 +5042,7 @@ SfxVoidItem SetInputMode SID_SETINPUTMODE SfxVoidItem SetOptimalColumnWidth FID_COL_OPT_WIDTH -(SfxUInt16Item aExtraWidth FID_COL_OPT_WIDTH) +(SfxUInt16Item aExtraWidth FID_COL_OPT_WIDTH,SfxUInt16Item Column FN_PARAM_1) [ AutoUpdate = FALSE, FastCall = FALSE, diff --git a/sc/source/ui/view/cellsh3.cxx b/sc/source/ui/view/cellsh3.cxx index 03334920544f..e7f405cc9340 100644 --- a/sc/source/ui/view/cellsh3.cxx +++ b/sc/source/ui/view/cellsh3.cxx @@ -861,9 +861,32 @@ void ScCellShell::Execute( SfxRequest& rReq ) const SfxUInt16Item& rUInt16Item = pReqArgs->Get( FID_COL_OPT_WIDTH ); // #101390#; the value of the macro is in HMM so use convertMm100ToTwip to convert - pTabViewShell->SetMarkedWidthOrHeight( true, SC_SIZE_OPTIMAL, - o3tl::toTwips(rUInt16Item.GetValue(), o3tl::Length::mm100) ); - ScGlobal::nLastColWidthExtra = rUInt16Item.GetValue(); + const sal_uInt16 nSizeTwips + = o3tl::toTwips(rUInt16Item.GetValue(), o3tl::Length::mm100); + ScGlobal::nLastColWidthExtra = nSizeTwips; + + if (const SfxPoolItem* pItem; pReqArgs->HasItem(FN_PARAM_1, &pItem)) + { + SCCOL nColumn = static_cast<const SfxUInt16Item*>(pItem)->GetValue() - 1; + // See also: ScColBar::SetEntrySize + std::vector<sc::ColRowSpan> aRanges; + ScMarkData& rMark = GetViewData().GetMarkData(); + + if (rMark.IsColumnMarked(nColumn)) + { + aRanges = rMark.GetMarkedColSpans(); + } + else + { + aRanges.emplace_back(nColumn, nColumn); + } + + pTabViewShell->SetWidthOrHeight(true, aRanges, SC_SIZE_OPTIMAL, nSizeTwips); + } + else + { + pTabViewShell->SetMarkedWidthOrHeight(true, SC_SIZE_OPTIMAL, nSizeTwips); + } if( ! rReq.IsAPI() ) rReq.Done(); commit e3f7588d8b5f8bf41c624b917b62b8c3eb57103f Author: Mike Kaganski <[email protected]> AuthorDate: Fri Oct 24 15:23:05 2025 +0500 Commit: Mike Kaganski <[email protected]> CommitDate: Thu Oct 30 10:53:20 2025 +0100 cool#13279: Pass ScMarkData to ScViewFunc::GetOptimalColWidth GetOptimalColWidth is only used from SetWidthOrHeight. Mark data is used both in SetWidthOrHeight itself, to iterate marked tabs; and in ScColumn::GetOptimalColWidth, to limit to marked area. As the mark data can be passed to SetWidthOrHeight directly, it is wrong to use potentially different data at different stages. Change-Id: I04ac571d7608b37f97e78f61f62e83ee18faf8b2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192949 Reviewed-by: Mike Kaganski <[email protected]> Tested-by: Jenkins diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx index 20dbc01f4de1..4520b9eb03a4 100644 --- a/sc/source/ui/inc/viewfunc.hxx +++ b/sc/source/ui/inc/viewfunc.hxx @@ -409,7 +409,7 @@ private: SCCOL nPosX, SCROW nPosY, bool bAllowDialogs, const TransferableDataHelper& rDataHelper, bool useSavedPrefs = false ); - sal_uInt16 GetOptimalColWidth( SCCOL nCol, SCTAB nTab, bool bFormula ); + sal_uInt16 GetOptimalColWidth(SCCOL nCol, SCTAB nTab, bool bFormula, const ScMarkData& rMark); void StartFormatArea(); diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx index d1526d043a4c..5d88395007b9 100644 --- a/sc/source/ui/view/viewfunc.cxx +++ b/sc/source/ui/view/viewfunc.cxx @@ -332,11 +332,10 @@ void ScViewData::setupSizeDeviceProviderForColWidth(const ScSizeDeviceProvider& } } -sal_uInt16 ScViewFunc::GetOptimalColWidth( SCCOL nCol, SCTAB nTab, bool bFormula ) +sal_uInt16 ScViewFunc::GetOptimalColWidth(SCCOL nCol, SCTAB nTab, bool bFormula, const ScMarkData& rMark) { ScDocShell& rDocSh = GetViewData().GetDocShell(); ScDocument& rDoc = rDocSh.GetDocument(); - ScMarkData& rMark = GetViewData().GetMarkData(); ScSizeDeviceProvider aProv(rDocSh); @@ -2571,7 +2570,7 @@ void ScViewFunc::SetWidthOrHeight( sal_uInt16 nThisSize = nSizeTwips; if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT ) - nThisSize = nSizeTwips + GetOptimalColWidth( nCol, nTab, bFormula ); + nThisSize = nSizeTwips + GetOptimalColWidth(nCol, nTab, bFormula, aMarkData); if ( nThisSize ) rDoc.SetColWidth( nCol, nTab, nThisSize );
