View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0017298 | Scribus | Scripter | public | 2024-10-23 11:38 | 2025-03-10 21:47 |
| Reporter | hugowett | Assigned To | jghali | ||
| Priority | normal | Severity | feature | Reproducibility | N/A |
| Status | closed | Resolution | fixed | ||
| Product Version | 1.6.2 | ||||
| Target Version | 1.6.4.svn | Fixed in Version | 1.6.4.svn | ||
| Summary | 0017298: Add functions for getting and setting the size of the current page, and getting the bounding box of a page item | ||||
| Description | I was writing a script for "cropping" a document to a set of elements and realised that we were missing functions for getting and setting the page size. There is a `getPageSize`, but only for getting the document setting. While calculating the bounds to crop to I also noticed that we don't have a way to get the actual size of an item if it has been rotated, getSize always returns the size pre-transform. * getCurrentPageSize() -> (width, height) - get the size of the current page * setCurrentPageSize(width, height) - changes the size of the current page * getBoundingBox() -> (x, y, width, height) - get the bounding box of a page item | ||||
| Additional Information | Example of what I did whith these functions. The idea is that the elements we want to crop to would be named with a common prefix, f.ex. "A1_Headline". import scribus def extractObjects(prefix): all = scribus.getAllObjects() names = [] # Collect all page items that have the name prefix, delete all others. for name in all: if not name.startswith(prefix): scribus.deleteObject(name) else: names.append(name) if len(names) == 0: raise Exception("unknown prefix") # Delete pages until only the page containing our page items remain. page = scribus.getItemPageNumber(names[0])+1 while scribus.pageCount() > 1: page = scribus.getItemPageNumber(names[0])+1 for i in range(1, scribus.pageCount()+1): if i == page: continue scribus.deletePage(i) break bounds = False # Get the bounding box for the page items. for name in names: x, y, width, height = scribus.getBoundingBox(name) print(f"{name} {x},{y} {width}x{height}") if not bounds: bounds = BoundingRect(x, y, width, height) else: bounds.extend(x, y, width, height) print(bounds) # We're going to move the page items to the top left of the page, make sure # that the baseline offset remains the same relative to the moved # frames. gridV, gridOff = scribus.getBaseLine() gridOff += gridV-(bounds.y%gridV) scribus.setBaseLine(gridV, gridOff) for name in names: scribus.moveObject(-bounds.x, -bounds.y, name) # Crop to content. scribus.setCurrentPageSize(bounds.width, bounds.height) class BoundingRect: def __init__(self, x, y, width, height): self.x = x self.y = y self.width = width self.height = height def extend(self, x, y, width, height): new_x_min = min(self.x, x) new_y_min = min(self.y, y) new_x_max = max(self.x + self.width, x + width) new_y_max = max(self.y + self.height, y + height) self.x = new_x_min self.y = new_y_min self.width = new_x_max - new_x_min self.height = new_y_max - new_y_min def __repr__(self): return f"BoundingRect(x={self.x}, y={self.y}, width={self.width}, height={self.height})" | ||||
| Tags | No tags attached. | ||||
| Attached Files | pagesize_bb.patch (7,130 bytes)
Index: scribus/plugins/scriptplugin/cmdgetprop.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdgetprop.cpp (revision 26360)
+++ scribus/plugins/scriptplugin/cmdgetprop.cpp (working copy)
@@ -328,6 +328,25 @@
return PyFloat_FromDouble(item->rotation() * -1.0);
}
+PyObject *scribus_getboundingbox(PyObject* /* self */, PyObject* args)
+{
+ PyESString name;
+ if (!PyArg_ParseTuple(args, "|es", "utf-8", name.ptr()))
+ return nullptr;
+ if (!checkHaveDocument())
+ return nullptr;
+ PageItem *item = GetUniqueItem(QString::fromUtf8(name.c_str()));
+ if (item == nullptr)
+ return nullptr;
+
+ return Py_BuildValue("(dddd)",
+ docUnitXToPageX(item->BoundingX),
+ docUnitYToPageY(item->BoundingY),
+ PointToValue(item->BoundingW),
+ PointToValue(item->BoundingH)
+ );
+}
+
PyObject *scribus_getallobjects(PyObject* /* self */, PyObject* args, PyObject *keywds)
{
int itemType = -1;
Index: scribus/plugins/scriptplugin/cmdgetprop.h
===================================================================
--- scribus/plugins/scriptplugin/cmdgetprop.h (revision 26360)
+++ scribus/plugins/scriptplugin/cmdgetprop.h (working copy)
@@ -252,6 +252,18 @@
PyObject *scribus_getrotation(PyObject * /*self*/, PyObject* args);
/*! docstring */
+PyDoc_STRVAR(scribus_getboundingbox__doc__,
+QT_TR_NOOP("getBoundingBox([\"name\"]) -> (x, y, width, height)\n\
+\n\
+Returns a (x, y, width, height) tuple with the position and size of the object \"name\".\n\
+If \"name\" is not given the currently selected item is used. The size is\n\
+expressed in the current measurement unit of the document - see UNIT_<type>\n\
+for reference.\n\
+"));
+/*! Returns size of the object */
+PyObject *scribus_getboundingbox(PyObject * /*self*/, PyObject* args);
+
+/*! docstring */
PyDoc_STRVAR(scribus_getallobjects__doc__,
QT_TR_NOOP("getAllObjects([type, page, \"layer\"]) -> list\n\
\n\
Index: scribus/plugins/scriptplugin/cmdpage.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdpage.cpp (revision 26360)
+++ scribus/plugins/scriptplugin/cmdpage.cpp (working copy)
@@ -195,6 +195,49 @@
return t;
}
+PyObject *scribus_getcurrentpagesize(PyObject* /* self */)
+{
+ if (!checkHaveDocument())
+ return nullptr;
+ ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
+ ScPage* currentPage = currentDoc->currentPage();
+
+ if (currentPage == nullptr)
+ return nullptr;
+
+ PyObject *t;
+ t = Py_BuildValue(
+ "(dd)",
+ PointToValue(currentPage->width()),
+ PointToValue(currentDoc->pageHeight())
+ );
+ return t;
+}
+
+PyObject *scribus_setcurrentpagesize(PyObject* /* self */, PyObject* args)
+{
+ double width, height;
+ if (!PyArg_ParseTuple(args, "dd", &width, &height))
+ return nullptr;
+ if (!checkHaveDocument())
+ return nullptr;
+
+ ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
+ ScribusView* currentView = ScCore->primaryMainWindow()->view;
+ ScPage* currentPage = currentDoc->currentPage();
+
+ if (currentPage == nullptr)
+ return nullptr;
+
+ currentPage->setWidth(ValueToPoint(width));
+ currentPage->setHeight(ValueToPoint(height));
+
+ currentView->reformPagesView();
+ currentView->DrawNew();
+
+ Py_RETURN_NONE;
+}
+
PyObject *scribus_getpagensize(PyObject* /* self */, PyObject* args)
{
int e;
Index: scribus/plugins/scriptplugin/cmdpage.h
===================================================================
--- scribus/plugins/scriptplugin/cmdpage.h (revision 26360)
+++ scribus/plugins/scriptplugin/cmdpage.h (working copy)
@@ -217,6 +217,25 @@
PyObject *scribus_getpagesize(PyObject * /*self*/);
/*! docstring */
+PyDoc_STRVAR(scribus_getcurrentpagesize__doc__,
+QT_TR_NOOP("getCurrentPageSize() -> (width, height)\n\
+\n\
+Returns a tuple with current page dimensions measured in the document's current units.\n\
+See UNIT_<type> constants and getPageMargins()\n\
+"));
+PyObject *scribus_getcurrentpagesize(PyObject * /*self*/);
+
+
+/*! docstring */
+PyDoc_STRVAR(scribus_setcurrentpagesize__doc__,
+QT_TR_NOOP("setCurrentPageSize(width, height)\n\
+\n\
+Sets the current page dimensions measured in the document's current units.\n\
+See UNIT_<type> constants and getPageMargins()\n\
+"));
+PyObject *scribus_setcurrentpagesize(PyObject * /*self*/, PyObject* args);
+
+/*! docstring */
PyDoc_STRVAR(scribus_getpagensize__doc__,
QT_TR_NOOP("getPageNSize(nr) -> tuple\n\
\n\
Index: scribus/plugins/scriptplugin/scriptplugin.cpp
===================================================================
--- scribus/plugins/scriptplugin/scriptplugin.cpp (revision 26360)
+++ scribus/plugins/scriptplugin/scriptplugin.cpp (working copy)
@@ -338,6 +338,7 @@
{ "getAllText", scribus_getalltext, METH_VARARGS, tr(scribus_getalltext__doc__)},
{ "getBaseLine", (PyCFunction) scribus_getbaseline, METH_NOARGS, tr(scribus_getbaseline__doc__)},
{ "getBleeds", scribus_getbleeds, METH_NOARGS, tr(scribus_getbleeds__doc__)},
+ { "getBoundingBox", scribus_getboundingbox, METH_VARARGS, tr(scribus_getalltext__doc__)},
{ "getCellColumnSpan", scribus_getcellcolumnspan, METH_VARARGS, tr(scribus_getcellcolumnspan__doc__)},
{ "getCellFillColor", scribus_getcellfillcolor, METH_VARARGS, tr(scribus_getcellfillcolor__doc__)},
{ "getCellRowSpan", scribus_getcellrowspan, METH_VARARGS, tr(scribus_getcellrowspan__doc__)},
@@ -355,6 +356,7 @@
{ "getColumns", scribus_getcolumns, METH_VARARGS, tr(scribus_getcolumns__doc__)},
{ "getColumnGuides", (PyCFunction) scribus_getColumnGuides, METH_VARARGS|METH_KEYWORDS, tr(scribus_getColumnGuides__doc__)},
{ "getCornerRadius", scribus_getcornerradius, METH_VARARGS, tr(scribus_getcornerradius__doc__)},
+ { "getCurrentPageSize", (PyCFunction) scribus_getcurrentpagesize, METH_NOARGS, tr(scribus_getcurrentpagesize__doc__)},
{ "getCustomLineStyle", scribus_getcustomlinestyle, METH_VARARGS, tr(scribus_getcustomlinestyle__doc__)},
{ "getDocName", (PyCFunction) scribus_getdocname, METH_NOARGS, tr(scribus_getdocname__doc__)},
{ "getFillBlendmode", scribus_getfillblendmode, METH_VARARGS, tr(scribus_getfillblendmode__doc__)},
@@ -527,6 +529,7 @@
{ "setColumnGuides", (PyCFunction) scribus_setColumnGuides, METH_VARARGS|METH_KEYWORDS, tr(scribus_setColumnGuides__doc__)},
{ "setCornerRadius", scribus_setcornerradius, METH_VARARGS, tr(scribus_setcornerradius__doc__)},
{ "setCursor", scribus_setcursor, METH_VARARGS, tr(scribus_setcursor__doc__)},
+ { "setCurrentPageSize", scribus_setcurrentpagesize, METH_VARARGS, tr(scribus_setcurrentpagesize__doc__)},
{ "setCustomLineStyle", scribus_setcustomlinestyle, METH_VARARGS, tr(scribus_setcustomlinestyle__doc__)},
{ "setDocType", scribus_setdoctype, METH_VARARGS, tr(scribus_setdoctype__doc__)},
{ "setEditMode", (PyCFunction) scribus_seteditmode, METH_NOARGS, tr(scribus_seteditmode__doc__)},
| ||||
| Patch | Yes | ||||
|
|
Ideally, the change page size code should be able to be very simple from scripter.. and call ScribusDoc::changePageProperties somehow, I need to check with Jean on that one. |
|
|
Did you get anywhere with finding a simpler way to change the size of the current page? To be clear, we are talking about this function, right? PyObject *scribus_setcurrentpagesize(PyObject* /* self */, PyObject* args) { double width, height; if (!PyArg_ParseTuple(args, "dd", &width, &height)) return nullptr; if (!checkHaveDocument()) return nullptr; ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc; ScribusView* currentView = ScCore->primaryMainWindow()->view; ScPage* currentPage = currentDoc->currentPage(); if (currentPage == nullptr) return nullptr; currentPage->setWidth(ValueToPoint(width)); currentPage->setHeight(ValueToPoint(height)); currentView->reformPagesView(); currentView->DrawNew(); Py_RETURN_NONE; } |
|
|
Hi, just checking in, is there anything I can do on my end to increase the chances of this getting accepted? |
|
|
We didn't bring this into 1.6.3, sorry, but will for 1.6.4 |
|
|
No worries, just looking forward to not having to do custom builds :) |
|
|
Thanks for the patch. I committed it with a few fix and also added getVisualBoundingBox() in the process. |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2024-10-23 11:38 | hugowett | New Issue | |
| 2024-10-23 11:38 | hugowett | File Added: pagesize_bb.patch | |
| 2024-10-30 20:47 | cbradney | Patch | No => Yes |
| 2024-10-30 20:49 | cbradney | Note Added: 0051506 | |
| 2024-11-06 12:18 | hugowett | Note Added: 0051532 | |
| 2025-01-21 19:10 | hugowett | Note Added: 0051933 | |
| 2025-01-21 21:30 | cbradney | Note Added: 0051934 | |
| 2025-01-21 21:31 | cbradney | Assigned To | => cbradney |
| 2025-01-21 21:31 | cbradney | Status | new => assigned |
| 2025-01-21 21:31 | cbradney | Target Version | => 1.6.4.svn |
| 2025-01-22 14:54 | hugowett | Note Added: 0051935 | |
| 2025-01-25 16:25 | cbradney | Assigned To | cbradney => jghali |
| 2025-01-25 16:25 | cbradney | Status | assigned => resolved |
| 2025-01-25 16:25 | cbradney | Resolution | open => fixed |
| 2025-01-25 16:25 | cbradney | Fixed in Version | => 1.6.4.svn |
| 2025-01-25 16:48 | jghali | Note Added: 0051939 | |
| 2025-03-10 21:47 | cbradney | Status | resolved => closed |