Merge lp:~aacid/qmenumodel/batch_insert_remove_from_menu into lp:qmenumodel

Proposed by Albert Astals Cid
Status: Merged
Approved by: Lukáš Tinkl
Approved revision: 131
Merged at revision: 129
Proposed branch: lp:~aacid/qmenumodel/batch_insert_remove_from_menu
Merge into: lp:qmenumodel
Diff against target: 334 lines (+84/-44)
5 files modified
libqmenumodel/src/gtk/gtkmenutracker.c (+44/-14)
libqmenumodel/src/gtk/gtkmenutracker.h (+2/-1)
libqmenumodel/src/unitymenumodel.cpp (+21/-18)
libqmenumodel/src/unitymenumodelevents.cpp (+12/-8)
libqmenumodel/src/unitymenumodelevents.h (+5/-3)
To merge this branch: bzr merge lp:~aacid/qmenumodel/batch_insert_remove_from_menu
Reviewer Review Type Date Requested Status
Charles Kerr (community) Approve
Lukáš Tinkl (community) Approve
Review via email: mp+318504@code.launchpad.net

Commit message

Batch add and removes into the model

Works much better with Qt Quick views to have all the insert/removes at once

Description of the change

Batch add and removes into the model

To post a comment you must log in.
130. By Albert Astals Cid

valign

Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

Crashes after a few popup menus opened:

http://paste.ubuntu.com/24182582/

review: Needs Fixing
131. By Albert Astals Cid

Fix c&p, this ref should be unref

Revision history for this message
Albert Astals Cid (aacid) wrote :

> Crashes after a few popup menus opened:
>
> http://paste.ubuntu.com/24182582/

Should be fixed, an ref should had been an unref (meh copy&paste)

Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

Works fine, no more crashes. I'd like someone with more glib/gobject knowledge to have a look at the code as well though

review: Approve
Revision history for this message
Charles Kerr (charlesk) wrote :

