1 | /* |
2 | * Copyright (c) 2014 Red Hat, Inc. |
3 | * |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2 of the License, or (at your option) any later version. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
16 | */ |
17 | |
18 | #include "config.h" |
19 | #include <glib/gi18n-lib.h> |
20 | |
21 | #include "menu.h" |
22 | |
23 | #include "gtktreestore.h" |
24 | #include "gtkwidgetprivate.h" |
25 | #include "gtklabel.h" |
26 | #include "gtkstack.h" |
27 | |
28 | |
29 | enum |
30 | { |
31 | COLUMN_TYPE, |
32 | COLUMN_LABEL, |
33 | COLUMN_ACTION, |
34 | COLUMN_TARGET, |
35 | COLUMN_ICON |
36 | }; |
37 | |
38 | struct |
39 | { |
40 | GtkTreeStore *; |
41 | }; |
42 | |
43 | G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorMenu, gtk_inspector_menu, GTK_TYPE_BOX) |
44 | |
45 | static void |
46 | (GtkInspectorMenu *sl) |
47 | { |
48 | sl->priv = gtk_inspector_menu_get_instance_private (self: sl); |
49 | gtk_widget_init_template (GTK_WIDGET (sl)); |
50 | } |
51 | |
52 | static void add_menu (GtkInspectorMenu *sl, |
53 | GtkStackPage *page, |
54 | GMenuModel *, |
55 | GtkTreeIter *parent); |
56 | |
57 | static void |
58 | add_item (GtkInspectorMenu *sl, |
59 | GtkStackPage *page, |
60 | GMenuModel *, |
61 | int idx, |
62 | GtkTreeIter *parent) |
63 | { |
64 | GtkTreeIter iter; |
65 | GVariant *value; |
66 | char *label = NULL; |
67 | char *action = NULL; |
68 | char *target = NULL; |
69 | char *icon = NULL; |
70 | GMenuModel *model; |
71 | |
72 | g_menu_model_get_item_attribute (model: menu, item_index: idx, G_MENU_ATTRIBUTE_LABEL, format_string: "s" , &label); |
73 | g_menu_model_get_item_attribute (model: menu, item_index: idx, G_MENU_ATTRIBUTE_ACTION, format_string: "s" , &action); |
74 | value = g_menu_model_get_item_attribute_value (model: menu, item_index: idx, G_MENU_ATTRIBUTE_TARGET, NULL); |
75 | if (value) |
76 | { |
77 | target = g_variant_print (value, FALSE); |
78 | g_variant_unref (value); |
79 | } |
80 | |
81 | gtk_tree_store_append (tree_store: sl->priv->model, iter: &iter, parent); |
82 | gtk_tree_store_set (tree_store: sl->priv->model, iter: &iter, |
83 | COLUMN_TYPE, "item" , |
84 | COLUMN_LABEL, label, |
85 | COLUMN_ACTION, action, |
86 | COLUMN_TARGET, target, |
87 | COLUMN_ICON, icon, |
88 | -1); |
89 | |
90 | model = g_menu_model_get_item_link (model: menu, item_index: idx, G_MENU_LINK_SECTION); |
91 | if (model) |
92 | { |
93 | if (label == NULL) |
94 | gtk_tree_store_set (tree_store: sl->priv->model, iter: &iter, |
95 | COLUMN_LABEL, _("Unnamed section" ), |
96 | -1); |
97 | add_menu (sl, page, menu: model, parent: &iter); |
98 | g_object_unref (object: model); |
99 | } |
100 | |
101 | model = g_menu_model_get_item_link (model: menu, item_index: idx, G_MENU_LINK_SUBMENU); |
102 | if (model) |
103 | { |
104 | add_menu (sl, page, menu: model, parent: &iter); |
105 | g_object_unref (object: model); |
106 | } |
107 | |
108 | g_free (mem: label); |
109 | g_free (mem: action); |
110 | g_free (mem: target); |
111 | g_free (mem: icon); |
112 | } |
113 | |
114 | static void |
115 | (GtkInspectorMenu *sl, |
116 | GtkStackPage *page, |
117 | GMenuModel *, |
118 | GtkTreeIter *parent) |
119 | { |
120 | int n_items; |
121 | int i; |
122 | |
123 | g_object_set (object: page, first_property_name: "visible" , TRUE, NULL); |
124 | |
125 | n_items = g_menu_model_get_n_items (model: menu); |
126 | for (i = 0; i < n_items; i++) |
127 | add_item (sl, page, menu, idx: i, parent); |
128 | } |
129 | |
130 | void |
131 | (GtkInspectorMenu *sl, |
132 | GObject *object) |
133 | { |
134 | GtkWidget *stack; |
135 | GtkStackPage *page; |
136 | |
137 | stack = gtk_widget_get_parent (GTK_WIDGET (sl)); |
138 | page = gtk_stack_get_page (GTK_STACK (stack), GTK_WIDGET (sl)); |
139 | |
140 | g_object_set (object: page, first_property_name: "visible" , FALSE, NULL); |
141 | gtk_tree_store_clear (tree_store: sl->priv->model); |
142 | |
143 | if (G_IS_MENU_MODEL (object)) |
144 | add_menu (sl, page, G_MENU_MODEL (object), NULL); |
145 | } |
146 | |
147 | static void |
148 | (GtkInspectorMenuClass *klass) |
149 | { |
150 | GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); |
151 | |
152 | gtk_widget_class_set_template_from_resource (widget_class, resource_name: "/org/gtk/libgtk/inspector/menu.ui" ); |
153 | gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorMenu, model); |
154 | } |
155 | |
156 | // vim: set et sw=2 ts=2: |
157 | |