planner-cell-renderer-date.c 15.2 KB
Newer Older
Richard Hult's avatar
Richard Hult committed
1 2
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
3
 * Copyright (C) 2005 Imendio AB
Richard Hult's avatar
Richard Hult committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 * Copyright (C) 2001-2002 CodeFactory AB
 * Copyright (C) 2001-2002 Richard Hult <richard@imendio.com>
 * Copyright (C) 2001-2002 Mikael Hallendal <micke@imendio.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
Josué Abarca's avatar
Josué Abarca committed
20 21
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
Richard Hult's avatar
Richard Hult committed
22 23 24 25 26
 */

#include <config.h>
#include <stdlib.h>
#include <gdk/gdkkeysyms.h>
27
#include <gtk/gtk.h>
28
#include <glib/gi18n.h>
Richard Hult's avatar
Richard Hult committed
29 30 31 32 33 34 35 36 37 38
#include "planner-marshal.h"
#include "planner-format.h"
#include "planner-cell-renderer-date.h"
#include "planner-popup-entry.h"

enum {
	PROP_0,
	PROP_USE_CONSTRAINT,
};

Richard Hult's avatar
Richard Hult committed
39 40
static void     mcrd_init                    (PlannerCellRendererDate      *date);
static void     mcrd_class_init              (PlannerCellRendererDateClass *class);
Richard Hult's avatar
Richard Hult committed
41 42 43 44 45 46 47 48
static void     mcrd_set_property            (GObject                 *object,
					      guint                    param_id,
					      const GValue            *value,
					      GParamSpec              *pspec);
static void     mcrd_get_property            (GObject                 *object,
					      guint                    param_id,
					      GValue                  *value,
					      GParamSpec              *pspec);
49 50 51 52
static void     mcrd_today_clicked           (GtkWidget               *button,
					      PlannerCellRendererDate *cell);
static void     mcrd_selected_double_click   (GtkWidget               *calendar,
					      PlannerCellRendererDate *cell);
Richard Hult's avatar
Richard Hult committed
53
static void     mcrd_cancel_clicked          (GtkWidget               *popup_window,
Richard Hult's avatar
Richard Hult committed
54
					      PlannerCellRendererDate      *cell);
Richard Hult's avatar
Richard Hult committed
55
static void     mcrd_ok_clicked              (GtkWidget               *popup_window,
Richard Hult's avatar
Richard Hult committed
56
					      PlannerCellRendererDate      *cell);
Richard Hult's avatar
Richard Hult committed
57
static void     mcrd_day_selected            (GtkWidget               *popup_window,
Richard Hult's avatar
Richard Hult committed
58
					      PlannerCellRendererDate      *cell);
Richard Hult's avatar
Richard Hult committed
59
static void     mcrd_constraint_activated_cb (GtkWidget               *widget,
Richard Hult's avatar
Richard Hult committed
60
					      PlannerCellRendererDate      *cell);
Richard Hult's avatar
Richard Hult committed
61 62 63 64 65 66 67
GtkCellEditable *mcrd_start_editing          (GtkCellRenderer         *cell,
					      GdkEvent                *event,
					      GtkWidget               *widget,
					      const gchar             *path,
					      GdkRectangle            *background_area,
					      GdkRectangle            *cell_area,
					      GtkCellRendererState     flags);
Richard Hult's avatar
Richard Hult committed
68
static void     mcrd_show                    (PlannerCellRendererPopup     *cell,
Richard Hult's avatar
Richard Hult committed
69 70 71 72 73
					      const gchar             *path,
					      gint                     x1,
					      gint                     y1,
					      gint                     x2,
					      gint                     y2);
Richard Hult's avatar
Richard Hult committed
74
static void     mcrd_hide                    (PlannerCellRendererPopup     *cell);
Richard Hult's avatar
Richard Hult committed
75
static void     mcrd_setup_option_menu       (GtkWidget               *option_menu,
76
					      GCallback                func,
Richard Hult's avatar
Richard Hult committed
77 78 79 80
					      gpointer                 user_data,
					      gpointer                 str1, ...);


