Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
Inkscape::Extension::Implementation::Script Class Reference

Utility class used for loading and launching script extensions. More...

#include <script.h>

Inheritance diagram for Inkscape::Extension::Implementation::Script:
Inkscape::Extension::Implementation::Implementation

Classes

class  file_listener
 
struct  interpreter_t
 A definition of an interpreter, which can be specified in the INX file, but we need to know what to call. More...
 
class  PreviewObserver
 

Public Member Functions

 Script ()
 This function creates a script object and sets up the variables.
 
 ~Script () override
 Destructor.
 
bool load (Inkscape::Extension::Extension *module) override
 This function 'loads' an extension, basically it determines the full command for the extension and stores that.
 
void unload (Inkscape::Extension::Extension *module) override
 Unload this puppy!
 
bool check (Inkscape::Extension::Extension *module) override
 Check every dependency that was given to make sure we should keep this extension.
 
std::unique_ptr< SPDocumentnew_from_template (Inkscape::Extension::Template *module) override
 Create a new document based on the given template.
 
void resize_to_template (Inkscape::Extension::Template *tmod, SPDocument *doc, SPPage *page) override
 Take an existing document and selected page and resize or add items as needed.
 
std::unique_ptr< SPDocumentopen (Inkscape::Extension::Input *module, char const *filename, bool is_importing) override
 This function uses a filename that is put in, and calls the extension's command to create an SVG file which is returned.
 
void save (Inkscape::Extension::Output *module, SPDocument *doc, gchar const *filename) override
 This function uses an extension to save a document. It first creates an SVG file of the document, and then runs it through the script.
 
void export_raster (Inkscape::Extension::Output *module, const SPDocument *doc, std::string const &png_file, gchar const *filename) override
 Convert from PNG to raster format.
 
void effect (Inkscape::Extension::Effect *module, ExecutionEnv *executionEnv, SPDesktop *desktop, ImplementationDocumentCache *docCache) override
 This function uses an extension as an effect on a document.
 
void effect (Inkscape::Extension::Effect *module, ExecutionEnv *executionEnv, SPDocument *document) override
 Pure document version for calling an extension from the command line.
 
bool cancelProcessing () override
 
- Public Member Functions inherited from Inkscape::Extension::Implementation::Implementation
 Implementation ()=default
 
virtual ~Implementation ()=default
 
virtual ImplementationDocumentCachenewDocCache (Inkscape::Extension::Extension *, SPDesktop *)
 Create a new document cache object.
 
virtual void commitDocument ()
 
virtual void get_template_presets (const Template *tmod, TemplatePresets &presets) const
 
virtual bool match_template_size (Inkscape::Extension::Template *tmod, double width, double height)
 
virtual Gtk::Widget * prefs_effect (Inkscape::Extension::Effect *module, SPDesktop *desktop, sigc::signal< void()> *changeSignal, ImplementationDocumentCache *docCache)
 Find out information about the file.
 
virtual bool apply_filter (Inkscape::Extension::Effect *module, SPItem *item)
 
virtual unsigned setup (Inkscape::Extension::Print *)
 
virtual unsigned set_preview (Inkscape::Extension::Print *)
 
virtual unsigned begin (Inkscape::Extension::Print *, SPDocument *)
 
virtual unsigned finish (Inkscape::Extension::Print *)
 
virtual bool textToPath (Inkscape::Extension::Print *)
 Tell the printing engine whether text should be text or path.
 
virtual bool fontEmbedded (Inkscape::Extension::Print *)
 Get "fontEmbedded" param, i.e.
 
virtual unsigned bind (Inkscape::Extension::Print *, Geom::Affine const &, float)
 
virtual unsigned release (Inkscape::Extension::Print *)
 
virtual unsigned fill (Inkscape::Extension::Print *, Geom::PathVector const &, Geom::Affine const &, SPStyle const *, Geom::OptRect const &, Geom::OptRect const &, Geom::OptRect const &)
 
virtual unsigned stroke (Inkscape::Extension::Print *, Geom::PathVector const &, Geom::Affine const &, SPStyle const *, Geom::OptRect const &, Geom::OptRect const &, Geom::OptRect const &)
 
