sc/qa/unit/uicalc/uicalc2.cxx |   86 ++++++++++++++++++++++++++++++++++++++++++
 sc/sdi/scalc.sdi              |    2 
 sc/source/ui/view/cellsh3.cxx |   29 ++++++++++++--
 3 files changed, 113 insertions(+), 4 deletions(-)

New commits:
commit 0cbb61d272744bf62b20f248f8e503115d483d6c
Author:     Mike Kaganski <[email protected]>
AuthorDate: Fri Oct 24 19:19:39 2025 +0500
Commit:     Miklos Vajna <[email protected]>
CommitDate: Thu Oct 30 10:33:45 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/+/192954
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/sc/qa/unit/uicalc/uicalc2.cxx b/sc/qa/unit/uicalc/uicalc2.cxx
index 7dc23ccafe96..9371e348626b 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>
@@ -1673,6 +1674,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 55e1f031eca2..a5f1dd2bb660 100644
--- a/sc/sdi/scalc.sdi
+++ b/sc/sdi/scalc.sdi
@@ -5025,7 +5025,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 879ede8c1e44..f3fc4f065eb2 100644
--- a/sc/source/ui/view/cellsh3.cxx
+++ b/sc/source/ui/view/cellsh3.cxx
@@ -862,9 +862,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();

Reply via email to