Thursday, 3 August 2017

Kadu is no longer actively maintained

Just to let you know - I'm leaving this project unattended, so don't expect any updates, new versions or fixes.

Thanks for all the great years!

Saturday, 29 April 2017

Simplifying avatars

One of my task for 5.0 was to reimplement avatar support. Version from 4.0 was seemed to complicated for such a simple task as downloading bunch of files and uploading one from time to time.

First simplification was easy. Kadu 4.0 supported two modes of updating avatars. One required server to send a notification about avatar change for each contact. Second one pulled server for new avatars from time to time. It was not used for a long time, as implementation for server notifications for GaduGadu was added several releases ago. Removing that cleaned up a lot of unnecessary code that finished with not storing avatar data in configuration file (its size reduced by 75%!).

The only thing remaining for storage was avatar id attached to each contact (simple string different for each protocol - hash for XMPP, timestamp of last upload for Gadu-Gadu or full URL for Facebook).
Second simplification was making most of requests one way, without callbacks or returning values. Downloading avatars is not a critical job, so knowing when one failed is not important - it will be retried after next login or when server sends another notification.

So API for ContactAvatarService class is extremely simple now:
  void download(const ContactAvatarId &id);
  void available(const ContactAvatarId &id);
  void downloaded(const ContactAvatarId &id, const QByteArray &content);
  void removed(const ContactId &id);
It is self-explanatory. After receiving available signal handler can ignore it (when given avatar is already locally cached) or call download. Action on downloaded signal is also obvious - store avatar in local cache and update property of Contact. That is it.

Third simplification was change of accessing avatar services for protocol. Most protocol services are (still) accesses by ProtocolHandler class attached to Account instances. The problem is that ProtocolHandler can change for Account if its plugin is reloaded (unlikely event, but has to be taken into account). It makes all code connecting to its signals complicated, as it must also listen to Account::protocolHandlerChanged. Too much indirection. In 5.0 there is one access point for all ContactAvatarService instances named AggregatedContactAvatarService. All ContactAvatarServices are registered there after creation. It has similar API to ContactAvatarService:
  void bool download(const ContactAvatarGlobalId &id)
  void void available(const ContactAvatarGlobalId &id);
  void downloaded(const ContactAvatarGlobalId &id, const QByteArray &content);
  void removed(const ContactGlobalId &id);
Global part in parameters allows AggregatedContactAvatarService to select proper ContactAvatarService for calling download and forward its arguments there (if there is no service, false is returned). It also passes all signals from these services.

This change will be done for all services currently accesses by ProtocolHandler. Hopefully it will reduce references to ProtocolHandler class to only a few places in code.

In summary, doing these changes reduced avatars size by half, configuration size by three quarters, reduced avatar cache size and allowed for less bugs and easier to understand code with three simple steps:

  • remove what is obviously not needed (polling)
  • remove what turns out to be not needed after some thought (failure tracking)
  • reduce number of access points to one

Friday, 21 April 2017

Injeqt 1.2 and plans for 2.0

Injeqt 1.2 will be the last release of 1.x series. It includes one bugfix (for invalid test results in release mode) and one more feature - get_all_with_type_role method.

I do not have any ideas for new features for Injeqt 2.0. It may mean that it is feature-complete or that my use cases are very simple and not representative for wider audiences. However, for each thing I wanted to add to the library, I have come up with better (and simpler) solution that works best outside of library.

For example, I wanted a Repository feature to automatically add object that are subclasses of given class to another object. In Kadu that would be sublasses of Action added to repository named Actions. Core has a lot of them and most of plugins provides additional ones. After lots of thinking a InjectorRegisteredActions RAII class was created inside of Kadu that takes care of this without any kind of new class annotations.

Here it is:

    Actions &actions,
    injeqt::injector &injector) : m_actions{actions}
    for (auto const &o : injector.get_all_with_type_role(ACTION))
        auto action = qobject_cast<ActionDescription *>(o);
        if (action && m_actions.insert(action))

    for (auto const &a : m_registeredActions)

It can be easily turned to template, and it will be as soon as need arise.

As I can think of any new features, Injeqt 2.0 will be more of API improvement release. There are things I need to do:

  • get rid of instantiate_all_with_type_role()
  • get rid of just-introduced get_all_with_type_role()
  • rename type role to tag
  • replace it with a types() method that will return all types with their tag information
  • then use all the data to implement instantiate_all_with_type_role() and get_all_with_type_role() outside of library or as free helper functions (with better names, of course)
  • get rid of version namespace, it is not needed as nobody will ever use it
  • check if ranges library will be useful (injeqt uses lots of containers and algorithms)

Thursday, 4 August 2016

Injeqt 1.1 and testing Qt applications

I've developed Injeqt as a way to improve Kadu quality. Its code was filled by singletons and hidden dependencies. Now, with Injeqt 1.1 released and Kadu 4.0 getting close to release I can tell that I've fulfilled my goals.

First step in making Kadu testable was to get rid of singletons and replace them with injected objects. With quick grep I discovered that the phase ::instance() had more than 2600 occurrences with more than 150 singleton classes in core alone (not counting plugins). It took me almost two months just to add Injeqt setters to each class that used these singletons and fix things that broke during that phase.

One of immediately visible benefit of this effort was that dependencies between classes were suddenly obvious (just look at header file for INJEQT_SET setters). And what follows - realization that some of them do not make any sense at all. And some classes have way too much dependencies (several classes with 10 or more dependencies and tens of classes with over 5). So its a good starting point for refactoring.

But you can't just get a 500000 lines project and refactor it. So I did what I think is the most reasonable way to it - refactor as you go (and add unit tests!).

This brings us to the core of this post - how easy it is to test classes and services using Injeqt.

First feature that I've added with this mindset was JumpList support on Windows. JumpList are additional menu items that shows in context menu over taskbar buttons, just like here:

Idea was simple - for Kadu it should display all currently open and recently used chats in two groups. This feature requires two services - OpenChatRepository and RecentChatRepository - these holds lists of open/recent chats (just wrapped sets with signals in reality). As these classes didn't exist at this time, I've implemented them and added tests (as these classes do not depend on anything, Injeqt is not used there).

Then more interesting things came - JumpList abstract class to act as an adaptor for Qt's QWinJumpList and WindowsJumpListService to to handle the chat repositories and the JumpList instance. Thanks to JumpList being an abstract interface it was easy to create JumpListStub and test the whole thing in windows-jump-list-service.test.cpp file. The core of this tests is in makeInjector method that contains private class module with all classes required to execute tests - including our stub class:

WindowsJumpListServiceTest::makeInjector() const
  class module : public injeqt::module

  auto modules =

  return injeqt::injector{std::move(modules)};

So I was able to recreate all required dependencies for WindowsJumpListService with ease. If OpenChatRepository or RecentChatRepository had their own dependencies it would be neccessary to mock them too, but fortunately it was not the case.

If you would like to test Injeqt if your own project or if you just have any questions, feel free to send me email and I'll be happy to answer.

Friday, 8 January 2016

Injeqt 1.1 is coming

After some hiatus (summer is time for riding a bike, not for spending evenings at home writing open-source code) I've moved Kadu few steps forward. New version - 4.0 - will require some more functionalities from Injeqt dependency injection library. So a few new had been added. Most of them for plugin support. I'll give a short description of each of them and then show you how these works together.


I've promised subinjectors when Injeqt 1.0 was released. And now these are available. In short - you can create new injector with new modules and classes that also gains all knowledge and instance of another injector (or injectors).

In Kadu this means that each plugin can new have its own injector and use all of Kadu classes and services in a nice way (using INJEQT_SET setters).


It is quite frequent to run some code after all required objects were injected into newly created one. Think of that as of two-step initialization (in that case it is not as bad as most people describe it, do not be scared). Slots marked with INJEQT_INIT tag will do just that - be called after all INJEQT_SET/INJEQT_SETTER slots.

INJEQT_DONE marked slots that will be called before any object created by injector is destructed. It allows for cleanup, writing files do disc and do other stuff without worrying about availability of other objects (such code can not be run from destructors, because Injeqt does not guarantee anything about order of object destruction).

In Kadu INJEQT_INIT methods are used to connects slots and signals of services and to do loading/storing data.


It is a new name for INJEQT_SETTER. Just to match grammar of INJEQT_INIT and INJEQT_DONE.


Now Injeqt allows you to select when given object will be instantiated. If it is tagged with INJEQT_INSTANCE_ON_DEMAND (default) the behavior will be the same as with Injeqt 1.0 - object will be first instantiated when it is needed. If class is tagged with INJEQT_INSTANCE_IMMEDIATE - object will be instantiated as soon as possible (before injeqt::injector constructor finishes). Useful for services that works on their own using signals from other services. In Kadu all main plugin objects are marked with INJEQT_INSTANCE_IMMEDIATE, so there is no need to manually create them after plugin is loaded and plugin's injector is created.