virtual unsigned image (Inkscape::Extension::Print *, unsigned char *, unsigned int, unsigned int, unsigned int, Geom::Affine const &, SPStyle const *)
 
virtual unsigned text (Inkscape::Extension::Print *, char const *, Geom::Point const &, SPStyle const *)
 
virtual void processPath (Inkscape::XML::Node *)
 
virtual void setDetachBase (bool detach)
 If detach = true, when saving to a file, don't store URIs relative to the filename.
 

Private Member Functions

void _change_extension (Inkscape::Extension::Extension *mod, ExecutionEnv *executionEnv, SPDocument *doc, std::list< std::string > &params, bool ignore_stderr, bool pipe_diffs=false)
 Internally, any modification of an existing document, used by effect and resize_page extensions.
 
void showPopupError (Glib::ustring const &filename, Gtk::MessageType type, Glib::ustring const &message)
 This function checks the stderr file, and if it has data, shows it in a warning dialog to the user.
 
int execute (std::list< std::string > const &in_command, std::list< std::string > const &in_params, Glib::ustring const &filein, file_listener &fileout, bool ignore_stderr=false, bool pipe_diffs=false)
 This is the core of the extension file as it actually does the execution of the extension.
 
void pump_events ()
 Make GTK+ events continue to come through a little bit.
 
std::string resolveInterpreterExecutable (const Glib::ustring &interpNameArg)
 Look up an interpreter name, and translate to something that is executable.
 

Private Attributes

bool _canceled
 
Glib::Pid _pid
 
Glib::RefPtr< Glib::MainLoop > _main_loop
 
std::list< std::string > command
 The command that has been derived from the configuration file with appropriate directories.
 
Glib::ustring helper_extension
 This is the extension that will be used as the helper to read in or write out the data.
 
Gtk::Window * parent_window
 The window which should be considered as "parent window" of the script execution, e.g.
 

Static Private Attributes

static const std::map< std::string, interpreter_tinterpreterTab
 A table of what interpreters to call for a given language.
 

Detailed Description

Utility class used for loading and launching script extensions.

Definition at line 52 of file script.h.

Constructor & Destructor Documentation

◆ Script()

Inkscape::Extension::Implementation::Script::Script ( )

This function creates a script object and sets up the variables.

Returns
A script object

This function just sets the command to NULL. It should get built officially in the load function. This allows for less allocation of memory in the unloaded state.

Definition at line 168 of file script.cpp.

◆ ~Script()

Inkscape::Extension::Implementation::Script::~Script ( )
overridedefault

Destructor.

Member Function Documentation

◆ _change_extension()

void Inkscape::Extension::Implementation::Script::_change_extension ( Inkscape::Extension::Extension mod,
ExecutionEnv executionEnv,
SPDocument doc,
std::list< std::string > &  params,
bool  ignore_stderr,
bool  pipe_diffs = false 
)
private

◆ cancelProcessing()

bool Inkscape::Extension::Implementation::Script::cancelProcessing ( )
overridevirtual

Reimplemented from Inkscape::Extension::Implementation::Implementation.

Definition at line 694 of file script.cpp.

References _canceled, _main_loop, and _pid.

◆ check()

bool Inkscape::Extension::Implementation::Script::check ( Inkscape::Extension::Extension module)
overridevirtual

Check every dependency that was given to make sure we should keep this extension.

Returns
Whether the check passed or not
Parameters
moduleThe Extension in question

Reimplemented from Inkscape::Extension::Implementation::Implementation.

Definition at line 267 of file script.cpp.

References Inkscape::XML::Node::content(), Inkscape::Extension::db, Inkscape::XML::Node::firstChild(), Inkscape::XML::Node::name(), and Inkscape::XML::Node::next().

◆ effect() [1/2]

void Inkscape::Extension::Implementation::Script::effect ( Inkscape::Extension::Effect module,
ExecutionEnv executionEnv,
SPDesktop desktop,
ImplementationDocumentCache docCache 
)
overridevirtual

This function uses an extension as an effect on a document.

Returns
none
Parameters
moduleExtension to effect with.
executionEnvCurrent execution environment.
desktopDesktop this extensions run on.
docDocument to run through the effect.

