Improve scripting and its experience in Scribus
Introduction
The potential of the scripting interface seems highly underestimated. You can
- add features without knowing C++ and without recompiling
- make something which directly fits your own needs
- automate repetitive tasks to improve usability and to save time
- test ideas - Python is great for prototyping and sometimes it makes more sense to improve the prototype instead of rewriting everything in C++
I actually have written prototypes (among others) of
- new-document-wizards
- spell checkers
- importers for exotic file formats
- connectors to databases and content management systems
- GUI hacks (full screen mode, tear-off menus etc.)
Current problems
As you see in the current state scripter is already powerful but it lacks
- full integration into the GUI and the core: Scripts cannot easily add menu entries or toolbar icons, save settings into the Scribus configuration file, etc. [CR: This will probably need a decently designed public C++ API for Scribus, plus a SIP wrapper for it]
- completeness: While writing scripts you sometimes find things which are still missing. For example there is a function to zoom the document view. But there lacks a function to get the current zoom factor. [CR: Again, need a real public API in C++ to make any kind of completeness effort viable and maintainable]
- ease of use: The script console is really minimalistic and needs improvement. Also there is no standard way to distribute and install scripts.
- security: Scripter should warn you if a script wants to import a module which can access the file system. The user should be asked if he trusts a script. [CR: unfortunately the first part of this is not viable, though the second is - see Scripter Security ]
How to make scripting situation better
So what is needed?
For the user
- a standard way to find and to install extensions and scripts from the web, preferably from a trusted repository [CR: Great idea, especially if combined with signing of scripts for integrity etc]
- scripts look and behave as native parts of Scribus
For the developer
- specifications on how scripts can be integrated with Scribus
- more example scripts / extensions to see what is possible and how to make use of Scribus' features
- completed missing functionally
My idea
So I propose writing an extension manager for Scribus together with some example scripts and extensions.
This will probably help to find missing functionally and integration issues. Currently it is very easy to write scripts and this should not become harder by adding this new layer.
Mozilla Firefox shows what is possible with easily installable extensions. People without knowledge of C-programming can realize crazy ideas and useful features. A lot of the popularity of Firefox comes from its add-ons.
Discussion
[CR: The very first step we need is a sane internal API that we can expose for scripts to use - including SIP wrappers for parts of the GUI that we want to open up for manipulation, etc. Discovery through Qt's parent/child mechanism is limited and clumsy. With a decent C++ API and a SIP wrapper we can start making more sane, powerful scripts - and can probably integrate script management into the existing plugin manager.]
Answer to CR: Of course it would be great to have direct access to all objects and their methods. And this would be a great final goal. Currently with the introspection features of Qt (children, queryList, allWidgets, ..) you can only get the base classes, so you get QMainWindow and not ScribusMainWindow. Wrapping everything with SIP is a large task and I think it should be done bit by bit when something is needed. I am currently looking what needs to be done to wrap Scribus classes with sip. As an interim solution it would already helpful for finding an widget if most widgets in Scribus would have an internal name which can be set with QObject.setName or with the constructor. Then already a lot is possible. Hooking into the GUI, responding to signals etc can be done.
CR: reply: Full access to every internal Scribus method really isn't ever going to be realistic, nor would it be useful. There's a lot of internal functionality in Scribus that neither scripts nor plug-ins should ever see or be able to see. Much of it also changes quite quickly, so exposing it would cause major compatibility problems. For example, a plugin or script should not be aware of, or have to care about, the details of how text is represented in Scribus's internal data structures ... it should just get access to a somewhat higher level API for text manipulation. What I suggest is that an important initial step before any sort of serious effort to expose more of Scribus to scripts is to provide a sane C++ API that hides much of these internal details behind more stable and somewhat simplified interfaces. These interfaces could then be wrapped using SIP for use by scripts and plug-ins.
That, in my opinion, would be a really GREAT GSoC project. I also think you have some great ideas with regards to making scripts easier to find, providing sensible and consistent ways to install them, etc. Don't let me discourage you ... I'm not trying to, I'm just trying to point out potential issues with the approach rather than goals.
That's not to say that permitting full introspection via PyQt (tagging everything with object names) is inherently a bad idea, but it will lead to scripts that'll only work for one particular version of Scribus. They'll sometimes break even on patch releases. It's useful as an interim step, I agree, but it's not something I'd ever seriously rely on. Wrapping Scribus's internal objects with SIP isn't much better, either, since they're hardly API stable. IMO we _REALLY_ need a more stable C++ API to expose Scribus's functionality to scripts and plug-ins. I spent quite a long time maintaining the scripter alongside Petr, so I am all to familiar with how much breakage there is from version to version and how hard it can be to keep up.
I'm also very strongly in agreement with you in terms of the desirablity of hooks into Scribus for use by scripts and plugins. I've been thinking about that for a while; see extension script page referenced below.
Some articles on the wiki that may be of note: Known_Scripter_Issues, Experimental_PyQt_projects and Extension_script_discussion .
Implementation details
The GUI part will use the PyQt library which can directly integrate with the Scribus GUI. PyQt is available on all platforms where Qt is available and also supports Qt4 which Scribus will soon use. Nearly all Linux distributions contain PyQt and some like Kubuntu install it by default.
Most parts of the extension manager can be implemented in pure Python and rely on the already available hooks in scripter. Besides some stuff has to be added:
- functions to get the configuration directory and the program directory
- some widgets need to have a name so PyQt can find and access them
- Bindings for the preferences manager [CR]
- Bindings for the menu manager [CR]
- (more to come soon)
See the links below to see that I already have experience in this area.