From 2ca43b02dd443e884e8c2acdf75cd011aac230ae Mon Sep 17 00:00:00 2001
From: Hugo Wetterberg <hugo@wetterberg.nu>
Date: Thu, 6 Feb 2025 15:56:43 +0100
Subject: [PATCH] scripting: add functions for setting and getting min word
 tracking

Also fixes documentation that stated that word tracking is an integer value.
---
 scribus/plugins/scriptplugin/cmdtext.cpp      | 69 ++++++++++++++++++-
 scribus/plugins/scriptplugin/cmdtext.h        | 28 +++++++-
 scribus/plugins/scriptplugin/scriptplugin.cpp |  2 +
 3 files changed, 96 insertions(+), 3 deletions(-)

diff --git scribus/plugins/scriptplugin/cmdtext.cpp scribus/plugins/scriptplugin/cmdtext.cpp
index 2ce25ecef..ec77307f2 100644
--- scribus/plugins/scriptplugin/cmdtext.cpp
+++ scribus/plugins/scriptplugin/cmdtext.cpp
@@ -207,6 +207,34 @@ PyObject *scribus_getwordtracking(PyObject* /* self */, PyObject* args)
 	return PyLong_FromLong(item->currentCharStyle().wordTracking()*100.0);
 }
 
+PyObject *scribus_getminwordtracking(PyObject* /* self */, PyObject* args)
+{
+	PyESString name;
+	if (!PyArg_ParseTuple(args, "|es", "utf-8", name.ptr()))
+		return nullptr;
+	if (!checkHaveDocument())
+		return nullptr;
+	const PageItem *item = GetUniqueItem(QString::fromUtf8(name.c_str()));
+	if (item == nullptr)
+		return nullptr;
+	if (!(item->isTextFrame()) && !(item->isPathText()))
+	{
+		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get word tracking of non-text frame.", "python error").toLocal8Bit().constData());
+		return nullptr;
+	}
+	if (item->HasSel)
+	{
+		for (int i = 0; i < item->itemText.length(); ++i)
+		{
+			if (item->itemText.selected(i))
+				return PyLong_FromLong(item->itemText.paragraphStyle(i).minWordTracking());
+		}
+		return nullptr;
+	}
+
+	return PyLong_FromLong(item->currentStyle().minWordTracking()*100.0);
+}
+
 PyObject *scribus_gettextlength(PyObject* /* self */, PyObject* args)
 {
 	PyESString name;
@@ -992,6 +1020,46 @@ PyObject *scribus_setwordtracking(PyObject* /* self */, PyObject* args)
 	Py_RETURN_NONE;
 }
 
+PyObject *scribus_setminwordtracking(PyObject* /* self */, PyObject* args)
+{
+	PyESString name;
+	double wt;
+	if (!PyArg_ParseTuple(args, "d|es", &wt, "utf-8", name.ptr()))
+		return nullptr;
+	if (!checkHaveDocument())
+		return nullptr;
+	if (wt < 1 || wt > 100)
+	{
+		PyErr_SetString(PyExc_ValueError, QObject::tr("Minimum word out of bounds, must be >= 1 and <= 100","python error").toLocal8Bit().constData());
+		return nullptr;
+	}
+	PageItem *item = GetUniqueItem(QString::fromUtf8(name.c_str()));
+	if (item == nullptr)
+		return nullptr;
+	if (!item->isTextFrame())
+	{
+		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot set minimum word tracking on a non-text frame.","python error").toLocal8Bit().constData());
+		return nullptr;
+	}
+
+	ScribusDoc* doc = ScCore->primaryMainWindow()->doc;
+	int oldAppMode = ScCore->primaryMainWindow()->doc->appMode;
+
+	Selection tmpSelection(nullptr, false);
+	tmpSelection.addItem(item);
+	if (item->HasSel)
+		doc->appMode = modeEdit;
+
+	ParagraphStyle newStyle;
+	newStyle.setMinWordTracking(wt / 100.0);
+	doc->itemSelection_ApplyParagraphStyle(newStyle, &tmpSelection);
+
+	doc->appMode = oldAppMode;
+
+	Py_RETURN_NONE;
+}
+
+
 PyObject *scribus_setlinespacingmode(PyObject* /* self */, PyObject* args)
 {
 	PyESString name;
@@ -1405,7 +1473,6 @@ PyObject *scribus_settextscalingv(PyObject* /* self */, PyObject* args)
 	Py_RETURN_NONE;
 }
 
