View Issue Details

IDProjectCategoryView StatusLast Update
0001628ScribusScripterpublic2005-02-04 18:50
ReporterringercAssigned Tosubik  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Platformx86 LinuxOSFedora CoreOS Version1
Product Version1.3.0cvs 
Fixed in Version1.3.0cvs 
Summary0001628: PATCH: Basic version of Qt property based scripter interface for pageitems
DescriptionThe attached files add a simple Python interface to Qt properties, permitting scripts to use the properties interface to access properties on PageItems.

The changes permit scripts to:
   Get a list of properties supported by a QObject
   Get the name of the C++ type of a property
   Get the value of a property of a QObject
   Set the value of a property of a QObject

The object to operate on may be specified either as a PageItem name, in which case it's looked up, or as a special object passed from another function in the scripter interface. That lays the groundwork for a real OO interface later.

Setting properties is pretty rough. In particular, because many of the setters in pageitem.cpp are incompletely functional (they rely on help from scribusview or other code to work properly), setting some parameters will not work or will only take effect after some action has been performed. When the setters in pageitem are fixed, the scripter will also be fixed with no changes required.

Code is also included to permit the exploration of the widget heirachy. This may be rather handy for extension scripts (a-la macro manager) and for testing and automation. It's currently pretty barebones, but working and will be fleshed out further in time. I plan to limit this to scripts that are run as 'extension scripts' as per the macro manager code.

This patch doesn't provide any sort of nice object oriented interface, nor does it try to create getters/setters or object attributes based on properties. All that stuff can be done trivially in pure Python code using the interfaces provided here, so I'll be writing a higher-level scripter wrapper for that sort of stuff later. Leaving it as individual functions will be both more flexible and simpler.

To apply: apply the attached diff with -p0 in the root of the checked out tree, then put the two new files in the scribus/plugins/scriptplugin directory.
TagsNo tags attached.
Patch

Relationships

child of 0003813 acknowledged Metabug: Scripter 

Activities

2005-02-03 15:48

 

scripter_properties.diff (9,443 bytes)   
Index: scribus/pageitem.h
===================================================================
RCS file: /cvs/Scribus/scribus/pageitem.h,v
retrieving revision 1.26.2.31
diff -u -r1.26.2.31 pageitem.h
--- scribus/pageitem.h	3 Feb 2005 11:16:42 -0000	1.26.2.31
+++ scribus/pageitem.h	3 Feb 2005 16:47:14 -0000
@@ -56,6 +56,9 @@
 	Q_PROPERTY(QString customLineStyle READ customLineStyle WRITE setCustomLineStyle DESIGNABLE false)
 	Q_PROPERTY(int startArrowIndex READ getStartArrowIndex WRITE setStartArrowIndex DESIGNABLE false)
 	Q_PROPERTY(int endArrowIndex READ getEndArrowIndex WRITE setEndArrowIndex DESIGNABLE false)
+	// FIXME Qt doesn't declare the enumerated types defined in the `Qt' namespace as enums,
+	// so we don't get to do any enum conversion on these. Grr. They may need to be redclared
+	// here, but for now we just don't perform any enum translation on them.
 	Q_ENUMS(PenStyle)
 	Q_PROPERTY(PenStyle lineStyle READ lineStyle WRITE setLineStyle DESIGNABLE false)
 	Q_ENUMS(PenCapStyle)
Index: scribus/plugins/scriptplugin/Makefile.am
===================================================================
RCS file: /cvs/Scribus/scribus/plugins/scriptplugin/Makefile.am,v
retrieving revision 1.9.2.6
diff -u -r1.9.2.6 Makefile.am
--- scribus/plugins/scriptplugin/Makefile.am	11 Dec 2004 23:02:53 -0000	1.9.2.6
+++ scribus/plugins/scriptplugin/Makefile.am	3 Feb 2005 16:47:14 -0000
@@ -4,8 +4,8 @@
 INCLUDES = $(LIBFREETYPE_CFLAGS) $(all_includes)
 libscriptplugin_la_LDFLAGS = -version-info 0:0:0
 libscriptplugin_la_METASOURCES = AUTO
