View Issue Details

IDProjectCategoryView StatusLast Update
0008118ScribusScripterpublic2017-04-16 15:17
Reporterdmcadmin Assigned Tojghali  
PrioritynormalSeverityfeatureReproducibilityN/A
Status closedResolutionfixed 
Target Version1.6 milestoneFixed in Version1.5.3.svn 
Summary0008118: Allow get/set of item attributes in scripter
DescriptionEach object in Scribus can have attributes that store various metadata. Currently, I believe this is used mainly for TOC.

It would be beneficial for Python scripts to be able to access these attributes. (For example, a user could tag objects and then a script would be able to automatically generate an index.)
TagsNo tags attached.
Patch

Activities

jurajF

2017-03-31 07:54

reporter   ~0043685

In patch are provided commands scribus.setObjectAttributes() and scribus.getObjectAttributes()
Also included file attr.py show how to use new commands.
0001-getObjectAttributes-setObjectAttributes-commands-for.patch (10,157 bytes)   
From 912487b4904f8b68fac4cdf40f7229bc5a13b997 Mon Sep 17 00:00:00 2001
From: Juraj Fedel <wtxnh-scribus@yahoo.com.au>
Date: Fri, 31 Mar 2017 09:32:04 +0200
Subject: [PATCH] getObjectAttributes setObjectAttributes commands for python

---
 scribus/plugins/scriptplugin/cmdgetprop.cpp   |  44 ++++++++++-
 scribus/plugins/scriptplugin/cmdgetprop.h     |   7 ++
 scribus/plugins/scriptplugin/cmdsetprop.cpp   | 107 +++++++++++++++++++++++++-
 scribus/plugins/scriptplugin/cmdsetprop.h     |  16 ++++
 scribus/plugins/scriptplugin/scriptplugin.cpp |   2 +
 5 files changed, 174 insertions(+), 2 deletions(-)

diff --git a/scribus/plugins/scriptplugin/cmdgetprop.cpp b/scribus/plugins/scriptplugin/cmdgetprop.cpp
index 8173b63e9..3f89baf69 100644
--- a/scribus/plugins/scriptplugin/cmdgetprop.cpp
+++ b/scribus/plugins/scriptplugin/cmdgetprop.cpp
@@ -327,6 +327,47 @@ PyObject *scribus_getallobj(PyObject* /* self */, PyObject* args)
 	return l;
 }
 
+PyObject *scribus_getobjectattributes(PyObject* /* self */, PyObject* args)
+{
+	if(!checkHaveDocument())
+		return NULL;
+	char *Name = const_cast<char*>("");
+	if (!PyArg_ParseTuple(args, "|es", "utf-8", &Name))
+		return NULL;
+	PageItem *item = GetUniqueItem(QString::fromUtf8(Name));
+	if (item == NULL)
+		return NULL;
+
+	ObjAttrVector *attributes=item->getObjectAttributes();
+	PyObject *lst;
+	lst = PyList_New(attributes->count());
+	if (!lst)
+		return NULL;
+	int n = 0;
+	for (ObjAttrVector::Iterator objAttrIt = attributes->begin() ; objAttrIt != attributes->end(); ++objAttrIt)
+	{
+		PyObject *tmp;
+		tmp = Py_BuildValue("{ssssssssssssss}",
+				    "Name", objAttrIt->name.toUtf8().data(),
+				    "Type", objAttrIt->type.toUtf8().data(),
+				    "Value", objAttrIt->value.toUtf8().data(),
+				    "Parameter", objAttrIt->parameter.toUtf8().data(),
+				    "Relationship", objAttrIt->relationship.toUtf8().data(),
+				    "RelationshipTo", objAttrIt->relationshipto.toUtf8().data(),
+				    "AutoAddTo", objAttrIt->autoaddto.toUtf8().data());
+		if (tmp)
+			PyList_SetItem(lst, n, tmp);
+		else {
+			// Error string is already set by Py_BuildValue()
+			Py_DECREF(lst);
+			return NULL;
+		}
+		n++;
+	}
+	return lst;
+}
+
+
 /*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings
 with header files structure untouched (docstrings are kept near declarations)
 PV */
@@ -342,5 +383,6 @@ void cmdgetpropdocwarnings()
 	  << scribus_getfillshade__doc__ << scribus_getcornerrad__doc__ 
 	  << scribus_getimgscale__doc__ << scribus_getimagefile__doc__ 
 	  << scribus_getposi__doc__ << scribus_getsize__doc__ 
