GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-csv-gnumeric-popup.c
1 /* The following is code copied from Gnumeric 1.7.8 licensed under the
2  * GNU General Public License version 2 and/or version 3. It is from the file
3  * gnumeric/src/gui-util.c, and it has been modified slightly to work
4  * within GnuCash. */
5 
6 /* Miguel de Icaza is not sure specifically who from the Gnumeric
7  * community is the copyright owner of the code below, so, on his
8  * recommendation, here is the full list of Gnumeric authors.
9  *
10  * Miguel de Icaza, creator.
11  * Jody Goldberg, maintainer.
12  * Harald Ashburner, Options pricers
13  * Sean Atkinson, functions and X-Base importing.
14  * Michel Berkelaar, Simplex algorithm for Solver (LP Solve).
15  * Jean Brefort, Core charting engine.
16  * Grandma Chema Celorio, Tester and sheet copy.
17  * Frank Chiulli, OLE support.
18  * Kenneth Christiansen, i18n, misc stuff.
19  * Zbigniew Chyla, plugin system, i18n.
20  * J.H.M. Dassen (Ray), debian packaging.
21  * Jeroen Dirks, Simplex algorithm for Solver (LP Solve).
22  * Tom Dyas, plugin support.
23  * Gergo Erdi, Gnumeric hacker.
24  * John Gotts, rpm packaging.
25  * Andreas J. Guelzow, Gnumeric hacker.
26  * Jon K. Hellan, Gnumeric hacker.
27  * Ross Ihaka, special functions.
28  * Jukka-Pekka Iivonen, numerous functions and tools.
29  * Jakub Jelinek, Gnumeric hacker.
30  * Chris Lahey, number format engine.
31  * Adrian Likins, documentation, debugging.
32  * Takashi Matsuda, original text plugin.
33  * Michael Meeks, Excel and OLE2 importing.
34  * Lutz Muller, SheetObject improvements.
35  * Emmanuel Pacaud, Many plot types for charting engine.
36  * Federico M. Quintero, canvas support.
37  * Mark Probst, Guile support.
38  * Rasca, HTML, troff, LaTeX exporters.
39  * Vincent Renardias, original CSV support, French localization.
40  * Ariel Rios, Guile support.
41  * Uwe Steinmann, Paradox Importer.
42  * Arturo Tena, OLE support.
43  * Almer S. Tigelaar, Gnumeric hacker.
44  * Bruno Unna, Excel bits.
45  * Daniel Veillard, XML support.
46  * Vladimir Vuksan, financial functions.
47  * Morten Welinder, Gnumeric hacker and leak plugging demi-god.
48  */
49 
50 #include "gnc-csv-gnumeric-popup.h"
51 
52 #include <glib/gi18n.h>
53 
54 static void
55 popup_item_activate (GtkWidget *item, gpointer *user_data)
56 {
57  GnumericPopupMenuElement const *elem =
58  g_object_get_data (G_OBJECT (item), "descriptor");
59  GnumericPopupMenuHandler handler =
60  g_object_get_data (G_OBJECT (item), "handler");
61 
62  g_return_if_fail (elem != NULL);
63  g_return_if_fail (handler != NULL);
64 
65  if (handler (elem, user_data))
66  gtk_widget_destroy (gtk_widget_get_toplevel (item));
67 }
68 
69 static void
70 gnumeric_create_popup_menu_list (GSList *elements,
71  GnumericPopupMenuHandler handler,
72  gpointer user_data,
73  int display_filter,
74  int sensitive_filter,
75  GdkEventButton *event)
76 {
77  GtkWidget *menu, *item;
78  char const *trans;
79 
80  menu = gtk_menu_new ();
81 
82  for (; elements != NULL ; elements = elements->next)
83  {
84  GnumericPopupMenuElement const *element = elements->data;
85  char const * const name = element->name;
86  char const * const pix_name = element->pixmap;
87 
88  item = NULL;
89 
90  if (element->display_filter != 0 &&
91  !(element->display_filter & display_filter))
92  continue;
93 
94  if (name != NULL && *name != '\0')
95  {
96  trans = _(name);
97  item = gtk_image_menu_item_new_with_mnemonic (trans);
98  if (element->sensitive_filter != 0 &&
99  (element->sensitive_filter & sensitive_filter))
100  gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
101  if (pix_name != NULL)
102  {
103  GtkWidget *image = gtk_image_new_from_stock (pix_name,
104  GTK_ICON_SIZE_MENU);
105  gtk_widget_show (image);
106  gtk_image_menu_item_set_image (
107  GTK_IMAGE_MENU_ITEM (item),
108  image);
109  }
110  }
111  else
112  {
113  /* separator */
114  item = gtk_menu_item_new ();
115  gtk_widget_set_sensitive (item, FALSE);
116  }
117 
118  if (element->index != 0)
119  {
120  g_signal_connect (G_OBJECT (item),
121  "activate",
122  G_CALLBACK (&popup_item_activate), user_data);
123  g_object_set_data (
124  G_OBJECT (item), "descriptor", (gpointer)(element));
125  g_object_set_data (
126  G_OBJECT (item), "handler", (gpointer)handler);
127  }
128 
129  gtk_widget_show (item);
130  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
131  }
132 
133  gnumeric_popup_menu (GTK_MENU (menu), event);
134 }
135 
136 void
137 gnumeric_create_popup_menu (GnumericPopupMenuElement const *elements,
138  GnumericPopupMenuHandler handler,
139  gpointer user_data,
140  int display_filter, int sensitive_filter,
141  GdkEventButton *event)
142 {
143  int i;
144  GSList *tmp = NULL;
145 
146  for (i = 0; elements [i].name != NULL; i++)
147  tmp = g_slist_prepend (tmp, (gpointer)(elements + i));
148 
149  tmp = g_slist_reverse (tmp);
150  gnumeric_create_popup_menu_list (tmp, handler, user_data,
151  display_filter, sensitive_filter, event);
152  g_slist_free (tmp);
153 }
154 
155 static void
156 kill_popup_menu (GtkWidget *widget, GtkMenu *menu)
157 {
158  g_return_if_fail (menu != NULL);
159  g_return_if_fail (GTK_IS_MENU (menu));
160 
161  g_object_unref (G_OBJECT (menu));
162 }
163 
172 void
173 gnumeric_popup_menu (GtkMenu *menu, GdkEventButton *event)
174 {
175  g_return_if_fail (menu != NULL);
176  g_return_if_fail (GTK_IS_MENU (menu));
177 
178  g_object_ref_sink (menu);
179 
180  if (event)
181  gtk_menu_set_screen (menu,
182  gdk_drawable_get_screen (event->window));
183 
184  g_signal_connect (G_OBJECT (menu),
185  "hide",
186  G_CALLBACK (kill_popup_menu), menu);
187 
188  /* Do NOT pass the button used to create the menu.
189  * instead pass 0. Otherwise bringing up a menu with
190  * the right button will disable clicking on the menu with the left.
191  */
192  gtk_menu_popup (menu, NULL, NULL, NULL, NULL, 0,
193  (event != NULL) ? event->time
194  : gtk_get_current_event_time());
195 }