View Issue Details

IDProjectCategoryView StatusLast Update
0017398ScribusScripterpublic2025-01-31 07:48
Reporterhugowett Assigned To 
PrioritynormalSeverityfeatureReproducibilityN/A
Status newResolutionopen 
Product Version1.6.4.svn 
Summary0017398: Add script methods for setting letter and word kerning/tracking on a frame
DescriptionThis patch adds setTextTracking(), setTextWordTracking() and setTextMinWordTracking() that can be used to set the kerning for a frame. They all accept the tracking as in percents.

Very useful/necessary functionality for scripting automatic handling of over and underflow with a combination of scaling and kerning.
Tagsautomation, scripter
PatchYes

Activities

hugowett

2025-01-31 07:48

reporter  

0001-scripting-add-functions-for-setting-frame-letter-and.patch (7,045 bytes)   
From 8b382ec982bce665aca530b1a2bc9b2b345517b1 Mon Sep 17 00:00:00 2001
From: Hugo Wetterberg <hugo@wetterberg.nu>
Date: Fri, 31 Jan 2025 08:35:07 +0100
Subject: [PATCH] scripting: add functions for setting frame letter and word
 kerning

---
 scribus/plugins/scriptplugin/cmdtext.cpp      | 108 ++++++++++++++++++
 scribus/plugins/scriptplugin/cmdtext.h        |  30 +++++
 scribus/plugins/scriptplugin/scriptplugin.cpp |   3 +
 3 files changed, 141 insertions(+)

diff --git scribus/plugins/scriptplugin/cmdtext.cpp scribus/plugins/scriptplugin/cmdtext.cpp
index 2a60a7099..2f45a3ed6 100644
--- scribus/plugins/scriptplugin/cmdtext.cpp
+++ scribus/plugins/scriptplugin/cmdtext.cpp
@@ -1291,6 +1291,114 @@ PyObject *scribus_settextscalingv(PyObject* /* self */, PyObject* args)
 	Py_RETURN_NONE;
 }
 
+PyObject *scribus_settexttracking(PyObject* /* self */, PyObject* args)
+{
+	PyESString name;
+	double tt;
+	if (!PyArg_ParseTuple(args, "d|es", &tt, "utf-8", name.ptr()))
+		return nullptr;
+	if (!checkHaveDocument())
+		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 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;
+	doc->itemSelection_SetTracking(qRound(tt*10), &tmpSelection);
+	doc->appMode = oldAppMode;
+
+	Py_RETURN_NONE;
+}
+
+PyObject *scribus_settextwordtracking(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)
+	{
+		PyErr_SetString(PyExc_ValueError, QObject::tr("Word tracking out of bounds, must be > 1","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 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.charStyle().setWordTracking(wt / 100.0);
+	doc->itemSelection_ApplyParagraphStyle(newStyle, &tmpSelection);
+
+	doc->appMode = oldAppMode;
+
+	Py_RETURN_NONE;
+}
+
+PyObject *scribus_settextminwordtracking(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_settextshade(PyObject* /* self */, PyObject* args)
 {
diff --git scribus/plugins/scriptplugin/cmdtext.h scribus/plugins/scriptplugin/cmdtext.h
index 1cf4fd196..93d76a70d 100644
--- scribus/plugins/scriptplugin/cmdtext.h
+++ scribus/plugins/scriptplugin/cmdtext.h
@@ -579,6 +579,36 @@ If \"name\" is not given the currently selected item is used.\n\
 /*! Set text shde */
 PyObject *scribus_settextscalingh(PyObject * /*self*/, PyObject* args);
 
+/*! docstring */
+PyDoc_STRVAR(scribus_settexttracking__doc__,
+QT_TR_NOOP("setTextTracking(ratio, [\"name\"])\n\
+\n\
+Sets the text tracking of the object \"name\" to \"ratio\" in percent.\n\
+If \"name\" is not given the currently selected item is used.\n\
+"));
+/*! Set text tracking */
+PyObject *scribus_settexttracking(PyObject * /*self*/, PyObject* args);
+
+/*! docstring */
+PyDoc_STRVAR(scribus_settextwordtracking__doc__,
+QT_TR_NOOP("setTextWordTracking(ratio, [\"name\"])\n\
+\n\
+Sets the word tracking of the object \"name\" to \"ratio\" in percent.\n\
+If \"name\" is not given the currently selected item is used.\n\
+"));
+/*! Set text word tracking */
+PyObject *scribus_settextwordtracking(PyObject * /*self*/, PyObject* args);
+
+/*! docstring */
+PyDoc_STRVAR(scribus_settextminwordtracking__doc__,
+QT_TR_NOOP("setTextMinWordTracking(ratio, [\"name\"])\n\
+\n\
+Sets the minimum word tracking of the object \"name\" to \"ratio\" in percent.\n\
+If \"name\" is not given the currently selected item is used.\n\
+"));
+/*! Set text minimum word tracking */
+PyObject *scribus_settextminwordtracking(PyObject * /*self*/, PyObject* args);
+
 /*! docstring */
 PyDoc_STRVAR(scribus_settextshade__doc__,
 QT_TR_NOOP("setTextShade(shade, [\"name\"])\n\
diff --git scribus/plugins/scriptplugin/scriptplugin.cpp scribus/plugins/scriptplugin/scriptplugin.cpp
index 49c00b156..c473e6f8a 100644
--- scribus/plugins/scriptplugin/scriptplugin.cpp
+++ scribus/plugins/scriptplugin/scriptplugin.cpp
@@ -598,6 +598,9 @@ 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__)},
+	{ "setTextTracking", scribus_settexttracking, METH_VARARGS, tr(scribus_settexttracking__doc__)},
+	{ "setTextWordTracking", scribus_settextwordtracking, METH_VARARGS, tr(scribus_settextwordtracking__doc__)},
+	{ "setTextMinWordTracking", scribus_settextminwordtracking, METH_VARARGS, tr(scribus_settextwordtracking__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

Issue History

Date Modified Username Field Change
2025-01-31 07:48 hugowett New Issue
2025-01-31 07:48 hugowett Tag Attached: automation
2025-01-31 07:48 hugowett Tag Attached: scripter
2025-01-31 07:48 hugowett File Added: 0001-scripting-add-functions-for-setting-frame-letter-and.patch