chart2/source/controller/dialogs/res_DataLabel.hxx          |    1 
 chart2/source/controller/dialogs/res_ErrorBar.cxx           |    1 
 chart2/source/controller/dialogs/tp_3D_SceneGeometry.hxx    |    1 
 chart2/source/controller/dialogs/tp_AxisLabel.hxx           |    1 
 chart2/source/controller/dialogs/tp_PolarOptions.hxx        |    1 
 chart2/source/controller/dialogs/tp_SeriesToAxis.hxx        |    1 
 chart2/source/controller/dialogs/tp_TitleRotation.hxx       |    1 
 chart2/source/controller/sidebar/ChartAxisPanel.hxx         |    1 
 cui/source/inc/TextColumnsPage.hxx                          |    1 
 cui/source/inc/align.hxx                                    |    1 
 cui/source/inc/border.hxx                                   |    1 
 cui/source/inc/chardlg.hxx                                  |    1 
 cui/source/inc/connect.hxx                                  |    1 
 cui/source/inc/cuigrfflt.hxx                                |    1 
 cui/source/inc/cuitabarea.hxx                               |    1 
 cui/source/inc/grfpage.hxx                                  |    1 
 cui/source/inc/labdlg.hxx                                   |    1 
 cui/source/inc/measure.hxx                                  |    1 
 cui/source/inc/numpages.hxx                                 |    1 
 cui/source/inc/page.hxx                                     |    1 
 cui/source/inc/paragrph.hxx                                 |    1 
 cui/source/inc/swpossizetabpage.hxx                         |    1 
 cui/source/inc/tabstpge.hxx                                 |    1 
 cui/source/inc/textanim.hxx                                 |    1 
 cui/source/inc/textattr.hxx                                 |    1 
 cui/source/inc/transfrm.hxx                                 |    1 
 cui/source/inc/zoom.hxx                                     |    1 
 cui/source/options/optgdlg.hxx                              |    1 
 cui/source/tabpages/autocdlg.cxx                            |    1 
 dbaccess/source/ui/inc/dlgsize.hxx                          |    1 
 extensions/source/propctrlr/commoncontrol.hxx               |    1 
 extensions/source/propctrlr/standardcontrol.hxx             |    1 
 extensions/source/scanner/sanedlg.hxx                       |    1 
 filter/source/pdf/impdialog.hxx                             |    1 
 include/svx/bmpmask.hxx                                     |    1 
 include/svx/dialcontrol.hxx                                 |    1 
 include/svx/float3d.hxx                                     |    1 
 include/svx/fontwork.hxx                                    |    1 
 include/svx/fontworkgallery.hxx                             |    1 
 include/svx/hdft.hxx                                        |    1 
 include/svx/relfld.hxx                                      |    1 
 include/svx/sidebar/AreaPropertyPanelBase.hxx               |    1 
 include/svx/sidebar/AreaTransparencyGradientPopup.hxx       |    1 
 include/svx/sidebar/LinePropertyPanelBase.hxx               |    1 
 include/svx/sidebar/LineWidthPopup.hxx                      |    1 
 include/vcl/weld/MetricSpinButton.hxx                       |  189 ++++++++++++
 include/vcl/weld/weld.hxx                                   |  172 ----------
 sc/source/ui/inc/mtrindlg.hxx                               |    1 
 sc/source/ui/inc/tptable.hxx                                |    1 
 sc/source/ui/inc/tpview.hxx                                 |    1 
 sc/source/ui/sidebar/AlignmentPropertyPanel.hxx             |    1 
 sd/source/ui/inc/BulletAndPositionDlg.hxx                   |    1 
 sd/source/ui/inc/CustomAnimationPane.hxx                    |    1 
 sd/source/ui/inc/SlideTransitionPane.hxx                    |    1 
 sd/source/ui/inc/copydlg.hxx                                |    1 
 sd/source/ui/inc/dlgsnap.hxx                                |    1 
 sd/source/ui/inc/tpoption.hxx                               |    1 
 sd/source/ui/inc/vectdlg.hxx                                |    1 
 sd/source/ui/sidebar/SlideBackground.cxx                    |    1 
 starmath/inc/dialog.hxx                                     |    1 
 svtools/source/control/ctrlbox.cxx                          |    1 
 svtools/source/misc/unitconv.cxx                            |    1 
 svx/inc/extrusiondepthdialog.hxx                            |    1 
 svx/source/dialog/contimp.hxx                               |    1 
 svx/source/dialog/optgrid.cxx                               |    1 
 svx/source/dialog/spacinglistbox.cxx                        |    1 
 svx/source/sidebar/effect/EffectPropertyPanel.hxx           |    1 
 svx/source/sidebar/effect/TextEffectPropertyPanel.hxx       |    1 
 svx/source/sidebar/graphic/GraphicPropertyPanel.hxx         |    1 
 svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx     |    1 
 svx/source/sidebar/paragraph/ParaPropertyPanel.hxx          |    1 
 svx/source/sidebar/paragraph/ParaSpacingWindow.hxx          |    1 
 svx/source/sidebar/possize/PosSizePropertyPanel.hxx         |    1 
 svx/source/sidebar/shadow/ShadowPropertyPanel.hxx           |    1 
 svx/source/sidebar/text/TextCharacterSpacingControl.hxx     |    1 
 svx/source/sidebar/textcolumns/TextColumnsPropertyPanel.hxx |    1 
 svx/source/tbxctrls/grafctrl.cxx                            |    1 
 svx/source/tbxctrls/linemetricbox.hxx                       |    1 
 sw/inc/colwd.hxx                                            |    1 
 sw/source/ui/dbui/mmlayoutpage.hxx                          |    1 
 sw/source/ui/envelp/envprt.hxx                              |    1 
 sw/source/ui/envelp/labfmt.hxx                              |    1 
 sw/source/ui/inc/regionsw.hxx                               |    1 
 sw/source/uibase/inc/column.hxx                             |    1 
 sw/source/uibase/inc/drpcps.hxx                             |    1 
 sw/source/uibase/inc/envlop.hxx                             |    1 
 sw/source/uibase/inc/frmpage.hxx                            |    1 
 sw/source/uibase/inc/labimp.hxx                             |    1 
 sw/source/uibase/inc/linenum.hxx                            |    1 
 sw/source/uibase/inc/num.hxx                                |    1 
 sw/source/uibase/inc/optload.hxx                            |    1 
 sw/source/uibase/inc/optpage.hxx                            |    1 
 sw/source/uibase/inc/pgfnote.hxx                            |    1 
 sw/source/uibase/inc/pggrid.hxx                             |    1 
 sw/source/uibase/inc/prcntfld.hxx                           |    1 
 sw/source/uibase/inc/rowht.hxx                              |    1 
 sw/source/uibase/inc/swuicnttab.hxx                         |    1 
 sw/source/uibase/inc/watermarkdialog.hxx                    |    1 
 sw/source/uibase/inc/wrap.hxx                               |    1 
 sw/source/uibase/sidebar/PageFormatPanel.hxx                |    1 
 sw/source/uibase/sidebar/PageMarginControl.hxx              |    1 
 sw/source/uibase/sidebar/PageSizeControl.hxx                |    1 
 sw/source/uibase/sidebar/TableEditPanel.hxx                 |    1 
 sw/source/uibase/table/tablepg.hxx                          |    1 
 vcl/Library_vcl.mk                                          |    1 
 vcl/inc/colorpicker.hxx                                     |    1 
 vcl/inc/printdlg.hxx                                        |    1 
 vcl/inc/qt5/QtInstanceBuilder.hxx                           |    1 
 vcl/inc/salvtables.hxx                                      |    1 
 vcl/source/weld/MetricSpinButton.cxx                        |  148 +++++++++
 vcl/source/weld/weldutils.cxx                               |   37 ++
 vcl/source/window/builder.cxx                               |  164 ----------
 vcl/unx/gtk3/gtkinst.cxx                                    |    1 
 113 files changed, 483 insertions(+), 335 deletions(-)

New commits:
commit 3278e44460afd4f87ce22c9abdabbe76f31a57b2
Author:     Michael Weghorn <[email protected]>
AuthorDate: Thu Dec 18 10:54:10 2025 +0100
Commit:     Michael Weghorn <[email protected]>
CommitDate: Thu Dec 18 19:44:31 2025 +0100

    weld: Move 2 helpers to source file matching header
    
    Move these 2 helper functions declared in
    include/vcl/weld/weldutils.hxx to the weldutils.cxx
    source file where the other logic declared in that
    header is also implemented instead of having them
    in a source file that is mostly about the otherwise
    unrelated VclBuilder implementation otherwise.
    
    Change-Id: I0fd646f2ca40dbe6f4d171f7124c4a1ffa2d13cf
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195833
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/vcl/source/weld/weldutils.cxx b/vcl/source/weld/weldutils.cxx
index cd3c4adb7b2f..e5c8e811f725 100644
--- a/vcl/source/weld/weldutils.cxx
+++ b/vcl/source/weld/weldutils.cxx
@@ -115,6 +115,43 @@ void 
TriStateEnabled::CheckButtonToggled(weld::CheckButton& rToggle)
     eState = rToggle.get_state();
 }
 
+size_t GetAbsPos(const weld::TreeView& rTreeView, const weld::TreeIter& rIter)
+{
+    size_t nAbsPos = 0;
+
+    std::unique_ptr<weld::TreeIter> xEntry(rTreeView.make_iterator(&rIter));
+    if (!rTreeView.get_iter_first(*xEntry))
+        xEntry.reset();
+
+    while (xEntry && rTreeView.iter_compare(*xEntry, rIter) != 0)
+    {
+        if (!rTreeView.iter_next(*xEntry))
+            xEntry.reset();
+        nAbsPos++;
+    }
+
+    return nAbsPos;
+}
+
+bool IsEntryVisible(const weld::TreeView& rTreeView, const weld::TreeIter& 
rIter)
+{
+    // short circuit for the common case
+    if (rTreeView.get_iter_depth(rIter) == 0)
+        return true;
+
+    std::unique_ptr<weld::TreeIter> xEntry(rTreeView.make_iterator(&rIter));
+    bool bRetVal = false;
+    do
+    {
+        if (rTreeView.get_iter_depth(*xEntry) == 0)
+        {
+            bRetVal = true;
+            break;
+        }
+    } while (rTreeView.iter_parent(*xEntry) && 
rTreeView.get_row_expanded(*xEntry));
+    return bRetVal;
+}
+
 void RemoveParentKeepChildren(weld::TreeView& rTreeView, const weld::TreeIter& 
rParent)
 {
     if (rTreeView.iter_has_child(rParent))
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 5a6d0630fbb0..c87788b846a8 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -303,43 +303,6 @@ namespace weld
             return (nValue - nHalf) / nFactor;
         return (nValue + nHalf) / nFactor;
     }
-
-    size_t GetAbsPos(const weld::TreeView& rTreeView, const weld::TreeIter& 
rIter)
-    {
-        size_t nAbsPos = 0;
-
-        std::unique_ptr<weld::TreeIter> 
xEntry(rTreeView.make_iterator(&rIter));
-        if (!rTreeView.get_iter_first(*xEntry))
-            xEntry.reset();
-
-        while (xEntry && rTreeView.iter_compare(*xEntry, rIter) != 0)
-        {
-            if (!rTreeView.iter_next(*xEntry))
-                xEntry.reset();
-            nAbsPos++;
-        }
-
-        return nAbsPos;
-    }
-
-    bool IsEntryVisible(const weld::TreeView& rTreeView, const weld::TreeIter& 
rIter)
-    {
-        // short circuit for the common case
-        if (rTreeView.get_iter_depth(rIter) == 0)
-            return true;
-
-        std::unique_ptr<weld::TreeIter> 
xEntry(rTreeView.make_iterator(&rIter));
-        bool bRetVal = false;
-        do
-        {
-            if (rTreeView.get_iter_depth(*xEntry) == 0)
-            {
-                bRetVal = true;
-                break;
-            }
-        }  while (rTreeView.iter_parent(*xEntry) && 
rTreeView.get_row_expanded(*xEntry));
-        return bRetVal;
-    }
 }
 
 // static
