--- gimp_main_window.c.dist Mon Oct 15 16:45:37 2001 +++ gimp_main_window.c Fri Dec 13 18:56:58 2002 @@ -33,6 +33,8 @@ #include "print-intl.h" #include +#include +#include /* * Constants for GUI. @@ -54,6 +56,7 @@ static GtkWidget *notebook; static GtkWidget *print_dialog; /* Print dialog window */ +static GtkWidget *template_button; static GtkWidget *recenter_button; static GtkWidget *recenter_vertical_button; static GtkWidget *recenter_horizontal_button; @@ -106,6 +109,9 @@ static GtkWidget *file_browser; /* FSD for print files */ static GtkWidget *adjust_color_button; static GtkWidget *about_dialog; +static GtkWidget *template_dialog = 0; +static GtkWidget *template_combo = 0; +static GtkWidget *which_x = 0, *which_y = 0; static GtkObject *scaling_adjustment; /* Adjustment object for scaling */ static gboolean suppress_scaling_adjustment = FALSE; @@ -203,6 +209,12 @@ static void gimp_image_type_callback (GtkWidget *widget, gpointer data); +static void gimp_label_template_callback (GtkWidget *widget); +static void gimp_template_dialog_ok_callback (GtkWidget *widget, + gpointer data); +static void gimp_template_dialog_apply_callback (GtkWidget *widget, + gpointer data); + static gdouble preview_ppi = 10; stp_vars_t *pv; @@ -469,6 +481,16 @@ _("Orientation:"), 1.0, 0.5, orientation_menu, 3, TRUE); + template_button = gtk_button_new_with_label (_("Templates...")); + gtk_widget_show (template_button); + gimp_help_set_help_data (template_button, + _("Choose from a list of templates"), + NULL); + gtk_signal_connect (GTK_OBJECT (template_button), "clicked", + GTK_SIGNAL_FUNC (gimp_label_template_callback), + NULL); + gtk_table_attach_defaults (GTK_TABLE (table), template_button, 3, 4, 0, 1); + sep = gtk_hseparator_new (); gtk_table_attach_defaults (GTK_TABLE (table), sep, 0, 4, 1, 2); gtk_widget_show (sep); @@ -1745,6 +1767,322 @@ gimp_preview_update (); } +static const char* +gimp_find_xml_arg(const char* lp, const char* arg, int arglen) +{ + lp = strstr(lp, arg); + if (!lp) + return 0; + lp += arglen; + while (isspace(*lp) || *lp == '=' || *lp == '"') + if (*(lp++) == '\0') + return 0; + return lp; +} + +/* get_template finds the next template matching paper_size and/or match_name; + * returns the template name on success, else 0 + */ +static char* +gimp_get_template(FILE* fp, const char* paper_size, const char* match_name, + float* width, float* height, float* x0, float* y0, + float* dx, float* dy, int* nx, int* ny) +{ + char line[1024]; + static char namebuf[64]; + while (fgets(line, sizeof(line), fp) != NULL) + { + const char* name; + /* Gimp doesn't have an XML parser. So just fudge this. + * For now, our parsing won't be very robust. Oh, well. + */ + char* lp = line; + while (*lp != '\0' && *lp != '<') + ++lp; + if (*lp == '\0') + continue; + if (strncmp(lp, "")) + return namebuf; + if (fgets(line, sizeof(line), fp) == NULL) + return namebuf; + } + } + return namebuf; + } + /* End of file. Give up. */ + return 0; +} + +static char *template_files[2]; + +static void +gimp_build_template_file_list(void) +{ + const char* home = getenv("HOME"); + const char* my = ".glabels/my.template"; + template_files[0] = strdup("/usr/local/share/glabels/predefined-labels.template"); + template_files[1] = malloc(strlen(home) + strlen(my) + 2); + sprintf(template_files[1], "%s/%s", home, my); +} + +/* + * gimp_label_template_callback() - Choose from a list of label templates. + */ +static void +gimp_label_template_callback (GtkWidget *widget) +{ + int i; + GList *items = 0; + const gchar* paper_size = Combo_get_text (media_size_combo); + + if (template_dialog) + { + gtk_widget_show(template_dialog); + return; + } + + gimp_build_template_file_list(); + + /* Loop over the template files and parse them */ + for (i=0; i< (sizeof template_files / sizeof *template_files); ++i) + { + FILE* fp = fopen(template_files[i], "r"); + const char* name; + + if (fp == NULL) + continue; + while ((name = gimp_get_template(fp, paper_size, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL)) + != 0) + { + /* We have at least one, so create the dialog */ + if (template_dialog == 0) + { + GtkWidget *label, *hbox; + GtkObject* obj; + template_dialog = + gimp_dialog_new (_("Label Templates"), "templates", + gimp_standard_help_func, + "filters/print.html", + GTK_WIN_POS_MOUSE, FALSE, TRUE, FALSE, + _("OK"), gimp_template_dialog_ok_callback, + NULL, 1, NULL, TRUE, TRUE, + _("Apply"), + gimp_template_dialog_apply_callback, + NULL, 1, NULL, FALSE, FALSE, + _("Cancel"), gtk_widget_hide, + NULL, 1, NULL, FALSE, TRUE, + NULL); + label = gtk_label_new (_("Label Template:")); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(template_dialog)->vbox), + label, FALSE, FALSE, 8); + gtk_widget_show (label); + + template_combo = gtk_combo_new(); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(template_dialog)->vbox), + template_combo, FALSE, FALSE, 6); + + /* The "which label" fields */ + hbox = gtk_hbox_new(FALSE, 3); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(template_dialog)->vbox), + hbox, FALSE, FALSE, 8); + label = gtk_label_new (_("Which x:")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 8); + gtk_widget_show (label); + + which_x = gimp_spin_button_new(&obj, + 1, 1.0, 50, + 1.0, 5.0, 0, 1, 2); + gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(which_x), 1); + gtk_spin_button_set_digits(GTK_SPIN_BUTTON(which_x), 0); + gtk_box_pack_start(GTK_BOX(hbox), which_x, + FALSE, FALSE, 8); + gtk_widget_show(which_x); + + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(template_dialog)->vbox), + hbox, FALSE, FALSE, 8); + label = gtk_label_new(_("Which y:")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 8); + gtk_widget_show (label); + + which_y = gimp_spin_button_new(&obj, + 1, 1.0, 50, + 1.0, 5.0, 0, 1, 2); + gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(which_y), 1); + gtk_spin_button_set_digits(GTK_SPIN_BUTTON(which_y), 0); + gtk_box_pack_start(GTK_BOX(hbox), which_y, + FALSE, FALSE, 8); + gtk_widget_show(which_y); + gtk_widget_show(hbox); + } + items = g_list_append (items, c_strdup(name)); + } + + fclose(fp); + } + + /* Now we've looped over all the lines in all the files. + * Time to set the combobox. + */ + if (!template_dialog) + return; + gtk_combo_set_popdown_strings(GTK_COMBO(template_combo), items); + gtk_widget_show (template_combo); + gtk_widget_show(template_dialog); +} + +static void +gimp_template_dialog_ok_callback(GtkWidget *widget, gpointer data) +{ + gimp_template_dialog_apply_callback(widget, data); + gtk_widget_hide(template_dialog); +} + +static void +gimp_template_dialog_apply_callback(GtkWidget *widget, gpointer data) +{ + int i; + const gchar* template_name = Combo_get_text (template_combo); + const gchar* paper_size = Combo_get_text (media_size_combo); + + /* Loop over the template files and parse them */ + for (i=0; i< (sizeof template_files / sizeof *template_files); ++i) + { + FILE* fp = fopen(template_files[i], "r"); + char* name; + float width, height, x0, y0, dx, dy; + int nx, ny; + + if (fp == NULL) + continue; + if ((name = gimp_get_template(fp, paper_size, template_name, + &width, &height, &x0, &y0, + &dx, &dy, &nx, &ny)) + != 0) + { + gint whichx = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(which_x)); + gint whichy = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(which_y)); + if (whichx > nx) { + whichx = nx; + gtk_spin_button_set_value(GTK_SPIN_BUTTON(which_x), nx); + } + if (whichx < 0) whichx = 1; + --whichx; + if (whichy > ny) { + whichy = ny; + gtk_spin_button_set_value(GTK_SPIN_BUTTON(which_y), ny); + } + if (whichy < 0) whichy = 1; + --whichy; + /* The callbacks on width and height change left and right; + * so these must be done first. + * Also, the callbacks affect each other, + * so set one value, call back before setting the next value. + */ + set_entry_value (width_entry, width / 72.0, 1); + gimp_position_callback(width_entry); + set_entry_value (height_entry, height / 72.0, 1); + gimp_position_callback(height_entry); + + set_entry_value (left_entry, (x0 + whichx * dx) / 72.0, 1); + gimp_position_callback(left_entry); + set_entry_value (top_entry, (y0 + whichy * dy) / 72.0, 1); + gimp_position_callback(top_entry); + break; + } + } +} + /* * gimp_position_callback() - callback for position entry widgets */ @@ -2332,6 +2670,7 @@ gtk_widget_destroy (print_dialog); gtk_widget_destroy (new_printer_dialog); gtk_widget_destroy (about_dialog); + gtk_widget_destroy (template_dialog); } static void @@ -2342,6 +2681,7 @@ gtk_widget_set_sensitive (print_dialog, sensitive); gtk_widget_set_sensitive (new_printer_dialog, sensitive); gtk_widget_set_sensitive (about_dialog, sensitive); + gtk_widget_set_sensitive (template_dialog, sensitive); } /*