nss: upgrade to release 3.73
[LibreOffice.git] / vcl / unx / gtk3 / gtk3gloactiongroup.cxx
blob1b64da0ffaf108343100a17be7f5d3f595c8ff16
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <unx/gtk/gtksalmenu.hxx>
12 #include <unx/gtk/gloactiongroup.h>
14 #include <sal/log.hxx>
17 * GLOAction
20 #define G_TYPE_LO_ACTION (g_lo_action_get_type ())
21 #define G_LO_ACTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
22 G_TYPE_LO_ACTION, GLOAction))
23 namespace {
25 struct GLOAction
27 GObject parent_instance;
29 gint item_id; // Menu item ID.
30 bool submenu; // TRUE if action is a submenu action.
31 bool enabled; // TRUE if action is enabled.
32 GVariantType* parameter_type; // A GVariantType with the action parameter type.
33 GVariantType* state_type; // A GVariantType with item state type
34 GVariant* state_hint; // A GVariant with state hints.
35 GVariant* state; // A GVariant with current item state
40 typedef GObjectClass GLOActionClass;
42 #ifdef __GNUC__
43 #pragma GCC diagnostic push
44 #pragma GCC diagnostic ignored "-Wunused-function"
45 #if defined __clang__
46 #if __has_warning("-Wdeprecated-volatile")
47 #pragma clang diagnostic ignored "-Wdeprecated-volatile"
48 #endif
49 #endif
50 #endif
51 G_DEFINE_TYPE (GLOAction, g_lo_action, G_TYPE_OBJECT);
52 #ifdef __GNUC__
53 #pragma GCC diagnostic pop
54 #endif
56 static GLOAction*
57 g_lo_action_new()
59 return G_LO_ACTION (g_object_new (G_TYPE_LO_ACTION, nullptr));
62 static void
63 g_lo_action_init (GLOAction *action)
65 action->item_id = -1;
66 action->submenu = false;
67 action->enabled = true;
68 action->parameter_type = nullptr;
69 action->state_type = nullptr;
70 action->state_hint = nullptr;
71 action->state = nullptr;
74 static void
75 g_lo_action_finalize (GObject *object)
77 GLOAction* action = G_LO_ACTION(object);
79 if (action->parameter_type)
80 g_variant_type_free (action->parameter_type);
82 if (action->state_type)
83 g_variant_type_free (action->state_type);
85 if (action->state_hint)
86 g_variant_unref (action->state_hint);
88 if (action->state)
89 g_variant_unref (action->state);
91 G_OBJECT_CLASS (g_lo_action_parent_class)->finalize (object);
94 static void
95 g_lo_action_class_init (GLOActionClass *klass)
97 GObjectClass *object_class = G_OBJECT_CLASS(klass);
99 object_class->finalize = g_lo_action_finalize;
103 * GLOActionGroup
106 struct GLOActionGroupPrivate
108 GHashTable *table; /* string -> GLOAction */
111 static void g_lo_action_group_iface_init (GActionGroupInterface *);
113 #ifdef __GNUC__
114 #pragma GCC diagnostic push
115 #pragma GCC diagnostic ignored "-Wunused-function"
116 #if defined __clang__
117 #if __has_warning("-Wdeprecated-volatile")
118 #pragma clang diagnostic ignored "-Wdeprecated-volatile"
119 #endif
120 #endif
121 #endif
122 G_DEFINE_TYPE_WITH_CODE (GLOActionGroup,
123 g_lo_action_group, G_TYPE_OBJECT,
124 G_ADD_PRIVATE(GLOActionGroup)
125 G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP,
126 g_lo_action_group_iface_init));
127 #ifdef __GNUC__
128 #pragma GCC diagnostic pop
129 #endif
131 static gchar **
132 g_lo_action_group_list_actions (GActionGroup *group)
134 GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group);
135 GHashTableIter iter;
136 gint n, i = 0;
137 gchar **keys;
138 gpointer key;
140 n = g_hash_table_size (loGroup->priv->table);
141 keys = g_new (gchar *, n + 1);
143 g_hash_table_iter_init (&iter, loGroup->priv->table);
144 while (g_hash_table_iter_next (&iter, &key, nullptr))
145 keys[i++] = g_strdup (static_cast<gchar*>(key));
146 g_assert_cmpint (i, ==, n);
147 keys[n] = nullptr;
149 return keys;
152 static gboolean
153 g_lo_action_group_query_action (GActionGroup *group,
154 const gchar *action_name,
155 gboolean *enabled,
156 const GVariantType **parameter_type,
157 const GVariantType **state_type,
158 GVariant **state_hint,
159 GVariant **state)
161 //SAL_INFO("vcl.unity", "g_lo_action_group_query_action on " << group);
162 GLOActionGroup *lo_group = G_LO_ACTION_GROUP (group);
163 GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name));
165 if (action == nullptr)
166 return FALSE;
168 if (enabled)
170 *enabled = action->enabled;
173 if (parameter_type)
174 *parameter_type = action->parameter_type;
176 if (state_type)
177 *state_type = action->state_type;
179 if (state_hint)
180 *state_hint = (action->state_hint) ? g_variant_ref (action->state_hint) : nullptr;
182 if (state)
183 *state = (action->state) ? g_variant_ref (action->state) : nullptr;
185 return true;
188 static void
189 g_lo_action_group_perform_submenu_action (GLOActionGroup *group,
190 const gchar *action_name,
191 GVariant *state)
193 bool bState = g_variant_get_boolean (state);
194 SAL_INFO("vcl.unity", "g_lo_action_group_perform_submenu_action on " << group << " to " << bState);
196 if (bState)
197 GtkSalMenu::Activate(action_name);
198 else
199 GtkSalMenu::Deactivate(action_name);
202 static void
203 g_lo_action_group_change_state (GActionGroup *group,
204 const gchar *action_name,
205 GVariant *value)
207 SAL_INFO("vcl.unity", "g_lo_action_group_change_state on " << group );
208 g_return_if_fail (value != nullptr);
210 g_variant_ref_sink (value);
212 if (action_name != nullptr)
214 GLOActionGroup* lo_group = G_LO_ACTION_GROUP (group);
215 GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name));
217 if (action != nullptr)
219 if (action->submenu)
220 g_lo_action_group_perform_submenu_action (lo_group, action_name, value);
221 else
223 bool is_new = false;
225 /* If action already exists but has no state, it should be removed and added again. */
226 if (action->state_type == nullptr)
228 g_action_group_action_removed (G_ACTION_GROUP (group), action_name);
229 action->state_type = g_variant_type_copy (g_variant_get_type(value));
230 is_new = true;
233 if (g_variant_is_of_type (value, action->state_type))
235 if (action->state)
236 g_variant_unref(action->state);
238 action->state = g_variant_ref (value);
240 if (is_new)
241 g_action_group_action_added (G_ACTION_GROUP (group), action_name);
242 else
243 g_action_group_action_state_changed (group, action_name, value);
249 g_variant_unref (value);
252 static void
253 g_lo_action_group_activate (GActionGroup *group,
254 const gchar *action_name,
255 GVariant *parameter)
257 if (parameter != nullptr)
258 g_action_group_change_action_state(group, action_name, parameter);
259 GtkSalMenu::DispatchCommand(action_name);
262 void
263 g_lo_action_group_insert (GLOActionGroup *group,
264 const gchar *action_name,
265 gint item_id,
266 gboolean submenu)
268 g_lo_action_group_insert_stateful (group, action_name, item_id, submenu, nullptr, nullptr, nullptr, nullptr);
271 void
272 g_lo_action_group_insert_stateful (GLOActionGroup *group,
273 const gchar *action_name,
274 gint item_id,
275 gboolean submenu,
276 const GVariantType *parameter_type,
277 const GVariantType *state_type,
278 GVariant *state_hint,
279 GVariant *state)
281 g_return_if_fail (G_IS_LO_ACTION_GROUP (group));
283 GLOAction* old_action = G_LO_ACTION (g_hash_table_lookup (group->priv->table, action_name));
285 if (old_action != nullptr && old_action->item_id == item_id)
286 return;
288 if (old_action != nullptr)
289 g_lo_action_group_remove (group, action_name);
291 GLOAction* action = g_lo_action_new();
293 g_hash_table_insert (group->priv->table, g_strdup (action_name), action);
295 action->item_id = item_id;
296 action->submenu = submenu;
298 if (parameter_type)
299 action->parameter_type = const_cast<GVariantType*>(parameter_type);
301 if (state_type)
302 action->state_type = const_cast<GVariantType*>(state_type);
304 if (state_hint)
305 action->state_hint = g_variant_ref_sink (state_hint);
307 if (state)
308 action->state = g_variant_ref_sink (state);
310 g_action_group_action_added (G_ACTION_GROUP (group), action_name);
313 static void
314 g_lo_action_group_finalize (GObject *object)
316 GLOActionGroup *lo_group = G_LO_ACTION_GROUP (object);
318 g_hash_table_unref (lo_group->priv->table);
320 G_OBJECT_CLASS (g_lo_action_group_parent_class)->finalize (object);
323 static void
324 g_lo_action_group_init (GLOActionGroup *group)
326 SAL_INFO("vcl.unity", "g_lo_action_group_init on " << group);
327 group->priv = static_cast<GLOActionGroupPrivate *>(g_lo_action_group_get_instance_private (group));
328 group->priv->table = g_hash_table_new_full (g_str_hash, g_str_equal,
329 g_free, g_object_unref);
332 static void
333 g_lo_action_group_class_init (GLOActionGroupClass *klass)
335 GObjectClass *object_class = G_OBJECT_CLASS (klass);
337 object_class->finalize = g_lo_action_group_finalize;
340 static void
341 g_lo_action_group_iface_init (GActionGroupInterface *iface)
343 iface->list_actions = g_lo_action_group_list_actions;
344 iface->query_action = g_lo_action_group_query_action;
345 iface->change_action_state = g_lo_action_group_change_state;
346 iface->activate_action = g_lo_action_group_activate;
349 GLOActionGroup *
350 g_lo_action_group_new()
352 GLOActionGroup* group = G_LO_ACTION_GROUP (g_object_new (G_TYPE_LO_ACTION_GROUP, nullptr));
353 return group;
356 void
357 g_lo_action_group_set_action_enabled (GLOActionGroup *group,
358 const gchar *action_name,
359 gboolean enabled)
361 SAL_INFO("vcl.unity", "g_lo_action_group_set_action_enabled on " << group);
362 g_return_if_fail (G_IS_LO_ACTION_GROUP (group));
363 g_return_if_fail (action_name != nullptr);
365 GLOAction* action = G_LO_ACTION (g_hash_table_lookup (group->priv->table, action_name));
367 if (action == nullptr)
368 return;
370 action->enabled = enabled;
372 g_action_group_action_enabled_changed (G_ACTION_GROUP (group), action_name, enabled);
375 void
376 g_lo_action_group_remove (GLOActionGroup *group,
377 const gchar *action_name)
379 SAL_INFO("vcl.unity", "g_lo_action_group_remove on " << group);
380 g_return_if_fail (G_IS_LO_ACTION_GROUP (group));
382 if (action_name != nullptr)
384 g_action_group_action_removed (G_ACTION_GROUP (group), action_name);
385 g_hash_table_remove (group->priv->table, action_name);
389 void
390 g_lo_action_group_clear (GLOActionGroup *group)
392 SAL_INFO("vcl.unity", "g_lo_action_group_clear on " << group);
393 g_return_if_fail (G_IS_LO_ACTION_GROUP (group));
395 GList* keys = g_hash_table_get_keys (group->priv->table);
397 for (GList* element = g_list_first (keys); element != nullptr; element = g_list_next (element))
399 g_lo_action_group_remove (group, static_cast<gchar*>(element->data));
402 g_list_free (keys);
405 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */