From 2bbdf4e2347ec566280b9d878a12b7b1e732f632 Mon Sep 17 00:00:00 2001 From: Nick Dedekind Date: Fri, 9 Aug 2013 10:50:12 +0100 Subject: glib callbacks pass events through qt. --- examples/unityqmlmenumodel.qml | 2 +- libqmenumodel/src/CMakeLists.txt | 1 + libqmenumodel/src/unitymenumodel.cpp | 95 +++++++++++++++++++++--------- libqmenumodel/src/unitymenumodel.h | 3 + libqmenumodel/src/unitymenumodelevents.cpp | 63 ++++++++++++++++++++ libqmenumodel/src/unitymenumodelevents.h | 69 ++++++++++++++++++++++ 6 files changed, 204 insertions(+), 29 deletions(-) create mode 100644 libqmenumodel/src/unitymenumodelevents.cpp create mode 100644 libqmenumodel/src/unitymenumodelevents.h diff --git a/examples/unityqmlmenumodel.qml b/examples/unityqmlmenumodel.qml index e1de3c8..c0e5adc 100644 --- a/examples/unityqmlmenumodel.qml +++ b/examples/unityqmlmenumodel.qml @@ -108,7 +108,7 @@ Item { if (submenu) listview.model = submenu; else - listview.model.activate(index); + action.activate(); } } } diff --git a/libqmenumodel/src/CMakeLists.txt b/libqmenumodel/src/CMakeLists.txt index e0ee902..db8095a 100644 --- a/libqmenumodel/src/CMakeLists.txt +++ b/libqmenumodel/src/CMakeLists.txt @@ -12,6 +12,7 @@ set(QMENUMODEL_SRC qstateaction.cpp unitymenuaction.cpp unitymenumodel.cpp + unitymenumodelevents.cpp unitythemediconprovider.cpp gtk/gtkactionmuxer.c gtk/gtkactionmuxer.h diff --git a/libqmenumodel/src/unitymenumodel.cpp b/libqmenumodel/src/unitymenumodel.cpp index 5226747..8e0f0d1 100644 --- a/libqmenumodel/src/unitymenumodel.cpp +++ b/libqmenumodel/src/unitymenumodel.cpp @@ -20,9 +20,11 @@ #include "converter.h" #include "actionstateparser.h" #include "unitymenuaction.h" +#include "unitymenumodelevents.h" #include #include +#include extern "C" { #include "gtk/gtkactionmuxer.h" @@ -165,18 +167,8 @@ UnityMenuModelPrivate::~UnityMenuModelPrivate() void UnityMenuModelPrivate::clearItems(bool resetModel) { - GSequenceIter *begin; - GSequenceIter *end; - - if (resetModel) - model->beginResetModel(); - - begin = g_sequence_get_begin_iter (this->items); - end = g_sequence_get_end_iter (this->items); - g_sequence_remove_range (begin, end); - - if (resetModel) - model->endResetModel(); + UnityMenuModelClearEvent ummce(resetModel); + QCoreApplication::sendEvent(model, &ummce); } void UnityMenuModelPrivate::clearName() @@ -260,28 +252,17 @@ void UnityMenuModelPrivate::nameVanished(GDBusConnection *connection, const gcha void UnityMenuModelPrivate::menuItemInserted(GtkMenuTrackerItem *item, gint position, gpointer user_data) { UnityMenuModelPrivate *priv = (UnityMenuModelPrivate *)user_data; - GSequenceIter *it; - - priv->model->beginInsertRows(QModelIndex(), position, position); - - it = g_sequence_get_iter_at_pos (priv->items, position); - it = g_sequence_insert_before (it, g_object_ref (item)); - g_object_set_qdata (G_OBJECT (item), unity_menu_model_quark (), priv->model); - g_signal_connect (item, "notify", G_CALLBACK (menuItemChanged), it); - priv->model->endInsertRows(); + UnityMenuModelAddRowEvent ummare(item, position); + QCoreApplication::sendEvent(priv->model, &ummare); } void UnityMenuModelPrivate::menuItemRemoved(gint position, gpointer user_data) { UnityMenuModelPrivate *priv = (UnityMenuModelPrivate *)user_data; - GSequenceIter *it; - - priv->model->beginRemoveRows(QModelIndex(), position, position); - g_sequence_remove (g_sequence_get_iter_at_pos (priv->items, position)); - - priv->model->endRemoveRows(); + UnityMenuModelRemoveRowEvent ummrre(position); + QCoreApplication::sendEvent(priv->model, &ummrre); } void UnityMenuModelPrivate::menuItemChanged(GObject *object, GParamSpec *pspec, gpointer user_data) @@ -297,7 +278,9 @@ void UnityMenuModelPrivate::menuItemChanged(GObject *object, GParamSpec *pspec, model = (UnityMenuModel *) g_object_get_qdata (G_OBJECT (item), unity_menu_model_quark ()); position = g_sequence_iter_get_position (it); - Q_EMIT model->dataChanged(model->index(position, 0), model->index(position, 0)); + // FIXME + UnityMenuModelDataChangeEvent ummdce(position); + QCoreApplication::sendEvent(model, &ummdce); } UnityMenuModel::UnityMenuModel(QObject *parent): @@ -639,3 +622,59 @@ QVariant UnityMenuModel::get(int row, const QByteArray &role) return this->data(this->index(row, 0), priv->roles[role]); } + +bool UnityMenuModel::event(QEvent* e) +{ + if (e->type() == UnityMenuModelClearEvent::eventType) { + UnityMenuModelClearEvent *emmce = static_cast(e); + + GSequenceIter *begin; + GSequenceIter *end; + + if (emmce->reset) + beginResetModel(); + + begin = g_sequence_get_begin_iter (priv->items); + end = g_sequence_get_end_iter (priv->items); + g_sequence_remove_range (begin, end); + + if (emmce->reset) + endResetModel(); + + return true; + } else if (e->type() == UnityMenuModelAddRowEvent::eventType) { + UnityMenuModelAddRowEvent *ummrce = static_cast(e); + + GSequenceIter *it; + it = g_sequence_get_iter_at_pos (priv->items, ummrce->position); + if (it) { + beginInsertRows(QModelIndex(), ummrce->position, ummrce->position); + + it = g_sequence_insert_before (it, g_object_ref (ummrce->item)); + g_object_set_qdata (G_OBJECT (ummrce->item), unity_menu_model_quark (), this); + g_signal_connect (ummrce->item, "notify", G_CALLBACK (UnityMenuModelPrivate::menuItemChanged), it); + + endInsertRows(); + } + return true; + } else if (e->type() == UnityMenuModelRemoveRowEvent::eventType) { + UnityMenuModelRemoveRowEvent *ummrre = static_cast(e); + + GSequenceIter *it; + it = g_sequence_get_iter_at_pos (priv->items, ummrre->position); + if (it) { + beginRemoveRows(QModelIndex(), ummrre->position, ummrre->position); + + g_sequence_remove (it); + + endRemoveRows(); + } + return true; + } else if (e->type() == UnityMenuModelDataChangeEvent::eventType) { + UnityMenuModelDataChangeEvent *ummdce = static_cast(e); + + Q_EMIT dataChanged(index(ummdce->position, 0), index(ummdce->position, 0)); + return true; + } + return QAbstractListModel::event(e); +} diff --git a/libqmenumodel/src/unitymenumodel.h b/libqmenumodel/src/unitymenumodel.h index 5401331..4aaadfd 100644 --- a/libqmenumodel/src/unitymenumodel.h +++ b/libqmenumodel/src/unitymenumodel.h @@ -64,6 +64,9 @@ Q_SIGNALS: void menuObjectPathChanged(const QByteArray &path); void actionStateParserChanged(ActionStateParser* parser); +protected: + virtual bool event(QEvent* e); + private: class UnityMenuModelPrivate *priv; friend class UnityMenuModelPrivate; diff --git a/libqmenumodel/src/unitymenumodelevents.cpp b/libqmenumodel/src/unitymenumodelevents.cpp new file mode 100644 index 0000000..e03d1c7 --- /dev/null +++ b/libqmenumodel/src/unitymenumodelevents.cpp @@ -0,0 +1,63 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Authors: + * Nicholas Dedekind +#include +} + +#include "unitymenumodelevents.h" +#include "unitymenumodel.h" + +const QEvent::Type UnityMenuModelClearEvent::eventType = static_cast(QEvent::registerEventType()); +const QEvent::Type UnityMenuModelAddRowEvent::eventType = static_cast(QEvent::registerEventType()); +const QEvent::Type UnityMenuModelRemoveRowEvent::eventType = static_cast(QEvent::registerEventType()); +const QEvent::Type UnityMenuModelDataChangeEvent::eventType = static_cast(QEvent::registerEventType()); + +UnityMenuModelClearEvent::UnityMenuModelClearEvent(bool _reset) + : QEvent(UnityMenuModelClearEvent::eventType), + reset(_reset) +{} + +UnityMenuModelAddRowEvent::UnityMenuModelAddRowEvent(GtkMenuTrackerItem *_item, int _position) + : QEvent(UnityMenuModelAddRowEvent::eventType), + item(_item), + position(_position) +{ + if (item) { + g_object_ref(item); + } +} + +UnityMenuModelAddRowEvent::~UnityMenuModelAddRowEvent() +{ + if (item) { + g_object_unref(item); + } +} + +UnityMenuModelRemoveRowEvent::UnityMenuModelRemoveRowEvent(int _position) + : QEvent(UnityMenuModelRemoveRowEvent::eventType), + position(_position) +{} + +UnityMenuModelDataChangeEvent::UnityMenuModelDataChangeEvent(int _position) + : QEvent(UnityMenuModelDataChangeEvent::eventType), + position(_position) +{} diff --git a/libqmenumodel/src/unitymenumodelevents.h b/libqmenumodel/src/unitymenumodelevents.h new file mode 100644 index 0000000..dcb27ff --- /dev/null +++ b/libqmenumodel/src/unitymenumodelevents.h @@ -0,0 +1,69 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Authors: + * Nicholas Dedekind + +typedef struct _GtkMenuTrackerItem GtkMenuTrackerItem; + +/* Event for a unitymenumodel clear */ +class UnityMenuModelClearEvent : public QEvent +{ +public: + static const QEvent::Type eventType; + UnityMenuModelClearEvent(bool reset); + + bool reset; +}; + +/* Event for a row add for unitymenumodel */ +class UnityMenuModelAddRowEvent : public QEvent +{ +public: + static const QEvent::Type eventType; + UnityMenuModelAddRowEvent(GtkMenuTrackerItem *item, int position); + ~UnityMenuModelAddRowEvent(); + + GtkMenuTrackerItem *item; + int position; +}; + +/* Event for a row remove for unitymenumodel */ +class UnityMenuModelRemoveRowEvent : public QEvent +{ +public: + static const QEvent::Type eventType; + UnityMenuModelRemoveRowEvent(int position); + + int position; +}; + +/* Event for a row data change for unitymenumodel */ +class UnityMenuModelDataChangeEvent : public QEvent +{ +public: + static const QEvent::Type eventType; + UnityMenuModelDataChangeEvent(int position); + + int position; +}; + +#endif //UNITYMENUMODELEVENTS_H -- cgit v1.2.3