Richard Hult's avatar
Richard Hult committed
81
static PlannerCellRendererPopupClass *parent_class;
Richard Hult's avatar
Richard Hult committed
82 83 84 85 86

GType
planner_cell_renderer_date_get_type (void)
{
	static GType cell_text_type = 0;
87

Richard Hult's avatar
Richard Hult committed
88 89
	if (!cell_text_type) {
		static const GTypeInfo cell_text_info = {
Richard Hult's avatar
Richard Hult committed
90
			sizeof (PlannerCellRendererDateClass),
Richard Hult's avatar
Richard Hult committed
91 92 93 94 95
			NULL,		/* base_init */
			NULL,		/* base_finalize */
			(GClassInitFunc) mcrd_class_init,
			NULL,		/* class_finalize */
			NULL,		/* class_data */
Richard Hult's avatar
Richard Hult committed
96
			sizeof (PlannerCellRendererDate),
Richard Hult's avatar
Richard Hult committed
97 98 99
			0,              /* n_preallocs */
			(GInstanceInitFunc) mcrd_init,
		};
100

Richard Hult's avatar
Richard Hult committed
101 102
		cell_text_type = g_type_register_static (PLANNER_TYPE_CELL_RENDERER_POPUP,
							 "PlannerCellRendererDate",
Richard Hult's avatar
Richard Hult committed
103 104 105
							 &cell_text_info,
							 0);
	}
106

Richard Hult's avatar
Richard Hult committed
107 108 109 110
	return cell_text_type;
}

static void
Richard Hult's avatar
Richard Hult committed
111
mcrd_init (PlannerCellRendererDate *date)
Richard Hult's avatar
Richard Hult committed
112
{
Richard Hult's avatar
Richard Hult committed
113
	PlannerCellRendererPopup *popup;
114 115 116 117 118
	GtkWidget                *frame;
	GtkWidget                *vbox;
	GtkWidget                *hbox;
	GtkWidget                *bbox;
	GtkWidget                *button;
Richard Hult's avatar
Richard Hult committed
119

Richard Hult's avatar
Richard Hult committed
120
	popup = PLANNER_CELL_RENDERER_POPUP (date);
Richard Hult's avatar
Richard Hult committed
121 122 123 124 125

	frame = gtk_frame_new (NULL);
	gtk_container_add (GTK_CONTAINER (popup->popup_window), frame);
	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);

126
	vbox = gtk_vbox_new (FALSE, 6);
Richard Hult's avatar
Richard Hult committed
127
	gtk_container_add (GTK_CONTAINER (frame), vbox);
128
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
129

Richard Hult's avatar
Richard Hult committed
130 131 132 133 134
	date->calendar = gtk_calendar_new ();
	popup->focus_window = date->calendar;
	gtk_box_pack_start (GTK_BOX (vbox), date->calendar, TRUE, TRUE, 0);

	date->constraint_vbox = gtk_vbox_new (FALSE, 0);
135
	gtk_box_pack_start (GTK_BOX (vbox), date->constraint_vbox, FALSE, FALSE, 0);
136

137 138 139 140
	hbox = gtk_hbox_new (FALSE, 6);
	/* I18n: the verb "schedule" here. */
	gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("Schedule:")),
			    FALSE, FALSE, 0);
141

Richard Hult's avatar
Richard Hult committed
142 143 144 145 146
	date->option_menu = gtk_option_menu_new ();
	mcrd_setup_option_menu (date->option_menu,
				G_CALLBACK (mcrd_constraint_activated_cb),
				date,
				_("As soon as possible"), MRP_CONSTRAINT_ASAP,
147 148
				_("No earlier than"), MRP_CONSTRAINT_SNET,
				_("On fixed date"), MRP_CONSTRAINT_MSO,
Richard Hult's avatar
Richard Hult committed
149
				NULL);
150 151 152
	gtk_box_pack_end (GTK_BOX (hbox), date->option_menu, TRUE, TRUE, 0);

	gtk_box_pack_start (GTK_BOX (date->constraint_vbox), hbox, TRUE, TRUE, 0);