This function is a little bit trickier than the previous two. It needs two temporary files to get its work done. Both of these files have random names created for them using the Glib::file_open_temp function with the ink_ext_ prefix in the temporary directory. Like the other functions, the temporary files are deleted at the end.

To save/load the two temporary documents (both are SVG) the internal modules for SVG load and save are used. They are both used through the module system function by passing their keys into the functions.

The command itself is built a little bit differently than in other functions because the effect support selections. So on the command line a list of all the ids that are selected is included. Currently, this only works for a single selected object, but there will be more. The command string is filled with the data, and then after the execution it is freed.

The execute function is used at the core of this function to execute the Script on the two SVG documents (actually only one exists at the time, the other is created by that script). At that point both should be full, and the second one is loaded.

Reimplemented from Inkscape::Extension::Implementation::Implementation.

Definition at line 545 of file script.cpp.

References _change_extension(), command, desktop, execute(), Inkscape::Extension::Extension::get_id(), SPDesktop::getDocument(), SPDesktop::getSelection(), Inkscape::Extension::Effect::ignore_stderr, Inkscape::Extension::Effect::no_doc, node, Inkscape::Extension::Effect::pipe_diffs, and sp_namedview_document_from_window().

◆ effect() [2/2]

void Inkscape::Extension::Implementation::Script::effect ( Inkscape::Extension::Effect module,
ExecutionEnv executionEnv,
SPDocument document 
)
overridevirtual

Pure document version for calling an extension from the command line.

Reimplemented from Inkscape::Extension::Implementation::Implementation.

Definition at line 605 of file script.cpp.

References _change_extension().

◆ execute()

int Inkscape::Extension::Implementation::Script::execute ( std::list< std::string > const &  in_command,
std::list< std::string > const &  in_params,
Glib::ustring const &  filein,
file_listener fileout,
bool  ignore_stderr = false,
bool  pipe_diffs = false 
)
private

This is the core of the extension file as it actually does the execution of the extension.

Parameters
in_commandThe command to be executed
fileinFilename coming in
fileoutFilename of the out file
Returns
Number of bytes that were read into the output file.

The first thing that this function does is build the command to be executed. This consists of the first string (in_command) and then the filename for input (filein). This file is put on the command line.

The next thing that this function does is open a pipe to the command and get the file handle in the ppipe variable. It then opens the output file with the output file handle. Both of these operations are checked extensively for errors.

After both are opened, then the data is copied from the output of the pipe into the file out using fread and fwrite. These two functions are used because of their primitive nature - they make no assumptions about the data. A buffer is used in the transfer, but the output of fread is stored so the exact number of bytes is handled gracefully.

At the very end (after the data has been copied) both of the files are closed, and we return to what we were doing.

Definition at line 731 of file script.cpp.

References _canceled, _main_loop, _pid, SPDesktop::connectDestroy(), SPDesktop::connectDocumentReplaced(), desktop, SPDesktop::doc(), Inkscape::Extension::Implementation::Script::file_listener::init(), Inkscape::Extension::Implementation::Script::file_listener::isDead(), Inkscape::Extension::Implementation::Script::file_listener::read(), showPopupError(), and Inkscape::Extension::Implementation::Script::file_listener::string().

Referenced by _change_extension(), effect(), export_raster(), new_from_template(), open(), and save().

◆ export_raster()

void Inkscape::Extension::Implementation::Script::export_raster ( Inkscape::Extension::Output module,
const SPDocument doc,
std::string const &  png_file,
gchar const *  filename 
)
overridevirtual

Convert from PNG to raster format.

The function takes a PNG file and converts it into the specific format.

Parameters
png_filePath to input file in PNG format. Value is in platform-native encoding (see Glib::filename_to_utf8).
filenamePath to output file. Value is in platform-native encoding (see Glib::filename_to_utf8).

Reimplemented from Inkscape::Extension::Implementation::Implementation.

Definition at line 488 of file script.cpp.

References command, execute(), Inkscape::Extension::Output::is_raster(), and Inkscape::Extension::Implementation::Script::file_listener::toFile().

