Add ability to load plugins at runtime

From @ubruhin on Wed Feb 21 2018 22:06:46 GMT+0000 (UTC)

It would be really nice to have an interface for plugins which can be loaded at runtime. See for example QPluginLoader and How to Create Qt Plugins.

Plugins could be used to implement extensions for LibrePCB, without the need to integrate them into the LibrePCB codebase. For example users/companies could implement integrations for their warehouse management, integration into other software, or similar things.

Maybe some effort can be shared with #4 and/or #2. For example the python bindings could be implemented on top of the plugin infrastructure, or the plugin infrastructure could be implemented on top of the python bindings. Or we even consider the python bindings as plugin infrastructure, so plugins are just python code…

Copied from original issue: https://github.com/LibrePCB/librepcb-rfcs/issues/5

From @hephaisto on Fri Feb 23 2018 22:58:18 GMT+0000 (UTC)

Qt plugins define interfaces for each plugin type. So every task has to get a separate interface definition. It is possible to create a very generalized interface, e.g. by supplying a reference to the current window as a parameter to the function call. However, there needs to be some way to trigger these commands.

Basic ideas for architecture

One button per plugin

Each loadable plugin gets two main functions: init and execute(CurrentWindow&) (and maybe something to retrieve metadata like a button icon).
In case of the python plugin, execute could display a file chooser dialog and execute the selected script.
Advantages:

  • few changes in main application code

Disadvantages:

  • not very convenient for plugins that provide multiple functions

Plugin with dropdown

Have a dropdown list for every plugin (or maybe one dropdown that combines all plugins). Instead of the simple execute, each plugin has
QList<QString> getAvailableCommands(); void execute(const QString &commandName, CurrentWindow&);
Then from the dropdown a command can be chosen and activated with a button. Of course there are other possibilities to add this to the GUI, e.g. as main menu options or separate buttons for every command etc. - that is not dependent on the plugin interface itself. (Maybe a good idea would be to have a separate tool button group for each plugin?)
In case of the python plugin, getAvailableCommands could return a list of all python scripts in a subdirectory.

Advantages (basically inverse to above…)

  • nice to use

Disadvantages

  • more application code (e.g. dynamically creating tool buttons)

Unsorted thoughts

  • Instead of just a command name, more complex metadata could be provided, e.g. whether the command is meant to be used on symbols or packages or schematics etc…
  • I think the main plugins should sooner or later be put into the main repo, to make them easier to build (otherwise you need to always refer to correct header files during compilation etc.), which introduces a lot of synchronisation boilerplate for developers and also people who want to build from source. (Yes, I’m talking about me. I have no idea about qmake and I am happy that I can add new folders in the fork without problems blush)

Some ideas perhaps to kick around about plugins:

  • importers for other ECADs (eagle,kicad…) could be plugins maybe, and only the one needed could be installed with the installer.
  • exporters also could be plugins, to put out cad stuff (step or whatever), and something like eagleup could be made to export towards sketchup