/* This is -*- C -*- */ /* $Id: guppi-data-select.c,v 1.13 2002/01/19 02:45:18 trow Exp $ */ /* * guppi-data-select.c * * Copyright (C) 2000 EMC Capital Management, Inc. * * Developed by Jon Trowbridge and * Havoc Pennington . * * 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 Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include #include "guppi-data-select.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "guppi-data-popup.h" static GtkObjectClass *parent_class = NULL; enum { ARG_0 }; enum { SELECTED_DATA, LAST_SIGNAL }; static guint sel_signals[LAST_SIGNAL] = { 0 }; static void guppi_data_select_get_arg (GtkObject * obj, GtkArg * arg, guint arg_id) { switch (arg_id) { default: break; }; } static void guppi_data_select_set_arg (GtkObject * obj, GtkArg * arg, guint arg_id) { switch (arg_id) { default: break; }; } static void guppi_data_select_destroy (GtkObject * obj) { if (parent_class->destroy) parent_class->destroy (obj); } static void guppi_data_select_finalize (GtkObject * obj) { guppi_unref0 (GUPPI_DATA_SELECT (obj)->data); guppi_free (GUPPI_DATA_SELECT (obj)->empty_label); if (parent_class->finalize) parent_class->finalize (obj); } /***************************************************************************/ static void drag_data_received (GtkWidget * w, GdkDragContext * context, gint x, gint y, GtkSelectionData * selection_data, guint info, guint time) { GuppiData *data; g_return_if_fail (w != NULL && GUPPI_IS_DATA_SELECT (w)); data = *(GuppiData **) selection_data->data; guppi_data_select_set_selected_data (GUPPI_DATA_SELECT (w), data); } static void popup_cb (GuppiDataPopup * popup, GuppiData * data, GuppiDataSelect * sel) { guppi_data_select_set_selected_data (sel, data); } /***************************************************************************/ static void guppi_data_select_class_init (GuppiDataSelectClass * klass) { GtkObjectClass *object_class = (GtkObjectClass *) klass; GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); parent_class = gtk_type_class (GTK_TYPE_EVENT_BOX); object_class->get_arg = guppi_data_select_get_arg; object_class->set_arg = guppi_data_select_set_arg; object_class->destroy = guppi_data_select_destroy; object_class->finalize = guppi_data_select_finalize; widget_class->drag_data_received = drag_data_received; sel_signals[SELECTED_DATA] = gtk_signal_new ("selected_data", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GuppiDataSelectClass, selected_data), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_POINTER); gtk_object_class_add_signals (object_class, sel_signals, LAST_SIGNAL); } static void guppi_data_select_init (GuppiDataSelect * obj) { obj->empty_label = guppi_strdup (_("(none)")); } GtkType guppi_data_select_get_type (void) { static GtkType guppi_data_select_type = 0; if (!guppi_data_select_type) { static const GtkTypeInfo guppi_data_select_info = { "GuppiDataSelect", sizeof (GuppiDataSelect), sizeof (GuppiDataSelectClass), (GtkClassInitFunc) guppi_data_select_class_init, (GtkObjectInitFunc) guppi_data_select_init, NULL, NULL, (GtkClassInitFunc) NULL }; guppi_data_select_type = gtk_type_unique (GTK_TYPE_EVENT_BOX, &guppi_data_select_info); } return guppi_data_select_type; } void guppi_data_select_construct (GuppiDataSelect * sel) { GtkWidget *frame; GtkWidget *w; GtkWidget *pix; GtkWidget *hbox; static GtkTargetEntry drag_types[] = { {"guppi/data", 0, 0} }; static gint n_drag_types = sizeof (drag_types) / sizeof (drag_types[0]); g_return_if_fail (sel != NULL && GUPPI_IS_DATA_SELECT (sel)); g_return_if_fail (sel->label == NULL); /* check for previous construction */ hbox = gtk_hbox_new (FALSE, 2); gtk_widget_show (hbox); gtk_container_add (GTK_CONTAINER (sel), hbox); frame = gtk_frame_new (NULL); w = gtk_label_new (sel->empty_label); gtk_container_add (GTK_CONTAINER (frame), w); gtk_widget_show_all (frame); gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 1); sel->label = GTK_LABEL (w); sel->popup = w = guppi_data_popup_new (); /* use default message for "none" */ guppi_data_popup_allow_none (GUPPI_DATA_POPUP (w), NULL); if (sel->type_fn) guppi_data_popup_set_allowed_type_fn (GUPPI_DATA_POPUP (w), sel->type_fn, sel->user_data); else guppi_data_popup_set_allowed_type (GUPPI_DATA_POPUP (w), sel->allowed_type); pix = gnome_stock_new_with_icon (GNOME_STOCK_MENU_FORWARD); gtk_container_add (GTK_CONTAINER (w), pix); gtk_box_pack_end (GTK_BOX (hbox), w, FALSE, FALSE, 1); gtk_widget_show_all (w); gtk_signal_connect (GTK_OBJECT (w), "selected_data", GTK_SIGNAL_FUNC (popup_cb), GTK_OBJECT (sel)); gtk_drag_dest_set (GTK_WIDGET (sel), GTK_DEST_DEFAULT_ALL, drag_types, n_drag_types, GDK_ACTION_COPY); } GtkWidget * guppi_data_select_new (void) { return guppi_data_select_new_by_type (0); } GtkWidget * guppi_data_select_new_by_type (GtkType type) { GuppiDataSelect *sel = GUPPI_DATA_SELECT (guppi_type_new (guppi_data_select_get_type ())); sel->allowed_type = type; guppi_data_select_construct (sel); return GTK_WIDGET (sel); } GtkWidget * guppi_data_select_new_by_type_fn (gboolean (*type_fn)(GtkType, gpointer), gpointer user_data) { GuppiDataSelect *sel; g_return_val_if_fail (type_fn, NULL); sel = GUPPI_DATA_SELECT (guppi_type_new (guppi_data_select_get_type ())); sel->type_fn = type_fn; sel->user_data = user_data; guppi_data_select_construct (sel); return GTK_WIDGET (sel); } void guppi_data_select_set_empty_label (GuppiDataSelect * sel, const gchar * txt) { g_return_if_fail (sel != NULL && GUPPI_IS_DATA_SELECT (sel)); guppi_free (sel->empty_label); sel->empty_label = guppi_strdup (txt); if (sel->label && sel->data == NULL) gtk_label_set_text (sel->label, sel->empty_label); } void guppi_data_select_set_allowed_type (GuppiDataSelect * sel, GtkType type) { g_return_if_fail (sel && GUPPI_IS_DATA_SELECT (sel)); sel->allowed_type = type; sel->type_fn = NULL; sel->user_data = NULL; guppi_data_popup_set_allowed_type (GUPPI_DATA_POPUP (sel->popup), type); } void guppi_data_select_set_allowed_type_fn (GuppiDataSelect * sel, gboolean (*fn)(GtkType, gpointer), gpointer user_data) { g_return_if_fail (sel && GUPPI_IS_DATA_SELECT (sel)); sel->allowed_type = 0; sel->type_fn = fn; sel->user_data = user_data; guppi_data_popup_set_allowed_type_fn (GUPPI_DATA_POPUP (sel->popup), fn, user_data); } void guppi_data_select_set_allow_all_types (GuppiDataSelect * sel) { guppi_data_select_set_allowed_type (sel, (GtkType)0); } gboolean guppi_data_select_allowed_type (GuppiDataSelect * sel, GtkType type) { g_return_val_if_fail (sel != NULL && GUPPI_IS_DATA_SELECT (sel), FALSE); if (sel->type_fn) return sel->type_fn (type, sel->user_data); else if (sel->allowed_type == 0) return TRUE; else return gtk_type_is_a (type, sel->allowed_type); } gboolean guppi_data_select_allowed_data (GuppiDataSelect * sel, GuppiData * d) { g_return_val_if_fail (sel != NULL && GUPPI_IS_DATA_SELECT (sel), FALSE); g_return_val_if_fail (d == NULL || GUPPI_IS_DATA (d), FALSE); return d == NULL || guppi_data_select_allowed_type (sel, GTK_OBJECT_TYPE (d)); } GuppiData * guppi_data_select_get_selected_data (GuppiDataSelect * sel) { g_return_val_if_fail (sel != NULL && GUPPI_IS_DATA_SELECT (sel), NULL); return sel->data; } void guppi_data_select_set_selected_data (GuppiDataSelect * sel, GuppiData * d) { g_return_if_fail (sel != NULL && GUPPI_IS_DATA_SELECT (sel)); g_return_if_fail (d == NULL || GUPPI_IS_DATA (d)); if (!guppi_data_select_allowed_data (sel, d)) return; if (sel->data != d) { guppi_refcounting_assign (sel->data, d); gtk_label_set_text (sel->label, d ? guppi_data_get_label (d) : sel->empty_label); gtk_signal_emit (GTK_OBJECT (sel), sel_signals[SELECTED_DATA], d); } } GtkWidget * guppi_data_select_glade_custom_func (gchar * name, gchar * type_restriction, gchar * label, gint d2, gint d3) { GtkType type = (GtkType) 0; GtkWidget *w; if (type_restriction != NULL) { type = gtk_type_from_name (type_restriction); if (strcmp (type_restriction, gtk_type_name (type))) { g_warning ("Failed to find type %s, got %d (%s)", type_restriction, type, gtk_type_name (type)); } } w = guppi_data_select_new_by_type (type); guppi_data_select_set_empty_label (GUPPI_DATA_SELECT (w), label); return w; } /* $Id: guppi-data-select.c,v 1.13 2002/01/19 02:45:18 trow Exp $ */