Merge lp:~dbusmenu-team/libdbusmenu/ubuntu into lp:~ubuntu-desktop/libdbusmenu/ubuntu

Proposed by Ted Gould
Status: Merged
Merged at revision: not available
Proposed branch: lp:~dbusmenu-team/libdbusmenu/ubuntu
Merge into: lp:~ubuntu-desktop/libdbusmenu/ubuntu
Diff against target: None lines
To merge this branch: bzr merge lp:~dbusmenu-team/libdbusmenu/ubuntu
Reviewer Review Type Date Requested Status
Ken VanDine Pending
Review via email: mp+11152@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Ted Gould (ted) wrote :

Update to upstream version 0.1.1.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2009-07-18 02:43:25 +0000
3+++ .bzrignore 2009-09-03 19:26:18 +0000
4@@ -1,5 +1,6 @@
5 compile
6 m4
7+debian/compat
8 libdbusmenu-glib/.deps
9 libdbusmenu-glib/.libs
10 libdbusmenu-glib/dbusmenu-glib.pc
11@@ -41,4 +42,4 @@
12 dbusmenu.py
13 mago.results
14 test-glib-simple-items
15-debian/compat
16+libdbusmenu-gtk/libdbusmenu_gtk_la-menuitem.lo
17
18=== modified file 'configure.ac'
19--- configure.ac 2009-08-27 18:25:07 +0000
20+++ configure.ac 2009-09-03 19:16:48 +0000
21@@ -1,11 +1,11 @@
22
23-AC_INIT(libdbusmenu, 0.1.0, ted@canonical.com)
24+AC_INIT(libdbusmenu, 0.1.1, ted@canonical.com)
25 AC_COPYRIGHT([Copyright 2009 Canonical])
26
27 AC_PREREQ(2.53)
28
29 AM_CONFIG_HEADER(config.h)
30-AM_INIT_AUTOMAKE(libdbusmenu, 0.1.0)
31+AM_INIT_AUTOMAKE(libdbusmenu, 0.1.1)
32
33 AM_MAINTAINER_MODE
34
35
36=== modified file 'debian/changelog'
37--- debian/changelog 2009-08-27 18:32:15 +0000
38+++ debian/changelog 2009-09-03 19:29:59 +0000
39@@ -1,3 +1,9 @@
40+libdbusmenu (0.1.1-0ubuntu1~ppa1) karmic; urgency=low
41+
42+ * Upstream release 0.1.1
43+
44+ -- Ted Gould <ted@ubuntu.com> Thu, 03 Sep 2009 14:28:11 -0500
45+
46 libdbusmenu (0.1.0-0ubuntu1) UNRELEASED; urgency=low
47
48 * Upstream release 0.1.0
49
50=== modified file 'libdbusmenu-glib/menuitem.h'
51--- libdbusmenu-glib/menuitem.h 2009-08-26 20:18:50 +0000
52+++ libdbusmenu-glib/menuitem.h 2009-09-02 14:48:52 +0000
53@@ -51,6 +51,7 @@
54 #define DBUSMENU_MENUITEM_SIGNAL_REALIZED_ID (g_signal_lookup(DBUSMENU_MENUITEM_SIGNAL_REALIZED, DBUSMENU_TYPE_MENUITEM))
55
56 #define DBUSMENU_MENUITEM_PROP_VISIBLE "visible"
57+#define DBUSMENU_MENUITEM_PROP_SENSITIVE "sensitive"
58 #define DBUSMENU_MENUITEM_PROP_LABEL "label"
59 #define DBUSMENU_MENUITEM_PROP_ICON "icon"
60 #define DBUSMENU_MENUITEM_PROP_ICON_DATA "icon-data"
61
62=== modified file 'libdbusmenu-gtk/Makefile.am'
63--- libdbusmenu-gtk/Makefile.am 2009-06-24 04:05:44 +0000
64+++ libdbusmenu-gtk/Makefile.am 2009-09-02 18:29:01 +0000
65@@ -9,13 +9,16 @@
66
67 libdbusmenu_gtkinclude_HEADERS = \
68 client.h \
69- menu.h
70+ menu.h \
71+ menuitem.h
72
73 libdbusmenu_gtk_la_SOURCES = \
74 client.h \
75 client.c \
76 menu.h \
77- menu.c
78+ menu.c \
79+ menuitem.h \
80+ menuitem.c
81
82 libdbusmenu_gtk_la_LDFLAGS = \
83 -version-info $(LIBDBUSMENU_CURRENT):$(LIBDBUSMENU_REVISION):$(LIBDBUSMENU_AGE) \
84
85=== modified file 'libdbusmenu-gtk/client.c'
86--- libdbusmenu-gtk/client.c 2009-08-27 13:45:49 +0000
87+++ libdbusmenu-gtk/client.c 2009-09-03 19:16:01 +0000
88@@ -33,6 +33,7 @@
89 #include <gtk/gtk.h>
90
91 #include "client.h"
92+#include "menuitem.h"
93
94 /* Prototypes */
95 static void dbusmenu_gtkclient_class_init (DbusmenuGtkClientClass *klass);
96@@ -48,6 +49,9 @@
97 static gboolean new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
98 static gboolean new_item_image (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
99
100+static void process_visible (GtkMenuItem * gmi, const gchar * value);
101+static void process_sensitive (GtkMenuItem * gmi, const gchar * value);
102+
103 /* GObject Stuff */
104 G_DEFINE_TYPE (DbusmenuGtkClient, dbusmenu_gtkclient, DBUSMENU_TYPE_CLIENT);
105
106@@ -116,6 +120,18 @@
107 return;
108 }
109
110+/* Process the sensitive property */
111+static void
112+process_sensitive (GtkMenuItem * gmi, const gchar * value)
113+{
114+ if (value == NULL || !g_strcmp0(value, "true")) {
115+ gtk_widget_set_sensitive(GTK_WIDGET(gmi), TRUE);
116+ } else {
117+ gtk_widget_set_sensitive(GTK_WIDGET(gmi), FALSE);
118+ }
119+ return;
120+}
121+
122 /* Whenever we have a property change on a DbusmenuMenuitem
123 we need to be responsive to that. */
124 static void
125@@ -125,6 +141,8 @@
126 gtk_menu_item_set_label(gmi, value);
127 } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_VISIBLE)) {
128 process_visible(gmi, value);
129+ } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_SENSITIVE)) {
130+ process_sensitive(gmi, value);
131 }
132
133 return;
134@@ -171,6 +189,7 @@
135 g_object_weak_ref(G_OBJECT(item), destoryed_dbusmenuitem_cb, gmi);
136
137 process_visible(gmi, dbusmenu_menuitem_property_get(item, DBUSMENU_MENUITEM_PROP_VISIBLE));
138+ process_sensitive(gmi, dbusmenu_menuitem_property_get(item, DBUSMENU_MENUITEM_PROP_SENSITIVE));
139
140 if (parent != NULL) {
141 new_child(parent, item, dbusmenu_menuitem_get_position(item, parent), DBUSMENU_GTKCLIENT(client));
142@@ -284,6 +303,8 @@
143 return mi;
144 }
145
146+/* The base type handler that builds a plain ol'
147+ GtkMenuItem to represent, well, the GtkMenuItem */
148 static gboolean
149 new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
150 {
151@@ -303,6 +324,8 @@
152 return TRUE;
153 }
154
155+/* Type handler for the seperators where it builds
156+ a GtkSeparator to act as the GtkMenuItem */
157 static gboolean
158 new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
159 {
160@@ -322,9 +345,124 @@
161 return TRUE;
162 }
163
164+/* This handler looks at property changes for items that are
165+ image menu items. */
166+static void
167+image_property_handle (DbusmenuMenuitem * item, const gchar * property, const gchar * value, gpointer userdata)
168+{
169+ /* We're only looking at these two properties here */
170+ g_return_if_fail(!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON) || !g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON_DATA));
171+
172+ if (value == NULL || value[0] == '\0') {
173+ /* This means that we're unsetting a value. */
174+ /* Try to use the other one */
175+ if (g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON)) {
176+ property = DBUSMENU_MENUITEM_PROP_ICON_DATA;
177+ } else {
178+ property = DBUSMENU_MENUITEM_PROP_ICON;
179+ }
180+ }
181+
182+ /* Grab the data of the items that we've got, so that
183+ we can know how things need to change. */
184+ GtkMenuItem * gimi = dbusmenu_gtkclient_menuitem_get (DBUSMENU_GTKCLIENT(userdata), item);
185+ if (gimi == NULL) {
186+ g_warning("Oddly we're handling image properties on a menuitem that doesn't have any GTK structures associated with it.");
187+ return;
188+ }
189+ GtkWidget * gtkimage = gtk_image_menu_item_get_image(GTK_IMAGE_MENU_ITEM(gimi));
190+
191+ if (!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON_DATA)) {
192+ /* If we have an image already built from a name that is
193+ way better than a pixbuf. Keep it. */
194+ if (gtk_image_get_storage_type(GTK_IMAGE(gtkimage)) == GTK_IMAGE_ICON_NAME) {
195+ return;
196+ }
197+ }
198+
199+ /* Now figure out what to change */
200+ if (!g_strcmp0(property, DBUSMENU_MENUITEM_PROP_ICON)) {
201+ const gchar * iconname = dbusmenu_menuitem_property_get(item, property);
202+ if (iconname == NULL) {
203+ /* If there is no name, by golly we want no
204+ icon either. */
205+ gtkimage = NULL;
206+ } else {
207+ /* If we don't have an image, we need to build
208+ one so that we can set the name. Otherwise we
209+ can just convert it to this name. */
210+ if (gtkimage == NULL) {
211+ gtkimage = gtk_image_new_from_icon_name(iconname, GTK_ICON_SIZE_MENU);
212+ } else {
213+ gtk_image_set_from_icon_name(GTK_IMAGE(gtkimage), iconname, GTK_ICON_SIZE_MENU);
214+ }
215+ }
216+ } else {
217+ GdkPixbuf * image = dbusmenu_menuitem_property_get_image(item, property);
218+ if (image == NULL) {
219+ /* If there is no pixbuf, by golly we want no
220+ icon either. */
221+ gtkimage = NULL;
222+ } else {
223+ /* Resize the pixbuf */
224+ gint width, height;
225+ gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
226+ if (gdk_pixbuf_get_width(image) > width ||
227+ gdk_pixbuf_get_height(image) > height) {
228+ GdkPixbuf * newimage = gdk_pixbuf_scale_simple(image,
229+ width,
230+ height,
231+ GDK_INTERP_BILINEAR);
232+ g_object_unref(image);
233+ image = newimage;
234+ }
235+
236+ /* If we don't have an image, we need to build
237+ one so that we can set the pixbuf. */
238+ if (gtkimage == NULL) {
239+ gtkimage = gtk_image_new_from_pixbuf(image);
240+ } else {
241+ gtk_image_set_from_pixbuf(GTK_IMAGE(gtkimage), image);
242+ }
243+ }
244+
245+ }
246+
247+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(gimi), gtkimage);
248+
249+ return;
250+}
251+
252+/* This is a type call back for the image type where
253+ it uses the GtkImageMenuitem to create the menu item. */
254 static gboolean
255 new_item_image (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
256 {
257+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
258+ g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
259+ /* Note: not checking parent, it's reasonable for it to be NULL */
260+
261+ GtkMenuItem * gmi;
262+ gmi = GTK_MENU_ITEM(gtk_image_menu_item_new_with_label(dbusmenu_menuitem_property_get(newitem, DBUSMENU_MENUITEM_PROP_LABEL)));
263+
264+ if (gmi != NULL) {
265+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent);
266+ } else {
267+ return FALSE;
268+ }
269+
270+ image_property_handle(newitem,
271+ DBUSMENU_MENUITEM_PROP_ICON,
272+ dbusmenu_menuitem_property_get(newitem, DBUSMENU_MENUITEM_PROP_ICON),
273+ client);
274+ image_property_handle(newitem,
275+ DBUSMENU_MENUITEM_PROP_ICON_DATA,
276+ dbusmenu_menuitem_property_get(newitem, DBUSMENU_MENUITEM_PROP_ICON_DATA),
277+ client);
278+ g_signal_connect(G_OBJECT(newitem),
279+ DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED,
280+ G_CALLBACK(image_property_handle),
281+ client);
282
283 return TRUE;
284 }
285
286=== added file 'libdbusmenu-gtk/menuitem.c'
287--- libdbusmenu-gtk/menuitem.c 1970-01-01 00:00:00 +0000
288+++ libdbusmenu-gtk/menuitem.c 2009-09-02 18:50:29 +0000
289@@ -0,0 +1,130 @@
290+/*
291+A library to take the object model made consistent by libdbusmenu-glib
292+and visualize it in GTK.
293+
294+Copyright 2009 Canonical Ltd.
295+
296+Authors:
297+ Ted Gould <ted@canonical.com>
298+
299+This program is free software: you can redistribute it and/or modify it
300+under the terms of either or both of the following licenses:
301+
302+1) the GNU Lesser General Public License version 3, as published by the
303+Free Software Foundation; and/or
304+2) the GNU Lesser General Public License version 2.1, as published by
305+the Free Software Foundation.
306+
307+This program is distributed in the hope that it will be useful, but
308+WITHOUT ANY WARRANTY; without even the implied warranties of
309+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
310+PURPOSE. See the applicable version of the GNU Lesser General Public
311+License for more details.
312+
313+You should have received a copy of both the GNU Lesser General Public
314+License version 3 and version 2.1 along with this program. If not, see
315+<http://www.gnu.org/licenses/>
316+*/
317+
318+#include "menuitem.h"
319+
320+/**
321+ dbusmenu_menuitem_property_set_image:
322+ @menuitem: The #DbusmenuMenuitem to set the property on.
323+ @property: Name of the property to set.
324+ @data: The image to place on the property.
325+
326+ This function takes the pixbuf that is stored in @data and
327+ turns it into a base64 encoded PNG so that it can be placed
328+ onto a standard #DbusmenuMenuitem property.
329+
330+ Return value: Whether the function was able to set the property
331+ or not.
332+*/
333+gboolean
334+dbusmenu_menuitem_property_set_image (DbusmenuMenuitem * menuitem, const gchar * property, const GdkPixbuf * data)
335+{
336+ g_return_val_if_fail(GDK_IS_PIXBUF(data), FALSE);
337+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(menuitem), FALSE);
338+ g_return_val_if_fail(property != NULL && property[0] != '\0', FALSE);
339+
340+ GError * error = NULL;
341+ gchar * png_data;
342+ gsize png_data_len;
343+
344+ if (!gdk_pixbuf_save_to_buffer((GdkPixbuf *)data, &png_data, &png_data_len, "png", &error, NULL)) {
345+ if (error == NULL) {
346+ g_warning("Unable to create pixbuf data stream: %d", png_data_len);
347+ } else {
348+ g_warning("Unable to create pixbuf data stream: %s", error->message);
349+ g_error_free(error);
350+ error = NULL;
351+ }
352+
353+ return FALSE;
354+ }
355+
356+ gchar * prop_str = g_base64_encode((guchar *)png_data, png_data_len);
357+ gboolean propreturn = FALSE;
358+ propreturn = dbusmenu_menuitem_property_set(menuitem, property, prop_str);
359+
360+ g_free(prop_str);
361+ g_free(png_data);
362+
363+ return propreturn;
364+}
365+
366+/**
367+ dbusmenu_menuitem_property_get_image:
368+ @menuitem: The #DbusmenuMenuite to look for the property on
369+ @property: The name of the property to look for.
370+
371+ This function looks on the menu item for a property by the
372+ name of @property. If one exists it tries to turn it into
373+ a #GdkPixbuf. It assumes that the property is a base64 encoded
374+ PNG file like the one created by #dbusmenu_menuite_property_set_image.
375+
376+ Return value: A pixbuf or #NULL to signal error.
377+*/
378+GdkPixbuf *
379+dbusmenu_menuitem_property_get_image (DbusmenuMenuitem * menuitem, const gchar * property)
380+{
381+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(menuitem), NULL);
382+ g_return_val_if_fail(property != NULL && property[0] != '\0', NULL);
383+
384+ const gchar * value = dbusmenu_menuitem_property_get(menuitem, property);
385+
386+ /* There is no icon */
387+ if (value == NULL || value[0] == '\0') {
388+ return NULL;
389+ }
390+
391+ gsize length = 0;
392+ guchar * icondata = g_base64_decode(value, &length);
393+
394+ GInputStream * input = g_memory_input_stream_new_from_data(icondata, length, NULL);
395+ if (input == NULL) {
396+ g_warning("Cound not create input stream from icon property data");
397+ g_free(icondata);
398+ return NULL;
399+ }
400+
401+ GError * error = NULL;
402+ GdkPixbuf * icon = gdk_pixbuf_new_from_stream(input, NULL, &error);
403+
404+ if (error != NULL) {
405+ g_warning("Unable to build Pixbuf from icon data: %s", error->message);
406+ g_error_free(error);
407+ }
408+
409+ error = NULL;
410+ g_input_stream_close(input, NULL, &error);
411+ if (error != NULL) {
412+ g_warning("Unable to close input stream: %s", error->message);
413+ g_error_free(error);
414+ }
415+ g_free(icondata);
416+
417+ return icon;
418+}
419+
420
421=== added file 'libdbusmenu-gtk/menuitem.h'
422--- libdbusmenu-gtk/menuitem.h 1970-01-01 00:00:00 +0000
423+++ libdbusmenu-gtk/menuitem.h 2009-09-02 18:29:01 +0000
424@@ -0,0 +1,39 @@
425+/*
426+A library to take the object model made consistent by libdbusmenu-glib
427+and visualize it in GTK.
428+
429+Copyright 2009 Canonical Ltd.
430+
431+Authors:
432+ Ted Gould <ted@canonical.com>
433+
434+This program is free software: you can redistribute it and/or modify it
435+under the terms of either or both of the following licenses:
436+
437+1) the GNU Lesser General Public License version 3, as published by the
438+Free Software Foundation; and/or
439+2) the GNU Lesser General Public License version 2.1, as published by
440+the Free Software Foundation.
441+
442+This program is distributed in the hope that it will be useful, but
443+WITHOUT ANY WARRANTY; without even the implied warranties of
444+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
445+PURPOSE. See the applicable version of the GNU Lesser General Public
446+License for more details.
447+
448+You should have received a copy of both the GNU Lesser General Public
449+License version 3 and version 2.1 along with this program. If not, see
450+<http://www.gnu.org/licenses/>
451+*/
452+
453+#ifndef __DBUSMENU_GTKMENUITEM_H__
454+#define __DBUSMENU_GTKMENUITEM_H__ 1
455+
456+#include <glib.h>
457+#include <gdk-pixbuf/gdk-pixbuf.h>
458+#include <libdbusmenu-glib/menuitem.h>
459+
460+gboolean dbusmenu_menuitem_property_set_image (DbusmenuMenuitem * menuitem, const gchar * property, const GdkPixbuf * data);
461+GdkPixbuf * dbusmenu_menuitem_property_get_image (DbusmenuMenuitem * menuitem, const gchar * property);
462+
463+#endif
464
465=== modified file 'tests/test-gtk-label-server.c'
466--- tests/test-gtk-label-server.c 2009-07-20 21:04:00 +0000
467+++ tests/test-gtk-label-server.c 2009-09-02 20:13:15 +0000
468@@ -156,7 +156,7 @@
469 server = dbusmenu_server_new("/org/test");
470
471 timer_func(NULL);
472- g_timeout_add_seconds(15, timer_func, NULL);
473+ g_timeout_add_seconds(5, timer_func, NULL);
474
475 mainloop = g_main_loop_new(NULL, FALSE);
476 g_main_loop_run(mainloop);
477
478=== modified file 'tests/test-gtk-label.json'
479--- tests/test-gtk-label.json 2009-08-26 20:32:37 +0000
480+++ tests/test-gtk-label.json 2009-09-03 19:16:01 +0000
481@@ -49,6 +49,52 @@
482 "label": "value29"}
483 ]
484 },
485+ {"id": 4, "type": "menuitem",
486+ "label": "value4",
487+ "submenu": [
488+ {"id": 40,
489+ "type": "menuitem",
490+ "sensitive": "true",
491+ "label": "value40"},
492+ {"id": 41,
493+ "type": "menuitem",
494+ "sensitive": "false",
495+ "label": "value41"},
496+ {"id": 42,
497+ "type": "menuitem",
498+ "sensitive": "true",
499+ "label": "value42"},
500+ {"id": 43,
501+ "type": "menuitem",
502+ "sensitive": "false",
503+ "label": "value43"},
504+ {"id": 44,
505+ "type": "menuitem",
506+ "sensitive": "true",
507+ "label": "value44"},
508+ {"id": 45,
509+ "type": "menuitem",
510+ "sensitive": "false",
511+ "label": "value45"},
512+ {"id": 46,
513+ "type": "menuitem",
514+ "sensitive": "true",
515+ "label": "value46"},
516+ {"id": 47,
517+ "type": "menuitem",
518+ "sensitive": "false",
519+ "label": "value47"},
520+ {"id": 48,
521+ "type": "menuitem",
522+ "sensitive": "true",
523+ "label": "value48"},
524+ {"id": 49,
525+ "type": "menuitem",
526+ "visible": "false",
527+ "sensitive": "false",
528+ "label": "value49"}
529+ ]
530+ },
531 {"id": 3, "type": "menuitem",
532 "label": "a super long label that is really of unreasonable length but we should make sure it makes it across the bus",
533 "not.a.value": "A useless value",
534@@ -154,5 +200,123 @@
535 ]
536 },
537 ]
538- }
539+ },
540+ {"id": 8, "type": "menuitem",
541+ "label": "value1",
542+ "submenu": [
543+ {"id": 80,
544+ "type": "imageitem",
545+ "icon": "face-angel",
546+ "label": "angel"},
547+ {"id": 81,
548+ "type": "imageitem",
549+ "icon": "face-angry",
550+ "label": "angry"},
551+ {"id": 82,
552+ "type": "imageitem",
553+ "icon": "face-cool",
554+ "label": "cool"},
555+ {"id": 83,
556+ "type":"imageitem",
557+ "icon": "face-devilish",
558+ "label": "devilish"},
559+ {"id": 84,
560+ "type": "imageitem",
561+ "icon": "face-embarrassed",
562+ "label": "embarrassed"},
563+ {"id": 85,
564+ "type": "imageitem",
565+ "icon": "face-kiss",
566+ "label": "kiss"},
567+ {"id": 86,
568+ "type": "imageitem",
569+ "icon": "face-laugh",
570+ "label": "laugh"},
571+ {"id": 87,
572+ "type": "imageitem",
573+ "icon": "face-monkey",
574+ "label": "monkey"},
575+ {"id": 88,
576+ "type": "imageitem",
577+ "icon": "face-sad",
578+ "label": "sad"},
579+ {"id": 89,
580+ "type": "imageitem",
581+ "icon": "face-sick",
582+ "label": "sick"}
583+ ]
584+ },
585+ {"id": 9, "type": "menuitem",
586+ "label": "value1",
587+ "submenu": [
588+ {"id": 90,
589+ "type": "imageitem",
590+ "icon-data":
591+"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACPUlEQVR4nGJgoBAAAAAA///Ch1gW
592+BzK0LQ5iaGNgYGDBpQgAAAD//8KpeY4/Q9+DCV7/H/S4/p8byDABlyEAAAAA///CqnluAMOEx5O8
593+/3/f0/P/+47m/4967P7PC2GYysDAwIquGAAAAP//YkLXPC+AodfNyStfRMuegenvdwamP98ZhJWM
594+GJzNzLIWhGMaAgAAAP//YkLT3Odq75InomrBwPT7CwPDr68M//98Y2D+951BREadwdFAL3VxJMNM
595+ZEMAAAAA//9ihPs5gKHPzdo2V0TNkoGZ4T/D//9/GRj+/WJg+PeT4f/vHwwMf78z/P31jeHN89sM
596++6/dXpS4lCGFgYHhNwAAAP//ghkguDqC4Z0CNwMDLwsDgxAHAwOfdQrD/1+fGP5/e83w/9tbhq/P
597+LjG8+8PA8PkPA8PDbwwMIXMYhBkYGN4BAAAA//80zDEOQDAAAMBLZ2MnITEafEziK2YfM/QBLDoX
598+g4jJPeD+IGJAgypNlrbuvNfBcxLYb/rZiIINK/IHAAD//zTRoRHAIBAAsMAU3X8iZCUSy5W7R0EN
599+rJDcmoEXFU8sVq/ko5SIDQoaJj74AQAA//+CGfADKoEIGZhmZiQ+RM0D5FgAAAAA//9Cj0aEKNRm
600+uGZmrCoZAAAAAP//wm4AskZkg7AAAAAAAP//wpo8n/6A2siEoJ/+wG4AAAAA///CZq4EAwODAZRG
601+Bi8YEIEIBwAAAAD//8JmAAcDA4MAlEYGPxgYGD5AaTgAAAAA//8DAD6xjTP5Y+A7AAAAAElFTkSu
602+QmCC",
603+ "label": "up"},
604+ {"id": 91,
605+ "type": "imageitem",
606+ "icon-data":
607+"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACl0lEQVR4nGJgoBAAAAAA//9ixCLG
608+sSWS4bs0B1QWip/+YGDwWcLAycDA8ANZMQAAAP//YsFigIA0JwODdvIsBob/fxgY/vxk+P/7OwPD
609+6ioGBgYGAQYGhhfIigEAAAD//8JmAAcDEwMDw5/vDAz/fjP8//uLgeHvDwYGJqgcGgAAAAD//8Jm
610+AAMDIwPD/99fGBj+/WVg+PeLgeHvTwYGZqwqGQAAAAD//8JuADMDA8PPLwwMDH8Z/v//AzGACbsB
611+AAAAAP//wmoAJwsDw/8/XxgY/v9l+P/rM8P/ry8ZONmwGwAAAAD//4LFAsfqaIbvCtwMDLxsDAxC
612+7AwMPMqWDP+/Pmf4//01w//fXxm+/2NgePebgeHLHwaGR98ZGIKmQ2IEAAAA//80zisSQFAAAMAd
613+wczzKRSvCIqrO4XqGoIkGTOv+SV7gv1j1XqY2jiI/agoSve2eM7VeyUyQk5X0gT2ZEYNHwAAAP//
614+gnnhb+lWhuk//90TD1dncBThYGBgYWGA+JsRQv9lYGB4/5uBYcdDhotZSxhaGRgY/jEwMDAAAAAA
615+//+CueALAwPDnZrtDK3r7jIcefuHgeEvI5JmRgaG938YGHY9YriatYShkoGB4TYDA8MnBgYGBgAA
616+AAD//4IZ8JuBgeE1AwPDjfLNDE2b7jGcfPsLYutfRgaGD78ZGPY+ZrievpChjIGB4SoDA8NLqB4G
617+AAAAAP//QkesDAwMMgwMDG6TwxnO3q5i+H+nhuH/nESGawwMDF4MDAzyDAwMKPEBAAAA///CZYgs
618+AwODR18kw4UJ0QyX8WkGAAAA///ClpkYoAolGBgYFKBqHjAwMDxnYGD4ha4QAAAA///CZQDMEG4o
619++ys2zQwMDAwAAAAA//8DAAF5nhyE7tENAAAAAElFTkSuQmCC",
620+ "label": "down"},
621+ {"id": 92,
622+ "type": "imageitem",
623+ "icon": "up",
624+ "icon-data":
625+"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACl0lEQVR4nGJgoBAAAAAA//9ixCLG
626+sSWS4bs0B1QWip/+YGDwWcLAycDA8ANZMQAAAP//YsFigIA0JwODdvIsBob/fxgY/vxk+P/7OwPD
627+6ioGBgYGAQYGhhfIigEAAAD//8JmAAcDEwMDw5/vDAz/fjP8//uLgeHvDwYGJqgcGgAAAAD//8Jm
628+AAMDIwPD/99fGBj+/WVg+PeLgeHvTwYGZqwqGQAAAAD//8JuADMDA8PPLwwMDH8Z/v//AzGACbsB
629+AAAAAP//wmoAJwsDw/8/XxgY/v9l+P/rM8P/ry8ZONmwGwAAAAD//4LFAsfqaIbvCtwMDLxsDAxC
630+7AwMPMqWDP+/Pmf4//01w//fXxm+/2NgePebgeHLHwaGR98ZGIKmQ2IEAAAA//80zisSQFAAAMAd
631+wczzKRSvCIqrO4XqGoIkGTOv+SV7gv1j1XqY2jiI/agoSve2eM7VeyUyQk5X0gT2ZEYNHwAAAP//
632+gnnhb+lWhuk//90TD1dncBThYGBgYWGA+JsRQv9lYGB4/5uBYcdDhotZSxhaGRgY/jEwMDAAAAAA
633+//+CueALAwPDnZrtDK3r7jIcefuHgeEvI5JmRgaG938YGHY9YriatYShkoGB4TYDA8MnBgYGBgAA
634+AAD//4IZ8JuBgeE1AwPDjfLNDE2b7jGcfPsLYutfRgaGD78ZGPY+ZrievpChjIGB4SoDA8NLqB4G
635+AAAAAP//QkesDAwMMgwMDG6TwxnO3q5i+H+nhuH/nESGawwMDF4MDAzyDAwMKPEBAAAA///CZYgs
636+AwODR18kw4UJ0QyX8WkGAAAA///ClpkYoAolGBgYFKBqHjAwMDxnYGD4ha4QAAAA///CZQDMEG4o
637++ys2zQwMDAwAAAAA//8DAAF5nhyE7tENAAAAAElFTkSuQmCC",
638+ "label": "up"},
639+ {"id": 93,
640+ "type": "imageitem",
641+ "icon": "down",
642+ "icon-data":
643+"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACPUlEQVR4nGJgoBAAAAAA///Ch1gW
644+BzK0LQ5iaGNgYGDBpQgAAAD//8KpeY4/Q9+DCV7/H/S4/p8byDABlyEAAAAA///CqnluAMOEx5O8
645+/3/f0/P/+47m/4967P7PC2GYysDAwIquGAAAAP//YkLXPC+AodfNyStfRMuegenvdwamP98ZhJWM
646+GJzNzLIWhGMaAgAAAP//YkLT3Odq75InomrBwPT7CwPDr68M//98Y2D+951BREadwdFAL3VxJMNM
647+ZEMAAAAA//9ihPs5gKHPzdo2V0TNkoGZ4T/D//9/GRj+/WJg+PeT4f/vHwwMf78z/P31jeHN89sM
648++6/dXpS4lCGFgYHhNwAAAP//ghkguDqC4Z0CNwMDLwsDgxAHAwOfdQrD/1+fGP5/e83w/9tbhq/P
649+LjG8+8PA8PkPA8PDbwwMIXMYhBkYGN4BAAAA//80zDEOQDAAAMBLZ2MnITEafEziK2YfM/QBLDoX
650+g4jJPeD+IGJAgypNlrbuvNfBcxLYb/rZiIINK/IHAAD//zTRoRHAIBAAsMAU3X8iZCUSy5W7R0EN
651+rJDcmoEXFU8sVq/ko5SIDQoaJj74AQAA//+CGfADKoEIGZhmZiQ+RM0D5FgAAAAA//9Cj0aEKNRm
652+uGZmrCoZAAAAAP//wm4AskZkg7AAAAAAAP//wpo8n/6A2siEoJ/+wG4AAAAA///CZq4EAwODAZRG
653+Bi8YEIEIBwAAAAD//8JmAAcDA4MAlEYGPxgYGD5AaTgAAAAA//8DAD6xjTP5Y+A7AAAAAElFTkSu
654+QmCC",
655+ "label": "down"}
656+ ]
657+ },
658 ]

Subscribers

People subscribed via source and target branches

to all changes: