From 81724738fc6c8a41485a2dcfc4671f10c47cbc1c Mon Sep 17 00:00:00 2001 From: Ettore Perazzoli Date: Mon, 1 Dec 2003 02:48:53 +0000 Subject: New test. * test-source-option-menu.c: New test. * e-source-option-menu.h: New. * e-source-option-menu.c: New. svn path=/trunk/; revision=23511 --- widgets/misc/ChangeLog | 7 + widgets/misc/Makefile.am | 16 +- widgets/misc/e-source-option-menu.c | 280 +++++++++++++++++++++++++++++++++ widgets/misc/e-source-option-menu.h | 64 ++++++++ widgets/misc/test-source-option-menu.c | 78 +++++++++ 5 files changed, 444 insertions(+), 1 deletion(-) create mode 100644 widgets/misc/e-source-option-menu.c create mode 100644 widgets/misc/e-source-option-menu.h create mode 100644 widgets/misc/test-source-option-menu.c (limited to 'widgets') diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index 155a5890b3..15a2bee117 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,10 @@ +2003-11-30 Ettore Perazzoli + + * test-source-option-menu.c: New test. + + * e-source-option-menu.h: New. + * e-source-option-menu.c: New. + 2003-11-17 Charles Zhang * e-search-bar.c(add_button): allow new lable with mnemonic diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 587962f220..637fe0934d 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -31,6 +31,7 @@ widgetsinclude_HEADERS = \ e-map.h \ e-multi-config-dialog.h \ e-search-bar.h \ + e-source-option-menu.h \ e-source-selector.h \ e-title-bar.h \ e-url-entry.h @@ -53,6 +54,7 @@ libemiscwidgets_la_SOURCES = \ e-map.c \ e-multi-config-dialog.c \ e-search-bar.c \ + e-source-option-menu.c \ e-source-selector.c \ e-title-bar.c \ e-url-entry.c @@ -75,6 +77,7 @@ noinst_PROGRAMS = \ test-dateedit \ test-dropdown-button \ test-multi-config-dialog \ + test-source-option-menu \ test-source-selector \ test-title-bar @@ -126,7 +129,7 @@ test_title_bar_LDADD = \ $(GNOME_FULL_LIBS) -# test-source-list-selector +# test-source-selector test_source_selector_SOURCES = \ test-source-selector.c @@ -137,6 +140,17 @@ test_source_selector_LDADD = \ $(SOURCE_SEL_LIBS) +# test-source-option-menu + +test_source_option_menu_SOURCES = \ + test-source-option-menu.c + +test_source_option_menu_LDADD = \ + ../../e-util/libeutil.la \ + ./libemiscwidgets.la \ + $(SOURCE_SEL_LIBS) + + BUILT_SOURCES = $(MARSHAL_GENERATED) CLEANFILES = $(BUILT_SOURCES) diff --git a/widgets/misc/e-source-option-menu.c b/widgets/misc/e-source-option-menu.c new file mode 100644 index 0000000000..3904a20dba --- /dev/null +++ b/widgets/misc/e-source-option-menu.c @@ -0,0 +1,280 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-source-option-menu.c + * + * Copyright (C) 2003 Novell, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ettore Perazzoli + */ + +#include + +#include "e-source-option-menu.h" + +#include + +#include +#include + + +#define PARENT_TYPE gtk_option_menu_get_type () +static GtkOptionMenuClass *parent_class = NULL; + + +/* We set data on each menu item specifying the corresponding ESource using this key. */ +#define MENU_ITEM_SOURCE_DATA_ID "ESourceOptionMenu:Source" + + +struct _ESourceOptionMenuPrivate { + ESourceList *source_list; + + ESource *selected_source; +}; + + +/* Selecting a source. */ + +typedef struct { + ESourceOptionMenu *option_menu; + int i; +} ForeachMenuItemData; + +static void +select_source_foreach_menu_item (GtkWidget *menu_item, + ForeachMenuItemData *data) +{ + ESource *source = gtk_object_get_data (GTK_OBJECT (menu_item), MENU_ITEM_SOURCE_DATA_ID); + + if (source == data->option_menu->priv->selected_source) + gtk_option_menu_set_history (GTK_OPTION_MENU (data->option_menu), data->i); + + data->i ++; +} + +static void +select_source (ESourceOptionMenu *menu, + ESource *source) +{ + if (menu->priv->selected_source != NULL) + g_object_unref (menu->priv->selected_source); + menu->priv->selected_source = source; + + if (source != NULL) { + ForeachMenuItemData *foreach_data = g_new0 (ForeachMenuItemData, 1); + + foreach_data->option_menu = menu; + + gtk_container_foreach (GTK_CONTAINER (GTK_OPTION_MENU (menu)->menu), + (GtkCallback) select_source_foreach_menu_item, foreach_data); + + g_free (foreach_data); + g_object_ref (source); + } +} + + +/* Menu callback. */ + +static void +menu_item_activate_callback (GtkMenuItem *menu_item, + ESourceOptionMenu *option_menu) +{ + ESource *source = gtk_object_get_data (GTK_OBJECT (menu_item), MENU_ITEM_SOURCE_DATA_ID); + + if (source != NULL) + select_source (option_menu, source); +} + + +/* Functions to keep the menu in sync with the ESourceList. */ + +static void +populate (ESourceOptionMenu *option_menu) +{ + GtkWidget *menu = gtk_menu_new (); + GSList *groups = e_source_list_peek_groups (option_menu->priv->source_list); + GSList *p; + ESource *first_source = NULL; + int first_source_item = -1; + int selected_item = -1; + int i; + + i = 0; + for (p = groups; p != NULL; p = p->next) { + ESourceGroup *group = E_SOURCE_GROUP (p->data); + GtkWidget *item = gtk_menu_item_new_with_label (e_source_group_peek_name (group)); + GSList *q; + + gtk_widget_set_sensitive (item, FALSE); + gtk_widget_show (item); + gtk_menu_append (GTK_MENU (menu), item); + + i ++; + + for (q = e_source_group_peek_sources (group); q != NULL; q = q->next) { + ESource *source = E_SOURCE (q->data); + char *label = g_strconcat (" ", e_source_peek_name (source), NULL); + GtkWidget *item = gtk_menu_item_new_with_label (label); + + gtk_object_set_data_full (GTK_OBJECT (item), MENU_ITEM_SOURCE_DATA_ID, source, + (GtkDestroyNotify) g_object_unref); + g_object_ref (source); + + g_signal_connect (item, "activate", G_CALLBACK (menu_item_activate_callback), option_menu); + + gtk_widget_show (item); + gtk_menu_append (GTK_MENU (menu), item); + + if (first_source_item == -1) { + first_source_item = i; + first_source = source; + } + + if (source == option_menu->priv->selected_source) + selected_item = i; + + i ++; + } + } + + gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu); + + if (selected_item != -1) { + gtk_option_menu_set_history (GTK_OPTION_MENU (option_menu), selected_item); + } else { + if (option_menu->priv->selected_source != NULL) + g_object_unref (option_menu->priv->selected_source); + option_menu->priv->selected_source = first_source; + if (option_menu->priv->selected_source != NULL) + g_object_ref (option_menu->priv->selected_source); + + gtk_option_menu_set_history (GTK_OPTION_MENU (option_menu), first_source_item); + } +} + + +static void +source_list_changed_callback (ESourceList *list, + ESourceOptionMenu *menu) +{ + populate (menu); +} + +static void +connect_signals (ESourceOptionMenu *menu) +{ + g_signal_connect_object (menu->priv->source_list, "changed", + G_CALLBACK (source_list_changed_callback), G_OBJECT (menu), 0); +} + + +/* GObject methods. */ + +static void +impl_dispose (GObject *object) +{ + ESourceOptionMenuPrivate *priv = E_SOURCE_OPTION_MENU (object)->priv; + + if (priv->source_list != NULL) { + g_object_unref (priv->source_list); + priv->source_list = NULL; + } + + if (priv->selected_source != NULL) { + g_object_unref (priv->selected_source); + priv->selected_source = NULL; + } + + (* G_OBJECT_CLASS (parent_class)->dispose) (object); +} + +static void +impl_finalize (GObject *object) +{ + ESourceOptionMenuPrivate *priv = E_SOURCE_OPTION_MENU (object)->priv; + + g_free (priv); + + (* G_OBJECT_CLASS (parent_class)->finalize) (object); +} + + +/* Initialization. */ + +static void +class_init (ESourceOptionMenuClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->dispose = impl_dispose; + object_class->finalize = impl_finalize; + + parent_class = g_type_class_peek_parent (class); +} + +static void +init (ESourceOptionMenu *source_option_menu) +{ + ESourceOptionMenuPrivate *priv; + + priv = g_new0 (ESourceOptionMenuPrivate, 1); + + source_option_menu->priv = priv; +} + + +/* Public methods. */ + +GtkWidget * +e_source_option_menu_new (ESourceList *source_list) +{ + ESourceOptionMenu *menu; + + g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), NULL); + + menu = g_object_new (e_source_option_menu_get_type (), NULL); + + menu->priv->source_list = source_list; + g_object_ref (source_list); + + connect_signals (menu); + populate (menu); + + return GTK_WIDGET (menu); +} + + +ESource * +e_source_option_menu_peek_selected (ESourceOptionMenu *menu) +{ + g_return_val_if_fail (E_IS_SOURCE_OPTION_MENU (menu), NULL); + + return menu->priv->selected_source; +} + + +void +e_source_option_menu_select (ESourceOptionMenu *menu, + ESource *source) +{ + g_return_if_fail (E_IS_SOURCE_OPTION_MENU (menu)); + g_return_if_fail (E_IS_SOURCE (source)); + + select_source (menu, source); +} + + +E_MAKE_TYPE (e_source_option_menu, "ESourceOptionMenu", ESourceOptionMenu, class_init, init, PARENT_TYPE) diff --git a/widgets/misc/e-source-option-menu.h b/widgets/misc/e-source-option-menu.h new file mode 100644 index 0000000000..74a85d629e --- /dev/null +++ b/widgets/misc/e-source-option-menu.h @@ -0,0 +1,64 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-source-option-menu.h + * + * Copyright (C) 2003 Novell, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ettore Perazzoli + */ + +#ifndef _E_SOURCE_OPTION_MENU_H_ +#define _E_SOURCE_OPTION_MENU_H_ + +#include + +#include + +#define E_TYPE_SOURCE_OPTION_MENU (e_source_option_menu_get_type ()) +#define E_SOURCE_OPTION_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SOURCE_OPTION_MENU, ESourceOptionMenu)) +#define E_SOURCE_OPTION_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SOURCE_OPTION_MENU, ESourceOptionMenuClass)) +#define E_IS_SOURCE_OPTION_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SOURCE_OPTION_MENU)) +#define E_IS_SOURCE_OPTION_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_SOURCE_OPTION_MENU)) + + +typedef struct _ESourceOptionMenu ESourceOptionMenu; +typedef struct _ESourceOptionMenuPrivate ESourceOptionMenuPrivate; +typedef struct _ESourceOptionMenuClass ESourceOptionMenuClass; + +struct _ESourceOptionMenu { + GtkOptionMenu parent; + + ESourceOptionMenuPrivate *priv; +}; + +struct _ESourceOptionMenuClass { + GtkOptionMenuClass parent_class; + + void (* source_selected) (ESourceOptionMenu *menu, + ESource *selected_source); +}; + + +GType e_source_option_menu_get_type (void); + +GtkWidget *e_source_option_menu_new (ESourceList *list); + +ESource *e_source_option_menu_peek_selected (ESourceOptionMenu *menu); +void e_source_option_menu_select (ESourceOptionMenu *menu, + ESource *source); + + +#endif /* _E_SOURCE_OPTION_MENU_H_ */ diff --git a/widgets/misc/test-source-option-menu.c b/widgets/misc/test-source-option-menu.c new file mode 100644 index 0000000000..91a7941e29 --- /dev/null +++ b/widgets/misc/test-source-option-menu.c @@ -0,0 +1,78 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-source-option-menu.c - Test for ESourceOptionMenu. + * + * Copyright (C) 2003 Novell, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ettore Perazzoli + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + + +#include "e-source-option-menu.h" + +#include +#include + +#include + + +static int +on_idle_create_widget (const char *gconf_path) +{ + GtkWidget *window; + GtkWidget *option_menu; + ESourceList *source_list; + GConfClient *gconf_client; + + gconf_client = gconf_client_get_default (); + source_list = e_source_list_new_for_gconf (gconf_client, gconf_path); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + option_menu = e_source_option_menu_new (source_list); + + gtk_container_add (GTK_CONTAINER (window), option_menu); + gtk_widget_show_all (window); + + g_object_unref (gconf_client); + g_object_unref (source_list); + + return FALSE; +} + + +int +main (int argc, char **argv) +{ + GnomeProgram *program; + const char *gconf_path; + + program = gnome_program_init ("test-source-list", "0.0", LIBGNOMEUI_MODULE, argc, argv, NULL); + + if (argc < 2) + gconf_path = "/apps/evolution/calendar/sources"; + else + gconf_path = argv [1]; + + g_idle_add ((GSourceFunc) on_idle_create_widget, (void *) gconf_path); + + gtk_main (); + + return 0; +} -- cgit