commit a28f06f474e9f1ae6e366f2264c559c94de68fb6
Author:     Michael Weghorn <[email protected]>
AuthorDate: Thu Dec 18 10:45:59 2025 +0100
Commit:     Michael Weghorn <[email protected]>
CommitDate: Thu Dec 18 19:44:22 2025 +0100

    weld: Move weld::MetricSpinButton to own header/source file
    
    Move the implementation to a new source file in the
    vcl/source/weld directory where most of the code for
    implementing weld::Widget implementations is by now
    (apart from the headers), while
    vcl/source/window/builder.cxx is mostly about
    VclBuilder.
    
    Change-Id: Ide967dab4a5321871da057f0c6b799dbc21230dd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195832
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/chart2/source/controller/dialogs/res_DataLabel.hxx 
b/chart2/source/controller/dialogs/res_DataLabel.hxx
index 66a062d2ca24..a50895731bd3 100644
--- a/chart2/source/controller/dialogs/res_DataLabel.hxx
+++ b/chart2/source/controller/dialogs/res_DataLabel.hxx
@@ -20,6 +20,7 @@
 
 #include <svl/itemset.hxx>
 #include <svx/dialcontrol.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <TextDirectionListBox.hxx>
 
 #include <map>
diff --git a/chart2/source/controller/dialogs/res_ErrorBar.cxx 
b/chart2/source/controller/dialogs/res_ErrorBar.cxx
index 431952248568..3fe92f971ac8 100644
--- a/chart2/source/controller/dialogs/res_ErrorBar.cxx
+++ b/chart2/source/controller/dialogs/res_ErrorBar.cxx
@@ -22,6 +22,7 @@
 #include <RangeSelectionHelper.hxx>
 #include <helpids.h>
 #include <chartview/ChartSfxItemIds.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 #include <ChartModel.hxx>
 
diff --git a/chart2/source/controller/dialogs/tp_3D_SceneGeometry.hxx 
b/chart2/source/controller/dialogs/tp_3D_SceneGeometry.hxx
index e89378b60337..db0de7211734 100644
--- a/chart2/source/controller/dialogs/tp_3D_SceneGeometry.hxx
+++ b/chart2/source/controller/dialogs/tp_3D_SceneGeometry.hxx
@@ -19,6 +19,7 @@
 #pragma once
 
 #include <vcl/timer.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 #include <rtl/ref.hxx>
 