-	  << scribus_getrotation__doc__ <<  scribus_getallobj__doc__;
+	  << scribus_getrotation__doc__ <<  scribus_getallobj__doc__
+	  << scribus_getobjectattributes__doc__;
 }
diff --git a/scribus/plugins/scriptplugin/cmdgetprop.h b/scribus/plugins/scriptplugin/cmdgetprop.h
index 83eae6baa..5ccd15c9c 100644
--- a/scribus/plugins/scriptplugin/cmdgetprop.h
+++ b/scribus/plugins/scriptplugin/cmdgetprop.h
@@ -219,5 +219,12 @@ Returns a list containing the names of all objects on the current page.\n\
 /*! Returns a list with all objects in page */
 PyObject *scribus_getallobj(PyObject * /*self*/, PyObject* args);
 
+/*! docstring */
+PyDoc_STRVAR(scribus_getobjectattributes__doc__,
+QT_TR_NOOP("getObjectAttributes([\"name\"]) -> list\n\
+Returns a list containing all attributes of object \"name\".\n\
+"));
+PyObject *scribus_getobjectattributes(PyObject * /*self*/, PyObject* args);
+
 #endif
 
diff --git a/scribus/plugins/scriptplugin/cmdsetprop.cpp b/scribus/plugins/scriptplugin/cmdsetprop.cpp
index 982c3347f..c8adb7aab 100644
--- a/scribus/plugins/scriptplugin/cmdsetprop.cpp
+++ b/scribus/plugins/scriptplugin/cmdsetprop.cpp
@@ -397,6 +397,111 @@ PyObject *scribus_setnewname(PyObject* /* self */, PyObject* args)
 	Py_RETURN_NONE;
 }
 
+PyObject *scribus_setobjectattributes(PyObject* /* self */, PyObject* args)
+{
+	if(!checkHaveDocument())
+		return NULL;
+	char *Name = const_cast<char*>("");
+	PyObject *attr;
+	if (!PyArg_ParseTuple(args, "O|es", &attr, "utf-8", &Name))
+		return NULL;
+	PageItem *item = GetUniqueItem(QString::fromUtf8(Name));
+	if (item == NULL)
+		return NULL;
+
+	if (!PyList_Check(attr)) {
+		PyErr_SetString(PyExc_TypeError, "argument must be list.");
+		return NULL;
+	}
+
+	ObjAttrVector attributes;
+	int n = PyList_Size(attr);
+	for (int i=0; i<n; ++i) {
+		PyObject *tmp = PyList_GetItem(attr, i);
+		if (!PyDict_Check(tmp)) {
+			PyErr_SetString(PyExc_TypeError, "elemets of 'attr' must be dictionary.");
+			return NULL;
+		}
+		ObjectAttribute blank;
+		PyObject *val;
+		char* data;
+
+		val = PyDict_GetItemString(tmp, "Name");
+		if (!val) {
+			PyErr_SetString(PyExc_TypeError, "attribute does not have 'Name' key.");
+			return NULL;
+		}
+		data = PyString_AsString(val);
+		if (!data)
+			return NULL;
+		blank.name = QString(data);
+
+		val = PyDict_GetItemString(tmp, "Type");
+		if (!val) {
+			PyErr_SetString(PyExc_TypeError, "attribute does not have 'Type' key.");
+			return NULL;
+		}
+		data = PyString_AsString(val);
+		if (!data)
+			return NULL;
+		blank.type = QString(data);
+
+		val = PyDict_GetItemString(tmp, "Value");
+		if (!val) {
+			PyErr_SetString(PyExc_TypeError, "attribute does not have 'Value' key.");
+			return NULL;
+		}
+		data = PyString_AsString(val);
+		if (!data)
+			return NULL;
+		blank.value = QString(data);
+
+		val = PyDict_GetItemString(tmp, "Parameter");
+		if (!val) {
+			PyErr_SetString(PyExc_TypeError, "attribute does not have 'Parameter' key.");
+			return NULL;
+		}
+		data = PyString_AsString(val);
+		if (!data)
+			return NULL;
+		blank.parameter = QString(data);
+
+		val = PyDict_GetItemString(tmp, "Relationship");
+		if (!val) {
+			PyErr_SetString(PyExc_TypeError, "attribute does not have 'Relationship' key.");
+			return NULL;
+		}
+		data = PyString_AsString(val);
+		if (!data)
+			return NULL;
+		blank.relationship = QString(data);
+
+		val = PyDict_GetItemString(tmp, "RelationshipTo");
+		if (!val) {
+			PyErr_SetString(PyExc_TypeError, "attribute does not have 'RelationshipTo' key.");
+			return NULL;
+		}
+		data = PyString_AsString(val);
+		if (!data)
+			return NULL;
+		blank.relationshipto = QString(data);
+
+		val = PyDict_GetItemString(tmp, "AutoAddTo");
+		if (!val) {
+			PyErr_SetString(PyExc_TypeError, "attribute does not have 'AutoAddTo' key.");
+			return NULL;
+		}
+		data = PyString_AsString(val);
+		if (!data)
+			return NULL;
+		blank.autoaddto = QString(data);
+
+		attributes.append(blank);
+	}
+
+	item->setObjectAttributes(&attributes);
+	Py_RETURN_NONE;
+}
 
 /*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings
 with header files structure untouched (docstrings are kept near declarations)
@@ -412,5 +517,5 @@ void cmdsetpropdocwarnings()
 	  << scribus_setlinejoin__doc__  << scribus_setlinecap__doc__   
 	  << scribus_setlinestyle__doc__ << scribus_setfillshade__doc__ 
 	  << scribus_setcornerrad__doc__ << scribus_setmultiline__doc__
-	  << scribus_setnewname__doc__;
+	  << scribus_setnewname__doc__   << scribus_setobjectattributes__doc__;
 }
diff --git a/scribus/plugins/scriptplugin/cmdsetprop.h b/scribus/plugins/scriptplugin/cmdsetprop.h
index 592a6bbd7..f4fcab54d 100644
--- a/scribus/plugins/scriptplugin/cmdsetprop.h
+++ b/scribus/plugins/scriptplugin/cmdsetprop.h
@@ -204,5 +204,21 @@ May raise NotFoundError if the line style doesn't exist.\n\
 "));
 /*! Set newname */
 PyObject *scribus_setnewname(PyObject * /*self*/, PyObject* args);
