LCOV - code coverage report
Current view: top level - borrowed/goffice - go-optionmenu.c (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 0.0 % 153 0
Test Date: 2025-02-07 16:25:45 Functions: 0.0 % 19 0
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /*
       2                 :             :  * go-optionmenu.c
       3                 :             :  *
       4                 :             :  * Copyright (C) 2002 Andreas J. Guelzow <aguelzow@taliesin.ca>
       5                 :             :  * Copyright (C) 2006 Morten Welinder (terra@gnome.org)
       6                 :             :  *
       7                 :             :  * based extensively on:
       8                 :             :  *
       9                 :             :  * GTK - The GIMP Toolkit
      10                 :             :  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
      11                 :             :  *
      12                 :             :  * Modified by the GTK+ Team and others 1997-2000.  See the GTK AUTHORS
      13                 :             :  * file for a list of people on the GTK+ Team.  See the ChangeLog
      14                 :             :  * files for a list of changes.  These files are distributed with
      15                 :             :  * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
      16                 :             :  *
      17                 :             :  *
      18                 :             :  * This library is free software; you can redistribute it and/or
      19                 :             :  * modify it under the terms of the GNU Lesser General Public
      20                 :             :  * License as published by the Free Software Foundation; either
      21                 :             :  * version 2 of the License, or (at your option) any later version.
      22                 :             :  *
      23                 :             :  * This library is distributed in the hope that it will be useful,
      24                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      25                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      26                 :             :  * Lesser General Public License for more details.
      27                 :             :  *
      28                 :             :  * You should have received a copy of the GNU Lesser General Public
      29                 :             :  * License along with this library; if not, write to the Free Software
      30                 :             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
      31                 :             :  * USA.
      32                 :             :  */
      33                 :             : 
      34                 :             : #include <config.h>
      35                 :             : #include "go-optionmenu.h"
      36                 :             : 
      37                 :             : #include <gdk/gdkkeysyms.h>
      38                 :             : #include <glib/gi18n-lib.h>
      39                 :             : 
      40                 :             : enum
      41                 :             : {
      42                 :             :     CHANGED, LAST_SIGNAL
      43                 :             : };
      44                 :             : 
      45                 :             : enum
      46                 :             : {
      47                 :             :     PROP_0,
      48                 :             :     PROP_MENU
      49                 :             : };
      50                 :             : 
      51                 :             : static guint signals[LAST_SIGNAL] = { 0 };
      52                 :             : 
      53                 :             : struct _GOOptionMenu
      54                 :             : {
      55                 :             :     GtkButton button;
      56                 :             : 
      57                 :             :     GtkMenuShell *menu;
      58                 :             :     GtkMenuItem *selected;
      59                 :             :     GtkLabel *button_label;
      60                 :             : };
      61                 :             : 
      62                 :           0 : G_DEFINE_TYPE (GOOptionMenu, go_option_menu, GTK_TYPE_BUTTON)
      63                 :             : 
      64                 :             : GtkWidget*
      65                 :           0 : go_option_menu_new(void)
      66                 :             : {
      67                 :           0 :     return g_object_new(GO_TYPE_OPTION_MENU, NULL);
      68                 :             : }
      69                 :             : 
      70                 :           0 : static void go_option_menu_detacher(GtkWidget *widget, GtkMenu *menu)
      71                 :             : {
      72                 :             : #if 0
      73                 :             :     GOOptionMenu *option_menu = GO_OPTION_MENU (widget);
      74                 :             :     /* What?  */
      75                 :             : #endif
      76                 :           0 : }
      77                 :             : 
      78                 :           0 : static void go_option_menu_update_contents(GOOptionMenu *option_menu)
      79                 :             : {
      80                 :             :     const char *text;
      81                 :             :     GtkWidget *w;
      82                 :           0 :     g_return_if_fail(GO_IS_OPTION_MENU(option_menu));
      83                 :             : 
      84                 :           0 :     w = gtk_bin_get_child(GTK_BIN(option_menu->selected));
      85                 :           0 :     text = g_object_get_data(G_OBJECT(w), "option-menu-text");
      86                 :             : 
      87                 :           0 :     if (!text && GTK_IS_LABEL(w))
      88                 :           0 :         text = gtk_label_get_text(GTK_LABEL(w));
      89                 :             : 
      90                 :           0 :     if (!text)
      91                 :           0 :         text = "";
      92                 :             : 
      93                 :             : #if 0
      94                 :             :     g_print ("text = \"%s\"\n", text);
      95                 :             : #endif
      96                 :             : 
      97                 :           0 :     gtk_label_set_text(option_menu->button_label, text);
      98                 :             : }
      99                 :             : 
     100                 :           0 : static void go_option_menu_select_item(GOOptionMenu *option_menu,
     101                 :             :         GtkMenuItem *item)
     102                 :             : {
     103                 :           0 :     if (item == option_menu->selected)
     104                 :           0 :         return;
     105                 :             : 
     106                 :           0 :     if (GTK_IS_CHECK_MENU_ITEM(option_menu->selected))
     107                 :           0 :         gtk_check_menu_item_set_active(
     108                 :           0 :                 GTK_CHECK_MENU_ITEM(option_menu->selected), FALSE);
     109                 :             : 
     110                 :           0 :     option_menu->selected = item;
     111                 :             : 
     112                 :           0 :     if (GTK_IS_CHECK_MENU_ITEM(item))
     113                 :           0 :         gtk_check_menu_item_set_active(
     114                 :           0 :                 GTK_CHECK_MENU_ITEM(option_menu->selected), TRUE);
     115                 :             : 
     116                 :           0 :     go_option_menu_update_contents(option_menu);
     117                 :             : }
     118                 :             : 
     119                 :           0 : static gint go_option_menu_button_press(GtkWidget *widget,
     120                 :             :         GdkEventButton *event)
     121                 :             : {
     122                 :             :     GOOptionMenu *option_menu;
     123                 :             : 
     124                 :           0 :     g_return_val_if_fail(GO_IS_OPTION_MENU(widget), FALSE);
     125                 :           0 :     g_return_val_if_fail(event != NULL, FALSE);
     126                 :             : 
     127                 :           0 :     option_menu = GO_OPTION_MENU(widget);
     128                 :             : 
     129                 :           0 :     if (event->type == GDK_BUTTON_PRESS && event->button == 1)
     130                 :             :     {
     131                 :           0 :         gtk_menu_popup_at_widget (GTK_MENU(option_menu->menu),
     132                 :             :                                   widget,
     133                 :             :                                   GDK_GRAVITY_SOUTH_WEST,
     134                 :             :                                   GDK_GRAVITY_NORTH_WEST,
     135                 :             :                                   (GdkEvent *) event);
     136                 :           0 :         return TRUE;
     137                 :             :     }
     138                 :           0 :     return FALSE;
     139                 :             : }
     140                 :             : 
     141                 :           0 : static gint go_option_menu_key_press(GtkWidget *widget, GdkEventKey *event)
     142                 :             : {
     143                 :           0 :     GOOptionMenu *option_menu = GO_OPTION_MENU(widget);
     144                 :             : 
     145                 :           0 :     switch (event->keyval)
     146                 :             :     {
     147                 :           0 :     case GDK_KEY_KP_Space:
     148                 :             :     case GDK_KEY_space:
     149                 :           0 :         gtk_menu_popup_at_widget (GTK_MENU(option_menu->menu),
     150                 :             :                                   widget,
     151                 :             :                                   GDK_GRAVITY_SOUTH_WEST,
     152                 :             :                                   GDK_GRAVITY_NORTH_WEST,
     153                 :             :                                   (GdkEvent *) event);
     154                 :           0 :         return TRUE;
     155                 :             :     }
     156                 :             : 
     157                 :           0 :     return FALSE;
     158                 :             : }
     159                 :             : 
     160                 :           0 : static void cb_select(GtkMenuItem *item, GOOptionMenu *option_menu)
     161                 :             : {
     162                 :           0 :     go_option_menu_select_item(option_menu, item);
     163                 :           0 :     g_signal_emit(option_menu, signals[CHANGED], 0);
     164                 :           0 : }
     165                 :             : 
     166                 :           0 : static void handle_menu_signals(GOOptionMenu *option_menu, gboolean connect)
     167                 :             : {
     168                 :           0 :     GList *children = gtk_container_get_children(
     169                 :           0 :             GTK_CONTAINER(option_menu->menu));
     170                 :             : 
     171                 :           0 :     while (children)
     172                 :             :     {
     173                 :           0 :         GtkWidget *child = children->data;
     174                 :           0 :         children = g_list_remove(children, child);
     175                 :             : 
     176                 :           0 :         if (GTK_IS_MENU_ITEM(child))
     177                 :             :         {
     178                 :           0 :             GtkWidget *sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(child));
     179                 :             : 
     180                 :           0 :             if (sub)
     181                 :           0 :                 children = g_list_concat(children,
     182                 :           0 :                         gtk_container_get_children(GTK_CONTAINER(sub)));
     183                 :           0 :             else if (connect)
     184                 :           0 :                 g_signal_connect(child, "activate", G_CALLBACK(cb_select),
     185                 :             :                         option_menu);
     186                 :             : 
     187                 :             :             else
     188                 :           0 :                 g_signal_handlers_disconnect_by_func(child,
     189                 :             :                         G_CALLBACK(cb_select), option_menu);
     190                 :             : 
     191                 :             :         }
     192                 :             :     }
     193                 :             : 
     194                 :           0 :     g_list_free (children);
     195                 :           0 : }
     196                 :             : 
     197                 :           0 : void go_option_menu_set_menu(GOOptionMenu *option_menu, GtkWidget *menu)
     198                 :             : {
     199                 :             :     GtkMenuShell *shell;
     200                 :             : 
     201                 :           0 :     g_return_if_fail(GO_IS_OPTION_MENU(option_menu));
     202                 :           0 :     g_return_if_fail(GTK_IS_MENU_SHELL(menu));
     203                 :             : 
     204                 :           0 :     shell = (GtkMenuShell *) menu;
     205                 :           0 :     if (option_menu->menu == shell)
     206                 :           0 :         return;
     207                 :             : 
     208                 :           0 :     if (option_menu->menu)
     209                 :             :     {
     210                 :           0 :         gtk_menu_shell_cancel(option_menu->menu);
     211                 :             : 
     212                 :           0 :         handle_menu_signals(option_menu, FALSE);
     213                 :             : 
     214                 :           0 :         gtk_menu_detach(GTK_MENU(option_menu->menu));
     215                 :           0 :         g_object_unref(option_menu->menu);
     216                 :             :     }
     217                 :             : 
     218                 :           0 :     option_menu->menu = shell;
     219                 :             : 
     220                 :           0 :     if (shell)
     221                 :             :     {
     222                 :           0 :         g_object_ref(shell);
     223                 :             : 
     224                 :           0 :         gtk_menu_attach_to_widget(GTK_MENU(shell), GTK_WIDGET(option_menu),
     225                 :             :                 go_option_menu_detacher);
     226                 :             : 
     227                 :           0 :         handle_menu_signals(option_menu, TRUE);
     228                 :             : 
     229                 :           0 :         go_option_menu_select_item(option_menu,
     230                 :           0 :                 GTK_MENU_ITEM(gtk_menu_get_active(GTK_MENU(shell))));
     231                 :             :     }
     232                 :             : 
     233                 :           0 :     g_object_notify(G_OBJECT(option_menu), "menu");
     234                 :             : }
     235                 :             : 
     236                 :           0 : void go_option_menu_set_history(GOOptionMenu *option_menu, GSList *selection)
     237                 :             : {
     238                 :           0 :     g_return_if_fail(selection != NULL);
     239                 :           0 :     g_return_if_fail(GO_IS_OPTION_MENU(option_menu));
     240                 :             : 
     241                 :           0 :     if (option_menu->menu)
     242                 :             :     {
     243                 :           0 :         GtkMenuShell *menu = option_menu->menu;
     244                 :             : 
     245                 :             :         while (1)
     246                 :           0 :         {
     247                 :           0 :             int n = GPOINTER_TO_INT(selection->data);
     248                 :           0 :             GList *children = gtk_container_get_children (GTK_CONTAINER(menu));
     249                 :           0 :             GtkMenuItem *item = g_list_nth_data (children, n);
     250                 :           0 :             g_list_free (children);
     251                 :           0 :             selection = selection->next;
     252                 :           0 :             if (selection)
     253                 :           0 :                 menu = GTK_MENU_SHELL(gtk_menu_item_get_submenu(item));
     254                 :             :             else
     255                 :             :             {
     256                 :           0 :                 go_option_menu_select_item(option_menu, item);
     257                 :           0 :                 break;
     258                 :             :             }
     259                 :             :         }
     260                 :             :     }
     261                 :             : }
     262                 :             : 
     263                 :             : /**
     264                 :             :  * go_option_menu_get_history:
     265                 :             :  * @option_menu: a #GOOptionMenu
     266                 :             :  *
     267                 :             :  * Retrieves the currently selected menu item.
     268                 :             :  *
     269                 :             :  * Return value: the selected menu_item
     270                 :             :  **/
     271                 :             : 
     272                 :             : GtkWidget *
     273                 :           0 : go_option_menu_get_history(GOOptionMenu *option_menu)
     274                 :             : {
     275                 :           0 :     return GTK_WIDGET(option_menu->selected);
     276                 :             : }
     277                 :             : 
     278                 :           0 : static void go_option_menu_set_property(GObject *object, guint prop_id,
     279                 :             :         const GValue *value, GParamSpec *pspec)
     280                 :             : {
     281                 :           0 :     GOOptionMenu *option_menu = GO_OPTION_MENU(object);
     282                 :             : 
     283                 :           0 :     switch (prop_id)
     284                 :             :     {
     285                 :           0 :     case PROP_MENU:
     286                 :           0 :         go_option_menu_set_menu(option_menu, g_value_get_object(value));
     287                 :           0 :         break;
     288                 :             : 
     289                 :           0 :     default:
     290                 :           0 :         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
     291                 :           0 :         break;
     292                 :             :     }
     293                 :           0 : }
     294                 :             : 
     295                 :           0 : static void go_option_menu_get_property(GObject *object, guint prop_id,
     296                 :             :         GValue *value, GParamSpec *pspec)
     297                 :             : {
     298                 :           0 :     GOOptionMenu *option_menu = GO_OPTION_MENU(object);
     299                 :             : 
     300                 :           0 :     switch (prop_id)
     301                 :             :     {
     302                 :           0 :     case PROP_MENU:
     303                 :           0 :         g_value_set_object(value, option_menu->menu);
     304                 :           0 :         break;
     305                 :             : 
     306                 :           0 :     default:
     307                 :           0 :         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
     308                 :           0 :         break;
     309                 :             :     }
     310                 :           0 : }
     311                 :             : 
     312                 :           0 : static void go_option_menu_destroy(GtkWidget *widget)
     313                 :             : {
     314                 :             :     GOOptionMenu *option_menu;
     315                 :             : 
     316                 :           0 :     g_return_if_fail(GO_IS_OPTION_MENU(widget));
     317                 :             : 
     318                 :           0 :     option_menu = GO_OPTION_MENU(widget);
     319                 :             : 
     320                 :           0 :     if (option_menu->menu)
     321                 :             :     {
     322                 :           0 :         gtk_widget_destroy(GTK_WIDGET(option_menu->menu));
     323                 :           0 :         g_object_unref(option_menu->menu);
     324                 :           0 :         option_menu->menu = NULL;
     325                 :             :     }
     326                 :           0 :     option_menu->selected = NULL;
     327                 :             : 
     328                 :           0 :     GTK_WIDGET_CLASS(go_option_menu_parent_class)->destroy(widget);
     329                 :             : }
     330                 :             : 
     331                 :           0 : static void go_option_menu_class_init(GOOptionMenuClass *class)
     332                 :             : {
     333                 :           0 :     GObjectClass *gobject_class = (GObjectClass*) class;
     334                 :           0 :     GtkWidgetClass *widget_class = (GtkWidgetClass*) class;
     335                 :             : 
     336                 :           0 :     signals[CHANGED] = g_signal_new("changed", G_OBJECT_CLASS_TYPE(class),
     337                 :             :             G_SIGNAL_RUN_LAST, 0,
     338                 :             :             NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
     339                 :             : 
     340                 :           0 :     gobject_class->set_property = go_option_menu_set_property;
     341                 :           0 :     gobject_class->get_property = go_option_menu_get_property;
     342                 :           0 :     widget_class->destroy = go_option_menu_destroy;
     343                 :           0 :     widget_class->button_press_event = go_option_menu_button_press;
     344                 :           0 :     widget_class->key_press_event = go_option_menu_key_press;
     345                 :             : 
     346                 :           0 :     g_object_class_install_property(gobject_class, PROP_MENU,
     347                 :             :             g_param_spec_object("menu", _("Menu"), _("The menu of options"),
     348                 :             :                     GTK_TYPE_MENU, G_PARAM_READABLE | G_PARAM_WRITABLE));
     349                 :           0 : }
     350                 :             : 
     351                 :           0 : static void go_option_menu_init(GOOptionMenu *option_menu)
     352                 :             : {
     353                 :             :     GtkWidget *box;
     354                 :             :     GtkWidget *arrow, *sep;
     355                 :             : 
     356                 :           0 :     gtk_widget_set_can_focus(GTK_WIDGET(option_menu), TRUE);
     357                 :           0 :     gtk_widget_set_can_default(GTK_WIDGET(option_menu), FALSE);
     358                 :           0 :     gtk_widget_set_receives_default(GTK_WIDGET(option_menu), FALSE);
     359                 :             : 
     360                 :           0 :     box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
     361                 :           0 :     gtk_box_set_homogeneous (GTK_BOX (box), FALSE);
     362                 :             : 
     363                 :           0 :     option_menu->menu = NULL;
     364                 :           0 :     option_menu->selected = NULL;
     365                 :             : 
     366                 :           0 :     option_menu->button_label = GTK_LABEL(gtk_label_new(""));
     367                 :           0 :     gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(option_menu->button_label), FALSE, TRUE, 0);
     368                 :           0 :     arrow = gtk_image_new_from_icon_name ("pan-down-symbolic", GTK_ICON_SIZE_BUTTON);
     369                 :           0 :     gtk_widget_set_margin_start (GTK_WIDGET(arrow), 5);
     370                 :             : 
     371                 :           0 :     gtk_box_pack_end(GTK_BOX(box), arrow, FALSE, FALSE, 0);
     372                 :             : 
     373                 :           0 :     sep = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
     374                 :           0 :     gtk_box_pack_end(GTK_BOX(box), sep, FALSE, FALSE, 0);
     375                 :             : 
     376                 :           0 :     gtk_container_add(GTK_CONTAINER(option_menu), GTK_WIDGET(box));
     377                 :           0 : }
        

Generated by: LCOV version 2.0-1