Preparing a qutIM plugin at home

    Today we will be preparing a plug-in for qutIM, but not for the one that has recently been released, but for the future, which is under active development.
    To begin with, I would like to say a few general words:
    1. In sdk03 we tried to take into account all the "mistakes of violent youth"
    2. It is completely incompatible with old skd02
    3. Most likely, there will be no more such abrupt transitions in the API between versions

    And that’s why I recommend that anyone who has never written plugins for Kutim, focus on sdk03
    I want to note the important fact that now the development is using Qt 4.6, it provides huge additional features that it’s a sin to refuse.
    If you are burning with the desire to realize something interesting, but don’t know where to direct your energy, then this article is for you!

    In the summer, we came to the conclusion that the current implementation of the plug-in system led the program to a standstill:
    It became very difficult to increase functionality, the program has long ceased to be lightweight and on weak machines, it slowed down when loading a long contact sheet. It took a lot of time to fix bugs.
    Therefore, the development of libqutim began, in which we tried to take into account all the mistakes of the old plug-in system, and to make the development of Kutim as simple and enjoyable as possible.
    The structure of the new qutIM:

    • Microkernel - it contains the implementation of the module manager. It is responsible for loading and the correct operation of all parts of qutIM. It has the ability to choose which modules to load and which not. Plus, it includes the ability to track dependencies, which may be indispensable for modules that rely on other components in their work. In addition, active modules can be switched directly in runtime, which, for example, is actively used in configbackend
    • libqutim - this library stores the interfaces of all modules, as well as a set of the most useful and frequently used functions
    • corelayers - that set of modules that compiles directly with the application, you can easily change it if desired, as will be discussed below
    • plugins - traditional shared libraries that are currently easiest to put in the plugins folder next to the executable file, best suited for protocols


    The first step is to install the Qt4.6 library, for Windows and Macos X they are on the official site .
    Ubunta users can use the kubuntu-experimental repository, you can add it with the command:
    $ add-apt-repository ppa: kubuntu-experimental
    Gentushniki just need to unmask the corresponding ebuilds. For the rest it will not be difficult to find the necessary packages or assemble them yourself.
    We take the source code from here:
    www.qutim.org/svn/qutim/branches/sdk03
    After as usual
    $ mkdir build && cd build && cmake ..
    , we will command in the terminal As a result, cmake will create a Makefile for you, if it turns out that not all the dependencies for the assembly are satisfied, then reinstall the missing packages.
    Please pay attention to lines like
    + layer KINETICPOPUPS added to build
    + layer XSETTINGSDIALOG added to build
    + layer ADIUMCHAT added to build

    To date, the cmake script has implemented auto-detection of the layers used. You just need to put the source code of your plugin in scr / corelayers / layer_name so that it is recognized by the system. This opens up enormous prospects for creating your own assemblies, and simplifies development.
    In this article I will describe how to implement the settings dialog:
    Create a subdirectory simplesettingsdialog in the src / corelayers directory.
    We create the settingslayerimpl class and inherit it from the SettingsLayer class from libqutim, as shown below:
    settingslayeriml.h
    #include "libqutim/settingslayer.h"

    class SettingsDialog;
    using namespace qutim_sdk_0_3;

    class SettingsLayerImpl : public SettingsLayer
    {
      Q_OBJECT
    public:
      SettingsLayerImpl();
      virtual ~SettingsLayerImpl();
      virtual void close();
      virtual void show ( const SettingsItemList& settings );
    private:
      QPointer m_dialog;
    };

    * This source code was highlighted with Source Code Highlighter.

    settingslayeriml.cpp

    Note: if you compile the module directly into a binary file, then you need to include the header files as shown in the example. If you take it to the plugin, then you need to replace it with
    The layer is very simple: at the show request, a list of settings is sent, which you need to display
    settingslayeriml.cpp
    #include "settingslayerimpl.h"
    #include "settingsdialog.h"
    #include "modulemanagerimpl.h"
    #include
    static Core::CoreModuleHelper settings_layer_static( //регистрируем наш модуль, теперь он станет видимым для менеджера модулей
        QT_TRANSLATE_NOOP("Plugin", "Simple Settings dialog"), //описание, макрос QT_TRANSLATE_NOOP позволяет делать его переводимым на разные языки
        QT_TRANSLATE_NOOP("Plugin", "SDK03 example")
        );

    void SettingsLayerImpl::show (const SettingsItemList& settings )
    {
      if (m_dialog.isNull())
        m_dialog = new SettingsDialog(settings); //создаем диалог, которому передаем наш список настроек
      m_dialog->show();
    }

    * This source code was highlighted with Source Code Highlighter.

    There is nothing tricky in the implementation of the settings dialog, it is only important to remember that SettingsItem generates the settings widget only upon request in order to minimize memory costs.
    Next, create the dialog itself:
    settingsdialog.cpp

    #include "settingsdialog.h"
    #include "ui_settingsdialog.h"
    #include
    SettingsDialog::SettingsDialog ( const qutim_sdk_0_3::SettingsItemList& settings)
    : ui (new Ui::SettingsDialog)
    {
      m_setting_list = settings;
      ui->setupUi(this);

      foreach (SettingsItem *settings_item, m_setting_list) //заполняем список настроек самым бесхистростным образом без деления на категории
      {
        QListWidgetItem *list_item = new QListWidgetItem (settings_item->icon(),
                                 settings_item->text(),
                                 ui->listWidget
                                 );
      }
      connect(ui->listWidget,SIGNAL(currentRowChanged(int)),SLOT(currentRowChanged(int)));//навигация по списку настроек
      ui->listWidget->setCurrentRow(0);
    }

    void SettingsDialog::currentRowChanged ( int index)
    {
      SettingsWidget *widget = m_setting_list.at(index)->widget();//генерируем виджет или даем указатель на него, если он существует
      if (widget == 0)
        return;
      if (ui->stackedWidget->indexOf(widget) == -1) //если виджет не добавлен в стек, то добавляем его
      {
        widget->load();
        ui->stackedWidget->addWidget(widget);
      }
      ui->stackedWidget->setCurrentWidget(widget);//просим показать текущий виджет
    }

    SettingsDialog::~SettingsDialog()
    {
      delete ui;
    }

    * This source code was highlighted with Source Code Highlighter.


    After adding the files, do not forget to run the command again:
    $ cmake ..
    If the line that appears below appears in the output, then you did everything right.
    + layer SIMPLESETTINGSDIALOG added to build
    Now you need to add a call to the Settings: showWidget () function somewhere, I usually add it to the constructor of one of the layers.
    When everything is assembled, you can run the application. In the end, this pretty window will appear.



    I hope you are convinced that writing plugins is now very easy. As you can see, the settings are not yet thick, so go ahead, fill in the blanks, and the best plugins will fall into the kernel!
    I hope this is not the last article on the development of the new Kutima, in the future I plan to talk about the work of the settings engine, how convenient the json format is for storing them, and much more.

    Thank you all for your attention. Source code can be downloaded here.

    Also popular now: