#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gimp-print/gimp-print-intl-internal.h>
#include <gimp-print-ui/gimp-print-ui.h>
#include "gimp-print-ui-internal.h"
#include <stdio.h>
#include <string.h>
static void default_errfunc(void *data, const char *buffer, size_t bytes);
static gchar *image_filename;
static stp_outfunc_t the_errfunc = default_errfunc;
static void *the_errdata = NULL;
static get_thumbnail_func_t thumbnail_func;
static void *thumbnail_private_data;
static gint
dialog_delete_callback (GtkWidget *widget,
GdkEvent *event,
gpointer data)
{
GtkSignalFunc cancel_callback;
GtkWidget *cancel_widget;
cancel_callback =
(GtkSignalFunc) gtk_object_get_data (GTK_OBJECT (widget),
"dialog_cancel_callback");
cancel_widget =
(GtkWidget*) gtk_object_get_data (GTK_OBJECT (widget),
"dialog_cancel_widget");
if (cancel_callback)
(* cancel_callback) (cancel_widget, data);
return TRUE;
}
static void
dialog_create_action_areav (GtkDialog *dialog,
va_list args)
{
GtkWidget *hbbox = NULL;
GtkWidget *button;
const gchar *label;
GtkSignalFunc callback;
gpointer data;
GtkObject *slot_object;
GtkWidget **widget_ptr;
gboolean default_action;
gboolean connect_delete;
gboolean delete_connected = FALSE;
g_return_if_fail (dialog != NULL);
g_return_if_fail (GTK_IS_DIALOG (dialog));
label = va_arg (args, const gchar *);
if (label)
{
gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 2);
gtk_box_set_homogeneous (GTK_BOX (dialog->action_area), FALSE);
hbbox = gtk_hbutton_box_new ();
gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbbox), 4);
gtk_box_pack_end (GTK_BOX (dialog->action_area), hbbox, FALSE, FALSE, 0);
gtk_widget_show (hbbox);
}
while (label)
{
callback = va_arg (args, GtkSignalFunc);
data = va_arg (args, gpointer);
slot_object = va_arg (args, GtkObject *);
widget_ptr = va_arg (args, GtkWidget **);
default_action = va_arg (args, gboolean);
connect_delete = va_arg (args, gboolean);
button = gtk_button_new_with_label (label);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_box_pack_start (GTK_BOX (hbbox), button, FALSE, FALSE, 0);
if (slot_object == (GtkObject *) 1)
slot_object = GTK_OBJECT (dialog);
if (data == NULL)
data = dialog;
if (callback)
{
if (slot_object)
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (callback),
slot_object);
else
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (callback),
data);
}
if (widget_ptr)
*widget_ptr = button;
if (connect_delete && callback && !delete_connected)
{
gtk_object_set_data (GTK_OBJECT (dialog),
"dialog_cancel_callback",
(gpointer) callback);
gtk_object_set_data (GTK_OBJECT (dialog),
"dialog_cancel_widget",
slot_object ? slot_object : GTK_OBJECT (button));
gtk_signal_connect (GTK_OBJECT (dialog), "delete_event",
GTK_SIGNAL_FUNC (dialog_delete_callback),
data);
delete_connected = TRUE;
}
if (default_action)
gtk_widget_grab_default (button);
gtk_widget_show (button);
label = va_arg (args, gchar *);
}
}
GtkWidget *
stpui_dialog_new (const gchar *title,
const gchar *wmclass_name,
GtkWindowPosition position,
gint allow_shrink,
gint allow_grow,
gint auto_shrink,
...)
{
GtkWidget *dialog;
va_list args;
va_start (args, auto_shrink);
g_return_val_if_fail (title != NULL, NULL);
g_return_val_if_fail (wmclass_name != NULL, NULL);
dialog = gtk_dialog_new ();
gtk_window_set_title (GTK_WINDOW (dialog), title);
gtk_window_set_wmclass (GTK_WINDOW (dialog), wmclass_name, "Gimp");
gtk_window_set_position (GTK_WINDOW (dialog), position);
gtk_window_set_policy (GTK_WINDOW (dialog),
allow_shrink, allow_grow, auto_shrink);
dialog_create_action_areav (GTK_DIALOG (dialog), args);
va_end (args);
return dialog;
}
GtkWidget *
stpui_option_menu_new(gboolean menu_only,
...)
{
GtkWidget *menu;
GtkWidget *menuitem;
const gchar *label;
GtkSignalFunc callback;
gpointer data;
gpointer user_data;
GtkWidget **widget_ptr;
gboolean active;
va_list args;
gint i;
gint initial_index;
menu = gtk_menu_new ();
initial_index = 0;
va_start (args, menu_only);
label = va_arg (args, const gchar *);
for (i = 0; label; i++)
{
callback = va_arg (args, GtkSignalFunc);
data = va_arg (args, gpointer);
user_data = va_arg (args, gpointer);
widget_ptr = va_arg (args, GtkWidget **);
active = va_arg (args, gboolean);
if (strcmp (label, "---"))
{
menuitem = gtk_menu_item_new_with_label (label);
gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
callback,
data);
if (user_data)
gtk_object_set_user_data (GTK_OBJECT (menuitem), user_data);
}
else
{
menuitem = gtk_menu_item_new ();
gtk_widget_set_sensitive (menuitem, FALSE);
}
gtk_menu_append (GTK_MENU (menu), menuitem);
if (widget_ptr)
*widget_ptr = menuitem;
gtk_widget_show (menuitem);
if (active)
initial_index = i;
label = va_arg (args, const gchar *);
}
va_end (args);
if (! menu_only)
{
GtkWidget *optionmenu;
optionmenu = gtk_option_menu_new ();
gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);
gtk_option_menu_set_history (GTK_OPTION_MENU (optionmenu), initial_index);
return optionmenu;
}
return menu;
}
static GtkWidget *
spin_button_new (GtkObject **adjustment,
gfloat value,
gfloat lower,
gfloat upper,
gfloat step_increment,
gfloat page_increment,
gfloat page_size,
gfloat climb_rate,
guint digits)
{
GtkWidget *spinbutton;
*adjustment = gtk_adjustment_new (value, lower, upper,
step_increment, page_increment, page_size);
spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (*adjustment),
climb_rate, digits);
gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinbutton),
GTK_SHADOW_NONE);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
gtk_widget_set_usize (spinbutton, 75, -1);
return spinbutton;
}
static void
scale_entry_unconstrained_adjustment_callback (GtkAdjustment *adjustment,
GtkAdjustment *other_adj)
{
gtk_signal_handler_block_by_data (GTK_OBJECT (other_adj), adjustment);
gtk_adjustment_set_value (other_adj, adjustment->value);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (other_adj), adjustment);
}
GtkObject *
stpui_scale_entry_new(GtkTable *table,
gint column,
gint row,
const gchar *text,
gint scale_usize,
gint spinbutton_usize,
gfloat value,
gfloat lower,
gfloat upper,
gfloat step_increment,
gfloat page_increment,
guint digits,
gboolean constrain,
gfloat unconstrained_lower,
gfloat unconstrained_upper,
const gchar *tooltip)
{
GtkWidget *label;
GtkWidget *scale;
GtkWidget *spinbutton;
GtkObject *adjustment;
GtkObject *return_adj;
label = gtk_label_new (text);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label,
column + 1, column + 2, row, row + 1,
GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (label);
if (! constrain &&
unconstrained_lower <= lower &&
unconstrained_upper >= upper)
{
GtkObject *constrained_adj;
constrained_adj = gtk_adjustment_new (value, lower, upper,
step_increment, page_increment,
0.0);
spinbutton = spin_button_new (&adjustment, value,
unconstrained_lower,
unconstrained_upper,
step_increment, page_increment, 0.0,
1.0, digits);
gtk_signal_connect
(GTK_OBJECT (constrained_adj), "value_changed",
GTK_SIGNAL_FUNC (scale_entry_unconstrained_adjustment_callback),
adjustment);
gtk_signal_connect
(GTK_OBJECT (adjustment), "value_changed",
GTK_SIGNAL_FUNC (scale_entry_unconstrained_adjustment_callback),
constrained_adj);
return_adj = adjustment;
adjustment = constrained_adj;
}
else
{
spinbutton = spin_button_new (&adjustment, value, lower, upper,
step_increment, page_increment, 0.0,
1.0, digits);
return_adj = adjustment;
}
if (spinbutton_usize > 0)
gtk_widget_set_usize (spinbutton, spinbutton_usize, -1);
scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
if (scale_usize > 0)
gtk_widget_set_usize (scale, scale_usize, -1);
gtk_scale_set_digits (GTK_SCALE (scale), digits);
gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
gtk_table_attach (GTK_TABLE (table), scale,
column + 2, column + 3, row, row + 1,
GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
gtk_widget_show (scale);
gtk_table_attach (GTK_TABLE (table), spinbutton,
column + 3, column + 4, row, row + 1,
GTK_SHRINK, GTK_SHRINK, 0, 0);
gtk_widget_show (spinbutton);
if (tooltip)
{
stpui_set_help_data (scale, tooltip);
stpui_set_help_data (spinbutton, tooltip);
}
gtk_object_set_data (GTK_OBJECT (return_adj), "label", label);
gtk_object_set_data (GTK_OBJECT (return_adj), "scale", scale);
gtk_object_set_data (GTK_OBJECT (return_adj), "spinbutton", spinbutton);
return return_adj;
}
void
stpui_table_attach_aligned (GtkTable *table,
gint column,
gint row,
const gchar *label_text,
gfloat xalign,
gfloat yalign,
GtkWidget *widget,
gint colspan,
gboolean left_align)
{
if (label_text)
{
GtkWidget *label;
label = gtk_label_new (label_text);
gtk_misc_set_alignment (GTK_MISC (label), xalign, yalign);
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
gtk_table_attach (table, label, column, column + 1, row, row + 1,
GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (label);
}
gtk_widget_show (widget);
if (left_align)
{
GtkWidget *alignment;
alignment = gtk_alignment_new (0.0, 0.5, 0.0, 0.0);
gtk_container_add (GTK_CONTAINER (alignment), widget);
widget = alignment;
}
gtk_table_attach (table, widget, column + 1, column + 1 + colspan,
row, row + 1,
GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
gtk_widget_show (widget);
}
static GtkTooltips * tool_tips = NULL;
void
stpui_help_init (void)
{
tool_tips = gtk_tooltips_new ();
}
void
stpui_help_free (void)
{
gtk_object_destroy (GTK_OBJECT (tool_tips));
gtk_object_unref (GTK_OBJECT (tool_tips));
}
void
stpui_enable_help (void)
{
gtk_tooltips_enable (tool_tips);
}
void
stpui_disable_help (void)
{
gtk_tooltips_disable (tool_tips);
}
void
stpui_set_help_data (GtkWidget *widget, const gchar *tooltip)
{
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
if (tooltip)
{
gtk_tooltips_set_tip (tool_tips, widget, tooltip, NULL);
}
}
void
stpui_set_image_filename(const char *name)
{
if (name && name == image_filename)
return;
if (image_filename)
g_free(image_filename);
if (name)
image_filename = g_strdup(name);
else
image_filename = g_strdup("");
}
const char *
stpui_get_image_filename(void)
{
stpui_set_image_filename(image_filename);
return(image_filename);
}
static void
default_errfunc(void *data, const char *buffer, size_t bytes)
{
fwrite(buffer, 1, bytes, data ? data : stderr);
}
void
stpui_set_errfunc(stp_outfunc_t wfunc)
{
the_errfunc = wfunc;
}
stp_outfunc_t
stpui_get_errfunc(void)
{
return the_errfunc;
}
void
stpui_set_errdata(void *errdata)
{
the_errdata = errdata;
}
void *
stpui_get_errdata(void)
{
return the_errdata;
}
void
stpui_set_thumbnail_func(get_thumbnail_func_t func)
{
thumbnail_func = func;
}
get_thumbnail_func_t
stpui_get_thumbnail_func(void)
{
return thumbnail_func;
}
void
stpui_set_thumbnail_data(void *data)
{
thumbnail_private_data = data;
}
void *
stpui_get_thumbnail_data(void)
{
return thumbnail_private_data;
}
GtkWidget *
stpui_create_entry(GtkWidget *table, int hpos, int vpos, const char *text,
const char *help, GtkSignalFunc callback)
{
GtkWidget *entry = gtk_entry_new();
gtk_widget_set_usize(entry, 60, 0);
stpui_table_attach_aligned(GTK_TABLE(table), hpos, vpos, text,
0.0, 0.5, entry, 1, TRUE);
stpui_set_help_data(entry, help);
gtk_signal_connect(GTK_OBJECT(entry), "activate",
GTK_SIGNAL_FUNC(callback), NULL);
return entry;
}
GSList *
stpui_create_radio_button(radio_group_t *radio, GSList *group,
GtkWidget *table, int hpos, int vpos,
GtkSignalFunc callback)
{
radio->button = gtk_radio_button_new_with_label(group, _(radio->name));
group = gtk_radio_button_group(GTK_RADIO_BUTTON(radio->button));
stpui_table_attach_aligned(GTK_TABLE(table), hpos, vpos, NULL, 0.5, 0.5,
radio->button, 1, FALSE);
stpui_set_help_data(radio->button, _(radio->help));
gtk_signal_connect(GTK_OBJECT(radio->button), "toggled",
GTK_SIGNAL_FUNC(callback), (gpointer) radio->value);
return group;
}
void
stpui_set_adjustment_tooltip (GtkObject *adj, const gchar *tip)
{
stpui_set_help_data (GTK_WIDGET (SCALE_ENTRY_SCALE (adj)), tip);
stpui_set_help_data (GTK_WIDGET (SCALE_ENTRY_SPINBUTTON (adj)), tip);
}
static GtkWidget *
table_label(GtkTable *table, gint column, gint row)
{
GList *children = table->children;;
while (children)
{
GtkTableChild *child = (GtkTableChild *)children->data;
if (child->left_attach == column + 1 && child->top_attach == row)
return child->widget;
children = children->next;
}
return NULL;
}
void
stpui_create_new_combo(option_t *option, GtkWidget *table,
int hpos, int vpos, gboolean is_optional)
{
GtkWidget *event_box = gtk_event_box_new();
GtkWidget *combo = gtk_combo_new();
option->checkbox = gtk_check_button_new();
gtk_table_attach(GTK_TABLE(table), option->checkbox,
hpos, hpos + 1, vpos, vpos + 1,
GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
option->info.list.combo = combo;
gtk_container_add(GTK_CONTAINER(event_box), combo);
gtk_widget_show(combo);
gtk_widget_show(event_box);
stpui_set_help_data(event_box, _(option->fast_desc->help));
stpui_table_attach_aligned
(GTK_TABLE(table), hpos + 1, vpos, _(option->fast_desc->text),
0.0, 0.5, event_box, 2, TRUE);
option->info.list.label = table_label(GTK_TABLE(table), hpos, vpos);
}
const char *
stpui_combo_get_name(GtkWidget *combo,
const stp_string_list_t *options)
{
if (options)
{
gint i;
gint num_options = stp_string_list_count(options);
gchar *text = (gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry)));
if (text == NULL)
return (NULL);
if (num_options == 0)
return ((const char *)text);
for (i = 0; i < num_options; i ++)
if (strcmp(stp_string_list_param(options, i)->text, text) == 0)
return (stp_string_list_param(options, i)->name);
}
return (NULL);
}
void
stpui_create_scale_entry(option_t *opt,
GtkTable *table,
gint column,
gint row,
const gchar *text,
gint scale_usize,
gint spinbutton_usize,
gfloat value,
gfloat lower,
gfloat upper,
gfloat step_increment,
gfloat page_increment,
guint digits,
gboolean constrain,
gfloat unconstrained_lower,
gfloat unconstrained_upper,
const gchar *tooltip,
gboolean is_optional)
{
opt->checkbox = gtk_check_button_new();
gtk_table_attach(GTK_TABLE(table), opt->checkbox,
column, column + 1, row, row + 1,
GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
opt->info.flt.adjustment =
stpui_scale_entry_new(table, column, row, text, scale_usize,
spinbutton_usize, value, lower, upper,
step_increment, page_increment, digits, constrain,
unconstrained_lower, unconstrained_upper, tooltip);
}