153

Richard Hult's avatar
Richard Hult committed
154 155
	hbox = gtk_hbox_new (FALSE, 0);
	gtk_box_pack_start (GTK_BOX (date->constraint_vbox), hbox, FALSE, FALSE, 0);
156

Richard Hult's avatar
Richard Hult committed
157
	bbox = gtk_hbutton_box_new ();
158
	gtk_box_set_spacing (GTK_BOX (bbox), 6);
Richard Hult's avatar
Richard Hult committed
159 160
	gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);

161 162 163 164 165
	date->today_button = gtk_button_new_with_label (_("Today"));
	gtk_container_add (GTK_CONTAINER (bbox), date->today_button);
	g_signal_connect (date->today_button, "clicked",
			  G_CALLBACK (mcrd_today_clicked),
			  date);
166

Richard Hult's avatar
Richard Hult committed
167 168 169 170 171 172 173
	button = gtk_button_new_with_label (_("Cancel"));
	gtk_container_add (GTK_CONTAINER (bbox), button);
	g_signal_connect (button,
			  "clicked",
			  G_CALLBACK (mcrd_cancel_clicked),
			  date);

174
	button = gtk_button_new_with_label (_("Select"));
Richard Hult's avatar
Richard Hult committed
175 176 177 178 179 180 181 182
	gtk_container_add (GTK_CONTAINER (bbox), button);
	g_signal_connect (button, "clicked",
			  G_CALLBACK (mcrd_ok_clicked),
			  date);

	g_signal_connect (date->calendar, "day-selected",
			  G_CALLBACK (mcrd_day_selected),
			  date);
183
	g_signal_connect (date->calendar, "day-selected-double-click",
184 185
			  G_CALLBACK (mcrd_selected_double_click),
			  date);
Richard Hult's avatar
Richard Hult committed
186 187 188 189 190

        gtk_widget_show_all (frame);
}

static void
Richard Hult's avatar
Richard Hult committed
191
mcrd_class_init (PlannerCellRendererDateClass *class)
Richard Hult's avatar
Richard Hult committed
192
{
Richard Hult's avatar
Richard Hult committed
193
	PlannerCellRendererPopupClass *popup_class;
194 195
	GtkCellRendererClass          *cell_class;
	GObjectClass                  *gobject_class;
Richard Hult's avatar
Richard Hult committed
196

Richard Hult's avatar
Richard Hult committed
197
	popup_class = PLANNER_CELL_RENDERER_POPUP_CLASS (class);
198
	cell_class = GTK_CELL_RENDERER_CLASS (class);
Richard Hult's avatar
Richard Hult committed
199
	parent_class = PLANNER_CELL_RENDERER_POPUP_CLASS (g_type_class_peek_parent (class));
Richard Hult's avatar
Richard Hult committed
200 201 202 203 204 205
	gobject_class = G_OBJECT_CLASS (class);

	gobject_class->set_property = mcrd_set_property;
	gobject_class->get_property = mcrd_get_property;

	cell_class->start_editing = mcrd_start_editing;
206

Richard Hult's avatar
Richard Hult committed
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
	popup_class->show_popup = mcrd_show;
	popup_class->hide_popup = mcrd_hide;

	g_object_class_install_property (
		gobject_class,
                 PROP_USE_CONSTRAINT,
                 g_param_spec_boolean ("use-constraint",
				       NULL,
				       NULL,
				       TRUE,
				       G_PARAM_READWRITE |
				       G_PARAM_CONSTRUCT_ONLY));
}

