~ubuntu-branches/ubuntu/hoary/gnucash/hoary

« back to all changes in this revision

Viewing changes to src/gnome/dialog-utils.c

  • Committer: Bazaar Package Importer
  • Author(s): James A. Treacy
  • Date: 2002-03-16 14:14:59 UTC
  • Revision ID: james.westby@ubuntu.com-20020316141459-wtkyyrpfovryhl1s
Tags: upstream-1.6.6
ImportĀ upstreamĀ versionĀ 1.6.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/********************************************************************\
 
2
 * dialog-utils.c -- utility functions for creating dialogs         *
 
3
 *                   for GnuCash                                    *
 
4
 * Copyright (C) 1999-2000 Linas Vepstas                            *
 
5
 *                                                                  *
 
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.              *
 
10
 *                                                                  *
 
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.                     *
 
15
 *                                                                  *
 
16
 * You should have received a copy of the GNU General Public License*
 
17
 * along with this program; if not, contact:                        *
 
18
 *                                                                  *
 
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                   *
 
22
 *                                                                  *
 
23
\********************************************************************/
 
24
 
 
25
#include "config.h"
 
26
 
 
27
#include <gnome.h>
 
28
 
 
29
#include "account-tree.h"
 
30
#include "dialog-utils.h"
 
31
#include "global-options.h"
 
32
#include "gnc-commodity.h"
 
33
#include "messages.h"
 
34
#include "EuroUtils.h"
 
35
#include "Group.h"
 
36
#include "gnc-dir.h"
 
37
#include "gnc-engine-util.h"
 
38
#include "gnc-ui-util.h"
 
39
#include "gnc-ui.h"
 
40
 
 
41
 
 
42
/* This static indicates the debugging module that this .o belongs to. */
 
43
static short module = MOD_GUI;
 
44
 
 
45
 
 
46
/********************************************************************\
 
47
 * gnc_ui_source_menu_create                                        *
 
48
 *   create the menu of stock quote sources                         *
 
49
 *                                                                  *
 
50
 * Args:    account - account to use to set default choice          *
 
51
 * Returns: the menu                                                *
 
52
 \*******************************************************************/
 
53
GtkWidget *
 
54
gnc_ui_source_menu_create(Account *account)
 
55
{
 
56
  gint i;
 
57
  GtkMenu   *menu;
 
58
  GtkWidget *item;
 
59
  GtkWidget *omenu;
 
60
  GNCAccountType type;
 
61
 
 
62
  menu = GTK_MENU(gtk_menu_new());
 
63
  gtk_widget_show(GTK_WIDGET(menu));
 
64
 
 
65
  for (i = 0; i < NUM_SOURCES; i++)
 
66
  {
 
67
    item = gtk_menu_item_new_with_label(gnc_get_source_name(i));
 
68
    gtk_widget_show(item);
 
69
    gtk_menu_append(menu, item);
 
70
  }
 
71
 
 
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);
 
76
 
 
77
  return omenu;
 
78
}
 
79
 
 
80
/********************************************************************\
 
81
 * price quote timezone handling
 
82
 */
 
83
 
 
84
static gchar *
 
85
known_timezones[] =
 
86
{
 
87
  "Asia/Tokyo",
 
88
  "Australia/Sydney",
 
89
  "America/New_York",
 
90
  "America/Chicago",
 
91
  "Europe/London",
 
92
  "Europe/Paris",
 
93
  NULL
 
94
};
 
95
 
 
96
guint
 
97
gnc_find_timezone_menu_position(const gchar *timezone)
 
98
{
 
99
  /* returns 0 on failure, position otherwise. */
 
100
  gboolean found = FALSE;
 
101
  guint i = 0;
 
102
  while(!found && known_timezones[i]) {
 
103
    if(safe_strcmp(timezone, known_timezones[i]) != 0) {
 
104
      i++;
 
105
    } else {
 
106
      found = TRUE;
 
107
    }
 
108
  }
 
109
  if(found) return i + 1;
 
110
  return 0;
 
111
}
 
112
 
 
113
gchar *
 
114
gnc_timezone_menu_position_to_string(guint pos)
 