+
+/*! docstring */
+PyDoc_STRVAR(scribus_setobjectattributes__doc__,
+QT_TR_NOOP("seObjectAttributes(attritbutes, [\"name\"])\n\
+\n\
+Sets attributes of the object \"name\".\n\
+If \"name\" is not given the currently selected item is used.\n\
+\n\
+attributes is list of dictionary. Each dictionary must have those keys:\n\
+Name, Type, Value, Parameter, Relationship, RelationshipTo, AutoAddTo\n\
+All values must be strings.\n\
+\n\
+May raise NotFoundError if the object doesn't exist.\n\
+"));
+PyObject *scribus_setobjectattributes(PyObject * /*self*/, PyObject* args);
+
 #endif
 
diff --git a/scribus/plugins/scriptplugin/scriptplugin.cpp b/scribus/plugins/scriptplugin/scriptplugin.cpp
index 11d9a4233..14bba5ed3 100644
--- a/scribus/plugins/scriptplugin/scriptplugin.cpp
+++ b/scribus/plugins/scriptplugin/scriptplugin.cpp
@@ -389,6 +389,7 @@ PyMethodDef scribus_methods[] = {
 	{const_cast<char*>("getPosition"), scribus_getposi, METH_VARARGS, tr(scribus_getposi__doc__)},
 	{const_cast<char*>("getRotation"), scribus_getrotation, METH_VARARGS, tr(scribus_getrotation__doc__)},
 	{const_cast<char*>("getObjectType"), scribus_getobjecttype, METH_VARARGS, tr(scribus_getobjecttype__doc__)},
+	{const_cast<char*>("getObjectAttributes"), scribus_getobjectattributes, METH_VARARGS, tr(scribus_getobjectattributes__doc__)},
 	{const_cast<char*>("getSelectedObject"), scribus_getselobjnam, METH_VARARGS, tr(scribus_getselobjnam__doc__)},
 	{const_cast<char*>("getSize"), scribus_getsize, METH_VARARGS, tr(scribus_getsize__doc__)},
 	{const_cast<char*>("getTableRows"), scribus_gettablerows, METH_VARARGS, tr(scribus_gettablerows__doc__)},
@@ -523,6 +524,7 @@ PyMethodDef scribus_methods[] = {
 	{const_cast<char*>("setMultiLine"), scribus_setmultiline, METH_VARARGS, tr(scribus_setmultiline__doc__)},
 	{const_cast<char*>("setNewName"), scribus_setnewname, METH_VARARGS, tr(scribus_setnewname__doc__)},
 	// duplicity? {"setMultiLine", scribus_setmultiline, METH_VARARGS, "TODO: docstring"},
+	{const_cast<char*>("setObjectAttributes"), scribus_setobjectattributes, METH_VARARGS, tr(scribus_setobjectattributes__doc__)},
 	{const_cast<char*>("setRedraw"), scribus_setredraw, METH_VARARGS, tr(scribus_setredraw__doc__)},
 	// missing? {"setSelectedObject", scribus_setselobjnam, METH_VARARGS, "Returns the Name of the selecteted Object. \"nr\" if given indicates the Number of the selected Object, e.g. 0 means the first selected Object, 1 means the second selected Object and so on."},
 	{const_cast<char*>("hyphenateText"), scribus_hyphenatetext, METH_VARARGS, tr(scribus_hyphenatetext__doc__)},
-- 
2.11.0

attr.py (2,291 bytes)   
#!/home/boza/usr/bin/scribus-1.5.3.svn --python-script
# -*- coding: utf-8 -*-

import sys
import scribus
#########################
# YOUR IMPORTS GO HERE  #
#########################

def main(argv):
    """Test setting and getting attributes on pageItem."""
    #########################
    #  YOUR CODE GOES HERE  #
    #########################
    scribus.newDocument(scribus.PAPER_A4,  (15,15,  20, 20),  scribus.PORTRAIT, 1, scribus.UNIT_POINTS,  scribus.PAGE_1, 0, 1)
    txt=scribus.createText(250, 70, 100,  150)
    scribus.setText('Some text!', txt)
    a1 = {
        "Name": 'MyAttribute',
        'Type': 'string',
        'Value': 'Something',
        'Parameter': '',
        'Relationship': 'none',
        'RelationshipTo': '',
        'AutoAddTo': 'none'
    }
    a2 = {
        "Name": 'Fancy Name',
        'Type': 'string',
        'Value': 'funny ľščťžýáíé',
        'Parameter': '',
        'Relationship': 'none',
        'RelationshipTo': '',
        'AutoAddTo': 'none'
    }
    attr = []
    attr.append(a1)
    attr.append(a2)
    scribus.setObjectAttributes(attr, txt)
    attr2 = scribus.getObjectAttributes(txt)
    for d in attr2:
        print d
        for key in d.keys():
            print key, d[key]

def main_wrapper(argv):
    """The main_wrapper() function disables redrawing, sets a sensible generic
    status bar message, and optionally sets up the progress bar. It then runs
    the main() function. Once everything finishes it cleans up after the main()
    function, making sure everything is sane before the script terminates."""
    try:
        scribus.statusMessage("Running script...")
        scribus.progressReset()
        main(argv)
    finally:
        # Exit neatly even if the script terminated with an exception,
        # so we leave the progress bar and status bar blank and make sure
        # drawing is enabled.
        if scribus.haveDoc():
            scribus.setRedraw(True)
        scribus.statusMessage("")
        scribus.progressReset()

# This code detects if the script is being run as a script, or imported as a module.
# It only runs main() if being run as a script. This permits you to import your script
# and control it manually for debugging.
if __name__ == '__main__':
    main_wrapper(sys.argv)
attr.py (2,291 bytes)   

jghali

2017-04-01 19:59

administrator   ~0043689

I've applied your patch in r21858. Thanks!

Issue History

Date Modified Username Field Change
2009-06-04 06:25 dmcadmin New Issue
2009-06-05 00:50 christoph_s Assigned To => subik
2009-06-05 00:50 christoph_s Status new => assigned
2009-06-05 00:50 christoph_s Target Version => 1.5.0
2014-07-03 04:51 Kunda Target Version 1.5.0 => 1.6 milestone
2017-03-31 07:54 jurajF File Added: 0001-getObjectAttributes-setObjectAttributes-commands-for.patch
2017-03-31 07:54 jurajF File Added: attr.py
2017-03-31 07:54 jurajF Note Added: 0043685
2017-04-01 19:59 jghali Assigned To subik => jghali
2017-04-01 19:59 jghali Status assigned => resolved
2017-04-01 19:59 jghali Resolution open => fixed
2017-04-01 19:59 jghali Fixed in Version => 1.5.3.svn
2017-04-01 19:59 jghali Note Added: 0043689
2017-04-16 15:17 cbradney Status resolved => closed