inject_into method

Sometimes you create object manually, but still want to put injectable objects into it. Just call injeqt::injector::injeqt_into(QObjec *) on it and you are done.

In Kadu this is mainly used to allow access to Kadu services by dynamically created widgets.

Usage in Kadu

Now I'll show you real-life example of how it all works together.

Lets get a quick overview on how Kadu plugins were loaded in the past (like 3.x releases).

class PluginRootComponent
  virtual bool init() = 0;
  virtual void done() = 0;

Q_DECLARE_INTERFACE(PluginRootComponent, "im.kadu.PluginRootComponent")
This is the class that each plugin must implement and export. You can see example implementation for OTR encryption plugin in otr-plugin.cpp file. As you can see it uses init() method to initialize its own injector, connect some of its signals and slots (unfortunately, Injeqt can not do it for you yet). Some objects from Kadu core are retrieved using Core::instance() calls (this is one thing that I'm fixing currently). And the done() method is used to remove OTR objects from Kadu services. Fortunately the Injeqt takes care of objects created with OTR injector. The last important part are PluginRootComponentHandler class:
  PluginRootComponent *pluginRootComponent) :

PluginRootComponentHandler::~PluginRootComponentHandler() noexcept
And the ActivePlugin class:
ActivePlugin::ActivePlugin(const QString &pluginName) :
So, finally, the steps are:
  1. load .dll or .so file
  2. create PluginRootComponent instance from it using Qt QPluginLoader
  3. call init() method on the instance, it creates its own objects and connects to Kadu core classes with awkward ::instance() calls (either Core::instance()->className() or className::instance()
  4. before unloading call done() method
In comparison, Kadu 4.x uses different method for that. PluginRootComponent is replaced with PluginModulesFactory:
class KADUAPI PluginModulesFactory : public QObject

  explicit PluginModulesFactory(QObject *parent = nullptr);
  virtual ~PluginModulesFactory();

  virtual std::vector<std::unique_ptr<injeqt::module>>
    createPluginModules() const = 0;
  virtual QString parentInjectorName() const;


Q_DECLARE_INTERFACE(PluginModulesFactory, "im.kadu.PluginModulesFactory")
Its only job is to create list of Injeqt modules. Implementation of this class is usually fairly simple:
OtrPluginModulesFactory::createPluginModules() const
  auto modules = std::vector<std::unique_ptr<injeqt::module>>{};

  return modules;
Then the injector is created and stored in PluginLoader class using following code:
injeqt::injector{std::vector<injeqt::injector *>{parentInjector},
And that is all that is needed from Kadu core. Now please look at new otr-plugin-object.h and otr-plugin-object.cpp files. There are few things to be seen in OtrPluginObject class:
  1. it is marked with INJEQT_INSTANCE_IMMEDIATE - it means it will be instantiated as soon as plugin is loaded and injector is created
  2. it has INJEQT_SET slots with Otr* objects (that come from OtrModule) and with other objects that comes from Kadu core - it is possible because of adding parentInjector into injeqt::injector constructor - we got rid of some of ::instance() calls
  3. it has INJEQT_INIT and INJEQT_DONE methods to set up and shut down the plugin - these two are called by Injeqt and replaces manually called init() and done() methods of PluginRootComponent


I think that Injeqt is going into good direction. It makes working with such a big project as Kadu a bit easier each time it is itself improved. In future I hope for two more things to be implemented in it: INJEQT_SIGNAL and INJEQT_SLOT tags that will allow to automatically connects slots and signals of Injeqt-created objects and something like INJEQT_ADD and INJEQT_REMOVE to simplify creating repository/registry-like classes. Maybe one of these feature will be added to Injeqt 1.2. After adding both of them, I could remove most of INJEQT_INIT and INJEQT_DONE methods from plugins.

Tuesday, 31 March 2015

End of Facebook Chat support

This is sad announcement. Kadu 3 will have its Facebook Chat support removed. There will be no longer possibility to add or use Facebook accounts and existing accounts will stop working. It is not Kadu fault. Facebook is closing its XMPP gates on 1.05.2015 [1] and their own protocol is not accessible for third party applications.


Tuesday, 3 March 2015

Moved to Gitlab

As you may know, Gitorious is merging with Gitlab. That means Kadu repository was also moved there: Github repository will be kept as mirror.