static void
mcrd_set_property (GObject      *object,
		   guint         param_id,
		   const GValue *value,
		   GParamSpec   *pspec)
{
Richard Hult's avatar
Richard Hult committed
227
	PlannerCellRendererDate *date;
Richard Hult's avatar
Richard Hult committed
228

Richard Hult's avatar
Richard Hult committed
229
	date = PLANNER_CELL_RENDERER_DATE (object);
230

Richard Hult's avatar
Richard Hult committed
231 232 233 234 235 236 237 238 239
	switch (param_id) {
	case PROP_USE_CONSTRAINT:
		date->use_constraint = g_value_get_boolean (value);

		if (date->use_constraint) {
			gtk_widget_show (date->constraint_vbox);
		} else {
			gtk_widget_hide (date->constraint_vbox);
		}
240 241 242 243

		gtk_widget_set_sensitive (date->calendar, date->use_constraint);
		gtk_widget_set_sensitive (date->today_button, date->use_constraint);

Richard Hult's avatar
Richard Hult committed
244 245 246 247 248 249 250 251 252 253 254 255 256
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
		break;
	}
}

static void
mcrd_get_property (GObject    *object,
		   guint       param_id,
		   GValue     *value,
		   GParamSpec *pspec)
{
Richard Hult's avatar
Richard Hult committed
257
	PlannerCellRendererDate *date;
Richard Hult's avatar
Richard Hult committed
258

Richard Hult's avatar
Richard Hult committed
259
	date = PLANNER_CELL_RENDERER_DATE (object);
260

Richard Hult's avatar
Richard Hult committed
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
	switch (param_id) {
	case PROP_USE_CONSTRAINT:
		g_value_set_boolean (value, date->use_constraint);
		break;

	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
		break;
	}
}

GtkCellEditable *
mcrd_start_editing (GtkCellRenderer      *cell,
		    GdkEvent             *event,
		    GtkWidget            *widget,
		    const gchar          *path,
		    GdkRectangle         *background_area,
		    GdkRectangle         *cell_area,
		    GtkCellRendererState  flags)
{
Richard Hult's avatar
Richard Hult committed
281
	PLANNER_CELL_RENDERER_POPUP (cell)->editing_canceled = TRUE;
282

Richard Hult's avatar
Richard Hult committed
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
	if (GTK_CELL_RENDERER_CLASS (parent_class)->start_editing) {
		return GTK_CELL_RENDERER_CLASS (parent_class)->start_editing (
							cell,
							event,
							widget,
							path,
							background_area,
							cell_area,
							flags);
	}

	return NULL;
}


static void
Richard Hult's avatar
Richard Hult committed
299
mcrd_hide (PlannerCellRendererPopup *cell)
Richard Hult's avatar
Richard Hult committed
300 301 302 303 304 305 306
{
	if (parent_class->hide_popup) {
		parent_class->hide_popup (cell);
	}
}

static void
Richard Hult's avatar
Richard Hult committed
307
mcrd_show (PlannerCellRendererPopup *cell,
308 309 310 311 312
	   const gchar              *path,
	   gint                      x1,
	   gint                      y1,
	   gint                      x2,
	   gint                      y2)
Richard Hult's avatar
Richard Hult committed
313
{
Richard Hult's avatar
Richard Hult committed
314
	PlannerCellRendererDate *date;
315 316 317 318 319
	gint                     year;
	gint                     month;
	gint                     day;
	gint                     index;
	gboolean                 sensitive;
Richard Hult's avatar
Richard Hult committed
320 321 322 323 324 325 326 327

	if (parent_class->show_popup) {
		parent_class->show_popup (cell,
					  path,
					  x1, y1,
					  x2, y2);
	}

Richard Hult's avatar
Richard Hult committed
328
	date = PLANNER_CELL_RENDERER_DATE (cell);
Richard Hult's avatar
Richard Hult committed
329 330

	mrp_time_decompose (date->time, &year, &month, &day, NULL, NULL, NULL);
331

Richard Hult's avatar
Richard Hult committed
332
	index = 0;
333

Richard Hult's avatar
Richard Hult committed
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
	switch (date->type) {
	case MRP_CONSTRAINT_ASAP:
		index = 0;
		break;
	case MRP_CONSTRAINT_SNET:
		index = 1;
		break;
	case MRP_CONSTRAINT_MSO:
		index = 2;
		break;
	default:
		g_assert_not_reached ();
	}

	sensitive = (!date->use_constraint ||
		     (date->type != MRP_CONSTRAINT_ASAP &&
		      date->type != MRP_CONSTRAINT_ALAP));
351

352 353
	gtk_widget_set_sensitive (date->calendar, sensitive);
	gtk_widget_set_sensitive (date->today_button, sensitive);
354

Richard Hult's avatar
Richard Hult committed
355 356 357 358 359
	gtk_calendar_clear_marks (GTK_CALENDAR (date->calendar));
	gtk_calendar_select_month (GTK_CALENDAR (date->calendar),
				   month - 1, year);
	gtk_calendar_select_day (GTK_CALENDAR (date->calendar), day);
	gtk_calendar_mark_day (GTK_CALENDAR (date->calendar), day);
360

Richard Hult's avatar
Richard Hult committed
361 362 363 364 365 366 367 368 369
	gtk_option_menu_set_history (GTK_OPTION_MENU (date->option_menu),
				     index);
}