It's a little twisty, but but at the glib/gobject level everything seems to balance out.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libqmenumodel/src/gtk/gtkmenutracker.c'
2--- libqmenumodel/src/gtk/gtkmenutracker.c 2013-06-04 19:35:59 +0000
3+++ libqmenumodel/src/gtk/gtkmenutracker.c 2017-03-16 15:38:21 +0000
4@@ -85,7 +85,8 @@
5 GMenuModel *model,
6 gboolean with_separators,
7 gint offset,
8- const gchar *action_namespace);
9+ const gchar *action_namespace,
10+ GPtrArray *items_already_created);
11 static void gtk_menu_tracker_section_free (GtkMenuTrackerSection *section);
12
13 static GtkMenuTrackerSection *
14@@ -195,9 +196,12 @@
15 {
16 /* Add a separator */
17 GtkMenuTrackerItem *item;
18+ GPtrArray *items = g_ptr_array_new ();
19
20 item = _gtk_menu_tracker_item_new (tracker->observable, parent_model, parent_index, NULL, TRUE);
21- (* tracker->insert_func) (item, offset, tracker->user_data);
22+ g_ptr_array_add (items, (gpointer) item);
23+ (* tracker->insert_func) (items, offset, tracker->user_data);
24+ g_ptr_array_unref (items);
25 g_object_unref (item);
26
27 section->has_separator = TRUE;
28@@ -205,7 +209,7 @@
29 else if (should_have_separator < section->has_separator)
30 {
31 /* Remove a separator */
32- (* tracker->remove_func) (offset, tracker->user_data);
33+ (* tracker->remove_func) (offset, 1, tracker->user_data);
34 section->has_separator = FALSE;
35 }
36
37@@ -241,6 +245,7 @@
38 gint n_items)
39 {
40 gint i;
41+ gint n_total_items = 0;
42
43 for (i = 0; i < n_items; i++)
44 {
45@@ -253,8 +258,12 @@
46 n = gtk_menu_tracker_section_measure (subsection);
47 gtk_menu_tracker_section_free (subsection);
48
49- while (n--)
50- (* tracker->remove_func) (offset, tracker->user_data);
51+ n_total_items += n;
52+ }
53+
54+ if (n_total_items)
55+ {
56+ (* tracker->remove_func) (offset, n_total_items, tracker->user_data);
57 }
58 }
59
60@@ -265,8 +274,19 @@
61 gint offset,
62 GMenuModel *model,
63 gint position,
64- gint n_items)
65+ gint n_items,
66+ GPtrArray *items_already_created
67+ )
68 {
69+ GPtrArray *items;
70+ if (items_already_created)
71+ {
72+ items = items_already_created;
73+ }
74+ else
75+ {
76+ items = g_ptr_array_new ();
77+ }
78 while (n_items--)
79 {
80 GMenuModel *submenu;
81@@ -286,11 +306,11 @@
82 gchar *namespace;
83
84 namespace = g_strjoin (".", section->action_namespace, action_namespace, NULL);
85- subsection = gtk_menu_tracker_section_new (tracker, submenu, FALSE, offset, namespace);
86+ subsection = gtk_menu_tracker_section_new (tracker, submenu, FALSE, offset, namespace, items_already_created);
87 g_free (namespace);
88 }
89 else
90- subsection = gtk_menu_tracker_section_new (tracker, submenu, FALSE, offset, section->action_namespace);
91+ subsection = gtk_menu_tracker_section_new (tracker, submenu, FALSE, offset, section->action_namespace, items_already_created);
92
93 *change_point = g_slist_prepend (*change_point, subsection);
94 g_free (action_namespace);
95@@ -302,12 +322,21 @@
96
97 item = _gtk_menu_tracker_item_new (tracker->observable, model, position + n_items,
98 section->action_namespace, FALSE);
99- (* tracker->insert_func) (item, offset, tracker->user_data);
100- g_object_unref (item);
101+ g_ptr_array_insert (items, 0, (gpointer) item);
102
103 *change_point = g_slist_prepend (*change_point, NULL);
104 }
105 }
106+ if (!items_already_created)
107+ {
108+ if (items->len)
109+ {
110+ (* tracker->insert_func) (items, offset, tracker->user_data);
111+ for (gint i = 0; i < items->len; ++i)
112+ g_object_unref(g_ptr_array_index(items, i));
113+ }
114+ g_ptr_array_unref (items);
115+ }
116 }
117
118 static void
119@@ -352,7 +381,7 @@
120 * would do by appending.
121 */
122 gtk_menu_tracker_remove_items (tracker, change_point, offset, removed);
123- gtk_menu_tracker_add_items (tracker, section, change_point, offset, model, position, added);
124+ gtk_menu_tracker_add_items (tracker, section, change_point, offset, model, position, added, NULL);
125
126 /* The offsets for insertion/removal of separators will be all over
127 * the place, however...
128@@ -378,7 +407,8 @@
129 GMenuModel *model,
130 gboolean with_separators,
131 gint offset,
132- const gchar *action_namespace)
133+ const gchar *action_namespace,
134+ GPtrArray *items_already_created)
135 {
136 GtkMenuTrackerSection *section;
137
138@@ -387,7 +417,7 @@
139 section->with_separators = with_separators;
140 section->action_namespace = g_strdup (action_namespace);
141
142- gtk_menu_tracker_add_items (tracker, section, &section->items, offset, model, 0, g_menu_model_get_n_items (model));
143+ gtk_menu_tracker_add_items (tracker, section, &section->items, offset, model, 0, g_menu_model_get_n_items (model), items_already_created);
144 section->handler = g_signal_connect (model, "items-changed", G_CALLBACK (gtk_menu_tracker_model_changed), tracker);
145
146 return section;
147@@ -461,7 +491,7 @@
148 tracker->remove_func = remove_func;
149 tracker->user_data = user_data;
150
151- tracker->toplevel = gtk_menu_tracker_section_new (tracker, model, with_separators, 0, action_namespace);
152+ tracker->toplevel = gtk_menu_tracker_section_new (tracker, model, with_separators, 0, action_namespace, NULL);
153 gtk_menu_tracker_section_sync_separators (tracker->toplevel, tracker, 0, FALSE, NULL, 0);
154
155 return tracker;
156
157=== modified file 'libqmenumodel/src/gtk/gtkmenutracker.h'
158--- libqmenumodel/src/gtk/gtkmenutracker.h 2013-06-04 19:35:59 +0000
159+++ libqmenumodel/src/gtk/gtkmenutracker.h 2017-03-16 15:38:21 +0000
160@@ -26,11 +26,12 @@
161
162 typedef struct _GtkMenuTracker GtkMenuTracker;
163
164-typedef void (* GtkMenuTrackerInsertFunc) (GtkMenuTrackerItem *item,
165+typedef void (* GtkMenuTrackerInsertFunc) (GPtrArray *items,
166 gint position,
167 gpointer user_data);
168
169 typedef void (* GtkMenuTrackerRemoveFunc) (gint position,
170+ gint n_items,
171 gpointer user_data);
172
173
174
175=== modified file 'libqmenumodel/src/unitymenumodel.cpp'
176--- libqmenumodel/src/unitymenumodel.cpp 2016-12-09 17:06:25 +0000
177+++ libqmenumodel/src/unitymenumodel.cpp 2017-03-16 15:38:21 +0000
178@@ -89,8 +89,8 @@
179
180 static void nameAppeared(GDBusConnection *connection, const gchar *name, const gchar *owner, gpointer user_data);
181 static void nameVanished(GDBusConnection *connection, const gchar *name, gpointer user_data);
182- static void menuItemInserted(GtkMenuTrackerItem *item, gint position, gpointer user_data);
183- static void menuItemRemoved(gint position, gpointer user_data);
184+ static void menuItemInserted(GPtrArray *items, gint position, gpointer user_data);
185+ static void menuItemRemoved(gint position, gint n_items, gpointer user_data);
186 static void menuItemChanged(GObject *object, GParamSpec *pspec, gpointer user_data);
187
188 static void registeredActionAdded(GtkSimpleActionObserver *observer_item,
189@@ -250,19 +250,19 @@
190 priv->clearName();
191 }
192
193-void UnityMenuModelPrivate::menuItemInserted(GtkMenuTrackerItem *item, gint position, gpointer user_data)
194+void UnityMenuModelPrivate::menuItemInserted(GPtrArray *items, gint position, gpointer user_data)
195 {
196 UnityMenuModelPrivate *priv = (UnityMenuModelPrivate *)user_data;
197
198- UnityMenuModelAddRowEvent ummare(item, position);
199+ UnityMenuModelAddRowEvent ummare(items, position);
200 QCoreApplication::sendEvent(priv->model, &ummare);
201 }
202
203-void UnityMenuModelPrivate::menuItemRemoved(gint position, gpointer user_data)
204+void UnityMenuModelPrivate::menuItemRemoved(gint position, gint n_items, gpointer user_data)
205 {
206 UnityMenuModelPrivate *priv = (UnityMenuModelPrivate *)user_data;
207
208- UnityMenuModelRemoveRowEvent ummrre(position);
209+ UnityMenuModelRemoveRowEvent ummrre(position, n_items);
210 QCoreApplication::sendEvent(priv->model, &ummrre);
211 }
212
213@@ -797,26 +797,29 @@
214 GSequenceIter *it;
215 it = g_sequence_get_iter_at_pos (priv->items, ummrce->position);
216
217- beginInsertRows(QModelIndex(), ummrce->position, ummrce->position);
218+ beginInsertRows(QModelIndex(), ummrce->position, ummrce->position + ummrce->items->len - 1);
219
220- it = g_sequence_insert_before (it, g_object_ref (ummrce->item));
221- g_object_set_qdata (G_OBJECT (ummrce->item), unity_menu_model_quark (), this);
222- g_signal_connect (ummrce->item, "notify", G_CALLBACK (UnityMenuModelPrivate::menuItemChanged), it);
223+ for (gint i = ummrce->items->len - 1; i >= 0; --i) {
224+ GtkMenuTrackerItem *item = (GtkMenuTrackerItem*)g_ptr_array_index(ummrce->items, i);
225+ it = g_sequence_insert_before (it, g_object_ref (item));
226+ g_object_set_qdata (G_OBJECT (item), unity_menu_model_quark (), this);
227+ g_signal_connect (item, "notify", G_CALLBACK (UnityMenuModelPrivate::menuItemChanged), it);
228+ }
229
230 endInsertRows();
231 return true;
232 } else if (e->type() == UnityMenuModelRemoveRowEvent::eventType) {
233 UnityMenuModelRemoveRowEvent *ummrre = static_cast<UnityMenuModelRemoveRowEvent*>(e);
234
235- GSequenceIter *it;
236- it = g_sequence_get_iter_at_pos (priv->items, ummrre->position);
237- if (!g_sequence_iter_is_end (it)) {
238- beginRemoveRows(QModelIndex(), ummrre->position, ummrre->position);
239-
240- g_sequence_remove (it);
241-
242- endRemoveRows();
243+ beginRemoveRows(QModelIndex(), ummrre->position, ummrre->position + ummrre->nItems - 1);
244+ for (int i = 0; i < ummrre->nItems; ++i) {
245+ GSequenceIter *it = g_sequence_get_iter_at_pos (priv->items, ummrre->position);
246+ if (!g_sequence_iter_is_end (it)) {
247+ g_sequence_remove (it);
248+ }
249 }
250+ endRemoveRows();
251+
252 return true;
253 } else if (e->type() == UnityMenuModelDataChangeEvent::eventType) {
254 UnityMenuModelDataChangeEvent *ummdce = static_cast<UnityMenuModelDataChangeEvent*>(e);
255
256=== modified file 'libqmenumodel/src/unitymenumodelevents.cpp'
257--- libqmenumodel/src/unitymenumodelevents.cpp 2013-08-09 09:50:12 +0000
258+++ libqmenumodel/src/unitymenumodelevents.cpp 2017-03-16 15:38:21 +0000
259@@ -35,26 +35,30 @@
260 reset(_reset)
261 {}
262
263-UnityMenuModelAddRowEvent::UnityMenuModelAddRowEvent(GtkMenuTrackerItem *_item, int _position)
264+UnityMenuModelAddRowEvent::UnityMenuModelAddRowEvent(GPtrArray *_items, int _position)
265 : QEvent(UnityMenuModelAddRowEvent::eventType),
266- item(_item),
267+ items(_items),
268 position(_position)
269 {
270- if (item) {
271- g_object_ref(item);
272+ if (items) {
273+ for (gint i = 0; i < items->len; ++i)
274+ g_object_ref(g_ptr_array_index(items, i));
275+ g_ptr_array_ref(items);
276 }
277 }
278
279 UnityMenuModelAddRowEvent::~UnityMenuModelAddRowEvent()
280 {
281- if (item) {
282- g_object_unref(item);
283+ if (items) {
284+ for (gint i = 0; i < items->len; ++i)
285+ g_object_unref(g_ptr_array_index(items, i));
286+ g_ptr_array_unref(items);
287 }
288 }
289
290-UnityMenuModelRemoveRowEvent::UnityMenuModelRemoveRowEvent(int _position)
291+UnityMenuModelRemoveRowEvent::UnityMenuModelRemoveRowEvent(int _position, int _nItems)
292 : QEvent(UnityMenuModelRemoveRowEvent::eventType),
293- position(_position)
294+ position(_position), nItems(_nItems)
295 {}
296
297 UnityMenuModelDataChangeEvent::UnityMenuModelDataChangeEvent(int _position)
298
299=== modified file 'libqmenumodel/src/unitymenumodelevents.h'
300--- libqmenumodel/src/unitymenumodelevents.h 2013-08-09 09:50:12 +0000
301+++ libqmenumodel/src/unitymenumodelevents.h 2017-03-16 15:38:21 +0000
302@@ -21,6 +21,7 @@
303 #define UNITYMENUMODELEVENTS_H
304
305 #include <QEvent>
306+#include <glib.h>
307
308 typedef struct _GtkMenuTrackerItem GtkMenuTrackerItem;
309
310@@ -39,10 +40,10 @@
311 {
312 public:
313 static const QEvent::Type eventType;
314- UnityMenuModelAddRowEvent(GtkMenuTrackerItem *item, int position);
315+ UnityMenuModelAddRowEvent(GPtrArray *_items, int position);
316 ~UnityMenuModelAddRowEvent();
317
318- GtkMenuTrackerItem *item;
319+ GPtrArray *items;
320 int position;
321 };
322
323@@ -51,9 +52,10 @@
324 {
325 public:
326 static const QEvent::Type eventType;
327- UnityMenuModelRemoveRowEvent(int position);
328+ UnityMenuModelRemoveRowEvent(int position, int nItems);
329
330 int position;
331+ int nItems;
332 };
333
334 /* Event for a row data change for unitymenumodel */

Subscribers

People subscribed via source and target branches