πŸš€ Quick Start With C++

Most of the time you want to store more than just QObject type, so create your custom type.

class Foo : public QObject
{
    Q_OBJECT
public:
    Foo(QObject* parent = nullptr) : QObject(parent) {}

    int foo = 0;
};

Then use a QOlm based object with class inheritance or as a typedef.

#include <Foo.hpp>
#include <QOlm/QOlm.hpp>

// Declare type
using FooList = qolm::QOlm<Foo>;

// Or create custom class
class FooList : public qolm::QOlm<Foo>
{
    Q_OBJECT
public:
    Foo(QObject* parent = nullptr,
        const QList<QByteArray> & exposedRoles = {},
        const QByteArray & displayRole = {}):
    qolm::QOlm<Foo>::(parent, exposedRoles, displayRole)
    {
    }
};

Then simply use it as a regular list.

πŸ“„ Api

Insert elements

The object provide multiple way to insert an object in the list:

  • append : Add an object at the end of the list.
  • prepend : Add an object at the beginning of the list.
  • insert : Insert object at requested offset.

Those three functions can also take a QList<_Object*> as a parameter entry to insert multiple object at once.

FooList list;
Foo foo1;
Foo foo2;
Foo foo3;
Foo foo4;

// {foo1}
list.append(&foo1);

// {foo2, foo1}
list.prepend(&foo2);

// {foo2, foo1, foo3}
list.append(&foo3);

// {foo2, foo4, foo1, foo3}
list.insert(1, &foo4);

Remove elements

To remove an item, simply call the remove function, either with a pointer to the _Object* , or with the index of the object at which you want to remove.

All elements can also be removed using clear function.

FooList list;
Foo foo1;
Foo foo2;
Foo foo3;
Foo foo4;
list.append({&foo1, &foo2, &foo3, &foo4});

// { &foo1, &foo2, &foo4 }
list.remove(&foo3);
// { &foo1, &foo2 }
list.remove(2);
// Remove all elements.
list.clear();

Move elements

Elements can be moved within the list, without changing the list size.

  • move from object at index from to index to.
  • moveUp: Move object at index index to index-1. This function make sense when seeing the list in a ListView for example. It move the item to previous index.
  • moveDown: Move object from index to index+1. This function make sense in a ListView in a column. It move the item to next index.
  • moveNext: alias of moveDown.
  • movePrevious: alias of moveUp.
FooList list;
Foo foo1;
Foo foo2;
Foo foo3;
Foo foo4;
list.append({&foo1, &foo2, &foo3, &foo4});

// { &foo1, &foo3, &foo4, &foo2 }
list.move(1, 3);

// { &foo2, &foo1, &foo3, &foo4 }
list.move(3, 0);

// { &foo2, &foo3, &foo1, &foo4 }
list.movePrevious(2);

// { &foo2, &foo3, &foo4, &foo1 }
list.moveNext(2);

Access element and get index

Multiple accessors can be used to get data.

  • get : Get pointer to the _Object* at index.
  • indexOf : Get the index from a _Object*
  • contains : Get if a _Object* is present.
  • size: Give the number of objects in the model
  • empty : True if model is empty.

🏠 Object ownership

The library follow qt ownership rules. So when inserting an object without parent, the list take ownership of that object. When the same object is removed it will be deleteLater.

FooList list;
// list take ownership on new Foo
list.append(new Foo());
// Since FooList have ownership on the foo at index 0, it call deleteLater on it. No need to worry about memory management.
list.remove(0);

πŸ”Ž Observe Insert/Remove/Move

Observe as QAbstractItemModel

The qolm::QOlm derived object can be observe for insertion and deletion like any qt model.

But those signals are not very convenient to use as a end user. That’s why QOlm provide other way to observe the list.

Observe thru signals

qolm::QOlmBase provide basic signal to react to QObject insert/remove/move operation.

  • onObjectInserted(QObject* object, int index)
  • onObjectRemoved(QObject* object, int index)
  • onObjectMoved(QObject* object, int from, int to)

They are call when the model can safely be iterated. You can simply retrieve a correct pointer by using qobject_cast<_Object*>(object).

Function override observe.

Sometime it can be useful to do some processing before the whole world gets notify about our object operation. This method is only available if you define a custom list type.

#include <Foo.hpp>
#include <QOlm/QOlm.hpp>

class FooList : public qolm::QOlm<Foo>
{
    Q_OBJECT
public:
    FooList(QObject* parent = nullptr,
        const QList<QByteArray> & exposedRoles = {},
        const QByteArray & displayRole = {}):
    QOlm<Foo>(parent, exposedRoles, displayRole)
    {
    }

protected:
    void onObjectAboutToBeInserted(_Object* item, int row) override
    {
        // Object is not yet inserted, do some preinsert operation on it.
    }
    void onObjectInserted(_Object* item, int row) override
    {
        // Object just got inserted, but no callback/signal have been called yet.
    }
    void onObjectAboutToBeMoved(_Object* item, int src, int dest) override
    {
        // Object haven't move yet, and no callback/signal have been called yet
    }
    void onObjectMoved(_Object* item, int src, int dest) override
    {
        // Object have been moved. No Callback/Signal have been called yet.
    }
    void onObjectAboutToBeRemoved(_Object* item, int row) override
    {
        // Object isn't removed yet, and no callback/signal have been called yet
    }
    void onObjectRemoved(_Object* item, int row) override
    {
        // Object have been removed. Callback/Signal have been called
    }
};

Observe with callback

Regular callback not dependent on qt can be used to handle insert/remove/move operation. We can’t use signal with correct pointer type because qt doesn’t support template moc.

FooList list;
list.onInserted([](const InsertedCallbackArgs& foo)
{
    // foo->foo can be directly accessed
    // foo.object gives a _Object*
    // foo.index gives inserted object index
});
list.onRemoved([](const RemovedCallbackArgs& foo)
{
    // foo->foo can be directly accessed
    // foo.object gives a _Object*
    // foo.index gives removed object index
});
list.onMoved([](const MovedCallbackArgs& foo)
{
    // foo->foo can be directly accessed
    // foo.object gives a _Object*
    // foo.from gives previous object index
    // foo.to gives new object index
});

Benefit of this method, is that the list can be observed by non qt object.

Each function return a callback handle that can be used to remove the callback.

auto handleInsert = list.onInserted([](const InsertedCallbackArgs& foo) {});
list.stopListenInsert(handleInsert);
auto handleRemove = list.onInserted([](const InsertedCallbackArgs& foo) {});
list.stopListenRemove(handleRemove);
auto handleMove = list.onInserted([](const InsertedCallbackArgs& foo) {});
list.stopListenMove(handleMove);

Iterator

QOlm is compatible with modern iterator, you can simply do:

FooList list;
for(const auto foo : list)
{
    //foo->getFoo()
}