/* 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 <trow@gnu.org> and
* Havoc Pennington <hp@pobox.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 Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
#include <config.h>
#include "guppi-data-select.h"
#include <string.h>
#include <gtk/gtksignal.h>
#include <gtk/gtkselection.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtkframe.h>
#include <gtk/gtkdnd.h>
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-config.h>
#include <libgnome/gnome-i18n.h>
#include <libgnomeui/gnome-stock.h>
#include <guppi-convenient.h>
#include <guppi-debug.h>
#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 $ */
syntax highlighted by Code2HTML, v. 0.9.1