diff options
author | Olivier Tilloy <olivier.tilloy@canonical.com> | 2012-12-04 10:39:31 +0000 |
---|---|---|
committer | Tarmac <> | 2012-12-04 10:39:31 +0000 |
commit | c544a5faf09b223ab0116b1e205ab2019be497d3 (patch) | |
tree | 8ae8c65425e3dbd501f37a9e05d5a1cbb4648291 /libqmenumodel | |
parent | 6eb5409aef2bd86d49f7af25b4c37ec5cea4e142 (diff) | |
parent | ac9450d43d09d817d0f8855ac8c691cab11eddbe (diff) | |
download | qmenumodel-c544a5faf09b223ab0116b1e205ab2019be497d3.tar.gz qmenumodel-c544a5faf09b223ab0116b1e205ab2019be497d3.tar.bz2 qmenumodel-c544a5faf09b223ab0116b1e205ab2019be497d3.zip |
Cache sub-menus.
Approved by Renato Araujo Oliveira Filho, PS Jenkins bot.
Diffstat (limited to 'libqmenumodel')
-rw-r--r-- | libqmenumodel/src/qmenumodel.cpp | 65 | ||||
-rw-r--r-- | libqmenumodel/src/qmenumodel.h | 4 |
2 files changed, 54 insertions, 15 deletions
diff --git a/libqmenumodel/src/qmenumodel.cpp b/libqmenumodel/src/qmenumodel.cpp index 53dc966..1326d77 100644 --- a/libqmenumodel/src/qmenumodel.cpp +++ b/libqmenumodel/src/qmenumodel.cpp @@ -15,6 +15,7 @@ * * Authors: * Renato Araujo Oliveira Filho <renato@canonical.com> + * Olivier Tilloy <olivier.tilloy@canonical.com> */ extern "C" { @@ -24,8 +25,6 @@ extern "C" { #include "qmenumodel.h" #include "converter.h" -#include <QDebug> - /*! \qmltype QMenuModel \brief The QMenuModel class implements the base list model for menus @@ -41,6 +40,7 @@ QMenuModel::QMenuModel(GMenuModel *other, QObject *parent) m_menuModel(0), m_signalChangedId(0) { + m_cache = new QHash<int, QMenuModel*>; setMenuModel(other); connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)), SIGNAL(countChanged())); @@ -52,6 +52,7 @@ QMenuModel::QMenuModel(GMenuModel *other, QObject *parent) QMenuModel::~QMenuModel() { clearModel(); + delete m_cache; } /*! @@ -131,10 +132,10 @@ void QMenuModel::clearModel() m_menuModel = NULL; } - QList<QMenuModel*> list = findChildren<QMenuModel*>(QString(), Qt::FindDirectChildrenOnly); - Q_FOREACH(QMenuModel *model, list) { - delete model; + Q_FOREACH(QMenuModel* child, *m_cache) { + delete child; } + m_cache->clear(); } /*! \internal */ @@ -219,17 +220,25 @@ QVariant QMenuModel::getStringAttribute(const QModelIndex &index, QVariant QMenuModel::getLink(const QModelIndex &index, const QString &linkName) const { - GMenuModel *link; - - link = g_menu_model_get_item_link(m_menuModel, - index.row(), - linkName.toUtf8().data()); - + GMenuModel *link = g_menu_model_get_item_link(m_menuModel, + index.row(), + linkName.toUtf8().data()); if (link) { - QMenuModel *other = new QMenuModel(link, const_cast<QMenuModel*>(this)); - return QVariant::fromValue<QObject*>(other); + QMenuModel* child = 0; + int key = index.row(); + if (m_cache->contains(key)) { + QMenuModel* cached = m_cache->value(key); + if (cached->menuModel() == link) { + child = cached; + } + } + if (child == 0) { + child = new QMenuModel(link); + m_cache->insert(key, child); + } + g_object_unref(link); + return QVariant::fromValue<QObject*>(child); } - return QVariant(); } @@ -265,21 +274,47 @@ QVariant QMenuModel::getExtraProperties(const QModelIndex &index) const } /*! \internal */ -void QMenuModel::onItemsChanged(GMenuModel *, +QHash<int, QMenuModel*> QMenuModel::cache() const +{ + return *m_cache; +} + +/*! \internal */ +void QMenuModel::onItemsChanged(GMenuModel *model, gint position, gint removed, gint added, gpointer data) { QMenuModel *self = reinterpret_cast<QMenuModel*>(data); + QHash<int, QMenuModel*>* cache = self->m_cache; + int prevcount = g_menu_model_get_n_items(model) + removed - added; if (removed > 0) { self->beginRemoveRows(QModelIndex(), position, position + removed - 1); + // Remove invalidated menus from the cache + for (int i = position, iMax = position + removed; i < iMax; ++i) { + if (cache->contains(i)) { + delete cache->take(i); + } + } + // Update the indexes of other cached menus to account for the removals + for (int i = position + removed; i < prevcount; ++i) { + if (cache->contains(i)) { + cache->insert(i - removed, cache->take(i)); + } + } self->endRemoveRows(); } if (added > 0) { self->beginInsertRows(QModelIndex(), position, position + added - 1); + // Update the indexes of cached menus to account for the insertions + for (int i = prevcount - removed - 1; i >= position; --i) { + if (cache->contains(i)) { + cache->insert(i + added, cache->take(i)); + } + } self->endInsertRows(); } } diff --git a/libqmenumodel/src/qmenumodel.h b/libqmenumodel/src/qmenumodel.h index 9371bd8..54a5c42 100644 --- a/libqmenumodel/src/qmenumodel.h +++ b/libqmenumodel/src/qmenumodel.h @@ -60,7 +60,11 @@ protected: void setMenuModel(GMenuModel *model); GMenuModel *menuModel() const; + // helper getter intended for use in tests only + QHash<int, QMenuModel*> cache() const; + private: + QHash<int, QMenuModel*>* m_cache; GMenuModel *m_menuModel; guint m_signalChangedId; |