Wednesday, September 4, 2013

Plugin manager - part 2

The second part of the plugin manager is the downloading and installing tab: it groups all available plugins in the same table allowing for a fast selection and install.

The screenshot is available underneath. Currently there are only a few test plugins on the list used for testing purposes.
The plugin manager downloads the information of all the plugins. The table displays the name and version of the plugin. An install button downloads and installs selected plugin which can be immediately used. The already installed plugins are marked so. The selection of the plugin displays a detailed description and preview image. For a fast find there is a search field to quickly display only wanted plugins in the table.

Now the plugin manager is finished. The plugins can be downloaded and incorporated into nomacs. So the first version of the plugin system is finished. It will still improve during the next week when also the first plugins will be developed.

Monday, August 19, 2013

Trip to Vienna

For the Google Summer of Code the mentoring organization receives a certain amount of money that can be used for students to come to visit their mentors. Because Ljubljana, the town where I live, is not far away (approx. 400 km) from Vienna, the town of the mentoring organization, the costs of traveling are not great. I was asked last year if I want to come to visit but I didn't have time. This year I had time so I gladly accepted the offer. On Thursday, July 11th I packed my bags and traveled to Vienna for a 3 days visit.

On Friday, after many skype conferences, I met my mentors in person. This day we set together in the same office and we did a lot of work on the nomacs plugin system. We modified the plugin interface to allow the user to create a submenu in the plugins menu. We also extended the interface to a viewport interface which now allows the plugins to completely connect to nomacs and to use all of its functionality. This is major addition to the plugin system. But it also needed a big change in nomacs which is now a dll. The main application had to be converted to a dll and a smaller application to call the dll. Because of the interconnection between different classes this is the only way for the plugins to use nomacs classes.

On Saturday I had some time to go some sightseeing around the town. In the evening I was invited to a dinner with all the mentors. On Sunday I finished my visit to Vienna and returned to home.

Thanks to all nomacs mentors: Markus, Stefan and Florian for a great trip to Vienna!

Monday, August 12, 2013

Plugin manager - part 1

Together with the nomacs mentors we decided that all the plugins will be managed by a Plugin manager: it will allow the user to download new plugins and to enable/disable already installed plugins. In this way the plugin installation is fast and simple. The user doesn't have to search for the plugins online but a refreshed database is shown in the plugin manager and the user just finds and installs the wanted plugin.

The plugin manager is the central part of the whole plugin system. It connects nomacs to the online database with plugin dlls and descriptions. It is also a connection to the dlls themselves. Because of the size of the plugin manager there was a change in my timeline from the proposal. The GUI for the plugin manager is much more extensive than the initially planed GUI of the plugin system. This is why more weeks will be used to develop the GUI.

Qt GUI on which nomacs is based has a great solution for the display of database data in tables: Model/View Programming. It is a great approach to connect the data to the tables for displaying. But it takes time to learn because of its vastness. The great thing is that it separates the displaying part and the data part. So when the data is changed only the cell in the table where the data was changed is refreshed. The table itself is very modifiable because with the use of delegates you can have buttons, checkboxes and many other things in the cells.

The first part of the plugin manager is the managing part. Bellow is the screenshot of it.
 The table displays the name and version of the installed plugin. A checkbox allows the user to enable or disable the installed plugin. And there is also an uninstall button for removing plugins. By selecting a plugin a plugin description and image preview are displayed.


Sunday, July 21, 2013

Qt plugins applied to nomacs

Because nomacs is based on Qt I decided that the best way to create plugins is using the Qt QPluginLoader. First we need to create an interface that is the connection between nomacs and dlls:
class DkPluginInterface {
public:
    virtual ~DkPluginInterface() {}

    virtual QString pluginID() const = 0;
    virtual QString pluginName() const = 0;
    virtual QString pluginDescription() const = 0;
    virtual QImage pluginDescriptionImage() const = 0;
    virtual QString pluginVersion() const = 0;

    virtual QStringList runID() const = 0;
    virtual QString pluginMenuName(const QString &runID) const = 0;
    virtual QString pluginStatusTip(const QString &runID) const = 0; 
    virtual QImage runPlugin(const QString &runID, const QImage &image) const = 0;
};

Q_DECLARE_INTERFACE(nmc::DkPluginInterface, "com.nomacs.ImageLounge.DkPluginInterface/0.1")
In the interface there are the functions that need to be implemented in the plugins. These are the function called from nomacs to retrieve plugin information and to run it. So that the QPluginLoader can know about the interface we have to declare it with Q_DECLARE_INTERFACE. The header file of a the plugin extends the above interface. Here is a test plugin header to show the import:
class DkFlipPlugin : public QObject, DkPluginInterface {
    Q_OBJECT
    Q_INTERFACES(nmc::DkPluginInterface)

public:
    QString pluginID() const;
    QString pluginName() const;
    QString pluginDescription() const;
    QImage pluginDescriptionImage() const;
    QString pluginVersion() const;

    QStringList runID() const;
    QString pluginMenuName(const QString &runID) const;
    QString pluginStatusTip(const QString &runID) const; 
    QImage runPlugin(const QString &runID, const QImage &image) const;
};
With Q_INTERFACES we let Qt know which interfaces the plugin uses. Just before the end of the plugin cpp file we need to export the plugin: Q_EXPORT_PLUGIN2(dkflipplugin, DkFlipPlugin). By doing this we tell Qt that class DkFlipPlugin is part of the plugin interface.

To build a Qt dll using cmake we need to add  the following lines to the cmake file:
ADD_DEFINITIONS(${QT_DEFINITIONS})
ADD_DEFINITIONS(-DQT_PLUGIN)
ADD_DEFINITIONS(-DQT_SHARED)
ADD_DEFINITIONS(-DQT_DLL)
 Now we have a plugin that we need to import into nomacs. We load the plugin using QPluginLoader from which we create a QObject instance that we cast to our DkPluginInterface class:
    QPluginLoader *loader = new QPluginLoader(filePath);
    QObject *plugin = loader->instance();
    if(plugin) {

        DkPluginInterface *initializedPlugin = qobject_cast<DkPluginInterface*>(plugin);
        if(initializedPlugin) {
            // do something with the plugin
        }
    }
    else delete loader;


Friday, June 28, 2013

The start to a second year with GSoC and Nomacs

This year I decided to apply for GSoC again. The main reason is the great experience I had last year. I really liked working with Nomacs and the Nomacs developers. They were really great mentors, always available to talk and help. This is also why I wanted to work with the Nomacs team again.

When April came I was glad to see that Nomacs team (part of the Computational Science and Engineering at TU Wien organisation) was again selected as a mentoring organisation. I looked at the project ideas they've prepared and one of them completely caught my eyes. It was the plug-in system idea. I decided that I want to do this project and I want anyone else take it from me.

Every year there are thousands of  students applying to GSoC. So to get selected ones needs to distinguish himself  from the others. I already had the advantage of knowing Nomacs and Qt from last years GSoC so I could really focus to prepare the project so it would best fit Nomacs. I read some books on the topic of Qt plug-ins and then implemented a simple test plug-in in Nomacs to show the feasibility. I also became a Nomacs translator. I've translated it into Slovene and Italian. So before the selection I already did a lot of work to show my commitment to the project.

My proposal with a full description of the project and timeline is accessible at: http://www.google-melange.com/gsoc/proposal/review/google/gsoc2013/tjerman/18001

In the weeks to come I'll be writing posts on the development of the plug-in system.