115
{
 
116
  if(pos == 0) return NULL;
 
117
  return known_timezones[pos - 1];
 
118
}
 
119
 
 
120
GtkWidget *
 
121
gnc_ui_quote_tz_menu_create(Account *account)
 
122
{
 
123
  gint i;
 
124
  GtkMenu   *menu;
 
125
  GtkWidget *item;
 
126
  GtkWidget *omenu;
 
127
  gchar     **itemstr;
 
128
 
 
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. */
 
134
 
 
135
  menu = GTK_MENU(gtk_menu_new());
 
136
  gtk_widget_show(GTK_WIDGET(menu));
 
137
 
 
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);
 
143
 
 
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);
 
148
  }
 
149
 
 
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);
 
154
 
 
155
  return omenu;
 
156
}
 
157
 
 
158
/* =========================================================== */
 
159
 
 
160
static void
 
161
gnc_option_menu_cb(GtkWidget *w, gpointer data)
 
162
{
 
163
  GNCOptionCallback cb;
 
164
  gpointer _index;
 
165
  gint index;
 
166
 
 
167
  cb = gtk_object_get_data(GTK_OBJECT(w), "gnc_option_cb");
 
168
 
 
169
  _index = gtk_object_get_data(GTK_OBJECT(w), "gnc_option_index");
 
170
  index = GPOINTER_TO_INT(_index);
 
171
 
 
172
  cb(w, index, data);
 
173
}
 
174
 
 
175
static void
 
176
option_menu_destroy_cb (GtkObject *obj, gpointer data)
 
177
{
 
178
  GtkTooltips *tips = data;
 
179
 
 
180
  gtk_object_unref (GTK_OBJECT (tips));
 
181
}
 
182
 
 
183
/********************************************************************\
 
184
 * gnc_ui_create_option_button                                      *
 
185
 *   create an option button given the option structure             *
 
186
 *                                                                  *
 
187
 * Args: option_info - the option structure to use                  *
 
188
 *       num_options - the number of options                        *
 
189
 * Returns: void                                                    *
 
190
 \*******************************************************************/
 
191
GtkWidget *
 
192
gnc_build_option_menu(GNCOptionInfo *option_info, gint num_options)
 
193
{
 
194
  GtkTooltips *tooltips;
 
195
  GtkWidget *omenu;
 
196
  GtkWidget *menu;
 
197
  GtkWidget *menu_item;
 
198
  gint i;
 
199
 
 
200
  omenu = gtk_option_menu_new();
 
201
  gtk_widget_show(omenu);
 
202
 
 
203
  menu = gtk_menu_new();
 
204
  gtk_widget_show(menu);
 
205
 
 
206
  tooltips = gtk_tooltips_new();
 
207
 
 
208
  gtk_object_ref (GTK_OBJECT (tooltips));
 
209
  gtk_object_sink (GTK_OBJECT (tooltips));
 
210
 
 
211
  for (i = 0; i < num_options; i++)
 
212
  {
 
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);
 
216
 
 
217
    gtk_object_set_data(GTK_OBJECT(menu_item),
 
218
                        "gnc_option_cb",
 
219
                        option_info[i].callback);
 
220
 
 
221
    gtk_object_set_data(GTK_OBJECT(menu_item),
 
222
                        "gnc_option_index",
 
223
                        GINT_TO_POINTER(i));
 
224
 
 
225
    gtk_object_set_data(GTK_OBJECT(menu_item),
 
226
                        "gnc_option_menu",
 
227
                        omenu);
 
228
 
 
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);
 
233
 
 
234
    gtk_menu_append(GTK_MENU(menu), menu_item);
 
235
  }
 
236
 
 
237
  gtk_option_menu_set_menu(GTK_OPTION_MENU(omenu), menu);
 
238
 
 
239
  gtk_signal_connect (GTK_OBJECT (omenu), "destroy",
 
240
                      GTK_SIGNAL_FUNC (option_menu_destroy_cb), tooltips);
 
241
 
 
242
  return omenu;
 
243
}
 
244
 
 
245
 
 
246
/********************************************************************\
 
247
 * gnc_get_pixmap                                                   *
 
248
 *   returns a GnomePixmap widget given a pixmap filename           *
 
249
 *                                                                  *
 
250
 * Args: none                                                       *
 
251
 * Returns: GnomePixmap widget or NULL if there was a problem       *
 
252
 \*******************************************************************/
 
