View Issue Details

IDProjectCategoryView StatusLast Update
0014837ScribusScripterpublic2017-06-04 15:16
Reporterdockattt Assigned To 
PrioritynormalSeverityfeatureReproducibilityalways
Status newResolutionopen 
Product Version1.5.4.svn 
Summary0014837: Add functions that get an object's page number and change an object's page number
Descriptionthere doesn't seem to be functions that tell you what page number a page item is on. Nor does there seem to be one that allows you to easily change the page number of a page item. The patch attached adds the getObjectPageNumber function that returns the page items page number. It also adds setObjectPageNumber which moves a page item to a new page.

getObjectPageNumber works simply like so
getObjectPageNumber()
getObjectPageNumber("name of page item")

setObjectPageNumber works like so:
setObjectPageNumber(newpagenumber)
setObjectPageNumber(newpagenumber, "name of page item")
 
Steps To Reproducesee doc strings for how to use.
Additional InformationSeeing the movement I'm expecting in testing.
TagsNo tags attached.
PatchYes

Activities

dockattt

2017-05-31 18:02

reporter  

moveObject.patch (4,987 bytes)   
Index: Scribus/scribus/plugins/scriptplugin/cmdpage.cpp
===================================================================
--- Scribus/scribus/plugins/scriptplugin/cmdpage.cpp	(revision 22048)
+++ Scribus/scribus/plugins/scriptplugin/cmdpage.cpp	(working copy)
@@ -501,7 +501,76 @@
 	Py_RETURN_NONE;
 }
 
+PyObject *scribus_getobjectpagenumber(PyObject* /* self */, PyObject* args){
 
+	char *name = const_cast<char*>("");
+	if (!PyArg_ParseTuple(args, "|es", "utf-8", &name))
+		return NULL;
+	if(!checkHaveDocument())
+		return NULL;
+	PageItem *i = GetUniqueItem(QString::fromUtf8(name));
+	if (i == NULL)
+		return NULL;
+	PyObject* rv = PyInt_FromLong(ScCore->primaryMainWindow()->doc->OnPage(i));
+	return rv;
+}
+
+PyObject *scribus_setobjectpagenumber(PyObject* /* self */, PyObject* args){
+
+	char *name = const_cast<char*>("");
+	int newpage;
+	if (!PyArg_ParseTuple(args, "i|es", &newpage, "utf-8", &name))
+		return NULL;
+	if(!checkHaveDocument())
+		return NULL;
+	PageItem *i = GetUniqueItem(QString::fromUtf8(name));
+	if (i == NULL)
+		return NULL;
+
+	if (newpage < 0)
+	{
+		PyErr_SetString(PyExc_RuntimeError, QObject::tr("Can't use a negative page number.","python error").toLocal8Bit().constData());
+		return NULL;
+	}
+
+	ScribusDoc* doc = ScCore->primaryMainWindow()->doc;
+	int numpages = doc->Pages->count();
+	if (newpage >= numpages)
+	{
+		QByteArray qba = QString("pagenumber must be less than the number of pages: ").append(QString::number(numpages)).toUtf8();
+		const char *message = qba.data();
+		PyErr_SetString(PyExc_RuntimeError, 
+				QObject::tr(message,"python error").toLocal8Bit().constData());
+		return NULL;
+	}
+
+	int oldpage = doc->OnPage(i);
+	if(oldpage == newpage) Py_RETURN_NONE;
+
+	MarginStruct newPageBleeds;
+	doc->getBleeds(newpage, newPageBleeds);
+	double newy = doc->Pages->at(newpage)->yOffset() - newPageBleeds.top();
+
+	MarginStruct oldPageBleeds;
+	doc->getBleeds(oldpage, oldPageBleeds);
+	double oldy = doc->Pages->at(oldpage)->yOffset() - oldPageBleeds.top();
+
+	double ytarget;
+	if(newpage > oldpage){
+		
+		ytarget = newy - oldy;
+	}
+	else{
+
+		ytarget = -(oldy - newy);
+	}
+	
+	doc->moveItem(0, ytarget, i);
+
+	Py_RETURN_NONE;
+}
+
+
 /*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings
 with header files structure untouched (docstrings are kept near declarations)
 PV */