-libscriptplugin_la_SOURCES = valuedialog.cpp cmdutil.cpp cmddialog.cpp cmddoc.cpp cmdpage.cpp cmdobj.cpp cmdgetprop.cpp cmdsetprop.cpp cmdtext.cpp cmdmani.cpp cmdcolor.cpp cmdmisc.cpp objprinter.cpp objpdffile.cpp guiapp.cpp conswin.cpp pconsole.cpp scriptplugin.cpp 
-EXTRA_DIST = valuedialog.h cmdvar.h cmdutil.cpp cmdutil.h cmddialog.cpp cmddialog.h cmddoc.cpp cmddoc.h cmdpage.cpp cmdpage.h cmdobj.cpp cmdobj.h cmdgetprop.cpp cmdgetprop.h cmdsetprop.cpp cmdsetprop.h cmdtext.cpp cmdtext.h cmdmani.cpp cmdmani.h cmdcolor.cpp cmdcolor.h cmdmisc.cpp cmdmisc.h objprinter.cpp objprinter.h objpdffile.cpp objpdffile.h guiapp.cpp guiapp.h scriptplugin.cpp scriptplugin.h pconsole.cpp pconsole.h conswin.cpp conswin.h 
+libscriptplugin_la_SOURCES = valuedialog.cpp cmdutil.cpp cmddialog.cpp cmddoc.cpp cmdpage.cpp cmdobj.cpp cmdgetprop.cpp cmdsetprop.cpp cmdtext.cpp cmdmani.cpp cmdcolor.cpp cmdmisc.cpp objprinter.cpp objpdffile.cpp guiapp.cpp conswin.cpp pconsole.cpp cmdgetsetprop.cpp scriptplugin.cpp
+EXTRA_DIST = valuedialog.h cmdvar.h cmdutil.cpp cmdutil.h cmddialog.cpp cmddialog.h cmddoc.cpp cmddoc.h cmdpage.cpp cmdpage.h cmdobj.cpp cmdobj.h cmdgetprop.cpp cmdgetprop.h cmdsetprop.cpp cmdsetprop.h cmdtext.cpp cmdtext.h cmdmani.cpp cmdmani.h cmdcolor.cpp cmdcolor.h cmdmisc.cpp cmdmisc.h objprinter.cpp objprinter.h objpdffile.cpp objpdffile.h guiapp.cpp guiapp.h scriptplugin.cpp scriptplugin.h pconsole.cpp pconsole.h conswin.cpp conswin.h cmdgetsetprop.h cmdgetsetprop.cpp
 KDE_OPTIONS = qtonly
 if COMPILE_DEBUG
  linkflag = 
Index: scribus/plugins/scriptplugin/cmdutil.cpp
===================================================================
RCS file: /cvs/Scribus/scribus/plugins/scriptplugin/cmdutil.cpp,v
retrieving revision 1.6.2.11
diff -u -r1.6.2.11 cmdutil.cpp
--- scribus/plugins/scriptplugin/cmdutil.cpp	2 Feb 2005 19:18:54 -0000	1.6.2.11
+++ scribus/plugins/scriptplugin/cmdutil.cpp	3 Feb 2005 16:47:14 -0000
@@ -156,6 +156,17 @@
 			PyErr_SetString(NoValidObjectError, QString("Can't use empty string for object name when there is no selection"));
 			return NULL;
 		}
+	else
+		return getPageItemByName(name);
+}
+
+PageItem* getPageItemByName(QString name)
+{
+	if (name.length() == 0)
+	{
+		PyErr_SetString(PyExc_ValueError, QString("Cannot accept empty name for pageitem"));
+		return NULL;
+	}
 	for (uint j = 0; j<Carrier->doc->Items.count(); j++)
 	{
 		if (name==Carrier->doc->Items.at(j)->itemName())
Index: scribus/plugins/scriptplugin/cmdutil.h
===================================================================
RCS file: /cvs/Scribus/scribus/plugins/scriptplugin/cmdutil.h,v
retrieving revision 1.4.2.5
diff -u -r1.4.2.5 cmdutil.h
--- scribus/plugins/scriptplugin/cmdutil.h	26 Jan 2005 22:29:12 -0000	1.4.2.5
+++ scribus/plugins/scriptplugin/cmdutil.h	3 Feb 2005 16:47:14 -0000
@@ -21,11 +21,25 @@
 int GetItem(QString Name);
 void ReplaceColor(QString col, QString rep);
 /*!
- * Returns PageItem itself by its unique name - page
- * independent.
- * 03/10/2004 petr vanek
+ * @brief Returns named PageItem, or selection if name '', or exception and NULL if no item.
+ *
+ * Returns a pointer to a PageItem by looking it up by name - page independent.
+ * If `name' is empty, returns selected item.  If the named item is not found,
+ * or `name' is empty and no item is selected, sets an exception and returns
+ * NULL.
+ *
+ * @author 03/10/2004 petr vanek
+ * @author 05/02/02 Craig Ringer
  */
 PageItem* GetUniqueItem(QString name);
+
+/*!
+ * @brief Returns named PageItem, or exception and NULL if not found.
+ *
+ * @author 03/10/2004 Petr Vanek
+ * @author 05/02/02 Craig Ringer
+ */
+PageItem* getPageItemByName(QString name);
 
 // 2004-10-27 Craig Ringer see cmdutil.cpp for description
 bool checkHaveDocument();
Index: scribus/plugins/scriptplugin/cmdvar.h
===================================================================
RCS file: /cvs/Scribus/scribus/plugins/scriptplugin/cmdvar.h,v
retrieving revision 1.6.2.7
diff -u -r1.6.2.7 cmdvar.h
--- scribus/plugins/scriptplugin/cmdvar.h	20 Dec 2004 13:10:00 -0000	1.6.2.7
+++ scribus/plugins/scriptplugin/cmdvar.h	3 Feb 2005 16:47:14 -0000
@@ -19,6 +19,13 @@
 /* Static global Variables */
 extern ScribusApp* Carrier;
 
+// Globals for testing Qt properties and probably other more intresting future
+// uses.
+/** @brief A PyCObject containing a pointer to qApp */
+extern PyObject* wrappedQApp;
+/** @brief A PyCObject containing a pointer to the main window ('Carrier') */
+extern PyObject* wrappedMainWindow;
+
 /* Exceptions */
 /*! Common scribus Exception */
 extern PyObject* ScribusException;
Index: scribus/plugins/scriptplugin/scriptplugin.cpp
===================================================================
RCS file: /cvs/Scribus/scribus/plugins/scriptplugin/scriptplugin.cpp,v
retrieving revision 1.33.2.35
diff -u -r1.33.2.35 scriptplugin.cpp
--- scribus/plugins/scriptplugin/scriptplugin.cpp	2 Feb 2005 23:03:20 -0000	1.33.2.35
+++ scribus/plugins/scriptplugin/scriptplugin.cpp	3 Feb 2005 16:47:15 -0000
@@ -28,6 +28,7 @@
 #include "cmdmani.h"
 #include "cmdcolor.h"
 #include "cmdmisc.h"
+#include "cmdgetsetprop.h"
 #include "scriptplugin.h"
 #include "scriptplugin.moc"
 #include "cmdutil.h"
@@ -49,6 +50,7 @@
  #include "config.h"
 #endif
 
+#include <qapplication.h>
 #include <qmessagebox.h>
 #include <qtextcodec.h>
 #include <qdom.h>
@@ -65,6 +67,10 @@
 PyObject* NotFoundError;
 PyObject* NameExistsError;
 
+// Other extern variables defined in cmdvar.h
+PyObject* wrappedMainWindow;
+PyObject* wrappedQApp;
+
 QString Name()
 {
 	return QObject::tr("S&cripter Manual...");
@@ -778,7 +784,15 @@
 	{const_cast<char*>("unGroupObject"), scribus_ungroupobj, METH_VARARGS, tr(scribus_ungroupobj__doc__)},
 	{const_cast<char*>("unlinkTextFrames"), scribus_unlinktextframes, METH_VARARGS, tr(scribus_unlinktextframes__doc__)},
 	{const_cast<char*>("valueDialog"), scribus_valdialog, METH_VARARGS, tr(scribus_valdialog__doc__)},
-	// end of aliases
+	// Property magic
+	{const_cast<char*>("getPropertyCType"), (PyCFunction)scribus_propertyctype, METH_KEYWORDS, tr(scribus_propertyctype__doc__)},
+	{const_cast<char*>("getPropertyNames"), (PyCFunction)scribus_getpropertynames, METH_KEYWORDS, tr(scribus_getpropertynames__doc__)},
+	{const_cast<char*>("getProperty"), (PyCFunction)scribus_getproperty, METH_KEYWORDS, tr(scribus_getproperty__doc__)},
+	{const_cast<char*>("setProperty"), (PyCFunction)scribus_setproperty, METH_KEYWORDS, tr(scribus_setproperty__doc__)},
+	{const_cast<char*>("getChildren"), (PyCFunction)scribus_getchildren, METH_KEYWORDS, tr(scribus_getchildren__doc__)},
+	{const_cast<char*>("getChild"), (PyCFunction)scribus_getchild, METH_KEYWORDS, tr(scribus_getchild__doc__)},
+
+	// Internal methods - Not for public use
 	{const_cast<char*>("retval"), scribus_retval, METH_VARARGS, const_cast<char*>("Scribus internal.")},
 	{const_cast<char*>("getval"), (PyCFunction)scribus_getval, METH_NOARGS, const_cast<char*>("Scribus internal.")},
 	{NULL, (PyCFunction)(0), 0, NULL} /* sentinel */
@@ -1216,5 +1230,29 @@
 	else
 		PyDict_SetItemString(d, const_cast<char*>("__doc__"), uniDocStr);
 	Py_DECREF(uniDocStr);
+
+	// Wrap up pointers to the the QApp and main window and push them out
+	// to Python.
+	wrappedQApp = wrapQObject(qApp);
+	if (!wrappedQApp)
+	{
+		qDebug("Failed to wrap up QApp");
+		PyErr_Print();
+	}
+	// Push it into the module dict, stealing a ref in the process
+	PyDict_SetItemString(d, const_cast<char*>("qApp"), wrappedQApp);
+	Py_DECREF(wrappedQApp);
+	wrappedQApp = NULL;
+
+	wrappedMainWindow = wrapQObject(Carrier);
+	if (!wrappedMainWindow)
+	{
+		qDebug("Failed to wrap up Carrier");
+		PyErr_Print();
+	}
+	// Push it into the module dict, stealing a ref in the process
+	PyDict_SetItemString(d, const_cast<char*>("mainWindow"), wrappedMainWindow);
+	Py_DECREF(wrappedMainWindow);
+	wrappedMainWindow = NULL;
 }
 
scripter_properties.diff (9,443 bytes)   

2005-02-03 15:49

 

cmdgetsetprop.h (6,646 bytes)

2005-02-03 15:50

 

cmdgetsetprop.cpp (14,228 bytes)

subik

2005-02-03 19:59

manager   ~0003606

craig, is it fro 1.2 or 1.3 or both?

ringerc

2005-02-04 16:54

reporter   ~0003622

Strictly 1.3 only, it depends on the pageitem refactor work going on in 1.3.

ringerc

2005-02-04 18:50

reporter   ~0003630

Subik kindly slogged through and applied this, so we now have working property access in the in-tree 1.3 scripter.

 \o/
  |
 / \

Issue History

Date Modified Username Field Change
2005-02-03 08:55 ringerc New Issue
2005-02-03 08:55 ringerc File Added: cmdgetsetprop.diff
2005-02-03 08:56 ringerc File Added: cmdgetsetprop.cpp
2005-02-03 08:56 ringerc File Added: cmdgetsetprop.h
2005-02-03 15:47 ringerc File Deleted: cmdgetsetprop.diff
2005-02-03 15:47 ringerc File Deleted: cmdgetsetprop.h
2005-02-03 15:47 ringerc File Deleted: cmdgetsetprop.cpp
2005-02-03 15:48 ringerc File Added: scripter_properties.diff
2005-02-03 15:49 ringerc File Added: cmdgetsetprop.h
2005-02-03 15:50 ringerc File Added: cmdgetsetprop.cpp
2005-02-03 15:57 ringerc Description Updated
2005-02-03 19:56 subik Status new => assigned
2005-02-03 19:56 subik Assigned To => subik
2005-02-03 19:59 subik Note Added: 0003606
2005-02-04 16:54 ringerc Note Added: 0003622
2005-02-04 18:48 subik Status assigned => resolved
2005-02-04 18:48 subik Resolution open => fixed
2005-02-04 18:50 ringerc Status resolved => closed
2005-02-04 18:50 ringerc Note Added: 0003630
2005-02-04 18:50 ringerc Fixed in Version => 1.3.0cvs
2006-05-13 21:49 christoph_s Relationship added child of 0003813