-
 PyObject *scribus_settextshade(PyObject* /* self */, PyObject* args)
 {
 	PyESString name;
diff --git scribus/plugins/scriptplugin/cmdtext.h scribus/plugins/scriptplugin/cmdtext.h
index 581226c09..9b7ce60f5 100644
--- scribus/plugins/scriptplugin/cmdtext.h
+++ scribus/plugins/scriptplugin/cmdtext.h
@@ -201,7 +201,7 @@ PyObject *scribus_gettracking(PyObject * /*self*/, PyObject* args);
 
 /*! docstring */
 PyDoc_STRVAR(scribus_getwordtracking__doc__,
-QT_TR_NOOP("getWordTracking([\"name\"]) -> integer\n\
+QT_TR_NOOP("getWordTracking([\"name\"]) -> float\n\
 \n\
 Gets the word tracking of text inside text frame \"name\".\n\
 If \"name\" is not given the currently selected item is used. \n\
@@ -210,6 +210,18 @@ If there is some text selected only the selected text tracking is returned.\n\
 /*! Get word tracking */
 PyObject *scribus_getwordtracking(PyObject * /*self*/, PyObject* args);
 
+/*! docstring */
+PyDoc_STRVAR(scribus_getminwordtracking__doc__,
+QT_TR_NOOP("getMinWordTracking([\"name\"]) -> float\n\
+\n\
+Gets the word tracking of text inside text frame \"name\".\n\
+If \"name\" is not given the currently selected item is used. \n\
+If there is some text selected only the selected text tracking is returned.\n\
+"));
+/*! Get minimum word tracking */
+PyObject *scribus_getminwordtracking(PyObject * /*self*/, PyObject* args);
+
+
 /*! docstring */
 PyDoc_STRVAR(scribus_getlinespacing__doc__,
 QT_TR_NOOP("getLineSpacing([\"name\"]) -> float\n\
@@ -634,12 +646,24 @@ QT_TR_NOOP("setWordTracking(kern, [\"name\"])\n\
 \n\
 Sets the word tracking of the text the object \"name\" to \"kern\". If\n\
 there is some text selected only the selected text is changed. \"kern\" must\n\
-be an integer. If \"name\" is not given the currently selected item is\n\
+be an number. If \"name\" is not given the currently selected item is\n\
 used.\n\
 "));
 /*! Set text word tracking */
 PyObject *scribus_setwordtracking(PyObject * /*self*/, PyObject* args);
 
+/*! docstring */
+PyDoc_STRVAR(scribus_setminwordtracking__doc__,
+QT_TR_NOOP("setMinWordTracking(kern, [\"name\"])\n\
+\n\
+Sets the minimum word tracking of the text the object \"name\" to \"kern\".\n\
+If there is some text selected only the selected text is changed. \"kern\"\n\
+must be an number. If \"name\" is not given the currently selected item is\n\
+used.\n\
+"));
+/*! Set text minimum word tracking */
+PyObject *scribus_setminwordtracking(PyObject * /*self*/, PyObject* args);
+
 /*! docstring */
 PyDoc_STRVAR(scribus_linktextframes__doc__,
 QT_TR_NOOP("linkTextFrames(\"fromname\", \"toname\")\n\
diff --git scribus/plugins/scriptplugin/scriptplugin.cpp scribus/plugins/scriptplugin/scriptplugin.cpp
index 5a5bdd175..222d7a628 100644
--- scribus/plugins/scriptplugin/scriptplugin.cpp
+++ scribus/plugins/scriptplugin/scriptplugin.cpp
@@ -436,6 +436,7 @@ PyMethodDef scribus_methods[] = {
 	{ "getUnit", (PyCFunction) scribus_getunit, METH_NOARGS, tr(scribus_getunit__doc__)},
 	{ "getVisualBoundingBox", scribus_getvisualboundingbox, METH_VARARGS, tr(scribus_getvisualboundingbox__doc__) },
 	{ "getWordTracking", scribus_getwordtracking, METH_VARARGS, tr(scribus_getwordtracking__doc__)},
+	{ "getMinWordTracking", scribus_getminwordtracking, METH_VARARGS, tr(scribus_getminwordtracking__doc__)},
 	{ "pointsToDocUnit", scribus_pointstodocunit, METH_VARARGS, tr(scribus_pointstodocunit__doc__)},
 	{ "docUnitToPoints", scribus_docunittopoints, METH_VARARGS, tr(scribus_docunittopoints__doc__)},
 	{ "stringValueToPoints", scribus_stringvaluetopoints, METH_VARARGS, tr(scribus_stringvaluetopoints__doc__)},
@@ -603,6 +604,7 @@ PyMethodDef scribus_methods[] = {
 	{ "setTextFlowMode", scribus_settextflowmode, METH_VARARGS, tr(scribus_settextflowmode__doc__)},
 	{ "setTextScalingH", scribus_settextscalingh, METH_VARARGS, tr(scribus_settextscalingh__doc__)},
 	{ "setTextScalingV", scribus_settextscalingv, METH_VARARGS, tr(scribus_settextscalingv__doc__)},
+	{ "setMinWordTracking", scribus_setminwordtracking, METH_VARARGS, tr(scribus_setminwordtracking__doc__)},
 	{ "setTextShade", scribus_settextshade, METH_VARARGS, tr(scribus_settextshade__doc__)},
 	{ "setTextStroke", scribus_settextstroke, METH_VARARGS, tr(scribus_settextstroke__doc__)},
 	{ "setTextVerticalAlignment", scribus_settextverticalalignment, METH_VARARGS, tr(scribus_settextverticalalignment__doc__)},
-- 
2.48.1

