Mbarcode Plugin Tutorial

This tutorial will give you a quick introduction to writing plugins for mBarcode. We will try to guide you from your very first steps all the way to a full fledged plugin. Our plugin will use 1D codes and do a search for these on the web. It will show the results in a window of its own.

Contents

Prerequisites

In this tutorial we'll be using Qt together with C++ to connect to the mBarcode plugin framework. To make the process very easy we are also using Qt Creator to write our code and Scratchbox to test and compile it. You don't have to use Scratchbox or Qt Creator if you don't want to, but this is not covered by this tutorial.

Heck, you can even get through this without Qt installed, but bare in mind that you are on your own then.

You must have:

  • Some basic knowledge about C++ and Qt
  • Scratchbox installed
  • Qt
  • Access to a terminal
  • An OS with dpkg

You could use:

  • Qt Creator

Using MADDE for development is currently a bit of a pain since it lacks the option for third party libraries. This might be unnecessary for plugins, but MADDE is in any case not covered by this tutorial yet.

First steps

Using Scratchbox is the easiest way to get started. Log in to Scratchbox by typing

/scratchbox/login

Install the mbarcode-dev package

apt-get install mbarcode-dev

Next, create a new "Empty Qt project" using Qt Creator and store this in /scratchbox/users/<your username>/home/<your username>/. For the sake of simplicity, we'll name our project "plugin".

Alternatively, create an empty folder using the terminal and add an empty plugin.pro file.

The project file

Add the following to your plugin.pro file:

TEMPLATE = lib
CONFIG += plugin
INCLUDEPATH += ../.. 

HEADERS = plugin.h
SOURCES = plugin.cpp
TARGET = $$qtLibraryTarget(mbarcode_isbnplugin)

unix { 
    # VARIABLES
    isEmpty(PREFIX):PREFIX = /usr
    BINDIR = $$PREFIX/bin
    DATADIR = $$PREFIX/share
    DEFINES += DATADIR=\"$$DATADIR\" \
        PKGDATADIR=\"$$PKGDATADIR\"
    
    # MAKE INSTALL
    INSTALLS += target
    target.path = $$DATADIR/mbarcode/plugins
}
OTHER_FILES += debian/changelog \
    debian/control

The plugin actions

Let's add some actions for our plugin! In Qt Creator, right click on your project and select "Add New...". Choose "C++ Class" and name it "ShowDialogAction".

Open the showdialogaction.h file and overwrite it with the following:

#ifndef SHOWDIALOGACTION_H
#define SHOWDIALOGACTION_H

#include <mbarcode-qt/plugininterfaces.h>
#include <mbarcode-qt/pluginaction.h>

class ShowDialogAction : public QObject, public PluginAction
{
    Q_OBJECT
public:
    ShowDialogAction(const PluginInterface *interface);

    QString getName() { return "My Plugin Action"; } // This name is just for convenience
    QString getText(); // This is the text that will show in the list
    bool isReady() { return ready; } // Tells the list wether this plugin is ready to be shown or not
    void clickAction(QWidget *parentWindow); // The action which is called whenever we are clicked

private slots:
    void barcodeAnalysed(QString barcodeType, QString barcodeData); // The slot where all the processing goes down

private:
    bool ready;
    QString barcodeType;
    QString barcodeData;
};

#endif // SHOWDIALOGACTION_H

Open the showdialogaction.cpp file and overwrite it with the following:

#include "showdialogaction.h"

#include <QMessageBox>

ShowDialogAction::ShowDialogAction(const PluginInterface *interface) : PluginAction(interface)
{
    // Do your initialization here.
    // Remember to set ready to false.
    // This keeps the plugin from appearing in the list before it is ready

    ready = false;
}

QString ShowDialogAction::getText() {
    // This is the text which will show in the list of results.

    return "Show Dialog";
}

void ShowDialogAction::clickAction(QWidget* parentWindow)
{
    // This is what happens when the user clicks our button.
    // In this example we only show a message box

    QMessageBox *msgBox = new QMessageBox(parentWindow);
    msgBox->setWindowTitle("My Plugin");
    msgBox->setText("The barcode was of type " + barcodeType + " and contained the data " + barcodeData);
    msgBox->exec();
}

void ShowDialogAction::barcodeAnalysed(QString barcodeType, QString barcodeData) {

    // In this function you process the data. This could be used for early web lookups or whatever.
    // We just store the data in memory for now.

    this->barcodeType = barcodeType;
    this->barcodeData = barcodeData;

    // We've done what we need to and are ready to show ourselves

    ready = true;
}

You could add more classes like this if you want different buttons with different actions, but for now, this will do.

Plugin interface

Let's connect to mBarcode's plugin interface. In Qt Creator, right click on your project and select "Add New...". Choose "C++ Class" and name it "Plugin".

Open your plugin.h file and overwrite it with the following:

#ifndef PLUGIN_H
#define PLUGIN_H

#include <QObject>

#include <mbarcode-qt/plugininterfaces.h>
#include <mbarcode-qt/pluginaction.h>

class Plugin : public QObject, public PluginInterface
{
    Q_OBJECT
    Q_INTERFACES(PluginInterface)
public:
    void initInterface(QWidget *parent);

    QSet<PluginAction*> getPluginActions(); // returns a list of actions this plugin provides
    QString getName() { return "My Plugin"; } // a name of your choosing

private:
    QWidget *parent;
    QSet<PluginAction*> pluginActions;

};

#endif // PLUGIN_H

Open your plugin.cpp file and add the following:

#include "plugin.h"
#include "showdialogaction.h"

void Plugin::initInterface(QWidget *parent)
{
    this->parent = parent;

    // Create an action

    ShowDialogAction *showDialogAction = new ShowDialogAction(this);

    // Add our action to the list

    pluginActions.insert(showDialogAction);

    // Connect the signal from the MaemoBarcodeWindow to our Action classes.

    connect(parent, SIGNAL(barcodeAnalysedSignal(QString,QString)),
            showDialogAction, SLOT(barcodeAnalysed(QString,QString)));

    // If you like to, you can connect this to whatever you want.
    // This means that you could even connect it to a slot in this class.
    // We've only chosen to do it this way for convenience.
}

QSet<PluginAction*> Plugin::getPluginActions() {
    return pluginActions;
}

Q_EXPORT_PLUGIN2(mbqt_myplugin, Plugin) // Please change this name

Testing your fancy new plugin

There you go! You are now ready to build your plugin and test it out. Before we build a complete debian package, let's see if everything works.

Build your plugin by issuing this command in your project folder in Scratchbox:

qmake && make

Go to your directory and pick up the new file named "libmbarcode_myplugin.so". Copy this to your device and place it in /home/user/.config/mbarcode/plugins.

Start mBarcode and scan a barcode as usual. Your plugin should now show up.

Troubleshooting

If your plugin doesn't load, please run mbarcode from terminal and look for error messages during the loading of the application.

Buildling it into a deb package

To be continued...