◆ load()

bool Inkscape::Extension::Implementation::Script::load ( Inkscape::Extension::Extension module)
overridevirtual

This function 'loads' an extension, basically it determines the full command for the extension and stores that.

Returns
none
Parameters
moduleThe extension to be loaded.

The most difficult part about this function is finding the actual command through all of the Reprs. Basically it is hidden down a couple of layers, and so the code has to move down too. When the command is actually found, it has its relative directory solved.

At that point all of the loops are exited, and there is an if statement to make sure they didn't exit because of not finding the command. If that's the case, the extension doesn't get loaded and should error out at a higher level.

Reimplemented from Inkscape::Extension::Implementation::Implementation.

Definition at line 200 of file script.cpp.

References Inkscape::XML::Node::attribute(), command, Inkscape::XML::Node::content(), Inkscape::XML::Node::firstChild(), helper_extension, Inkscape::Extension::Extension::loaded(), Inkscape::XML::Node::name(), Inkscape::XML::Node::next(), and resolveInterpreterExecutable().

◆ new_from_template()

std::unique_ptr< SPDocument > Inkscape::Extension::Implementation::Script::new_from_template ( Inkscape::Extension::Template module)
overridevirtual

◆ open()

std::unique_ptr< SPDocument > Inkscape::Extension::Implementation::Script::open ( Inkscape::Extension::Input module,
char const *  filenameArg,
bool  is_importing 
)
overridevirtual

This function uses a filename that is put in, and calls the extension's command to create an SVG file which is returned.

Returns
A new document that has been opened
Parameters
moduleExtension to use.
filenameFile to open.

First things first, this function needs a temporary file name. To create one of those the function Glib::file_open_tmp is used with the header of ink_ext_.

The extension is then executed using the 'execute' function with the filename assigned and then the temporary filename. After execution the SVG should be in the temporary file.