253
GtkWidget *
 
254
gnc_get_pixmap (const char *name)
 
255
{
 
256
  GtkWidget *pixmap;
 
257
  char *fullname;
 
258
 
 
259
  g_return_val_if_fail (name != NULL, NULL);
 
260
 
 
261
  fullname = g_strconcat (GNC_PIXMAP_DIR, "/", name, NULL);
 
262
  pixmap = gnome_pixmap_new_from_file (fullname);
 
263
  g_free (fullname);
 
264
 
 
265
  return pixmap;
 
266
}
 
267
 
 
268
 
 
269
/********************************************************************\
 
270
 * gnc_get_imlib_image                                              *
 
271
 *   returns a GdkImlibImage object given a pixmap filename         *
 
272
 *                                                                  *
 
273
 * Args: none                                                       *
 
274
 * Returns: GnomePixmap widget or NULL if there was a problem       *
 
275
 \*******************************************************************/
 
276
GdkImlibImage *
 
277
gnc_get_gdk_imlib_image (const char *name)
 
278
{
 
279
  GdkImlibImage *image;
 
280
 
 
281
  char *fullname;
 
282
 
 
283
  g_return_val_if_fail (name != NULL, NULL);
 
284
 
 
285
  fullname = g_strconcat (GNC_PIXMAP_DIR, "/", name, NULL);
 
286
  image = gdk_imlib_load_image (fullname);
 
287
  g_free (fullname);
 
288
 
 
289
  return image;
 
290
}
 
291
 
 
292
 
 
293
/********************************************************************\
 
294
 * gnc_get_toolbar_style                                            *
 
295
 *   returns the current toolbar style for gnucash toolbars         *
 
296
 *                                                                  *
 
297
 * Args: none                                                       *
 
298
 * Returns: toolbar style                                           *
 
299
 \*******************************************************************/
 
300
GtkToolbarStyle
 
301
gnc_get_toolbar_style(void)
 
302
{
 
303
  GtkToolbarStyle tbstyle = GTK_TOOLBAR_BOTH;
 
304
  char *style_string;
 
305
 
 
306
  style_string = gnc_lookup_multichoice_option("General",
 
307
                                               "Toolbar Buttons",
 
308
                                               "icons_and_text");
 
309
 
 
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;
 
316
 
 
317
  if (style_string != NULL)
 
318
    free(style_string);
 
319
 
 
320
  return tbstyle;
 
321
}
 
322
 
 
323
/********************************************************************
 
324
 * gnc_get_mdi_mode                                                 *
 
325
 * returns the current Gnome MDI mode preference                    *
 
326
 ********************************************************************/
 
327
GnomeMDIMode 
 
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",
 
332
                                                     "");
 
333
  if(!safe_strcmp(mode_string, "mdi-notebook")) {
 
334
    mode = GNOME_MDI_NOTEBOOK;
 
335
  }
 
336
  else if(!safe_strcmp(mode_string, "mdi-toplevel")) {
 
337
    mode = GNOME_MDI_TOPLEVEL;    
 
338
  }
 
339
  else if(!safe_strcmp(mode_string, "mdi-modal")) {
 
340
    mode = GNOME_MDI_MODAL;    
 
341
  }
 
342
  else if(!safe_strcmp(mode_string, "mdi-default")) {
 
343
    mode = GNOME_MDI_DEFAULT_MODE;    
 
344
  }
 
345
 
 
346
  if(mode_string) free(mode_string);
 
347
  return mode;
 
348
}
 
349
 
 
350
 
 
351
/********************************************************************\
 
352
 * gnc_get_deficit_color                                            *
 
353
 *   fill in the 3 color values for the color of deficit values     *
 
354
 *                                                                  *
 
355
 * Args: color - color structure                                    *
 
356
 * Returns: none                                                    *
 
357
 \*******************************************************************/
 
358
void
 
359
gnc_get_deficit_color(GdkColor *color)
 
360
{
 
361
  color->red   = 50000;
 
362
  color->green = 0;
 
363
  color->blue  = 0;
 
364
}
 
