View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0017298 | Scribus | Scripter | public | 2024-10-23 11:38 | 2024-10-30 20:49 |
Reporter | hugowett | Assigned To | |||
Priority | normal | Severity | feature | Reproducibility | N/A |
Status | new | Resolution | open | ||
Product Version | 1.6.2 | ||||
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. | ||||
Patch | Yes | ||||
|
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__)}, |
|
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. |