@@ -516,5 +585,7 @@
 	  << scribus_getVguides__doc__     << scribus_setVguides__doc__
 	  << scribus_pagedimension__doc__  << scribus_getpageitems__doc__
 	  << scribus_getpagemargins__doc__ << scribus_importpage__doc__
-	  << scribus_pagensize__doc__      << scribus_pagenmargins__doc__;
+	  << scribus_pagensize__doc__      << scribus_pagenmargins__doc__
+	  << scribus_getobjectpagenumber__doc__
+	  << scribus_setobjectpagenumber__doc__;
 }
Index: Scribus/scribus/plugins/scriptplugin/cmdpage.h
===================================================================
--- Scribus/scribus/plugins/scriptplugin/cmdpage.h	(revision 22048)
+++ Scribus/scribus/plugins/scriptplugin/cmdpage.h	(working copy)
@@ -224,5 +224,25 @@
 "));
 PyObject *scribus_importpage(PyObject */*self*/, PyObject* args);
 
+/*! docstring */
+PyDoc_STRVAR(scribus_getobjectpagenumber__doc__,
+QT_TR_NOOP("getObjectPageNumber([\"name\"]) -> an integer\n\
+\n\
+Returns an integer that is the page number of the page item \"name\"\n\
+Page numbers start at 0 so the number returned will be 0 to (total pages)-1.\n\
+If \"name\" is not given the currently selected item is used.\n\
+"));
+PyObject *scribus_getobjectpagenumber(PyObject* /* self */, PyObject* args);
+
+/*! docstring */
+PyDoc_STRVAR(scribus_setobjectpagenumber__doc__,
+QT_TR_NOOP("setObjectPageNumber(pagenumber,[\"name\"]) -> None\n\
+\n\
+Moves the page item with the name \"name\" to the page \"pagenumber\".\n\
+Page numbers start at 0 so the number used must be 0 to (total pages)-1.\n\
+If \"name\" is not given the currently selected item is used.\n\
+"));
+PyObject *scribus_setobjectpagenumber(PyObject* /* self */, PyObject* args);
+
 #endif
 
Index: Scribus/scribus/plugins/scriptplugin/scriptplugin.cpp
===================================================================
--- Scribus/scribus/plugins/scriptplugin/scriptplugin.cpp	(revision 22048)
+++ Scribus/scribus/plugins/scriptplugin/scriptplugin.cpp	(working copy)
@@ -572,6 +572,8 @@
 	// Internal methods - Not for public use
 	{const_cast<char*>("retval"), (PyCFunction)scribus_retval, METH_VARARGS, const_cast<char*>("Scribus internal.")},
 	{const_cast<char*>("getval"), (PyCFunction)scribus_getval, METH_NOARGS, const_cast<char*>("Scribus internal.")},
+	{const_cast<char*>("getObjectPageNumber"), (PyCFunction)scribus_getobjectpagenumber, METH_VARARGS, tr(scribus_getobjectpagenumber__doc__)},
+	{const_cast<char*>("setObjectPageNumber"), (PyCFunction)scribus_setobjectpagenumber, METH_VARARGS, tr(scribus_setobjectpagenumber__doc__)},
 	{NULL, (PyCFunction)(0), 0, NULL} /* sentinel */
 };
 
moveObject.patch (4,987 bytes)   

jghali

2017-05-31 19:46

administrator   ~0043978

Last edited: 2017-05-31 20:03

The object page number is an internal property, it should be accessed, never be set externally. In some cases it is deliberately set to -1 by Scribus and must stay so. This page number is also useless when object covers two different pages.

dockattt

2017-06-04 14:58

reporter   ~0043992

I've thought about this before I read this note. It's less of a "set page number" function than a "move object to page function". I think there's an page owning variable on the page item that if you set it doesn't seem to do anything. That's why it has to be moved/changed.

