GnuCash  5.6-150-g038405b370+
gnc-csv-gnumeric-popup.c
1 /********************************************************************\
2  * The following is code copied from Gnumeric 1.7.8 src/gui-util.c, *
3  * and it has been modified slightly to work within GnuCash. *
4  * This program is free software; you can redistribute it and/or *
5  * modify it under the terms of the GNU General Public License as *
6  * published by the Free Software Foundation; either version 2 of *
7  * the License, or (at your option) any later version. *
8  * *
9  * This program 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 *
12  * GNU General Public License for more details. *
13  * *
14  * You should have received a copy of the GNU General Public License*
15  * along with this program; if not, contact: *
16  * *
17  * Free Software Foundation Voice: +1-617-542-5942 *
18  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
19  * Boston, MA 02110-1301, USA gnu@gnu.org *
20  * *
21 \********************************************************************/
22 
23 
24 /* Miguel de Icaza is not sure specifically who from the Gnumeric
25  * community is the copyright owner of the code below, so, on his
26  * recommendation, here is the full list of Gnumeric authors.
27  *
28  * Miguel de Icaza, creator.
29  * Jody Goldberg, maintainer.
30  * Harald Ashburner, Options pricers
31  * Sean Atkinson, functions and X-Base importing.
32  * Michel Berkelaar, Simplex algorithm for Solver (LP Solve).
33  * Jean Brefort, Core charting engine.
34  * Grandma Chema Celorio, Tester and sheet copy.
35  * Frank Chiulli, OLE support.
36  * Kenneth Christiansen, i18n, misc stuff.
37  * Zbigniew Chyla, plugin system, i18n.
38  * J.H.M. Dassen (Ray), debian packaging.
39  * Jeroen Dirks, Simplex algorithm for Solver (LP Solve).
40  * Tom Dyas, plugin support.
41  * Gergo Erdi, Gnumeric hacker.
42  * John Gotts, rpm packaging.
43  * Andreas J. Guelzow, Gnumeric hacker.
44  * Jon K. Hellan, Gnumeric hacker.
45  * Ross Ihaka, special functions.
46  * Jukka-Pekka Iivonen, numerous functions and tools.
47  * Jakub Jelinek, Gnumeric hacker.
48  * Chris Lahey, number format engine.
49  * Adrian Likins, documentation, debugging.
50  * Takashi Matsuda, original text plugin.
51  * Michael Meeks, Excel and OLE2 importing.
52  * Lutz Muller, SheetObject improvements.
53  * Emmanuel Pacaud, Many plot types for charting engine.
54  * Federico M. Quintero, canvas support.
55  * Mark Probst, Guile support.
56  * Rasca, HTML, troff, LaTeX exporters.
57  * Vincent Renardias, original CSV support, French localization.
58  * Ariel Rios, Guile support.
59  * Uwe Steinmann, Paradox Importer.
60  * Arturo Tena, OLE support.
61  * Almer S. Tigelaar, Gnumeric hacker.
62  * Bruno Unna, Excel bits.
63  * Daniel Veillard, XML support.
64  * Vladimir Vuksan, financial functions.
65  * Morten Welinder, Gnumeric hacker and leak plugging demi-god.
66  */
67 
68 #include "gnc-csv-gnumeric-popup.h"
69 
70 #include <glib/gi18n.h>
71 
72 static void
73 popup_item_activate (GtkWidget *item, gpointer *user_data)
74 {
75  GnumericPopupMenuElement const *elem =
76  g_object_get_data (G_OBJECT (item), "descriptor");
77  GnumericPopupMenuHandler handler =
78  g_object_get_data (G_OBJECT (item), "handler");
79 
80  g_return_if_fail (elem != NULL);
81  g_return_if_fail (handler != NULL);
82 
83  if (handler (elem, user_data))
84  gtk_widget_destroy (gtk_widget_get_toplevel (item));
85 }
86 
87 static void
88 gnumeric_create_popup_menu_list (GSList *elements,
89  GnumericPopupMenuHandler handler,
90  gpointer user_data,
91  int display_filter,
92  int sensitive_filter,
93  GdkEventButton *event)
94 {
95  GtkWidget *menu = gtk_menu_new ();
96  GtkWidget *item;
97 
98  for (; elements != NULL ; elements = elements->next)
99  {
100  GnumericPopupMenuElement const *element = elements->data;
101  char const * const name = element->name;
102  char const * const pix_name = element->pixmap;
103 
104  if (element->display_filter != 0 &&
105  !(element->display_filter & display_filter))
106  continue;
107 
108  if (name != NULL && *name != '\0')
109  {
110  GtkWidget *label = gtk_label_new_with_mnemonic (name);
111  GtkWidget *box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
112 
113  item = gtk_menu_item_new();
114  gtk_box_set_homogeneous (GTK_BOX (box), FALSE);
115  gtk_widget_set_hexpand (GTK_WIDGET(box), FALSE);
116  gtk_widget_set_halign (GTK_WIDGET(box), GTK_ALIGN_START);
117 
118  if (pix_name != NULL)
119  {
120  GtkWidget *image = gtk_image_new_from_icon_name (pix_name,
121  GTK_ICON_SIZE_MENU);
122 
123  gtk_container_add (GTK_CONTAINER (box), image);
124  gtk_widget_show (image);
125  }
126  gtk_box_pack_end (GTK_BOX (box), label, TRUE, TRUE, 0);
127  gtk_container_add (GTK_CONTAINER (item), box);
128 
129  if (element->sensitive_filter != 0 &&
130  (element->sensitive_filter & sensitive_filter))
131  gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
132  }
133  else
134  {
135  /* separator */
136  item = gtk_separator_menu_item_new ();
137  }
138  gtk_widget_show_all (item);
139 
140  if (element->index != 0)
141  {
142  g_signal_connect (G_OBJECT (item),
143  "activate",
144  G_CALLBACK (&popup_item_activate), user_data);
145  g_object_set_data (
146  G_OBJECT (item), "descriptor", (gpointer)(element));
147  g_object_set_data (
148  G_OBJECT (item), "handler", (gpointer)handler);
149  }
150 
151  gtk_widget_show (item);
152  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
153  }
154 
155  gnumeric_popup_menu (GTK_MENU (menu), event);
156 }
157 
158 void
159 gnumeric_create_popup_menu (GnumericPopupMenuElement const *elements,
160  GnumericPopupMenuHandler handler,
161  gpointer user_data,
162  int display_filter, int sensitive_filter,
163  GdkEventButton *event)
164 {
165  int i;
166  GSList *tmp = NULL;
167 
168  for (i = 0; elements [i].name != NULL; i++)
169  tmp = g_slist_prepend (tmp, (gpointer)(elements + i));
170 
171  tmp = g_slist_reverse (tmp);
172  gnumeric_create_popup_menu_list (tmp, handler, user_data,
173  display_filter, sensitive_filter, event);
174  g_slist_free (tmp);
175 }
176 
177 static void
178 kill_popup_menu (GtkWidget *widget, GtkMenu *menu)
179 {
180  g_return_if_fail (menu != NULL);
181  g_return_if_fail (GTK_IS_MENU (menu));
182 
183  g_object_unref (G_OBJECT (menu));
184 }
185 
194 void
195 gnumeric_popup_menu (GtkMenu *menu, GdkEventButton *event)
196 {
197  g_return_if_fail (menu != NULL);
198  g_return_if_fail (GTK_IS_MENU (menu));
199 
200  g_object_ref_sink (menu);
201 
202  if (event)
203  gtk_menu_set_screen (menu,
204  gdk_window_get_screen (event->window));
205 
206  g_signal_connect (G_OBJECT (menu),
207  "hide",
208  G_CALLBACK (kill_popup_menu), menu);
209 
210  /* Do NOT pass the button used to create the menu.
211  * instead pass 0. Otherwise bringing up a menu with
212  * the right button will disable clicking on the menu with the left.
213  */
214  gtk_menu_popup_at_pointer (GTK_MENU(menu), (GdkEvent *) event);
215 }