365
 
 
366
 
 
367
/********************************************************************\
 
368
 * gnc_set_label_color                                              *
 
369
 *   sets the color of the label given the value                    *
 
370
 *                                                                  *
 
371
 * Args: label - gtk label widget                                   *
 
372
 *       value - value to use to set color                          *
 
373
 * Returns: none                                                    *
 
374
 \*******************************************************************/
 
375
void
 
376
gnc_set_label_color(GtkWidget *label, gnc_numeric value)
 
377
{
 
378
  gboolean deficit;
 
379
  GdkColormap *cm;
 
380
  GtkStyle *style;
 
381
 
 
382
  if (!gnc_color_deficits())
 
383
    return;
 
384
 
 
385
  cm = gtk_widget_get_colormap(GTK_WIDGET(label));
 
386
  style = gtk_widget_get_style(GTK_WIDGET(label));
 
387
 
 
388
  style = gtk_style_copy(style);
 
389
 
 
390
  deficit = gnc_numeric_negative_p (value);
 
391
 
 
392
  if (deficit)
 
393
  {
 
394
    gnc_get_deficit_color(&style->fg[GTK_STATE_NORMAL]);
 
395
    gdk_colormap_alloc_color(cm, &style->fg[GTK_STATE_NORMAL], FALSE, TRUE);
 
396
  }
 
397
  else
 
398
    style->fg[GTK_STATE_NORMAL] = style->black;
 
399
 
 
400
  gtk_widget_set_style(label, style);
 
401
 
 
402
  gtk_style_unref(style);
 
403
}
 
404
 
 
405
 
 
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. *
 
410
 *                                                                  *
 
411
 * Args: prefix - the option name prefix                            *
 
412
 *       width  - pointer to width                                  *
 
413
 *       height - pointer to height                                 *
 
414
 * Returns: nothing                                                 *
 
415
 \*******************************************************************/
 
416
void
 
417
gnc_get_window_size(const char *prefix, int *width, int *height)
 
418
{
 
419
  int w, h;
 
420
  char *name;
 
421
 
 
422
  if (gnc_lookup_boolean_option("General", "Save Window Geometry", TRUE))
 
423
  {
 
424
    name = g_strconcat(prefix, "_width", NULL);
 
425
    w = gnc_lookup_number_option("__gui", name, 0.0);
 
426
    g_free(name);
 
427
 
 
428
    name = g_strconcat(prefix, "_height", NULL);
 
429
    h = gnc_lookup_number_option("__gui", name, 0.0);
 
430
    g_free(name);
 
431
  }
 
432
  else
 
433
  {
 
434
    w = 0;
 
435
    h = 0;
 
436
  }
 
437
 
 
438
  if (width != NULL)
 
439
    *width = w;
 
440
 
 
441
  if (height != NULL)
 
442
    *height = h;
 
443
}
 
444
 
 
445
 
 
446
/********************************************************************\
 
447
 * gnc_save_window_size                                             *
 
448
 *   save the window size into options whose names are determined   *
 
449
 *   by the string prefix.                                          *
 
450
 *                                                                  *
 
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                      *
 
454
 * Returns: nothing                                                 *
 
455
\********************************************************************/
 
456
void
 
457
gnc_save_window_size(const char *prefix, int width, int height)
 
458
{
 
459
  char *name;
 
460
  gboolean save;
 
461
 
 
462
  save = gnc_lookup_boolean_option("General", "Save Window Geometry", FALSE);
 
463
 
 
464
  name = g_strconcat(prefix, "_width", NULL);
 
465
  if (save)
 
466
    gnc_set_number_option("__gui", name, width);
 
467
  else
 
468
    gnc_set_option_default("__gui", name);
 
469
  g_free(name);
 
470
 
 
471
  name = g_strconcat(prefix, "_height", NULL);
 
472
  if (save)
 
473
    gnc_set_number_option("__gui", name, height);
 
474
  else
 
475
    gnc_set_option_default("__gui", name);
 
476
  g_free(name);
 
477
}
 
478
 
 
479
 
 
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.                        *
 
484
 *                                                                  *
 
485
 * Args: info - the menu to fill                                    *
 