diff --git a/chart2/source/controller/dialogs/tp_AxisLabel.hxx 
b/chart2/source/controller/dialogs/tp_AxisLabel.hxx
index f3062163e28c..1bed8e05c231 100644
--- a/chart2/source/controller/dialogs/tp_AxisLabel.hxx
+++ b/chart2/source/controller/dialogs/tp_AxisLabel.hxx
@@ -21,6 +21,7 @@
 #include <sfx2/tabdlg.hxx>
 #include <svx/dialcontrol.hxx>
 #include <tools/degree.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <TextDirectionListBox.hxx>
 
 namespace weld {
diff --git a/chart2/source/controller/dialogs/tp_PolarOptions.hxx 
b/chart2/source/controller/dialogs/tp_PolarOptions.hxx
index 51ad7a809be0..656879f3c896 100644
--- a/chart2/source/controller/dialogs/tp_PolarOptions.hxx
+++ b/chart2/source/controller/dialogs/tp_PolarOptions.hxx
@@ -20,6 +20,7 @@
 
 #include <sfx2/tabdlg.hxx>
 #include <svx/dialcontrol.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 namespace weld {
     class CheckButton;
diff --git a/chart2/source/controller/dialogs/tp_SeriesToAxis.hxx 
b/chart2/source/controller/dialogs/tp_SeriesToAxis.hxx
index 48001d4fb7b8..9b8b46a1392f 100644
--- a/chart2/source/controller/dialogs/tp_SeriesToAxis.hxx
+++ b/chart2/source/controller/dialogs/tp_SeriesToAxis.hxx
@@ -19,6 +19,7 @@
 #pragma once
 
 #include <sfx2/tabdlg.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 namespace weld {
     class CheckButton;
diff --git a/chart2/source/controller/dialogs/tp_TitleRotation.hxx 
b/chart2/source/controller/dialogs/tp_TitleRotation.hxx
index 559212ddf293..ae34d8a4d0f1 100644
--- a/chart2/source/controller/dialogs/tp_TitleRotation.hxx
+++ b/chart2/source/controller/dialogs/tp_TitleRotation.hxx
@@ -20,6 +20,7 @@
 
 #include <sfx2/tabdlg.hxx>
 #include <svx/dialcontrol.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <TextDirectionListBox.hxx>
 
 namespace weld {
diff --git a/chart2/source/controller/sidebar/ChartAxisPanel.hxx 
b/chart2/source/controller/sidebar/ChartAxisPanel.hxx
index e5ed4b5ebcc6..1dddc8bce8c1 100644
--- a/chart2/source/controller/sidebar/ChartAxisPanel.hxx
+++ b/chart2/source/controller/sidebar/ChartAxisPanel.hxx
@@ -14,6 +14,7 @@
 #include <sfx2/sidebar/IContextChangeReceiver.hxx>
 #include <sfx2/sidebar/SidebarModelUpdate.hxx>
 #include <sfx2/sidebar/PanelLayout.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include "ChartSidebarModifyListener.hxx"
 #include "ChartSidebarSelectionListener.hxx"
 
diff --git a/cui/source/inc/TextColumnsPage.hxx 
b/cui/source/inc/TextColumnsPage.hxx
index 0aa6e2c9e800..c61fcd03c548 100644
--- a/cui/source/inc/TextColumnsPage.hxx
+++ b/cui/source/inc/TextColumnsPage.hxx
@@ -12,6 +12,7 @@
 #include <sal/config.h>
 
 #include <sfx2/tabdlg.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 #include <memory>
 
diff --git a/cui/source/inc/align.hxx b/cui/source/inc/align.hxx
index ca578ac955d6..7c99b1bf8ce6 100644
--- a/cui/source/inc/align.hxx
+++ b/cui/source/inc/align.hxx
@@ -42,6 +42,7 @@ enum VerticalAlign {
 #include <svtools/valueset.hxx>
 #include <svx/dialcontrol.hxx>
 #include <svx/frmdirlbox.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 
 class SvxJustifyMethodItem;
diff --git a/cui/source/inc/border.hxx b/cui/source/inc/border.hxx
index d929ba8fc1ff..30b0d2369d75 100644
--- a/cui/source/inc/border.hxx
+++ b/cui/source/inc/border.hxx
@@ -21,6 +21,7 @@
 #include <editeng/shaditem.hxx>
 #include <svtools/ctrlbox.hxx>
 #include <vcl/weld/IconView.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 #include <sfx2/tabdlg.hxx>
 #include <svx/algitem.hxx>
diff --git a/cui/source/inc/chardlg.hxx b/cui/source/inc/chardlg.hxx
index adede23d5029..ed69628c3d68 100644
--- a/cui/source/inc/chardlg.hxx
+++ b/cui/source/inc/chardlg.hxx
@@ -23,6 +23,7 @@
 #include <svx/fntctrl.hxx>
 #include <svx/colorbox.hxx>
 #include <svx/langbox.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/TreeView.hxx>
 #include <vcl/weld/weld.hxx>
 #include <memory>
diff --git a/cui/source/inc/connect.hxx b/cui/source/inc/connect.hxx
index 218f1666c0c7..3b8b58f9eddf 100644
--- a/cui/source/inc/connect.hxx
+++ b/cui/source/inc/connect.hxx
@@ -20,6 +20,7 @@
 
 #include <svx/connctrl.hxx>
 #include <sfx2/tabdlg.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <vcl/weld/weld.hxx>
 #include <sfx2/basedlgs.hxx>
diff --git a/cui/source/inc/cuigrfflt.hxx b/cui/source/inc/cuigrfflt.hxx
index 075c74c29f42..ffd62dd92f22 100644
--- a/cui/source/inc/cuigrfflt.hxx
+++ b/cui/source/inc/cuigrfflt.hxx
@@ -22,6 +22,7 @@
 #include <vcl/timer.hxx>
 #include <svx/dlgctrl.hxx>
 #include <svx/rectenum.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class CuiGraphicPreviewWindow : public weld::CustomWidgetController
 {
diff --git a/cui/source/inc/cuitabarea.hxx b/cui/source/inc/cuitabarea.hxx
index c1acc7f2ce14..faf1c26374d3 100644
--- a/cui/source/inc/cuitabarea.hxx
+++ b/cui/source/inc/cuitabarea.hxx
@@ -27,6 +27,7 @@
 #include <svx/PaletteManager.hxx>
 #include <svx/svdview.hxx>
 #include <vcl/hexcolorcontrol.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class ColorListBox;
 class SdrModel;
diff --git a/cui/source/inc/grfpage.hxx b/cui/source/inc/grfpage.hxx
index 12d44bc268a0..f0e5aa3492ef 100644
--- a/cui/source/inc/grfpage.hxx
+++ b/cui/source/inc/grfpage.hxx
@@ -20,6 +20,7 @@
 #pragma once
 
 #include <vcl/graph.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <sfx2/tabdlg.hxx>
 
diff --git a/cui/source/inc/labdlg.hxx b/cui/source/inc/labdlg.hxx
index b04c2a2b6d05..0ce3f7ff2c1c 100644
--- a/cui/source/inc/labdlg.hxx
+++ b/cui/source/inc/labdlg.hxx
@@ -24,6 +24,7 @@
 #include <svx/sxcecitm.hxx>
 #include <svx/anchorid.hxx>
 #include <vcl/image.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class SdrView;
 
diff --git a/cui/source/inc/measure.hxx b/cui/source/inc/measure.hxx
index c30e83ee1ed4..723d9fee0e1d 100644
--- a/cui/source/inc/measure.hxx
+++ b/cui/source/inc/measure.hxx
@@ -21,6 +21,7 @@
 #include <sfx2/basedlgs.hxx>
 #include <svx/dlgctrl.hxx>
 #include <svx/measctrl.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class SdrView;
 
diff --git a/cui/source/inc/numpages.hxx b/cui/source/inc/numpages.hxx
index 37de9822097e..ffe6292e9747 100644
--- a/cui/source/inc/numpages.hxx
+++ b/cui/source/inc/numpages.hxx
@@ -26,6 +26,7 @@
 #include <editeng/svxenum.hxx>
 #include <svtools/ctrlbox.hxx>
 #include <svx/numberingpreview.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/TreeView.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <vcl/timer.hxx>
diff --git a/cui/source/inc/page.hxx b/cui/source/inc/page.hxx
index 81acdd58a7c8..fe4b2cfc8d97 100644
--- a/cui/source/inc/page.hxx
+++ b/cui/source/inc/page.hxx
@@ -26,6 +26,7 @@
 #include <i18nutil/paper.hxx>
 #include <svx/flagsdef.hxx>
 #include <vcl/print.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 // class SvxPageDescPage -------------------------------------------------
 /*
diff --git a/cui/source/inc/paragrph.hxx b/cui/source/inc/paragrph.hxx
index 9d95e1adfa9b..8ab678c83f6f 100644
--- a/cui/source/inc/paragrph.hxx
+++ b/cui/source/inc/paragrph.hxx
@@ -22,6 +22,7 @@
 #include <svx/relfld.hxx>
 #include <svx/paraprev.hxx>
 #include <svx/frmdirlbox.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class SvxLineSpacingItem;
 
diff --git a/cui/source/inc/swpossizetabpage.hxx 
b/cui/source/inc/swpossizetabpage.hxx
index 83edd4379572..c4fbdf112255 100644
--- a/cui/source/inc/swpossizetabpage.hxx
+++ b/cui/source/inc/swpossizetabpage.hxx
@@ -20,6 +20,7 @@
 
 #include <sfx2/tabdlg.hxx>
 #include <svx/swframeexample.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 #include <svx/dlgutil.hxx>
 
diff --git a/cui/source/inc/tabstpge.hxx b/cui/source/inc/tabstpge.hxx
index b9a556591a85..a6ae82a3dbfd 100644
--- a/cui/source/inc/tabstpge.hxx
+++ b/cui/source/inc/tabstpge.hxx
@@ -19,6 +19,7 @@
 #pragma once
 
 #include <vcl/weld/EntryTreeView.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/TreeView.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <vcl/weld/weld.hxx>
diff --git a/cui/source/inc/textanim.hxx b/cui/source/inc/textanim.hxx
index 9ac0e2f991c6..7d9b8a895ef5 100644
--- a/cui/source/inc/textanim.hxx
+++ b/cui/source/inc/textanim.hxx
@@ -21,6 +21,7 @@
 #include <sfx2/tabdlg.hxx>
 #include <svx/sdtakitm.hxx>
 #include <svx/sdtaditm.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 
 class SdrView;
diff --git a/cui/source/inc/textattr.hxx b/cui/source/inc/textattr.hxx
index 8ea2e4d8e43d..c1a13272edaa 100644
--- a/cui/source/inc/textattr.hxx
+++ b/cui/source/inc/textattr.hxx
@@ -20,6 +20,7 @@
 
 #include <svx/dlgctrl.hxx>
 #include <svx/svdobjkind.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 /*************************************************************************
 |*
diff --git a/cui/source/inc/transfrm.hxx b/cui/source/inc/transfrm.hxx
index 6ea12bb67a82..0edd62deaf18 100644
--- a/cui/source/inc/transfrm.hxx
+++ b/cui/source/inc/transfrm.hxx
@@ -22,6 +22,7 @@
 #include <svx/dlgutil.hxx>
 #include <svx/dialcontrol.hxx>
 #include <svx/anchorid.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <basegfx/range/b2drange.hxx>
 
 // predefines
diff --git a/cui/source/inc/zoom.hxx b/cui/source/inc/zoom.hxx
index 66bf0dcafa6f..4d4d6053e679 100644
--- a/cui/source/inc/zoom.hxx
+++ b/cui/source/inc/zoom.hxx
@@ -22,6 +22,7 @@
 #include <sfx2/basedlgs.hxx>
 #include <svl/itemset.hxx>
 #include <svx/zoom_def.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 
 class SvxZoomDialog : public SfxDialogController
diff --git a/cui/source/options/optgdlg.hxx b/cui/source/options/optgdlg.hxx
index 4bebe067cd41..c6fbc2529dda 100644
--- a/cui/source/options/optgdlg.hxx
+++ b/cui/source/options/optgdlg.hxx
@@ -21,6 +21,7 @@
 #include <config_features.h>
 #include <sfx2/tabdlg.hxx>
 #include <svx/langbox.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class CanvasSettings;
 
diff --git a/cui/source/tabpages/autocdlg.cxx b/cui/source/tabpages/autocdlg.cxx
index 132f2c903305..9ca743ed690f 100644
--- a/cui/source/tabpages/autocdlg.cxx
+++ b/cui/source/tabpages/autocdlg.cxx
@@ -26,6 +26,7 @@
 #include <vcl/keycodes.hxx>
 #include <vcl/settings.hxx>
 #include <vcl/transfer.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/TreeView.hxx>
 #include <sfx2/app.hxx>
 #include <sfx2/objsh.hxx>
diff --git a/dbaccess/source/ui/inc/dlgsize.hxx 
b/dbaccess/source/ui/inc/dlgsize.hxx
index 34ae24ad49cc..b32c060ea4b3 100644
--- a/dbaccess/source/ui/inc/dlgsize.hxx
+++ b/dbaccess/source/ui/inc/dlgsize.hxx
@@ -18,6 +18,7 @@
  */
 #pragma once
 
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 
 namespace dbaui
diff --git a/extensions/source/propctrlr/commoncontrol.hxx 
b/extensions/source/propctrlr/commoncontrol.hxx
index a7bff865dd96..62fc99d856ae 100644
--- a/extensions/source/propctrlr/commoncontrol.hxx
+++ b/extensions/source/propctrlr/commoncontrol.hxx
@@ -24,6 +24,7 @@
 #include <cppuhelper/compbase.hxx>
 #include <cppuhelper/basemutex.hxx>
 #include <tools/link.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 #include <vcl/weld/weldutils.hxx>
 
diff --git a/extensions/source/propctrlr/standardcontrol.hxx 
b/extensions/source/propctrlr/standardcontrol.hxx
index 35888811b155..08147130de4f 100644
--- a/extensions/source/propctrlr/standardcontrol.hxx
+++ b/extensions/source/propctrlr/standardcontrol.hxx
@@ -28,6 +28,7 @@
 #include <comphelper/interfacecontainer2.hxx>
 #include <svtools/ctrlbox.hxx>
 #include <svx/colorbox.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 namespace pcr
 {
diff --git a/extensions/source/scanner/sanedlg.hxx 
b/extensions/source/scanner/sanedlg.hxx
index 8ed4ef9dd4cc..0266ce01707b 100644
--- a/extensions/source/scanner/sanedlg.hxx
+++ b/extensions/source/scanner/sanedlg.hxx
@@ -18,6 +18,7 @@
  */
 #pragma once
 
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/TreeView.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <vcl/weld/weld.hxx>
diff --git a/filter/source/pdf/impdialog.hxx b/filter/source/pdf/impdialog.hxx
index 4e3e088f053c..b8e78d92b343 100644
--- a/filter/source/pdf/impdialog.hxx
+++ b/filter/source/pdf/impdialog.hxx
@@ -24,6 +24,7 @@
 
 #include <vcl/pdfwriter.hxx>
 #include <vcl/FilterConfigItem.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/TreeView.hxx>
 #include <vcl/weld/weld.hxx>
 
diff --git a/include/svx/bmpmask.hxx b/include/svx/bmpmask.hxx
index bfd92f76f0f8..b9320ad902ec 100644
--- a/include/svx/bmpmask.hxx
+++ b/include/svx/bmpmask.hxx
@@ -30,6 +30,7 @@
 #include <vcl/bitmap.hxx>
 #include <vcl/gdimtf.hxx>
 #include <vcl/graph.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <memory>
 
 namespace vcl { class Window; }
diff --git a/include/svx/dialcontrol.hxx b/include/svx/dialcontrol.hxx
index 3eef892613a0..529f0f978760 100644
--- a/include/svx/dialcontrol.hxx
+++ b/include/svx/dialcontrol.hxx
@@ -22,6 +22,7 @@
 
 #include <memory>
 #include <vcl/virdev.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <svx/svxdllapi.h>
 
diff --git a/include/svx/float3d.hxx b/include/svx/float3d.hxx
index b092ff701bbb..299d55fddb2b 100644
--- a/include/svx/float3d.hxx
+++ b/include/svx/float3d.hxx
@@ -24,6 +24,7 @@
 #include <editeng/colritem.hxx>
 #include <sfx2/ctrlitem.hxx>
 #include <sfx2/dockwin.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 #include <svl/eitem.hxx>
 #include <svx/e3ditem.hxx>
diff --git a/include/svx/fontwork.hxx b/include/svx/fontwork.hxx
index cf6ae5c60f76..1780e3a313d6 100644
--- a/include/svx/fontwork.hxx
+++ b/include/svx/fontwork.hxx
@@ -23,6 +23,7 @@
 #include <sfx2/ctrlitem.hxx>
 #include <svx/svxdllapi.h>
 #include <vcl/idle.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 
 class ColorListBox;
diff --git a/include/svx/fontworkgallery.hxx b/include/svx/fontworkgallery.hxx
index 4391ca1b8738..bb805be4b7a8 100644
--- a/include/svx/fontworkgallery.hxx
+++ b/include/svx/fontworkgallery.hxx
@@ -23,6 +23,7 @@
 
 #include <svx/svxdllapi.h>
 #include <vcl/weld/IconView.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 #include <com/sun/star/frame/XFrame.hpp>
 #include <map>
diff --git a/include/svx/hdft.hxx b/include/svx/hdft.hxx
index 2b9fe5f03f21..227958d0c1d9 100644
--- a/include/svx/hdft.hxx
+++ b/include/svx/hdft.hxx
@@ -21,6 +21,7 @@
 
 #include <sfx2/tabdlg.hxx>
 
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 
 #include <svx/pagectrl.hxx>
diff --git a/include/svx/relfld.hxx b/include/svx/relfld.hxx
index de4ad875f417..dc9611a479f4 100644
--- a/include/svx/relfld.hxx
+++ b/include/svx/relfld.hxx
@@ -21,6 +21,7 @@
 
 #include <tools/fldunit.hxx>
 #include <svtools/unitconv.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 #include <svx/svxdllapi.h>
 
diff --git a/include/svx/sidebar/AreaPropertyPanelBase.hxx 
b/include/svx/sidebar/AreaPropertyPanelBase.hxx
index 131d53233eca..f1bff240466c 100644
--- a/include/svx/sidebar/AreaPropertyPanelBase.hxx
+++ b/include/svx/sidebar/AreaPropertyPanelBase.hxx
@@ -35,6 +35,7 @@
 #include <svl/intitem.hxx>
 #include <svx/svxdllapi.h>
 #include <vcl/EnumContext.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class ToolbarUnoDispatcher;
 class XFillFloatTransparenceItem;
diff --git a/include/svx/sidebar/AreaTransparencyGradientPopup.hxx 
b/include/svx/sidebar/AreaTransparencyGradientPopup.hxx
index 3aa26b6e3fa1..96d9643a7a83 100644
--- a/include/svx/sidebar/AreaTransparencyGradientPopup.hxx
+++ b/include/svx/sidebar/AreaTransparencyGradientPopup.hxx
@@ -20,6 +20,7 @@
 #define INCLUDED_SVX_SOURCE_SIDEBAR_AREA_AREATRANSPARENCYGRADIENTPOPUP_HXX
 
 #include <basegfx/utils/bgradient.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 #include <svtools/toolbarmenu.hxx>
 
diff --git a/include/svx/sidebar/LinePropertyPanelBase.hxx 
b/include/svx/sidebar/LinePropertyPanelBase.hxx
index a063b955c414..ea1fc8475eee 100644
--- a/include/svx/sidebar/LinePropertyPanelBase.hxx
+++ b/include/svx/sidebar/LinePropertyPanelBase.hxx
@@ -19,6 +19,7 @@
 #ifndef INCLUDED_SVX_SOURCE_SIDEBAR_LINE_LINEPROPERTYPANELBASE_HXX
 #define INCLUDED_SVX_SOURCE_SIDEBAR_LINE_LINEPROPERTYPANELBASE_HXX
 
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 #include <memory>
 #include <svl/poolitem.hxx>
diff --git a/include/svx/sidebar/LineWidthPopup.hxx 
b/include/svx/sidebar/LineWidthPopup.hxx
index 193b04acb96e..b57674313fe4 100644
--- a/include/svx/sidebar/LineWidthPopup.hxx
+++ b/include/svx/sidebar/LineWidthPopup.hxx
@@ -21,6 +21,7 @@
 
 #include <tools/mapunit.hxx>
 #include <vcl/image.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <vcl/weld/weld.hxx>
 #include <svtools/toolbarmenu.hxx>
diff --git a/include/vcl/weld/MetricSpinButton.hxx 
b/include/vcl/weld/MetricSpinButton.hxx
new file mode 100644
index 000000000000..2e247ba2f8d3
--- /dev/null
+++ b/include/vcl/weld/MetricSpinButton.hxx
@@ -0,0 +1,189 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <vcl/dllapi.h>
+#include <vcl/weld/weld.hxx>
+
+namespace weld
+{
+class VCL_DLLPUBLIC MetricSpinButton final
+{
+    FieldUnit m_eSrcUnit;
+    std::unique_ptr<weld::SpinButton> m_xSpinButton;
+    Link<MetricSpinButton&, void> m_aValueChangedHdl;
+
+    DECL_LINK(spin_button_value_changed, weld::SpinButton&, void);
+    DECL_LINK(spin_button_output, sal_Int64, OUString);
+    DECL_LINK(spin_button_input, const OUString&, std::optional<int>);
+
+    void signal_value_changed() { m_aValueChangedHdl.Call(*this); }
+
+    sal_Int64 ConvertValue(sal_Int64 nValue, FieldUnit eInUnit, FieldUnit 
eOutUnit) const;
+    OUString format_number(sal_Int64 nValue) const;
+    void update_width_chars();
+
+public:
+    MetricSpinButton(std::unique_ptr<SpinButton> pSpinButton, FieldUnit 
eSrcUnit)
+        : m_eSrcUnit(eSrcUnit)
+        , m_xSpinButton(std::move(pSpinButton))
+    {
+        update_width_chars();
+        m_xSpinButton->set_value_formatter(LINK(this, MetricSpinButton, 
spin_button_output));
+        m_xSpinButton->set_text_parser(LINK(this, MetricSpinButton, 
spin_button_input));
+        m_xSpinButton->connect_value_changed(
+            LINK(this, MetricSpinButton, spin_button_value_changed));
+        m_xSpinButton->set_text(format_number(m_xSpinButton->get_value()));
+    }
+
+    static OUString MetricToString(FieldUnit rUnit);
+
+    FieldUnit get_unit() const { return m_eSrcUnit; }
+
+    void set_unit(FieldUnit eUnit);
+
+    sal_Int64 convert_value_to(sal_Int64 nValue, FieldUnit eValueUnit) const
+    {
+        return ConvertValue(nValue, m_eSrcUnit, eValueUnit);
+    }
+
+    sal_Int64 convert_value_from(sal_Int64 nValue, FieldUnit eValueUnit) const
+    {
+        return ConvertValue(nValue, eValueUnit, m_eSrcUnit);
+    }
+
+    void set_value(sal_Int64 nValue, FieldUnit eValueUnit)
+    {
+        m_xSpinButton->set_value(convert_value_from(nValue, eValueUnit));
+    }
+
+    sal_Int64 get_value(FieldUnit eDestUnit) const
+    {
+        return convert_value_to(m_xSpinButton->get_value(), eDestUnit);
+    }
+
+    // typically you only need to call this if set_text (e.g. with "") was
+    // previously called to display some arbitrary text instead of the
+    // formatted value and now you want to show it as formatted again
+    void reformat()
+    {
+        const OUString sText = format_number(m_xSpinButton->get_value());
+        m_xSpinButton->set_text(sText);
+    }
+
+    void set_range(sal_Int64 min, sal_Int64 max, FieldUnit eValueUnit)
+    {
+        min = convert_value_from(min, eValueUnit);
+        max = convert_value_from(max, eValueUnit);
+        m_xSpinButton->set_range(min, max);
+        update_width_chars();
+    }
+
+    void get_range(sal_Int64& min, sal_Int64& max, FieldUnit eDestUnit) const
+    {
+        m_xSpinButton->get_range(min, max);
+        min = convert_value_to(min, eDestUnit);
+        max = convert_value_to(max, eDestUnit);
+    }
+
+    void set_min(sal_Int64 min, FieldUnit eValueUnit)
+    {
+        sal_Int64 dummy, max;
+        get_range(dummy, max, eValueUnit);
+        set_range(min, max, eValueUnit);
+    }
+
+    void set_max(sal_Int64 max, FieldUnit eValueUnit)
+    {
+        sal_Int64 min, dummy;
+        get_range(min, dummy, eValueUnit);
+        set_range(min, max, eValueUnit);
+    }
+
+    sal_Int64 get_min(FieldUnit eValueUnit) const
+    {
+        sal_Int64 min, dummy;
+        get_range(min, dummy, eValueUnit);
+        return min;
+    }
+
+    sal_Int64 get_max(FieldUnit eValueUnit) const
+    {
+        sal_Int64 dummy, max;
+        get_range(dummy, max, eValueUnit);
+        return max;
+    }
+
+    void set_increments(sal_Int64 step, sal_Int64 page, FieldUnit eValueUnit)
+    {
+        step = convert_value_from(step, eValueUnit);
+        page = convert_value_from(page, eValueUnit);
+        m_xSpinButton->set_increments(step, page);
+    }
+
+    void get_increments(sal_Int64& step, sal_Int64& page, FieldUnit eDestUnit) 
const
+    {
+        m_xSpinButton->get_increments(step, page);
+        step = convert_value_to(step, eDestUnit);
+        page = convert_value_to(page, eDestUnit);
+    }
+
+    void connect_value_changed(const Link<MetricSpinButton&, void>& rLink)
+    {
+        m_aValueChangedHdl = rLink;
+    }
+
+    sal_Int64 normalize(sal_Int64 nValue) const { return 
m_xSpinButton->normalize(nValue); }
+    sal_Int64 denormalize(sal_Int64 nValue) const { return 
m_xSpinButton->denormalize(nValue); }
+    void set_sensitive(bool sensitive) { 
m_xSpinButton->set_sensitive(sensitive); }
+    bool get_sensitive() const { return m_xSpinButton->get_sensitive(); }
+    bool get_visible() const { return m_xSpinButton->get_visible(); }
+    void grab_focus() { m_xSpinButton->grab_focus(); }
+    bool has_focus() const { return m_xSpinButton->has_focus(); }
+    void show() { m_xSpinButton->show(); }
+    void set_visible(bool bShow) { m_xSpinButton->set_visible(bShow); }
+    void hide() { m_xSpinButton->hide(); }
+    void set_digits(unsigned int digits);
+    void set_accessible_name(const OUString& rName) { 
m_xSpinButton->set_accessible_name(rName); }
+    unsigned int get_digits() const { return m_xSpinButton->get_digits(); }
+    void save_value() { m_xSpinButton->save_value(); }
+    bool get_value_changed_from_saved() const
+    {
+        return m_xSpinButton->get_value_changed_from_saved();
+    }
+    void set_text(const OUString& rText) { m_xSpinButton->set_text(rText); }
+    OUString get_text() const { return m_xSpinButton->get_text(); }
+    void set_size_request(int nWidth, int nHeight)
+    {
+        m_xSpinButton->set_size_request(nWidth, nHeight);
+    }
+    Size get_size_request() const { return m_xSpinButton->get_size_request(); }
+    Size get_preferred_size() const { return 
m_xSpinButton->get_preferred_size(); }
+    void connect_focus_in(const Link<Widget&, void>& rLink)
+    {
+        m_xSpinButton->connect_focus_in(rLink);
+    }
+    void connect_focus_out(const Link<Widget&, void>& rLink)
+    {
+        m_xSpinButton->connect_focus_out(rLink);
+    }
+    OUString get_buildable_name() const { return 
m_xSpinButton->get_buildable_name(); }
+    void set_help_id(const OUString& rName) { 
m_xSpinButton->set_help_id(rName); }
+    void set_position(int nCursorPos) { 
m_xSpinButton->set_position(nCursorPos); }
+    // set the width of the underlying widget in characters, this setting is
+    // invalidated when changing the units, range or digits, so to have effect
+    // must come after changing those values
+    void set_width_chars(int nChars) { m_xSpinButton->set_width_chars(nChars); 
}
+    int get_width_chars() const { return m_xSpinButton->get_width_chars(); }
+    weld::SpinButton& get_widget() { return *m_xSpinButton; }
+};
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/include/vcl/weld/weld.hxx b/include/vcl/weld/weld.hxx
index 34cf4bf28f6c..70e24faaa4b7 100644
--- a/include/vcl/weld/weld.hxx
+++ b/include/vcl/weld/weld.hxx
@@ -81,6 +81,7 @@ class Container;
 class DialogController;
 class EntryTreeView;
 class IconView;
+class MetricSpinButton;
 class TreeView;
 
 class VCL_DLLPUBLIC Widget
@@ -1599,177 +1600,6 @@ public:
     virtual Date get_date() const = 0;
 };
 
-class VCL_DLLPUBLIC MetricSpinButton final
-{
-    FieldUnit m_eSrcUnit;
-    std::unique_ptr<weld::SpinButton> m_xSpinButton;
-    Link<MetricSpinButton&, void> m_aValueChangedHdl;
-
-    DECL_LINK(spin_button_value_changed, weld::SpinButton&, void);
-    DECL_LINK(spin_button_output, sal_Int64, OUString);
-    DECL_LINK(spin_button_input, const OUString&, std::optional<int>);
-
-    void signal_value_changed() { m_aValueChangedHdl.Call(*this); }
-
-    sal_Int64 ConvertValue(sal_Int64 nValue, FieldUnit eInUnit, FieldUnit 
eOutUnit) const;
-    OUString format_number(sal_Int64 nValue) const;
-    void update_width_chars();
-
-public:
-    MetricSpinButton(std::unique_ptr<SpinButton> pSpinButton, FieldUnit 
eSrcUnit)
-        : m_eSrcUnit(eSrcUnit)
-        , m_xSpinButton(std::move(pSpinButton))
-    {
-        update_width_chars();
-        m_xSpinButton->set_value_formatter(LINK(this, MetricSpinButton, 
spin_button_output));
-        m_xSpinButton->set_text_parser(LINK(this, MetricSpinButton, 
spin_button_input));
-        m_xSpinButton->connect_value_changed(
-            LINK(this, MetricSpinButton, spin_button_value_changed));
-        m_xSpinButton->set_text(format_number(m_xSpinButton->get_value()));
-    }
-
-    static OUString MetricToString(FieldUnit rUnit);
-
-    FieldUnit get_unit() const { return m_eSrcUnit; }
-
-    void set_unit(FieldUnit eUnit);
-
-    sal_Int64 convert_value_to(sal_Int64 nValue, FieldUnit eValueUnit) const
-    {
-        return ConvertValue(nValue, m_eSrcUnit, eValueUnit);
-    }
-
-    sal_Int64 convert_value_from(sal_Int64 nValue, FieldUnit eValueUnit) const
-    {
-        return ConvertValue(nValue, eValueUnit, m_eSrcUnit);
-    }
-
-    void set_value(sal_Int64 nValue, FieldUnit eValueUnit)
-    {
-        m_xSpinButton->set_value(convert_value_from(nValue, eValueUnit));
-    }
-
-    sal_Int64 get_value(FieldUnit eDestUnit) const
-    {
-        return convert_value_to(m_xSpinButton->get_value(), eDestUnit);
-    }
-
-    // typically you only need to call this if set_text (e.g. with "") was
-    // previously called to display some arbitrary text instead of the
-    // formatted value and now you want to show it as formatted again
-    void reformat()
-    {
-        const OUString sText = format_number(m_xSpinButton->get_value());
-        m_xSpinButton->set_text(sText);
-    }
-
-    void set_range(sal_Int64 min, sal_Int64 max, FieldUnit eValueUnit)
-    {
-        min = convert_value_from(min, eValueUnit);
-        max = convert_value_from(max, eValueUnit);
-        m_xSpinButton->set_range(min, max);
-        update_width_chars();
-    }
-
-    void get_range(sal_Int64& min, sal_Int64& max, FieldUnit eDestUnit) const
-    {
-        m_xSpinButton->get_range(min, max);
-        min = convert_value_to(min, eDestUnit);
-        max = convert_value_to(max, eDestUnit);
-    }
-
-    void set_min(sal_Int64 min, FieldUnit eValueUnit)
-    {
-        sal_Int64 dummy, max;
-        get_range(dummy, max, eValueUnit);
-        set_range(min, max, eValueUnit);
-    }
-
-    void set_max(sal_Int64 max, FieldUnit eValueUnit)
-    {
-        sal_Int64 min, dummy;
-        get_range(min, dummy, eValueUnit);
-        set_range(min, max, eValueUnit);
-    }
-
-    sal_Int64 get_min(FieldUnit eValueUnit) const
-    {
-        sal_Int64 min, dummy;
-        get_range(min, dummy, eValueUnit);
-        return min;
-    }
-
-    sal_Int64 get_max(FieldUnit eValueUnit) const
-    {
-        sal_Int64 dummy, max;
-        get_range(dummy, max, eValueUnit);
-        return max;
-    }
-
-    void set_increments(sal_Int64 step, sal_Int64 page, FieldUnit eValueUnit)
-    {
-        step = convert_value_from(step, eValueUnit);
-        page = convert_value_from(page, eValueUnit);
-        m_xSpinButton->set_increments(step, page);
-    }
-
-    void get_increments(sal_Int64& step, sal_Int64& page, FieldUnit eDestUnit) 
const
-    {
-        m_xSpinButton->get_increments(step, page);
-        step = convert_value_to(step, eDestUnit);
-        page = convert_value_to(page, eDestUnit);
-    }
-
-    void connect_value_changed(const Link<MetricSpinButton&, void>& rLink)
-    {
-        m_aValueChangedHdl = rLink;
-    }
-
-    sal_Int64 normalize(sal_Int64 nValue) const { return 
m_xSpinButton->normalize(nValue); }
-    sal_Int64 denormalize(sal_Int64 nValue) const { return 
m_xSpinButton->denormalize(nValue); }
-    void set_sensitive(bool sensitive) { 
m_xSpinButton->set_sensitive(sensitive); }
-    bool get_sensitive() const { return m_xSpinButton->get_sensitive(); }
-    bool get_visible() const { return m_xSpinButton->get_visible(); }
-    void grab_focus() { m_xSpinButton->grab_focus(); }
-    bool has_focus() const { return m_xSpinButton->has_focus(); }
-    void show() { m_xSpinButton->show(); }
-    void set_visible(bool bShow) { m_xSpinButton->set_visible(bShow); }
-    void hide() { m_xSpinButton->hide(); }
-    void set_digits(unsigned int digits);
-    void set_accessible_name(const OUString& rName) { 
m_xSpinButton->set_accessible_name(rName); }
-    unsigned int get_digits() const { return m_xSpinButton->get_digits(); }
-    void save_value() { m_xSpinButton->save_value(); }
-    bool get_value_changed_from_saved() const
-    {
-        return m_xSpinButton->get_value_changed_from_saved();
-    }
-    void set_text(const OUString& rText) { m_xSpinButton->set_text(rText); }
-    OUString get_text() const { return m_xSpinButton->get_text(); }
-    void set_size_request(int nWidth, int nHeight)
-    {
-        m_xSpinButton->set_size_request(nWidth, nHeight);
-    }
-    Size get_size_request() const { return m_xSpinButton->get_size_request(); }
-    Size get_preferred_size() const { return 
m_xSpinButton->get_preferred_size(); }
-    void connect_focus_in(const Link<Widget&, void>& rLink)
-    {
-        m_xSpinButton->connect_focus_in(rLink);
-    }
-    void connect_focus_out(const Link<Widget&, void>& rLink)
-    {
-        m_xSpinButton->connect_focus_out(rLink);
-    }
-    OUString get_buildable_name() const { return 
m_xSpinButton->get_buildable_name(); }
-    void set_help_id(const OUString& rName) { 
m_xSpinButton->set_help_id(rName); }
-    void set_position(int nCursorPos) { 
m_xSpinButton->set_position(nCursorPos); }
-    // set the width of the underlying widget in characters, this setting is
-    // invalidated when changing the units, range or digits, so to have effect
-    // must come after changing those values
-    void set_width_chars(int nChars) { m_xSpinButton->set_width_chars(nChars); 
}
-    int get_width_chars() const { return m_xSpinButton->get_width_chars(); }
-    weld::SpinButton& get_widget() { return *m_xSpinButton; }
-};
-
 enum class LabelType
 {
     Normal,
diff --git a/sc/source/ui/inc/mtrindlg.hxx b/sc/source/ui/inc/mtrindlg.hxx
index 516a918b5e10..733965efe397 100644
--- a/sc/source/ui/inc/mtrindlg.hxx
+++ b/sc/source/ui/inc/mtrindlg.hxx
@@ -19,6 +19,7 @@
 
 #pragma once
 
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 
 class ScMetricInputDlg : public weld::GenericDialogController
diff --git a/sc/source/ui/inc/tptable.hxx b/sc/source/ui/inc/tptable.hxx
index 9e98c050a20e..0052398045b4 100644
--- a/sc/source/ui/inc/tptable.hxx
+++ b/sc/source/ui/inc/tptable.hxx
@@ -20,6 +20,7 @@
 #pragma once
 
 #include <sfx2/tabdlg.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class ScTablePage : public SfxTabPage
 {
diff --git a/sc/source/ui/inc/tpview.hxx b/sc/source/ui/inc/tpview.hxx
index 3ed12e498982..6fbf3c773b8a 100644
--- a/sc/source/ui/inc/tpview.hxx
+++ b/sc/source/ui/inc/tpview.hxx
@@ -21,6 +21,7 @@
 
 #include <sfx2/tabdlg.hxx>
 #include <svx/colorbox.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class ScViewOptions;
 
diff --git a/sc/source/ui/sidebar/AlignmentPropertyPanel.hxx 
b/sc/source/ui/sidebar/AlignmentPropertyPanel.hxx
index 7de9cc633049..5eedf7657b06 100644
--- a/sc/source/ui/sidebar/AlignmentPropertyPanel.hxx
+++ b/sc/source/ui/sidebar/AlignmentPropertyPanel.hxx
@@ -23,6 +23,7 @@
 #include <sfx2/weldutils.hxx>
 #include <sfx2/sidebar/PanelLayout.hxx>
 #include <vcl/EnumContext.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 namespace sc::sidebar {
 
diff --git a/sd/source/ui/inc/BulletAndPositionDlg.hxx 
b/sd/source/ui/inc/BulletAndPositionDlg.hxx
index d39f554afa1a..e2cc8c2c97c5 100644
--- a/sd/source/ui/inc/BulletAndPositionDlg.hxx
+++ b/sd/source/ui/inc/BulletAndPositionDlg.hxx
@@ -24,6 +24,7 @@
 
 #include <editeng/numdef.hxx>
 #include <editeng/svxenum.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/TreeView.hxx>
 #include <vcl/weld/weld.hxx>
 #include "View.hxx"
diff --git a/sd/source/ui/inc/CustomAnimationPane.hxx 
b/sd/source/ui/inc/CustomAnimationPane.hxx
index 7d833fa66f31..f2c34d506b04 100644
--- a/sd/source/ui/inc/CustomAnimationPane.hxx
+++ b/sd/source/ui/inc/CustomAnimationPane.hxx
@@ -22,6 +22,7 @@
 #include <sfx2/sidebar/ILayoutableWindow.hxx>
 #include <sfx2/sidebar/PanelLayout.hxx>
 #include <vcl/idle.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include "CustomAnimationList.hxx"
 #include <misc/scopelock.hxx>
 
diff --git a/sd/source/ui/inc/SlideTransitionPane.hxx 
b/sd/source/ui/inc/SlideTransitionPane.hxx
index 0fcb29cc7920..26ca96b0e48a 100644
--- a/sd/source/ui/inc/SlideTransitionPane.hxx
+++ b/sd/source/ui/inc/SlideTransitionPane.hxx
@@ -24,6 +24,7 @@
 #include <sfx2/sidebar/ILayoutableWindow.hxx>
 #include <sfx2/sidebar/PanelLayout.hxx>
 #include <vcl/weld/IconView.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 
 #include <vector>
diff --git a/sd/source/ui/inc/copydlg.hxx b/sd/source/ui/inc/copydlg.hxx
index 9bd8a5a4c111..79ed5af43e44 100644
--- a/sd/source/ui/inc/copydlg.hxx
+++ b/sd/source/ui/inc/copydlg.hxx
@@ -21,6 +21,7 @@
 
 #include <sfx2/basedlgs.hxx>
 #include <tools/fract.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class ColorListBox;
 
diff --git a/sd/source/ui/inc/dlgsnap.hxx b/sd/source/ui/inc/dlgsnap.hxx
index 4999f5f8d12c..7085b72ccae1 100644
--- a/sd/source/ui/inc/dlgsnap.hxx
+++ b/sd/source/ui/inc/dlgsnap.hxx
@@ -20,6 +20,7 @@
 #pragma once
 
 #include <tools/fract.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 
 /************************************************************************/
diff --git a/sd/source/ui/inc/tpoption.hxx b/sd/source/ui/inc/tpoption.hxx
index e1065eb28b1b..48b62a0ff113 100644
--- a/sd/source/ui/inc/tpoption.hxx
+++ b/sd/source/ui/inc/tpoption.hxx
@@ -21,6 +21,7 @@
 
 #include <sfx2/tabdlg.hxx>
 #include <svx/optgrid.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 /**
  * Option-Tab-Page: Snap
diff --git a/sd/source/ui/inc/vectdlg.hxx b/sd/source/ui/inc/vectdlg.hxx
index 627a407c0fe7..bfc687394d66 100644
--- a/sd/source/ui/inc/vectdlg.hxx
+++ b/sd/source/ui/inc/vectdlg.hxx
@@ -19,6 +19,7 @@
 
 #pragma once
 
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 #include <svx/graphctl.hxx>
 
diff --git a/sd/source/ui/sidebar/SlideBackground.cxx 
b/sd/source/ui/sidebar/SlideBackground.cxx
index af856ce005ec..37de19ba1638 100644
--- a/sd/source/ui/sidebar/SlideBackground.cxx
+++ b/sd/source/ui/sidebar/SlideBackground.cxx
@@ -59,6 +59,7 @@
 #include <utility>
 #include <vcl/EnumContext.hxx>
 #include <vcl/svapp.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 #include <editeng/sizeitem.hxx>
 #include <comphelper/lok.hxx>
diff --git a/starmath/inc/dialog.hxx b/starmath/inc/dialog.hxx
index c4570bffa143..60640956c124 100644
--- a/starmath/inc/dialog.hxx
+++ b/starmath/inc/dialog.hxx
@@ -22,6 +22,7 @@
 #include <sfx2/tabdlg.hxx>
 #include <vcl/outdev.hxx>
 #include <vcl/weld/EntryTreeView.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/customweld.hxx>
 #include "symbol.hxx"
 
diff --git a/svtools/source/control/ctrlbox.cxx 
b/svtools/source/control/ctrlbox.cxx
index bc5dad9c78e6..1123fc96e079 100644
--- a/svtools/source/control/ctrlbox.cxx
+++ b/svtools/source/control/ctrlbox.cxx
@@ -32,6 +32,7 @@
 #include <vcl/settings.hxx>
 #include <vcl/image.hxx>
 #include <vcl/virdev.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <vcl/weld/weldutils.hxx>
 #include <rtl/math.hxx>
diff --git a/svtools/source/misc/unitconv.cxx b/svtools/source/misc/unitconv.cxx
index c7bbc561ce7e..3c80e5508618 100644
--- a/svtools/source/misc/unitconv.cxx
+++ b/svtools/source/misc/unitconv.cxx
@@ -22,6 +22,7 @@
 #include <tools/debug.hxx>
 #include <tools/UnitConversion.hxx>
 #include <vcl/outdev.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 
 void SetFieldUnit(weld::MetricSpinButton& rField, FieldUnit eUnit, bool bAll)
diff --git a/svx/inc/extrusiondepthdialog.hxx b/svx/inc/extrusiondepthdialog.hxx
index 6e5b21add3b9..faaba48c8e32 100644
--- a/svx/inc/extrusiondepthdialog.hxx
+++ b/svx/inc/extrusiondepthdialog.hxx
@@ -20,6 +20,7 @@
 #ifndef INCLUDED_SVX_INC_EXTRUSIONDEPTHDIALOG_HXX
 #define INCLUDED_SVX_INC_EXTRUSIONDEPTHDIALOG_HXX
 
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 
 namespace svx
diff --git a/svx/source/dialog/contimp.hxx b/svx/source/dialog/contimp.hxx
index 268e64695249..ab2e920f1d47 100644
--- a/svx/source/dialog/contimp.hxx
+++ b/svx/source/dialog/contimp.hxx
@@ -21,6 +21,7 @@
 #include <sfx2/ctrlitem.hxx>
 #include "contwnd.hxx"
 #include <vcl/idle.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class SvxSuperContourDlg;
 
diff --git a/svx/source/dialog/optgrid.cxx b/svx/source/dialog/optgrid.cxx
index 4bb23f2752ff..997fb7c421a5 100644
--- a/svx/source/dialog/optgrid.cxx
+++ b/svx/source/dialog/optgrid.cxx
@@ -28,6 +28,7 @@
 #include <officecfg/Office/Draw.hxx>
 #include <sfx2/viewfrm.hxx>
 #include <vcl/commandinfoprovider.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <rtl/ustrbuf.hxx>
 
 #include <svx/svxids.hrc>
diff --git a/svx/source/dialog/spacinglistbox.cxx 
b/svx/source/dialog/spacinglistbox.cxx
index 90cc689ccc6f..6b0310887b7a 100644
--- a/svx/source/dialog/spacinglistbox.cxx
+++ b/svx/source/dialog/spacinglistbox.cxx
@@ -22,6 +22,7 @@
 #include <unotools/localedatawrapper.hxx>
 #include <vcl/settings.hxx>
 #include <vcl/svapp.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <spacing.hrc>
 
 namespace SpacingListBox
diff --git a/svx/source/sidebar/effect/EffectPropertyPanel.hxx 
b/svx/source/sidebar/effect/EffectPropertyPanel.hxx
index 7edc219a47bd..7cb5422cef49 100644
--- a/svx/source/sidebar/effect/EffectPropertyPanel.hxx
+++ b/svx/source/sidebar/effect/EffectPropertyPanel.hxx
@@ -11,6 +11,7 @@
 
 #include <sfx2/sidebar/ControllerItem.hxx>
 #include <sfx2/sidebar/PanelLayout.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class ColorListBox;
 
diff --git a/svx/source/sidebar/effect/TextEffectPropertyPanel.hxx 
b/svx/source/sidebar/effect/TextEffectPropertyPanel.hxx
index 5966d407b055..bfb6f85a0a2f 100644
--- a/svx/source/sidebar/effect/TextEffectPropertyPanel.hxx
+++ b/svx/source/sidebar/effect/TextEffectPropertyPanel.hxx
@@ -11,6 +11,7 @@
 
 #include <sfx2/sidebar/ControllerItem.hxx>
 #include <sfx2/sidebar/PanelLayout.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class ColorListBox;
 
diff --git a/svx/source/sidebar/graphic/GraphicPropertyPanel.hxx 
b/svx/source/sidebar/graphic/GraphicPropertyPanel.hxx
index 4f4c1adf68b2..8a645d0dc416 100644
--- a/svx/source/sidebar/graphic/GraphicPropertyPanel.hxx
+++ b/svx/source/sidebar/graphic/GraphicPropertyPanel.hxx
@@ -21,6 +21,7 @@
 
 #include <sfx2/sidebar/ControllerItem.hxx>
 #include <sfx2/sidebar/PanelLayout.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 
 namespace svx::sidebar {
diff --git a/svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx 
b/svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx
index e49556f16c59..f8ff548dc421 100644
--- a/svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx
+++ b/svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx
@@ -19,6 +19,7 @@
 #pragma once
 
 #include <svtools/toolbarmenu.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class SvxLineSpacingItem;
 
diff --git a/svx/source/sidebar/paragraph/ParaPropertyPanel.hxx 
b/svx/source/sidebar/paragraph/ParaPropertyPanel.hxx
index aa43825c3f22..49928429b3f0 100644
--- a/svx/source/sidebar/paragraph/ParaPropertyPanel.hxx
+++ b/svx/source/sidebar/paragraph/ParaPropertyPanel.hxx
@@ -30,6 +30,7 @@
 #include <svl/poolitem.hxx>
 #include <tools/fldunit.hxx>
 #include <vcl/EnumContext.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class ToolbarUnoDispatcher;
 
diff --git a/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx 
b/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx
index a5485272adbe..42841c6a27ab 100644
--- a/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx
+++ b/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx
@@ -22,6 +22,7 @@
 #include <vcl/EnumContext.hxx>
 #include <vcl/InterimItemWindow.hxx>
 #include <svx/relfld.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 namespace svx
 {
diff --git a/svx/source/sidebar/possize/PosSizePropertyPanel.hxx 
b/svx/source/sidebar/possize/PosSizePropertyPanel.hxx
index 103a331a2379..de66876dc55d 100644
--- a/svx/source/sidebar/possize/PosSizePropertyPanel.hxx
+++ b/svx/source/sidebar/possize/PosSizePropertyPanel.hxx
@@ -29,6 +29,7 @@
 #include <com/sun/star/ui/XSidebar.hpp>
 #include <basegfx/range/b2drange.hxx>
 #include <vcl/EnumContext.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <vcl/weld/weld.hxx>
 #include <svx/dlgutil.hxx>
diff --git a/svx/source/sidebar/shadow/ShadowPropertyPanel.hxx 
b/svx/source/sidebar/shadow/ShadowPropertyPanel.hxx
index a68405eb0c1b..6a0883c2a182 100644
--- a/svx/source/sidebar/shadow/ShadowPropertyPanel.hxx
+++ b/svx/source/sidebar/shadow/ShadowPropertyPanel.hxx
@@ -11,6 +11,7 @@
 
 #include <sfx2/sidebar/ControllerItem.hxx>
 #include <sfx2/sidebar/PanelLayout.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class ColorListBox;
 
diff --git a/svx/source/sidebar/text/TextCharacterSpacingControl.hxx 
b/svx/source/sidebar/text/TextCharacterSpacingControl.hxx
index dc7312f0ea58..4f866aacb000 100644
--- a/svx/source/sidebar/text/TextCharacterSpacingControl.hxx
+++ b/svx/source/sidebar/text/TextCharacterSpacingControl.hxx
@@ -20,6 +20,7 @@
 #define INCLUDED_SVX_SOURCE_SIDEBAR_TEXT_TEXTCHARACTERSPACINGCONTROL_HXX
 
 #include <svtools/toolbarmenu.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 namespace svx {
 #define SPACING_NOCUSTOM                0
diff --git a/svx/source/sidebar/textcolumns/TextColumnsPropertyPanel.hxx 
b/svx/source/sidebar/textcolumns/TextColumnsPropertyPanel.hxx
index 17ae0b55c45e..d93db7b13ca9 100644
--- a/svx/source/sidebar/textcolumns/TextColumnsPropertyPanel.hxx
+++ b/svx/source/sidebar/textcolumns/TextColumnsPropertyPanel.hxx
@@ -11,6 +11,7 @@
 
 #include <sfx2/sidebar/ControllerItem.hxx>
 #include <sfx2/sidebar/PanelLayout.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 namespace svx::sidebar
 {
diff --git a/svx/source/tbxctrls/grafctrl.cxx b/svx/source/tbxctrls/grafctrl.cxx
index 2e866cbc59a9..e3b0b750564d 100644
--- a/svx/source/tbxctrls/grafctrl.cxx
+++ b/svx/source/tbxctrls/grafctrl.cxx
@@ -22,6 +22,7 @@
 #include <comphelper/propertyvalue.hxx>
 #include <o3tl/string_view.hxx>
 #include <vcl/toolbox.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <svl/intitem.hxx>
 #include <svl/itempool.hxx>
 #include <svl/eitem.hxx>
diff --git a/svx/source/tbxctrls/linemetricbox.hxx 
b/svx/source/tbxctrls/linemetricbox.hxx
index 79be63904a13..653883f4aaf0 100644
--- a/svx/source/tbxctrls/linemetricbox.hxx
+++ b/svx/source/tbxctrls/linemetricbox.hxx
@@ -19,6 +19,7 @@
 #pragma once
 
 #include <vcl/InterimItemWindow.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <com/sun/star/frame/XFrame.hpp>
 
 class XLineWidthItem;
diff --git a/sw/inc/colwd.hxx b/sw/inc/colwd.hxx
index 42992a14e8fa..2efafaf84964 100644
--- a/sw/inc/colwd.hxx
+++ b/sw/inc/colwd.hxx
@@ -18,6 +18,7 @@
  */
 #pragma once
 
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 #include <memory>
 
diff --git a/sw/source/ui/dbui/mmlayoutpage.hxx 
b/sw/source/ui/dbui/mmlayoutpage.hxx
index f891b287485d..2a047c2eea07 100644
--- a/sw/source/ui/dbui/mmlayoutpage.hxx
+++ b/sw/source/ui/dbui/mmlayoutpage.hxx
@@ -20,6 +20,7 @@
 #define INCLUDED_SW_SOURCE_UI_DBUI_MMLAYOUTPAGE_HXX
 
 #include <vcl/wizardmachine.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <mailmergehelper.hxx>
 #include <com/sun/star/uno/Reference.h>
 
diff --git a/sw/source/ui/envelp/envprt.hxx b/sw/source/ui/envelp/envprt.hxx
index 0321f7308664..b6530b0d1f06 100644
--- a/sw/source/ui/envelp/envprt.hxx
+++ b/sw/source/ui/envelp/envprt.hxx
@@ -21,6 +21,7 @@
 
 #include <sfx2/tabdlg.hxx>
 #include <vcl/print.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 
 #include <envimg.hxx>
diff --git a/sw/source/ui/envelp/labfmt.hxx b/sw/source/ui/envelp/labfmt.hxx
index 871f8fbbff3b..670ba94b4a1d 100644
--- a/sw/source/ui/envelp/labfmt.hxx
+++ b/sw/source/ui/envelp/labfmt.hxx
@@ -23,6 +23,7 @@
 
 #include <sfx2/tabdlg.hxx>
 #include <vcl/idle.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <vcl/weld/weld.hxx>
 
diff --git a/sw/source/ui/inc/regionsw.hxx b/sw/source/ui/inc/regionsw.hxx
index e21834fc7759..aacf7aab9098 100644
--- a/sw/source/ui/inc/regionsw.hxx
+++ b/sw/source/ui/inc/regionsw.hxx
@@ -28,6 +28,7 @@
 #include <numberingtypelistbox.hxx>
 #include <svx/paraprev.hxx>
 #include <vcl/weld/EntryTreeView.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/TreeView.hxx>
 
 #include <memory>
diff --git a/sw/source/uibase/inc/column.hxx b/sw/source/uibase/inc/column.hxx
index 6eabca9db70c..9a2f5158caf9 100644
--- a/sw/source/uibase/inc/column.hxx
+++ b/sw/source/uibase/inc/column.hxx
@@ -24,6 +24,7 @@
 #include <sfx2/tabdlg.hxx>
 #include <svx/colorbox.hxx>
 #include <svx/frmdirlbox.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <map>
 #include "colex.hxx"
 #include "prcntfld.hxx"
diff --git a/sw/source/uibase/inc/drpcps.hxx b/sw/source/uibase/inc/drpcps.hxx
index 3a44fea10b30..f913dca62d4f 100644
--- a/sw/source/uibase/inc/drpcps.hxx
+++ b/sw/source/uibase/inc/drpcps.hxx
@@ -24,6 +24,7 @@
 #include <sfx2/basedlgs.hxx>
 #include <sfx2/tabdlg.hxx>
 #include <vcl/print.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/customweld.hxx>
 
 /// Dedicated drop caps dialog, opened by the .uno:FormatDropcap UNO command, 
which is not in the
diff --git a/sw/source/uibase/inc/envlop.hxx b/sw/source/uibase/inc/envlop.hxx
index d1f3b1310c33..46e6467b8aa4 100644
--- a/sw/source/uibase/inc/envlop.hxx
+++ b/sw/source/uibase/inc/envlop.hxx
@@ -20,6 +20,7 @@
 #define INCLUDED_SW_SOURCE_UIBASE_INC_ENVLOP_HXX
 
 #include <sfx2/tabdlg.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <vcl/weld/weld.hxx>
 #include "envimg.hxx"
diff --git a/sw/source/uibase/inc/frmpage.hxx b/sw/source/uibase/inc/frmpage.hxx
index da0e4c215f03..eca60df1a271 100644
--- a/sw/source/uibase/inc/frmpage.hxx
+++ b/sw/source/uibase/inc/frmpage.hxx
@@ -25,6 +25,7 @@
 #include <svx/dlgutil.hxx>
 #include <svx/frmdirlbox.hxx>
 #include <svx/swframeexample.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <swtypes.hxx>
 #include "bmpwin.hxx"
 #include "prcntfld.hxx"
diff --git a/sw/source/uibase/inc/labimp.hxx b/sw/source/uibase/inc/labimp.hxx
index f39ac53cf9de..fef5f4d8907d 100644
--- a/sw/source/uibase/inc/labimp.hxx
+++ b/sw/source/uibase/inc/labimp.hxx
@@ -19,6 +19,7 @@
 #ifndef INCLUDED_SW_SOURCE_UIBASE_INC_LABIMP_HXX
 #define INCLUDED_SW_SOURCE_UIBASE_INC_LABIMP_HXX
 
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 
 inline int getfldval(const weld::MetricSpinButton& rField)
diff --git a/sw/source/uibase/inc/linenum.hxx b/sw/source/uibase/inc/linenum.hxx
index eaed16129626..48e516bcbf2c 100644
--- a/sw/source/uibase/inc/linenum.hxx
+++ b/sw/source/uibase/inc/linenum.hxx
@@ -20,6 +20,7 @@
 #define INCLUDED_SW_SOURCE_UIBASE_INC_LINENUM_HXX
 
 #include <sfx2/basedlgs.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include "numberingtypelistbox.hxx"
 
 class SwView;
diff --git a/sw/source/uibase/inc/num.hxx b/sw/source/uibase/inc/num.hxx
index 86fb9775a3e2..817f4d431e9c 100644
--- a/sw/source/uibase/inc/num.hxx
+++ b/sw/source/uibase/inc/num.hxx
@@ -20,6 +20,7 @@
 #define INCLUDED_SW_SOURCE_UIBASE_INC_NUM_HXX
 
 #include <sfx2/tabdlg.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/TreeView.hxx>
 #include "numprevw.hxx"
 #include <numrule.hxx>
diff --git a/sw/source/uibase/inc/optload.hxx b/sw/source/uibase/inc/optload.hxx
index b8966e01af9d..30c3fd6ae942 100644
--- a/sw/source/uibase/inc/optload.hxx
+++ b/sw/source/uibase/inc/optload.hxx
@@ -25,6 +25,7 @@
 
 #include <utility>
 #include <vcl/textfilter.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/TreeView.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <vcl/weld/weld.hxx>
diff --git a/sw/source/uibase/inc/optpage.hxx b/sw/source/uibase/inc/optpage.hxx
index d6743aa7e7e8..7747ec808516 100644
--- a/sw/source/uibase/inc/optpage.hxx
+++ b/sw/source/uibase/inc/optpage.hxx
@@ -21,6 +21,7 @@
 
 #include <sfx2/tabdlg.hxx>
 
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 #include <svtools/ctrlbox.hxx>
 #include <svx/colorbox.hxx>
diff --git a/sw/source/uibase/inc/pgfnote.hxx b/sw/source/uibase/inc/pgfnote.hxx
index 77b367230c67..adacd7f5a3cd 100644
--- a/sw/source/uibase/inc/pgfnote.hxx
+++ b/sw/source/uibase/inc/pgfnote.hxx
@@ -22,6 +22,7 @@
 
 #include <svtools/ctrlbox.hxx>
 #include <svx/colorbox.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 // footnote settings TabPage
 class SwFootNotePage final : public SfxTabPage
diff --git a/sw/source/uibase/inc/pggrid.hxx b/sw/source/uibase/inc/pggrid.hxx
index d3198fe4e9b6..989864a73c7d 100644
--- a/sw/source/uibase/inc/pggrid.hxx
+++ b/sw/source/uibase/inc/pggrid.hxx
@@ -20,6 +20,7 @@
 
 #include <sfx2/tabdlg.hxx>
 #include "colex.hxx"
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <vcl/weld/weld.hxx>
 #include <svx/colorbox.hxx>
diff --git a/sw/source/uibase/inc/prcntfld.hxx 
b/sw/source/uibase/inc/prcntfld.hxx
index 77ed9e8dd696..cd13bbb17c40 100644
--- a/sw/source/uibase/inc/prcntfld.hxx
+++ b/sw/source/uibase/inc/prcntfld.hxx
@@ -19,6 +19,7 @@
 #pragma once
 
 #include <svtools/unitconv.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 #include <swdllapi.h>
 
diff --git a/sw/source/uibase/inc/rowht.hxx b/sw/source/uibase/inc/rowht.hxx
index 9c76191dc99b..81c82dd6e26c 100644
--- a/sw/source/uibase/inc/rowht.hxx
+++ b/sw/source/uibase/inc/rowht.hxx
@@ -18,6 +18,7 @@
  */
 #pragma once
 
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 
 class SwWrtShell;
diff --git a/sw/source/uibase/inc/swuicnttab.hxx 
b/sw/source/uibase/inc/swuicnttab.hxx
index 47396b6926dd..cc05f12bdc98 100644
--- a/sw/source/uibase/inc/swuicnttab.hxx
+++ b/sw/source/uibase/inc/swuicnttab.hxx
@@ -22,6 +22,7 @@
 #include <sfx2/tabdlg.hxx>
 #include <svx/langbox.hxx>
 #include <vcl/idle.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/TreeView.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <vcl/weld/weld.hxx>
diff --git a/sw/source/uibase/inc/watermarkdialog.hxx 
b/sw/source/uibase/inc/watermarkdialog.hxx
index 8e42656cfeee..f25fd94278cf 100644
--- a/sw/source/uibase/inc/watermarkdialog.hxx
+++ b/sw/source/uibase/inc/watermarkdialog.hxx
@@ -10,6 +10,7 @@
 #define INCLUDED_SW_SOURCE_UIBASE_INC_WATERMARKDIALOG_HXX
 
 #include <sfx2/bindings.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/weld.hxx>
 #include <svx/colorbox.hxx>
 #include <sfx2/basedlgs.hxx>
diff --git a/sw/source/uibase/inc/wrap.hxx b/sw/source/uibase/inc/wrap.hxx
index f3c1e32a1580..70aeea6b56be 100644
--- a/sw/source/uibase/inc/wrap.hxx
+++ b/sw/source/uibase/inc/wrap.hxx
@@ -22,6 +22,7 @@
 #include <sfx2/tabdlg.hxx>
 #include <sfx2/basedlgs.hxx>
 #include <svx/swframetypes.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class SwWrtShell;
 
diff --git a/sw/source/uibase/sidebar/PageFormatPanel.hxx 
b/sw/source/uibase/sidebar/PageFormatPanel.hxx
index a1eb2f109bca..27a119b69ead 100644
--- a/sw/source/uibase/sidebar/PageFormatPanel.hxx
+++ b/sw/source/uibase/sidebar/PageFormatPanel.hxx
@@ -28,6 +28,7 @@
 #include <tools/fldunit.hxx>
 #include <svl/poolitem.hxx>
 #include <svx/relfld.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 #include <memory>
 
diff --git a/sw/source/uibase/sidebar/PageMarginControl.hxx 
b/sw/source/uibase/sidebar/PageMarginControl.hxx
index 6cfb7b05bf7c..0ff3af4cbd91 100644
--- a/sw/source/uibase/sidebar/PageMarginControl.hxx
+++ b/sw/source/uibase/sidebar/PageMarginControl.hxx
@@ -23,6 +23,7 @@
 
 #include <o3tl/unit_conversion.hxx>
 #include <svtools/toolbarmenu.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 #define SWPAGE_NARROW_VALUE    720
 #define SWPAGE_NORMAL_VALUE    1136
diff --git a/sw/source/uibase/sidebar/PageSizeControl.hxx 
b/sw/source/uibase/sidebar/PageSizeControl.hxx
index b0e2189ea22c..8baf06ae0e48 100644
--- a/sw/source/uibase/sidebar/PageSizeControl.hxx
+++ b/sw/source/uibase/sidebar/PageSizeControl.hxx
@@ -22,6 +22,7 @@
 
 #include <svtools/toolbarmenu.hxx>
 #include <svtools/valueset.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/TreeView.hxx>
 
 #include <vector>
diff --git a/sw/source/uibase/sidebar/TableEditPanel.hxx 
b/sw/source/uibase/sidebar/TableEditPanel.hxx
index 8aee8b4cea6d..3c88a350bab1 100644
--- a/sw/source/uibase/sidebar/TableEditPanel.hxx
+++ b/sw/source/uibase/sidebar/TableEditPanel.hxx
@@ -15,6 +15,7 @@
 #include <sfx2/sidebar/ControllerItem.hxx>
 #include <sfx2/weldutils.hxx>
 #include <svx/relfld.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 namespace sw::sidebar
 {
diff --git a/sw/source/uibase/table/tablepg.hxx 
b/sw/source/uibase/table/tablepg.hxx
index 227f3942b2fe..03a977694e05 100644
--- a/sw/source/uibase/table/tablepg.hxx
+++ b/sw/source/uibase/table/tablepg.hxx
@@ -22,6 +22,7 @@
 #include <prcntfld.hxx>
 #include <swtypes.hxx>
 #include <svx/frmdirlbox.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 
 class SwWrtShell;
 class SwTableRep;
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index a8365d08dad9..b9773a1ccb9b 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -585,6 +585,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/source/weld/EntryTreeView \
     vcl/source/weld/IconView \
     vcl/source/weld/ItemView \
+    vcl/source/weld/MetricSpinButton \
     vcl/source/weld/weldutils \
     vcl/backendtest/outputdevice/bitmap \
     vcl/backendtest/outputdevice/clip \
diff --git a/vcl/inc/colorpicker.hxx b/vcl/inc/colorpicker.hxx
index a8a0bc7d4ace..d0c579774f07 100644
--- a/vcl/inc/colorpicker.hxx
+++ b/vcl/inc/colorpicker.hxx
@@ -22,6 +22,7 @@
 #include <vcl/ColorDialog.hxx>
 #include <vcl/hexcolorcontrol.hxx>
 #include <vcl/virdev.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <vcl/weld/weld.hxx>
 #include <o3tl/typed_flags_set.hxx>
diff --git a/vcl/inc/printdlg.hxx b/vcl/inc/printdlg.hxx
index e7ddae417b9a..6e81b372fa00 100644
--- a/vcl/inc/printdlg.hxx
+++ b/vcl/inc/printdlg.hxx
@@ -23,6 +23,7 @@
 #include <vcl/gdimtf.hxx>
 #include <vcl/idle.hxx>
 #include <vcl/print.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/customweld.hxx>
 #include <vcl/weld/weld.hxx>
 #include <map>
diff --git a/vcl/inc/qt5/QtInstanceBuilder.hxx 
b/vcl/inc/qt5/QtInstanceBuilder.hxx
index 5c8c933de107..dce62ebdb414 100644
--- a/vcl/inc/qt5/QtInstanceBuilder.hxx
+++ b/vcl/inc/qt5/QtInstanceBuilder.hxx
@@ -17,6 +17,7 @@
 
 #include <rtl/ustring.hxx>
 #include <vcl/weld/EntryTreeView.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/TreeView.hxx>
 #include <vcl/weld/weld.hxx>
 
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index d2c9a283bcdd..814158c5c8dd 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -10,6 +10,7 @@
 
 #include <vcl/builder.hxx>
 #include <vcl/weld/EntryTreeView.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <vcl/weld/TreeView.hxx>
 #include <vcl/weld/weld.hxx>
 #include <vcl/svapp.hxx>
diff --git a/vcl/source/weld/MetricSpinButton.cxx 
b/vcl/source/weld/MetricSpinButton.cxx
new file mode 100644
index 000000000000..b51ea8ebe3f7
--- /dev/null
+++ b/vcl/source/weld/MetricSpinButton.cxx
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <svdata.hxx>
+
+#include <i18nutil/unicode.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <vcl/fieldvalues.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
+
+namespace weld
+{
+OUString MetricSpinButton::MetricToString(FieldUnit rUnit)
+{
+    const FieldUnitStringList& rList = ImplGetFieldUnits();
+    // return unit's default string (ie, the first one )
+    auto it = std::find_if(
+        rList.begin(), rList.end(),
+        [&rUnit](const std::pair<OUString, FieldUnit>& rItem) { return 
rItem.second == rUnit; });
+    if (it != rList.end())
+        return it->first;
+
+    return OUString();
+}
+
+IMPL_LINK_NOARG(MetricSpinButton, spin_button_value_changed, SpinButton&, void)
+{
+    signal_value_changed();
+}
+
+IMPL_LINK(MetricSpinButton, spin_button_output, sal_Int64, nValue, OUString)
+{
+    return format_number(nValue);
+}
+
+void MetricSpinButton::update_width_chars()
+{
+    sal_Int64 min, max;
+    m_xSpinButton->get_range(min, max);
+    auto width = 
std::max(m_xSpinButton->get_pixel_size(format_number(min)).Width(),
+                          
m_xSpinButton->get_pixel_size(format_number(max)).Width());
+    int chars = ceil(width / m_xSpinButton->get_approximate_digit_width());
+    m_xSpinButton->set_width_chars(chars);
+}
+
+OUString MetricSpinButton::format_number(sal_Int64 nValue) const
+{
+    OUString aStr;
+
+    const LocaleDataWrapper& rLocaleData = 
Application::GetSettings().GetLocaleDataWrapper();
+
+    unsigned int nDecimalDigits = m_xSpinButton->get_digits();
+    //pawn percent off to icu to decide whether percent is separated from its 
number for this locale
+    if (m_eSrcUnit == FieldUnit::PERCENT)
+    {
+        double fValue = nValue;
+        fValue /= SpinButton::Power10(nDecimalDigits);
+        aStr = unicode::formatPercent(fValue, rLocaleData.getLanguageTag());
+    }
+    else
+    {
+        aStr = rLocaleData.getNum(nValue, nDecimalDigits, true, true);
+        OUString aSuffix = MetricToString(m_eSrcUnit);
+        if (m_eSrcUnit != FieldUnit::NONE && m_eSrcUnit != FieldUnit::DEGREE
+            && m_eSrcUnit != FieldUnit::INCH && m_eSrcUnit != FieldUnit::FOOT)
+            aStr += " ";
+        if (m_eSrcUnit == FieldUnit::INCH)
+        {
+            OUString sDoublePrime = u"\u2033"_ustr;
+            if (aSuffix != "\"" && aSuffix != sDoublePrime)
+                aStr += " ";
+            else
+                aSuffix = sDoublePrime;
+        }
+        else if (m_eSrcUnit == FieldUnit::FOOT)
+        {
+            OUString sPrime = u"\u2032"_ustr;
+            if (aSuffix != "'" && aSuffix != sPrime)
+                aStr += " ";
+            else
+                aSuffix = sPrime;
+        }
+
+        assert(m_eSrcUnit != FieldUnit::PERCENT);
+        aStr += aSuffix;
+    }
+
+    return aStr;
+}
+
+void MetricSpinButton::set_digits(unsigned int digits)
+{
+    sal_Int64 step, page;
+    get_increments(step, page, m_eSrcUnit);
+    sal_Int64 value = get_value(m_eSrcUnit);
+    m_xSpinButton->set_digits(digits);
+    set_increments(step, page, m_eSrcUnit);
+    set_value(value, m_eSrcUnit);
+    update_width_chars();
+}
+
+void MetricSpinButton::set_unit(FieldUnit eUnit)
+{
+    if (eUnit != m_eSrcUnit)
+    {
+        sal_Int64 step, page;
+        get_increments(step, page, m_eSrcUnit);
+        sal_Int64 value = get_value(m_eSrcUnit);
+        m_eSrcUnit = eUnit;
+        set_increments(step, page, m_eSrcUnit);
+        set_value(value, m_eSrcUnit);
+        const OUString sText = format_number(m_xSpinButton->get_value());
+        m_xSpinButton->set_text(sText);
+        update_width_chars();
+    }
+}
+
+sal_Int64 MetricSpinButton::ConvertValue(sal_Int64 nValue, FieldUnit eInUnit,
+                                         FieldUnit eOutUnit) const
+{
+    return vcl::ConvertValue(nValue, 0, m_xSpinButton->get_digits(), eInUnit, 
eOutUnit);
+}
+
+IMPL_LINK(MetricSpinButton, spin_button_input, const OUString&, rText, 
std::optional<int>)
+{
+    const LocaleDataWrapper& rLocaleData = 
Application::GetSettings().GetLocaleDataWrapper();
+    double fResult(0.0);
+    bool bRet
+        = vcl::TextToValue(rText, fResult, 0, m_xSpinButton->get_digits(), 
rLocaleData, m_eSrcUnit);
+    if (!bRet)
+        return {};
+
+    if (fResult > SAL_MAX_INT32)
+        fResult = SAL_MAX_INT32;
+    else if (fResult < SAL_MIN_INT32)
+        fResult = SAL_MIN_INT32;
+
+    return std::optional<int>(std::round(fResult));
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index fb2f0ad95b5e..5a6d0630fbb0 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -19,13 +19,11 @@
 #include <frozen/unordered_map.h>
 
 #include <comphelper/lok.hxx>
-#include <i18nutil/unicode.hxx>
 #include <jsdialog/enabled.hxx>
 #include <o3tl/string_view.hxx>
 #include <officecfg/Office/Common.hxx>
 #include <osl/module.hxx>
 #include <sal/log.hxx>
-#include <unotools/localedatawrapper.hxx>
 #include <unotools/resmgr.hxx>
 #include <utility>
 #include <vcl/builder.hxx>
@@ -281,39 +279,6 @@ weld::Window* Application::GetFrameWeld(const 
css::uno::Reference<css::awt::XWin
 
 namespace weld
 {
-    OUString MetricSpinButton::MetricToString(FieldUnit rUnit)
-    {
-        const FieldUnitStringList& rList = ImplGetFieldUnits();
-        // return unit's default string (ie, the first one )
-        auto it = std::find_if(
-            rList.begin(), rList.end(),
-            [&rUnit](const std::pair<OUString, FieldUnit>& rItem) { return 
rItem.second == rUnit; });
-        if (it != rList.end())
-            return it->first;
-
-        return OUString();
-    }
-
-    IMPL_LINK_NOARG(MetricSpinButton, spin_button_value_changed, SpinButton&, 
void)
-    {
-        signal_value_changed();
-    }
-
-    IMPL_LINK(MetricSpinButton, spin_button_output, sal_Int64, nValue, 
OUString)
-    {
-        return format_number(nValue);
-    }
-
-    void MetricSpinButton::update_width_chars()
-    {
-        sal_Int64 min, max;
-        m_xSpinButton->get_range(min, max);
-        auto width = 
std::max(m_xSpinButton->get_pixel_size(format_number(min)).Width(),
-                              
m_xSpinButton->get_pixel_size(format_number(max)).Width());
-        int chars = ceil(width / m_xSpinButton->get_approximate_digit_width());
-        m_xSpinButton->set_width_chars(chars);
-    }
-
     unsigned int SpinButton::Power10(unsigned int n)
     {
         unsigned int nValue = 1;
@@ -339,98 +304,6 @@ namespace weld
         return (nValue + nHalf) / nFactor;
     }
 
-    OUString MetricSpinButton::format_number(sal_Int64 nValue) const
-    {
-        OUString aStr;
-
-        const LocaleDataWrapper& rLocaleData = 
Application::GetSettings().GetLocaleDataWrapper();
-
-        unsigned int nDecimalDigits = m_xSpinButton->get_digits();
-        //pawn percent off to icu to decide whether percent is separated from 
its number for this locale
-        if (m_eSrcUnit == FieldUnit::PERCENT)
-        {
-            double fValue = nValue;
-            fValue /= SpinButton::Power10(nDecimalDigits);
-            aStr = unicode::formatPercent(fValue, 
rLocaleData.getLanguageTag());
-        }
-        else
-        {
-            aStr = rLocaleData.getNum(nValue, nDecimalDigits, true, true);
-            OUString aSuffix = MetricToString(m_eSrcUnit);
-            if (m_eSrcUnit != FieldUnit::NONE && m_eSrcUnit != 
FieldUnit::DEGREE && m_eSrcUnit != FieldUnit::INCH && m_eSrcUnit != 
FieldUnit::FOOT)
-                aStr += " ";
-            if (m_eSrcUnit == FieldUnit::INCH)
-            {
-                OUString sDoublePrime = u"\u2033"_ustr;
-                if (aSuffix != "\"" && aSuffix != sDoublePrime)
-                    aStr += " ";
-                else
-                    aSuffix = sDoublePrime;
-            }
-            else if (m_eSrcUnit == FieldUnit::FOOT)
-            {
-                OUString sPrime = u"\u2032"_ustr;
-                if (aSuffix != "'" && aSuffix != sPrime)
-                    aStr += " ";
-                else
-                    aSuffix = sPrime;
-            }
-
-            assert(m_eSrcUnit != FieldUnit::PERCENT);
-            aStr += aSuffix;
-        }
-
-        return aStr;
-    }
-
-    void MetricSpinButton::set_digits(unsigned int digits)
-    {
-        sal_Int64 step, page;
-        get_increments(step, page, m_eSrcUnit);
-        sal_Int64 value = get_value(m_eSrcUnit);
-        m_xSpinButton->set_digits(digits);
-        set_increments(step, page, m_eSrcUnit);
-        set_value(value, m_eSrcUnit);
-        update_width_chars();
-    }
-
-    void MetricSpinButton::set_unit(FieldUnit eUnit)
-    {
-        if (eUnit != m_eSrcUnit)
-        {
-            sal_Int64 step, page;
-            get_increments(step, page, m_eSrcUnit);
-            sal_Int64 value = get_value(m_eSrcUnit);
-            m_eSrcUnit = eUnit;
-            set_increments(step, page, m_eSrcUnit);
-            set_value(value, m_eSrcUnit);
-            const OUString sText = format_number(m_xSpinButton->get_value());
-            m_xSpinButton->set_text(sText);
-            update_width_chars();
-        }
-    }
-
-    sal_Int64 MetricSpinButton::ConvertValue(sal_Int64 nValue, FieldUnit 
eInUnit, FieldUnit eOutUnit) const
-    {
-        return vcl::ConvertValue(nValue, 0, m_xSpinButton->get_digits(), 
eInUnit, eOutUnit);
-    }
-
-    IMPL_LINK(MetricSpinButton, spin_button_input, const OUString&, rText, 
std::optional<int>)
-    {
-        const LocaleDataWrapper& rLocaleData = 
Application::GetSettings().GetLocaleDataWrapper();
-        double fResult(0.0);
-        bool bRet = vcl::TextToValue(rText, fResult, 0, 
m_xSpinButton->get_digits(), rLocaleData, m_eSrcUnit);
-        if (!bRet)
-            return {};
-
-        if (fResult > SAL_MAX_INT32)
-            fResult = SAL_MAX_INT32;
-        else if (fResult < SAL_MIN_INT32)
-            fResult = SAL_MIN_INT32;
-
-        return std::optional<int>(std::round(fResult));
-    }
-
     size_t GetAbsPos(const weld::TreeView& rTreeView, const weld::TreeIter& 
rIter)
     {
         size_t nAbsPos = 0;
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index d010cfe46253..43b96034b50c 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -36,6 +36,7 @@
 #include <vcl/sysdata.hxx>
 #include <vcl/transfer.hxx>
 #include <vcl/toolkit/floatwin.hxx>
+#include <vcl/weld/MetricSpinButton.hxx>
 #include <unx/genpspgraphics.h>
 #include <rtl/strbuf.hxx>
 #include <sal/log.hxx>

Reply via email to