I just tested the "object on multiple pages" scenario and it did as I expected. It returned the number of the page where the object starts on. If the object is between 2 pages it returns -1. I just found that Scribus crashes if its off in the scratch area. The function needs to be fixed if the page is on -1 so it doesn't crash. I'm not sure if that's a bug in Scribus or not!

dockattt

2017-06-04 15:16

reporter   ~0043993

ok I just added some code in that guards against the crash that occurs when an object isn't on a page. Changed the pydocs a little as well to reflect this. This is in the new patch.

I think when I was scripting this problem I used gotoPage(newPageNumber) and set the items page coordinates to what it already was. This "moved" the object to the page I wanted it on.
moveObject_2.patch (5,321 bytes)   
Index: Scribus/scribus/plugins/scriptplugin/cmdpage.cpp
===================================================================
--- Scribus/scribus/plugins/scriptplugin/cmdpage.cpp	(revision 22048)
+++ Scribus/scribus/plugins/scriptplugin/cmdpage.cpp	(working copy)
@@ -501,7 +501,80 @@
 	Py_RETURN_NONE;
 }
 
+PyObject *scribus_getobjectpagenumber(PyObject* /* self */, PyObject* args){
 
+	char *name = const_cast<char*>("");
+	if (!PyArg_ParseTuple(args, "|es", "utf-8", &name))
+		return NULL;
+	if(!checkHaveDocument())
+		return NULL;
+	PageItem *i = GetUniqueItem(QString::fromUtf8(name));
+	if (i == NULL)
+		return NULL;
+	PyObject* rv = PyInt_FromLong(ScCore->primaryMainWindow()->doc->OnPage(i));
+	return rv;
+}
+
+PyObject *scribus_setobjectpagenumber(PyObject* /* self */, PyObject* args){
+
+	char *name = const_cast<char*>("");
+	int newpage;
+	if (!PyArg_ParseTuple(args, "i|es", &newpage, "utf-8", &name))
+		return NULL;
+	if(!checkHaveDocument())
+		return NULL;
+	PageItem *i = GetUniqueItem(QString::fromUtf8(name));
+	if (i == NULL)
+		return NULL;
+
+	if (newpage < 0)
+	{
+		PyErr_SetString(PyExc_RuntimeError, QObject::tr("Can't use a negative page number.","python error").toLocal8Bit().constData());
+		return NULL;
+	}
+
+	ScribusDoc* doc = ScCore->primaryMainWindow()->doc;
+	int numpages = doc->Pages->count();
+	if (newpage >= numpages)
+	{
+		QByteArray qba = QString("pagenumber must be less than the number of pages: ").append(QString::number(numpages)).toUtf8();
+		const char *message = qba.data();
+		PyErr_SetString(PyExc_RuntimeError, 
+				QObject::tr(message,"python error").toLocal8Bit().constData());
+		return NULL;
+	}
+
+	int oldpage = doc->OnPage(i);
+	if(oldpage == newpage) Py_RETURN_NONE;
+	else if(oldpage < 0){
+		PyErr_SetString(PyExc_RuntimeError, QObject::tr("Can't change an object's page that isn't on an identifiable page.","python error").toLocal8Bit().constData());
+		return NULL;
+	}
+
+	MarginStruct newPageBleeds;
+	doc->getBleeds(newpage, newPageBleeds);
+	double newy = doc->Pages->at(newpage)->yOffset() - newPageBleeds.top();
+
+	MarginStruct oldPageBleeds;
+	doc->getBleeds(oldpage, oldPageBleeds);
+	double oldy = doc->Pages->at(oldpage)->yOffset() - oldPageBleeds.top();
+
+	double ytarget;
+	if(newpage > oldpage){
+		
+		ytarget = newy - oldy;
+	}
+	else{
+
+		ytarget = -(oldy - newy);
+	}
+	
+	doc->moveItem(0, ytarget, i);
+
+	Py_RETURN_NONE;
+}
+
+
 /*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings
 with header files structure untouched (docstrings are kept near declarations)
 PV */