486
 *       data - the value to fill with                              *
 
487
 * Returns: nothing                                                 *
 
488
\********************************************************************/
 
489
void
 
490
gnc_fill_menu_with_data(GnomeUIInfo *info, gpointer data)
 
491
{
 
492
  if (info == NULL)
 
493
    return;
 
494
 
 
495
  while (1)
 
496
  {
 
497
    switch (info->type)
 
498
    {
 
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);
 
503
        break;
 
504
      case GNOME_APP_UI_ENDOFINFO:
 
505
        return;
 
506
      default:
 
507
        info->user_data = data;
 
508
        break;
 
509
    }
 
510
 
 
511
    info++;
 
512
  }
 
513
}
 
514
 
 
515
 
 
516
void
 
517
gnc_option_menu_init(GtkWidget * w)
 
518
{
 
519
  GtkWidget * menu;
 
520
  GtkWidget * active;
 
521
  int i;
 
522
 
 
523
  menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(w));
 
524
 
 
525
  for(i = 0; i < g_list_length(GTK_MENU_SHELL(menu)->children); i++)
 
526
  {
 
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), 
 
530
                        "option_index",
 
531
                        GINT_TO_POINTER(i));
 
532
  }
 
533
 
 
534
  gtk_option_menu_set_history(GTK_OPTION_MENU(w), 0);
 
535
}
 
536
 
 
537
 
 
538
int
 
539
gnc_option_menu_get_active(GtkWidget * w)
 
540
{
 
541
  GtkWidget * menu;
 
542
  GtkWidget * menuitem;
 
543
 
 
544
  menu     = gtk_option_menu_get_menu(GTK_OPTION_MENU(w));
 
545
  menuitem = gtk_menu_get_active(GTK_MENU(menu));
 
546
 
 
547
  return GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(menuitem),
 
548
                                             "option_index"));
 
549
}
 
550
 
 
551
 
 
552
/********************************************************************\
 
553
 * gnc_window_adjust_for_screen                                     *
 
554
 *   adjust the window size if it is bigger than the screen size.   *
 
555
 *                                                                  *
 
556
 * Args: window - the window to adjust                              *
 
557
 * Returns: nothing                                                 *
 
558
\********************************************************************/
 
559
void
 
560
gnc_window_adjust_for_screen(GtkWindow * window)
 
561
{
 
562
  gint screen_width;
 
563
  gint screen_height;
 
564
  gint width;
 
565
  gint height;
 
566
 
 
567
  if (window == NULL)
 
568
    return;
 
569
 
 
570
  g_return_if_fail(GTK_IS_WINDOW(window));
 
571
  if (GTK_WIDGET(window)->window == NULL)
 
572
    return;
 
573
 
 
574
  screen_width = gdk_screen_width();
 
575
  screen_height = gdk_screen_height();
 
576
  gdk_window_get_size(GTK_WIDGET(window)->window, &width, &height);
 
577
 
 
578
  if ((width <= screen_width) && (height <= screen_height))
 
579
    return;
 
580
 
 
581
  width = MIN(width, screen_width - 10);
 
582
  width = MAX(width, 0);
 
583
 
 
584
  height = MIN(height, screen_height - 10);
 
585
  height = MAX(height, 0);
 
586
 
 
587
  gdk_window_resize(GTK_WIDGET(window)->window, width, height);
 
588
  gtk_widget_queue_resize(GTK_WIDGET(window));
 
589
}
 
590
 
 
591
 
 
592
typedef struct
 
593
{
 
594
  int row;
 
595
  int col;
 
596
  gboolean checked;
 
597
} GNCCListCheckNode;
 
598
 
 
599
typedef struct
 
600
{
 
601
  GdkPixmap *on_pixmap;
 
602
  GdkPixmap *off_pixmap;
 
603
  GdkBitmap *mask;
 
604
 
 
605
  GList *pending_checks;
 
606
} GNCCListCheckInfo;
 
607
 
 
608
static void
 
609
free_check_list (GList *list)
 
610
{
 
611
  GList *node;
 
612
 
 
613
  for (node = list; node; node = node->next)
 
614
    g_free (node->data);
 
615
 
 
616
  g_list_free (list);
 
617
}
 