Finally, the temporary file is opened using the SVG input module and a document is returned. That document has its filename set to the incoming filename (so that it's not the temporary filename). That document is then returned from this function.

Todo:
Popup dialog here

Reimplemented from Inkscape::Extension::Implementation::Implementation.

Definition at line 363 of file script.cpp.

References command, Inkscape::Extension::db, execute(), helper_extension, Inkscape::Extension::open(), and Inkscape::Extension::Implementation::Script::file_listener::toFile().

◆ pump_events()

void Inkscape::Extension::Implementation::Script::pump_events ( )
private

Make GTK+ events continue to come through a little bit.

This just keeps coming the events through so that we'll make the GUI update and look pretty.

Definition at line 83 of file script.cpp.

Referenced by _change_extension().

◆ resize_to_template()

void Inkscape::Extension::Implementation::Script::resize_to_template ( Inkscape::Extension::Template tmod,
SPDocument doc,
SPPage page 
)
overridevirtual

Take an existing document and selected page and resize or add items as needed.

Reimplemented from Inkscape::Extension::Implementation::Implementation.

Definition at line 326 of file script.cpp.

References _change_extension(), SPObject::getId(), SPDocument::getRoot(), and page.

◆ resolveInterpreterExecutable()

std::string Inkscape::Extension::Implementation::Script::resolveInterpreterExecutable ( const Glib::ustring &  interpNameArg)
private

Look up an interpreter name, and translate to something that is executable.

Parameters
interpNameArgThe name of the interpreter that we're looking for, should be an entry in interpreterTab

Definition at line 121 of file script.cpp.

References Inkscape::Preferences::get(), and interpreterTab.

Referenced by load().

◆ save()

void Inkscape::Extension::Implementation::Script::save ( Inkscape::Extension::Output module,
SPDocument doc,
gchar const *  filename 
)
overridevirtual

This function uses an extension to save a document. It first creates an SVG file of the document, and then runs it through the script.

Returns
none
Parameters
moduleExtension to be used
docDocument to be saved
filenameThe name to save the final file as
Returns
false in case of any failure writing the file, otherwise true

Well, at some point people need to save - it is really what makes the entire application useful. And, it is possible that someone would want to use an extension for this, so we need a function to do that, eh?

First things first, the document is saved to a temporary file that is an SVG file. To get the temporary filename Glib::file_open_tmp is used with ink_ext_ as a prefix. Don't worry, this file gets deleted at the end of the function.

After we have the SVG file, then Script::execute is called with the temporary file name and the final output filename. This should put the output of the script into the final output file. We then delete the temporary file.

Todo:
Popup dialog here

Reimplemented from Inkscape::Extension::Implementation::Implementation.

Definition at line 437 of file script.cpp.

References command, Inkscape::Extension::db, execute(), Inkscape::Extension::FILE_SAVE_METHOD_TEMPORARY, helper_extension, Inkscape::Extension::save(), and Inkscape::Extension::Implementation::Script::file_listener::toFile().

◆ showPopupError()

void Inkscape::Extension::Implementation::Script::showPopupError ( Glib::ustring const &  filename,
Gtk::MessageType  type,
Glib::ustring const &  message 
)
private

This function checks the stderr file, and if it has data, shows it in a warning dialog to the user.

Parameters
filenameFilename of the stderr file

Definition at line 664 of file script.cpp.

References data, Inkscape::UI::dialog_run(), Inkscape::UI::pack_start(), parent_window, and sp_transientize().

Referenced by execute().

◆ unload()

void Inkscape::Extension::Implementation::Script::unload ( Inkscape::Extension::Extension module)
overridevirtual

Unload this puppy!

Returns
None.
Parameters
moduleExtension to be unloaded.

This function just sets the module to unloaded. It free's the command if it has been allocated.

Reimplemented from Inkscape::Extension::Implementation::Implementation.

Definition at line 252 of file script.cpp.

References command, and helper_extension.

Member Data Documentation

◆ _canceled

bool Inkscape::Extension::Implementation::Script::_canceled
private

Definition at line 74 of file script.h.

Referenced by cancelProcessing(), and execute().

◆ _main_loop

Glib::RefPtr<Glib::MainLoop> Inkscape::Extension::Implementation::Script::_main_loop
private

◆ _pid

Glib::Pid Inkscape::Extension::Implementation::Script::_pid
private

Definition at line 75 of file script.h.

Referenced by cancelProcessing(), and execute().

◆ command

std::list<std::string> Inkscape::Extension::Implementation::Script::command
private

The command that has been derived from the configuration file with appropriate directories.

Definition at line 85 of file script.h.

Referenced by _change_extension(), effect(), export_raster(), load(), new_from_template(), open(), save(), and unload().

◆ helper_extension

Glib::ustring Inkscape::Extension::Implementation::Script::helper_extension
private

This is the extension that will be used as the helper to read in or write out the data.

Definition at line 92 of file script.h.

Referenced by load(), open(), save(), and unload().

◆ interpreterTab

const std::map< std::string, Script::interpreter_t > Inkscape::Extension::Implementation::Script::interpreterTab
staticprivate
Initial value:
= {
#ifdef _WIN32
{ "perl", {"perl-interpreter", {"wperl" }}},
{ "python", {"python-interpreter", {"pythonw" }}},
#elif defined __APPLE__
{ "perl", {"perl-interpreter", {"perl" }}},
{ "python", {"python-interpreter", {"python3" }}},
#else
{ "perl", {"perl-interpreter", {"perl" }}},
{ "python", {"python-interpreter", {"python3", "python" }}},
#endif
{ "python2", {"python2-interpreter", {"python2", "python" }}},
{ "ruby", {"ruby-interpreter", {"ruby" }}},
{ "shell", {"shell-interpreter", {"sh" }}},
}

A table of what interpreters to call for a given language.

This table is used to keep track of all the programs to execute a given script. It also tracks the preference to use to overwrite the given interpreter to a custom one per user.

Definition at line 159 of file script.h.

Referenced by resolveInterpreterExecutable().

◆ parent_window

Gtk::Window* Inkscape::Extension::Implementation::Script::parent_window
private

The window which should be considered as "parent window" of the script execution, e.g.

when showin warning messages

If set to NULL the main window of the currently active document is used.

Definition at line 100 of file script.h.

Referenced by _change_extension(), and showPopupError().


The documentation for this class was generated from the following files: