https://bugs.scribus.net/view.php?id=15030
Add Note: A week ago I told that I got normal scripts running. Now here's the full patch with all changes from the beginning from me and from william. Patch is attached below. Python part of ticket https://bugs.scribus.net/view.php?id=15131 "0015131: Add fast & precise duplicate to core+scripter " is included, scribus part not. Maybe the naming of duplicateobject_legacy is not final. BR Jonas __..--::??""^^?? Index: CMakeLists.txt =================================================================== --- CMakeLists.txt (Revision 22369) +++ CMakeLists.txt (Arbeitskopie) @@ -749,8 +749,14 @@ #<< JPEG, TIFF #<< PYTHON -#set(PythonLibs_FIND_VERSION 2) -find_package(PythonLibs 2 REQUIRED) +if (WANT_PYTHON3) + #set(PythonLibs_FIND_VERSION 3) + #find_package(PythonInterp 3) + find_package(PythonLibs 3 REQUIRED) +else() + #set(PythonLibs_FIND_VERSION 2) + find_package(PythonLibs 2 REQUIRED) +endif() if (PYTHON_LIBRARY) message("Python Library Found OK") set(HAVE_PYTHON 1) Index: scribus/fonts/ftface.cpp =================================================================== --- scribus/fonts/ftface.cpp (Revision 22369) +++ scribus/fonts/ftface.cpp (Arbeitskopie) @@ -346,7 +346,7 @@ glEncoding.glyphName = adobeGlyphName(charcode); else glEncoding.glyphName = QString(reinterpret_cast<char*>(buf)); - glEncoding.toUnicode = QString().sprintf("%04X", charcode); + glEncoding.toUnicode = QString().sprintf("%04lX", charcode); GList.insert(gindex, glEncoding); charcode = FT_Get_Next_Char(face, charcode, &gindex ); @@ -379,7 +379,7 @@ ScFace::GlyphEncoding glEncoding; glEncoding.charcode = static_cast<ScFace::ucs4_type>(charcode); glEncoding.glyphName = glyphname; - glEncoding.toUnicode = QString().sprintf("%04X", charcode); + glEncoding.toUnicode = QString().sprintf("%04lX", charcode); if ((charcode == 0) && glyphname.startsWith("uni")) { QString uniHexStr = uniGlyphNameToUnicode(glyphname); Index: scribus/fonts/scface_ttf.cpp =================================================================== --- scribus/fonts/scface_ttf.cpp (Revision 22369) +++ scribus/fonts/scface_ttf.cpp (Arbeitskopie) @@ -94,7 +94,7 @@ ScFace::GlyphEncoding glEncoding; glEncoding.charcode = charcode; glEncoding.glyphName = adobeGlyphName(charcode); - glEncoding.toUnicode = QString().sprintf("%04X", charcode); + glEncoding.toUnicode = QString().sprintf("%04lX", charcode); GList.insert(gindex, glEncoding); charcode = FT_Get_Next_Char(face, charcode, &gindex ); } Index: scribus/plugins/scriptplugin/cmdannotations.cpp =================================================================== --- scribus/plugins/scriptplugin/cmdannotations.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/cmdannotations.cpp (Arbeitskopie) @@ -54,8 +54,8 @@ getLinkData(drv, a.Ziel(), a.Action()); const char path[] = "path"; - PyObject *pathkey = PyString_FromString(path); - PyObject *pathvalue = PyString_FromString(a.Extern().toUtf8()); + PyObject *pathkey = Legacy_PyString_FromString(path); + PyObject *pathvalue = Legacy_PyString_FromString(a.Extern().toUtf8()); PyDict_SetItem(drv, pathkey, pathvalue); add_text_to_dict(drv, i); PyObject *rv = Py_BuildValue("(sO)", name3, drv); @@ -64,8 +64,8 @@ else if (atype == Annotation::Link && actype == Annotation::Action_URI) { const char uri[] = "uri"; - PyObject *ukey = PyString_FromString(uri); - PyObject *uval = PyString_FromString(a.Extern().toUtf8()); + PyObject *ukey = Legacy_PyString_FromString(uri); + PyObject *uval = Legacy_PyString_FromString(a.Extern().toUtf8()); PyDict_SetItem(drv, ukey, uval); add_text_to_dict(drv, i); char *name4= const_cast<char*>("Link URI"); @@ -138,12 +138,12 @@ }; if (icon >= 0 && icon < 9) { - PyObject *iconkey = PyString_FromString("icon"); - PyObject *iconvalue = PyString_FromString(icons[icon]); + PyObject *iconkey = Legacy_PyString_FromString("icon"); + PyObject *iconvalue = Legacy_PyString_FromString(icons[icon]); PyDict_SetItem(drv, iconkey, iconvalue); } - PyObject *openkey = PyString_FromString("open"); + PyObject *openkey = Legacy_PyString_FromString("open"); PyObject *open = Py_False; if (a.IsAnOpen()) open = Py_True; @@ -437,7 +437,7 @@ break; } - return PyString_FromString(m_doc->Items->at(i)->itemName().toUtf8()); + return Legacy_PyString_FromString(m_doc->Items->at(i)->itemName().toUtf8()); } @@ -463,7 +463,7 @@ int x, y; const char pagenum[] = "page"; - PyObject *pagekey = PyString_FromString(pagenum); + PyObject *pagekey = Legacy_PyString_FromString(pagenum); PyObject *pagevalue = PyInt_FromLong((long)page); PyDict_SetItem(rv, pagekey, pagevalue); @@ -471,7 +471,7 @@ x = qsl[0].toInt(); const char x2[] = "x"; - PyObject *xkey = PyString_FromString(x2); + PyObject *xkey = Legacy_PyString_FromString(x2); PyObject *xvalue = PyInt_FromLong((long)x); PyDict_SetItem(rv, xkey, xvalue); @@ -478,7 +478,7 @@ int height =ScCore->primaryMainWindow()->doc->pageHeight(); y = height - qsl[1].toInt(); const char y2[] = "y"; - PyObject *ykey = PyString_FromString(y2); + PyObject *ykey = Legacy_PyString_FromString(y2); PyObject *yvalue = PyInt_FromLong((long)y); PyDict_SetItem(rv, ykey, yvalue); @@ -519,9 +519,9 @@ static void add_text_to_dict(PyObject *drv, PageItem * i) { const char text[] = "text"; - PyObject *textkey = PyString_FromString(text); + PyObject *textkey = Legacy_PyString_FromString(text); QString txt = i->itemText.text(0, i->itemText.length()); - PyObject *textvalue = PyString_FromString(txt.toUtf8()); + PyObject *textvalue = Legacy_PyString_FromString(txt.toUtf8()); PyDict_SetItem(drv, textkey, textvalue); Annotation &a = i->annotation(); @@ -530,8 +530,8 @@ if (actype == Annotation::Action_JavaScript) { const char text[] = "javascript"; - PyObject *jskey = PyString_FromString(text); - PyObject *jsvalue = PyString_FromString(i->annotation().Action().toUtf8()); + PyObject *jskey = Legacy_PyString_FromString(text); + PyObject *jsvalue = Legacy_PyString_FromString(i->annotation().Action().toUtf8()); PyDict_SetItem(drv, jskey, jsvalue); } @@ -543,10 +543,10 @@ "Named", NULL }; const char action[] = "action"; - PyObject *akey = PyString_FromString(action); + PyObject *akey = Legacy_PyString_FromString(action); if (actype > 10) actype = 6; - PyObject *avalue = PyString_FromString(aactions[actype]); + PyObject *avalue = Legacy_PyString_FromString(aactions[actype]); PyDict_SetItem(drv, akey, avalue); int atype = a.Type(); @@ -553,7 +553,7 @@ if (atype == Annotation::Checkbox || atype == Annotation::RadioButton) { const char checked[] = "checked"; - PyObject *checkkey = PyString_FromString(checked); + PyObject *checkkey = Legacy_PyString_FromString(checked); PyObject *checkvalue = Py_False; if (a.IsChk()) checkvalue = Py_True; @@ -563,7 +563,7 @@ if (atype == Annotation::Combobox || atype == Annotation::Listbox) { const char editable[] = "editable"; - PyObject *ekey = PyString_FromString(editable); + PyObject *ekey = Legacy_PyString_FromString(editable); PyObject *edit = Py_False; int result = Annotation::Flag_Edit & a.Flag(); Index: scribus/plugins/scriptplugin/cmdcell.cpp =================================================================== --- scribus/plugins/scriptplugin/cmdcell.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/cmdcell.cpp (Arbeitskopie) @@ -61,7 +61,7 @@ PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData()); return NULL; } - return PyString_FromString(table->cellAt(row, column).styleName().toUtf8()); + return Legacy_PyString_FromString(table->cellAt(row, column).styleName().toUtf8()); } PyObject *scribus_setcellstyle(PyObject* /* self */, PyObject* args) @@ -153,7 +153,7 @@ PyErr_SetString(PyExc_ValueError, QObject::tr("The cell %1,%2 does not exist in table", "python error").arg(row).arg(column).toLocal8Bit().constData()); return NULL; } - return PyString_FromString(table->cellAt(row, column).fillColor().toUtf8()); + return Legacy_PyString_FromString(table->cellAt(row, column).fillColor().toUtf8()); } PyObject *scribus_setcellfillcolor(PyObject* /* self */, PyObject* args) Index: scribus/plugins/scriptplugin/cmdcolor.cpp =================================================================== --- scribus/plugins/scriptplugin/cmdcolor.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/cmdcolor.cpp (Arbeitskopie) @@ -22,7 +22,7 @@ l = PyList_New(edc.count()); for (it = edc.begin(); it != edc.end(); ++it) { - PyList_SetItem(l, cc, PyString_FromString(it.key().toUtf8())); + PyList_SetItem(l, cc, Legacy_PyString_FromString(it.key().toUtf8())); cc++; } return l; Index: scribus/plugins/scriptplugin/cmddialog.cpp =================================================================== --- scribus/plugins/scriptplugin/cmddialog.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/cmddialog.cpp (Arbeitskopie) @@ -68,7 +68,7 @@ ); // QApplication::restoreOverrideCursor(); // FIXME: filename return unicode OK? - return PyString_FromString(fName.toUtf8()); + return Legacy_PyString_FromString(fName.toUtf8()); } PyObject *scribus_messdia(PyObject* /* self */, PyObject* args, PyObject* kw) @@ -120,7 +120,7 @@ QLineEdit::Normal, QString::fromUtf8(value)); // QApplication::restoreOverrideCursor(); - return PyString_FromString(txt.toUtf8()); + return Legacy_PyString_FromString(txt.toUtf8()); } PyObject *scribus_newstyledialog(PyObject*, PyObject* args) @@ -143,7 +143,7 @@ st.create(p); d->redefineStyles(st, false); ScCore->primaryMainWindow()->styleMgr()->setDoc(d); - return PyString_FromString(s.toUtf8()); + return Legacy_PyString_FromString(s.toUtf8()); } else Py_RETURN_NONE; Index: scribus/plugins/scriptplugin/cmddoc.cpp =================================================================== --- scribus/plugins/scriptplugin/cmddoc.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/cmddoc.cpp (Arbeitskopie) @@ -197,9 +197,9 @@ return NULL; if (! ScCore->primaryMainWindow()->doc->hasName) { - return PyString_FromString(""); + return Legacy_PyString_FromString(""); } - return PyString_FromString(ScCore->primaryMainWindow()->doc->DocName.toUtf8()); + return Legacy_PyString_FromString(ScCore->primaryMainWindow()->doc->DocName.toUtf8()); } PyObject *scribus_savedocas(PyObject* /* self */, PyObject* args) @@ -318,7 +318,7 @@ int n = 0; for ( ; it != itEnd; ++it ) { - PyList_SET_ITEM(names, n++, PyString_FromString(it.key().toUtf8().data()) ); + PyList_SET_ITEM(names, n++, Legacy_PyString_FromString(it.key().toUtf8().data()) ); } return names; } @@ -403,7 +403,7 @@ PyErr_SetString(PyExc_IndexError, QObject::tr("Page number out of range: '%1'.","python error").arg(e+1).toLocal8Bit().constData()); return NULL; } - return PyString_FromString(ScCore->primaryMainWindow()->doc->DocPages.at(e)->MPageNam.toUtf8()); + return Legacy_PyString_FromString(ScCore->primaryMainWindow()->doc->DocPages.at(e)->MPageNam.toUtf8()); } PyObject* scribus_applymasterpage(PyObject* /* self */, PyObject* args) Index: scribus/plugins/scriptplugin/cmdgetprop.cpp =================================================================== --- scribus/plugins/scriptplugin/cmdgetprop.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/cmdgetprop.cpp (Arbeitskopie) @@ -44,7 +44,7 @@ result = "Multiple"; } - return PyString_FromString(result.toUtf8()); + return Legacy_PyString_FromString(result.toUtf8()); } PyObject *scribus_getfillcolor(PyObject* /* self */, PyObject* args) @@ -55,7 +55,7 @@ if(!checkHaveDocument()) return NULL; PageItem *i = GetUniqueItem(QString::fromUtf8(Name)); - return i != NULL ? PyString_FromString(i->fillColor().toUtf8()) : NULL; + return i != NULL ? Legacy_PyString_FromString(i->fillColor().toUtf8()) : NULL; } PyObject *scribus_getfilltrans(PyObject* /* self */, PyObject* args) @@ -91,7 +91,7 @@ it = GetUniqueItem(QString::fromUtf8(Name)); if (it == NULL) return NULL; - return PyString_FromString(it->customLineStyle().toUtf8()); + return Legacy_PyString_FromString(it->customLineStyle().toUtf8()); } PyObject *scribus_getlinecolor(PyObject* /* self */, PyObject* args) @@ -110,11 +110,11 @@ for (int b = 0; b < it->itemText.length(); ++b) { if (it->itemText.selected(b)) - return PyString_FromString(it->itemText.charStyle(b).fillColor().toUtf8()); + return Legacy_PyString_FromString(it->itemText.charStyle(b).fillColor().toUtf8()); } } else - return PyString_FromString(it->lineColor().toUtf8()); + return Legacy_PyString_FromString(it->lineColor().toUtf8()); PyErr_SetString(NotFoundError, QObject::tr("Color not found - python error", "python error").toLocal8Bit().constData()); return NULL; } @@ -250,7 +250,7 @@ if(!checkHaveDocument()) return NULL; PageItem *i = GetUniqueItem(QString::fromUtf8(Name)); - return i != NULL ? PyString_FromString(i->Pfile.toUtf8()) : NULL; + return i != NULL ? Legacy_PyString_FromString(i->Pfile.toUtf8()) : NULL; } PyObject *scribus_getposi(PyObject* /* self */, PyObject* args) @@ -338,13 +338,13 @@ { if (ScCore->primaryMainWindow()->doc->Items->at(lam)->itemType() == typ) { - PyList_SetItem(l, counter2, PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(lam)->itemName().toUtf8())); + PyList_SetItem(l, counter2, Legacy_PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(lam)->itemName().toUtf8())); counter2++; } } else { - PyList_SetItem(l, counter2, PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(lam)->itemName().toUtf8())); + PyList_SetItem(l, counter2, Legacy_PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(lam)->itemName().toUtf8())); counter2++; } } Index: scribus/plugins/scriptplugin/cmdgetsetprop.cpp =================================================================== --- scribus/plugins/scriptplugin/cmdgetsetprop.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/cmdgetsetprop.cpp (Arbeitskopie) @@ -88,7 +88,7 @@ PyErr_SetString(PyExc_KeyError, QObject::tr("Property not found").toLocal8Bit().constData()); return NULL; } - return PyString_FromString(type); + return Legacy_PyString_FromString(type); } PyObject* convert_QStringList_to_PyListObject(QStringList& origlist) @@ -98,7 +98,7 @@ return NULL; for ( QStringList::Iterator it = origlist.begin(); it != origlist.end(); ++it ) - if (PyList_Append(resultList, PyString_FromString((*it).toUtf8().data())) == -1) + if (PyList_Append(resultList, Legacy_PyString_FromString((*it).toUtf8().data())) == -1) return NULL; return resultList; @@ -289,9 +289,9 @@ resultobj = PyBool_FromLong(prop.toBool()); // STRING TYPES else if (prop.type() == QVariant::ByteArray) - resultobj = PyString_FromString(prop.toByteArray().data()); + resultobj = Legacy_PyString_FromString(prop.toByteArray().data()); else if (prop.type() == QVariant::String) - resultobj = PyString_FromString(prop.toString().toUtf8().data()); + resultobj = Legacy_PyString_FromString(prop.toString().toUtf8().data()); // HIGHER ORDER TYPES else if (prop.type() == QVariant::Point) { Index: scribus/plugins/scriptplugin/cmdmani.cpp =================================================================== --- scribus/plugins/scriptplugin/cmdmani.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/cmdmani.cpp (Arbeitskopie) @@ -406,7 +406,7 @@ finalSelection=0; delete tempSelection; - return (group ? PyString_FromString(group->itemName().toUtf8()) : NULL); + return (group ? Legacy_PyString_FromString(group->itemName().toUtf8()) : NULL); } PyObject *scribus_ungroupobj(PyObject* /* self */, PyObject* args) @@ -464,10 +464,10 @@ if(!checkHaveDocument()) return NULL; if ((i < static_cast<int>(ScCore->primaryMainWindow()->doc->m_Selection->count())) && (i > -1)) - return PyString_FromString(ScCore->primaryMainWindow()->doc->m_Selection->itemAt(i)->itemName().toUtf8()); + return Legacy_PyString_FromString(ScCore->primaryMainWindow()->doc->m_Selection->itemAt(i)->itemName().toUtf8()); else // FIXME: Should probably return None if no selection? - return PyString_FromString(""); + return Legacy_PyString_FromString(""); } PyObject *scribus_selcount(PyObject* /* self */) Index: scribus/plugins/scriptplugin/cmdmisc.cpp =================================================================== --- scribus/plugins/scriptplugin/cmdmisc.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/cmdmisc.cpp (Arbeitskopie) @@ -49,7 +49,7 @@ { if (it.current().usable()) { - PyList_SetItem(l, cc, PyString_FromString(it.currentKey().toUtf8())); + PyList_SetItem(l, cc, Legacy_PyString_FromString(it.currentKey().toUtf8())); cc++; } } @@ -128,7 +128,7 @@ int bufferSize = buffer.size(); buffer.close(); // Now make a Python string from the data we generated - PyObject* stringPython = PyString_FromStringAndSize(buffer_string,bufferSize); + PyObject* stringPython = Legacy_PyBytes_FromStringAndSize(buffer_string,bufferSize); // Return even if the result is NULL (error) since an exception will have been // set in that case. return stringPython; @@ -157,7 +157,7 @@ PyObject *l; l = PyList_New(ScCore->primaryMainWindow()->doc->Layers.count()); for (int lam=0; lam < ScCore->primaryMainWindow()->doc->Layers.count(); lam++) - PyList_SetItem(l, lam, PyString_FromString(ScCore->primaryMainWindow()->doc->Layers[lam].Name.toUtf8())); + PyList_SetItem(l, lam, Legacy_PyString_FromString(ScCore->primaryMainWindow()->doc->Layers[lam].Name.toUtf8())); return l; } @@ -190,7 +190,7 @@ { if(!checkHaveDocument()) return NULL; - return PyString_FromString(ScCore->primaryMainWindow()->doc->activeLayerName().toUtf8()); + return Legacy_PyString_FromString(ScCore->primaryMainWindow()->doc->activeLayerName().toUtf8()); } PyObject *scribus_senttolayer(PyObject* /* self */, PyObject* args) @@ -761,7 +761,7 @@ PyObject *scribus_getlanguage(PyObject* /* self */) { - return PyString_FromString(ScCore->getGuiLanguage().toUtf8()); + return Legacy_PyString_FromString(ScCore->getGuiLanguage().toUtf8()); } /*! 04.01.2007 : Joachim Neu : Moves item selection to front. */ Index: scribus/third_party/fparser/fparser.cc =================================================================== --- scribus/third_party/fparser/fparser.cc (Revision 22369) +++ scribus/third_party/fparser/fparser.cc (Arbeitskopie) @@ -1625,9 +1625,11 @@ { default: case '+': - if(!is_unary) data->ByteCode.push_back(cAdd); break; + if(!is_unary) data->ByteCode.push_back(cAdd); + break; case '-': - data->ByteCode.push_back(is_unary ? cNeg : cSub); break; + data->ByteCode.push_back(is_unary ? cNeg : cSub); + break; } } --StackPtr; Index: scribus/plugins/scriptplugin/objimageexport.cpp =================================================================== --- scribus/plugins/scriptplugin/objimageexport.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/objimageexport.cpp (Arbeitskopie) @@ -33,7 +33,7 @@ Py_XDECREF(self->name); Py_XDECREF(self->type); Py_XDECREF(self->allTypes); - self->ob_type->tp_free((PyObject *)self); + Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * ImageExport_new(PyTypeObject *type, PyObject * /*args*/, PyObject * /*kwds*/) @@ -44,8 +44,8 @@ ImageExport *self; self = (ImageExport *)type->tp_alloc(type, 0); if (self != NULL) { - self->name = PyString_FromString("ImageExport.png"); - self->type = PyString_FromString("PNG"); + self->name = Legacy_PyString_FromString("ImageExport.png"); + self->type = Legacy_PyString_FromString("PNG"); self->allTypes = PyList_New(0); self->dpi = 72; self->scale = 100; @@ -119,7 +119,7 @@ l = PyList_New(list.count()); for (QList<QByteArray>::Iterator it = list.begin(); it != list.end(); ++it) { - PyList_SetItem(l, pos, PyString_FromString(QString((*it)).toLatin1().constData())); + PyList_SetItem(l, pos, Legacy_PyString_FromString(QString((*it)).toLatin1().constData())); ++pos; } return l; @@ -204,10 +204,15 @@ PyTypeObject ImageExport_Type = { PyObject_HEAD_INIT(NULL) // PyObject_VAR_HEAD +#if !IS_PY3K 0, +#endif const_cast<char*>("scribus.ImageExport"), // char *tp_name; /* For printing, in format "<module>.<name>" */ sizeof(ImageExport), // int tp_basicsize, /* For allocation */ 0, // int tp_itemsize; /* For allocation */ + + /* Methods to implement standard operations */ + (destructor) ImageExport_dealloc, // destructor tp_dealloc; 0, // printfunc tp_print; 0, // getattrfunc tp_getattr; @@ -214,23 +219,54 @@ 0, // setattrfunc tp_setattr; 0, // cmpfunc tp_compare; 0, // reprfunc tp_repr; + + /* Method suites for standard classes */ + 0, // PyNumberMethods *tp_as_number; 0, // PySequenceMethods *tp_as_sequence; 0, // PyMappingMethods *tp_as_mapping; + + /* More standard operations (here for binary compatibility) */ + 0, // hashfunc tp_hash; 0, // ternaryfunc tp_call; 0, // reprfunc tp_str; 0, // getattrofunc tp_getattro; 0, // setattrofunc tp_setattro; + + /* Functions to access object as input/output buffer */ + 0, // PyBufferProcs *tp_as_buffer; + + /* Flags to define presence of optional/expanded features */ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, // long tp_flags; + imgexp__doc__, // char *tp_doc; /* Documentation string */ + + /* traverse all accessible objects, assigned in 2.0 */ + 0, // traverseproc tp_traverse; + + /* delete references to contained objects */ + 0, // inquiry tp_clear; + + /* rich comparisons, assigned in 2.1 */ + 0, // richcmpfunc tp_richcompare; + + /* weak reference enabler */ + 0, // long tp_weaklistoffset; + + /* Iterators, added in 2.2 */ + 0, // getiterfunc tp_iter; 0, // iternextfunc tp_iternext; + + /* Attribute descriptor and subclassing stuff */ + ImageExport_methods, // struct PyMethodDef *tp_methods; ImageExport_members, // struct PyMemberDef *tp_members; ImageExport_getseters, // struct PyGetSetDef *tp_getset; @@ -251,6 +287,15 @@ 0, // PyObject *tp_weaklist; 0, // destructor tp_del; +#if IS_PY3K || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6) + /* Type attribute cache version tag. Added in version 2.6 */ + 0, // unsigned int tp_version_tag; +#endif + +#if IS_PY3K + 0, // destructor tp_finalize; +#endif + #ifdef COUNT_ALLOCS /* these must be last and never explicitly initialized */ // int tp_allocs; Index: scribus/plugins/scriptplugin/objpdffile.cpp =================================================================== --- scribus/plugins/scriptplugin/objpdffile.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/objpdffile.cpp (Arbeitskopie) @@ -135,7 +135,7 @@ Py_XDECREF(self->info); Py_XDECREF(self->rotateDeg); Py_XDECREF(self->openAction); - self->ob_type->tp_free((PyObject *)self); + Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * PDFfile_new(PyTypeObject *type, PyObject * /*args*/, PyObject * /*kwds*/) @@ -150,7 +150,7 @@ self = (PDFfile *)type->tp_alloc(type, 0); if (self) { // set file attribute - self->file = PyString_FromString(""); + self->file = Legacy_PyString_FromString(""); if (!self->file) { Py_DECREF(self); return NULL; @@ -239,13 +239,13 @@ return NULL; } // set owner attribute - self->owner = PyString_FromString(""); + self->owner = Legacy_PyString_FromString(""); if (!self->owner){ Py_DECREF(self); return NULL; } // set user attribute - self->user = PyString_FromString(""); + self->user = Legacy_PyString_FromString(""); if (!self->user){ Py_DECREF(self); return NULL; @@ -269,22 +269,22 @@ self->intents = 0; // int - 0 - ? self->intenti = 0; // int - 0 - ? self->noembicc = 0; // bool - self->solidpr = PyString_FromString(""); + self->solidpr = Legacy_PyString_FromString(""); if (!self->solidpr){ Py_DECREF(self); return NULL; } - self->imagepr = PyString_FromString(""); + self->imagepr = Legacy_PyString_FromString(""); if (!self->imagepr){ Py_DECREF(self); return NULL; } - self->printprofc = PyString_FromString(""); + self->printprofc = Legacy_PyString_FromString(""); if (!self->printprofc){ Py_DECREF(self); return NULL; } - self->info = PyString_FromString(""); + self->info = Legacy_PyString_FromString(""); if (!self->info){ Py_DECREF(self); return NULL; @@ -313,7 +313,7 @@ self->hideToolBar = 0; self->hideMenuBar = 0; self->fitWindow = 0; - self->openAction = PyString_FromString(""); + self->openAction = Legacy_PyString_FromString(""); if (!self->openAction){ Py_DECREF(self); return NULL; @@ -339,7 +339,7 @@ tf = fi.path()+"/"+fi.baseName()+".pdf"; } PyObject *file = NULL; - file = PyString_FromString(tf.toLatin1()); + file = Legacy_PyString_FromString(tf.toUtf8()); if (file){ Py_DECREF(self->file); self->file = file; @@ -375,7 +375,7 @@ { QString fontName = tmpEm.at(i); PyObject *tmp= NULL; - tmp = PyString_FromString(fontName.toLatin1()); + tmp = Legacy_PyString_FromString(fontName.toUtf8()); if (tmp) { PyList_Append(self->fonts, tmp); // do i need Py_DECREF(tmp) here? @@ -401,7 +401,7 @@ for (int fe = 0; fe < pdfOptions.SubsetList.count(); ++fe) { PyObject *tmp= NULL; - tmp = PyString_FromString(pdfOptions.SubsetList[fe].toLatin1().data()); + tmp = Legacy_PyString_FromString(pdfOptions.SubsetList[fe].toUtf8()); if (tmp) { PyList_Append(self->subsetList, tmp); Py_DECREF(tmp); @@ -536,7 +536,7 @@ QMap<QString,LPIData>::Iterator it = pdfOptions.LPISettings.begin(); while (it != pdfOptions.LPISettings.end()) { PyObject *tmp; - tmp = Py_BuildValue(const_cast<char*>("[siii]"), it.key().toLatin1().constData(), it.value().Frequency, it.value().Angle, it.value().SpotFunc); + tmp = Py_BuildValue(const_cast<char*>("[siii]"), it.key().toUtf8().constData(), it.value().Frequency, it.value().Angle, it.value().SpotFunc); if (!tmp) { PyErr_SetString(PyExc_SystemError, "Can not initialize 'lpival' attribute"); return -1; @@ -549,7 +549,7 @@ self->lpival = lpival; // set owner's password PyObject *owner = NULL; - owner = PyString_FromString(pdfOptions.PassOwner.toLatin1()); + owner = Legacy_PyString_FromString(pdfOptions.PassOwner.toUtf8()); if (owner){ Py_DECREF(self->owner); self->owner = owner; @@ -559,7 +559,7 @@ } // set user'a password PyObject *user = NULL; - user = PyString_FromString(pdfOptions.PassUser.toLatin1()); + user = Legacy_PyString_FromString(pdfOptions.PassUser.toUtf8()); if (user){ Py_DECREF(self->user); self->user = user; @@ -589,7 +589,7 @@ if (!ScCore->InputProfiles.contains(tp)) tp = currentDoc->cmsSettings().DefaultSolidColorRGBProfile; PyObject *solidpr = NULL; - solidpr = PyString_FromString(tp.toLatin1()); + solidpr = Legacy_PyString_FromString(tp.toUtf8()); if (solidpr){ Py_DECREF(self->solidpr); self->solidpr = solidpr; @@ -601,7 +601,7 @@ if (!ScCore->InputProfiles.contains(tp2)) tp2 = currentDoc->cmsSettings().DefaultSolidColorRGBProfile; PyObject *imagepr = NULL; - imagepr = PyString_FromString(tp2.toLatin1()); + imagepr = Legacy_PyString_FromString(tp2.toUtf8()); if (imagepr){ Py_DECREF(self->imagepr); self->imagepr = imagepr; @@ -613,7 +613,7 @@ if (!ScCore->PDFXProfiles.contains(tp3)) tp3 = currentDoc->cmsSettings().DefaultPrinterProfile; PyObject *printprofc = NULL; - printprofc = PyString_FromString(tp3.toLatin1()); + printprofc = Legacy_PyString_FromString(tp3.toUtf8()); if (printprofc){ Py_DECREF(self->printprofc); self->printprofc = printprofc; @@ -623,7 +623,7 @@ } QString tinfo = pdfOptions.Info; PyObject *info = NULL; - info = PyString_FromString(tinfo.toLatin1()); + info = Legacy_PyString_FromString(tinfo.toUtf8()); if (info){ Py_DECREF(self->info); self->info = info; @@ -661,7 +661,7 @@ self->fitWindow = pdfOptions.fitWindow; // bool PyObject *openAction = NULL; - openAction = PyString_FromString(pdfOptions.openAction.toLatin1().data()); + openAction = Legacy_PyString_FromString(pdfOptions.openAction.toUtf8().data()); if (openAction){ Py_DECREF(self->openAction); self->openAction = openAction; @@ -1528,7 +1528,7 @@ fn = "Cannot write the File: " + fn; if (!errorMessage.isEmpty()) fn += QString("\n%1").arg(errorMessage); - PyErr_SetString(PyExc_SystemError, fn.toLatin1()); + PyErr_SetString(PyExc_SystemError, fn.toUtf8()); } if (self->useDocBleeds) @@ -1546,7 +1546,9 @@ PyTypeObject PDFfile_Type = { PyObject_HEAD_INIT(NULL) // PyObject_VAR_HEAD - 0, // +#if !IS_PY3K + 0, +#endif const_cast<char*>("scribus.PDFfile"), // char *tp_name; /* For printing, in format "<module>.<name>" */ sizeof(PDFfile), // int tp_basicsize, /* For allocation */ 0, // int tp_itemsize; /* For allocation */ @@ -1575,9 +1577,11 @@ 0, // setattrofunc tp_setattro; /* Functions to access object as input/output buffer */ + 0, // PyBufferProcs *tp_as_buffer; /* Flags to define presence of optional/expanded features */ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, // long tp_flags; pdffile__doc__, // char *tp_doc; /* Documentation string */ @@ -1622,6 +1626,15 @@ 0, // PyObject *tp_weaklist; 0, // destructor tp_del; +#if IS_PY3K || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6) + /* Type attribute cache version tag. Added in version 2.6 */ + 0, // unsigned int tp_version_tag; +#endif + +#if IS_PY3K + 0, // destructor tp_finalize; +#endif + #ifdef COUNT_ALLOCS /* these must be last and never explicitly initialized */ // int tp_allocs; Index: scribus/plugins/scriptplugin/objprinter.cpp =================================================================== --- scribus/plugins/scriptplugin/objprinter.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/objprinter.cpp (Arbeitskopie) @@ -59,7 +59,7 @@ Py_XDECREF(self->cmd); Py_XDECREF(self->pages); Py_XDECREF(self->separation); - self->ob_type->tp_free((PyObject *)self); + Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * Printer_new(PyTypeObject *type, PyObject * /*args*/, PyObject * /*kwds*/) @@ -79,19 +79,19 @@ return NULL; } // set printer attribute - self->printer = PyString_FromString(""); + self->printer = Legacy_PyString_FromString(""); if (self->printer == NULL){ Py_DECREF(self); return NULL; } // set file attribute - self->file = PyString_FromString(""); + self->file = Legacy_PyString_FromString(""); if (self->file == NULL){ Py_DECREF(self); return NULL; } // set cmd attribute - self->cmd = PyString_FromString(""); + self->cmd = Legacy_PyString_FromString(""); if (self->cmd == NULL){ Py_DECREF(self); return NULL; @@ -103,7 +103,7 @@ return NULL; } // set separation attribute - self->separation = PyString_FromString("No"); + self->separation = Legacy_PyString_FromString("No"); if (self->separation == NULL){ Py_DECREF(self); return NULL; @@ -144,18 +144,18 @@ QString prn = printers[i]; if (prn.isEmpty()) continue; - PyObject *tmppr = PyString_FromString(prn.toLocal8Bit().constData()); + PyObject *tmppr = Legacy_PyString_FromString(prn.toLocal8Bit().constData()); if (tmppr){ PyList_Append(self->allPrinters, tmppr); Py_DECREF(tmppr); } } - PyObject *tmp2 = PyString_FromString("File"); + PyObject *tmp2 = Legacy_PyString_FromString("File"); PyList_Append(self->allPrinters, tmp2); Py_DECREF(tmp2); // as defaut set to print into file PyObject *printer = NULL; - printer = PyString_FromString("File"); + printer = Legacy_PyString_FromString("File"); if (printer){ Py_DECREF(self->printer); self->printer = printer; @@ -167,7 +167,7 @@ tf = fi.path()+"/"+fi.baseName()+".pdf"; } PyObject *file = NULL; - file = PyString_FromString(tf.toLatin1()); + file = Legacy_PyString_FromString(tf.toLatin1()); if (file){ Py_DECREF(self->file); self->file = file; @@ -177,7 +177,7 @@ } // alternative printer commands default to "" PyObject *cmd = NULL; - cmd = PyString_FromString(""); + cmd = Legacy_PyString_FromString(""); if (cmd){ Py_DECREF(self->cmd); self->cmd = cmd; @@ -199,7 +199,7 @@ } // do not print separation PyObject *separation = NULL; - separation = PyString_FromString("No"); + separation = Legacy_PyString_FromString("No"); if (separation){ Py_DECREF(self->separation); self->separation = separation; @@ -514,7 +514,9 @@ PyTypeObject Printer_Type = { PyObject_HEAD_INIT(NULL) // PyObject_VAR_HEAD - 0, // +#if !IS_PY3K + 0, +#endif const_cast<char*>("scribus.Printer"), // char *tp_name; /* For printing, in format "<module>.<name>" */ sizeof(Printer), // int tp_basicsize, /* For allocation */ 0, // int tp_itemsize; /* For allocation */ @@ -543,9 +545,11 @@ 0, // setattrofunc tp_setattro; /* Functions to access object as input/output buffer */ + 0, // PyBufferProcs *tp_as_buffer; /* Flags to define presence of optional/expanded features */ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, // long tp_flags; printer__doc__, // char *tp_doc; /* Documentation string */ @@ -590,6 +594,15 @@ 0, // PyObject *tp_weaklist; 0, // destructor tp_del; +#if IS_PY3K || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6) + /* Type attribute cache version tag. Added in version 2.6 */ + 0, // unsigned int tp_version_tag; +#endif + +#if IS_PY3K + 0, // destructor tp_finalize; +#endif + #ifdef COUNT_ALLOCS /* these must be last and never explicitly initialized */ // int tp_allocs; Index: scribus/plugins/scriptplugin/scriptercore.cpp =================================================================== --- scribus/plugins/scriptplugin/scriptercore.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/scriptercore.cpp (Arbeitskopie) @@ -73,6 +73,10 @@ QObject::connect(ScQApp, SIGNAL(appStarted()) , this, SLOT(runStartupScript()) ); QObject::connect(ScQApp, SIGNAL(appStarted()) , this, SLOT(slotRunPythonScript()) ); + + + num_main_interpreters = 0; + num_side_interpreters = 0; } ScripterCore::~ScripterCore() @@ -240,6 +244,7 @@ if (ScCore->primaryMainWindow()->scriptIsRunning()) return; disableMainWindowMenu(); + emit starting_script(inMainInterpreter); PyThreadState *state = NULL; QFileInfo fi(fileName); @@ -259,7 +264,7 @@ global_state = PyThreadState_Get(); state = Py_NewInterpreter(); // Init the scripter module in the sub-interpreter - initscribus(ScCore->primaryMainWindow()); + initscribus(ScCore->primaryMainWindow(), true); } // Make sure sys.argv[0] is the path to the script @@ -266,18 +271,35 @@ arguments.prepend(na.data()); //convert arguments (QListString) to char** for Python bridge /* typically arguments == ['path/to/script.py','--argument1','valueforarg1','--flag']*/ +#if IS_PY3K + wchar_t **comm = new wchar_t*[arguments.size()]; +#else char **comm = new char*[arguments.size()]; +#endif for (int i = 0; i < arguments.size(); i++) { QByteArray localStr = arguments.at(i).toLocal8Bit(); +#if IS_PY3K + char * tmp = new char[localStr.size() + 1]; + tmp[localStr.size()] = 0; + strncpy(tmp, localStr.data(), localStr.size()); + comm[i] = Py_DecodeLocale(tmp, NULL); + delete[] tmp; +#else comm[i] = new char[localStr.size() + 1]; //+1 to allow adding '\0'. may be useless, don't know how to check. comm[i][localStr.size()] = 0; strncpy(comm[i], localStr.data(), localStr.size()); +#endif } PySys_SetArgv(arguments.size(), comm); - for (int i = 0; i < arguments.size(); i++) + for (int i = 0; i < arguments.size(); i++) { +#if IS_PY3K + PyMem_RawFree(comm[i]); +#else delete[] comm[i]; +#endif + } delete[] comm; // call python script @@ -294,7 +316,11 @@ // Build the Python code to run the script //QString cm = QString("from __future__ import division\n"); removed due #5252 PV QString cm = QString("import sys\n"); +#if IS_PY3K + cm += QString("import io\n"); +#else cm += QString("import cStringIO\n"); +#endif /* Implementation of the help() in pydoc.py reads some OS variables * for output settings. I use ugly hack to stop freezing calling help() * in script. pv. */ @@ -302,7 +328,11 @@ cm += QString("sys.path[0] = \"%1\"\n").arg(escapedAbsPath); // Replace sys.stdin with a dummy StringIO that always returns // "" for read +#if IS_PY3K + cm += QString("sys.stdin = io.StringIO()\n"); +#else cm += QString("sys.stdin = cStringIO.StringIO()\n"); +#endif // tell the script if it's running in the main intepreter or a subinterpreter cm += QString("import scribus\n"); if (inMainInterpreter) @@ -310,7 +340,11 @@ else cm+= QString("scribus.mainInterpreter = False\n"); cm += QString("try:\n"); +#if IS_PY3K + cm += QString(" exec(open(\"%1\").read())\n").arg(escapedFileName); +#else cm += QString(" execfile(\"%1\")\n").arg(escapedFileName); +#endif cm += QString("except SystemExit:\n"); cm += QString(" pass\n"); // Capture the text of any other exception that's raised by the interpreter @@ -344,7 +378,11 @@ } else if (ScCore->usingGUI()) { +#if IS_PY3K + QString errorMsg = PyUnicode_AsUTF8(errorMsgPyStr); +#else QString errorMsg = PyString_AsString(errorMsgPyStr); +#endif // Display a dialog to the user with the exception QClipboard *cp = QApplication::clipboard(); cp->setText(errorMsg); @@ -372,7 +410,8 @@ qApp->restoreOverrideCursor(); ScCore->primaryMainWindow()->setScriptRunning(false); } - + + emit finishing_script(inMainInterpreter); enableMainWindowMenu(); } @@ -392,6 +431,7 @@ if (ScCore->primaryMainWindow()->scriptIsRunning()) return; disableMainWindowMenu(); + emit starting_script(true); ScCore->primaryMainWindow()->propertiesPalette->unsetDoc(); ScCore->primaryMainWindow()->textPalette->unsetDoc(); @@ -402,7 +442,7 @@ cm = "# -*- coding: utf8 -*- \n"; if (PyThreadState_Get() != NULL) { - initscribus(ScCore->primaryMainWindow()); + initscribus(ScCore->primaryMainWindow(), false); /* HACK: following loop handles all input line by line. It *should* use I.C. because of docstrings etc. I.I. cannot handle docstrings right. @@ -411,8 +451,14 @@ works fine in plain Python. Not here. WTF? */ cm += ( "try:\n" + " print('Started script console.') # Outputs to stdout of scribus\n" +#if IS_PY3K + " import io\n" + " scribus._bu = io.StringIO()\n" +#else " import cStringIO\n" " scribus._bu = cStringIO.StringIO()\n" +#endif " sys.stdout = scribus._bu\n" " sys.stderr = scribus._bu\n" " sys.argv = ['scribus']\n" // this is the PySys_SetArgv replacement @@ -423,9 +469,9 @@ " sys.stdout = sys.__stdout__\n" " sys.stderr = sys.__stderr__\n" "except SystemExit:\n" - " print 'Catched SystemExit - it is not good for Scribus'\n" + " print ('Caught SystemExit - it is not good for Scribus')\n" "except KeyboardInterrupt:\n" - " print 'Catched KeyboardInterrupt - it is not good for Scribus'\n" + " print ('Caught KeyboardInterrupt - it is not good for Scribus')\n" ); } // Set up sys.argv @@ -459,6 +505,7 @@ } ScCore->primaryMainWindow()->setScriptRunning(false); + emit finishing_script(true); enableMainWindowMenu(); } @@ -596,14 +643,21 @@ bool ScripterCore::setupMainInterpreter() { + // Code duplication - StringIO several times assigned to sys.stdin? QString cm = QString( "# -*- coding: utf-8 -*-\n" - "import scribus\n" + "import scribus\n" // TODO: This line without effect? "import sys\n" "import code\n" "sys.path.insert(0, \"%1\")\n" +#if IS_PY3K + "import io\n" + "sys.stdin = io.StringIO()\n" +#else "import cStringIO\n" "sys.stdin = cStringIO.StringIO()\n" +#endif + "#print(' scriptercore.cpp: This is the .so plugin loading code.')\n" "scribus._ia = code.InteractiveConsole(globals())\n" ).arg(ScPaths::instance().scriptDir()); if (m_importAllNames) @@ -636,6 +690,74 @@ pcon->updateSyntaxHighlighter(); } +void ScripterCore::disable_updates(bool main_thread) +{ + if (main_thread) + { + if (num_main_interpreters == 0) + { + // Freeze the GUI + ScCore->primaryMainWindow()->doc->DoDrawing = false; + ScCore->primaryMainWindow()->doc->view()->updatesOn(false); + main_checkpoints = 0; + } + num_main_interpreters ++; + return; + } + + num_side_interpreters ++; + +} + +void ScripterCore::test_checkpoint(int num) +{ + main_checkpoints += num; + + // FIXME: Magic Number! + if (main_checkpoints >= 1000) { + ScCore->primaryMainWindow()->doc->DoDrawing = true; + ScCore->primaryMainWindow()->doc->view()->updatesOn(true); + + ScCore->primaryMainWindow()->doc->view()->DrawNew(); + ScCore->primaryMainWindow()->doc->changed(); + + ScCore->primaryMainWindow()->doc->DoDrawing = false; + ScCore->primaryMainWindow()->doc->view()->updatesOn(false); + } +} + +void ScripterCore::enable_updates(bool main_thread) +{ + if (main_thread) + { + if (num_main_interpreters == 0) + { + qDebug() << "ScripterCore::script_finished(): slot WARNING: more scripts finished than started."; + num_main_interpreters++; + } + num_main_interpreters --; + if (num_main_interpreters == 0) + { + ScCore->primaryMainWindow()->doc->DoDrawing = true; + ScCore->primaryMainWindow()->doc->view()->updatesOn(true); + ScCore->primaryMainWindow()->doc->view()->DrawNew(); + ScCore->primaryMainWindow()->doc->changed(); + } + return; + } + + + if (num_side_interpreters == 0) + { + qDebug() << "ScripterCore::script_finished(): slot WARNING: more side scripts finished than started."; + num_side_interpreters++; + } + num_side_interpreters --; + +} + + + const QString & ScripterCore::startupScript() const { return m_startupScript; Index: scribus/plugins/scriptplugin/scriptercore.h =================================================================== --- scribus/plugins/scriptplugin/scriptercore.h (Revision 22369) +++ scribus/plugins/scriptplugin/scriptercore.h (Arbeitskopie) @@ -62,7 +62,17 @@ void setStartupScript(const QString& newScript); void setExtensionsEnabled(bool enable); void updateSyntaxHighlighter(); + + void disable_updates(bool main_thread); + void test_checkpoint(int num); // How many counters the checkpoint should be raised. + void enable_updates(bool main_thread); +signals: + void starting_script(bool main); + void checkpoint(int num); + void finishing_script(bool main); + + protected: // Private helper functions void FinishScriptRun(); @@ -81,7 +91,11 @@ MenuManager *menuMgr; QMap<QString, QPointer<ScrAction> > scrScripterActions; QMap<QString, QPointer<ScrAction> > scrRecentScriptActions; - + + int num_main_interpreters; + int num_side_interpreters; + int main_checkpoints; + // Preferences /** \brief pref: Enable access to main interpreter and 'extension scripts' */ bool m_enableExtPython; Index: scribus/plugins/scriptplugin/scriptplugin.cpp =================================================================== --- scribus/plugins/scriptplugin/scriptplugin.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/scriptplugin.cpp (Arbeitskopie) @@ -171,16 +171,27 @@ Py_SetPythonHome(pythonHome.data()); } #endif + +#if IS_PY3K + scripterCore = new ScripterCore(ScCore->primaryMainWindow()); + Q_CHECK_PTR(scripterCore); + + PyImport_AppendInittab("scribus", &PyInit_scribus); +#endif + Py_Initialize(); - if (PyUnicode_SetDefaultEncoding("utf-8")) - { + +#if !IS_PY3K + scripterCore = new ScripterCore(ScCore->primaryMainWindow()); + Q_CHECK_PTR(scripterCore); + + if (PyUnicode_SetDefaultEncoding("utf-8")) { qDebug("Failed to set default encoding to utf-8.\n"); PyErr_Clear(); } + initscribus(ScCore->primaryMainWindow(), false); +#endif - scripterCore = new ScripterCore(ScCore->primaryMainWindow()); - Q_CHECK_PTR(scripterCore); - initscribus(ScCore->primaryMainWindow()); #ifdef HAVE_SCRIPTER2 scripter2_init(); #endif @@ -255,7 +266,7 @@ /*static */PyObject *scribus_getval(PyObject* /*self*/) { - return PyString_FromString(scripterCore->inValue.toUtf8().data()); + return PyUnicode_FromString(scripterCore->inValue.toUtf8().data()); } /*! \brief Translate a docstring. Small helper function for use with the @@ -460,6 +471,7 @@ {const_cast<char*>("redrawAll"), (PyCFunction)scribus_redraw, METH_NOARGS, tr(scribus_redraw__doc__)}, {const_cast<char*>("removeTableRows"), scribus_removetablerows, METH_VARARGS, tr(scribus_removetablerows__doc__)}, {const_cast<char*>("removeTableColumns"), scribus_removetablecolumns, METH_VARARGS, tr(scribus_removetablecolumns__doc__)}, + {const_cast<char*>("renameObject"), (PyCFunction)scribus_renameobject, METH_VARARGS, tr(scribus_renameobject__doc__)}, {const_cast<char*>("renderFont"), (PyCFunction)scribus_renderfont, METH_KEYWORDS, tr(scribus_renderfont__doc__)}, {const_cast<char*>("replaceColor"), scribus_replcolor, METH_VARARGS, tr(scribus_replcolor__doc__)}, {const_cast<char*>("resizeTableColumn"), scribus_resizetablecolumn, METH_VARARGS, tr(scribus_resizetablecolumn__doc__)}, @@ -578,8 +590,9 @@ {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__)}, + {const_cast<char*>("duplicateObject"), scribus_duplicateobject, METH_VARARGS, tr(scribus_duplicateobject__doc__)}, // by Christian Hausknecht - {const_cast<char*>("duplicateObject"), scribus_duplicateobject, METH_VARARGS, tr(scribus_duplicateobject__doc__)}, + {const_cast<char*>("duplicateObject_legacy"), scribus_duplicateobject_legacy, METH_VARARGS, tr(scribus_duplicateobject_legacy__doc__)}, {const_cast<char*>("copyObject"), scribus_copyobject, METH_VARARGS, tr(scribus_copyobject__doc__)}, {const_cast<char*>("pasteObject"), scribus_pasteobject, METH_VARARGS, tr(scribus_pasteobject__doc__)}, // Internal methods - Not for public use @@ -594,6 +607,36 @@ {NULL, (PyCFunction)(0), 0, NULL} /* sentinel */ }; + +#if IS_PY3K +struct module_state { + PyObject *error; +}; +#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) + +static int myextension_traverse(PyObject *m, visitproc visit, void *arg) { + Py_VISIT(GETSTATE(m)->error); + return 0; +} + +static int myextension_clear(PyObject *m) { + Py_CLEAR(GETSTATE(m)->error); + return 0; +} + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "scribus", + NULL, + sizeof(struct module_state), + scribus_methods, + NULL, + myextension_traverse, + myextension_clear, + NULL +}; +#endif + void initscribus_failed(const char* fileName, int lineNo) { qDebug("Scripter setup failed (%s:%i)", fileName, lineNo); @@ -602,8 +645,18 @@ return; } -void initscribus(ScribusMainWindow *pl) +#if IS_PY3K +// explanation on how it's to be done: https://docs.python.org/3/howto/cporting.html +// Additional hint: has to be called by PyImport_AppendInittab before Py_Initialize +/*static*/ PyObject* PyInit_scribus(void) { + PyObject *m; + m = PyModule_Create(&moduledef); + return m; +} +#endif +void initscribus(ScribusMainWindow *pl, bool subinit) { + if (!scripterCore) { qWarning("scriptplugin: Tried to init scribus module, but no scripter core. Aborting."); @@ -610,16 +663,33 @@ return; } PyObject *m, *d; - PyImport_AddModule((char*)"scribus"); - + int result; + +#if !IS_PY3K + subinit = false; +#endif + if (!subinit) + m = PyImport_AddModule((char*)"scribus"); + else + m = PyImport_ImportModule((char*)"scribus"); + PyType_Ready(&Printer_Type); PyType_Ready(&PDFfile_Type); PyType_Ready(&ImageExport_Type); +#if !IS_PY3K m = Py_InitModule((char*)"scribus", scribus_methods); +#endif + Py_INCREF(&Printer_Type); - PyModule_AddObject(m, (char*)"Printer", (PyObject *) &Printer_Type); + result = PyModule_AddObject(m, (char*)"Printer", (PyObject *) &Printer_Type); + if (result != 0) { + qDebug("scriptplugin: Could not create scribus.Printer module"); + } Py_INCREF(&PDFfile_Type); - PyModule_AddObject(m, (char*)"PDFfile", (PyObject *) &PDFfile_Type); + result = PyModule_AddObject(m, (char*)"PDFfile", (PyObject *) &PDFfile_Type); + if (result != 0) { + qDebug("scriptplugin: Could not create scribus.PDFfile module"); + } Py_INCREF(&ImageExport_Type); PyModule_AddObject(m, (char*)"ImageExport", (PyObject *) &ImageExport_Type); d = PyModule_GetDict(m); @@ -652,6 +722,114 @@ // Done with exception setup // CONSTANTS +#if IS_PY3K + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("UNIT_POINTS")), PyInt_FromLong(unitIndexFromString("pt"))); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("UNIT_MILLIMETERS")), PyInt_FromLong(unitIndexFromString("mm"))); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("UNIT_INCHES")), PyInt_FromLong(unitIndexFromString("in"))); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("UNIT_PICAS")), PyInt_FromLong(unitIndexFromString("p"))); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("UNIT_CENTIMETRES")), PyInt_FromLong(unitIndexFromString("cm"))); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("UNIT_CICERO")), PyInt_FromLong(unitIndexFromString("c"))); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("UNIT_PT")), PyInt_FromLong(unitIndexFromString("pt"))); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("UNIT_MM")), PyInt_FromLong(unitIndexFromString("mm"))); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("UNIT_IN")), PyInt_FromLong(unitIndexFromString("in"))); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("UNIT_P")), PyInt_FromLong(unitIndexFromString("p"))); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("UNIT_CM")), PyInt_FromLong(unitIndexFromString("cm"))); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("UNIT_C")), PyInt_FromLong(unitIndexFromString("c"))); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PORTRAIT")), Py_BuildValue(const_cast<char*>("i"), portraitPage)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("LANDSCAPE")), Py_BuildValue(const_cast<char*>("i"), landscapePage)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("NOFACINGPAGES")), Py_BuildValue(const_cast<char*>("i"), 0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("FACINGPAGES")), Py_BuildValue(const_cast<char*>("i"), 1)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("FIRSTPAGERIGHT")), Py_BuildValue(const_cast<char*>("i"), 1)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("FIRSTPAGELEFT")), Py_BuildValue(const_cast<char*>("i"), 0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("ALIGN_LEFT")), Py_BuildValue(const_cast<char*>("i"), 0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("ALIGN_RIGHT")), Py_BuildValue(const_cast<char*>("i"), 2)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("ALIGN_CENTERED")), Py_BuildValue(const_cast<char*>("i"), 1)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("ALIGN_BLOCK")), Py_BuildValue(const_cast<char*>("i"), 3)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("ALIGN_FORCED")), Py_BuildValue(const_cast<char*>("i"), 4)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("DIRECTION_LTR")), Py_BuildValue(const_cast<char*>("i"), 0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("DIRECTION_RTL")), Py_BuildValue(const_cast<char*>("i"), 1)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("FILL_NOG")), Py_BuildValue(const_cast<char*>("i"), 0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("FILL_HORIZONTALG")), Py_BuildValue(const_cast<char*>("i"), 1)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("FILL_VERTICALG")), Py_BuildValue(const_cast<char*>("i"), 2)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("FILL_DIAGONALG")), Py_BuildValue(const_cast<char*>("i"), 3)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("FILL_CROSSDIAGONALG")), Py_BuildValue(const_cast<char*>("i"), 4)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("FILL_RADIALG")), Py_BuildValue(const_cast<char*>("i"), 5)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("LINE_SOLID")), Py_BuildValue(const_cast<char*>("i"), Qt::SolidLine)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("LINE_DASH")), Py_BuildValue(const_cast<char*>("i"), Qt::DashLine)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("LINE_DOT")), Py_BuildValue(const_cast<char*>("i"), Qt::DotLine)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("LINE_DASHDOT")), Py_BuildValue(const_cast<char*>("i"), Qt::DashDotLine)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("LINE_DASHDOTDOT")), Py_BuildValue(const_cast<char*>("i"), Qt::DashDotDotLine)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("JOIN_MITTER")), Py_BuildValue(const_cast<char*>("i"), Qt::MiterJoin)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("JOIN_BEVEL")), Py_BuildValue(const_cast<char*>("i"), Qt::BevelJoin)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("JOIN_ROUND")), Py_BuildValue(const_cast<char*>("i"), Qt::RoundJoin)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("CAP_FLAT")), Py_BuildValue(const_cast<char*>("i"), Qt::FlatCap)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("CAP_SQUARE")), Py_BuildValue(const_cast<char*>("i"), Qt::SquareCap)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("CAP_ROUND")), Py_BuildValue(const_cast<char*>("i"), Qt::RoundCap)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("BUTTON_NONE")), Py_BuildValue(const_cast<char*>("i"), QMessageBox::NoButton)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("BUTTON_OK")), Py_BuildValue(const_cast<char*>("i"), QMessageBox::Ok)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("BUTTON_CANCEL")), Py_BuildValue(const_cast<char*>("i"), QMessageBox::Cancel)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("BUTTON_YES")), Py_BuildValue(const_cast<char*>("i"), QMessageBox::Yes)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("BUTTON_NO")), Py_BuildValue(const_cast<char*>("i"), QMessageBox::No)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("BUTTON_ABORT")), Py_BuildValue(const_cast<char*>("i"), QMessageBox::Abort)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("BUTTON_RETRY")), Py_BuildValue(const_cast<char*>("i"), QMessageBox::Retry)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("BUTTON_IGNORE")), Py_BuildValue(const_cast<char*>("i"), QMessageBox::Ignore)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("BUTTON_DEFAULT")), Py_BuildValue(const_cast<char*>("i"), QMessageBox::Default)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("ICON_NONE")), Py_BuildValue(const_cast<char*>("i"), QMessageBox::NoIcon)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("ICON_INFORMATION")), Py_BuildValue(const_cast<char*>("i"), QMessageBox::Information)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("ICON_WARNING")), Py_BuildValue(const_cast<char*>("i"), QMessageBox::Warning)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("ICON_CRITICAL")), Py_BuildValue(const_cast<char*>("i"), QMessageBox::Critical)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_A0")), Py_BuildValue(const_cast<char*>("(ff)"), 2380.0, 3368.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_A1")), Py_BuildValue(const_cast<char*>("(ff)"), 1684.0, 2380.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_A2")), Py_BuildValue(const_cast<char*>("(ff)"), 1190.0, 1684.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_A3")), Py_BuildValue(const_cast<char*>("(ff)"), 842.0, 1190.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_A4")), Py_BuildValue(const_cast<char*>("(ff)"), 595.0, 842.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_A5")), Py_BuildValue(const_cast<char*>("(ff)"), 421.0, 595.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_A6")), Py_BuildValue(const_cast<char*>("(ff)"), 297.0, 421.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_A7")), Py_BuildValue(const_cast<char*>("(ff)"), 210.0, 297.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_A8")), Py_BuildValue(const_cast<char*>("(ff)"), 148.0, 210.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_A9")), Py_BuildValue(const_cast<char*>("(ff)"), 105.0, 148.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_B0")), Py_BuildValue(const_cast<char*>("(ff)"), 2836.0, 4008.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_B1")), Py_BuildValue(const_cast<char*>("(ff)"), 2004.0, 2836.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_B2")), Py_BuildValue(const_cast<char*>("(ff)"), 1418.0, 2004.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_B3")), Py_BuildValue(const_cast<char*>("(ff)"), 1002.0, 1418.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_B4")), Py_BuildValue(const_cast<char*>("(ff)"), 709.0, 1002.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_B5")), Py_BuildValue(const_cast<char*>("(ff)"), 501.0, 709.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_B6")), Py_BuildValue(const_cast<char*>("(ff)"), 355.0, 501.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_B7")), Py_BuildValue(const_cast<char*>("(ff)"), 250.0, 355.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_B8")), Py_BuildValue(const_cast<char*>("(ff)"), 178.0, 250.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_B9")), Py_BuildValue(const_cast<char*>("(ff)"), 125.0, 178.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_B10")), Py_BuildValue(const_cast<char*>("(ff)"), 89.0, 125.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_C5E")), Py_BuildValue(const_cast<char*>("(ff)"), 462.0, 649.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_COMM10E")), Py_BuildValue(const_cast<char*>("(ff)"), 298.0, 683.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_DLE")), Py_BuildValue(const_cast<char*>("(ff)"), 312.0, 624.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_EXECUTIVE")), Py_BuildValue(const_cast<char*>("(ff)"), 542.0, 720.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_FOLIO")), Py_BuildValue(const_cast<char*>("(ff)"), 595.0, 935.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_LEDGER")), Py_BuildValue(const_cast<char*>("(ff)"), 1224.0, 792.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_LEGAL")), Py_BuildValue(const_cast<char*>("(ff)"), 612.0, 1008.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_LETTER")), Py_BuildValue(const_cast<char*>("(ff)"), 612.0, 792.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAPER_TABLOID")), Py_BuildValue(const_cast<char*>("(ff)"), 792.0, 1224.0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("NORMAL")), Py_BuildValue(const_cast<char*>("i"), 0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("DARKEN")), Py_BuildValue(const_cast<char*>("i"), 1)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("LIGHTEN")), Py_BuildValue(const_cast<char*>("i"), 2)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("MULTIPLY")), Py_BuildValue(const_cast<char*>("i"), 3)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("SCREEN")), Py_BuildValue(const_cast<char*>("i"), 4)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("OVERLAY")), Py_BuildValue(const_cast<char*>("i"), 5)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("HARD_LIGHT")), Py_BuildValue(const_cast<char*>("i"), 6)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("SOFT_LIGHT")), Py_BuildValue(const_cast<char*>("i"), 7)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("DIFFERENCE")), Py_BuildValue(const_cast<char*>("i"), 8)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("EXCLUSION")), Py_BuildValue(const_cast<char*>("i"), 9)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("COLOR_DODGE")), Py_BuildValue(const_cast<char*>("i"), 10)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("COLOR_BURN")), Py_BuildValue(const_cast<char*>("i"), 11)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("HUE")), Py_BuildValue(const_cast<char*>("i"), 12)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("SATURATION")), Py_BuildValue(const_cast<char*>("i"), 13)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("COLOR")), Py_BuildValue(const_cast<char*>("i"), 14)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("LUMINOSITY")), Py_BuildValue(const_cast<char*>("i"), 15)); + // preset page layouts + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAGE_1")), Py_BuildValue(const_cast<char*>("i"), 0)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAGE_2")), Py_BuildValue(const_cast<char*>("i"), 1)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAGE_3")), Py_BuildValue(const_cast<char*>("i"), 2)); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("PAGE_4")), Py_BuildValue(const_cast<char*>("i"), 3)); +#else PyDict_SetItemString(d, const_cast<char*>("UNIT_POINTS"), PyInt_FromLong(unitIndexFromString("pt"))); PyDict_SetItemString(d, const_cast<char*>("UNIT_MILLIMETERS"), PyInt_FromLong(unitIndexFromString("mm"))); PyDict_SetItemString(d, const_cast<char*>("UNIT_INCHES"), PyInt_FromLong(unitIndexFromString("in"))); @@ -758,6 +936,7 @@ PyDict_SetItemString(d, const_cast<char*>("PAGE_2"), Py_BuildValue(const_cast<char*>("i"), 1)); PyDict_SetItemString(d, const_cast<char*>("PAGE_3"), Py_BuildValue(const_cast<char*>("i"), 2)); PyDict_SetItemString(d, const_cast<char*>("PAGE_4"), Py_BuildValue(const_cast<char*>("i"), 3)); +#endif // Measurement units understood by Scribus's units.cpp functions are exported as constant conversion // factors to be used from Python. @@ -772,9 +951,19 @@ // `in' is a reserved word in Python so we must replace it PyObject* name; if (unitGetUntranslatedStrFromIndex(i) == "in") + { +#if IS_PY3K + name = PyUnicode_FromString("inch"); +#else name = PyString_FromString("inch"); - else +#endif + } else { +#if IS_PY3K + name = PyUnicode_FromString(unitGetUntranslatedStrFromIndex(i).toLatin1().constData()); +#else name = PyString_FromString(unitGetUntranslatedStrFromIndex(i).toLatin1().constData()); +#endif + } if (!name) { initscribus_failed(__FILE__, __LINE__); @@ -788,7 +977,11 @@ } // Export the Scribus version into the module namespace so scripts know what they're running in +#if IS_PY3K + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("scribus_version")), PyUnicode_FromString(const_cast<char*>(VERSION))); +#else PyDict_SetItemString(d, const_cast<char*>("scribus_version"), PyString_FromString(const_cast<char*>(VERSION))); +#endif // Now build a version tuple like that provided by Python in sys.version_info // The tuple is of the form (major, minor, patchlevel, extraversion, reserved) QRegExp version_re("(\\d+)\\.(\\d+)\\.(\\d+)(.*)"); @@ -804,7 +997,13 @@ PyObject* versionTuple = Py_BuildValue(const_cast<char*>("(iiisi)"),\ majorVersion, minorVersion, patchVersion, (const char*)extraVersion.toUtf8(), 0); if (versionTuple != NULL) + { +#if IS_PY3K + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("scribus_version_info")), versionTuple); +#else PyDict_SetItemString(d, const_cast<char*>("scribus_version_info"), versionTuple); +#endif + } else qDebug("Failed to build version tuple for version string '%s' in scripter", VERSION); } @@ -813,18 +1012,36 @@ // ScMW = pl; // Function aliases for compatibility - // We need to import the __builtins__, warnings and exceptions modules to be able to run + // We need to import the builtins, warnings and exceptions modules to be able to run // the generated Python functions from inside the `scribus' module's context. // This code makes it possible to extend the `scribus' module by running Python code // from C in other ways too. + // JONAS: __builtin__ -> builtins (Python3) +#if IS_PY3K + PyObject* builtinModule = PyImport_ImportModuleEx(const_cast<char*>("builtins"), + d, d, Py_BuildValue(const_cast<char*>("[]"))); +#else PyObject* builtinModule = PyImport_ImportModuleEx(const_cast<char*>("__builtin__"), d, d, Py_BuildValue(const_cast<char*>("[]"))); +#endif if (builtinModule == NULL) { +#if IS_PY3K + qDebug("Failed to import 'builtins' module. Something is probably broken with your Python."); +#else qDebug("Failed to import __builtin__ module. Something is probably broken with your Python."); +#endif return; } +#if IS_PY3K + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("builtins")), builtinModule); +#else PyDict_SetItemString(d, const_cast<char*>("__builtin__"), builtinModule); +#endif + +#if IS_PY3K + /* "exceptions" has been merged into "builtins" in Python 3 */ +#else PyObject* exceptionsModule = PyImport_ImportModuleEx(const_cast<char*>("exceptions"), d, d, Py_BuildValue(const_cast<char*>("[]"))); if (exceptionsModule == NULL) @@ -832,7 +1049,9 @@ qDebug("Failed to import exceptions module. Something is probably broken with your Python."); return; } - PyDict_SetItemString(d, const_cast<char*>("exceptions"), exceptionsModule); + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("exceptions")), exceptionsModule); +#endif + PyObject* warningsModule = PyImport_ImportModuleEx(const_cast<char*>("warnings"), d, d, Py_BuildValue(const_cast<char*>("[]"))); if (warningsModule == NULL) @@ -840,7 +1059,11 @@ qDebug("Failed to import warnings module. Something is probably broken with your Python."); return; } +#if IS_PY3K + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("warnings")), warningsModule); +#else PyDict_SetItemString(d, const_cast<char*>("warnings"), warningsModule); +#endif // Create the module-level docstring. This can be a proper unicode string, unlike // the others, because we can just create a Unicode object and insert it in our // module dictionary. @@ -876,11 +1099,18 @@ is not exhaustive due to exceptions from called functions.\n\ "); +#if IS_PY3K + PyObject* docStr = PyUnicode_FromString(docstring.toUtf8().data()); +#else PyObject* docStr = PyString_FromString(docstring.toUtf8().data()); +#endif if (!docStr) qDebug("Failed to create module-level docstring (couldn't make str)"); else { +#if IS_PY3K + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("__doc__")), docStr); +#else PyObject* uniDocStr = PyUnicode_FromEncodedObject(docStr, "utf-8", NULL); Py_DECREF(docStr); docStr = NULL; @@ -887,9 +1117,16 @@ if (!uniDocStr) qDebug("Failed to create module-level docstring object (couldn't make unicode)"); else + { +#if IS_PY3K + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("__doc__")), uniDocStr); +#else PyDict_SetItemString(d, const_cast<char*>("__doc__"), uniDocStr); +#endif + } Py_DECREF(uniDocStr); uniDocStr = NULL; +#endif } // Wrap up pointers to the the QApp and main window and push them out @@ -901,7 +1138,11 @@ PyErr_Print(); } // Push it into the module dict, stealing a ref in the process +#if IS_PY3K + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("qApp")), wrappedQApp); +#else PyDict_SetItemString(d, const_cast<char*>("qApp"), wrappedQApp); +#endif Py_DECREF(wrappedQApp); wrappedQApp = NULL; @@ -912,9 +1153,15 @@ PyErr_Print(); } // Push it into the module dict, stealing a ref in the process +#if IS_PY3K + PyDict_SetItem(d, PyUnicode_FromString(const_cast<char*>("mainWindow")), wrappedMainWindow); +#else PyDict_SetItemString(d, const_cast<char*>("mainWindow"), wrappedMainWindow); +#endif Py_DECREF(wrappedMainWindow); wrappedMainWindow = NULL; + + return; } /*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings Index: scribus/plugins/scriptplugin/cmdobj.cpp =================================================================== --- scribus/plugins/scriptplugin/cmdobj.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/cmdobj.cpp (Arbeitskopie) @@ -16,7 +16,9 @@ #include "selection.h" #include "util_math.h" +#include "scriptercore.h" + PyObject *scribus_newrect(PyObject* /* self */, PyObject* args) { double x, y, w, h; @@ -43,7 +45,7 @@ if (!ItemExists(objName)) ScCore->primaryMainWindow()->doc->Items->at(i)->setItemName(objName); } - return PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(i)->itemName().toUtf8()); + return Legacy_PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(i)->itemName().toUtf8()); } @@ -69,7 +71,7 @@ if (!ItemExists(objName)) ScCore->primaryMainWindow()->doc->Items->at(i)->setItemName(objName); } - return PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(i)->itemName().toUtf8()); + return Legacy_PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(i)->itemName().toUtf8()); } @@ -94,7 +96,7 @@ if (!ItemExists(objName)) ScCore->primaryMainWindow()->doc->Items->at(i)->setItemName(objName); } - return PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(i)->itemName().toUtf8()); + return Legacy_PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(i)->itemName().toUtf8()); } @@ -119,7 +121,7 @@ if (!ItemExists(objName)) ScCore->primaryMainWindow()->doc->Items->at(i)->setItemName(objName); } - return PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(i)->itemName().toUtf8()); + return Legacy_PyString_FromString(ScCore->primaryMainWindow()->doc->Items->at(i)->itemName().toUtf8()); } PyObject *scribus_newtable(PyObject* /* self */, PyObject* args) @@ -155,7 +157,7 @@ if (!ItemExists(objName)) ScCore->primaryMainWindow()->doc->Items->at(i)->setItemName(objName); } - return PyString_FromString(table->itemName().toUtf8()); + return Legacy_PyString_FromString(table->itemName().toUtf8()); } PyObject *scribus_newline(PyObject* /* self */, PyObject* args) @@ -215,7 +217,7 @@ if (!ItemExists(objName)) ScCore->primaryMainWindow()->doc->Items->at(i)->setItemName(objName); } - return PyString_FromString(it->itemName().toUtf8()); + return Legacy_PyString_FromString(it->itemName().toUtf8()); } @@ -292,7 +294,7 @@ if (!ItemExists(objName)) ScCore->primaryMainWindow()->doc->Items->at(ic)->setItemName(objName); } - return PyString_FromString(it->itemName().toUtf8()); + return Legacy_PyString_FromString(it->itemName().toUtf8()); } @@ -374,7 +376,7 @@ if (!ItemExists(objName)) ScCore->primaryMainWindow()->doc->Items->at(ic)->setItemName(objName); } - return PyString_FromString(it->itemName().toUtf8()); + return Legacy_PyString_FromString(it->itemName().toUtf8()); } PyObject *scribus_bezierline(PyObject* /* self */, PyObject* args) @@ -465,7 +467,7 @@ if (!ItemExists(objName)) ScCore->primaryMainWindow()->doc->Items->at(ic)->setItemName(objName); } - return PyString_FromString(it->itemName().toUtf8()); + return Legacy_PyString_FromString(it->itemName().toUtf8()); } @@ -506,7 +508,7 @@ if (!ItemExists(objName)) i->setItemName(objName); } - return PyString_FromString(i->itemName().toUtf8()); + return Legacy_PyString_FromString(i->itemName().toUtf8()); } @@ -527,6 +529,9 @@ ScCore->primaryMainWindow()->doc->itemSelection_DeleteItem(); // Py_INCREF(Py_None); // return Py_None; + + emit scripterCore->checkpoint(10); + Py_RETURN_NONE; } @@ -760,7 +765,7 @@ styleList = PyList_New(0); for (int i=0; i < ScCore->primaryMainWindow()->doc->paragraphStyles().count(); ++i) { - if (PyList_Append(styleList, PyString_FromString(ScCore->primaryMainWindow()->doc->paragraphStyles()[i].name().toUtf8()))) + if (PyList_Append(styleList, Legacy_PyString_FromString(ScCore->primaryMainWindow()->doc->paragraphStyles()[i].name().toUtf8()))) { // An exception will have already been set by PyList_Append apparently. return NULL; @@ -777,7 +782,7 @@ charStyleList = PyList_New(0); for (int i=0; i < ScCore->primaryMainWindow()->doc->charStyles().count(); ++i) { - if (PyList_Append(charStyleList, PyString_FromString(ScCore->primaryMainWindow()->doc->charStyles()[i].name().toUtf8()))) + if (PyList_Append(charStyleList, Legacy_PyString_FromString(ScCore->primaryMainWindow()->doc->charStyles()[i].name().toUtf8()))) { // An exception will have already been set by PyList_Append apparently. return NULL; @@ -786,16 +791,82 @@ return charStyleList; } +PyObject *scribus_renameobject(PyObject * /* self */, PyObject *args) +{ + char* origname = const_cast<char*>(""); + char* newname = const_cast<char*>(""); + if (!PyArg_ParseTuple(args, "es|es", "utf-8", &newname, "utf-8", &origname)) { + Py_RETURN_NONE; + } + if(!checkHaveDocument()) { + Py_RETURN_NONE; + } + + PageItem *src = GetUniqueItem(QString::fromUtf8(origname)); + if (src == NULL) { + qDebug() << QString("Cannot get item \"%1\".").arg(origname); + Py_RETURN_NONE; + } + + src->setItemName(newname); + if (src->itemName() != newname) + { + PyErr_SetString( + NameExistsError, + QObject::tr("An object with the requested name already exists.", + "python error").toUtf8().constData()); + src->setItemName(origname); + qDebug() << QString("Wanted back to \"%1\", got \"%2\".").arg(origname, src->itemName()); + Py_RETURN_NONE; + } + + emit scripterCore->checkpoint(5); + + return Legacy_PyString_FromString(src->itemName().toUtf8()); +} + PyObject *scribus_duplicateobject(PyObject * /* self */, PyObject *args) { char* name = const_cast<char*>(""); + char* newname = const_cast<char*>(""); + if (!PyArg_ParseTuple(args, "|eses", "utf-8", &newname, "utf-8", &name)) { + Py_RETURN_NONE; + } + if(!checkHaveDocument()) { + Py_RETURN_NONE; + } + // We require a name given and duplicate only one object at one time. + PageItem *src = GetUniqueItem(QString::fromUtf8(name)); + if (src == NULL) { + qDebug() << "Cannot duplicate NULL."; + Py_RETURN_NONE; + } + + QString qnewname = QString::fromUtf8(newname); + + // do the duplicate + PageItem *dst = ScCore->primaryMainWindow()->slotDuplicateSingle(src, &qnewname); + + if (dst == NULL) { + emit scripterCore->checkpoint(4); + Py_RETURN_NONE; + } + + emit scripterCore->checkpoint(12); + + return Legacy_PyString_FromString(dst->itemName().toUtf8()); +} + +PyObject *scribus_duplicateobject_legacy(PyObject * /* self */, PyObject *args) +{ + char* name = const_cast<char*>(""); if (!PyArg_ParseTuple(args, "|es", "utf-8", &name)) { - return NULL; + Py_RETURN_NONE; } if(!checkHaveDocument()) { - return NULL; + Py_RETURN_NONE; } - // Is there a special name given? Yes -> add this to selection + // Is there a special name given? Yes -> make a selection of it PageItem *i = GetUniqueItem(QString::fromUtf8(name)); if (i != NULL) { ScCore->primaryMainWindow()->doc->m_Selection->clear(); @@ -802,12 +873,15 @@ ScCore->primaryMainWindow()->doc->m_Selection->addItem(i); } else - return NULL; + Py_RETURN_NONE; // do the duplicate ScCore->primaryMainWindow()->slotEditCopy(); ScCore->primaryMainWindow()->slotEditPaste(); // Py_INCREF(Py_None); // return Py_None; + + emit scripterCore->checkpoint(20); + Py_RETURN_NONE; } @@ -855,8 +929,8 @@ /*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings with header files structure untouched (docstrings are kept near declarations) PV */ -void cmdobjdocwarnings() +inline void cmdobjdocwarnings() { QStringList s; - s << scribus_newrect__doc__ <<scribus_newellipse__doc__ << scribus_newimage__doc__ << scribus_newtext__doc__ << scribus_newtable__doc__ << scribus_newline__doc__ <<scribus_polyline__doc__ << scribus_polygon__doc__ << scribus_bezierline__doc__ <<scribus_pathtext__doc__ <<scribus_deleteobj__doc__ <<scribus_textflow__doc__ <<scribus_objectexists__doc__ <<scribus_setstyle__doc__ <<scribus_getstylenames__doc__ <<scribus_getcharstylenames__doc__ <<scribus_duplicateobject__doc__ <<scribus_copyobject__doc__ <<scribus_pasteobject__doc__; + s << scribus_newrect__doc__ <<scribus_newellipse__doc__ << scribus_newimage__doc__ << scribus_newtext__doc__ << scribus_newtable__doc__ << scribus_newline__doc__ <<scribus_polyline__doc__ << scribus_polygon__doc__ << scribus_bezierline__doc__ <<scribus_pathtext__doc__ <<scribus_deleteobj__doc__ <<scribus_textflow__doc__ <<scribus_objectexists__doc__ <<scribus_setstyle__doc__ <<scribus_setcharstyle__doc__ <<scribus_getstylenames__doc__ <<scribus_getcharstylenames__doc__ <<scribus_renameobject__doc__ <<scribus_duplicateobject__doc__ <<scribus_duplicateobject__doc__ <<scribus_duplicateobject_legacy__doc__ <<scribus_copyobject__doc__ <<scribus_pasteobject__doc__; } Index: scribus/plugins/scriptplugin/cmdtable.cpp =================================================================== --- scribus/plugins/scriptplugin/cmdtable.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/cmdtable.cpp (Arbeitskopie) @@ -338,7 +338,7 @@ PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get table style on a non-table item.","python error").toLocal8Bit().constData()); return NULL; } - return PyString_FromString(table->styleName().toUtf8()); + return Legacy_PyString_FromString(table->styleName().toUtf8()); } PyObject *scribus_settablestyle(PyObject* /* self */, PyObject* args) @@ -378,7 +378,7 @@ PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot get table fill color on a non-table item.","python error").toLocal8Bit().constData()); return NULL; } - return PyString_FromString(table->fillColor().toUtf8()); + return Legacy_PyString_FromString(table->fillColor().toUtf8()); } PyObject *scribus_settablefillcolor(PyObject* /* self */, PyObject* args) Index: scribus/plugins/scriptplugin/cmdtext.cpp =================================================================== --- scribus/plugins/scriptplugin/cmdtext.cpp (Revision 22369) +++ scribus/plugins/scriptplugin/cmdtext.cpp (Arbeitskopie) @@ -17,6 +17,7 @@ #include "selection.h" #include "util.h" +#include "scriptercore.h" template<typename T> class ApplyCharstyleHelper { @@ -91,11 +92,11 @@ { for (int b = 0; b < it->itemText.length(); b++) if (it->itemText.selected(b)) - return PyString_FromString(it->itemText.charStyle(b).font().scName().toUtf8()); + return Legacy_PyString_FromString(it->itemText.charStyle(b).font().scName().toUtf8()); return NULL; } else - return PyString_FromString(it->currentCharStyle().font().scName().toUtf8()); + return Legacy_PyString_FromString(it->currentCharStyle().font().scName().toUtf8()); } PyObject *scribus_gettextsize(PyObject* /* self */, PyObject* args) @@ -171,11 +172,11 @@ { for (int b = 0; b < it->itemText.length(); b++) if (it->itemText.selected(b)) - return PyString_FromString(it->itemText.charStyle(b).fontFeatures().toUtf8()); + return Legacy_PyString_FromString(it->itemText.charStyle(b).fontFeatures().toUtf8()); return NULL; } else - return PyString_FromString(it->currentCharStyle().fontFeatures().toUtf8()); + return Legacy_PyString_FromString(it->currentCharStyle().fontFeatures().toUtf8()); } PyObject *scribus_getlinespace(PyObject* /* self */, PyObject* args) @@ -264,7 +265,7 @@ text += it->itemText.text(a); } } - return PyString_FromString(text.toUtf8()); + return Legacy_PyString_FromString(text.toUtf8()); } PyObject *scribus_gettext(PyObject* /* self */, PyObject* args) @@ -297,7 +298,7 @@ text += it->itemText.text(a); } } // for - return PyString_FromString(text.toUtf8()); + return Legacy_PyString_FromString(text.toUtf8()); } PyObject *scribus_setboxtext(PyObject* /* self */, PyObject* args) @@ -358,12 +359,16 @@ if (pos == -1) pos = it->itemText.length(); it->itemText.insertChars(pos, textData, true); - it->Dirty = true; + + /*it->Dirty = true; if (ScCore->primaryMainWindow()->doc->DoDrawing) { // FIXME adapt to Qt-4 painting style it->Dirty = false; - } + }*/ // (We are not in editMode.) + + emit scripterCore->checkpoint(2); + Py_RETURN_NONE; } Index: scribus/plugins/scriptplugin/cmdvar.h =================================================================== --- scribus/plugins/scriptplugin/cmdvar.h (Revision 22369) +++ scribus/plugins/scriptplugin/cmdvar.h (Arbeitskopie) @@ -32,6 +32,41 @@ #define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True #endif + +#if PY_MAJOR_VERSION >= 3 +#define IS_PY3K 1 +#endif + +#if IS_PY3K +// Python 2 -> Python 3 transition: +// Convert a Utf8 buffer to a Python String Object +#define Legacy_PyString_FromString PyUnicode_FromString +// Convert a data buffer to Python bytes +#define Legacy_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +// Return True if a Python Object is a Unicode String +#define PyString_Check PyUnicode_Check +// rather CheckExact? +#define PyString_Size PyBytes_Size +// Convert a Python String Object to a char* that points to a null-terminated Utf8 buffer +#define PyString_AsString PyUnicode_AsUTF8 +#define PyInt_FromLong PyLong_FromLong +#define PyInt_Check PyLong_Check +#define PyInt_AsLong PyLong_AsLong +#define PyCObject_Check PyCapsule_CheckExact +#define PyCObject_AsVoidPtr(capsule) \ + (PyCapsule_GetPointer(capsule, NULL)) +#define PyCObject_FromVoidPtr(pointer, destructor) \ + (PyCapsule_New(pointer, NULL, destructor)) +// Helpful is: +// https://docs.python.org/3/howto/cporting.html#cobject-replaced-with-capsule +// as well as: +// https://docs.python.org/3/c-api/bytes.html +// etc. +#else +#define Legacy_PyString_FromString PyString_FromString +#define Legacy_PyBytes_FromStringAndSize PyString_FromStringAndSize +#endif + #include <QString> #include "scribus.h" @@ -50,7 +85,10 @@ extern ScripterCore* scripterCore; /** @brief Initialize the 'scribus' Python module in the currently active interpreter */ -extern "C" void initscribus(ScribusMainWindow *pl); +extern "C" void initscribus(ScribusMainWindow *pl, bool subinit); +#if IS_PY3K +/*static*/ PyObject* PyInit_scribus(void); +#endif /* Exceptions */ /*! Common scribus Exception */