GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-general-select.c
1 /*
2  * gnc-general-select.c -- General Selection Widget
3  *
4  * Copyright (C) 2001 Free Software Foundation
5  * All rights reserved.
6  *
7  * Derek Atkins <[email protected]>
8  *
9  * Gnucash is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public License
11  * as published by the Free Software Foundation; either version 2 of the
12  * License, or (at your option) any later version.
13  *
14  * Gnucash is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, contact:
21  *
22  * Free Software Foundation Voice: +1-617-542-5942
23  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
24  * Boston, MA 02110-1301, USA [email protected]
25  *
26  */
27 /*
28  @NOTATION@
29  */
30 
31 #include "config.h"
32 
33 #include <gtk/gtk.h>
34 #include <glib/gi18n.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <stdio.h>
38 
39 #include "gnc-general-select.h"
40 
41 /* Signal codes */
42 enum
43 {
44  SELECTION_CHANGED,
45  LAST_SIGNAL
46 };
47 
48 
49 static void gnc_general_select_init (GNCGeneralSelect *gsl);
50 static void gnc_general_select_class_init (GNCGeneralSelectClass *klass);
51 static void gnc_general_select_dispose (GObject *object);
52 static void gnc_general_select_finalize (GObject *object);
53 
54 static GtkHBoxClass *parent_class;
55 static guint general_select_signals[LAST_SIGNAL];
56 
57 
63 GType
64 gnc_general_select_get_type (void)
65 {
66  static GType general_select_type = 0;
67 
68  if (general_select_type == 0)
69  {
70  static const GTypeInfo general_select_info =
71  {
72  sizeof (GNCGeneralSelectClass),
73  NULL,
74  NULL,
75  (GClassInitFunc) gnc_general_select_class_init,
76  NULL,
77  NULL,
78  sizeof (GNCGeneralSelect),
79  0,
80  (GInstanceInitFunc) gnc_general_select_init,
81  NULL,
82  };
83 
84  general_select_type = g_type_register_static(GTK_TYPE_HBOX,
85  "GNCGeneralSelect",
86  &general_select_info, 0);
87  }
88 
89  return general_select_type;
90 }
91 
92 static void
93 gnc_general_select_forall (GtkContainer *container, gboolean include_internals,
94  GtkCallback callback, gpointer callback_data)
95 {
96  g_return_if_fail (container != NULL);
97  g_return_if_fail (GNC_IS_GENERAL_SELECT (container));
98  g_return_if_fail (callback != NULL);
99 
100  /* Let GtkBox handle things only if the internal widgets need
101  * to be poked. */
102  if (!include_internals)
103  return;
104 
105  if (!GTK_CONTAINER_CLASS (parent_class)->forall)
106  return;
107 
108  GTK_CONTAINER_CLASS (parent_class)->forall (container,
109  include_internals,
110  callback,
111  callback_data);
112 }
113 
114 static void
115 gnc_general_select_class_init (GNCGeneralSelectClass *klass)
116 {
117  GObjectClass *object_class = (GObjectClass *) klass;
118  GtkContainerClass *container_class = (GtkContainerClass *) klass;
119 
120  object_class = (GObjectClass*) klass;
121 
122  parent_class = g_type_class_ref(GTK_TYPE_HBOX);
123 
124  general_select_signals[SELECTION_CHANGED] =
125  g_signal_new("changed",
126  G_TYPE_FROM_CLASS(object_class),
127  G_SIGNAL_RUN_FIRST,
128  G_STRUCT_OFFSET(GNCGeneralSelectClass,
129  changed),
130  NULL, NULL,
131  g_cclosure_marshal_VOID__VOID,
132  G_TYPE_NONE, 0);
133 
134  container_class->forall = gnc_general_select_forall;
135 
136  object_class->dispose = gnc_general_select_dispose;
137  object_class->finalize = gnc_general_select_finalize;
138 
139  klass->changed = NULL;
140 }
141 
142 static void
143 gnc_general_select_init (GNCGeneralSelect *gsl)
144 {
145  gsl->disposed = FALSE;
146  gsl->selected_item = NULL;
147 }
148 
149 static void
150 gnc_general_select_finalize (GObject *object)
151 {
152  g_return_if_fail (object != NULL);
153  g_return_if_fail (GNC_IS_GENERAL_SELECT (object));
154 
155  if (G_OBJECT_CLASS (parent_class)->finalize)
156  G_OBJECT_CLASS (parent_class)->finalize (object);
157 }
158 
159 static void
160 gnc_general_select_dispose (GObject *object)
161 {
162  GNCGeneralSelect *gsl;
163 
164  g_return_if_fail (object != NULL);
165  g_return_if_fail (GNC_IS_GENERAL_SELECT (object));
166 
167  gsl = GNC_GENERAL_SELECT (object);
168 
169  if (gsl->disposed)
170  return;
171 
172  gsl->disposed = TRUE;
173 
174 
175  gtk_widget_destroy(GTK_WIDGET(gsl->entry));
176  gsl->entry = NULL;
177 
178  gtk_widget_destroy(GTK_WIDGET(gsl->button));
179  gsl->button = NULL;
180 
181 
182  if (G_OBJECT_CLASS (parent_class)->dispose)
183  G_OBJECT_CLASS (parent_class)->dispose (object);
184 }
185 
186 static void
187 select_cb(GtkButton * button, gpointer user_data)
188 {
189  GNCGeneralSelect *gsl = user_data;
190  gpointer new_selection;
191  GtkWidget *toplevel;
192 
193  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
194 
195  new_selection = (gsl->new_select)(gsl->cb_arg, gsl->selected_item,
196  toplevel);
197 
198  /* NULL return means cancel; no change */
199  if (new_selection == NULL)
200  return;
201 
202  gnc_general_select_set_selected (gsl, new_selection);
203 }
204 
205 static void
206 create_children (GNCGeneralSelect *gsl, GNCGeneralSelectType type)
207 {
208  gsl->entry = gtk_entry_new ();
209  gtk_editable_set_editable (GTK_EDITABLE (gsl->entry), FALSE);
210  gtk_box_pack_start (GTK_BOX (gsl), gsl->entry, TRUE, TRUE, 0);
211  gtk_widget_show (gsl->entry);
212 
213  if (type == GNC_GENERAL_SELECT_TYPE_SELECT)
214  gsl->button = gtk_button_new_with_label (_("Select..."));
215  else if (type == GNC_GENERAL_SELECT_TYPE_EDIT)
216  gsl->button = gtk_button_new_with_label (_("Edit..."));
217  else if (type == GNC_GENERAL_SELECT_TYPE_VIEW)
218  gsl->button = gtk_button_new_with_label (_("View..."));
219 
220  gtk_box_pack_start (GTK_BOX (gsl), gsl->button, FALSE, FALSE, 0);
221  g_signal_connect (G_OBJECT (gsl->button), "clicked",
222  G_CALLBACK (select_cb), gsl);
223  gtk_widget_show (gsl->button);
224 }
225 
234 GtkWidget *
235 gnc_general_select_new (GNCGeneralSelectType type,
236  GNCGeneralSelectGetStringCB get_string,
237  GNCGeneralSelectNewSelectCB new_select,
238  gpointer cb_arg)
239 {
240  GNCGeneralSelect *gsl;
241  g_return_val_if_fail (get_string != NULL, NULL);
242  g_return_val_if_fail (new_select != NULL, NULL);
243 
244  gsl = g_object_new(GNC_TYPE_GENERAL_SELECT, NULL, NULL);
245 
246  create_children (gsl, type);
247  gsl->get_string = get_string;
248  gsl->new_select = new_select;
249  gsl->cb_arg = cb_arg;
250 
251  return GTK_WIDGET (gsl);
252 }
253 
254 /*
255  * gnc_general_select_get_printname:
256  * @gsl: the general selection widget
257  * @selection: the selection to get the printname
258  *
259  * returns the printable name of the selection
260  */
261 const char *
262 gnc_general_select_get_printname (GNCGeneralSelect *gsl, gpointer selection)
263 {
264  g_return_val_if_fail (gsl != NULL, NULL);
265  g_return_val_if_fail (selection != NULL, NULL);
266 
267  return (gsl->get_string)(selection);
268 }
269 
279 void
280 gnc_general_select_set_selected (GNCGeneralSelect *gsl, gpointer selection)
281 {
282  const char *text;
283 
284  g_return_if_fail(gsl != NULL);
285  g_return_if_fail(GNC_IS_GENERAL_SELECT(gsl));
286 
287  gsl->selected_item = selection;
288 
289  if (selection == NULL)
290  text = "";
291  else
292  text = gnc_general_select_get_printname(gsl, selection);
293 
294  gtk_entry_set_text(GTK_ENTRY(gsl->entry), text);
295 
296  g_signal_emit(gsl, general_select_signals[SELECTION_CHANGED], 0);
297 }
298 
305 gpointer
306 gnc_general_select_get_selected (GNCGeneralSelect *gsl)
307 {
308  g_return_val_if_fail(gsl != NULL, NULL);
309  g_return_val_if_fail(GNC_IS_GENERAL_SELECT(gsl), NULL);
310 
311  return gsl->selected_item;
312 }
313 
322 void
323 gnc_general_select_make_mnemonic_target (GNCGeneralSelect *gsl, GtkWidget *label)
324 {
325  g_return_if_fail(gsl);
326  g_return_if_fail(GNC_IS_GENERAL_SELECT(gsl));
327  g_return_if_fail(label);
328 
329  gtk_label_set_mnemonic_widget (GTK_LABEL(label), gsl->entry);
330 }
331