@@ -516,5 +589,7 @@
 	  << scribus_getVguides__doc__     << scribus_setVguides__doc__
 	  << scribus_pagedimension__doc__  << scribus_getpageitems__doc__
 	  << scribus_getpagemargins__doc__ << scribus_importpage__doc__
-	  << scribus_pagensize__doc__      << scribus_pagenmargins__doc__;
+	  << scribus_pagensize__doc__      << scribus_pagenmargins__doc__
+	  << scribus_getobjectpagenumber__doc__
+	  << scribus_setobjectpagenumber__doc__;
 }
Index: Scribus/scribus/plugins/scriptplugin/cmdpage.h
===================================================================
--- Scribus/scribus/plugins/scriptplugin/cmdpage.h	(revision 22048)
+++ Scribus/scribus/plugins/scriptplugin/cmdpage.h	(working copy)
@@ -224,5 +224,27 @@
 "));
 PyObject *scribus_importpage(PyObject */*self*/, PyObject* args);
 
+/*! docstring */
+PyDoc_STRVAR(scribus_getobjectpagenumber__doc__,
+QT_TR_NOOP("getObjectPageNumber([\"name\"]) -> an integer\n\
+\n\
+Returns an integer that is the page number of the page item \"name\"\n\
+Page numbers start at 0 so the number returned will be 0 to (total pages)-1.\n\
+Will return -1 if the object is not on any page.\n\
+If \"name\" is not given the currently selected item is used.\n\
+"));
+PyObject *scribus_getobjectpagenumber(PyObject* /* self */, PyObject* args);
+
+/*! docstring */
+PyDoc_STRVAR(scribus_setobjectpagenumber__doc__,
+QT_TR_NOOP("setObjectPageNumber(pagenumber,[\"name\"]) -> None\n\
+\n\
+Moves the page item with the name \"name\" to the page \"pagenumber\".\n\
+Page numbers start at 0 so the number used must be 0 to (total pages)-1.\n\
+Objects that are not on any page cannot be moved to a different page.\n\
+If \"name\" is not given the currently selected item is used.\n\
+"));
+PyObject *scribus_setobjectpagenumber(PyObject* /* self */, PyObject* args);
+
 #endif
 
Index: Scribus/scribus/plugins/scriptplugin/scriptplugin.cpp
===================================================================
--- Scribus/scribus/plugins/scriptplugin/scriptplugin.cpp	(revision 22048)
+++ Scribus/scribus/plugins/scriptplugin/scriptplugin.cpp	(working copy)
@@ -572,6 +572,8 @@
 	// Internal methods - Not for public use
 	{const_cast<char*>("retval"), (PyCFunction)scribus_retval, METH_VARARGS, const_cast<char*>("Scribus internal.")},
 	{const_cast<char*>("getval"), (PyCFunction)scribus_getval, METH_NOARGS, const_cast<char*>("Scribus internal.")},
+	{const_cast<char*>("getObjectPageNumber"), (PyCFunction)scribus_getobjectpagenumber, METH_VARARGS, tr(scribus_getobjectpagenumber__doc__)},
+	{const_cast<char*>("setObjectPageNumber"), (PyCFunction)scribus_setobjectpagenumber, METH_VARARGS, tr(scribus_setobjectpagenumber__doc__)},
 	{NULL, (PyCFunction)(0), 0, NULL} /* sentinel */
 };
 
moveObject_2.patch (5,321 bytes)   

Issue History

Date Modified Username Field Change
2017-05-31 18:02 dockattt New Issue
2017-05-31 18:02 dockattt File Added: moveObject.patch
2017-05-31 19:46 jghali Note Added: 0043978
2017-05-31 20:03 jghali Note Edited: 0043978
2017-06-04 14:58 dockattt Note Added: 0043992
2017-06-04 15:16 dockattt File Added: moveObject_2.patch
2017-06-04 15:16 dockattt Note Added: 0043993