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 );
 

Reply via email to