GtkCellRenderer *
planner_cell_renderer_date_new (gboolean use_constraint)
{
	GObject *cell;

Richard Hult's avatar
Richard Hult committed
370
	cell = g_object_new (PLANNER_TYPE_CELL_RENDERER_DATE,
Richard Hult's avatar
Richard Hult committed
371 372
			     "use-constraint", use_constraint,
			     NULL);
373

Richard Hult's avatar
Richard Hult committed
374 375 376 377
	return GTK_CELL_RENDERER (cell);
}

static void
378 379 380 381 382
mcrd_today_clicked (GtkWidget               *button,
		    PlannerCellRendererDate *cell)
{
	mrptime today;
	gint    year, month, day;
383

384 385 386 387
	today = mrp_time_current_time ();

	mrp_time_decompose (today, &year, &month, &day,
			    NULL, NULL, NULL);
388

389 390 391 392 393 394 395 396 397 398 399 400
	gtk_calendar_clear_marks (GTK_CALENDAR (cell->calendar));
	gtk_calendar_select_month (GTK_CALENDAR (cell->calendar),
				   month - 1, year);
	gtk_calendar_select_day (GTK_CALENDAR (cell->calendar), day);
	gtk_calendar_mark_day (GTK_CALENDAR (cell->calendar), day);
}

static void
mcrd_selected_double_click (GtkWidget               *calendar,
			    PlannerCellRendererDate *cell)
{
	PlannerCellRendererPopup *popup;
401

402 403 404 405 406 407 408
	popup = PLANNER_CELL_RENDERER_POPUP (cell);

	mcrd_ok_clicked (popup->popup_window, cell);
}

static void
mcrd_cancel_clicked (GtkWidget               *popup_window,
Richard Hult's avatar
Richard Hult committed
409
		     PlannerCellRendererDate *cell)
Richard Hult's avatar
Richard Hult committed
410
{
Richard Hult's avatar
Richard Hult committed
411
	PlannerCellRendererPopup *popup;
412

Richard Hult's avatar
Richard Hult committed
413
	popup = PLANNER_CELL_RENDERER_POPUP (cell);
Richard Hult's avatar
Richard Hult committed
414 415 416 417 418 419

	popup->editing_canceled = TRUE;
	planner_cell_renderer_popup_hide (popup);
}

static void
420
mcrd_ok_clicked (GtkWidget               *popup_window,
Richard Hult's avatar
Richard Hult committed
421
		 PlannerCellRendererDate *cell)
Richard Hult's avatar
Richard Hult committed
422
{
Richard Hult's avatar
Richard Hult committed
423
	PlannerCellRendererPopup *popup;
424

Richard Hult's avatar
Richard Hult committed
425
	popup = PLANNER_CELL_RENDERER_POPUP (cell);
Richard Hult's avatar
Richard Hult committed
426 427 428 429 430 431 432 433

	mcrd_day_selected (popup_window, cell);

	popup->editing_canceled = FALSE;
	planner_cell_renderer_popup_hide (popup);
}

static void
434
mcrd_day_selected (GtkWidget               *popup_window,
Richard Hult's avatar
Richard Hult committed
435
		   PlannerCellRendererDate *cell)
