LCOV - code coverage report
Current view: top level - vcl/unx/gtk/window - gloactiongroup.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 28 170 16.5 %
Date: 2015-06-13 12:38:46 Functions: 9 25 36.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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             :  */
       9             : 
      10             : #include <unx/gtk/gtksalmenu.hxx>
      11             : 
      12             : #ifdef ENABLE_GMENU_INTEGRATION
      13             : 
      14             : #include <unx/gtk/gloactiongroup.h>
      15             : #include <unx/gtk/gtkinst.hxx>
      16             : #include <unx/gtk/gtkframe.hxx>
      17             : 
      18             : /*
      19             :  * GLOAction
      20             :  */
      21             : 
      22             : #define G_TYPE_LO_ACTION                                (g_lo_action_get_type ())
      23             : #define G_LO_ACTION(inst)                               (G_TYPE_CHECK_INSTANCE_CAST ((inst),                     \
      24             :                                                          G_TYPE_LO_ACTION, GLOAction))
      25             : 
      26             : struct _GLOAction
      27             : {
      28             :     GObject         parent_instance;
      29             : 
      30             :     gint            item_id;            // Menu item ID.
      31             :     gboolean        submenu;            // TRUE if action is a submenu action.
      32             :     gboolean        enabled;            // TRUE if action is enabled.
      33             :     GVariantType*   parameter_type;     // A GVariantType with the action parameter type.
      34             :     GVariantType*   state_type;         // A GVariantType with item state type
      35             :     GVariant*       state_hint;         // A GVariant with state hints.
      36             :     GVariant*       state;              // A GVariant with current item state
      37             : };
      38             : 
      39             : typedef GObjectClass GLOActionClass;
      40             : typedef struct _GLOAction GLOAction;
      41             : 
      42             : #ifdef __GNUC__
      43             : #pragma GCC diagnostic push
      44             : #pragma GCC diagnostic ignored "-Wunused-function"
      45             : #endif
      46           0 : G_DEFINE_TYPE (GLOAction, g_lo_action, G_TYPE_OBJECT);
      47             : #ifdef __GNUC__
      48             : #pragma GCC diagnostic pop
      49             : #endif
      50             : 
      51             : GLOAction*
      52           0 : g_lo_action_new()
      53             : {
      54           0 :     return G_LO_ACTION (g_object_new (G_TYPE_LO_ACTION, NULL));
      55             : }
      56             : 
      57             : static void
      58           0 : g_lo_action_init (GLOAction *action)
      59             : {
      60           0 :     action->item_id = -1;
      61           0 :     action->submenu = FALSE;
      62           0 :     action->enabled = TRUE;
      63           0 :     action->parameter_type = NULL;
      64           0 :     action->state_type = NULL;
      65           0 :     action->state_hint = NULL;
      66           0 :     action->state = NULL;
      67           0 : }
      68             : 
      69             : static void
      70           0 : g_lo_action_finalize (GObject *object)
      71             : {
      72           0 :     GLOAction* action = G_LO_ACTION(object);
      73             : 
      74           0 :     if (action->parameter_type)
      75           0 :         g_variant_type_free (action->parameter_type);
      76             : 
      77           0 :     if (action->state_type)
      78           0 :         g_variant_type_free (action->state_type);
      79             : 
      80           0 :     if (action->state_hint)
      81           0 :         g_variant_unref (action->state_hint);
      82             : 
      83           0 :     if (action->state)
      84           0 :         g_variant_unref (action->state);
      85             : 
      86           0 :     G_OBJECT_CLASS (g_lo_action_parent_class)->finalize (object);
      87           0 : }
      88             : 
      89             : static void
      90           0 : g_lo_action_class_init (GLOActionClass *klass)
      91             : {
      92           0 :     GObjectClass *object_class = G_OBJECT_CLASS(klass);
      93             : 
      94           0 :     object_class->finalize = g_lo_action_finalize;
      95           0 : }
      96             : 
      97             : /*
      98             :  * GLOActionGroup
      99             :  */
     100             : 
     101             : struct _GLOActionGroupPrivate
     102             : {
     103             :     GHashTable  *table;  /* string -> GLOAction */
     104             :     GtkSalFrame *frame;  /* Frame to which GActionGroup is associated. */
     105             : };
     106             : 
     107             : static void g_lo_action_group_iface_init (GActionGroupInterface *);
     108             : 
     109             : #ifdef __GNUC__
     110             : #pragma GCC diagnostic push
     111             : #pragma GCC diagnostic ignored "-Wunused-function"
     112             : #endif
     113          55 : G_DEFINE_TYPE_WITH_CODE (GLOActionGroup,
     114             :     g_lo_action_group, G_TYPE_OBJECT,
     115             :     G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP,
     116             :                            g_lo_action_group_iface_init));
     117             : #ifdef __GNUC__
     118             : #pragma GCC diagnostic pop
     119             : #endif
     120             : 
     121             : static gchar **
     122           0 : g_lo_action_group_list_actions (GActionGroup *group)
     123             : {
     124           0 :     GLOActionGroup *loGroup = G_LO_ACTION_GROUP (group);
     125             :     GHashTableIter iter;
     126           0 :     gint n, i = 0;
     127             :     gchar **keys;
     128             :     gpointer key;
     129             : 
     130           0 :     n = g_hash_table_size (loGroup->priv->table);
     131           0 :     keys = g_new (gchar *, n + 1);
     132             : 
     133           0 :     g_hash_table_iter_init (&iter, loGroup->priv->table);
     134           0 :     while (g_hash_table_iter_next (&iter, &key, NULL))
     135           0 :         keys[i++] = g_strdup (static_cast<gchar*>(key));
     136           0 :     g_assert_cmpint (i, ==, n);
     137           0 :     keys[n] = NULL;
     138             : 
     139           0 :     return keys;
     140             : }
     141             : 
     142             : static gboolean
     143           0 : g_lo_action_group_query_action (GActionGroup        *group,
     144             :                                 const gchar         *action_name,
     145             :                                 gboolean            *enabled,
     146             :                                 const GVariantType **parameter_type,
     147             :                                 const GVariantType **state_type,
     148             :                                 GVariant           **state_hint,
     149             :                                 GVariant           **state)
     150             : {
     151             :     //SAL_INFO("vcl.unity", "g_lo_action_group_query_action on " << group);
     152           0 :     GLOActionGroup *lo_group = G_LO_ACTION_GROUP (group);
     153             :     GLOAction* action;
     154             : 
     155           0 :     action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name));
     156             : 
     157           0 :     if (action == NULL)
     158           0 :         return FALSE;
     159             : 
     160           0 :     if (enabled)
     161             :     {
     162           0 :         GtkSalFrame* pFrame = lo_group->priv->frame;
     163           0 :         if (pFrame) {
     164           0 :             pFrame->EnsureDbusMenuSynced();
     165             :         }
     166           0 :         *enabled = action->enabled;
     167             :     }
     168             : 
     169           0 :     if (parameter_type)
     170           0 :         *parameter_type = action->parameter_type;
     171             : 
     172           0 :     if (state_type)
     173           0 :         *state_type = action->state_type;
     174             : 
     175           0 :     if (state_hint)
     176           0 :         *state_hint = (action->state_hint) ? g_variant_ref (action->state_hint) : NULL;
     177             : 
     178           0 :     if (state)
     179           0 :         *state = (action->state) ? g_variant_ref (action->state) : NULL;
     180             : 
     181           0 :     return TRUE;
     182             : }
     183             : 
     184             : static void
     185           0 : g_lo_action_group_perform_submenu_action (GLOActionGroup *group,
     186             :                                           const gchar    *action_name,
     187             :                                           GVariant       *state)
     188             : {
     189             : 
     190           0 :     GtkSalFrame* pFrame = group->priv->frame;
     191             :     SAL_INFO("vcl.unity", "g_lo_action_group_perform_submenu_action on " << group << " for frame " << pFrame);
     192             : 
     193           0 :     if (pFrame == NULL)
     194           0 :         return;
     195             : 
     196           0 :     GtkSalMenu* pSalMenu = static_cast<GtkSalMenu*> (pFrame->GetMenu());
     197             :     SAL_INFO("vcl.unity", "g_lo_action_group_perform_submenu_action on " << group << " for menu " << pSalMenu);
     198             : 
     199           0 :     if (pSalMenu != NULL) {
     200           0 :         gboolean bState = g_variant_get_boolean (state);
     201             :         SAL_INFO("vcl.unity", "g_lo_action_group_perform_submenu_action on " << group << " to " << bState);
     202             : 
     203           0 :         if (bState)
     204           0 :             pSalMenu->Activate();
     205             :         else
     206           0 :             pSalMenu->Deactivate (action_name);
     207             :     }
     208             : }
     209             : 
     210             : static void
     211           0 : g_lo_action_group_change_state (GActionGroup *group,
     212             :                                 const gchar  *action_name,
     213             :                                 GVariant     *value)
     214             : {
     215             :     SAL_INFO("vcl.unity", "g_lo_action_group_change_state on " << group );
     216           0 :     g_return_if_fail (value != NULL);
     217             : 
     218           0 :     g_variant_ref_sink (value);
     219             : 
     220           0 :     if (action_name != NULL)
     221             :     {
     222           0 :         GLOActionGroup* lo_group = G_LO_ACTION_GROUP (group);
     223           0 :         GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name));
     224             : 
     225           0 :         if (action != NULL)
     226             :         {
     227           0 :             if (action->submenu)
     228           0 :                 g_lo_action_group_perform_submenu_action (lo_group, action_name, value);
     229             :             else
     230             :             {
     231           0 :                 gboolean is_new = FALSE;
     232             : 
     233             :                 /* If action already exists but has no state, it should be removed and added again. */
     234           0 :                 if (action->state_type == NULL)
     235             :                 {
     236           0 :                     g_action_group_action_removed (G_ACTION_GROUP (group), action_name);
     237           0 :                     action->state_type = g_variant_type_copy (g_variant_get_type(value));
     238           0 :                     is_new = TRUE;
     239             :                 }
     240             : 
     241           0 :                 if (g_variant_is_of_type (value, action->state_type))
     242             :                 {
     243           0 :                     if (action->state)
     244           0 :                         g_variant_unref(action->state);
     245             : 
     246           0 :                     action->state = g_variant_ref (value);
     247             : 
     248           0 :                     if (is_new)
     249           0 :                         g_action_group_action_added (G_ACTION_GROUP (group), action_name);
     250             :                     else
     251           0 :                         g_action_group_action_state_changed (group, action_name, value);
     252             :                 }
     253             :             }
     254             :         }
     255             :     }
     256             : 
     257           0 :     g_variant_unref (value);
     258             : }
     259             : 
     260             : static void
     261           0 : g_lo_action_group_activate (GActionGroup *group,
     262             :                             const gchar  *action_name,
     263             :                             GVariant     *parameter)
     264             : {
     265           0 :     GLOActionGroup *lo_group = G_LO_ACTION_GROUP (group);
     266           0 :     GtkSalFrame *pFrame = lo_group->priv->frame;
     267             :     SAL_INFO("vcl.unity", "g_lo_action_group_activate on group " << group << " for frame " << pFrame << " with parameter " << parameter);
     268             : 
     269           0 :     if ( parameter != NULL )
     270           0 :         g_action_group_change_action_state( group, action_name, parameter );
     271             : 
     272           0 :     if ( pFrame != NULL )
     273             :     {
     274           0 :         GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( pFrame->GetMenu() );
     275             :         SAL_INFO("vcl.unity", "g_lo_action_group_activate for menu " << pSalMenu);
     276             : 
     277           0 :         if ( pSalMenu != NULL )
     278             :         {
     279           0 :             GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name));
     280             :             SAL_INFO("vcl.unity", "g_lo_action_group_activate dispatching action " << action << " named " << action_name << " on menu " << pSalMenu);
     281           0 :             pSalMenu->DispatchCommand( action->item_id, action_name );
     282             :         }
     283             :     }
     284           0 : }
     285             : 
     286             : void
     287           0 : g_lo_action_group_insert (GLOActionGroup *group,
     288             :                           const gchar    *action_name,
     289             :                           gint            item_id,
     290             :                           gboolean        submenu)
     291             : {
     292           0 :     g_lo_action_group_insert_stateful (group, action_name, item_id, submenu, NULL, NULL, NULL, NULL);
     293           0 : }
     294             : 
     295             : void
     296           0 : g_lo_action_group_insert_stateful (GLOActionGroup     *group,
     297             :                                    const gchar        *action_name,
     298             :                                    gint                item_id,
     299             :                                    gboolean            submenu,
     300             :                                    const GVariantType *parameter_type,
     301             :                                    const GVariantType *state_type,
     302             :                                    GVariant           *state_hint,
     303             :                                    GVariant           *state)
     304             : {
     305           0 :     g_return_if_fail (G_IS_LO_ACTION_GROUP (group));
     306             : 
     307           0 :     GLOAction* old_action = G_LO_ACTION (g_hash_table_lookup (group->priv->table, action_name));
     308             : 
     309           0 :     if (old_action == NULL || old_action->item_id != item_id)
     310             :     {
     311           0 :         if (old_action != NULL)
     312           0 :             g_lo_action_group_remove (group, action_name);
     313             : //            g_action_group_action_removed (G_ACTION_GROUP (group), action_name);
     314             : 
     315           0 :         GLOAction* action = g_lo_action_new();
     316             : 
     317           0 :         g_hash_table_insert (group->priv->table, g_strdup (action_name), action);
     318             : 
     319           0 :         action->item_id = item_id;
     320           0 :         action->submenu = submenu;
     321             : 
     322           0 :         if (parameter_type)
     323           0 :             action->parameter_type = const_cast<GVariantType*>(parameter_type);
     324             : 
     325           0 :         if (state_type)
     326           0 :             action->state_type = const_cast<GVariantType*>(state_type);
     327             : 
     328           0 :         if (state_hint)
     329           0 :             action->state_hint = g_variant_ref_sink (state_hint);
     330             : 
     331           0 :         if (state)
     332           0 :             action->state = g_variant_ref_sink (state);
     333             : 
     334           0 :         g_action_group_action_added (G_ACTION_GROUP (group), action_name);
     335             :     }
     336             : }
     337             : 
     338             : static void
     339           0 : g_lo_action_group_finalize (GObject *object)
     340             : {
     341           0 :     GLOActionGroup *lo_group = G_LO_ACTION_GROUP (object);
     342             : 
     343           0 :     g_hash_table_unref (lo_group->priv->table);
     344             : 
     345           0 :     G_OBJECT_CLASS (g_lo_action_group_parent_class)->finalize (object);
     346           0 : }
     347             : 
     348             : static void
     349          16 : g_lo_action_group_init (GLOActionGroup *group)
     350             : {
     351             :     SAL_INFO("vcl.unity", "g_lo_action_group_init on " << group);
     352          16 :     group->priv = G_TYPE_INSTANCE_GET_PRIVATE (group,
     353             :                                                  G_TYPE_LO_ACTION_GROUP,
     354          32 :                                                  GLOActionGroupPrivate);
     355             :     group->priv->table = g_hash_table_new_full (g_str_hash, g_str_equal,
     356          16 :                                                   g_free, g_object_unref);
     357          16 :     group->priv->frame = NULL;
     358          16 : }
     359             : 
     360             : static void
     361           3 : g_lo_action_group_class_init (GLOActionGroupClass *klass)
     362             : {
     363           3 :     GObjectClass *object_class = G_OBJECT_CLASS (klass);
     364             : 
     365           3 :     object_class->finalize = g_lo_action_group_finalize;
     366             : 
     367           3 :     g_type_class_add_private (klass, sizeof (GLOActionGroupPrivate));
     368           3 : }
     369             : 
     370             : static void
     371           3 : g_lo_action_group_iface_init (GActionGroupInterface *iface)
     372             : {
     373           3 :     iface->list_actions = g_lo_action_group_list_actions;
     374           3 :     iface->query_action = g_lo_action_group_query_action;
     375           3 :     iface->change_action_state = g_lo_action_group_change_state;
     376           3 :     iface->activate_action = g_lo_action_group_activate;
     377           3 : }
     378             : 
     379             : GLOActionGroup *
     380          16 : g_lo_action_group_new (gpointer frame)
     381             : {
     382          16 :     GLOActionGroup* group = G_LO_ACTION_GROUP (g_object_new (G_TYPE_LO_ACTION_GROUP, NULL));
     383          16 :     group->priv->frame = static_cast< GtkSalFrame* > (frame);
     384             : 
     385          16 :     return group;
     386             : }
     387             : 
     388             : void
     389           0 : g_lo_action_group_set_action_enabled (GLOActionGroup *group,
     390             :                                       const gchar    *action_name,
     391             :                                       gboolean        enabled)
     392             : {
     393             :     SAL_INFO("vcl.unity", "g_lo_action_group_set_action_enabled on " << group);
     394           0 :     g_return_if_fail (G_IS_LO_ACTION_GROUP (group));
     395           0 :     g_return_if_fail (action_name != NULL);
     396             : 
     397           0 :     GLOAction* action = G_LO_ACTION (g_hash_table_lookup (group->priv->table, action_name));
     398             : 
     399           0 :     if (action == NULL)
     400           0 :         return;
     401             : 
     402           0 :     action->enabled = enabled;
     403             : 
     404           0 :     g_action_group_action_enabled_changed (G_ACTION_GROUP (group), action_name, enabled);
     405             : }
     406             : 
     407             : void
     408           0 : g_lo_action_group_remove (GLOActionGroup *group,
     409             :                           const gchar    *action_name)
     410             : {
     411             :     SAL_INFO("vcl.unity", "g_lo_action_group_remove on " << group);
     412           0 :     g_return_if_fail (G_IS_LO_ACTION_GROUP (group));
     413             : 
     414           0 :     if (action_name != NULL)
     415             :     {
     416           0 :         g_action_group_action_removed (G_ACTION_GROUP (group), action_name);
     417           0 :         g_hash_table_remove (group->priv->table, action_name);
     418             :     }
     419             : }
     420             : 
     421             : void
     422           2 : g_lo_action_group_clear (GLOActionGroup  *group)
     423             : {
     424             :     SAL_INFO("vcl.unity", "g_lo_action_group_clear on " << group);
     425           4 :     g_return_if_fail (G_IS_LO_ACTION_GROUP (group));
     426             : 
     427           2 :     GList* keys = g_hash_table_get_keys (group->priv->table);
     428             : 
     429           2 :     for (GList* element = g_list_first (keys); element != NULL; element = g_list_next (element))
     430             :     {
     431           0 :         g_lo_action_group_remove (group, static_cast<gchar*>(element->data));
     432             :     }
     433             : 
     434           2 :     g_list_free (keys);
     435           9 : }
     436             : 
     437             : #endif
     438             : 
     439             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11