618
 
 
619
static void
 
620
check_realize (GtkWidget *widget, gpointer user_data)
 
621
{
 
622
  GNCCListCheckInfo *check_info = user_data;
 
623
  GdkGCValues gc_values;
 
624
  GtkCList *clist;
 
625
  gint font_height;
 
626
  gint check_size;
 
627
  GdkColormap *cm;
 
628
  GtkStyle *style;
 
629
  GList *list;
 
630
  GList *node;
 
631
  GdkGC *gc;
 
632
 
 
633
  if (check_info->mask)
 
634
    return;
 
635
 
 
636
  style = gtk_widget_get_style (widget);
 
637
 
 
638
  font_height = style->font->ascent + style->font->descent;
 
639
  check_size = (font_height > 0) ? font_height - 3 : 9;
 
640
 
 
641
  check_info->mask = gdk_pixmap_new (NULL, check_size, check_size, 1);
 
642
 
 
643
  check_info->on_pixmap = gdk_pixmap_new (widget->window,
 
644
                                          check_size, check_size, -1);
 
645
 
 
646
  check_info->off_pixmap = gdk_pixmap_new (widget->window,
 
647
                                           check_size, check_size, -1);
 
648
 
 
649
  gc_values.foreground = style->white;
 
650
  gc = gtk_gc_get (1, gtk_widget_get_colormap (widget),
 
651
                   &gc_values, GDK_GC_FOREGROUND);
 
652
 
 
653
  gdk_draw_rectangle (check_info->mask, gc, TRUE,
 
654
                      0, 0, check_size, check_size);
 
655
 
 
656
  gtk_gc_release (gc);
 
657
 
 
658
  gc = style->base_gc[GTK_STATE_NORMAL];
 
659
 
 
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);
 
664
 
 
665
  cm = gtk_widget_get_colormap (widget);
 
666
 
 
667
  gc_values.foreground.red = 0;
 
668
  gc_values.foreground.green = 65535 / 2;
 
669
  gc_values.foreground.blue = 0;
 
670
 
 
671
  gdk_colormap_alloc_color (cm, &gc_values.foreground, FALSE, TRUE);
 
672
 
 
673
  gc = gdk_gc_new_with_values (widget->window, &gc_values, GDK_GC_FOREGROUND);
 
674
 
 
675
  gdk_draw_line (check_info->on_pixmap, gc,
 
676
                 1, check_size / 2,
 
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);
 
681
        
 
682
  gdk_draw_line (check_info->on_pixmap, gc,
 
683
                 check_size / 3, check_size - 5,
 
684
                 check_size - 3, 2);
 
685
  gdk_draw_line (check_info->on_pixmap, gc,
 
686
                 check_size / 3, check_size - 4,
 
687
                 check_size - 3, 1);
 
688
 
 
689
  gdk_gc_unref (gc);
 
690
 
 
691
  clist = GTK_CLIST (widget);
 
692
 
 
693
  list = check_info->pending_checks;
 
694
  check_info->pending_checks = NULL;
 
695
 
 
696
  /* reverse so we apply in the order of the calls */
 
697
  list = g_list_reverse (list);
 
698
 
 
699
  for (node = list; node; node = node->next)
 
700
  {
 
701
    GNCCListCheckNode *cl_node = node->data;
 
702
 
 
703
    gnc_clist_set_check (clist, cl_node->row, cl_node->col, cl_node->checked);
 
704
  }
 
705
 
 
706
  free_check_list (list);
 
707
}
 
708
 
 
709
static void
 
710
check_unrealize (GtkWidget *widget, gpointer user_data)
 
711
{
 
712
  GNCCListCheckInfo *check_info = user_data;
 
713
 
 
714
  if (check_info->mask)
 
715
    gdk_bitmap_unref (check_info->mask);
 
716
 
 
717
  if (check_info->on_pixmap)
 
718
    gdk_pixmap_unref (check_info->on_pixmap);
 
719
 
 
720
  if (check_info->off_pixmap)
 
721
    gdk_pixmap_unref (check_info->off_pixmap);
 
722
 
 
723
  check_info->mask = NULL;
 
724
  check_info->on_pixmap = NULL;
 
725
  check_info->off_pixmap = NULL;
 
726
}
 