Richard Hult's avatar
Richard Hult committed
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
{
	guint    year;
	guint    month;
	guint    day;
	mrptime  t;
	gchar   *str;

	gtk_calendar_get_date (GTK_CALENDAR (cell->calendar),
			       &year,
			       &month,
			       &day);

	t = mrp_time_compose (year, month + 1, day, 0, 0, 0);

	cell->time = t;

	str = planner_format_date (t);
	planner_popup_entry_set_text (
Richard Hult's avatar
Richard Hult committed
454
		PLANNER_POPUP_ENTRY (PLANNER_CELL_RENDERER_POPUP (cell)->editable), str);
Richard Hult's avatar
Richard Hult committed
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
	g_free (str);
}

static gboolean
mcrd_grab_on_window (GdkWindow *window,
		     guint32    activate_time)
{
	if ((gdk_pointer_grab (window, TRUE,
			       GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
			       GDK_POINTER_MOTION_MASK,
			       NULL, NULL, activate_time) == 0)) {
		if (gdk_keyboard_grab (window, TRUE,
			       activate_time) == 0)
			return TRUE;
		else {
			gdk_pointer_ungrab (activate_time);
			return FALSE;
		}
	}

	return FALSE;
}

static void
479
mcrd_constraint_activated_cb (GtkWidget               *widget,
Richard Hult's avatar
Richard Hult committed
480
			      PlannerCellRendererDate *cell)
Richard Hult's avatar
Richard Hult committed
481 482 483
{
	gpointer data;
	gboolean sensitive;
484

Richard Hult's avatar
Richard Hult committed
485 486 487 488 489 490 491
	data = g_object_get_data (G_OBJECT (widget), "data");

	cell->type = GPOINTER_TO_INT (data);

	sensitive = (!cell->use_constraint ||
		     (cell->type != MRP_CONSTRAINT_ASAP &&
		      cell->type != MRP_CONSTRAINT_ALAP));
492

Richard Hult's avatar
Richard Hult committed
493
	gtk_widget_set_sensitive (cell->calendar, sensitive);
494
	gtk_widget_set_sensitive (cell->today_button, sensitive);
495

Richard Hult's avatar
Richard Hult committed
496 497 498 499
	/* A bit hackish. Grab focus on the popup window again when the
	 * optionmenu is activated, since focus is transferred to the optionmenu
	 * when it's popped up.
	 */
Richard Hult's avatar
Richard Hult committed
500
	mcrd_grab_on_window (PLANNER_CELL_RENDERER_POPUP (cell)->popup_window->window,
Richard Hult's avatar
Richard Hult committed
501 502 503 504 505 506 507 508
			     gtk_get_current_event_time ());
}

/* Utility function to use before optionmenus work with libglade again.
 */

static void
mcrd_setup_option_menu (GtkWidget     *option_menu,
509
			GCallback      func,
Richard Hult's avatar
Richard Hult committed
510 511 512 513 514 515 516 517 518 519 520 521 522
			gpointer       user_data,
			gpointer       str1, ...)
{
	GtkWidget *menu, *menu_item;
	gint       i;
	va_list    args;
	gpointer   str;
	gint       type;

       	menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (option_menu));
	if (menu) {
		gtk_widget_destroy (menu);
	}
523

Richard Hult's avatar
Richard Hult committed
524 525 526 527 528 529
	menu = gtk_menu_new ();

	va_start (args, str1);
	for (str = str1, i = 0; str != NULL; str = va_arg (args, gpointer), i++) {
		menu_item = gtk_menu_item_new_with_label (str);
		gtk_widget_show (menu_item);
530
		gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
Richard Hult's avatar
Richard Hult committed
531 532

		type = va_arg (args, gint);
533

Richard Hult's avatar
Richard Hult committed
534 535 536
		g_object_set_data (G_OBJECT (menu_item),
				   "data",
				   GINT_TO_POINTER (type));
537
		g_signal_connect (G_OBJECT (menu_item),
Richard Hult's avatar
Richard Hult committed
538 539 540 541 542 543 544 545 546 547
				    "activate",
				    func,
				    user_data);
	}
	va_end (args);

	gtk_widget_show (menu);
	gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
}