From 9b94a0f9c2cad99fef925a7b33f852aa5e38913a Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Fri, 14 Dec 2012 12:03:52 -0300 Subject: Avoid change rowCount value outside of BeginModel[Insert|Remove|Reset] functions --- libqmenumodel/src/qmenumodel.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'libqmenumodel/src/qmenumodel.cpp') diff --git a/libqmenumodel/src/qmenumodel.cpp b/libqmenumodel/src/qmenumodel.cpp index 57c61d0..c0d8c94 100644 --- a/libqmenumodel/src/qmenumodel.cpp +++ b/libqmenumodel/src/qmenumodel.cpp @@ -38,7 +38,8 @@ extern "C" { QMenuModel::QMenuModel(GMenuModel *other, QObject *parent) : QAbstractListModel(parent), m_menuModel(0), - m_signalChangedId(0) + m_signalChangedId(0), + m_rowCount(0) { m_cache = new QHash; setMenuModel(other); @@ -87,7 +88,7 @@ QVariantMap QMenuModel::get(int row) const */ int QMenuModel::count() const { - return rowCount(); + return m_rowCount; } /*! \internal */ @@ -105,12 +106,13 @@ void QMenuModel::setMenuModel(GMenuModel *other) if (m_menuModel) { g_object_ref(m_menuModel); - // this will trigger the menu load - (void) g_menu_model_get_n_items(m_menuModel); + m_rowCount = g_menu_model_get_n_items(m_menuModel); m_signalChangedId = g_signal_connect(m_menuModel, "items-changed", G_CALLBACK(QMenuModel::onItemsChanged), this); + } else { + m_rowCount = 0; } endResetModel(); @@ -296,12 +298,13 @@ void QMenuModel::onItemsChanged(GMenuModel *model, int prevcount = g_menu_model_get_n_items(model) + removed - added; if (removed > 0) { self->beginRemoveRows(QModelIndex(), position, position + removed - 1); + self->m_rowCount -= removed; // Remove invalidated menus from the cache for (int i = position, iMax = position + removed; i < iMax; ++i) { if (cache->contains(i)) { - QMenuModel *model = cache->take(i); - model->setMenuModel(NULL); - model->deleteLater(); + QMenuModel *cached = cache->take(i); + cached->setMenuModel(NULL); + cached->deleteLater(); } } // Update the indexes of other cached menus to account for the removals @@ -321,6 +324,7 @@ void QMenuModel::onItemsChanged(GMenuModel *model, cache->insert(i + added, cache->take(i)); } } + self->m_rowCount += removed; self->endInsertRows(); } } -- cgit v1.2.3 From 96a4d9c492d85c5e221cdf9117ba4d378a8c0e0f Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Fri, 14 Dec 2012 22:15:05 -0300 Subject: Only checks for row index in cache. Used Q_EMIT keywork for signals. --- libqmenumodel/src/qmenumodel.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'libqmenumodel/src/qmenumodel.cpp') diff --git a/libqmenumodel/src/qmenumodel.cpp b/libqmenumodel/src/qmenumodel.cpp index c0d8c94..3da71d7 100644 --- a/libqmenumodel/src/qmenumodel.cpp +++ b/libqmenumodel/src/qmenumodel.cpp @@ -234,9 +234,7 @@ QVariant QMenuModel::getLink(const QModelIndex &index, int key = index.row(); if (m_cache->contains(key)) { QMenuModel* cached = m_cache->value(key); - if (cached->menuModel() == link) { - child = cached; - } + child = cached; } if (child == 0) { child = new QMenuModel(link); @@ -297,7 +295,7 @@ void QMenuModel::onItemsChanged(GMenuModel *model, int prevcount = g_menu_model_get_n_items(model) + removed - added; if (removed > 0) { - self->beginRemoveRows(QModelIndex(), position, position + removed - 1); + Q_EMIT self->beginRemoveRows(QModelIndex(), position, position + removed - 1); self->m_rowCount -= removed; // Remove invalidated menus from the cache for (int i = position, iMax = position + removed; i < iMax; ++i) { @@ -313,19 +311,19 @@ void QMenuModel::onItemsChanged(GMenuModel *model, cache->insert(i - removed, cache->take(i)); } } - self->endRemoveRows(); + Q_EMIT self->endRemoveRows(); } if (added > 0) { - self->beginInsertRows(QModelIndex(), position, position + added - 1); + Q_EMIT 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->m_rowCount += removed; - self->endInsertRows(); + self->m_rowCount += added; + Q_EMIT self->endInsertRows(); } } -- cgit v1.2.3 From b601ff786a6c385f0a293e18d5947b4e79b46235 Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Sat, 15 Dec 2012 10:20:43 -0300 Subject: Removed keywords from VIRTUAL functions. --- libqmenumodel/src/qmenumodel.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'libqmenumodel/src/qmenumodel.cpp') diff --git a/libqmenumodel/src/qmenumodel.cpp b/libqmenumodel/src/qmenumodel.cpp index 3da71d7..787e7a3 100644 --- a/libqmenumodel/src/qmenumodel.cpp +++ b/libqmenumodel/src/qmenumodel.cpp @@ -295,7 +295,7 @@ void QMenuModel::onItemsChanged(GMenuModel *model, int prevcount = g_menu_model_get_n_items(model) + removed - added; if (removed > 0) { - Q_EMIT self->beginRemoveRows(QModelIndex(), position, position + removed - 1); + self->beginRemoveRows(QModelIndex(), position, position + removed - 1); self->m_rowCount -= removed; // Remove invalidated menus from the cache for (int i = position, iMax = position + removed; i < iMax; ++i) { @@ -311,11 +311,11 @@ void QMenuModel::onItemsChanged(GMenuModel *model, cache->insert(i - removed, cache->take(i)); } } - Q_EMIT self->endRemoveRows(); + self->endRemoveRows(); } if (added > 0) { - Q_EMIT self->beginInsertRows(QModelIndex(), position, position + added - 1); + 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)) { @@ -323,7 +323,7 @@ void QMenuModel::onItemsChanged(GMenuModel *model, } } self->m_rowCount += added; - Q_EMIT self->endInsertRows(); + self->endInsertRows(); } } -- cgit v1.2.3 From 64e7281e1de56c45a3cb6a75adbb7bf9a82eff21 Mon Sep 17 00:00:00 2001 From: Renato Araujo Oliveira Filho Date: Sun, 16 Dec 2012 23:00:41 -0300 Subject: Fixed model changes and singal. Try to keep the module unchanged until the function begin[Insert|Remove]Rows is called. --- libqmenumodel/src/qmenumodel.cpp | 92 ++++++++++++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 22 deletions(-) (limited to 'libqmenumodel/src/qmenumodel.cpp') diff --git a/libqmenumodel/src/qmenumodel.cpp b/libqmenumodel/src/qmenumodel.cpp index 787e7a3..5127cc2 100644 --- a/libqmenumodel/src/qmenumodel.cpp +++ b/libqmenumodel/src/qmenumodel.cpp @@ -39,7 +39,10 @@ QMenuModel::QMenuModel(GMenuModel *other, QObject *parent) : QAbstractListModel(parent), m_menuModel(0), m_signalChangedId(0), - m_rowCount(0) + m_rowCount(0), + m_currentOperationPosition(0), + m_currentOperationAdded(0), + m_currentOperationRemoved(0) { m_cache = new QHash; setMenuModel(other); @@ -162,25 +165,34 @@ QHash QMenuModel::roleNames() const QVariant QMenuModel::data(const QModelIndex &index, int role) const { QVariant attribute; - int rowCountValue = rowCount(); - if ((rowCountValue > 0) && (index.row() >= 0) && (index.row() < rowCountValue)) { + // Return a empty variant if the remove operation is in progress + if ((m_currentOperationRemoved > 0) && + (index.row() >= m_currentOperationPosition) && + (index.row() < (m_currentOperationPosition + m_currentOperationRemoved))) { + return attribute; + } + + int rowCountValue = rowCount() + (m_currentOperationAdded - m_currentOperationRemoved); + int row = rowIndex(index); + + if ((row >= 0) && (row < rowCountValue)) { if (m_menuModel) { switch (role) { case Action: - attribute = getStringAttribute(index, G_MENU_ATTRIBUTE_ACTION); + attribute = getStringAttribute(row, G_MENU_ATTRIBUTE_ACTION); break; case Label: - attribute = getStringAttribute(index, G_MENU_ATTRIBUTE_LABEL); + attribute = getStringAttribute(row, G_MENU_ATTRIBUTE_LABEL); break; case LinkSection: - attribute = getLink(index, G_MENU_LINK_SECTION); + attribute = getLink(row, G_MENU_LINK_SECTION); break; case LinkSubMenu: - attribute = getLink(index, G_MENU_LINK_SUBMENU); + attribute = getLink(row, G_MENU_LINK_SUBMENU); break; case Extra: - attribute = getExtraProperties(index); + attribute = getExtraProperties(row); break; default: break; @@ -199,20 +211,35 @@ QModelIndex QMenuModel::parent(const QModelIndex &index) const /*! \internal */ int QMenuModel::rowCount(const QModelIndex &) const { - if (m_menuModel) { - return g_menu_model_get_n_items(m_menuModel); + return m_rowCount; +} + +/*! \internal */ +int QMenuModel::rowIndex(const QModelIndex &index) const +{ + int row = index.row(); + /* + if ((m_currentOperationAdded > 0) && (row >= m_currentOperationPosition)) { + row += m_currentOperationAdded; + } else if ((m_currentOperationRemoved > 0) && (row >= (row >= m_currentOperationPosition))) { + } - return 0; + */ + if (row >= m_currentOperationPosition) { + row += (m_currentOperationAdded - m_currentOperationRemoved); + } + return row; } + /*! \internal */ -QVariant QMenuModel::getStringAttribute(const QModelIndex &index, +QVariant QMenuModel::getStringAttribute(int row, const QString &attribute) const { QVariant result; gchar* value = NULL; g_menu_model_get_item_attribute(m_menuModel, - index.row(), + row, attribute.toUtf8().data(), "s", &value); if (value) { @@ -223,22 +250,23 @@ QVariant QMenuModel::getStringAttribute(const QModelIndex &index, } /*! \internal */ -QVariant QMenuModel::getLink(const QModelIndex &index, +QVariant QMenuModel::getLink(int row, const QString &linkName) const { GMenuModel *link = g_menu_model_get_item_link(m_menuModel, - index.row(), + row, linkName.toUtf8().data()); if (link) { QMenuModel* child = 0; - int key = index.row(); - if (m_cache->contains(key)) { - QMenuModel* cached = m_cache->value(key); - child = cached; + if (m_cache->contains(row)) { + child = m_cache->value(row); + if (child->menuModel() != link) { + child->setMenuModel(link); + } } if (child == 0) { child = new QMenuModel(link); - m_cache->insert(key, child); + m_cache->insert(row, child); } g_object_unref(link); return QVariant::fromValue(child); @@ -257,9 +285,9 @@ QString QMenuModel::parseExtraPropertyName(const QString &name) const } /*! \internal */ -QVariant QMenuModel::getExtraProperties(const QModelIndex &index) const +QVariant QMenuModel::getExtraProperties(int row) const { - GMenuAttributeIter *iter = g_menu_model_iterate_item_attributes(m_menuModel, index.row()); + GMenuAttributeIter *iter = g_menu_model_iterate_item_attributes(m_menuModel, row); if (iter == NULL) { return QVariant(); } @@ -293,9 +321,28 @@ void QMenuModel::onItemsChanged(GMenuModel *model, QMenuModel *self = reinterpret_cast(data); QHash* cache = self->m_cache; + self->m_currentOperationPosition = position; + self->m_currentOperationAdded = added; + self->m_currentOperationRemoved = removed; + int prevcount = g_menu_model_get_n_items(model) + removed - added; if (removed > 0) { + // help function to proxy model + for(int i=position, iMax=(position + removed - 1); i <= iMax; i++) { + if (cache->contains(i)) { + Q_EMIT self->aboutToRemoveLink(cache->value(i), i); + } + } + + // We need clear the removed items before start remove it, + // because we do not have information about the previous data, and QML + // will try to retrieve it during the signal 'rowsAboutToBeRemoved' + QModelIndex start = self->index(position); + QModelIndex end = self->index(position + removed -1); + Q_EMIT self->dataChanged(start, end); + self->beginRemoveRows(QModelIndex(), position, position + removed - 1); + self->m_currentOperationPosition = self->m_currentOperationAdded = self->m_currentOperationRemoved = 0; self->m_rowCount -= removed; // Remove invalidated menus from the cache for (int i = position, iMax = position + removed; i < iMax; ++i) { @@ -316,6 +363,7 @@ void QMenuModel::onItemsChanged(GMenuModel *model, if (added > 0) { self->beginInsertRows(QModelIndex(), position, position + added - 1); + self->m_currentOperationPosition = self->m_currentOperationAdded = self->m_currentOperationRemoved = 0; // Update the indexes of cached menus to account for the insertions for (int i = prevcount - removed - 1; i >= position; --i) { if (cache->contains(i)) { -- cgit v1.2.3