1
/********************************************************************\
2
* dialog-utils.c -- utility functions for creating dialogs *
4
* Copyright (C) 1999-2000 Linas Vepstas *
6
* This program is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU General Public License as *
8
* published by the Free Software Foundation; either version 2 of *
9
* the License, or (at your option) any later version. *
11
* This program is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU General Public License for more details. *
16
* You should have received a copy of the GNU General Public License*
17
* along with this program; if not, contact: *
19
* Free Software Foundation Voice: +1-617-542-5942 *
20
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
21
* Boston, MA 02111-1307, USA gnu@gnu.org *
23
\********************************************************************/
29
#include "account-tree.h"
30
#include "dialog-utils.h"
31
#include "global-options.h"
32
#include "gnc-commodity.h"
34
#include "EuroUtils.h"
37
#include "gnc-engine-util.h"
38
#include "gnc-ui-util.h"
42
/* This static indicates the debugging module that this .o belongs to. */
43
static short module = MOD_GUI;
46
/********************************************************************\
47
* gnc_ui_source_menu_create *
48
* create the menu of stock quote sources *
50
* Args: account - account to use to set default choice *
52
\*******************************************************************/
54
gnc_ui_source_menu_create(Account *account)
62
menu = GTK_MENU(gtk_menu_new());
63
gtk_widget_show(GTK_WIDGET(menu));
65
for (i = 0; i < NUM_SOURCES; i++)
67
item = gtk_menu_item_new_with_label(gnc_get_source_name(i));
68
gtk_widget_show(item);
69
gtk_menu_append(menu, item);
72
omenu = gtk_option_menu_new();
73
gtk_widget_show(omenu);
74
gtk_option_menu_set_menu(GTK_OPTION_MENU(omenu), GTK_WIDGET(menu));
75
gnc_option_menu_init(omenu);
80
/********************************************************************\
81
* price quote timezone handling
97
gnc_find_timezone_menu_position(const gchar *timezone)
99
/* returns 0 on failure, position otherwise. */
100
gboolean found = FALSE;
102
while(!found && known_timezones[i]) {
103
if(safe_strcmp(timezone, known_timezones[i]) != 0) {
109
if(found) return i + 1;
114
gnc_timezone_menu_position_to_string(guint pos)
116
if(pos == 0) return NULL;
117
return known_timezones[pos - 1];
121
gnc_ui_quote_tz_menu_create(Account *account)
129
/* add items here as needed, but bear in mind that right now these
130
must be timezones that GNU libc understands. Also, I'd prefer if
131
we only add things here we *know* we need. That's because in
132
order to be portable to non GNU OSes, we may have to support
133
whatever we add here manually on those systems. */
135
menu = GTK_MENU(gtk_menu_new());
136
gtk_widget_show(GTK_WIDGET(menu));
138
item = gtk_menu_item_new_with_label(_("Use local time"));
139
/* set user data to non NULL so we can detect this item specially. */
140
gtk_object_set_user_data(GTK_OBJECT(item), (gpointer) 1);
141
gtk_widget_show(item);
142
gtk_menu_append(menu, item);
144
for(itemstr = &known_timezones[0]; *itemstr; itemstr++) {
145
item = gtk_menu_item_new_with_label(*itemstr);
146
gtk_widget_show(item);
147
gtk_menu_append(menu, item);
150
omenu = gtk_option_menu_new();
151
gtk_widget_show(omenu);
152
gtk_option_menu_set_menu(GTK_OPTION_MENU(omenu), GTK_WIDGET(menu));
153
gnc_option_menu_init(omenu);
158
/* =========================================================== */
161
gnc_option_menu_cb(GtkWidget *w, gpointer data)
163
GNCOptionCallback cb;
167
cb = gtk_object_get_data(GTK_OBJECT(w), "gnc_option_cb");
169
_index = gtk_object_get_data(GTK_OBJECT(w), "gnc_option_index");
170
index = GPOINTER_TO_INT(_index);
176
option_menu_destroy_cb (GtkObject *obj, gpointer data)
178
GtkTooltips *tips = data;
180
gtk_object_unref (GTK_OBJECT (tips));
183
/********************************************************************\
184
* gnc_ui_create_option_button *
185
* create an option button given the option structure *
187
* Args: option_info - the option structure to use *
188
* num_options - the number of options *
190
\*******************************************************************/
192
gnc_build_option_menu(GNCOptionInfo *option_info, gint num_options)
194
GtkTooltips *tooltips;
197
GtkWidget *menu_item;
200
omenu = gtk_option_menu_new();
201
gtk_widget_show(omenu);
203
menu = gtk_menu_new();
204
gtk_widget_show(menu);
206
tooltips = gtk_tooltips_new();
208
gtk_object_ref (GTK_OBJECT (tooltips));
209
gtk_object_sink (GTK_OBJECT (tooltips));
211
for (i = 0; i < num_options; i++)
213
menu_item = gtk_menu_item_new_with_label(option_info[i].name);
214
gtk_tooltips_set_tip(tooltips, menu_item, option_info[i].tip, NULL);
215
gtk_widget_show(menu_item);
217
gtk_object_set_data(GTK_OBJECT(menu_item),
219
option_info[i].callback);
221
gtk_object_set_data(GTK_OBJECT(menu_item),
225
gtk_object_set_data(GTK_OBJECT(menu_item),
229
if (option_info[i].callback != NULL)
230
gtk_signal_connect(GTK_OBJECT(menu_item), "activate",
231
GTK_SIGNAL_FUNC(gnc_option_menu_cb),
232
option_info[i].user_data);
234
gtk_menu_append(GTK_MENU(menu), menu_item);
237
gtk_option_menu_set_menu(GTK_OPTION_MENU(omenu), menu);
239
gtk_signal_connect (GTK_OBJECT (omenu), "destroy",
240
GTK_SIGNAL_FUNC (option_menu_destroy_cb), tooltips);
246
/********************************************************************\
248
* returns a GnomePixmap widget given a pixmap filename *
251
* Returns: GnomePixmap widget or NULL if there was a problem *
252
\*******************************************************************/
254
gnc_get_pixmap (const char *name)
259
g_return_val_if_fail (name != NULL, NULL);
261
fullname = g_strconcat (GNC_PIXMAP_DIR, "/", name, NULL);
262
pixmap = gnome_pixmap_new_from_file (fullname);
269
/********************************************************************\
270
* gnc_get_imlib_image *
271
* returns a GdkImlibImage object given a pixmap filename *
274
* Returns: GnomePixmap widget or NULL if there was a problem *
275
\*******************************************************************/
277
gnc_get_gdk_imlib_image (const char *name)
279
GdkImlibImage *image;
283
g_return_val_if_fail (name != NULL, NULL);
285
fullname = g_strconcat (GNC_PIXMAP_DIR, "/", name, NULL);
286
image = gdk_imlib_load_image (fullname);
293
/********************************************************************\
294
* gnc_get_toolbar_style *
295
* returns the current toolbar style for gnucash toolbars *
298
* Returns: toolbar style *
299
\*******************************************************************/
301
gnc_get_toolbar_style(void)
303
GtkToolbarStyle tbstyle = GTK_TOOLBAR_BOTH;
306
style_string = gnc_lookup_multichoice_option("General",
310
if (safe_strcmp(style_string, "icons_and_text") == 0)
311
tbstyle = GTK_TOOLBAR_BOTH;
312
else if (safe_strcmp(style_string, "icons_only") == 0)
313
tbstyle = GTK_TOOLBAR_ICONS;
314
else if (safe_strcmp(style_string, "text_only") == 0)
315
tbstyle = GTK_TOOLBAR_TEXT;
317
if (style_string != NULL)
323
/********************************************************************
325
* returns the current Gnome MDI mode preference *
326
********************************************************************/
328
gnc_get_mdi_mode(void) {
329
GnomeMDIMode mode = GNOME_MDI_DEFAULT_MODE;
330
char * mode_string = gnc_lookup_multichoice_option("General",
331
"Application MDI mode",
333
if(!safe_strcmp(mode_string, "mdi-notebook")) {
334
mode = GNOME_MDI_NOTEBOOK;
336
else if(!safe_strcmp(mode_string, "mdi-toplevel")) {
337
mode = GNOME_MDI_TOPLEVEL;
339
else if(!safe_strcmp(mode_string, "mdi-modal")) {
340
mode = GNOME_MDI_MODAL;
342
else if(!safe_strcmp(mode_string, "mdi-default")) {
343
mode = GNOME_MDI_DEFAULT_MODE;
346
if(mode_string) free(mode_string);
351
/********************************************************************\
352
* gnc_get_deficit_color *
353
* fill in the 3 color values for the color of deficit values *
355
* Args: color - color structure *
357
\*******************************************************************/
359
gnc_get_deficit_color(GdkColor *color)
367
/********************************************************************\
368
* gnc_set_label_color *
369
* sets the color of the label given the value *
371
* Args: label - gtk label widget *
372
* value - value to use to set color *
374
\*******************************************************************/
376
gnc_set_label_color(GtkWidget *label, gnc_numeric value)
382
if (!gnc_color_deficits())
385
cm = gtk_widget_get_colormap(GTK_WIDGET(label));
386
style = gtk_widget_get_style(GTK_WIDGET(label));
388
style = gtk_style_copy(style);
390
deficit = gnc_numeric_negative_p (value);
394
gnc_get_deficit_color(&style->fg[GTK_STATE_NORMAL]);
395
gdk_colormap_alloc_color(cm, &style->fg[GTK_STATE_NORMAL], FALSE, TRUE);
398
style->fg[GTK_STATE_NORMAL] = style->black;
400
gtk_widget_set_style(label, style);
402
gtk_style_unref(style);
406
/********************************************************************\
407
* gnc_get_window_size *
408
* returns the window size to use for the given option prefix, *
409
* if window sizes are being saved, otherwise returns 0 for both. *
411
* Args: prefix - the option name prefix *
412
* width - pointer to width *
413
* height - pointer to height *
415
\*******************************************************************/
417
gnc_get_window_size(const char *prefix, int *width, int *height)
422
if (gnc_lookup_boolean_option("General", "Save Window Geometry", TRUE))
424
name = g_strconcat(prefix, "_width", NULL);
425
w = gnc_lookup_number_option("__gui", name, 0.0);
428
name = g_strconcat(prefix, "_height", NULL);
429
h = gnc_lookup_number_option("__gui", name, 0.0);
446
/********************************************************************\
447
* gnc_save_window_size *
448
* save the window size into options whose names are determined *
449
* by the string prefix. *
451
* Args: prefix - determines the options used to save the values *
452
* width - width of the window to save *
453
* height - height of the window to save *
455
\********************************************************************/
457
gnc_save_window_size(const char *prefix, int width, int height)
462
save = gnc_lookup_boolean_option("General", "Save Window Geometry", FALSE);
464
name = g_strconcat(prefix, "_width", NULL);
466
gnc_set_number_option("__gui", name, width);
468
gnc_set_option_default("__gui", name);
471
name = g_strconcat(prefix, "_height", NULL);
473
gnc_set_number_option("__gui", name, height);
475
gnc_set_option_default("__gui", name);
480
/********************************************************************\
481
* gnc_fill_menu_with_data *
482
* fill the user data values in the menu structure with the given *
483
* value. The filling is done recursively. *
485
* Args: info - the menu to fill *
486
* data - the value to fill with *
488
\********************************************************************/
490
gnc_fill_menu_with_data(GnomeUIInfo *info, gpointer data)
499
case GNOME_APP_UI_RADIOITEMS:
500
case GNOME_APP_UI_SUBTREE:
501
case GNOME_APP_UI_SUBTREE_STOCK:
502
gnc_fill_menu_with_data((GnomeUIInfo *) info->moreinfo, data);
504
case GNOME_APP_UI_ENDOFINFO:
507
info->user_data = data;
517
gnc_option_menu_init(GtkWidget * w)
523
menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(w));
525
for(i = 0; i < g_list_length(GTK_MENU_SHELL(menu)->children); i++)
527
gtk_option_menu_set_history(GTK_OPTION_MENU(w), i);
528
active = gtk_menu_get_active(GTK_MENU(menu));
529
gtk_object_set_data(GTK_OBJECT(active),
534
gtk_option_menu_set_history(GTK_OPTION_MENU(w), 0);
539
gnc_option_menu_get_active(GtkWidget * w)
542
GtkWidget * menuitem;
544
menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(w));
545
menuitem = gtk_menu_get_active(GTK_MENU(menu));
547
return GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(menuitem),
552
/********************************************************************\
553
* gnc_window_adjust_for_screen *
554
* adjust the window size if it is bigger than the screen size. *
556
* Args: window - the window to adjust *
558
\********************************************************************/
560
gnc_window_adjust_for_screen(GtkWindow * window)
570
g_return_if_fail(GTK_IS_WINDOW(window));
571
if (GTK_WIDGET(window)->window == NULL)
574
screen_width = gdk_screen_width();
575
screen_height = gdk_screen_height();
576
gdk_window_get_size(GTK_WIDGET(window)->window, &width, &height);
578
if ((width <= screen_width) && (height <= screen_height))
581
width = MIN(width, screen_width - 10);
582
width = MAX(width, 0);
584
height = MIN(height, screen_height - 10);
585
height = MAX(height, 0);
587
gdk_window_resize(GTK_WIDGET(window)->window, width, height);
588
gtk_widget_queue_resize(GTK_WIDGET(window));
601
GdkPixmap *on_pixmap;
602
GdkPixmap *off_pixmap;
605
GList *pending_checks;
609
free_check_list (GList *list)
613
for (node = list; node; node = node->next)
620
check_realize (GtkWidget *widget, gpointer user_data)
622
GNCCListCheckInfo *check_info = user_data;
623
GdkGCValues gc_values;
633
if (check_info->mask)
636
style = gtk_widget_get_style (widget);
638
font_height = style->font->ascent + style->font->descent;
639
check_size = (font_height > 0) ? font_height - 3 : 9;
641
check_info->mask = gdk_pixmap_new (NULL, check_size, check_size, 1);
643
check_info->on_pixmap = gdk_pixmap_new (widget->window,
644
check_size, check_size, -1);
646
check_info->off_pixmap = gdk_pixmap_new (widget->window,
647
check_size, check_size, -1);
649
gc_values.foreground = style->white;
650
gc = gtk_gc_get (1, gtk_widget_get_colormap (widget),
651
&gc_values, GDK_GC_FOREGROUND);
653
gdk_draw_rectangle (check_info->mask, gc, TRUE,
654
0, 0, check_size, check_size);
658
gc = style->base_gc[GTK_STATE_NORMAL];
660
gdk_draw_rectangle (check_info->on_pixmap, gc, TRUE,
661
0, 0, check_size, check_size);
662
gdk_draw_rectangle (check_info->off_pixmap, gc, TRUE,
663
0, 0, check_size, check_size);
665
cm = gtk_widget_get_colormap (widget);
667
gc_values.foreground.red = 0;
668
gc_values.foreground.green = 65535 / 2;
669
gc_values.foreground.blue = 0;
671
gdk_colormap_alloc_color (cm, &gc_values.foreground, FALSE, TRUE);
673
gc = gdk_gc_new_with_values (widget->window, &gc_values, GDK_GC_FOREGROUND);
675
gdk_draw_line (check_info->on_pixmap, gc,
677
check_size / 3, check_size - 5);
678
gdk_draw_line (check_info->on_pixmap, gc,
679
1, check_size / 2 + 1,
680
check_size / 3, check_size - 4);
682
gdk_draw_line (check_info->on_pixmap, gc,
683
check_size / 3, check_size - 5,
685
gdk_draw_line (check_info->on_pixmap, gc,
686
check_size / 3, check_size - 4,
691
clist = GTK_CLIST (widget);
693
list = check_info->pending_checks;
694
check_info->pending_checks = NULL;
696
/* reverse so we apply in the order of the calls */
697
list = g_list_reverse (list);
699
for (node = list; node; node = node->next)
701
GNCCListCheckNode *cl_node = node->data;
703
gnc_clist_set_check (clist, cl_node->row, cl_node->col, cl_node->checked);
706
free_check_list (list);
710
check_unrealize (GtkWidget *widget, gpointer user_data)
712
GNCCListCheckInfo *check_info = user_data;
714
if (check_info->mask)
715
gdk_bitmap_unref (check_info->mask);
717
if (check_info->on_pixmap)
718
gdk_pixmap_unref (check_info->on_pixmap);
720
if (check_info->off_pixmap)
721
gdk_pixmap_unref (check_info->off_pixmap);
723
check_info->mask = NULL;
724
check_info->on_pixmap = NULL;
725
check_info->off_pixmap = NULL;
729
check_destroy (GtkWidget *widget, gpointer user_data)
731
GNCCListCheckInfo *check_info = user_data;
733
free_check_list (check_info->pending_checks);
734
check_info->pending_checks = NULL;
739
static GNCCListCheckInfo *
740
gnc_clist_add_check (GtkCList *list)
742
GNCCListCheckInfo *check_info;
745
object = GTK_OBJECT (list);
747
check_info = gtk_object_get_data (object, "gnc-check-info");
750
PWARN ("clist already has check");
754
check_info = g_new0 (GNCCListCheckInfo, 1);
756
gtk_object_set_data (object, "gnc-check-info", check_info);
758
gtk_signal_connect (object, "realize",
759
GTK_SIGNAL_FUNC (check_realize), check_info);
760
gtk_signal_connect (object, "unrealize",
761
GTK_SIGNAL_FUNC (check_unrealize), check_info);
762
gtk_signal_connect (object, "destroy",
763
GTK_SIGNAL_FUNC (check_destroy), check_info);
765
if (GTK_WIDGET_REALIZED (GTK_WIDGET (list)))
766
check_realize (GTK_WIDGET (list), check_info);
773
gnc_clist_set_check (GtkCList *list, int row, int col, gboolean checked)
775
GNCCListCheckInfo *check_info;
778
g_return_if_fail (GTK_IS_CLIST (list));
780
check_info = gtk_object_get_data (GTK_OBJECT (list), "gnc-check-info");
782
check_info = gnc_clist_add_check (list);
784
if (!GTK_WIDGET_REALIZED (GTK_WIDGET (list)))
786
GNCCListCheckNode *node;
788
node = g_new0 (GNCCListCheckNode, 1);
792
node->checked = checked;
794
check_info->pending_checks =
795
g_list_prepend (check_info->pending_checks, node);
800
pixmap = checked ? check_info->on_pixmap : check_info->off_pixmap;
803
gtk_clist_set_pixmap (list, row, col, pixmap, check_info->mask);
805
gtk_clist_set_text (list, row, col, "");
809
gnc_clist_columns_autosize (GtkCList *list)
816
g_return_if_fail (GTK_IS_CLIST (list));
818
style = gtk_widget_get_style (GTK_WIDGET(list));
826
for (i = 0; TRUE; i++)
832
widget = gtk_clist_get_column_widget (list, i);
836
if (!GTK_IS_LABEL (widget))
839
gtk_label_get (GTK_LABEL (widget), &title);
841
width = gdk_string_width (font, title);
842
gtk_clist_set_column_min_width (list, i, width + 5);
845
gtk_clist_columns_autosize (list);