aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am311
-rw-r--r--tests/dbusmenu-jsonloader-0.4.pc.in14
-rw-r--r--tests/json-loader.c179
-rw-r--r--tests/json-loader.h31
-rw-r--r--tests/run-xvfb.sh2
-rw-r--r--tests/test-glib-events-client.c138
-rw-r--r--tests/test-glib-events-server.c103
-rw-r--r--tests/test-glib-layout-client.c5
-rw-r--r--tests/test-glib-layout-server.c53
-rw-r--r--tests/test-glib-objects.c70
-rw-r--r--tests/test-glib-properties-client.c2
-rw-r--r--tests/test-glib-properties-server.c7
-rw-r--r--tests/test-glib-proxy-client.c7
-rw-r--r--tests/test-glib-proxy-proxy.c52
-rw-r--r--tests/test-glib-proxy-server.c51
-rw-r--r--tests/test-glib-simple-items.c3
-rwxr-xr-xtests/test-glib-simple-items.py35
-rw-r--r--tests/test-glib-submenu-server.c53
-rw-r--r--tests/test-gtk-label-client.c2
-rw-r--r--tests/test-gtk-label-server.c123
-rw-r--r--tests/test-gtk-objects.c145
-rw-r--r--tests/test-gtk-objects.jpgbin0 -> 14376 bytes
-rw-r--r--tests/test-gtk-parser.c115
-rw-r--r--tests/test-gtk-reorder-server.c55
-rw-r--r--tests/test-gtk-shortcut-client.c76
-rwxr-xr-xtests/test-gtk-shortcut-client.py52
-rw-r--r--tests/test-gtk-shortcut-server.c100
-rw-r--r--tests/test-gtk-submenu-client.c150
-rw-r--r--tests/test-gtk-submenu-server.c114
-rw-r--r--tests/test-json-01.json4023
-rw-r--r--tests/test-json-client.c79
-rw-r--r--tests/test-json-server.c88
32 files changed, 5971 insertions, 267 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f1b50bc..61b3e69 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,19 +1,33 @@
DBUS_RUNNER=dbus-test-runner
+CLEANFILES=
+DISTCLEANFILES=
+EXTRA_DIST =
+
TESTS = \
test-glib-objects-test \
+ test-glib-events \
test-glib-layout \
test-glib-properties \
test-glib-proxy \
test-glib-simple-items \
test-glib-submenu \
+ test-json \
+ test-gtk-objects-test \
test-gtk-label \
- test-gtk-reorder
+ test-gtk-shortcut \
+ test-gtk-shortcut-python \
+ test-gtk-reorder \
+ test-gtk-submenu \
+ test-gtk-parser-test \
+ test-glib-simple-items.py
check_PROGRAMS = \
glib-server-nomenu \
test-glib-objects \
+ test-glib-events-client \
+ test-glib-events-server \
test-glib-layout-client \
test-glib-layout-server \
test-glib-properties-client \
@@ -21,15 +35,63 @@ check_PROGRAMS = \
test-glib-proxy-client \
test-glib-proxy-server \
test-glib-proxy-proxy \
+ test-gtk-objects \
test-glib-submenu-client \
test-glib-submenu-server \
test-gtk-label-client \
test-gtk-label-server \
+ test-gtk-shortcut-client \
+ test-gtk-shortcut-server \
test-glib-simple-items \
- test-gtk-reorder-server
+ test-gtk-reorder-server \
+ test-json-client \
+ test-json-server \
+ test-gtk-submenu-server \
+ test-gtk-submenu-client \
+ test-gtk-parser
XVFB_RUN=". $(srcdir)/run-xvfb.sh"
+# for the GI tests, prefer/use the typelibs from the local build tree
+TESTS_ENVIRONMENT = env GI_TYPELIB_PATH=$(top_builddir)/libdbusmenu-glib:$(top_builddir)/libdbusmenu-gtk:$(GI_TYPELIB_PATH)
+
+######################
+# JSON Loader lib
+######################
+
+lib_LTLIBRARIES = libdbusmenu-jsonloader.la
+
+libdbusmenu_jsonloaderincludedir=$(includedir)/libdbusmenu-0.4/libdbusmenu-jsonloader/
+
+libdbusmenu_jsonloaderinclude_HEADERS = \
+ json-loader.h
+
+libdbusmenu_jsonloader_la_SOURCES = \
+ json-loader.h \
+ json-loader.c
+
+libdbusmenu_jsonloader_la_LDFLAGS = \
+ -version-info $(LIBDBUSMENU_CURRENT):$(LIBDBUSMENU_REVISION):$(LIBDBUSMENU_AGE) \
+ -no-undefined \
+ -export-symbols-regex "^[^_].*"
+
+libdbusmenu_jsonloader_la_CFLAGS = \
+ $(DBUSMENUGLIB_CFLAGS) \
+ $(DBUSMENUTESTS_CFLAGS) \
+ -I $(srcdir)/.. \
+ -Wall \
+ -Werror \
+ -DG_DISABLE_DEPRECATED \
+ -DG_LOG_DOMAIN="\"LIBDBUSMENU-JSONLOADER\""
+
+libdbusmenu_jsonloader_la_LIBADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ $(DBUSMENUGLIB_LIBS) \
+ $(DBUSMENUTESTS_LIBS)
+
+pkgconfig_DATA = dbusmenu-jsonloader-0.4.pc
+pkgconfigdir = $(libdir)/pkgconfig
+
######################
# Test GLib server
######################
@@ -79,6 +141,78 @@ test_glib_layout_client_LDADD = \
$(DBUSMENUGLIB_LIBS)
######################
+# Test Glib Events
+######################
+
+test-glib-events: test-glib-events-client test-glib-events-server Makefile.am
+ @echo "#!/bin/bash" > $@
+ @echo $(DBUS_RUNNER) --task ./test-glib-events-client --task-name Client --task ./test-glib-events-server --task-name Server --ignore-return >> $@
+ @chmod +x $@
+
+test_glib_events_server_SOURCES = \
+ test-glib-events-server.c
+
+test_glib_events_server_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_glib_events_server_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ $(DBUSMENUGLIB_LIBS)
+
+test_glib_events_client_SOURCES = \
+ test-glib-events-client.c
+
+test_glib_events_client_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_glib_events_client_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ $(DBUSMENUGLIB_LIBS)
+
+######################
+# Test JSON
+######################
+
+test-json: test-json-client test-json-server Makefile.am
+ @echo "#!/bin/bash" > $@
+ @echo $(XVFB_RUN) >> $@
+ @echo $(DBUS_RUNNER) --task ./test-json-client --task-name Client --parameter $(top_builddir)/tools/dbusmenu-dumper --parameter test-json-01.output.json --ignore-return --task ./test-json-server --task-name Server --parameter $(srcdir)/test-json-01.json --ignore-return >> $@
+ @echo diff $(srcdir)/test-json-01.json test-json-01.output.json \> /dev/null >> $@
+ @chmod +x $@
+
+CLEANFILES += test-json-01.output.json
+
+test_json_server_SOURCES = \
+ test-json-server.c
+
+test_json_server_CFLAGS = \
+ -I $(srcdir)/.. \
+ -I $(srcdir) \
+ $(DBUSMENUGLIB_CFLAGS) \
+ $(DBUSMENUTESTS_CFLAGS) \
+ -Wall -Werror
+
+test_json_server_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ libdbusmenu-jsonloader.la \
+ $(DBUSMENUTESTS_LIBS) \
+ $(DBUSMENUGLIB_LIBS)
+
+test_json_client_SOURCES = \
+ test-json-client.c
+
+test_json_client_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_json_client_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ $(DBUSMENUTESTS_LIBS) \
+ $(DBUSMENUGLIB_LIBS)
+
+######################
# Test Glib Submenu
######################
@@ -119,7 +253,7 @@ OBJECT_XML_REPORT = test-glib-objects.xml
test-glib-objects-test: test-glib-objects Makefile.am
@echo "#!/bin/bash" > $@
- @echo $(DBUS_RUNNER) --task gtester --parameter --verbose --parameter -k --parameter -o --parameter $(OBJECT_XML_REPORT) --parameter ./test-glib-objects >> $@
+ @echo $(DBUS_RUNNER) --task gtester --task-name test --parameter --verbose --parameter -k --parameter -o --parameter $(OBJECT_XML_REPORT) --parameter ./test-glib-objects >> $@
@chmod +x $@
test_glib_objects_SOURCES = \
@@ -133,6 +267,8 @@ test_glib_objects_LDADD = \
../libdbusmenu-glib/libdbusmenu-glib.la \
$(DBUSMENUGLIB_LIBS)
+DISTCLEANFILES += $(OBJECT_XML_REPORT)
+
######################
# Test Glib Properties
######################
@@ -231,6 +367,68 @@ test_glib_simple_items_LDADD = \
../libdbusmenu-glib/libdbusmenu-glib.la \
$(DBUSMENUGLIB_LIBS)
+EXTRA_DIST += test-glib-simple-items.py
+
+######################
+# Test GTK Object
+######################
+
+GTK_OBJECT_XML_REPORT = test-gtk-objects.xml
+
+test-gtk-objects-test: test-gtk-objects Makefile.am
+ @echo "#!/bin/bash" > $@
+ @echo $(XVFB_RUN) >> $@
+ @echo $(DBUS_RUNNER) --task gtester --task-name test --parameter --verbose --parameter -k --parameter -o --parameter $(GTK_OBJECT_XML_REPORT) --parameter ./test-gtk-objects >> $@
+ @chmod +x $@
+
+test_gtk_objects_SOURCES = \
+ test-gtk-objects.c
+
+test_gtk_objects_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGLIB_CFLAGS) \
+ $(DBUSMENUGTK_CFLAGS) \
+ -DSRCDIR="\"$(srcdir)\"" \
+ -Wall -Werror
+
+test_gtk_objects_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ ../libdbusmenu-gtk/libdbusmenu-gtk.la \
+ $(DBUSMENUGLIB_LIBS) \
+ $(DBUSMENUGTK_LIBS)
+
+DISTCLEANFILES += $(GTK_OBJECT_XML_REPORT)
+
+######################
+# Test GTK Parser
+######################
+
+GTK_PARSER_XML_REPORT = test-gtk-parser.xml
+
+test-gtk-parser-test: test-gtk-parser Makefile.am
+ @echo "#!/bin/bash" > $@
+ @echo $(XVFB_RUN) >> $@
+ @echo gtester --verbose -k -o $(GTK_PARSER_XML_REPORT) ./test-gtk-parser >> $@
+ @chmod +x $@
+
+test_gtk_parser_SOURCES = \
+ test-gtk-parser.c
+
+test_gtk_parser_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGLIB_CFLAGS) \
+ $(DBUSMENUGTK_CFLAGS) \
+ -DSRCDIR="\"$(srcdir)\"" \
+ -Wall -Werror
+
+test_gtk_parser_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ ../libdbusmenu-gtk/libdbusmenu-gtk.la \
+ $(DBUSMENUGLIB_LIBS) \
+ $(DBUSMENUGTK_LIBS)
+
+DISTCLEANFILES += $(GTK_PARSER_XML_REPORT)
+
#########################
# Test GTK Label
#########################
@@ -253,6 +451,7 @@ test_gtk_label_server_CFLAGS = \
test_gtk_label_server_LDADD = \
../libdbusmenu-glib/libdbusmenu-glib.la \
../libdbusmenu-gtk/libdbusmenu-gtk.la \
+ libdbusmenu-jsonloader.la \
$(DBUSMENUGTK_LIBS) \
$(DBUSMENUTESTS_LIBS)
@@ -272,6 +471,59 @@ test_gtk_label_client_LDADD = \
$(DBUSMENUTESTS_LIBS)
#########################
+# Test GTK Shortcut
+#########################
+
+test-gtk-shortcut: test-gtk-shortcut-client test-gtk-shortcut-server Makefile.am
+ @echo "#!/bin/bash" > $@
+ @echo $(XVFB_RUN) >> $@
+ @echo $(DBUS_RUNNER) --task ./test-gtk-shortcut-client --task-name Client --task ./test-gtk-shortcut-server --task-name Server --ignore-return >> $@
+ @chmod +x $@
+
+test_gtk_shortcut_server_SOURCES = \
+ test-gtk-shortcut-server.c
+
+test_gtk_shortcut_server_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGTK_CFLAGS) \
+ $(DBUSMENUTESTS_CFLAGS) \
+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_gtk_shortcut_server_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ ../libdbusmenu-gtk/libdbusmenu-gtk.la \
+ $(DBUSMENUGTK_LIBS) \
+ $(DBUSMENUTESTS_LIBS)
+
+test_gtk_shortcut_client_SOURCES = \
+ test-gtk-shortcut-client.c
+
+test_gtk_shortcut_client_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGTK_CFLAGS) \
+ $(DBUSMENUTESTS_CFLAGS) \
+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_gtk_shortcut_client_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ ../libdbusmenu-gtk/libdbusmenu-gtk.la \
+ $(DBUSMENUGTK_LIBS) \
+ $(DBUSMENUTESTS_LIBS)
+
+#########################
+# Test GTK Shortcut Python
+#########################
+
+test-gtk-shortcut-python: test-gtk-shortcut-server test-gtk-shortcut-client.py Makefile.am
+ @echo "#!/bin/bash" > $@
+ @echo $(XVFB_RUN) >> $@
+ @echo $(DBUS_RUNNER) --task $(srcdir)/test-gtk-shortcut-client.py --task-name Client --task ./test-gtk-shortcut-server --task-name Server --ignore-return >> $@
+ @chmod +x $@
+
+EXTRA_DIST += test-gtk-shortcut-client.py
+CLEANFILES += test-gtk-shortcut-client.pyc
+
+#########################
# Test GTK Reorder
#########################
@@ -297,6 +549,46 @@ test_gtk_reorder_server_LDADD = \
$(DBUSMENUTESTS_LIBS)
#########################
+# Test GTK Submenu
+#########################
+
+test-gtk-submenu: test-gtk-submenu-client test-gtk-submenu-server Makefile.am
+ @echo "#!/bin/bash" > $@
+ @echo $(XVFB_RUN) >> $@
+ @echo $(DBUS_RUNNER) --task ./test-gtk-submenu-client --task-name Client --task ./test-gtk-submenu-server --task-name Server --ignore-return >> $@
+ @chmod +x $@
+
+test_gtk_submenu_server_SOURCES = \
+ test-gtk-submenu-server.c
+
+test_gtk_submenu_server_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGTK_CFLAGS) \
+ $(DBUSMENUTESTS_CFLAGS) \
+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_gtk_submenu_server_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ ../libdbusmenu-gtk/libdbusmenu-gtk.la \
+ $(DBUSMENUGTK_LIBS) \
+ $(DBUSMENUTESTS_LIBS)
+
+test_gtk_submenu_client_SOURCES = \
+ test-gtk-submenu-client.c
+
+test_gtk_submenu_client_CFLAGS = \
+ -I $(srcdir)/.. \
+ $(DBUSMENUGTK_CFLAGS) \
+ $(DBUSMENUTESTS_CFLAGS) \
+ $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
+
+test_gtk_submenu_client_LDADD = \
+ ../libdbusmenu-glib/libdbusmenu-glib.la \
+ ../libdbusmenu-gtk/libdbusmenu-gtk.la \
+ $(DBUSMENUGTK_LIBS) \
+ $(DBUSMENUTESTS_LIBS)
+
+#########################
# Test Mago
#########################
@@ -325,10 +617,11 @@ jsondir = $(datadir)/${PACKAGE}/json/
json_DATA = \
test-gtk-label.json
-EXTRA_DIST = \
+EXTRA_DIST += \
$(examples_DATA) \
run-xvfb.sh \
$(json_DATA) \
+ test-gtk-objects.jpg \
dbusmenu-gtk/dbusMenuTest \
dbusmenu-gtk/mago_tests/dbusmenu.xml \
dbusmenu-gtk/mago_tests/dbusmenu.py \
@@ -347,15 +640,15 @@ EXTRA_DIST = \
dbusmenu-gtk/mago_tests/data/several_submenus_recursive.json \
dbusmenu-gtk/mago_tests/data/several_submenus_utf8.json \
dbusmenu-gtk/mago_tests/data/static.json \
- dbusmenu-gtk/mago_tests/data/test-gtk-label.json
+ dbusmenu-gtk/mago_tests/data/test-gtk-label.json \
+ test-json-01.json
-CLEANFILES = \
+CLEANFILES += \
dbusmenu-gtk/mago_tests/dbusmenu.pyc
distclean-local:
-rm -rf $(builddir)/mago.results
-DISTCLEANFILES = \
- $(TESTS) \
- $(OBJECT_XML_REPORT)
+DISTCLEANFILES += \
+ $(filter-out %.py, $(TESTS))
diff --git a/tests/dbusmenu-jsonloader-0.4.pc.in b/tests/dbusmenu-jsonloader-0.4.pc.in
new file mode 100644
index 0000000..62bfeb2
--- /dev/null
+++ b/tests/dbusmenu-jsonloader-0.4.pc.in
@@ -0,0 +1,14 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+bindir=@bindir@
+includedir=@includedir@
+
+Cflags: -I${includedir}/libdbusmenu-0.1
+Requires: dbusmenu-glib-0.4 json-glib-1.0
+Libs: -L${libdir} -ldbusmenu-jsonloader
+
+Name: libdbusmenu-jsonloader
+Description: A small library to load JSON descriptions of menus. Mostly for testing.
+Version: @VERSION@
+
diff --git a/tests/json-loader.c b/tests/json-loader.c
new file mode 100644
index 0000000..36157dc
--- /dev/null
+++ b/tests/json-loader.c
@@ -0,0 +1,179 @@
+/*
+A loader to turn JSON into dbusmenu menuitems
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "json-loader.h"
+
+static GVariant * node2variant (JsonNode * node);
+
+static void
+array_foreach (JsonArray * array, guint index, JsonNode * node, gpointer user_data)
+{
+ GVariantBuilder * builder = (GVariantBuilder *)user_data;
+ GVariant * variant = node2variant(node);
+ if (variant != NULL) {
+ g_variant_builder_add_value(builder, variant);
+ }
+ return;
+}
+
+static void
+object_foreach (JsonObject * array, const gchar * member, JsonNode * node, gpointer user_data)
+{
+ GVariantBuilder * builder = (GVariantBuilder *)user_data;
+ GVariant * variant = node2variant(node);
+ if (variant != NULL) {
+ g_variant_builder_add(builder, "{sv}", member, variant);
+ }
+ return;
+}
+
+static GVariant *
+node2variant (JsonNode * node)
+{
+ if (node == NULL) {
+ return NULL;
+ }
+
+ if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE) {
+ switch (json_node_get_value_type(node)) {
+ case G_TYPE_INT:
+ case G_TYPE_INT64:
+ return g_variant_new_int32(json_node_get_int(node));
+ case G_TYPE_DOUBLE:
+ case G_TYPE_FLOAT:
+ return g_variant_new_double(json_node_get_double(node));
+ case G_TYPE_BOOLEAN:
+ return g_variant_new_boolean(json_node_get_boolean(node));
+ case G_TYPE_STRING:
+ return g_variant_new_string(json_node_get_string(node));
+ default:
+ g_assert_not_reached();
+ }
+ }
+
+ if (JSON_NODE_TYPE(node) == JSON_NODE_ARRAY) {
+ GVariantBuilder builder;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+
+ JsonArray * array = json_node_get_array(node);
+ json_array_foreach_element(array, array_foreach, &builder);
+
+ return g_variant_builder_end(&builder);
+ }
+
+ if (JSON_NODE_TYPE(node) == JSON_NODE_OBJECT) {
+ GVariantBuilder builder;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_DICTIONARY);
+
+ JsonObject * array = json_node_get_object(node);
+ json_object_foreach_member(array, object_foreach, &builder);
+
+ return g_variant_builder_end(&builder);
+ }
+
+ return NULL;
+}
+
+static void
+set_props (DbusmenuMenuitem * mi, JsonObject * node)
+{
+ if (node == NULL) return;
+
+ GList * members = NULL;
+ for (members = json_object_get_members(node); members != NULL; members = g_list_next(members)) {
+ const gchar * member = members->data;
+
+ if (!g_strcmp0(member, "id")) { continue; }
+ if (!g_strcmp0(member, "submenu")) { continue; }
+
+ JsonNode * lnode = json_object_get_member(node, member);
+ GVariant * variant = node2variant(lnode);
+
+ if (variant != NULL) {
+ dbusmenu_menuitem_property_set_variant(mi, member, variant);
+ }
+ }
+
+ return;
+}
+
+DbusmenuMenuitem *
+dbusmenu_json_build_from_node (const JsonNode * cnode)
+{
+ JsonNode * node = (JsonNode *)cnode; /* To match the jsonglib API :( */
+
+ if (node == NULL) return NULL;
+ if (JSON_NODE_TYPE(node) != JSON_NODE_OBJECT) return NULL;
+
+ JsonObject * layout = json_node_get_object(node);
+
+ DbusmenuMenuitem * local = NULL;
+ if (json_object_has_member(layout, "id")) {
+ JsonNode * node = json_object_get_member(layout, "id");
+ g_return_val_if_fail(JSON_NODE_TYPE(node) == JSON_NODE_VALUE, NULL);
+ local = dbusmenu_menuitem_new_with_id(json_node_get_int(node));
+ } else {
+ local = dbusmenu_menuitem_new();
+ }
+
+ set_props(local, layout);
+
+ if (json_object_has_member(layout, "submenu")) {
+ JsonNode * node = json_object_get_member(layout, "submenu");
+ g_return_val_if_fail(JSON_NODE_TYPE(node) == JSON_NODE_ARRAY, local);
+ JsonArray * array = json_node_get_array(node);
+ guint count;
+ for (count = 0; count < json_array_get_length(array); count++) {
+ DbusmenuMenuitem * child = dbusmenu_json_build_from_node(json_array_get_element(array, count));
+ if (child != NULL) {
+ dbusmenu_menuitem_child_append(local, child);
+ }
+ }
+ }
+
+ /* g_debug("Layout to menu return: 0x%X", (unsigned int)local); */
+ return local;
+}
+
+DbusmenuMenuitem *
+dbusmenu_json_build_from_file (const gchar * filename)
+{
+ JsonParser * parser = json_parser_new();
+
+ GError * error = NULL;
+ if (!json_parser_load_from_file(parser, filename, &error)) {
+ g_warning("Failed parsing file %s because: %s", filename, error->message);
+ g_error_free(error);
+ return NULL;
+ }
+
+ JsonNode * root_node = json_parser_get_root(parser);
+ if (JSON_NODE_TYPE(root_node) != JSON_NODE_OBJECT) {
+ g_warning("Root node is not an object, fail. It's an: %s", json_node_type_name(root_node));
+ return NULL;
+ }
+
+ DbusmenuMenuitem * mi = dbusmenu_json_build_from_node(root_node);
+
+ g_object_unref(parser);
+
+ return mi;
+}
diff --git a/tests/json-loader.h b/tests/json-loader.h
new file mode 100644
index 0000000..666bb6e
--- /dev/null
+++ b/tests/json-loader.h
@@ -0,0 +1,31 @@
+/*
+A loader to turn JSON into dbusmenu menuitems
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __DBUSMENU_JSON_LOADER_H__
+#define __DBUSMENU_JSON_LOADER_H__
+
+#include <libdbusmenu-glib/menuitem.h>
+#include <json-glib/json-glib.h>
+
+DbusmenuMenuitem * dbusmenu_json_build_from_node (const JsonNode * node);
+DbusmenuMenuitem * dbusmenu_json_build_from_file (const gchar * filename);
+
+#endif /* __DBUSMENU_JSON_LOADER_H__ */
diff --git a/tests/run-xvfb.sh b/tests/run-xvfb.sh
index 3622dbf..3aa05c1 100644
--- a/tests/run-xvfb.sh
+++ b/tests/run-xvfb.sh
@@ -1,4 +1,4 @@
-if [ "$DISPLAY" == "" ]; then
+if [ "x$DISPLAY" == "x" ]; then
Xvfb -ac -noreset -screen 0 800x600x16 -help 2>/dev/null 1>&2
XID=`for id in 101 102 103 104 105 106 107 197 199 211 223 227 293 307 308 309 310 311 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 4703 4721 4723 4729 4733 4751 9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992 9993 9994 9995 9996 9997 9998 9999 ; do test -e /tmp/.X$id-lock || { echo $id; exit 0; }; done; exit 1`
{ Xvfb -ac -noreset -screen 0 800x600x16 :$XID -screen 0 800x600x16 -nolisten tcp -auth /dev/null >/dev/null 2>&1 & trap "kill -15 $! " 0 HUP INT QUIT TRAP USR1 PIPE TERM ; } || { echo "Gtk+Tests:ERROR: Failed to start Xvfb environment for X11 target tests."; exit 1; }
diff --git a/tests/test-glib-events-client.c b/tests/test-glib-events-client.c
new file mode 100644
index 0000000..2cc5439
--- /dev/null
+++ b/tests/test-glib-events-client.c
@@ -0,0 +1,138 @@
+/*
+A test for libdbusmenu to ensure its quality.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+
+#include <libdbusmenu-glib/client.h>
+#include <libdbusmenu-glib/menuitem.h>
+
+#include "test-glib-submenu.h"
+
+#define TIMESTAMP_VALUE 54
+#define DATA_VALUE 32
+#define USER_VALUE 76
+
+static GMainLoop * mainloop = NULL;
+static gboolean passed = TRUE;
+static gboolean first = TRUE;
+
+static void
+event_status (DbusmenuClient * client, DbusmenuMenuitem * item, gchar * name, GVariant * data, guint timestamp, GError * error, gpointer user_data)
+{
+ g_debug("Event status: %s", error == NULL ? "Sent" : "Error");
+
+ if (timestamp != TIMESTAMP_VALUE) {
+ g_debug("Timestamp value pass fail got: %d", timestamp);
+ passed = FALSE;
+ g_main_loop_quit(mainloop);
+ return;
+ }
+
+ if (g_variant_get_int32(data) != DATA_VALUE) {
+ g_debug("Data value pass fail got: %d", g_variant_get_int32(g_variant_get_child_value(data, 0)));
+ passed = FALSE;
+ g_main_loop_quit(mainloop);
+ return;
+ }
+
+ if (GPOINTER_TO_INT(user_data) != USER_VALUE) {
+ g_debug("User value pass fail got: %d", GPOINTER_TO_INT(user_data));
+ passed = FALSE;
+ g_main_loop_quit(mainloop);
+ return;
+ }
+
+ if (first && error != NULL) {
+ passed = FALSE;
+ g_debug("First signal back failed.");
+ g_main_loop_quit(mainloop);
+ return;
+ }
+
+ if (!first && error == NULL) {
+ passed = FALSE;
+ g_debug("Second signal didn't fail.");
+ g_main_loop_quit(mainloop);
+ return;
+ }
+
+ if (!first && error != NULL) {
+ g_debug("Second signal failed: pass.");
+ g_main_loop_quit(mainloop);
+ return;
+ }
+
+ first = FALSE;
+ dbusmenu_menuitem_handle_event(item, "clicked", data, timestamp);
+ return;
+}
+
+static void
+layout_updated (DbusmenuClient * client, gpointer user_data)
+{
+ g_debug("Layout Updated");
+
+ DbusmenuMenuitem * menuroot = dbusmenu_client_get_root(client);
+ if (menuroot == NULL) {
+ g_debug("Root is NULL?");
+ return;
+ }
+
+ GVariant * data = g_variant_new_int32(DATA_VALUE);
+ dbusmenu_menuitem_handle_event(menuroot, "clicked", data, TIMESTAMP_VALUE);
+
+ return;
+}
+
+static gboolean
+timer_func (gpointer data)
+{
+ g_debug("Death timer. Oops.");
+ passed = FALSE;
+ g_main_loop_quit(mainloop);
+ return FALSE;
+}
+
+int
+main (int argc, char ** argv)
+{
+ g_type_init();
+
+ DbusmenuClient * client = dbusmenu_client_new("org.dbusmenu.test", "/org/test");
+ g_signal_connect(G_OBJECT(client), DBUSMENU_CLIENT_SIGNAL_LAYOUT_UPDATED, G_CALLBACK(layout_updated), NULL);
+ g_signal_connect(G_OBJECT(client), DBUSMENU_CLIENT_SIGNAL_EVENT_RESULT, G_CALLBACK(event_status), GINT_TO_POINTER(USER_VALUE));
+
+ g_timeout_add_seconds(5, timer_func, client);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ g_debug("Main loop complete");
+ g_object_unref(G_OBJECT(client));
+
+ if (passed) {
+ g_debug("Quiting");
+ return 0;
+ } else {
+ g_debug("Quiting as we're a failure");
+ return 1;
+ }
+}
diff --git a/tests/test-glib-events-server.c b/tests/test-glib-events-server.c
new file mode 100644
index 0000000..ab72c6b
--- /dev/null
+++ b/tests/test-glib-events-server.c
@@ -0,0 +1,103 @@
+/*
+A test for libdbusmenu to ensure its quality.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <libdbusmenu-glib/server.h>
+#include <libdbusmenu-glib/menuitem.h>
+
+static DbusmenuServer * server = NULL;
+static GMainLoop * mainloop = NULL;
+static gboolean passed = TRUE;
+
+static void
+handle_event (void) {
+ g_debug("Handle event");
+ g_main_loop_quit(mainloop);
+ return;
+}
+
+static gboolean
+timer_func (gpointer data)
+{
+ passed = FALSE;
+ g_debug("Never got a signal");
+ g_main_loop_quit(mainloop);
+ return FALSE;
+}
+
+static void
+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ server = dbusmenu_server_new("/org/test");
+ DbusmenuMenuitem * menuitem = dbusmenu_menuitem_new();
+ dbusmenu_server_set_root(server, menuitem);
+
+ g_signal_connect(G_OBJECT(menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(handle_event), NULL);
+
+ return;
+}
+
+static void
+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ g_error("Unable to get name '%s' on DBus", name);
+ g_main_loop_quit(mainloop);
+ return;
+}
+
+int
+main (int argc, char ** argv)
+{
+ g_type_init();
+
+ g_bus_own_name(G_BUS_TYPE_SESSION,
+ "org.dbusmenu.test",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus,
+ NULL,
+ name_lost,
+ NULL,
+ NULL);
+
+ g_timeout_add_seconds(3, timer_func, NULL);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ if (passed) {
+ int i;
+
+ for (i = 0; i < 5; i++) {
+ g_debug("Ignoring signals: %d", i);
+ g_usleep(1000 * 1000);
+ }
+ }
+
+ if (passed) {
+ g_debug("Test Passed");
+ return 0;
+ } else {
+ g_debug("Test Failed");
+ return 1;
+ }
+}
diff --git a/tests/test-glib-layout-client.c b/tests/test-glib-layout-client.c
index 5ea0cf8..3afe042 100644
--- a/tests/test-glib-layout-client.c
+++ b/tests/test-glib-layout-client.c
@@ -81,6 +81,11 @@ layout_updated (DbusmenuClient * client, gpointer data)
g_debug("Layout Updated");
DbusmenuMenuitem * menuroot = dbusmenu_client_get_root(client);
+ if (menuroot == NULL) {
+ g_debug("Root NULL, waiting");
+ return;
+ }
+
layout_t * layout = &layouts[layouton];
if (!verify_root_to_layout(menuroot, layout)) {
diff --git a/tests/test-glib-layout-server.c b/tests/test-glib-layout-server.c
index 111e164..e289349 100644
--- a/tests/test-glib-layout-server.c
+++ b/tests/test-glib-layout-server.c
@@ -20,11 +20,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <glib.h>
-
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <dbus/dbus-glib-bindings.h>
+#include <gio/gio.h>
#include <libdbusmenu-glib/server.h>
#include <libdbusmenu-glib/menuitem.h>
@@ -72,33 +68,38 @@ timer_func (gpointer data)
return TRUE;
}
-int
-main (int argc, char ** argv)
+static void
+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
{
- GError * error = NULL;
-
- g_type_init();
-
- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
+ server = dbusmenu_server_new("/org/test");
- DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
- guint nameret = 0;
+ timer_func(NULL);
+ g_timeout_add(2500, timer_func, NULL);
- if (!org_freedesktop_DBus_request_name(bus_proxy, "org.dbusmenu.test", 0, &nameret, &error)) {
- g_error("Unable to call to request name");
- return 1;
- }
+ return;
+}
- if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
- g_error("Unable to get name");
- return 1;
- }
+static void
+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ g_error("Unable to get name '%s' on DBus", name);
+ g_main_loop_quit(mainloop);
+ return;
+}
- server = dbusmenu_server_new("/org/test");
+int
+main (int argc, char ** argv)
+{
+ g_type_init();
- timer_func(NULL);
- g_timeout_add(2500, timer_func, NULL);
+ g_bus_own_name(G_BUS_TYPE_SESSION,
+ "org.dbusmenu.test",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus,
+ NULL,
+ name_lost,
+ NULL,
+ NULL);
mainloop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(mainloop);
diff --git a/tests/test-glib-objects.c b/tests/test-glib-objects.c
index 1d4f673..9c99280 100644
--- a/tests/test-glib-objects.c
+++ b/tests/test-glib-objects.c
@@ -77,17 +77,17 @@ test_object_menuitem_props_string (void)
{
/* Build a menu item */
DbusmenuMenuitem * item = dbusmenu_menuitem_new();
- const GValue * out = NULL;
+ GVariant * out = NULL;
/* Test to make sure it's a happy object */
g_assert(item != NULL);
/* Setting a string */
dbusmenu_menuitem_property_set(item, "string", "value");
- out = dbusmenu_menuitem_property_get_value(item, "string");
+ out = dbusmenu_menuitem_property_get_variant(item, "string");
g_assert(out != NULL);
- g_assert(G_VALUE_TYPE(out) == G_TYPE_STRING);
- g_assert(!g_strcmp0(g_value_get_string(out), "value"));
+ g_assert(g_variant_type_equal(g_variant_get_type(out), G_VARIANT_TYPE_STRING));
+ g_assert(!g_strcmp0(g_variant_get_string(out, NULL), "value"));
g_assert(!g_strcmp0(dbusmenu_menuitem_property_get(item, "string"), "value"));
g_object_unref(item);
@@ -101,17 +101,17 @@ test_object_menuitem_props_int (void)
{
/* Build a menu item */
DbusmenuMenuitem * item = dbusmenu_menuitem_new();
- const GValue * out = NULL;
+ GVariant * out = NULL;
/* Test to make sure it's a happy object */
g_assert(item != NULL);
/* Setting a string */
dbusmenu_menuitem_property_set_int(item, "int", 12345);
- out = dbusmenu_menuitem_property_get_value(item, "int");
+ out = dbusmenu_menuitem_property_get_variant(item, "int");
g_assert(out != NULL);
- g_assert(G_VALUE_TYPE(out) == G_TYPE_INT);
- g_assert(g_value_get_int(out) == 12345);
+ g_assert(g_variant_type_equal(g_variant_get_type(out), G_VARIANT_TYPE_INT32));
+ g_assert(g_variant_get_int32(out) == 12345);
g_assert(dbusmenu_menuitem_property_get_int(item, "int") == 12345);
g_object_unref(item);
@@ -125,18 +125,18 @@ test_object_menuitem_props_bool (void)
{
/* Build a menu item */
DbusmenuMenuitem * item = dbusmenu_menuitem_new();
- const GValue * out = NULL;
+ GVariant * out = NULL;
/* Test to make sure it's a happy object */
g_assert(item != NULL);
/* Setting a string */
dbusmenu_menuitem_property_set_bool(item, "boolean", TRUE);
- out = dbusmenu_menuitem_property_get_value(item, "boolean");
+ out = dbusmenu_menuitem_property_get_variant(item, "boolean");
g_assert(out != NULL);
- g_assert(G_VALUE_TYPE(out) == G_TYPE_BOOLEAN);
- g_assert(g_value_get_boolean(out));
- g_assert(dbusmenu_menuitem_property_get_int(item, "boolean"));
+ g_assert(g_variant_type_equal(g_variant_get_type(out), G_VARIANT_TYPE_BOOLEAN));
+ g_assert(g_variant_get_boolean(out));
+ /* g_assert(dbusmenu_menuitem_property_get_int(item, "boolean") == 0); */
g_object_unref(item);
@@ -177,7 +177,7 @@ test_object_menuitem_props_swap (void)
/* A helper to put a value into a pointer for eval. */
static void
-test_object_menuitem_props_signals_helper (DbusmenuMenuitem * mi, gchar * property, GValue * value, GValue ** out)
+test_object_menuitem_props_signals_helper (DbusmenuMenuitem * mi, gchar * property, GVariant * value, GVariant ** out)
{
if (!g_strcmp0(property, "swapper")) {
*out = value;
@@ -194,7 +194,7 @@ test_object_menuitem_props_signals (void)
{
/* Build a menu item */
DbusmenuMenuitem * item = dbusmenu_menuitem_new();
- GValue * out = NULL;
+ GVariant * out = NULL;
/* Test to make sure it's a happy object */
g_assert(item != NULL);
@@ -205,25 +205,25 @@ test_object_menuitem_props_signals (void)
/* Setting a boolean */
dbusmenu_menuitem_property_set_bool(item, "swapper", TRUE);
g_assert(out != NULL);
- g_assert(g_value_get_boolean(out));
+ g_assert(g_variant_get_boolean(out));
out = NULL;
/* Setting a int */
dbusmenu_menuitem_property_set_int(item, "swapper", 5432);
g_assert(out != NULL);
- g_assert(g_value_get_int(out) == 5432);
+ g_assert(g_variant_get_int32(out) == 5432);
out = NULL;
/* Setting a string */
dbusmenu_menuitem_property_set(item, "swapper", "mystring");
g_assert(out != NULL);
- g_assert(!g_strcmp0(g_value_get_string(out), "mystring"));
+ g_assert(!g_strcmp0(g_variant_get_string(out, NULL), "mystring"));
out = NULL;
/* Setting a boolean */
dbusmenu_menuitem_property_set_bool(item, "swapper", FALSE);
g_assert(out != NULL);
- g_assert(!g_value_get_boolean(out));
+ g_assert(!g_variant_get_boolean(out));
out = NULL;
g_object_unref(item);
@@ -274,6 +274,37 @@ test_object_menuitem_props_boolstr (void)
return;
}
+/* Set and then remove a prop */
+static void
+test_object_menuitem_props_removal (void)
+{
+ /* Build a menu item */
+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
+
+ /* Test to make sure it's a happy object */
+ g_assert(item != NULL);
+
+ /* Set the property and ensure that it's set */
+ dbusmenu_menuitem_property_set_variant(item, "myprop", g_variant_new_int32(34));
+ g_assert(dbusmenu_menuitem_property_get_variant(item, "myprop") != NULL);
+
+ /* Remove the property and ensure it goes away */
+ dbusmenu_menuitem_property_set_variant(item, "myprop", NULL);
+ g_assert(dbusmenu_menuitem_property_get_variant(item, "myprop") == NULL);
+
+ /* Set the property again */
+ dbusmenu_menuitem_property_set_variant(item, "myprop", g_variant_new_int32(34));
+ g_assert(dbusmenu_menuitem_property_get_variant(item, "myprop") != NULL);
+
+ /* Remove the property with a NULL string */
+ dbusmenu_menuitem_property_set(item, "myprop", NULL);
+ g_assert(dbusmenu_menuitem_property_get_variant(item, "myprop") == NULL);
+
+ g_object_unref(item);
+
+ return;
+}
+
/* Build the test suite */
static void
test_glib_objects_suite (void)
@@ -286,6 +317,7 @@ test_glib_objects_suite (void)
g_test_add_func ("/dbusmenu/glib/objects/menuitem/props_swap", test_object_menuitem_props_swap);
g_test_add_func ("/dbusmenu/glib/objects/menuitem/props_signals", test_object_menuitem_props_signals);
g_test_add_func ("/dbusmenu/glib/objects/menuitem/props_boolstr", test_object_menuitem_props_boolstr);
+ g_test_add_func ("/dbusmenu/glib/objects/menuitem/props_removal", test_object_menuitem_props_removal);
return;
}
diff --git a/tests/test-glib-properties-client.c b/tests/test-glib-properties-client.c
index 434465a..ae7b80b 100644
--- a/tests/test-glib-properties-client.c
+++ b/tests/test-glib-properties-client.c
@@ -121,7 +121,7 @@ static void
layout_updated (DbusmenuClient * client, gpointer data)
{
g_debug("Layout Updated");
- g_timeout_add (250, layout_verify_timer, client);
+ g_timeout_add (500, layout_verify_timer, client);
return;
}
diff --git a/tests/test-glib-properties-server.c b/tests/test-glib-properties-server.c
index 091e550..4248ea2 100644
--- a/tests/test-glib-properties-server.c
+++ b/tests/test-glib-properties-server.c
@@ -20,10 +20,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <glib.h>
-
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
+#include <gio/gio.h>
#include <libdbusmenu-glib/menuitem.h>
#include <libdbusmenu-glib/server.h>
@@ -91,8 +88,6 @@ main (int argc, char ** argv)
{
g_type_init();
- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
-
server = dbusmenu_server_new("/org/test");
timer_func(NULL);
diff --git a/tests/test-glib-proxy-client.c b/tests/test-glib-proxy-client.c
index 0ae2e20..2e1e2d2 100644
--- a/tests/test-glib-proxy-client.c
+++ b/tests/test-glib-proxy-client.c
@@ -150,10 +150,9 @@ layout_verify_timer (gpointer data)
g_main_loop_quit(mainloop);
}
- GValue value = {0};
- g_value_init(&value, G_TYPE_INT);
- g_value_set_int(&value, 0);
- dbusmenu_menuitem_handle_event(menuroot, "clicked", &value, layouton);
+ GVariant * value = g_variant_new("i", 0);
+ dbusmenu_menuitem_handle_event(menuroot, "clicked", value, layouton);
+ g_variant_unref(value);
return FALSE;
}
diff --git a/tests/test-glib-proxy-proxy.c b/tests/test-glib-proxy-proxy.c
index 722cf1f..8a17ead 100644
--- a/tests/test-glib-proxy-proxy.c
+++ b/tests/test-glib-proxy-proxy.c
@@ -1,9 +1,5 @@
#include <glib.h>
-
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <dbus/dbus-glib-bindings.h>
+#include <gio/gio.h>
#include <libdbusmenu-glib/menuitem.h>
#include <libdbusmenu-glib/menuitem-proxy.h>
@@ -32,6 +28,24 @@ root_changed (DbusmenuClient * client, DbusmenuMenuitem * newroot, gpointer user
return;
}
+static void
+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ client = dbusmenu_client_new((gchar *)user_data, "/org/test");
+
+ g_signal_connect(client, DBUSMENU_CLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(root_changed), server);
+
+ return;
+}
+
+static void
+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ g_error("Unable to get name '%s' on DBus", name);
+ g_main_loop_quit(mainloop);
+ return;
+}
+
int
main (int argc, char ** argv)
{
@@ -47,28 +61,16 @@ main (int argc, char ** argv)
g_debug("I am '%s' and I'm proxying '%s'", whoami, myproxy);
- GError * error = NULL;
- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-
- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(connection)));
-
- DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
- guint nameret = 0;
-
- if (!org_freedesktop_DBus_request_name(bus_proxy, whoami, 0, &nameret, &error)) {
- g_error("Unable to call to request name");
- return 1;
- }
-
- if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
- g_error("Unable to get name");
- return 1;
- }
-
server = dbusmenu_server_new("/org/test");
- client = dbusmenu_client_new(myproxy, "/org/test");
- g_signal_connect(client, DBUSMENU_CLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(root_changed), server);
+ g_bus_own_name(G_BUS_TYPE_SESSION,
+ whoami,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus,
+ NULL,
+ name_lost,
+ myproxy,
+ NULL);
mainloop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(mainloop);
diff --git a/tests/test-glib-proxy-server.c b/tests/test-glib-proxy-server.c
index f32b426..a5dfd4e 100644
--- a/tests/test-glib-proxy-server.c
+++ b/tests/test-glib-proxy-server.c
@@ -20,11 +20,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <glib.h>
-
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <dbus/dbus-glib-bindings.h>
+#include <gio/gio.h>
#include <libdbusmenu-glib/menuitem.h>
#include <libdbusmenu-glib/server.h>
@@ -104,31 +100,36 @@ layout_change (DbusmenuMenuitem * oldroot, guint timestamp, gpointer data)
return;
}
-int
-main (int argc, char ** argv)
+static void
+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
{
- g_type_init();
-
- GError * error = NULL;
- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-
- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(connection)));
+ server = dbusmenu_server_new("/org/test");
+ layout_change(NULL, 0, NULL);
- DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
- guint nameret = 0;
+ return;
+}
- if (!org_freedesktop_DBus_request_name(bus_proxy, "test.proxy.server", 0, &nameret, &error)) {
- g_error("Unable to call to request name");
- return 1;
- }
+static void
+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ g_error("Unable to get name '%s' on DBus", name);
+ g_main_loop_quit(mainloop);
+ return;
+}
- if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
- g_error("Unable to get name");
- return 1;
- }
+int
+main (int argc, char ** argv)
+{
+ g_type_init();
- server = dbusmenu_server_new("/org/test");
- layout_change(NULL, 0, NULL);
+ g_bus_own_name(G_BUS_TYPE_SESSION,
+ "test.proxy.server",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus,
+ NULL,
+ name_lost,
+ NULL,
+ NULL);
mainloop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(mainloop);
diff --git a/tests/test-glib-simple-items.c b/tests/test-glib-simple-items.c
index 5b9f538..3ea5480 100644
--- a/tests/test-glib-simple-items.c
+++ b/tests/test-glib-simple-items.c
@@ -1,6 +1,3 @@
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-bindings.h>
-
#include <libdbusmenu-glib/server.h>
#include <libdbusmenu-glib/menuitem.h>
diff --git a/tests/test-glib-simple-items.py b/tests/test-glib-simple-items.py
new file mode 100755
index 0000000..d7ad7d7
--- /dev/null
+++ b/tests/test-glib-simple-items.py
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+# This is the Python GI version of test-glib-simple-items.c
+
+import gobject
+from gi.repository import Dbusmenu
+
+dummies = ['Bob', 'Jim', 'Alvin', 'Mary']
+
+def dummy_users(root):
+ count = 0
+ for user in dummies:
+ mi = Dbusmenu.Menuitem()
+ print 'Creating item: %d %s' % (mi.get_id(), user)
+ print '\tRoot ID:', root.get_id()
+ mi.property_set('label', user)
+ root.child_add_position(mi, count)
+ assert mi.property_get('label') == user
+ count += 1
+
+def quititall(mainloop):
+ mainloop.quit()
+ return False
+
+# main
+
+server = Dbusmenu.Server.new('/test/object')
+root_menuitem = Dbusmenu.Menuitem()
+server.set_root(root_menuitem)
+print 'Root ID:', root_menuitem.get_id()
+
+dummy_users(root_menuitem)
+
+mainloop = gobject.MainLoop()
+gobject.timeout_add_seconds(1, quititall, mainloop)
+mainloop.run()
diff --git a/tests/test-glib-submenu-server.c b/tests/test-glib-submenu-server.c
index 68f7004..73362c1 100644
--- a/tests/test-glib-submenu-server.c
+++ b/tests/test-glib-submenu-server.c
@@ -20,11 +20,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <glib.h>
-
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <dbus/dbus-glib-bindings.h>
+#include <gio/gio.h>
#include <libdbusmenu-glib/server.h>
#include <libdbusmenu-glib/menuitem.h>
@@ -72,33 +68,38 @@ timer_func (gpointer data)
return TRUE;
}
-int
-main (int argc, char ** argv)
+static void
+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
{
- GError * error = NULL;
-
- g_type_init();
-
- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
+ server = dbusmenu_server_new("/org/test");
- DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
- guint nameret = 0;
+ timer_func(NULL);
+ g_timeout_add(2500, timer_func, NULL);
- if (!org_freedesktop_DBus_request_name(bus_proxy, "org.dbusmenu.test", 0, &nameret, &error)) {
- g_error("Unable to call to request name");
- return 1;
- }
+ return;
+}
- if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
- g_error("Unable to get name");
- return 1;
- }
+static void
+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ g_error("Unable to get name '%s' on DBus", name);
+ g_main_loop_quit(mainloop);
+ return;
+}
- server = dbusmenu_server_new("/org/test");
+int
+main (int argc, char ** argv)
+{
+ g_type_init();
- timer_func(NULL);
- g_timeout_add(2500, timer_func, NULL);
+ g_bus_own_name(G_BUS_TYPE_SESSION,
+ "org.dbusmenu.test",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus,
+ NULL,
+ name_lost,
+ NULL,
+ NULL);
mainloop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(mainloop);
diff --git a/tests/test-gtk-label-client.c b/tests/test-gtk-label-client.c
index 070c278..14eb5bd 100644
--- a/tests/test-gtk-label-client.c
+++ b/tests/test-gtk-label-client.c
@@ -22,7 +22,6 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <gtk/gtk.h>
#include <libdbusmenu-gtk/menu.h>
-static guint layouton = 0;
static GMainLoop * mainloop = NULL;
static gboolean passed = TRUE;
static guint death_timer = 0;
@@ -105,7 +104,6 @@ verify_root_to_layout(DbusmenuMenuitem * mi, proplayout_t * layout)
static gboolean
timer_func (gpointer data)
{
- g_debug("Death timer. Oops. Got to: %d", layouton);
passed = TRUE;
g_main_loop_quit(mainloop);
return FALSE;
diff --git a/tests/test-gtk-label-server.c b/tests/test-gtk-label-server.c
index 32d7a43..ddf8fcf 100644
--- a/tests/test-gtk-label-server.c
+++ b/tests/test-gtk-label-server.c
@@ -20,84 +20,13 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <glib.h>
-
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <dbus/dbus-glib-bindings.h>
+#include <gio/gio.h>
#include <libdbusmenu-glib/menuitem.h>
#include <libdbusmenu-glib/server.h>
#include <json-glib/json-glib.h>
-
-static void
-menuitem_click(DbusmenuMenuitem * mi, guint32 time, gpointer user_data)
-{
- g_debug("Clicked on: %d @ %d", dbusmenu_menuitem_get_id(mi), time);
- return;
-}
-
-static void
-set_props (DbusmenuMenuitem * mi, JsonObject * node)
-{
- if (node == NULL) return;
-
- GList * members = NULL;
- for (members = json_object_get_members(node); members != NULL; members = g_list_next(members)) {
- const gchar * member = members->data;
-
- if (!g_strcmp0(member, "id")) { continue; }
- if (!g_strcmp0(member, "submenu")) { continue; }
-
- JsonNode * lnode = json_object_get_member(node, member);
- if (JSON_NODE_TYPE(lnode) != JSON_NODE_VALUE) { continue; }
-
- GValue value = {0};
- json_node_get_value(lnode, &value);
- dbusmenu_menuitem_property_set_value(mi, member, &value);
- g_value_unset(&value);
- }
-
- return;
-}
-
-static DbusmenuMenuitem *
-layout2menuitem (JsonNode * inlayout)
-{
- if (inlayout == NULL) return NULL;
- if (JSON_NODE_TYPE(inlayout) != JSON_NODE_OBJECT) return NULL;
-
- JsonObject * layout = json_node_get_object(inlayout);
-
- DbusmenuMenuitem * local = NULL;
- if (json_object_has_member(layout, "id")) {
- JsonNode * node = json_object_get_member(layout, "id");
- g_return_val_if_fail(JSON_NODE_TYPE(node) == JSON_NODE_VALUE, NULL);
- local = dbusmenu_menuitem_new_with_id(json_node_get_int(node));
- } else {
- local = dbusmenu_menuitem_new();
- }
- g_signal_connect(G_OBJECT(local), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(menuitem_click), NULL);
-
- set_props(local, layout);
-
- if (json_object_has_member(layout, "submenu")) {
- JsonNode * node = json_object_get_member(layout, "submenu");
- g_return_val_if_fail(JSON_NODE_TYPE(node) == JSON_NODE_ARRAY, local);
- JsonArray * array = json_node_get_array(node);
- guint count;
- for (count = 0; count < json_array_get_length(array); count++) {
- DbusmenuMenuitem * child = layout2menuitem(json_array_get_element(array, count));
- if (child != NULL) {
- dbusmenu_menuitem_child_append(local, child);
- }
- }
- }
-
- /* g_debug("Layout to menu return: 0x%X", (unsigned int)local); */
- return local;
-}
+#include "json-loader.h"
static JsonArray * root_array = NULL;
static guint layouton = 0;
@@ -114,12 +43,31 @@ timer_func (gpointer data)
}
g_debug("Updating to Layout %d", layouton);
- dbusmenu_server_set_root(server, layout2menuitem(json_array_get_element(root_array, layouton)));
+ dbusmenu_server_set_root(server, dbusmenu_json_build_from_node(json_array_get_element(root_array, layouton)));
layouton++;
return TRUE;
}
+static void
+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ server = dbusmenu_server_new("/org/test");
+
+ timer_func(NULL);
+ g_timeout_add_seconds(5, timer_func, NULL);
+
+ return;
+}
+
+static void
+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ g_error("Unable to get name '%s' on DBus", name);
+ g_main_loop_quit(mainloop);
+ return;
+}
+
int
main (int argc, char ** argv)
{
@@ -140,26 +88,15 @@ main (int argc, char ** argv)
root_array = json_node_get_array(root_node);
g_debug("%d layouts in test description '%s'", json_array_get_length(root_array), argv[1]);
- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
-
- DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
- guint nameret = 0;
-
- if (!org_freedesktop_DBus_request_name(bus_proxy, "glib.label.test", 0, &nameret, &error)) {
- g_error("Unable to call to request name");
- return 1;
- }
-
- if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
- g_error("Unable to get name");
- return 1;
- }
-
- server = dbusmenu_server_new("/org/test");
- timer_func(NULL);
- g_timeout_add_seconds(5, timer_func, NULL);
+ g_bus_own_name(G_BUS_TYPE_SESSION,
+ "glib.label.test",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus,
+ NULL,
+ name_lost,
+ NULL,
+ NULL);
mainloop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(mainloop);
diff --git a/tests/test-gtk-objects.c b/tests/test-gtk-objects.c
new file mode 100644
index 0000000..30fc022
--- /dev/null
+++ b/tests/test-gtk-objects.c
@@ -0,0 +1,145 @@
+/*
+Testing for the various objects just by themselves.
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libdbusmenu-glib/menuitem.h>
+#include <libdbusmenu-gtk/menuitem.h>
+#include <gdk/gdkkeysyms.h>
+
+#define TEST_IMAGE SRCDIR "/" "test-gtk-objects.jpg"
+
+/* Building the basic menu item, make sure we didn't break
+ any core GObject stuff */
+static void
+test_object_menuitem (void)
+{
+ /* Build a menu item */
+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
+
+ /* Test to make sure it's a happy object */
+ g_assert(item != NULL);
+ g_assert(G_IS_OBJECT(item));
+ g_assert(DBUSMENU_IS_MENUITEM(item));
+
+ /* Set up a check to make sure it gets destroyed on unref */
+ g_object_add_weak_pointer(G_OBJECT(item), (gpointer *)&item);
+ g_object_unref(item);
+
+ /* Did it go away? */
+ g_assert(item == NULL);
+
+ return;
+}
+
+/* Setting and getting a pixbuf */
+static void
+test_object_prop_pixbuf (void)
+{
+ const gchar * prop_name = "image-test";
+
+ /* Build a menu item */
+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
+
+ /* Test to make sure it's a happy object */
+ g_assert(item != NULL);
+ g_assert(G_IS_OBJECT(item));
+ g_assert(DBUSMENU_IS_MENUITEM(item));
+
+ /* Load our image */
+ GdkPixbuf * pixbuf = gdk_pixbuf_new_from_file(TEST_IMAGE, NULL);
+ g_assert(pixbuf != NULL);
+
+ /* Set the property */
+ gboolean success = dbusmenu_menuitem_property_set_image(item, prop_name, pixbuf);
+ g_assert(success);
+ g_object_unref(pixbuf);
+
+ /* Check to see if it's set */
+ GVariant * val = dbusmenu_menuitem_property_get_variant(item, prop_name);
+ g_assert(val != NULL);
+
+ /* Get the pixbuf back! */
+ GdkPixbuf * newpixbuf = dbusmenu_menuitem_property_get_image(item, prop_name);
+ g_assert(newpixbuf != NULL);
+ g_object_unref(newpixbuf);
+
+ g_object_unref(item);
+
+ return;
+}
+
+/* Setting and getting a shortcut */
+static void
+test_object_prop_shortcut (void)
+{
+ /* Build a menu item */
+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
+
+ /* Test to make sure it's a happy object */
+ g_assert(item != NULL);
+ g_assert(G_IS_OBJECT(item));
+ g_assert(DBUSMENU_IS_MENUITEM(item));
+
+ guint key = GDK_c;
+ GdkModifierType modifier = GDK_CONTROL_MASK;
+
+ /* Set a shortcut */
+ gboolean success = dbusmenu_menuitem_property_set_shortcut(item, key, modifier);
+ g_assert(success);
+
+ /* Check for value */
+ GVariant * val = dbusmenu_menuitem_property_get_variant(item, DBUSMENU_MENUITEM_PROP_SHORTCUT);
+ g_assert(val != NULL);
+
+ /* Check to see if we love it */
+ guint newkey = 0;
+ GdkModifierType newmodifier = 0;
+ dbusmenu_menuitem_property_get_shortcut(item, &newkey, &newmodifier);
+
+ g_assert(key == newkey);
+ g_assert(newmodifier == modifier);
+
+ g_object_unref(item);
+
+ return;
+}
+
+/* Build the test suite */
+static void
+test_gtk_objects_suite (void)
+{
+ g_test_add_func ("/dbusmenu/gtk/objects/menuitem/base", test_object_menuitem);
+ g_test_add_func ("/dbusmenu/gtk/objects/menuitem/prop_pixbuf", test_object_prop_pixbuf);
+ g_test_add_func ("/dbusmenu/gtk/objects/menuitem/prop_shortcut", test_object_prop_shortcut);
+ return;
+}
+
+gint
+main (gint argc, gchar * argv[])
+{
+ gtk_init(&argc, &argv);
+
+ g_test_init(&argc, &argv, NULL);
+
+ /* Test suites */
+ test_gtk_objects_suite();
+
+ return g_test_run ();
+}
diff --git a/tests/test-gtk-objects.jpg b/tests/test-gtk-objects.jpg
new file mode 100644
index 0000000..478704e
--- /dev/null
+++ b/tests/test-gtk-objects.jpg
Binary files differ
diff --git a/tests/test-gtk-parser.c b/tests/test-gtk-parser.c
new file mode 100644
index 0000000..b66b46a
--- /dev/null
+++ b/tests/test-gtk-parser.c
@@ -0,0 +1,115 @@
+/*
+Testing for the various objects just by themselves.
+
+Copyright 2011 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libdbusmenu-glib/menuitem-private.h>
+#include <libdbusmenu-gtk/parser.h>
+
+/* Just makes sure we can connect here people */
+static void
+test_parser_runs (void)
+{
+ GtkWidget * gmi = gtk_menu_item_new_with_label("Test Item");
+ g_assert(gmi != NULL);
+ DbusmenuMenuitem * mi = dbusmenu_gtk_parse_menu_structure(gmi);
+ g_assert(mi != NULL);
+
+ g_object_unref(gmi);
+ g_object_unref(mi);
+
+ return;
+}
+
+const gchar * test_parser_children_builder =
+"<?xml version=\"1.0\"?>"
+"<interface>"
+"<requires lib=\"gtk+\" version=\"2.16\"/>"
+/* Start menu bar */
+"<object class=\"GtkMenuBar\" id=\"menubar\"><property name=\"visible\">True</property>"
+/* Child 1 */
+"<child><object class=\"GtkMenuItem\" id=\"child_one\"><property name=\"visible\">True</property><property name=\"label\">Child One</property></object></child>"
+/* Child 2 */
+"<child><object class=\"GtkMenuItem\" id=\"child_two\"><property name=\"visible\">True</property><property name=\"label\">Child Two</property></object></child>"
+/* Child 3 */
+"<child><object class=\"GtkMenuItem\" id=\"child_three\"><property name=\"visible\">True</property><property name=\"label\">Child Three</property></object></child>"
+/* Child 4 */
+"<child><object class=\"GtkMenuItem\" id=\"child_four\"><property name=\"visible\">True</property><property name=\"label\">Child Four</property></object></child>"
+/* Stop menubar */
+"</object>"
+"</interface>";
+
+/* Ensure the parser can find children */
+static void
+test_parser_children (void) {
+ GtkBuilder * builder = gtk_builder_new();
+ g_assert(builder != NULL);
+
+ GError * error = NULL;
+ gtk_builder_add_from_string(builder, test_parser_children_builder, -1, &error);
+ if (error != NULL) {
+ g_error("Unable to parse UI definition: %s", error->message);
+ g_error_free(error);
+ error = NULL;
+ }
+
+ GtkWidget * menu = GTK_WIDGET(gtk_builder_get_object(builder, "menubar"));
+ g_assert(menu != NULL);
+
+ DbusmenuMenuitem * mi = dbusmenu_gtk_parse_menu_structure(menu);
+ g_assert(mi != NULL);
+
+/*
+ GPtrArray * xmlarray = g_ptr_array_new();
+ dbusmenu_menuitem_buildxml(mi, xmlarray);
+ g_debug("XML: %s", g_strjoinv("", (gchar **)xmlarray->pdata));
+*/
+
+ GList * children = dbusmenu_menuitem_get_children(mi);
+ g_assert(children != NULL);
+
+ g_assert(g_list_length(children) == 4);
+
+ g_object_unref(mi);
+ g_object_unref(menu);
+
+ return;
+}
+
+/* Build the test suite */
+static void
+test_gtk_parser_suite (void)
+{
+ g_test_add_func ("/dbusmenu/gtk/parser/base", test_parser_runs);
+ g_test_add_func ("/dbusmenu/gtk/parser/children", test_parser_children);
+ return;
+}
+
+gint
+main (gint argc, gchar * argv[])
+{
+ gtk_init(&argc, &argv);
+ g_test_init(&argc, &argv, NULL);
+
+ /* Test suites */
+ test_gtk_parser_suite();
+
+
+ return g_test_run ();
+}
diff --git a/tests/test-gtk-reorder-server.c b/tests/test-gtk-reorder-server.c
index eee9bb8..44209f1 100644
--- a/tests/test-gtk-reorder-server.c
+++ b/tests/test-gtk-reorder-server.c
@@ -20,11 +20,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <glib.h>
-
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <dbus/dbus-glib-bindings.h>
+#include <gio/gio.h>
#include <libdbusmenu-glib/menuitem.h>
#include <libdbusmenu-glib/server.h>
@@ -73,29 +69,9 @@ timer_func (gpointer data)
return TRUE;
}
-int
-main (int argc, char ** argv)
+static void
+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
{
- GError * error = NULL;
-
- g_type_init();
-
- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
- g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL))));
-
- DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
- guint nameret = 0;
-
- if (!org_freedesktop_DBus_request_name(bus_proxy, "glib.label.test", 0, &nameret, &error)) {
- g_error("Unable to call to request name");
- return 1;
- }
-
- if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
- g_error("Unable to get name");
- return 1;
- }
-
server = dbusmenu_server_new("/org/test");
root = dbusmenu_menuitem_new();
dbusmenu_server_set_root(server, root);
@@ -109,6 +85,31 @@ main (int argc, char ** argv)
timer_func(NULL);
g_timeout_add_seconds(5, timer_func, NULL);
+ return;
+}
+
+static void
+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ g_error("Unable to get name '%s' on DBus", name);
+ g_main_loop_quit(mainloop);
+ return;
+}
+
+int
+main (int argc, char ** argv)
+{
+ g_type_init();
+
+ g_bus_own_name(G_BUS_TYPE_SESSION,
+ "glib.label.test",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus,
+ NULL,
+ name_lost,
+ NULL,
+ NULL);
+
mainloop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(mainloop);
diff --git a/tests/test-gtk-shortcut-client.c b/tests/test-gtk-shortcut-client.c
new file mode 100644
index 0000000..003885c
--- /dev/null
+++ b/tests/test-gtk-shortcut-client.c
@@ -0,0 +1,76 @@
+/*
+A test for libdbusmenu to ensure its quality.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <gtk/gtk.h>
+#include <libdbusmenu-gtk/menu.h>
+#include <libdbusmenu-gtk/client.h>
+
+static GMainLoop * mainloop = NULL;
+static gboolean passed = TRUE;
+static guint death_timer = 0;
+
+static gboolean
+timer_func (gpointer data)
+{
+ passed = TRUE;
+ g_main_loop_quit(mainloop);
+ return FALSE;
+}
+
+int
+main (int argc, char ** argv)
+{
+ gtk_init(&argc, &argv);
+
+ g_debug("Building Window");
+ GtkWidget * window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ GtkWidget * menubar = gtk_menu_bar_new();
+ GtkWidget * menuitem = gtk_menu_item_new_with_label("Test");
+
+ DbusmenuGtkMenu * dmenu = dbusmenu_gtkmenu_new ("glib.label.test", "/org/test");
+ DbusmenuGtkClient * dclient = dbusmenu_gtkmenu_get_client(dmenu);
+
+ GtkAccelGroup * agroup = gtk_accel_group_new();
+ dbusmenu_gtkclient_set_accel_group(dclient, agroup);
+
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), GTK_WIDGET(dmenu));
+ gtk_widget_show(menuitem);
+ gtk_menu_bar_append(menubar, menuitem);
+ gtk_widget_show(menubar);
+ gtk_container_add(GTK_CONTAINER(window), menubar);
+ gtk_window_set_title(GTK_WINDOW(window), "libdbusmenu-gtk test");
+ gtk_window_add_accel_group(GTK_WINDOW(window), agroup);
+ gtk_widget_show(window);
+
+ death_timer = g_timeout_add_seconds(10, timer_func, window);
+
+ g_debug("Entering Mainloop");
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ if (passed) {
+ g_debug("Quiting");
+ return 0;
+ } else {
+ g_debug("Quiting as we're a failure");
+ return 1;
+ }
+}
diff --git a/tests/test-gtk-shortcut-client.py b/tests/test-gtk-shortcut-client.py
new file mode 100755
index 0000000..885d227
--- /dev/null
+++ b/tests/test-gtk-shortcut-client.py
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+
+# A test for libdbusmenu to ensure its quality. This is the Python GI version
+# of test-gtk-shortcut-client.c
+#
+# Copyright 2011 Canonical Ltd.
+# Authors:
+# Martin Pitt <martin.pitt@ubuntu.com>
+
+import sys
+import gobject
+from gi.repository import Gtk, DbusmenuGtk
+Gtk.require_version('2.0')
+
+passed = True
+main_loop = gobject.MainLoop()
+
+def timer_func(data):
+ passed = True
+ main_loop.quit()
+ return False
+
+# main
+print 'Building Window'
+window = Gtk.Window(type=Gtk.WindowType.TOPLEVEL)
+menubar = Gtk.MenuBar()
+menuitem = Gtk.MenuItem(label='Test')
+
+dmenu = DbusmenuGtk.Menu(dbus_name='glib.label.test', dbus_object='/org/test')
+dclient = dmenu.get_client()
+agroup = Gtk.AccelGroup()
+dclient.set_accel_group(agroup)
+
+menuitem.set_submenu(dmenu)
+menuitem.show()
+menubar.append(menuitem)
+menubar.show()
+window.add(menubar)
+window.set_title('libdbusmenu-gtk test')
+window.add_accel_group(agroup)
+window.show_all()
+
+gobject.timeout_add_seconds(10, timer_func, window)
+
+print 'Entering Mainloop'
+main_loop.run()
+
+if passed:
+ print 'Quiting'
+else:
+ print "Quiting as we're a failure"
+ sys.exit(1)
diff --git a/tests/test-gtk-shortcut-server.c b/tests/test-gtk-shortcut-server.c
new file mode 100644
index 0000000..b205d03
--- /dev/null
+++ b/tests/test-gtk-shortcut-server.c
@@ -0,0 +1,100 @@
+/*
+A test for libdbusmenu to ensure its quality.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <libdbusmenu-glib/menuitem.h>
+#include <libdbusmenu-glib/server.h>
+#include <libdbusmenu-gtk/menuitem.h>
+
+GMainLoop * mainloop = NULL;
+DbusmenuServer * server = NULL;
+
+gboolean
+timer_func (gpointer userdata)
+{
+ g_main_loop_quit(mainloop);
+ return FALSE;
+}
+
+void
+build_menu (void)
+{
+ DbusmenuMenuitem * item;
+
+ DbusmenuMenuitem * root = dbusmenu_menuitem_new();
+
+ item = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, "Control-L");
+ dbusmenu_menuitem_property_set_shortcut(item, GDK_l, GDK_CONTROL_MASK);
+ dbusmenu_menuitem_child_append(root, item);
+ g_object_unref(item);
+
+
+ dbusmenu_server_set_root(server, root);
+ g_object_unref(root);
+
+ return;
+}
+
+static void
+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ server = dbusmenu_server_new("/org/test");
+ build_menu();
+
+ g_timeout_add_seconds(10, timer_func, NULL);
+
+ return;
+}
+
+static void
+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ g_error("Unable to get name '%s' on DBus", name);
+ g_main_loop_quit(mainloop);
+ return;
+}
+
+int
+main (int argc, char ** argv)
+{
+ g_type_init();
+
+ g_bus_own_name(G_BUS_TYPE_SESSION,
+ "glib.label.test",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus,
+ NULL,
+ name_lost,
+ NULL,
+ NULL);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ g_debug("Quiting");
+
+ return 0;
+}
+
diff --git a/tests/test-gtk-submenu-client.c b/tests/test-gtk-submenu-client.c
new file mode 100644
index 0000000..ec46122
--- /dev/null
+++ b/tests/test-gtk-submenu-client.c
@@ -0,0 +1,150 @@
+/*
+A test for libdbusmenu to ensure its quality.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <gtk/gtk.h>
+#include <libdbusmenu-gtk/menu.h>
+
+static GMainLoop * mainloop = NULL;
+static gboolean passed = TRUE;
+
+static gboolean check_menu_content(GtkMenu * menu, char ** content)
+{
+ GList * child = gtk_container_get_children(GTK_CONTAINER(menu));
+ char ** expected = content;
+ for (; child != NULL; child = g_list_next(child), ++expected) {
+ if (*expected == NULL) {
+ g_warning("Too many gtk items");
+ return FALSE;
+ }
+ const char * label = gtk_menu_item_get_label(GTK_MENU_ITEM(child->data));
+ if (g_strcmp0(label, *expected) != 0) {
+ g_warning("Expected '%s', got '%s'", *expected, label);
+ return FALSE;
+ }
+ }
+ if (*expected != NULL) {
+ g_warning("Not enough gtk items");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
+abort_test(const char * message)
+{
+ if (message) {
+ g_warning("%s", message);
+ }
+ passed = FALSE;
+ g_main_loop_quit(mainloop);
+}
+
+static gboolean
+timer_func (gpointer data)
+{
+ static char * root_content[] = { "Folder 1", "Folder 2", NULL };
+ static char * folder1_content[] = { "1.1", "1.2", "1.3", NULL };
+ static char * folder2_content[] = { "2.1", "2.2", "2.3", NULL };
+
+ GtkMenuItem * root_item = GTK_MENU_ITEM(data);
+ GtkMenu * menu = GTK_MENU(gtk_menu_item_get_submenu(root_item));
+
+ /* Root */
+ if (!check_menu_content(menu, root_content)) {
+ abort_test("Checking root content failed");
+ return FALSE;
+ }
+
+ /* Folder 1 */
+ GList * child = gtk_container_get_children(GTK_CONTAINER(menu));
+ GtkMenuItem * item = GTK_MENU_ITEM(child->data);
+ GtkMenu * folder_menu = GTK_MENU(gtk_menu_item_get_submenu(item));
+ if (!folder_menu) {
+ abort_test("Folder 1 has no menu");
+ return FALSE;
+ }
+
+ if (!check_menu_content(folder_menu, folder1_content)) {
+ abort_test("Checking folder1 content failed");
+ return FALSE;
+ }
+
+ /* Folder 2 */
+ child = g_list_next(child);
+ item = GTK_MENU_ITEM(child->data);
+ folder_menu = GTK_MENU(gtk_menu_item_get_submenu(item));
+ if (!folder_menu) {
+ abort_test("Folder 2 has no menu");
+ return FALSE;
+ }
+
+ if (!check_menu_content(folder_menu, folder2_content)) {
+ abort_test("Checking folder2 content failed");
+ return FALSE;
+ }
+
+ passed = TRUE;
+ return FALSE;
+}
+
+gboolean
+finished_func (gpointer user_data)
+{
+ g_main_loop_quit(mainloop);
+ return FALSE;
+}
+
+int
+main (int argc, char ** argv)
+{
+ gtk_init(&argc, &argv);
+
+ g_debug("Client Initialized. Waiting.");
+ /* Make sure the server starts up and all that */
+ g_usleep(500000);
+
+ g_debug("Building Window");
+ GtkWidget * window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ GtkWidget * menubar = gtk_menu_bar_new();
+ GtkWidget * menuitem = gtk_menu_item_new_with_label("Test");
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), GTK_WIDGET(dbusmenu_gtkmenu_new ("glib.label.test", "/org/test")));
+ gtk_widget_show(menuitem);
+ gtk_menu_bar_append(menubar, menuitem);
+ gtk_widget_show(menubar);
+ gtk_container_add(GTK_CONTAINER(window), menubar);
+ gtk_window_set_title(GTK_WINDOW(window), "libdbusmenu-gtk test");
+ gtk_widget_show(window);
+
+ g_timeout_add_seconds(2, timer_func, menuitem);
+ g_timeout_add_seconds(6, finished_func, menuitem);
+
+ g_debug("Entering Mainloop");
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ if (passed) {
+ g_debug("Quiting");
+ return 0;
+ } else {
+ g_debug("Quiting as we're a failure");
+ return 1;
+ }
+}
diff --git a/tests/test-gtk-submenu-server.c b/tests/test-gtk-submenu-server.c
new file mode 100644
index 0000000..9c4d7d4
--- /dev/null
+++ b/tests/test-gtk-submenu-server.c
@@ -0,0 +1,114 @@
+/*
+A test for libdbusmenu to ensure its quality.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <libdbusmenu-glib/menuitem.h>
+#include <libdbusmenu-glib/server.h>
+
+static GMainLoop *mainloop = NULL;
+
+static gboolean
+timer_func (gpointer data)
+{
+ g_main_loop_quit (mainloop);
+
+ return FALSE;
+}
+
+static gboolean
+show_item (gpointer pmi)
+{
+ DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(pmi);
+ g_debug("Showing item");
+
+ dbusmenu_menuitem_show_to_user(mi, 0);
+
+ return FALSE;
+}
+
+DbusmenuMenuitem *
+add_item(DbusmenuMenuitem * parent, const char * label)
+{
+ DbusmenuMenuitem * item = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(item, "label", label);
+ dbusmenu_menuitem_child_append(parent, item);
+ return item;
+}
+
+static void
+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ DbusmenuServer * server = dbusmenu_server_new("/org/test");
+ DbusmenuMenuitem * root = dbusmenu_menuitem_new();
+ dbusmenu_server_set_root(server, root);
+
+ DbusmenuMenuitem * item;
+ item = add_item(root, "Folder 1");
+ add_item(item, "1.1");
+ add_item(item, "1.2");
+ add_item(item, "1.3");
+
+ g_timeout_add_seconds(2, show_item, item);
+
+ item = add_item(root, "Folder 2");
+ add_item(item, "2.1");
+ add_item(item, "2.2");
+ add_item(item, "2.3");
+
+ g_timeout_add_seconds(4, show_item, item);
+
+ return;
+}
+
+static void
+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ g_error("Unable to get name '%s' on DBus", name);
+ g_main_loop_quit(mainloop);
+ return;
+}
+
+int
+main (int argc, char ** argv)
+{
+ g_type_init();
+
+ g_bus_own_name(G_BUS_TYPE_SESSION,
+ "glib.label.test",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus,
+ NULL,
+ name_lost,
+ NULL,
+ NULL);
+
+ g_timeout_add_seconds(6, timer_func, NULL);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ g_debug("Quiting");
+
+ return 0;
+}
+
diff --git a/tests/test-json-01.json b/tests/test-json-01.json
new file mode 100644
index 0000000..b626d20
--- /dev/null
+++ b/tests/test-json-01.json
@@ -0,0 +1,4023 @@
+{
+ "id": 0,
+ "children-display": 'submenu',
+ "submenu": [
+ {
+ "id": 5,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'File',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 6,
+ "enabled": true,
+ "label": 'Quit',
+ "shortcut": [['Control', 'q']],
+ "visible": true
+ },
+ {
+ "id": 7,
+ "enabled": true,
+ "label": 'Close all',
+ "shortcut": [['Control', 'Shift', 'w']],
+ "visible": true
+ },
+ {
+ "id": 8,
+ "enabled": true,
+ "label": 'Close',
+ "shortcut": [['Control', 'w']],
+ "visible": true
+ },
+ {
+ "id": 9,
+ "type": 'separator'
+ },
+ {
+ "id": 10,
+ "enabled": true,
+ "label": 'Send by Email...',
+ "visible": true
+ },
+ {
+ "id": 11,
+ "enabled": true,
+ "label": 'Print...',
+ "shortcut": [['Control', 'p']],
+ "visible": true
+ },
+ {
+ "id": 12,
+ "enabled": true,
+ "label": 'Page Setup',
+ "visible": true
+ },
+ {
+ "id": 13,
+ "type": 'separator'
+ },
+ {
+ "id": 14,
+ "enabled": true,
+ "label": 'Revert',
+ "visible": true
+ },
+ {
+ "id": 15,
+ "enabled": true,
+ "label": 'Save as Template...',
+ "visible": true
+ },
+ {
+ "id": 16,
+ "enabled": true,
+ "label": 'Save a Copy...',
+ "visible": true
+ },
+ {
+ "id": 17,
+ "enabled": true,
+ "label": 'Save As...',
+ "shortcut": [['Control', 'Shift', 's']],
+ "visible": true
+ },
+ {
+ "id": 18,
+ "enabled": true,
+ "label": 'Save',
+ "shortcut": [['Control', 's']],
+ "visible": true
+ },
+ {
+ "id": 19,
+ "type": 'separator'
+ },
+ {
+ "id": 20,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Open Recent',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 21,
+ "enabled": true,
+ "label": 'Document History',
+ "visible": true
+ },
+ {
+ "id": 22,
+ "type": 'separator'
+ },
+ {
+ "id": 23,
+ "enabled": true,
+ "label": 'giggity.jpg',
+ "shortcut": [['Control', '2']],
+ "visible": true
+ },
+ {
+ "id": 24,
+ "enabled": true,
+ "label": 'Icon Height.svg',
+ "shortcut": [['Control', '1']],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 25,
+ "enabled": true,
+ "label": 'Open Location...',
+ "visible": true
+ },
+ {
+ "id": 26,
+ "enabled": true,
+ "label": 'Open as Layers...',
+ "shortcut": [['Control', 'Alt', 'o']],
+ "visible": true
+ },
+ {
+ "id": 27,
+ "enabled": true,
+ "label": 'Open...',
+ "shortcut": [['Control', 'o']],
+ "visible": true
+ },
+ {
+ "id": 28,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Create',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 29,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Web Page Themes',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 30,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Classic.Gimp.Org',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 31,
+ "enabled": true,
+ "label": 'Tube Sub-Sub-Button Label...',
+ "visible": true
+ },
+ {
+ "id": 32,
+ "enabled": true,
+ "label": 'Tube Sub-Button Label...',
+ "visible": true
+ },
+ {
+ "id": 33,
+ "enabled": true,
+ "label": 'Tube Button Label...',
+ "visible": true
+ },
+ {
+ "id": 34,
+ "enabled": true,
+ "label": 'Small Header...',
+ "visible": true
+ },
+ {
+ "id": 35,
+ "enabled": true,
+ "label": 'General Tube Labels...',
+ "visible": true
+ },
+ {
+ "id": 36,
+ "enabled": true,
+ "label": 'Big Header...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 37,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Beveled Pattern',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 38,
+ "enabled": true,
+ "label": 'Hrule...',
+ "visible": true
+ },
+ {
+ "id": 39,
+ "enabled": true,
+ "label": 'Heading...',
+ "visible": true
+ },
+ {
+ "id": 40,
+ "enabled": true,
+ "label": 'Button...',
+ "visible": true
+ },
+ {
+ "id": 41,
+ "enabled": true,
+ "label": 'Bullet...',
+ "visible": true
+ },
+ {
+ "id": 42,
+ "enabled": true,
+ "label": 'Arrow...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 43,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Alien Glow',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 44,
+ "enabled": true,
+ "label": 'Hrule...',
+ "visible": true
+ },
+ {
+ "id": 45,
+ "enabled": true,
+ "label": 'Button...',
+ "visible": true
+ },
+ {
+ "id": 46,
+ "enabled": true,
+ "label": 'Bullet...',
+ "visible": true
+ },
+ {
+ "id": 47,
+ "enabled": true,
+ "label": 'Arrow...',
+ "visible": true
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": 48,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Patterns',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 49,
+ "enabled": true,
+ "label": 'Truchet...',
+ "visible": true
+ },
+ {
+ "id": 50,
+ "enabled": true,
+ "label": 'Swirly...',
+ "visible": true
+ },
+ {
+ "id": 51,
+ "enabled": true,
+ "label": 'Swirl-Tile...',
+ "visible": true
+ },
+ {
+ "id": 52,
+ "enabled": true,
+ "label": 'Render Map...',
+ "visible": true
+ },
+ {
+ "id": 53,
+ "enabled": true,
+ "label": 'Land...',
+ "visible": true
+ },
+ {
+ "id": 54,
+ "enabled": true,
+ "label": 'Flatland...',
+ "visible": true
+ },
+ {
+ "id": 55,
+ "enabled": true,
+ "label": 'Camouflage...',
+ "visible": true
+ },
+ {
+ "id": 56,
+ "enabled": true,
+ "label": '3D Truchet...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 57,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Logos',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 58,
+ "enabled": true,
+ "label": 'Web Title Header...',
+ "visible": true
+ },
+ {
+ "id": 59,
+ "enabled": true,
+ "label": 'Textured...',
+ "visible": true
+ },
+ {
+ "id": 60,
+ "enabled": true,
+ "label": 'Text Circle...',
+ "visible": true
+ },
+ {
+ "id": 61,
+ "enabled": true,
+ "label": 'Starscape...',
+ "visible": true
+ },
+ {
+ "id": 62,
+ "enabled": true,
+ "label": 'Speed Text...',
+ "visible": true
+ },
+ {
+ "id": 63,
+ "enabled": true,
+ "label": 'SOTA Chrome...',
+ "visible": true
+ },
+ {
+ "id": 64,
+ "enabled": true,
+ "label": 'Particle Trace...',
+ "visible": true
+ },
+ {
+ "id": 65,
+ "enabled": true,
+ "label": 'Newsprint Text...',
+ "visible": true
+ },
+ {
+ "id": 66,
+ "enabled": true,
+ "label": 'Neon...',
+ "visible": true
+ },
+ {
+ "id": 67,
+ "enabled": true,
+ "label": 'Imigre-26...',
+ "visible": true
+ },
+ {
+ "id": 68,
+ "enabled": true,
+ "label": 'Gradient Bevel...',
+ "visible": true
+ },
+ {
+ "id": 69,
+ "enabled": true,
+ "label": 'Glowing Hot...',
+ "visible": true
+ },
+ {
+ "id": 70,
+ "enabled": true,
+ "label": 'Glossy...',
+ "visible": true
+ },
+ {
+ "id": 71,
+ "enabled": true,
+ "label": 'Frosty...',
+ "visible": true
+ },
+ {
+ "id": 72,
+ "enabled": true,
+ "label": 'Crystal...',
+ "visible": true
+ },
+ {
+ "id": 73,
+ "enabled": true,
+ "label": 'Cool Metal...',
+ "visible": true
+ },
+ {
+ "id": 74,
+ "enabled": true,
+ "label": 'Comic Book...',
+ "visible": true
+ },
+ {
+ "id": 75,
+ "enabled": true,
+ "label": 'Chrome...',
+ "visible": true
+ },
+ {
+ "id": 76,
+ "enabled": true,
+ "label": 'Chip Away...',
+ "visible": true
+ },
+ {
+ "id": 77,
+ "enabled": true,
+ "label": 'Chalk...',
+ "visible": true
+ },
+ {
+ "id": 78,
+ "enabled": true,
+ "label": 'Carved...',
+ "visible": true
+ },
+ {
+ "id": 79,
+ "enabled": true,
+ "label": 'Bovination...',
+ "visible": true
+ },
+ {
+ "id": 80,
+ "enabled": true,
+ "label": 'Blended...',
+ "visible": true
+ },
+ {
+ "id": 81,
+ "enabled": true,
+ "label": 'Basic I...',
+ "visible": true
+ },
+ {
+ "id": 82,
+ "enabled": true,
+ "label": 'Basic II...',
+ "visible": true
+ },
+ {
+ "id": 83,
+ "enabled": true,
+ "label": 'Alien Neon...',
+ "visible": true
+ },
+ {
+ "id": 84,
+ "enabled": true,
+ "label": 'Alien Glow...',
+ "visible": true
+ },
+ {
+ "id": 85,
+ "enabled": true,
+ "label": '3D Outline...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 86,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Buttons',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 87,
+ "enabled": true,
+ "label": 'Simple Beveled Button...',
+ "visible": true
+ },
+ {
+ "id": 88,
+ "enabled": true,
+ "label": 'Round Button...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 89,
+ "type": 'separator'
+ },
+ {
+ "id": 90,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'xscanimage',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 91,
+ "enabled": false,
+ "label": 'Device dialog...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 92,
+ "enabled": true,
+ "label": 'Screenshot...',
+ "visible": true
+ },
+ {
+ "id": 93,
+ "enabled": true,
+ "label": 'From Clipboard',
+ "shortcut": [['Control', 'Shift', 'v']],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 94,
+ "enabled": true,
+ "label": 'New...',
+ "shortcut": [['Control', 'n']],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 95,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Edit',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 96,
+ "enabled": true,
+ "label": 'Units',
+ "visible": true
+ },
+ {
+ "id": 97,
+ "enabled": true,
+ "label": 'Modules',
+ "visible": true
+ },
+ {
+ "id": 98,
+ "enabled": true,
+ "label": 'Keyboard Shortcuts',
+ "visible": true
+ },
+ {
+ "id": 99,
+ "enabled": true,
+ "label": 'Preferences',
+ "visible": true
+ },
+ {
+ "id": 100,
+ "type": 'separator'
+ },
+ {
+ "id": 101,
+ "enabled": false,
+ "label": 'Stroke Path...',
+ "visible": true
+ },
+ {
+ "id": 102,
+ "enabled": false,
+ "label": 'Stroke Selection...',
+ "visible": true
+ },
+ {
+ "id": 103,
+ "enabled": true,
+ "label": 'Fill with Pattern',
+ "shortcut": [['Control', 'semicolon']],
+ "visible": true
+ },
+ {
+ "id": 104,
+ "enabled": true,
+ "label": 'Fill with BG Color',
+ "shortcut": [['Control', 'period']],
+ "visible": true
+ },
+ {
+ "id": 105,
+ "enabled": true,
+ "label": 'Fill with FG Color',
+ "shortcut": [['Control', 'comma']],
+ "visible": true
+ },
+ {
+ "id": 106,
+ "enabled": true,
+ "label": 'Clear',
+ "shortcut": [['Delete']],
+ "visible": true
+ },
+ {
+ "id": 107,
+ "type": 'separator'
+ },
+ {
+ "id": 108,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Buffer',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 109,
+ "enabled": true,
+ "label": 'Paste Named...',
+ "visible": true
+ },
+ {
+ "id": 110,
+ "enabled": true,
+ "label": 'Copy Visible Named...',
+ "visible": true
+ },
+ {
+ "id": 111,
+ "enabled": true,
+ "label": 'Copy Named...',
+ "visible": true
+ },
+ {
+ "id": 112,
+ "enabled": true,
+ "label": 'Cut Named...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 113,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Paste as',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 114,
+ "enabled": true,
+ "label": 'New Pattern...',
+ "visible": true
+ },
+ {
+ "id": 115,
+ "enabled": true,
+ "label": 'New Brush...',
+ "visible": true
+ },
+ {
+ "id": 116,
+ "enabled": true,
+ "label": 'New Layer',
+ "visible": true
+ },
+ {
+ "id": 117,
+ "enabled": true,
+ "label": 'New Image',
+ "shortcut": [['Control', 'Shift', 'v']],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 118,
+ "enabled": true,
+ "label": 'Paste Into',
+ "visible": true
+ },
+ {
+ "id": 119,
+ "enabled": true,
+ "label": 'Paste',
+ "shortcut": [['Control', 'v']],
+ "visible": true
+ },
+ {
+ "id": 120,
+ "enabled": true,
+ "label": 'Copy Visible',
+ "shortcut": [['Control', 'Shift', 'c']],
+ "visible": true
+ },
+ {
+ "id": 121,
+ "enabled": true,
+ "label": 'Copy',
+ "shortcut": [['Control', 'c']],
+ "visible": true
+ },
+ {
+ "id": 122,
+ "enabled": true,
+ "label": 'Cut',
+ "shortcut": [['Control', 'x']],
+ "visible": true
+ },
+ {
+ "id": 123,
+ "type": 'separator'
+ },
+ {
+ "id": 124,
+ "enabled": true,
+ "label": 'Undo History',
+ "visible": true
+ },
+ {
+ "id": 3,
+ "enabled": false,
+ "label": '_Fade...',
+ "visible": true
+ },
+ {
+ "id": 2,
+ "enabled": false,
+ "label": '_Redo',
+ "shortcut": [['Control', 'y']],
+ "visible": true
+ },
+ {
+ "id": 1,
+ "enabled": false,
+ "label": '_Undo',
+ "shortcut": [['Control', 'z']],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 125,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Select',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 126,
+ "enabled": false,
+ "label": 'To Path',
+ "visible": true
+ },
+ {
+ "id": 127,
+ "enabled": true,
+ "label": 'Save to Channel',
+ "visible": true
+ },
+ {
+ "id": 128,
+ "enabled": true,
+ "label": 'Toggle Quick Mask',
+ "shortcut": [['Shift', 'q']],
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 129,
+ "type": 'separator'
+ },
+ {
+ "id": 130,
+ "enabled": true,
+ "label": 'Distort...',
+ "visible": true
+ },
+ {
+ "id": 131,
+ "enabled": false,
+ "label": 'Border...',
+ "visible": true
+ },
+ {
+ "id": 132,
+ "enabled": false,
+ "label": 'Grow...',
+ "visible": true
+ },
+ {
+ "id": 133,
+ "enabled": false,
+ "label": 'Shrink...',
+ "visible": true
+ },
+ {
+ "id": 134,
+ "enabled": false,
+ "label": 'Sharpen',
+ "visible": true
+ },
+ {
+ "id": 135,
+ "enabled": false,
+ "label": 'Feather...',
+ "visible": true
+ },
+ {
+ "id": 136,
+ "type": 'separator'
+ },
+ {
+ "id": 137,
+ "enabled": true,
+ "label": 'Selection Editor',
+ "visible": true
+ },
+ {
+ "id": 138,
+ "enabled": false,
+ "label": 'From Path',
+ "shortcut": [['Shift', 'v']],
+ "visible": true
+ },
+ {
+ "id": 139,
+ "enabled": true,
+ "label": 'By Color',
+ "shortcut": [['Shift', 'o']],
+ "visible": true
+ },
+ {
+ "id": 140,
+ "enabled": false,
+ "label": 'Float',
+ "shortcut": [['Control', 'Shift', 'l']],
+ "visible": true
+ },
+ {
+ "id": 141,
+ "enabled": true,
+ "label": 'Invert',
+ "shortcut": [['Control', 'i']],
+ "visible": true
+ },
+ {
+ "id": 142,
+ "enabled": false,
+ "label": 'None',
+ "shortcut": [['Control', 'Shift', 'a']],
+ "visible": true
+ },
+ {
+ "id": 143,
+ "enabled": true,
+ "label": 'All',
+ "shortcut": [['Control', 'a']],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 144,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'View',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 145,
+ "enabled": true,
+ "label": 'Show Statusbar',
+ "toggle-state": 1,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 146,
+ "enabled": true,
+ "label": 'Show Scrollbars',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 147,
+ "enabled": true,
+ "label": 'Show Rulers',
+ "shortcut": [['Control', 'Shift', 'r']],
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 148,
+ "enabled": true,
+ "label": 'Show Menubar',
+ "toggle-state": 1,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 149,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Padding Color',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 150,
+ "enabled": true,
+ "label": 'As in Preferences',
+ "visible": true
+ },
+ {
+ "id": 151,
+ "type": 'separator'
+ },
+ {
+ "id": 152,
+ "enabled": true,
+ "label": 'Select Custom Color...',
+ "visible": true
+ },
+ {
+ "id": 153,
+ "enabled": true,
+ "label": 'Dark Check Color',
+ "visible": true
+ },
+ {
+ "id": 154,
+ "enabled": true,
+ "label": 'Light Check Color',
+ "visible": true
+ },
+ {
+ "id": 155,
+ "enabled": true,
+ "label": 'From Theme',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 156,
+ "type": 'separator'
+ },
+ {
+ "id": 157,
+ "enabled": true,
+ "label": 'Snap to Active Path',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 158,
+ "enabled": true,
+ "label": 'Snap to Canvas Edges',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 159,
+ "enabled": true,
+ "label": 'Snap to Grid',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 160,
+ "enabled": true,
+ "label": 'Snap to Guides',
+ "toggle-state": 1,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 161,
+ "type": 'separator'
+ },
+ {
+ "id": 162,
+ "enabled": true,
+ "label": 'Show Sample Points',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 163,
+ "enabled": true,
+ "label": 'Show Grid',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 164,
+ "enabled": true,
+ "label": 'Show Guides',
+ "shortcut": [['Control', 'Shift', 't']],
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 165,
+ "enabled": true,
+ "label": 'Show Layer Boundary',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 166,
+ "enabled": true,
+ "label": 'Show Selection',
+ "shortcut": [['Control', 't']],
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 167,
+ "type": 'separator'
+ },
+ {
+ "id": 168,
+ "enabled": true,
+ "label": 'Display Filters...',
+ "visible": true
+ },
+ {
+ "id": 169,
+ "enabled": true,
+ "label": 'Navigation Window',
+ "visible": true
+ },
+ {
+ "id": 170,
+ "type": 'separator'
+ },
+ {
+ "id": 171,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Fullscreen',
+ "shortcut": [['F11']],
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 172,
+ "enabled": true,
+ "label": 'Open Display...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 173,
+ "enabled": true,
+ "label": 'Shrink Wrap',
+ "shortcut": [['Control', 'e']],
+ "visible": true
+ },
+ {
+ "id": 174,
+ "type": 'separator'
+ },
+ {
+ "id": 175,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": '_Zoom (67%)',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 176,
+ "enabled": true,
+ "label": 'Othe_r (67%)...',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 177,
+ "type": 'separator'
+ },
+ {
+ "id": 178,
+ "enabled": true,
+ "label": '1:16 (6.25%)',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 179,
+ "enabled": true,
+ "label": '1:8 (12.5%)',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 180,
+ "enabled": true,
+ "label": '1:4 (25%)',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 181,
+ "enabled": true,
+ "label": '1:2 (50%)',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 182,
+ "enabled": true,
+ "label": '1:1 (100%)',
+ "shortcut": [['1']],
+ "toggle-state": 1,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 183,
+ "enabled": true,
+ "label": '2:1 (200%)',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 184,
+ "enabled": true,
+ "label": '4:1 (400%)',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 185,
+ "enabled": true,
+ "label": '8:1 (800%)',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 186,
+ "enabled": true,
+ "label": '16:1 (1600%)',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 187,
+ "type": 'separator'
+ },
+ {
+ "id": 188,
+ "enabled": true,
+ "label": 'Fill Window',
+ "visible": true
+ },
+ {
+ "id": 189,
+ "enabled": true,
+ "label": 'Fit Image in Window',
+ "shortcut": [['Control', 'Shift', 'e']],
+ "visible": true
+ },
+ {
+ "id": 190,
+ "enabled": true,
+ "label": 'Zoom In',
+ "shortcut": [['plus']],
+ "visible": true
+ },
+ {
+ "id": 191,
+ "enabled": true,
+ "label": 'Zoom Out',
+ "shortcut": [['minus']],
+ "visible": true
+ },
+ {
+ "id": 4,
+ "enabled": true,
+ "label": 'Re_vert Zoom (67%)',
+ "shortcut": [['grave']],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 192,
+ "enabled": true,
+ "label": 'Dot for Dot',
+ "toggle-state": 1,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 193,
+ "enabled": true,
+ "label": 'New View',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 194,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Image',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 195,
+ "enabled": true,
+ "label": 'Image Properties',
+ "shortcut": [['Alt', 'Return']],
+ "visible": true
+ },
+ {
+ "id": 196,
+ "enabled": true,
+ "label": 'Configure Grid...',
+ "visible": true
+ },
+ {
+ "id": 197,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Guides',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 198,
+ "enabled": true,
+ "label": 'Remove all Guides',
+ "visible": true
+ },
+ {
+ "id": 199,
+ "enabled": true,
+ "label": 'New Guides from Selection',
+ "visible": true
+ },
+ {
+ "id": 200,
+ "enabled": true,
+ "label": 'New Guide...',
+ "visible": true
+ },
+ {
+ "id": 201,
+ "enabled": true,
+ "label": 'New Guide (by Percent)...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 202,
+ "type": 'separator'
+ },
+ {
+ "id": 203,
+ "enabled": true,
+ "label": 'Align Visible Layers...',
+ "visible": true
+ },
+ {
+ "id": 204,
+ "enabled": true,
+ "label": 'Flatten Image',
+ "visible": true
+ },
+ {
+ "id": 205,
+ "enabled": true,
+ "label": 'Merge Visible Layers...',
+ "shortcut": [['Control', 'm']],
+ "visible": true
+ },
+ {
+ "id": 206,
+ "type": 'separator'
+ },
+ {
+ "id": 207,
+ "enabled": true,
+ "label": 'Zealous Crop',
+ "visible": true
+ },
+ {
+ "id": 208,
+ "enabled": true,
+ "label": 'Autocrop Image',
+ "visible": true
+ },
+ {
+ "id": 209,
+ "enabled": false,
+ "label": 'Crop to Selection',
+ "visible": true
+ },
+ {
+ "id": 210,
+ "type": 'separator'
+ },
+ {
+ "id": 211,
+ "enabled": true,
+ "label": 'Scale Image...',
+ "visible": true
+ },
+ {
+ "id": 212,
+ "enabled": true,
+ "label": 'Print Size...',
+ "visible": true
+ },
+ {
+ "id": 213,
+ "enabled": false,
+ "label": 'Fit Canvas to Selection',
+ "visible": true
+ },
+ {
+ "id": 214,
+ "enabled": true,
+ "label": 'Fit Canvas to Layers',
+ "visible": true
+ },
+ {
+ "id": 215,
+ "enabled": true,
+ "label": 'Canvas Size...',
+ "visible": true
+ },
+ {
+ "id": 216,
+ "type": 'separator'
+ },
+ {
+ "id": 217,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Transform',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 218,
+ "enabled": true,
+ "label": 'Guillotine',
+ "visible": true
+ },
+ {
+ "id": 219,
+ "type": 'separator'
+ },
+ {
+ "id": 220,
+ "enabled": true,
+ "label": 'Rotate 180?',
+ "visible": true
+ },
+ {
+ "id": 221,
+ "enabled": true,
+ "label": 'Rotate 90? counter-clockwise',
+ "visible": true
+ },
+ {
+ "id": 222,
+ "enabled": true,
+ "label": 'Rotate 90? clockwise',
+ "visible": true
+ },
+ {
+ "id": 223,
+ "type": 'separator'
+ },
+ {
+ "id": 224,
+ "enabled": true,
+ "label": 'Flip Vertically',
+ "visible": true
+ },
+ {
+ "id": 225,
+ "enabled": true,
+ "label": 'Flip Horizontally',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 226,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Mode',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 227,
+ "enabled": true,
+ "label": 'Convert to Color Profile...',
+ "visible": true
+ },
+ {
+ "id": 228,
+ "enabled": true,
+ "label": 'Assign Color Profile...',
+ "visible": true
+ },
+ {
+ "id": 229,
+ "type": 'separator'
+ },
+ {
+ "id": 230,
+ "enabled": true,
+ "label": 'Indexed...',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 231,
+ "enabled": true,
+ "label": 'Grayscale',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 232,
+ "enabled": true,
+ "label": 'RGB',
+ "toggle-state": 1,
+ "toggle-type": 'checkmark',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 233,
+ "enabled": true,
+ "label": 'Duplicate',
+ "shortcut": [['Control', 'd']],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 234,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Layer',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 235,
+ "enabled": true,
+ "label": 'Autocrop Layer',
+ "visible": true
+ },
+ {
+ "id": 236,
+ "enabled": false,
+ "label": 'Crop to Selection',
+ "visible": true
+ },
+ {
+ "id": 237,
+ "enabled": true,
+ "label": 'Scale Layer...',
+ "visible": true
+ },
+ {
+ "id": 238,
+ "enabled": true,
+ "label": 'Layer to Image Size',
+ "visible": true
+ },
+ {
+ "id": 239,
+ "enabled": true,
+ "label": 'Layer Boundary Size...',
+ "visible": true
+ },
+ {
+ "id": 240,
+ "type": 'separator'
+ },
+ {
+ "id": 241,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Transform',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 242,
+ "enabled": true,
+ "label": 'Offset...',
+ "shortcut": [['Control', 'Shift', 'o']],
+ "visible": true
+ },
+ {
+ "id": 243,
+ "type": 'separator'
+ },
+ {
+ "id": 244,
+ "enabled": true,
+ "label": 'Arbitrary Rotation...',
+ "visible": true
+ },
+ {
+ "id": 245,
+ "enabled": true,
+ "label": 'Rotate 180?',
+ "visible": true
+ },
+ {
+ "id": 246,
+ "enabled": true,
+ "label": 'Rotate 90? counter-clockwise',
+ "visible": true
+ },
+ {
+ "id": 247,
+ "enabled": true,
+ "label": 'Rotate 90? clockwise',
+ "visible": true
+ },
+ {
+ "id": 248,
+ "type": 'separator'
+ },
+ {
+ "id": 249,
+ "enabled": true,
+ "label": 'Flip Vertically',
+ "visible": true
+ },
+ {
+ "id": 250,
+ "enabled": true,
+ "label": 'Flip Horizontally',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 251,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Transparency',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 252,
+ "enabled": true,
+ "label": 'Intersect with Selection',
+ "visible": true
+ },
+ {
+ "id": 253,
+ "enabled": true,
+ "label": 'Subtract from Selection',
+ "visible": true
+ },
+ {
+ "id": 254,
+ "enabled": true,
+ "label": 'Add to Selection',
+ "visible": true
+ },
+ {
+ "id": 255,
+ "enabled": true,
+ "label": 'Alpha to Selection',
+ "visible": true
+ },
+ {
+ "id": 256,
+ "type": 'separator'
+ },
+ {
+ "id": 257,
+ "enabled": true,
+ "label": 'Threshold Alpha...',
+ "visible": true
+ },
+ {
+ "id": 258,
+ "enabled": true,
+ "label": 'Semi-Flatten',
+ "visible": true
+ },
+ {
+ "id": 259,
+ "enabled": true,
+ "label": 'Color to Alpha...',
+ "visible": true
+ },
+ {
+ "id": 260,
+ "enabled": true,
+ "label": 'Remove Alpha Channel',
+ "visible": true
+ },
+ {
+ "id": 261,
+ "enabled": false,
+ "label": 'Add Alpha Channel',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 262,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Mask',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 263,
+ "enabled": false,
+ "label": 'Intersect with Selection',
+ "visible": true
+ },
+ {
+ "id": 264,
+ "enabled": false,
+ "label": 'Subtract from Selection',
+ "visible": true
+ },
+ {
+ "id": 265,
+ "enabled": false,
+ "label": 'Add to Selection',
+ "visible": true
+ },
+ {
+ "id": 266,
+ "enabled": false,
+ "label": 'Mask to Selection',
+ "visible": true
+ },
+ {
+ "id": 267,
+ "type": 'separator'
+ },
+ {
+ "id": 268,
+ "enabled": false,
+ "label": 'Disable Layer Mask',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 269,
+ "enabled": false,
+ "label": 'Edit Layer Mask',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 270,
+ "enabled": false,
+ "label": 'Show Layer Mask',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 271,
+ "type": 'separator'
+ },
+ {
+ "id": 272,
+ "enabled": false,
+ "label": 'Delete Layer Mask',
+ "visible": true
+ },
+ {
+ "id": 273,
+ "enabled": false,
+ "label": 'Apply Layer Mask',
+ "visible": true
+ },
+ {
+ "id": 274,
+ "enabled": true,
+ "label": 'Add Layer Mask...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 275,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Stack',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 276,
+ "enabled": true,
+ "label": 'Reverse Layer Order',
+ "visible": true
+ },
+ {
+ "id": 277,
+ "type": 'separator'
+ },
+ {
+ "id": 278,
+ "enabled": false,
+ "label": 'Layer to Bottom',
+ "visible": true
+ },
+ {
+ "id": 279,
+ "enabled": false,
+ "label": 'Layer to Top',
+ "visible": true
+ },
+ {
+ "id": 280,
+ "enabled": false,
+ "label": 'Lower Layer',
+ "visible": true
+ },
+ {
+ "id": 281,
+ "enabled": false,
+ "label": 'Raise Layer',
+ "visible": true
+ },
+ {
+ "id": 282,
+ "type": 'separator'
+ },
+ {
+ "id": 283,
+ "enabled": false,
+ "label": 'Select Bottom Layer',
+ "shortcut": [['End']],
+ "visible": true
+ },
+ {
+ "id": 284,
+ "enabled": false,
+ "label": 'Select Top Layer',
+ "shortcut": [['Home']],
+ "visible": true
+ },
+ {
+ "id": 285,
+ "enabled": false,
+ "label": 'Select Next Layer',
+ "shortcut": [['Page_Down']],
+ "visible": true
+ },
+ {
+ "id": 286,
+ "enabled": false,
+ "label": 'Select Previous Layer',
+ "shortcut": [['Page_Up']],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 287,
+ "children-display": 'submenu',
+ "type": 'separator',
+ "submenu": [
+ {
+ "id": 288,
+ "enabled": false,
+ "label": 'Empty',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 289,
+ "enabled": true,
+ "label": 'Delete Layer',
+ "visible": true
+ },
+ {
+ "id": 290,
+ "enabled": false,
+ "label": 'Merge Down',
+ "visible": true
+ },
+ {
+ "id": 291,
+ "enabled": false,
+ "label": 'Anchor Layer',
+ "shortcut": [['Control', 'h']],
+ "visible": true
+ },
+ {
+ "id": 292,
+ "enabled": true,
+ "label": 'Duplicate Layer',
+ "shortcut": [['Control', 'Shift', 'd']],
+ "visible": true
+ },
+ {
+ "id": 293,
+ "enabled": true,
+ "label": 'New from Visible',
+ "visible": true
+ },
+ {
+ "id": 294,
+ "enabled": true,
+ "label": 'New Layer...',
+ "shortcut": [['Control', 'Shift', 'n']],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 295,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Colors',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 296,
+ "enabled": true,
+ "label": 'Retinex...',
+ "visible": true
+ },
+ {
+ "id": 297,
+ "enabled": true,
+ "label": 'Maximum RGB...',
+ "visible": true
+ },
+ {
+ "id": 298,
+ "enabled": false,
+ "label": 'Hot...',
+ "visible": true
+ },
+ {
+ "id": 299,
+ "enabled": true,
+ "label": 'Filter Pack...',
+ "visible": true
+ },
+ {
+ "id": 300,
+ "enabled": true,
+ "label": 'Color to Alpha...',
+ "visible": true
+ },
+ {
+ "id": 301,
+ "enabled": true,
+ "label": 'Colorify...',
+ "visible": true
+ },
+ {
+ "id": 302,
+ "type": 'separator'
+ },
+ {
+ "id": 303,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Info',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 304,
+ "enabled": true,
+ "label": 'Smooth Palette...',
+ "visible": true
+ },
+ {
+ "id": 305,
+ "enabled": true,
+ "label": 'Colorcube Analysis...',
+ "visible": true
+ },
+ {
+ "id": 306,
+ "enabled": true,
+ "label": 'Border Average...',
+ "visible": true
+ },
+ {
+ "id": 307,
+ "enabled": true,
+ "label": 'Histogram',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 308,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Map',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 309,
+ "enabled": true,
+ "label": 'Sample Colorize...',
+ "visible": true
+ },
+ {
+ "id": 310,
+ "enabled": true,
+ "label": 'Rotate Colors...',
+ "visible": true
+ },
+ {
+ "id": 311,
+ "enabled": true,
+ "label": 'Palette Map',
+ "visible": true
+ },
+ {
+ "id": 312,
+ "enabled": true,
+ "label": 'Gradient Map',
+ "visible": true
+ },
+ {
+ "id": 313,
+ "enabled": true,
+ "label": 'Color Exchange...',
+ "visible": true
+ },
+ {
+ "id": 314,
+ "enabled": true,
+ "label": 'Alien Map...',
+ "visible": true
+ },
+ {
+ "id": 315,
+ "type": 'separator'
+ },
+ {
+ "id": 316,
+ "enabled": false,
+ "label": 'Set Colormap...',
+ "visible": true
+ },
+ {
+ "id": 317,
+ "enabled": false,
+ "label": 'Rearrange Colormap...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 318,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Components',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 319,
+ "enabled": false,
+ "label": 'Recompose',
+ "visible": true
+ },
+ {
+ "id": 320,
+ "enabled": true,
+ "label": 'Decompose...',
+ "visible": true
+ },
+ {
+ "id": 321,
+ "enabled": false,
+ "label": 'Compose...',
+ "visible": true
+ },
+ {
+ "id": 322,
+ "enabled": true,
+ "label": 'Channel Mixer...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 323,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Auto',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 324,
+ "enabled": true,
+ "label": 'Stretch HSV',
+ "visible": true
+ },
+ {
+ "id": 325,
+ "enabled": true,
+ "label": 'Stretch Contrast',
+ "visible": true
+ },
+ {
+ "id": 326,
+ "enabled": true,
+ "label": 'Normalize',
+ "visible": true
+ },
+ {
+ "id": 327,
+ "enabled": true,
+ "label": 'Color Enhance',
+ "visible": true
+ },
+ {
+ "id": 328,
+ "enabled": true,
+ "label": 'White Balance',
+ "visible": true
+ },
+ {
+ "id": 329,
+ "enabled": true,
+ "label": 'Equalize',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 330,
+ "type": 'separator'
+ },
+ {
+ "id": 331,
+ "enabled": true,
+ "label": 'Use GEGL',
+ "toggle-state": 0,
+ "toggle-type": 'checkmark',
+ "visible": true
+ },
+ {
+ "id": 332,
+ "type": 'separator'
+ },
+ {
+ "id": 333,
+ "enabled": true,
+ "label": 'Value Invert',
+ "visible": true
+ },
+ {
+ "id": 334,
+ "enabled": true,
+ "label": 'Invert',
+ "visible": true
+ },
+ {
+ "id": 335,
+ "type": 'separator'
+ },
+ {
+ "id": 336,
+ "enabled": true,
+ "label": 'Desaturate...',
+ "visible": true
+ },
+ {
+ "id": 337,
+ "enabled": true,
+ "label": 'Posterize...',
+ "visible": true
+ },
+ {
+ "id": 338,
+ "enabled": true,
+ "label": 'Curves...',
+ "visible": true
+ },
+ {
+ "id": 339,
+ "enabled": true,
+ "label": 'Levels...',
+ "visible": true
+ },
+ {
+ "id": 340,
+ "enabled": true,
+ "label": 'Threshold...',
+ "visible": true
+ },
+ {
+ "id": 341,
+ "enabled": true,
+ "label": 'Brightness-Contrast...',
+ "visible": true
+ },
+ {
+ "id": 342,
+ "enabled": true,
+ "label": 'Colorize...',
+ "visible": true
+ },
+ {
+ "id": 343,
+ "enabled": true,
+ "label": 'Hue-Saturation...',
+ "visible": true
+ },
+ {
+ "id": 344,
+ "enabled": true,
+ "label": 'Color Balance...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 345,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Tools',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 346,
+ "enabled": true,
+ "label": 'Swap Colors',
+ "shortcut": [['x']],
+ "visible": true
+ },
+ {
+ "id": 347,
+ "enabled": true,
+ "label": 'Default Colors',
+ "shortcut": [['d']],
+ "visible": true
+ },
+ {
+ "id": 348,
+ "enabled": true,
+ "label": 'Toolbox',
+ "shortcut": [['Control', 'b']],
+ "visible": true
+ },
+ {
+ "id": 349,
+ "type": 'separator'
+ },
+ {
+ "id": 350,
+ "enabled": true,
+ "label": 'GEGL Operation...',
+ "visible": true
+ },
+ {
+ "id": 351,
+ "enabled": true,
+ "label": 'Text',
+ "shortcut": [['t']],
+ "visible": true
+ },
+ {
+ "id": 352,
+ "enabled": true,
+ "label": 'Measure',
+ "shortcut": [['Shift', 'm']],
+ "visible": true
+ },
+ {
+ "id": 353,
+ "enabled": true,
+ "label": 'Zoom',
+ "shortcut": [['z']],
+ "visible": true
+ },
+ {
+ "id": 354,
+ "enabled": true,
+ "label": 'Color Picker',
+ "shortcut": [['o']],
+ "visible": true
+ },
+ {
+ "id": 355,
+ "enabled": true,
+ "label": 'Paths',
+ "shortcut": [['b']],
+ "visible": true
+ },
+ {
+ "id": 356,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Color Tools',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 357,
+ "enabled": true,
+ "label": 'Desaturate...',
+ "visible": true
+ },
+ {
+ "id": 358,
+ "enabled": true,
+ "label": 'Posterize...',
+ "visible": true
+ },
+ {
+ "id": 359,
+ "enabled": true,
+ "label": 'Curves...',
+ "visible": true
+ },
+ {
+ "id": 360,
+ "enabled": true,
+ "label": 'Levels...',
+ "visible": true
+ },
+ {
+ "id": 361,
+ "enabled": true,
+ "label": 'Threshold...',
+ "visible": true
+ },
+ {
+ "id": 362,
+ "enabled": true,
+ "label": 'Brightness-Contrast...',
+ "visible": true
+ },
+ {
+ "id": 363,
+ "enabled": true,
+ "label": 'Colorize...',
+ "visible": true
+ },
+ {
+ "id": 364,
+ "enabled": true,
+ "label": 'Hue-Saturation...',
+ "visible": true
+ },
+ {
+ "id": 365,
+ "enabled": true,
+ "label": 'Color Balance...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 366,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Transform Tools',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 367,
+ "enabled": true,
+ "label": 'Flip',
+ "shortcut": [['Shift', 'f']],
+ "visible": true
+ },
+ {
+ "id": 368,
+ "enabled": true,
+ "label": 'Perspective',
+ "shortcut": [['Shift', 'p']],
+ "visible": true
+ },
+ {
+ "id": 369,
+ "enabled": true,
+ "label": 'Shear',
+ "shortcut": [['Shift', 's']],
+ "visible": true
+ },
+ {
+ "id": 370,
+ "enabled": true,
+ "label": 'Scale',
+ "shortcut": [['Shift', 't']],
+ "visible": true
+ },
+ {
+ "id": 371,
+ "enabled": true,
+ "label": 'Rotate',
+ "shortcut": [['Shift', 'r']],
+ "visible": true
+ },
+ {
+ "id": 372,
+ "enabled": true,
+ "label": 'Crop',
+ "shortcut": [['Shift', 'c']],
+ "visible": true
+ },
+ {
+ "id": 373,
+ "enabled": true,
+ "label": 'Move',
+ "shortcut": [['m']],
+ "visible": true
+ },
+ {
+ "id": 374,
+ "enabled": true,
+ "label": 'Align',
+ "shortcut": [['q']],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 375,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Paint Tools',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 376,
+ "enabled": true,
+ "label": 'Dodge / Burn',
+ "shortcut": [['Shift', 'd']],
+ "visible": true
+ },
+ {
+ "id": 377,
+ "enabled": true,
+ "label": 'Smudge',
+ "shortcut": [['s']],
+ "visible": true
+ },
+ {
+ "id": 378,
+ "enabled": true,
+ "label": 'Blur / Sharpen',
+ "shortcut": [['Shift', 'u']],
+ "visible": true
+ },
+ {
+ "id": 379,
+ "enabled": true,
+ "label": 'Perspective Clone',
+ "visible": true
+ },
+ {
+ "id": 380,
+ "enabled": true,
+ "label": 'Heal',
+ "shortcut": [['h']],
+ "visible": true
+ },
+ {
+ "id": 381,
+ "enabled": true,
+ "label": 'Clone',
+ "shortcut": [['c']],
+ "visible": true
+ },
+ {
+ "id": 382,
+ "enabled": true,
+ "label": 'Ink',
+ "shortcut": [['k']],
+ "visible": true
+ },
+ {
+ "id": 383,
+ "enabled": true,
+ "label": 'Airbrush',
+ "shortcut": [['a']],
+ "visible": true
+ },
+ {
+ "id": 384,
+ "enabled": true,
+ "label": 'Eraser',
+ "shortcut": [['Shift', 'e']],
+ "visible": true
+ },
+ {
+ "id": 385,
+ "enabled": true,
+ "label": 'Paintbrush',
+ "shortcut": [['p']],
+ "visible": true
+ },
+ {
+ "id": 386,
+ "enabled": true,
+ "label": 'Pencil',
+ "shortcut": [['n']],
+ "visible": true
+ },
+ {
+ "id": 387,
+ "enabled": true,
+ "label": 'Blend',
+ "shortcut": [['l']],
+ "visible": true
+ },
+ {
+ "id": 388,
+ "enabled": true,
+ "label": 'Bucket Fill',
+ "shortcut": [['Shift', 'b']],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 389,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Selection Tools',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 390,
+ "enabled": true,
+ "label": 'Intelligent Scissors',
+ "shortcut": [['i']],
+ "visible": true
+ },
+ {
+ "id": 391,
+ "enabled": true,
+ "label": 'By Color Select',
+ "shortcut": [['Shift', 'o']],
+ "visible": true
+ },
+ {
+ "id": 392,
+ "enabled": true,
+ "label": 'Fuzzy Select',
+ "shortcut": [['u']],
+ "visible": true
+ },
+ {
+ "id": 393,
+ "enabled": true,
+ "label": 'Foreground Select',
+ "visible": true
+ },
+ {
+ "id": 394,
+ "enabled": true,
+ "label": 'Free Select',
+ "shortcut": [['f']],
+ "visible": true
+ },
+ {
+ "id": 395,
+ "enabled": true,
+ "label": 'Ellipse Select',
+ "shortcut": [['e']],
+ "visible": true
+ },
+ {
+ "id": 396,
+ "enabled": true,
+ "label": 'Rectangle Select',
+ "shortcut": [['r']],
+ "visible": true
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": 397,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Filters',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 398,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Script-Fu',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 399,
+ "enabled": true,
+ "label": 'Start Server...',
+ "visible": true
+ },
+ {
+ "id": 400,
+ "enabled": true,
+ "label": 'Refresh Scripts',
+ "visible": true
+ },
+ {
+ "id": 401,
+ "enabled": true,
+ "label": 'Console',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 402,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Python-Fu',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 403,
+ "enabled": true,
+ "label": 'Console',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 404,
+ "type": 'separator'
+ },
+ {
+ "id": 405,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Alpha to Logo',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 406,
+ "enabled": true,
+ "label": 'Textured...',
+ "visible": true
+ },
+ {
+ "id": 407,
+ "enabled": true,
+ "label": 'Particle Trace...',
+ "visible": true
+ },
+ {
+ "id": 408,
+ "enabled": true,
+ "label": 'Neon...',
+ "visible": true
+ },
+ {
+ "id": 409,
+ "enabled": true,
+ "label": 'Gradient Bevel...',
+ "visible": true
+ },
+ {
+ "id": 410,
+ "enabled": true,
+ "label": 'Glowing Hot...',
+ "visible": true
+ },
+ {
+ "id": 411,
+ "enabled": true,
+ "label": 'Glossy...',
+ "visible": true
+ },
+ {
+ "id": 412,
+ "enabled": true,
+ "label": 'Frosty...',
+ "visible": true
+ },
+ {
+ "id": 413,
+ "enabled": true,
+ "label": 'Cool Metal...',
+ "visible": true
+ },
+ {
+ "id": 414,
+ "enabled": true,
+ "label": 'Comic Book...',
+ "visible": true
+ },
+ {
+ "id": 415,
+ "enabled": true,
+ "label": 'Chrome...',
+ "visible": true
+ },
+ {
+ "id": 416,
+ "enabled": true,
+ "label": 'Chip Away...',
+ "visible": true
+ },
+ {
+ "id": 417,
+ "enabled": true,
+ "label": 'Chalk...',
+ "visible": true
+ },
+ {
+ "id": 418,
+ "enabled": true,
+ "label": 'Bovination...',
+ "visible": true
+ },
+ {
+ "id": 419,
+ "enabled": true,
+ "label": 'Blended...',
+ "visible": true
+ },
+ {
+ "id": 420,
+ "enabled": true,
+ "label": 'Basic I...',
+ "visible": true
+ },
+ {
+ "id": 421,
+ "enabled": true,
+ "label": 'Basic II...',
+ "visible": true
+ },
+ {
+ "id": 422,
+ "enabled": true,
+ "label": 'Alien Neon...',
+ "visible": true
+ },
+ {
+ "id": 423,
+ "enabled": true,
+ "label": 'Alien Glow...',
+ "visible": true
+ },
+ {
+ "id": 424,
+ "enabled": true,
+ "label": '3D Outline...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 425,
+ "type": 'separator'
+ },
+ {
+ "id": 426,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Animation',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 427,
+ "enabled": true,
+ "label": 'Unoptimize',
+ "visible": true
+ },
+ {
+ "id": 428,
+ "enabled": true,
+ "label": 'Playback...',
+ "visible": true
+ },
+ {
+ "id": 429,
+ "enabled": true,
+ "label": 'Optimize (for GIF)',
+ "visible": true
+ },
+ {
+ "id": 430,
+ "enabled": true,
+ "label": 'Optimize (Difference)',
+ "visible": true
+ },
+ {
+ "id": 431,
+ "type": 'separator'
+ },
+ {
+ "id": 432,
+ "enabled": true,
+ "label": 'Waves...',
+ "visible": true
+ },
+ {
+ "id": 433,
+ "enabled": true,
+ "label": 'Spinning Globe...',
+ "visible": true
+ },
+ {
+ "id": 434,
+ "enabled": true,
+ "label": 'Rippling...',
+ "visible": true
+ },
+ {
+ "id": 435,
+ "enabled": true,
+ "label": 'Burn-In...',
+ "visible": true
+ },
+ {
+ "id": 436,
+ "enabled": true,
+ "label": 'Blend...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 437,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Web',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 438,
+ "enabled": true,
+ "label": 'Slice...',
+ "visible": true
+ },
+ {
+ "id": 439,
+ "enabled": true,
+ "label": 'Semi-Flatten',
+ "visible": true
+ },
+ {
+ "id": 440,
+ "enabled": true,
+ "label": 'Image Map...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 441,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Render',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 442,
+ "enabled": true,
+ "label": 'Spyrogimp...',
+ "visible": true
+ },
+ {
+ "id": 443,
+ "enabled": true,
+ "label": 'Sphere Designer...',
+ "visible": true
+ },
+ {
+ "id": 444,
+ "enabled": true,
+ "label": 'Line Nova...',
+ "visible": true
+ },
+ {
+ "id": 445,
+ "enabled": true,
+ "label": 'Lava...',
+ "visible": true
+ },
+ {
+ "id": 446,
+ "enabled": true,
+ "label": 'Gfig...',
+ "visible": true
+ },
+ {
+ "id": 447,
+ "enabled": true,
+ "label": 'Fractal Explorer...',
+ "visible": true
+ },
+ {
+ "id": 448,
+ "enabled": true,
+ "label": 'Circuit...',
+ "visible": true
+ },
+ {
+ "id": 449,
+ "type": 'separator'
+ },
+ {
+ "id": 450,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Pattern',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 451,
+ "enabled": true,
+ "label": 'Sinus...',
+ "visible": true
+ },
+ {
+ "id": 452,
+ "enabled": true,
+ "label": 'Qbist...',
+ "visible": true
+ },
+ {
+ "id": 453,
+ "enabled": true,
+ "label": 'Maze...',
+ "visible": true
+ },
+ {
+ "id": 454,
+ "enabled": true,
+ "label": 'Jigsaw...',
+ "visible": true
+ },
+ {
+ "id": 455,
+ "enabled": true,
+ "label": 'Grid...',
+ "visible": true
+ },
+ {
+ "id": 456,
+ "enabled": true,
+ "label": 'Diffraction Patterns...',
+ "visible": true
+ },
+ {
+ "id": 457,
+ "enabled": true,
+ "label": 'CML Explorer...',
+ "visible": true
+ },
+ {
+ "id": 458,
+ "enabled": true,
+ "label": 'Checkerboard...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 459,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Nature',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 460,
+ "enabled": true,
+ "label": 'IFS Fractal...',
+ "visible": true
+ },
+ {
+ "id": 461,
+ "enabled": true,
+ "label": 'Flame...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 462,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Clouds',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 463,
+ "enabled": true,
+ "label": 'Solid Noise...',
+ "visible": true
+ },
+ {
+ "id": 464,
+ "enabled": true,
+ "label": 'Plasma...',
+ "visible": true
+ },
+ {
+ "id": 465,
+ "enabled": true,
+ "label": 'Fog...',
+ "visible": true
+ },
+ {
+ "id": 466,
+ "enabled": true,
+ "label": 'Difference Clouds...',
+ "visible": true
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": 467,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Map',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 468,
+ "enabled": true,
+ "label": 'Warp...',
+ "visible": true
+ },
+ {
+ "id": 469,
+ "enabled": true,
+ "label": 'Tile...',
+ "visible": true
+ },
+ {
+ "id": 470,
+ "enabled": true,
+ "label": 'Small Tiles...',
+ "visible": true
+ },
+ {
+ "id": 471,
+ "enabled": true,
+ "label": 'Paper Tile...',
+ "visible": true
+ },
+ {
+ "id": 472,
+ "enabled": true,
+ "label": 'Map Object...',
+ "visible": true
+ },
+ {
+ "id": 473,
+ "enabled": true,
+ "label": 'Make Seamless',
+ "visible": true
+ },
+ {
+ "id": 474,
+ "enabled": true,
+ "label": 'Illusion...',
+ "visible": true
+ },
+ {
+ "id": 475,
+ "enabled": true,
+ "label": 'Fractal Trace...',
+ "visible": true
+ },
+ {
+ "id": 476,
+ "enabled": true,
+ "label": 'Displace...',
+ "visible": true
+ },
+ {
+ "id": 477,
+ "enabled": true,
+ "label": 'Bump Map...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 478,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Decor',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 479,
+ "enabled": false,
+ "label": 'Stencil Chrome...',
+ "visible": true
+ },
+ {
+ "id": 480,
+ "enabled": false,
+ "label": 'Stencil Carve...',
+ "visible": true
+ },
+ {
+ "id": 481,
+ "enabled": false,
+ "label": 'Slide...',
+ "visible": true
+ },
+ {
+ "id": 482,
+ "enabled": false,
+ "label": 'Round Corners...',
+ "visible": true
+ },
+ {
+ "id": 483,
+ "enabled": true,
+ "label": 'Old Photo...',
+ "visible": true
+ },
+ {
+ "id": 484,
+ "enabled": true,
+ "label": 'Fuzzy Border...',
+ "visible": true
+ },
+ {
+ "id": 485,
+ "enabled": true,
+ "label": 'Coffee Stain...',
+ "visible": true
+ },
+ {
+ "id": 486,
+ "enabled": true,
+ "label": 'Add Border...',
+ "visible": true
+ },
+ {
+ "id": 487,
+ "enabled": true,
+ "label": 'Add Bevel...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 488,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Artistic',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 489,
+ "enabled": true,
+ "label": 'Weave...',
+ "visible": true
+ },
+ {
+ "id": 490,
+ "enabled": true,
+ "label": 'Van Gogh (LIC)...',
+ "visible": true
+ },
+ {
+ "id": 491,
+ "enabled": true,
+ "label": 'Softglow...',
+ "visible": true
+ },
+ {
+ "id": 492,
+ "enabled": true,
+ "label": 'Predator...',
+ "visible": true
+ },
+ {
+ "id": 493,
+ "enabled": true,
+ "label": 'Photocopy...',
+ "visible": true
+ },
+ {
+ "id": 494,
+ "enabled": true,
+ "label": 'Oilify...',
+ "visible": true
+ },
+ {
+ "id": 495,
+ "enabled": true,
+ "label": 'GIMPressionist...',
+ "visible": true
+ },
+ {
+ "id": 496,
+ "enabled": true,
+ "label": 'Cubism...',
+ "visible": true
+ },
+ {
+ "id": 497,
+ "enabled": true,
+ "label": 'Clothify...',
+ "visible": true
+ },
+ {
+ "id": 498,
+ "enabled": true,
+ "label": 'Cartoon...',
+ "visible": true
+ },
+ {
+ "id": 499,
+ "enabled": true,
+ "label": 'Apply Canvas...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 500,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Combine',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 501,
+ "enabled": true,
+ "label": 'Filmstrip...',
+ "visible": true
+ },
+ {
+ "id": 502,
+ "enabled": true,
+ "label": 'Depth Merge...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 503,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Generic',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 504,
+ "enabled": true,
+ "label": 'Erode',
+ "visible": true
+ },
+ {
+ "id": 505,
+ "enabled": true,
+ "label": 'Dilate',
+ "visible": true
+ },
+ {
+ "id": 506,
+ "enabled": true,
+ "label": 'Convolution Matrix...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 507,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Edge-Detect',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 508,
+ "enabled": true,
+ "label": 'Sobel...',
+ "visible": true
+ },
+ {
+ "id": 509,
+ "enabled": true,
+ "label": 'Neon...',
+ "visible": true
+ },
+ {
+ "id": 510,
+ "enabled": true,
+ "label": 'Laplace',
+ "visible": true
+ },
+ {
+ "id": 511,
+ "enabled": true,
+ "label": 'Edge...',
+ "visible": true
+ },
+ {
+ "id": 512,
+ "enabled": true,
+ "label": 'Difference of Gaussians...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 513,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Noise',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 514,
+ "enabled": true,
+ "label": 'Spread...',
+ "visible": true
+ },
+ {
+ "id": 515,
+ "enabled": true,
+ "label": 'Slur...',
+ "visible": true
+ },
+ {
+ "id": 516,
+ "enabled": true,
+ "label": 'RGB Noise...',
+ "visible": true
+ },
+ {
+ "id": 517,
+ "enabled": true,
+ "label": 'Pick...',
+ "visible": true
+ },
+ {
+ "id": 518,
+ "enabled": true,
+ "label": 'Hurl...',
+ "visible": true
+ },
+ {
+ "id": 519,
+ "enabled": true,
+ "label": 'HSV Noise...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 520,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Light and Shadow',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 521,
+ "enabled": true,
+ "label": 'Glass Tile...',
+ "visible": true
+ },
+ {
+ "id": 522,
+ "enabled": true,
+ "label": 'Apply Lens...',
+ "visible": true
+ },
+ {
+ "id": 523,
+ "type": 'separator'
+ },
+ {
+ "id": 524,
+ "enabled": true,
+ "label": 'Xach-Effect...',
+ "visible": true
+ },
+ {
+ "id": 525,
+ "enabled": true,
+ "label": 'Perspective...',
+ "visible": true
+ },
+ {
+ "id": 526,
+ "enabled": true,
+ "label": 'Drop Shadow...',
+ "visible": true
+ },
+ {
+ "id": 527,
+ "type": 'separator'
+ },
+ {
+ "id": 528,
+ "enabled": true,
+ "label": 'Supernova...',
+ "visible": true
+ },
+ {
+ "id": 529,
+ "enabled": true,
+ "label": 'Sparkle...',
+ "visible": true
+ },
+ {
+ "id": 530,
+ "enabled": true,
+ "label": 'Lighting Effects...',
+ "visible": true
+ },
+ {
+ "id": 531,
+ "enabled": true,
+ "label": 'Lens Flare...',
+ "visible": true
+ },
+ {
+ "id": 532,
+ "enabled": true,
+ "label": 'Gradient Flare...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 533,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Distorts',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 534,
+ "enabled": true,
+ "label": 'Wind...',
+ "visible": true
+ },
+ {
+ "id": 535,
+ "enabled": true,
+ "label": 'Whirl and Pinch...',
+ "visible": true
+ },
+ {
+ "id": 536,
+ "enabled": true,
+ "label": 'Waves...',
+ "visible": true
+ },
+ {
+ "id": 537,
+ "enabled": true,
+ "label": 'Video...',
+ "visible": true
+ },
+ {
+ "id": 538,
+ "enabled": true,
+ "label": 'Value Propagate...',
+ "visible": true
+ },
+ {
+ "id": 539,
+ "enabled": true,
+ "label": 'Shift...',
+ "visible": true
+ },
+ {
+ "id": 540,
+ "enabled": true,
+ "label": 'Ripple...',
+ "visible": true
+ },
+ {
+ "id": 541,
+ "enabled": true,
+ "label": 'Polar Coordinates...',
+ "visible": true
+ },
+ {
+ "id": 542,
+ "enabled": true,
+ "label": 'Pagecurl...',
+ "visible": true
+ },
+ {
+ "id": 543,
+ "enabled": true,
+ "label": 'Newsprint...',
+ "visible": true
+ },
+ {
+ "id": 544,
+ "enabled": true,
+ "label": 'Mosaic...',
+ "visible": true
+ },
+ {
+ "id": 545,
+ "enabled": true,
+ "label": 'Lens Distortion...',
+ "visible": true
+ },
+ {
+ "id": 546,
+ "enabled": true,
+ "label": 'IWarp...',
+ "visible": true
+ },
+ {
+ "id": 547,
+ "enabled": true,
+ "label": 'Erase Every Other Row...',
+ "visible": true
+ },
+ {
+ "id": 548,
+ "enabled": true,
+ "label": 'Engrave...',
+ "visible": true
+ },
+ {
+ "id": 549,
+ "enabled": true,
+ "label": 'Emboss...',
+ "visible": true
+ },
+ {
+ "id": 550,
+ "enabled": true,
+ "label": 'Curve Bend...',
+ "visible": true
+ },
+ {
+ "id": 551,
+ "enabled": true,
+ "label": 'Blinds...',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 552,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Enhance',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 553,
+ "enabled": true,
+ "label": 'Unsharp Mask...',
+ "visible": true
+ },
+ {
+ "id": 554,
+ "enabled": true,
+ "label": 'Sharpen...',
+ "visible": true
+ },
+ {
+ "id": 555,
+ "enabled": true,
+ "label": 'Red Eye Removal...',
+ "visible": true
+ },
+ {
+ "id": 556,
+ "enabled": false,
+ "label": 'NL Filter...',
+ "visible": true
+ },
+ {
+ "id": 557,
+ "enabled": true,
+ "label": 'Destripe...',
+ "visible": true
+ },
+ {
+ "id": 558,
+ "enabled": true,
+ "label": 'Despeckle...',
+ "visible": true
+ },
+ {
+ "id": 559,
+ "enabled": true,
+ "label": 'Deinterlace...',
+ "visible": true
+ },
+ {
+ "id": 560,
+ "enabled": true,
+ "label": 'Antialias',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 561,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Blur',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 562,
+ "enabled": true,
+ "label": 'Tileable Blur...',
+ "visible": true
+ },
+ {
+ "id": 563,
+ "enabled": true,
+ "label": 'Selective Gaussian Blur...',
+ "visible": true
+ },
+ {
+ "id": 564,
+ "enabled": true,
+ "label": 'Pixelize...',
+ "visible": true
+ },
+ {
+ "id": 565,
+ "enabled": true,
+ "label": 'Motion Blur...',
+ "visible": true
+ },
+ {
+ "id": 566,
+ "enabled": true,
+ "label": 'Gaussian Blur...',
+ "visible": true
+ },
+ {
+ "id": 567,
+ "enabled": true,
+ "label": 'Blur',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 568,
+ "type": 'separator'
+ },
+ {
+ "id": 569,
+ "enabled": true,
+ "label": 'Reset all Filters',
+ "visible": true
+ },
+ {
+ "id": 570,
+ "children-display": 'submenu',
+ "enabled": false,
+ "label": 'Re-Show Last',
+ "shortcut": [['Control', 'Shift', 'f']],
+ "visible": true,
+ "submenu": [
+ {
+ "id": 571,
+ "enabled": false,
+ "label": 'Empty',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 572,
+ "enabled": false,
+ "label": 'Repeat Last',
+ "shortcut": [['Control', 'f']],
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 573,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Windows',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 574,
+ "enabled": true,
+ "label": 'Toolbox',
+ "shortcut": [['Control', 'b']],
+ "visible": true
+ },
+ {
+ "id": 575,
+ "type": 'separator'
+ },
+ {
+ "id": 576,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Dockable Dialogs',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 577,
+ "enabled": true,
+ "label": 'Error Console',
+ "visible": true
+ },
+ {
+ "id": 578,
+ "enabled": true,
+ "label": 'Tools',
+ "visible": true
+ },
+ {
+ "id": 579,
+ "enabled": true,
+ "label": 'Templates',
+ "visible": true
+ },
+ {
+ "id": 580,
+ "enabled": true,
+ "label": 'Document History',
+ "visible": true
+ },
+ {
+ "id": 581,
+ "enabled": true,
+ "label": 'Images',
+ "visible": true
+ },
+ {
+ "id": 582,
+ "type": 'separator'
+ },
+ {
+ "id": 583,
+ "enabled": true,
+ "label": 'Buffers',
+ "visible": true
+ },
+ {
+ "id": 584,
+ "enabled": true,
+ "label": 'Fonts',
+ "visible": true
+ },
+ {
+ "id": 585,
+ "enabled": true,
+ "label": 'Palettes',
+ "visible": true
+ },
+ {
+ "id": 586,
+ "enabled": true,
+ "label": 'Gradients',
+ "shortcut": [['Control', 'g']],
+ "visible": true
+ },
+ {
+ "id": 587,
+ "enabled": true,
+ "label": 'Patterns',
+ "shortcut": [['Control', 'Shift', 'p']],
+ "visible": true
+ },
+ {
+ "id": 588,
+ "enabled": true,
+ "label": 'Brushes',
+ "shortcut": [['Control', 'Shift', 'b']],
+ "visible": true
+ },
+ {
+ "id": 589,
+ "enabled": true,
+ "label": 'Colors',
+ "visible": true
+ },
+ {
+ "id": 590,
+ "type": 'separator'
+ },
+ {
+ "id": 591,
+ "enabled": true,
+ "label": 'Sample Points',
+ "visible": true
+ },
+ {
+ "id": 592,
+ "enabled": true,
+ "label": 'Pointer',
+ "visible": true
+ },
+ {
+ "id": 593,
+ "enabled": true,
+ "label": 'Undo History',
+ "visible": true
+ },
+ {
+ "id": 594,
+ "enabled": true,
+ "label": 'Navigation',
+ "visible": true
+ },
+ {
+ "id": 595,
+ "enabled": true,
+ "label": 'Selection Editor',
+ "visible": true
+ },
+ {
+ "id": 596,
+ "enabled": true,
+ "label": 'Histogram',
+ "visible": true
+ },
+ {
+ "id": 597,
+ "enabled": true,
+ "label": 'Colormap',
+ "visible": true
+ },
+ {
+ "id": 598,
+ "enabled": true,
+ "label": 'Paths',
+ "visible": true
+ },
+ {
+ "id": 599,
+ "enabled": true,
+ "label": 'Channels',
+ "visible": true
+ },
+ {
+ "id": 600,
+ "enabled": true,
+ "label": 'Layers',
+ "shortcut": [['Control', 'l']],
+ "visible": true
+ },
+ {
+ "id": 601,
+ "type": 'separator'
+ },
+ {
+ "id": 602,
+ "enabled": true,
+ "label": 'Device Status',
+ "visible": true
+ },
+ {
+ "id": 603,
+ "enabled": true,
+ "label": 'Tool Options',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 604,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Recently Closed Docks',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 605,
+ "enabled": false,
+ "label": 'Empty',
+ "visible": true
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": 606,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'Help',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 607,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'User Manual',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 608,
+ "enabled": true,
+ "label": 'Working with Digital Camera Photos',
+ "visible": true
+ },
+ {
+ "id": 609,
+ "enabled": true,
+ "label": 'Using Paths',
+ "visible": true
+ },
+ {
+ "id": 610,
+ "enabled": true,
+ "label": 'Preparing your Images for the Web',
+ "visible": true
+ },
+ {
+ "id": 611,
+ "enabled": true,
+ "label": 'How to Use Dialogs',
+ "visible": true
+ },
+ {
+ "id": 612,
+ "enabled": true,
+ "label": 'Drawing Simple Objects',
+ "visible": true
+ },
+ {
+ "id": 613,
+ "enabled": true,
+ "label": 'Create, Open and Save Files',
+ "visible": true
+ },
+ {
+ "id": 614,
+ "enabled": true,
+ "label": 'Basic Concepts',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 615,
+ "children-display": 'submenu',
+ "enabled": true,
+ "label": 'GIMP Online',
+ "visible": true,
+ "submenu": [
+ {
+ "id": 616,
+ "enabled": true,
+ "label": 'User Manual Web Site',
+ "visible": true
+ },
+ {
+ "id": 617,
+ "enabled": true,
+ "label": 'Plug-in Registry',
+ "visible": true
+ },
+ {
+ "id": 618,
+ "enabled": true,
+ "label": 'Main Web Site',
+ "visible": true
+ },
+ {
+ "id": 619,
+ "enabled": true,
+ "label": 'Developer Web Site',
+ "visible": true
+ }
+ ]
+ },
+ {
+ "id": 620,
+ "type": 'separator'
+ },
+ {
+ "id": 621,
+ "enabled": true,
+ "label": 'Procedure Browser',
+ "visible": true
+ },
+ {
+ "id": 622,
+ "enabled": true,
+ "label": 'Plug-In Browser',
+ "visible": true
+ },
+ {
+ "id": 623,
+ "type": 'separator'
+ },
+ {
+ "id": 624,
+ "enabled": true,
+ "label": 'About',
+ "visible": true
+ },
+ {
+ "id": 625,
+ "enabled": true,
+ "label": 'Tip of the Day',
+ "visible": true
+ },
+ {
+ "id": 626,
+ "enabled": true,
+ "label": 'Context Help',
+ "shortcut": [['Shift', 'F1']],
+ "visible": true
+ },
+ {
+ "id": 627,
+ "enabled": true,
+ "label": 'Help',
+ "shortcut": [['F1']],
+ "visible": true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/test-json-client.c b/tests/test-json-client.c
new file mode 100644
index 0000000..d4e782b
--- /dev/null
+++ b/tests/test-json-client.c
@@ -0,0 +1,79 @@
+/*
+Test to check the json-loader and dbusmenu-dumper
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+#include <gio/gio.h>
+
+GMainLoop * mainloop = NULL;
+
+gboolean
+timeout_func (gpointer user_data)
+{
+ g_warning("Timeout without getting name");
+ g_main_loop_quit(mainloop);
+ return FALSE;
+}
+
+void
+name_appeared (GDBusConnection * connection, const gchar * name, const gchar * owner, gpointer user_data)
+{
+ char ** argv = (char **)user_data;
+
+ g_usleep(500000);
+
+ g_debug("Initing");
+
+ gchar * command = g_strdup_printf("%s --dbus-name=org.dbusmenu.test --dbus-object=/org/test", argv[1]);
+ g_debug("Executing: %s", command);
+
+ gchar * output;
+ g_spawn_command_line_sync(command, &output, NULL, NULL, NULL);
+
+ GFile * ofile = g_file_new_for_commandline_arg(argv[2]);
+ if (ofile != NULL) {
+ g_file_replace_contents(ofile, output, g_utf8_strlen(output, -1), NULL, FALSE, 0, NULL, NULL, NULL);
+ }
+
+ g_main_loop_quit(mainloop);
+ return;
+}
+
+int
+main (int argc, char ** argv)
+{
+ g_type_init();
+ g_debug("Wait for friends");
+
+ g_bus_watch_name(G_BUS_TYPE_SESSION,
+ "org.dbusmenu.test",
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ name_appeared,
+ NULL,
+ argv,
+ NULL);
+
+ g_timeout_add_seconds(2, timeout_func, NULL);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ return 0;
+}
diff --git a/tests/test-json-server.c b/tests/test-json-server.c
new file mode 100644
index 0000000..083de60
--- /dev/null
+++ b/tests/test-json-server.c
@@ -0,0 +1,88 @@
+/*
+Test to check the json-loader and dbusmenu-dumper
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <libdbusmenu-glib/server.h>
+#include <libdbusmenu-glib/menuitem.h>
+
+#include "json-loader.h"
+
+static GMainLoop * mainloop = NULL;
+
+static gboolean
+timer_func (gpointer data)
+{
+ g_main_loop_quit(mainloop);
+ return FALSE;
+}
+
+static void
+on_bus (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ gchar ** argv = (gchar **)user_data;
+
+ DbusmenuServer * server = dbusmenu_server_new("/org/test");
+
+ DbusmenuMenuitem * root = dbusmenu_json_build_from_file(argv[1]);
+ if (root == NULL) {
+ g_warning("Unable to build root");
+ g_main_loop_quit(mainloop);
+ return;
+ }
+
+ dbusmenu_server_set_root(server, root);
+
+ g_timeout_add(10000, timer_func, NULL);
+
+ return;
+}
+
+static void
+name_lost (GDBusConnection * connection, const gchar * name, gpointer user_data)
+{
+ g_error("Unable to get name '%s' on DBus", name);
+ g_main_loop_quit(mainloop);
+ return;
+}
+
+int
+main (int argc, char ** argv)
+{
+ g_type_init();
+
+ g_bus_own_name(G_BUS_TYPE_SESSION,
+ "org.dbusmenu.test",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus,
+ NULL,
+ name_lost,
+ argv,
+ NULL);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ g_debug("Quiting");
+
+ return 0;
+}