727
 
 
728
static void
 
729
check_destroy (GtkWidget *widget, gpointer user_data)
 
730
{
 
731
  GNCCListCheckInfo *check_info = user_data;
 
732
 
 
733
  free_check_list (check_info->pending_checks);
 
734
  check_info->pending_checks = NULL;
 
735
 
 
736
  g_free (check_info);
 
737
}
 
738
 
 
739
static GNCCListCheckInfo *
 
740
gnc_clist_add_check (GtkCList *list)
 
741
{
 
742
  GNCCListCheckInfo *check_info;
 
743
  GtkObject *object;
 
744
 
 
745
  object = GTK_OBJECT (list);
 
746
 
 
747
  check_info = gtk_object_get_data (object, "gnc-check-info");
 
748
  if (check_info)
 
749
  {
 
750
    PWARN ("clist already has check");
 
751
    return check_info;
 
752
  }
 
753
 
 
754
  check_info = g_new0 (GNCCListCheckInfo, 1);
 
755
 
 
756
  gtk_object_set_data (object, "gnc-check-info", check_info);
 
757
 
 
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);
 
764
 
 
765
  if (GTK_WIDGET_REALIZED (GTK_WIDGET (list)))
 
766
    check_realize (GTK_WIDGET (list), check_info);
 
767
 
 
768
  return check_info;
 
769
}
 
770
 
 
771
 
 
772
void
 
773
gnc_clist_set_check (GtkCList *list, int row, int col, gboolean checked)
 
774
{
 
775
  GNCCListCheckInfo *check_info;
 
776
  GdkPixmap *pixmap;
 
777
 
 
778
  g_return_if_fail (GTK_IS_CLIST (list));
 
779
 
 
780
  check_info = gtk_object_get_data (GTK_OBJECT (list), "gnc-check-info");
 
781
  if (!check_info)
 
782
    check_info = gnc_clist_add_check (list);
 
783
 
 
784
  if (!GTK_WIDGET_REALIZED (GTK_WIDGET (list)))
 
785
  {
 
786
    GNCCListCheckNode *node;
 
787
 
 
788
    node = g_new0 (GNCCListCheckNode, 1);
 
789
 
 
790
    node->row = row;
 
791
    node->col = col;
 
792
    node->checked = checked;
 
793
 
 
794
    check_info->pending_checks =
 
795
      g_list_prepend (check_info->pending_checks, node);
 
796
 
 
797
    return;
 
798
  }
 
799
 
 
800
  pixmap = checked ? check_info->on_pixmap : check_info->off_pixmap;
 
801
 
 
802
  if (checked)
 
803
    gtk_clist_set_pixmap (list, row, col, pixmap, check_info->mask);
 
804
  else
 
805
    gtk_clist_set_text (list, row, col, "");
 
806
}
 
807
 
 
808
void
 
809
gnc_clist_columns_autosize (GtkCList *list)
 
810
{
 
811
  GtkStyle *style;
 
812
  GdkFont *font;
 
813
  gint i;
 
814
 
 
815
  if (!list) return;
 
816
  g_return_if_fail (GTK_IS_CLIST (list));
 
817
 
 
818
  style = gtk_widget_get_style (GTK_WIDGET(list));
 
819
  if (!style)
 
820
    return;
 
821
 
 
822
  font = style->font;
 
823
  if (!font)
 
824
    return;
 
825
 
 
826
  for (i = 0; TRUE; i++)
 
827
  {
 
828
    GtkWidget *widget;
 
829
    char *title;
 
830
    gint width;
 
831
 
 
832
    widget = gtk_clist_get_column_widget (list, i);
 
833
    if (!widget)
 
834
      break;
 
835
 
 
836
    if (!GTK_IS_LABEL (widget))
 
837
      continue;
 
838
 
 
839
    gtk_label_get (GTK_LABEL (widget), &title);
 
840
 
 
841
    width = gdk_string_width (font, title);
 
842
    gtk_clist_set_column_min_width (list, i, width + 5);
 
843
  }
 
844
 
 
845
  gtk_clist_columns_autosize (list);
 
846
}