/*
 * GPR
 *
 * Copyright (C) 2006-09 A. Mennucci
 *
 * Copyright (C) 2000 CompuMetric Labs, Inc.
 *
 * For more information contact:
 *        Thomas Hubbell
 *        CompuMetric Labs, Inc.
 *        5920 Grelot Road, Suite C-2
 *        Mobile, AL 36609
 * 
 * Voice: (334) 342-2220
 *   Fax: (334) 343-2261
 * Email: thubbell@compumetric.com
 *   Web: http://www.compumetric.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.
 *    
 *        File: Interface.c
 * 
 * Description: Routines to create the user interface
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>

#ifdef USE_GNOME
#include <gnome.h>
#else
#include <gtk/gtk.h>
#endif

#include "callbacks.h"
#include "interface.h"
#include "support.h"

/* keywords used to assign data to widgets with gtk_object_set_data */
#define PN "printer name"
#define SD "spool directory"
#define PF "PPD file"
#define OT "option text"
#define OK "option keyword"
#define CT "choice text"
#define CK "choice keyword"
#define IN "index"
#define SS "saved settings"

#define MASTER_PPDDIR "/usr/share/postscript/ppd"

extern char *cmdname;

/* local functions */
static GtkWidget *get_printer_menu(ppd_struct * ppd);
static void fileentry_combo_popdown (GtkWidget *fileentry, 
				     ppd_struct *ppd);

/* Added by MLP: The fileentry_combo_popdown() function needs this
   widget. I couldn't find a way to use the 
   local_ppd->ppd_fileentry element in the callback successfully.
*/

//GtkWidget *GLOBAL_ppdfile_fileentry=NULL;

/*----------------------------------------------------------------
  These are the pixmaps we're going to embed in the app.
----------------------------------------------------------------*/

#include "../pixmaps/nup1up.xpm"
#include "../pixmaps/nup2up.xpm"
#include "../pixmaps/nup4up.xpm"
#include "../pixmaps/collate.xpm"
#include "../pixmaps/forward.xpm"
#include "../pixmaps/noncoll.xpm"
#include "../pixmaps/reverse.xpm"
#include "../pixmaps/tuxprint.xpm"

/* OK, globals are not so neat, but they work*/
GtkWidget *border_toggle=NULL;
GtkWidget *header_toggle=NULL;
GtkWidget *notebook1=NULL;
GtkWidget *nup_1up_radiobutton=NULL;
GtkWidget *nup_2up_radiobutton=NULL;
GtkWidget *nup_4up_radiobutton=NULL;
GtkWidget *numcopies_spinbutton=NULL;
GtkWidget *collate_yes_radiobutton=NULL;
GtkWidget *collate_no_radiobutton=NULL;
GtkWidget *revordr_yes_radiobutton=NULL;
GtkWidget *revordr_no_radiobutton=NULL;

/*
 * This function creates the main program window with three tabs
 */
GtkWidget *create_gpr_main_window(ppd_struct * ppd,
				  GtkWidget * inst_opts_window)
{
  /* Main window widgets */
  GtkWidget *gpr_main_window;
  GtkWidget *vbox1;

  /* Notebook tab 1 widgets */
  GtkWidget *vbox2;
  GtkWidget *hbox1;
  GtkWidget *printfile_label;
  GtkWidget *printfile_fileentry;
  GtkWidget *hseparator1;
  GtkWidget *hbox2;
  GtkWidget *printer_select_label;
  GtkWidget *printer_select_optionmenu;
  GtkWidget *printer_select_optionmenu_menu;
  //GtkWidget *hseparator2;
  GtkWidget *hbox3;
  GtkWidget *ppdfile_label;
  GtkWidget *ppdfile_fileentry;
  /*GtkWidget *ppd_gnome_combo;*/
  GtkWidget *hbox4;
  //GtkWidget *hbox5;
  //GtkWidget *vbox3;
  GtkWidget *pconfig_frame;
  GtkWidget *hbox14;
  GtkWidget *pconfig_pixmap;
  //GtkWidget *hbuttonbox5;
  GtkWidget *pconfig_button;
  GtkWidget *savesett_frame;
  GtkWidget *vbox4;
  GtkWidget *savesett_label1;

  GtkWidget *savesett_button;
  GtkWidget *main_notebook_label;

  /* Notebook tab 2 widgets */
  GtkWidget *vbox5;
  GtkWidget *hbox8;
  //GtkWidget *hbox11;
  GtkWidget *numcopies_label;
  GtkObject *numcopies_spinbutton_adj;
  //GtkWidget *vbox9;
  //GtkWidget *vbox6;
  GtkWidget *hbox20;
  GtkWidget *pagesize_label;
  GtkWidget *hbox7;
  GtkWidget *range_frame;
  GtkWidget *vbox10;
  GtkWidget *hbox18;
  GSList *page_range_group = NULL;
  GtkWidget *range_all_radiobutton;
  GtkWidget *range_odd_radiobutton;
  GtkWidget *range_even_radiobutton;
  GtkWidget *hboxfromto;
  GtkWidget *range_from_radiobutton;
  GtkWidget *range_from_entry;
  GtkWidget *range_to_label;
  GtkWidget *range_to_entry;
  GtkWidget *nup_frame;
  GtkWidget *hbox12;
  GtkWidget *nup1up_pixmap;
  GtkWidget *nup2up_pixmap;
  GtkWidget *nup4up_pixmap;
  //GtkWidget *vbox8;
  GtkWidget *vbox17;
  GSList *n_up_group = NULL;
  GtkWidget *hbox17;
  //GtkWidget *hbox21;
  GtkWidget *collate_frame;
  GtkWidget *hbox22;
  GtkWidget *collate_off_pixmap;
  GtkWidget *collate_on_pixmap;
  GtkWidget *vbox14;
  GSList *collate_group = NULL;
  GtkWidget *revordr_frame;
  GtkWidget *hbox23;
  GtkWidget *order_rev_pixmap;
  GtkWidget *order_for_pixmap;
  GtkWidget *vbox15;
  GSList *rev_order_group = NULL;
  GtkWidget *common_notebook_label;
  GtkWidget *hbox24;
  GtkWidget *hbox25;
  GtkWidget *temp_menu;
  GtkWidget *temp_menu2;

  /* Notebook tab 3 widgets */
  GtkWidget *advanced_notebook_label;

  /* main window widgets */
  GtkWidget *hbuttonbox1;
  GtkWidget *main_print_button;
  GtkWidget *main_cancel_button;

  ppd_struct *local_ppd;	/* local copy of ppd_struct */
  /* end declarations */

  local_ppd = ppd;

  /* create main window */
  gpr_main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_object_set_data(GTK_OBJECT(gpr_main_window), "gpr_main_window",
		      gpr_main_window);

  /* delete the line below once we adjust size of viewport 
     contents */
  // this is a bad idea gtk_widget_set_usize(gpr_main_window, 500, 0);
  gtk_window_set_title(GTK_WINDOW(gpr_main_window), _("gpr"));

  /* add a vbox to the window containing a notebook and a button 
     box */
  vbox1 = gtk_vbox_new(FALSE, 0);
  gtk_widget_show(vbox1);
  gtk_container_add(GTK_CONTAINER(gpr_main_window), vbox1);

  /* create notebook */
  notebook1 = gtk_notebook_new();
  gtk_widget_show(notebook1);
  gtk_box_pack_start(GTK_BOX(vbox1), notebook1, TRUE, TRUE, 0);

  /* a container */
  vbox2 = gtk_vbox_new(FALSE, 0);
  gtk_widget_show(vbox2);
  gtk_container_add(GTK_CONTAINER(notebook1), vbox2);

  /* a container */
  hbox1 = gtk_hbox_new(FALSE, 1);
  gtk_widget_show(hbox1);
  gtk_box_pack_start(GTK_BOX(vbox2), hbox1, TRUE, FALSE, 0);

  /* label for printfile entrybox */
  printfile_label = gtk_label_new(_("File To Print"));
  gtk_widget_show(printfile_label);
  gtk_box_pack_start(GTK_BOX(hbox1), printfile_label, FALSE, FALSE, 5);

  /* printfile entrybox ?????  */
  // shameless stolen from http://mail.gnome.org/archives/evolution-patches/2006-March/msg00019.html
#ifdef USE_GNOMEFILEENTRY
  printfile_fileentry = gnome_file_entry_new(NULL, NULL);
#else
  printfile_fileentry =  gtk_file_chooser_button_new (_("Choose a file"), GTK_FILE_CHOOSER_ACTION_OPEN); 
#endif

  /* specify some default settings for the entrybox */
#ifdef USE_GNOMEFILEENTRY
  gnome_file_entry_set_title(GNOME_FILE_ENTRY(printfile_fileentry),
  			     "Select a file to print");
  gnome_file_entry_set_default_path(GNOME_FILE_ENTRY(printfile_fileentry),
   g_get_home_dir());
#else
  gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON(printfile_fileentry),
				     "Select a file to print");
  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(printfile_fileentry),
				       g_get_home_dir() );
#endif

  gtk_widget_show(printfile_fileentry);
  gtk_box_pack_start(GTK_BOX(hbox1), printfile_fileentry, TRUE, TRUE, 5);
  //this is a bad idea gtk_widget_set_usize(printfile_fileentry, 260, 42);
  //this I do not like gtk_container_set_border_width(GTK_CONTAINER(printfile_fileentry), 10);

#ifdef USE_GNOMEFILEENTRY
  GtkWidget *printfile_combo_entry;
  /* printfile combo entry - entrybox + file browser */
  printfile_combo_entry =
    gnome_file_entry_gtk_entry(GNOME_FILE_ENTRY(printfile_fileentry));
  gtk_widget_show(printfile_combo_entry);
#endif

  /* set the file name to the one specified on the command line, 
     if it exists */
  if (local_ppd->file_to_print != NULL) {
#ifdef USE_GNOMEFILEENTRY
    gtk_entry_set_text(GTK_ENTRY
		       (gnome_file_entry_gtk_entry
			(GNOME_FILE_ENTRY(printfile_fileentry))),
		       local_ppd->file_to_print);
#else
    gtk_file_chooser_set_filename  (GTK_FILE_CHOOSER(printfile_fileentry),
				    local_ppd->file_to_print); 
#endif
    gtk_widget_set_sensitive(printfile_fileentry, FALSE);
  }

  /* signal handler called each time the filename changes */
  gtk_signal_connect(GTK_OBJECT
#ifdef USE_GNOMEFILEENTRY
		     (gnome_file_entry_gtk_entry
		      (GNOME_FILE_ENTRY(printfile_fileentry)))
		     , "changed",
#else
		     (printfile_fileentry)
		     ,"selection-changed",
#endif
		     GTK_SIGNAL_FUNC(grab_file_to_print),(gpointer) local_ppd);


  /* separator */
  hseparator1 = gtk_hseparator_new();
  gtk_widget_show(hseparator1);
  gtk_box_pack_start(GTK_BOX(vbox2), hseparator1, FALSE, FALSE, 0);

  /* a container */
  hbox2 = gtk_hbox_new(FALSE, 1);
  gtk_widget_show(hbox2);
  gtk_box_pack_start(GTK_BOX(vbox2), hbox2, TRUE, FALSE, 0);
  //gtk_container_set_border_width(GTK_CONTAINER(hbox2), 5);

  /* label for printer selection optionmenu */
  printer_select_label = gtk_label_new(_("Select Printer"));
  gtk_widget_show(printer_select_label);
  gtk_box_pack_start(GTK_BOX(hbox2), printer_select_label, FALSE, FALSE, 5);

  /* printer selection option menu */
  printer_select_optionmenu = gtk_option_menu_new();
  gtk_widget_show(printer_select_optionmenu);
  gtk_box_pack_start(GTK_BOX(hbox2), printer_select_optionmenu, TRUE, TRUE, 5);
  //this is a bad idea gtk_widget_set_usize(printer_select_optionmenu, 242, 27);

  printer_select_optionmenu_menu = get_printer_menu(local_ppd);

  gtk_option_menu_set_menu(GTK_OPTION_MENU(printer_select_optionmenu),
			   printer_select_optionmenu_menu);

  /* a separator */
  //hseparator2 = gtk_hseparator_new();
  //gtk_widget_show(hseparator2);
  //gtk_box_pack_start(GTK_BOX(vbox2), hseparator2, FALSE, FALSE, 0);

  /* a container */
  hbox3 = gtk_hbox_new(FALSE, 0);
  gtk_widget_show(hbox3);
  gtk_box_pack_start(GTK_BOX(vbox2), hbox3, TRUE, FALSE, 0);
  //gtk_container_set_border_width(GTK_CONTAINER(hbox3), 5);
  /* label for ppd file entry box */
  ppdfile_label = gtk_label_new(_("PPD File"));
  gtk_widget_show(ppdfile_label);
  gtk_box_pack_start(GTK_BOX(hbox3), ppdfile_label, FALSE, FALSE, 5);

  /* ppd file entry box */
#ifdef USE_GNOMEFILEENTRY
  ppdfile_fileentry = gnome_file_entry_new(NULL, NULL);
  /* specify some default settings for the file entry widget */
  gnome_file_entry_set_title(GNOME_FILE_ENTRY(ppdfile_fileentry),
			     _("Select a PPD File"));
#else
  ppdfile_fileentry = gtk_file_chooser_button_new 
    (_("Select a PPD File"),
     GTK_FILE_CHOOSER_ACTION_OPEN); 
#endif
  local_ppd->ppd_fileentry = ppdfile_fileentry;
  gtk_widget_show(ppdfile_fileentry);
  gtk_box_pack_start(GTK_BOX(hbox3), ppdfile_fileentry, TRUE, TRUE, 5);
  //this is a bad idea gtk_widget_set_usize(ppdfile_fileentry, 260, 42);
  //this I do not like gtk_container_set_border_width(GTK_CONTAINER(ppdfile_fileentry), 10);

  /* signal handler called every time the "browser" button is 
     clicked */
  gtk_signal_connect(GTK_OBJECT(ppdfile_fileentry),
#ifdef USE_GNOMEFILEENTRY
		     "browse-clicked",
#else
		     "button-press-event", // FIXME does this work ??
#endif
		     GTK_SIGNAL_FUNC(update_ppd_path),
		     (gpointer) local_ppd);

#ifdef USE_GNOMEFILEENTRY
  GtkWidget *ppdfile_combo_entry;
  /* ppd file combo entry - entrybox+ file browser */
  ppdfile_combo_entry =
    gnome_file_entry_gtk_entry(GNOME_FILE_ENTRY(ppdfile_fileentry));
  /*--------------------------------------------------------------
    Attempt to tell when new combo entry was selected. I needed 
    to dig down in the GnomeFileEntry widget hierarchy, to find 
    some event to trap when a new entry was selected. The combo 
    box's popwin widget has an unmap event that seemed to work 
    the best, so we hook into that and call the 
    fileentry_combo_popdown function. That function calls the 
    three functions that are triggered by a FileEntry activate
    event. I couldn't simply emit an activate signal, as this has
    the side-effect of adding a duplicate entry in the combo box
    history list. (MLP 12/15/2000)
  --------------------------------------------------------------
  Mennucci2006 the new widget does not (seem to) have a combo
  */
  GLOBAL_ppdfile_fileentry = ppdfile_combo_entry;

  ppd_gnome_combo =
    gnome_file_entry_gnome_entry(GNOME_FILE_ENTRY(ppdfile_fileentry));
  gtk_signal_connect(GTK_OBJECT(GTK_COMBO(ppd_gnome_combo)->popwin), "unmap",
		     GTK_SIGNAL_FUNC(fileentry_combo_popdown),
		     (gpointer) local_ppd);
  /* End MLP section. ----------------------------------------- */
  gtk_widget_show(ppdfile_combo_entry);
#else
  gtk_signal_connect(GTK_OBJECT(ppdfile_fileentry), "selection-changed",
		     GTK_SIGNAL_FUNC(fileentry_combo_popdown),
		     (gpointer) local_ppd);
#endif

  /* signal handler called every time the entry box text is 
     changed */
  gtk_signal_connect(GTK_OBJECT
#ifdef USE_GNOMEFILEENTRY
		     (gnome_file_entry_gtk_entry
		      (GNOME_FILE_ENTRY(ppdfile_fileentry)))
		     , "activate",
#else
		     (ppdfile_fileentry)
		     ,"selection-changed",
#endif
		     GTK_SIGNAL_FUNC(grab_ppd_file), (gpointer) local_ppd);

  /* Forces select printer menu to emit a signal so that default 
     ppd shows at start up */
  temp_menu2 = gtk_menu_get_active(GTK_MENU(printer_select_optionmenu_menu));
  gtk_signal_emit_by_name(GTK_OBJECT(temp_menu2), "activate");

  /* a container */
  hbox4 = gtk_hbox_new(FALSE, 0);
  gtk_widget_show(hbox4);
  gtk_box_pack_start(GTK_BOX(vbox2), hbox4, TRUE, FALSE, 0);

  ///* a container */
  //hbox5 = gtk_hbox_new(FALSE, 1);
  //gtk_widget_ref(hbox5);
  //gtk_object_set_data_full(GTK_OBJECT(gpr_main_window), "hbox5", hbox5,
  //			   (GtkDestroyNotify) gtk_widget_unref);
  //gtk_widget_show(hbox5);
  //gtk_box_pack_start(GTK_BOX(hbox4), hbox5, TRUE, TRUE, 0);

  /* a container */
  //vbox3 = gtk_vbox_new(FALSE, 1);
  //gtk_widget_show(vbox3);
  //gtk_box_pack_start(GTK_BOX(hbox4), vbox3, TRUE, TRUE, 0);

  /* frame around printer configuration objects */
  pconfig_frame = gtk_frame_new(_("Printer Configuration"));
  gtk_widget_show(pconfig_frame);
  gtk_box_pack_start(GTK_BOX(hbox4), pconfig_frame, TRUE, FALSE, 0);

  /* a container */
  hbox14 = gtk_hbox_new(FALSE, 1);
  gtk_widget_show(hbox14);
  gtk_container_add(GTK_CONTAINER(pconfig_frame), hbox14);

  /* printer configuration icon */
  pconfig_pixmap =
    create_pixmap_from_data(gpr_main_window, tuxprint_xpm, FALSE);
  gtk_widget_show(pconfig_pixmap);
  gtk_box_pack_start(GTK_BOX(hbox14), pconfig_pixmap, FALSE, FALSE, 0);

  /* buttonbox containing printer configuration control button */
  //hbuttonbox5 = gtk_hbutton_box_new();
  //gtk_widget_show(hbuttonbox5);
  //gtk_box_pack_start(GTK_BOX(hbox14), hbuttonbox5, TRUE, TRUE, 0);

  /* printer configuration button */
  pconfig_button = gtk_button_new_with_label(_("Configure\nPrinter"));
  gtk_widget_show(pconfig_button);
  gtk_box_pack_start(GTK_BOX(hbox14), pconfig_button, FALSE, FALSE, 5);
  GTK_WIDGET_SET_FLAGS(pconfig_button, GTK_CAN_DEFAULT);

  /* signal handler called when printer configuration button is 
     clicked */
  gtk_signal_connect_object(GTK_OBJECT(pconfig_button), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_show),
			    GTK_OBJECT(inst_opts_window));

  /* frame around saved settings objects */
  savesett_frame = gtk_frame_new(_("Saved Settings"));
  gtk_widget_show(savesett_frame);
  gtk_box_pack_start(GTK_BOX(hbox4), savesett_frame, TRUE, FALSE, 0);

  /* a container */
  vbox4 = gtk_vbox_new(FALSE, 1);
  gtk_widget_show(vbox4);
  gtk_container_add(GTK_CONTAINER(savesett_frame), vbox4);
  //gtk_container_set_border_width(GTK_CONTAINER(vbox4), 5);

  /* a container */
  hbox24 = gtk_hbox_new(FALSE, 1);
  gtk_widget_show(hbox24);
  gtk_container_add(GTK_CONTAINER(vbox4), hbox24);


  /* label for saved setting option menu */
  savesett_label1 = gtk_label_new(_("Retrieve"));
  gtk_widget_show(savesett_label1);
  gtk_box_pack_start(GTK_BOX(hbox24), savesett_label1, FALSE, FALSE, 5);

  /* printer selection option menu */
  local_ppd->savesett_optionmenu = gtk_option_menu_new();
  gtk_widget_show(local_ppd->savesett_optionmenu);
  gtk_box_pack_start(GTK_BOX(hbox24), local_ppd->savesett_optionmenu, TRUE, TRUE, 5);

  temp_menu = gtk_menu_new();
  gtk_option_menu_set_menu(GTK_OPTION_MENU(local_ppd->savesett_optionmenu),
			   temp_menu);

  /* a container */
  hbox25 = gtk_hbox_new(FALSE, 1);
  gtk_widget_show(hbox25);
  gtk_container_add(GTK_CONTAINER(vbox4), hbox25);

  /* "Save Settings button */
  savesett_button = gtk_button_new_with_label(_("Save"));
  gtk_widget_show(savesett_button);
  gtk_box_pack_start(GTK_BOX(hbox25), savesett_button, FALSE, FALSE, 5);
  GTK_WIDGET_SET_FLAGS(savesett_button, GTK_CAN_DEFAULT);

  /* add a button click event handler here */
  gtk_signal_connect(GTK_OBJECT(savesett_button), "clicked",
		     GTK_SIGNAL_FUNC(save_sett), (gpointer) local_ppd);

  local_ppd->savesett_textentry = gtk_entry_new();
  gtk_widget_show(GTK_WIDGET(local_ppd->savesett_textentry));
  gtk_entry_set_max_length(GTK_ENTRY(local_ppd->savesett_textentry),7);
  gtk_entry_set_width_chars(GTK_ENTRY(local_ppd->savesett_textentry),7);
  gtk_box_pack_start(GTK_BOX(hbox25),local_ppd->savesett_textentry, FALSE, FALSE, 5);

  /* notebook tab1 label */
  main_notebook_label = gtk_label_new(_("Main"));
  gtk_widget_show(main_notebook_label);
  gtk_notebook_set_tab_label(GTK_NOTEBOOK(notebook1),
			     gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook1),
						       0), 
			     main_notebook_label);

  /* END NOTEBOOK TAB 1 ITEMS */

  /* a container */
  vbox5 = gtk_vbox_new(FALSE, 1);
  gtk_widget_show(vbox5);
  gtk_container_add(GTK_CONTAINER(notebook1), vbox5);

  /* a container */
  hbox8 = gtk_hbox_new(FALSE, 1);
  gtk_widget_show(hbox8);
  gtk_box_pack_start(GTK_BOX(vbox5), hbox8, FALSE, FALSE, 0);

  /* a container */
  //hbox11 = gtk_hbox_new(FALSE, 1);
  //gtk_widget_show(hbox11);
  //gtk_box_pack_start(GTK_BOX(hbox8), hbox11, FALSE, FALSE, 0);

  /* label for the number of copies spinbox */
  numcopies_label = gtk_label_new(_("Copies"));
  gtk_widget_show(numcopies_label);
  gtk_box_pack_start(GTK_BOX(hbox8), numcopies_label, FALSE, FALSE, 5);

  /* number of copies spinbutton widget */
  numcopies_spinbutton_adj = gtk_adjustment_new(1, 1, 99, 1, 10, 0);
  numcopies_spinbutton =
    gtk_spin_button_new(GTK_ADJUSTMENT(numcopies_spinbutton_adj), 1, 0);
  //gtk_entry_set_max_length((numcopies_spinbutton),4);
  //gtk_entry_set_width_chars((numcopies_spinbutton),3);
  gtk_widget_show(numcopies_spinbutton);
  gtk_box_pack_start(GTK_BOX(hbox8), numcopies_spinbutton, FALSE, FALSE, 5);

  /* signal handler called each time the item in the numcopies 
     box changes */
  gtk_signal_connect(GTK_OBJECT(numcopies_spinbutton), "changed",
		     GTK_SIGNAL_FUNC(update_num_copies), (gpointer) local_ppd);

  /* a container */
  //vbox9 = gtk_vbox_new(FALSE, 1);
  //gtk_widget_show(vbox9);
  //gtk_box_pack_start(GTK_BOX(hbox8), vbox9, TRUE, TRUE, 0);

  /* a container */
  //vbox6 = gtk_vbox_new(FALSE, 1);
  //gtk_widget_show(vbox6);
  //gtk_box_pack_start(GTK_BOX(vbox9), vbox6, TRUE, TRUE, 0);

  /* a container */
  hbox20 = gtk_hbox_new(FALSE, 1);
  gtk_widget_show(hbox20);
  gtk_box_pack_start(GTK_BOX(vbox5), hbox20, FALSE, FALSE, 0);

  /* label describing the page size option combo */
  pagesize_label = gtk_label_new(_("Media"));
  gtk_widget_show(pagesize_label);
  gtk_box_pack_start(GTK_BOX(hbox8), pagesize_label, FALSE, FALSE, 5);

  /* page size option menu */ 
#if USE_COMBO_BOX
  local_ppd->pagesize_optionmenu = gtk_combo_box_new_text();
#else
  local_ppd->pagesize_optionmenu = gtk_combo_new();
  gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(local_ppd->pagesize_optionmenu)->entry), FALSE);
#endif
  gtk_widget_show(local_ppd->pagesize_optionmenu);
  gtk_box_pack_start(GTK_BOX(hbox8), local_ppd->pagesize_optionmenu, 
		     FALSE, FALSE, 0);
  //this is a bad idea gtk_widget_set_usize(local_ppd->pagesize_optionmenu, 40, 20);

  /* a container */
  hbox7 = gtk_hbox_new(FALSE, 1);
  gtk_widget_show(hbox7);
  gtk_box_pack_start(GTK_BOX(vbox5), hbox7, TRUE, FALSE, 0);

  /* frame around page range objects */
  range_frame = gtk_frame_new(_("Page Ranges"));
  gtk_widget_show(range_frame);
  gtk_box_pack_start(GTK_BOX(hbox7), range_frame, TRUE, FALSE, 0);

  /* a container */
  vbox10 = gtk_vbox_new(FALSE, 1);
  gtk_widget_show(vbox10);
  gtk_container_add(GTK_CONTAINER(range_frame), vbox10);
  //gtk_container_set_border_width(GTK_CONTAINER(vbox10), 5);

  /* a container */
  hbox18 = gtk_hbox_new(FALSE, 1);
  gtk_widget_show(hbox18);
  gtk_box_pack_start(GTK_BOX(vbox10), hbox18, TRUE, TRUE, 0);

  /* radiobutton for printing all pages in the document */
  range_all_radiobutton =
    gtk_radio_button_new_with_label(page_range_group, _("All"));
  page_range_group =
    gtk_radio_button_group(GTK_RADIO_BUTTON(range_all_radiobutton));
  gtk_widget_show(range_all_radiobutton);
  gtk_box_pack_start(GTK_BOX(hbox18), range_all_radiobutton, TRUE, TRUE, 0);
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(range_all_radiobutton), TRUE);

  /* radiobutton for printing only the odd pages in the doc */
  range_odd_radiobutton =
    gtk_radio_button_new_with_label(page_range_group, _("Odd"));
  page_range_group =
    gtk_radio_button_group(GTK_RADIO_BUTTON(range_odd_radiobutton));
  gtk_widget_show(range_odd_radiobutton);
  gtk_box_pack_start(GTK_BOX(hbox18), range_odd_radiobutton, TRUE, TRUE, 0);

  /* radiobutton for printing only the even pages in the document */
  range_even_radiobutton =
    gtk_radio_button_new_with_label(page_range_group, _("Even"));
  page_range_group =
    gtk_radio_button_group(GTK_RADIO_BUTTON(range_even_radiobutton));
  gtk_widget_show(range_even_radiobutton);
  gtk_box_pack_start(GTK_BOX(hbox18), range_even_radiobutton, TRUE, TRUE, 0);

  hboxfromto = gtk_hbox_new(FALSE, 1);
  gtk_widget_show(hboxfromto);
  gtk_box_pack_start(GTK_BOX(vbox10), hboxfromto, TRUE, TRUE, 0);

  /* radiobutton for printing a specified range of pages in the 
     document */
  range_from_radiobutton =
    gtk_radio_button_new_with_label(page_range_group, _("From"));
  page_range_group =
    gtk_radio_button_group(GTK_RADIO_BUTTON(range_from_radiobutton));
  gtk_widget_show(range_from_radiobutton);
  gtk_box_pack_start(GTK_BOX(hboxfromto), range_from_radiobutton, FALSE, FALSE, 0);

  /* entry box for specifying the first page in the page range to
     print */
  range_from_entry = gtk_entry_new();
  gtk_entry_set_max_length(GTK_ENTRY(range_from_entry),4);
  gtk_entry_set_width_chars(GTK_ENTRY(range_from_entry),4);
  /* "grey-out" the entrybox by default */
  gtk_widget_set_sensitive(range_from_entry, FALSE);

  gtk_widget_show(range_from_entry);
  gtk_box_pack_start(GTK_BOX(hboxfromto), range_from_entry, FALSE, FALSE, 5);
  //this is a bad idea gtk_widget_set_usize(range_from_entry, 25, -2);

  //GtkWidget *hboxpippo = gtk_hbox_new(FALSE, 1);
  //gtk_widget_show(GTK_WIDGET(hboxpippo));
  //gtk_box_pack_start(GTK_BOX(vbox10), hboxpippo, TRUE, TRUE, 0);


  /* label for the "To" portion of the range */
  range_to_label = gtk_label_new(_("To"));
  gtk_widget_show(range_to_label);
  gtk_box_pack_start(GTK_BOX(hboxfromto), range_to_label, FALSE, FALSE, 2);

  /* entry box for specifying the last page in the page range to 
     print */
  range_to_entry = gtk_entry_new(); 
  gtk_entry_set_max_length(GTK_ENTRY(range_to_entry),4);
  gtk_entry_set_width_chars(GTK_ENTRY(range_to_entry),4);
  /* grey out entrybox by default */
  gtk_widget_set_sensitive(range_to_entry, FALSE);
  gtk_box_pack_start(GTK_BOX(hboxfromto), range_to_entry, FALSE, FALSE, 0);
  //this is a bad idea gtk_widget_set_usize(range_to_entry, 25, -2);

  gtk_widget_show(range_to_entry);

  /* "ungrey" boxes when the "From...To" item is selected */
  gtk_signal_connect(GTK_OBJECT(range_from_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(ungrey_entrybox),
		     (gpointer) range_from_entry);

  gtk_signal_connect(GTK_OBJECT(range_from_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(ungrey_entrybox),
		     (gpointer) range_to_entry);
  /* "regrey" boxes when any other choice is selected */
  gtk_signal_connect(GTK_OBJECT(range_all_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(regrey_entrybox),
		     (gpointer) range_from_entry);

  gtk_signal_connect(GTK_OBJECT(range_all_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(regrey_entrybox),
		     (gpointer) range_to_entry);

  gtk_signal_connect(GTK_OBJECT(range_odd_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(regrey_entrybox),
		     (gpointer) range_from_entry);

  gtk_signal_connect(GTK_OBJECT(range_odd_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(regrey_entrybox),
		     (gpointer) range_to_entry);

  gtk_signal_connect(GTK_OBJECT(range_even_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(regrey_entrybox),
		     (gpointer) range_from_entry);

  gtk_signal_connect(GTK_OBJECT(range_even_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(regrey_entrybox),
		     (gpointer) range_to_entry);

  /* now handle the real work - specifying job settings */
  gtk_signal_connect(GTK_OBJECT(range_all_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(update_pageset_all),(gpointer) local_ppd);

  gtk_signal_connect(GTK_OBJECT(range_odd_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(update_pageset_odd),(gpointer) local_ppd);

  gtk_signal_connect(GTK_OBJECT(range_even_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(update_pageset_even),
		     (gpointer) local_ppd);


  /* handle page ranges */
  gtk_signal_connect(GTK_OBJECT(range_from_entry), "changed",
		     GTK_SIGNAL_FUNC(update_range_from), (gpointer) local_ppd);

  gtk_signal_connect(GTK_OBJECT(range_to_entry), "changed",
		     GTK_SIGNAL_FUNC(update_range_to), (gpointer) local_ppd);


  /* frame around n-up objects */
  nup_frame = gtk_frame_new(_("N-Up Printing"));
  gtk_widget_show(nup_frame);
  gtk_box_pack_start(GTK_BOX(hbox7), nup_frame, TRUE, FALSE, 0);

  /* a container */
  hbox12 = gtk_hbox_new(FALSE, 1);
  gtk_widget_show(hbox12);
  gtk_container_add(GTK_CONTAINER(nup_frame), hbox12);

  /* n-up icon */
  nup1up_pixmap = create_pixmap_from_data(gpr_main_window, nup1up_xpm, FALSE);
  gtk_widget_show(nup1up_pixmap);
  gtk_box_pack_start(GTK_BOX(hbox12), nup1up_pixmap, TRUE, TRUE, 0);

  nup2up_pixmap = create_pixmap_from_data(gpr_main_window, nup2up_xpm, FALSE);
  gtk_box_pack_start(GTK_BOX(hbox12), nup2up_pixmap, TRUE, TRUE, 0);

  nup4up_pixmap = create_pixmap_from_data(gpr_main_window, nup4up_xpm, FALSE);
  gtk_box_pack_start(GTK_BOX(hbox12), nup4up_pixmap, TRUE, TRUE, 0);

  /* a container */
  //vbox8 = gtk_vbox_new(FALSE, 1);
  //gtk_widget_show(vbox8);
  //gtk_box_pack_start(GTK_BOX(hbox12), vbox8, TRUE, TRUE, 0);

  /* a container */
  vbox17 = gtk_vbox_new(FALSE, 1);
  gtk_widget_show(vbox17);
  gtk_box_pack_start(GTK_BOX(hbox12), vbox17, TRUE, TRUE, 0);

  /* radiobutton for choosing 1-up layout (default) */
  nup_1up_radiobutton = gtk_radio_button_new_with_label(n_up_group, _("1-Up"));
  n_up_group = gtk_radio_button_group(GTK_RADIO_BUTTON(nup_1up_radiobutton));
  gtk_widget_show(nup_1up_radiobutton);
  gtk_box_pack_start(GTK_BOX(vbox17), nup_1up_radiobutton, TRUE, TRUE, 0);
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(nup_1up_radiobutton), TRUE);

  /* radiobutton for choosing 2-up layout */
  nup_2up_radiobutton = gtk_radio_button_new_with_label(n_up_group, _("2-Up"));
  n_up_group = gtk_radio_button_group(GTK_RADIO_BUTTON(nup_2up_radiobutton));
  gtk_widget_show(nup_2up_radiobutton);
  gtk_box_pack_start(GTK_BOX(vbox17), nup_2up_radiobutton, TRUE, TRUE, 0);

  /* radiobutton for choosing 4-up layout */
  nup_4up_radiobutton = gtk_radio_button_new_with_label(n_up_group, _("4-Up"));
  n_up_group = gtk_radio_button_group(GTK_RADIO_BUTTON(nup_4up_radiobutton));
  gtk_widget_show(nup_4up_radiobutton);
  gtk_box_pack_start(GTK_BOX(vbox17), nup_4up_radiobutton, TRUE,TRUE, 0);

  /* signal handlers called when n-up buttons are clicked */
  gtk_signal_connect(GTK_OBJECT(nup_1up_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(update_nup_1up), (gpointer) local_ppd);

  gtk_signal_connect(GTK_OBJECT(nup_2up_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(update_nup_2up), (gpointer) local_ppd);

  gtk_signal_connect(GTK_OBJECT(nup_4up_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(update_nup_4up), (gpointer) local_ppd);

  /* Code to enable swicthing of icons */
  gtk_signal_connect_object(GTK_OBJECT(nup_1up_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_show),
			    GTK_OBJECT(nup1up_pixmap));

  gtk_signal_connect_object(GTK_OBJECT(nup_1up_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_hide),
			    GTK_OBJECT(nup2up_pixmap));

  gtk_signal_connect_object(GTK_OBJECT(nup_1up_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_hide),
			    GTK_OBJECT(nup4up_pixmap));

  gtk_signal_connect_object(GTK_OBJECT(nup_2up_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_show),
			    GTK_OBJECT(nup2up_pixmap));

  gtk_signal_connect_object(GTK_OBJECT(nup_2up_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_hide),
			    GTK_OBJECT(nup1up_pixmap));

  gtk_signal_connect_object(GTK_OBJECT(nup_2up_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_hide),
			    GTK_OBJECT(nup4up_pixmap));

  gtk_signal_connect_object(GTK_OBJECT(nup_4up_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_show),
			    GTK_OBJECT(nup4up_pixmap));

  gtk_signal_connect_object(GTK_OBJECT(nup_4up_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_hide),
			    GTK_OBJECT(nup1up_pixmap));

  gtk_signal_connect_object(GTK_OBJECT(nup_4up_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_hide),
			    GTK_OBJECT(nup2up_pixmap));

  /* a container */
  hbox17 = gtk_hbox_new(FALSE, 1);
  gtk_widget_show(hbox17);
  gtk_box_pack_start(GTK_BOX(vbox5), hbox17, TRUE, FALSE, 0);

  /* a container */
  //hbox21 = gtk_hbox_new(FALSE, 1);
  //gtk_widget_show(hbox21);
  //gtk_box_pack_start(GTK_BOX(hbox17), hbox21, TRUE, TRUE, 0);

  /* frame around collate objects */
  collate_frame = gtk_frame_new(_("Collate"));
  gtk_widget_show(collate_frame);
  gtk_box_pack_start(GTK_BOX(hbox17), collate_frame, TRUE, FALSE, 0);

  /* a container */
  hbox22 = gtk_hbox_new(FALSE, 1);
  gtk_widget_show(hbox22);
  gtk_container_add(GTK_CONTAINER(collate_frame), hbox22);

  /* collate icon */
  collate_off_pixmap =
    create_pixmap_from_data(gpr_main_window, noncoll_xpm, FALSE);
  gtk_widget_show(collate_off_pixmap);
  gtk_box_pack_start(GTK_BOX(hbox22), collate_off_pixmap, TRUE, TRUE, 0);

  /* collate icon */
  collate_on_pixmap =
    create_pixmap_from_data(gpr_main_window, collate_xpm, FALSE);
  gtk_box_pack_start(GTK_BOX(hbox22), collate_on_pixmap, TRUE, TRUE, 0);


  /* a container */
  vbox14 = gtk_vbox_new(FALSE, 1);
  gtk_widget_show(vbox14);
  gtk_box_pack_start(GTK_BOX(hbox22), vbox14, TRUE, TRUE, 0);

  /* radiobutton to select the collate option */
  collate_yes_radiobutton =
    gtk_radio_button_new_with_label(collate_group, _("Yes"));
  collate_group =
    gtk_radio_button_group(GTK_RADIO_BUTTON(collate_yes_radiobutton));
  gtk_widget_show(collate_yes_radiobutton);
  gtk_box_pack_start(GTK_BOX(vbox14), collate_yes_radiobutton, FALSE, FALSE,0);

  /* radiobutton to de-select the collate option (default) */
  collate_no_radiobutton =
    gtk_radio_button_new_with_label(collate_group, _("No"));
  collate_group =
    gtk_radio_button_group(GTK_RADIO_BUTTON(collate_no_radiobutton));
  gtk_widget_show(collate_no_radiobutton);
  gtk_box_pack_start(GTK_BOX(vbox14), collate_no_radiobutton, FALSE, FALSE, 0);
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(collate_no_radiobutton),TRUE);

  /* signal handlers for collate choices */
  gtk_signal_connect(GTK_OBJECT(collate_yes_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(update_collate_yes),(gpointer) local_ppd);

  gtk_signal_connect(GTK_OBJECT(collate_no_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(update_collate_no), (gpointer) local_ppd);

  /* Code to enable swicthing of icons */
  gtk_signal_connect_object(GTK_OBJECT(collate_yes_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_show),
			    GTK_OBJECT(collate_on_pixmap));

  gtk_signal_connect_object(GTK_OBJECT(collate_yes_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_hide),
			    GTK_OBJECT(collate_off_pixmap));

  gtk_signal_connect_object(GTK_OBJECT(collate_no_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_show),
			    GTK_OBJECT(collate_off_pixmap));

  gtk_signal_connect_object(GTK_OBJECT(collate_no_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_hide),
			    GTK_OBJECT(collate_on_pixmap));

  /* frame around reverse order objects */
  revordr_frame = gtk_frame_new(_("Reverse Order"));
  gtk_widget_show(revordr_frame);
  gtk_box_pack_start(GTK_BOX(hbox17), revordr_frame, TRUE, FALSE, 0);

  /* a container */
  hbox23 = gtk_hbox_new(FALSE, 1);
  gtk_widget_show(hbox23);
  gtk_container_add(GTK_CONTAINER(revordr_frame), hbox23);

  /* reverse order icons */
  order_for_pixmap =
    create_pixmap_from_data(gpr_main_window, forward_xpm, FALSE);
  gtk_widget_show(order_for_pixmap);
  gtk_box_pack_start(GTK_BOX(hbox23), order_for_pixmap, TRUE, TRUE, 0);

  order_rev_pixmap =
    create_pixmap_from_data(gpr_main_window, reverse_xpm, FALSE);
  gtk_box_pack_start(GTK_BOX(hbox23), order_rev_pixmap, TRUE, TRUE, 0);

  /* a container */
  vbox15 = gtk_vbox_new(FALSE, 1);
  gtk_widget_show(vbox15);
  gtk_box_pack_start(GTK_BOX(hbox23), vbox15, TRUE, TRUE, 0);

  /* radiobutton to enable reverse order printing */
  revordr_yes_radiobutton =
    gtk_radio_button_new_with_label(rev_order_group, _("Yes"));
  rev_order_group =
    gtk_radio_button_group(GTK_RADIO_BUTTON(revordr_yes_radiobutton));
  gtk_widget_show(revordr_yes_radiobutton);
  gtk_box_pack_start(GTK_BOX(vbox15), revordr_yes_radiobutton, FALSE, FALSE,0);

  /* radiobutton to disable reverse order printing (default) */
  revordr_no_radiobutton =
    gtk_radio_button_new_with_label(rev_order_group, _("No"));
  rev_order_group =
    gtk_radio_button_group(GTK_RADIO_BUTTON(revordr_no_radiobutton));
  gtk_widget_show(revordr_no_radiobutton);
  gtk_box_pack_start(GTK_BOX(vbox15), revordr_no_radiobutton, FALSE, FALSE, 0);
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(revordr_no_radiobutton),TRUE);

  /* signal handlers for reverse order choices */
  gtk_signal_connect(GTK_OBJECT(revordr_yes_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(update_revordr_yes),(gpointer) local_ppd);

  gtk_signal_connect(GTK_OBJECT(revordr_no_radiobutton), "clicked",
		     GTK_SIGNAL_FUNC(update_revordr_no), (gpointer) local_ppd);
  /* Code to enable swicthing of icons */
  gtk_signal_connect_object(GTK_OBJECT(revordr_yes_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_show),
			    GTK_OBJECT(order_rev_pixmap));

  gtk_signal_connect_object(GTK_OBJECT(revordr_yes_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_hide),
			    GTK_OBJECT(order_for_pixmap));

  gtk_signal_connect_object(GTK_OBJECT(revordr_no_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_show),
			    GTK_OBJECT(order_for_pixmap));

  gtk_signal_connect_object(GTK_OBJECT(revordr_no_radiobutton), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_hide),
			    GTK_OBJECT(order_rev_pixmap));

  /* text file a2ps options */
  GtkWidget *hboxblah=gtk_hbox_new(FALSE,0);
  gtk_widget_show(hboxblah);
  gtk_box_pack_start(GTK_BOX(vbox5), hboxblah, TRUE, FALSE, 0);
  GtkWidget *textfile_frame = gtk_frame_new(_("Text file options"));
  gtk_widget_show(textfile_frame);
  gtk_box_pack_start(GTK_BOX(hboxblah), textfile_frame, TRUE, FALSE, 0);
  GtkWidget *hbox_text=gtk_hbox_new(FALSE, 1);
  gtk_container_add(GTK_CONTAINER(textfile_frame), hbox_text);
  //gtk_container_set_border_width(GTK_CONTAINER(hbox_text), 5);
  gtk_widget_show(hbox_text);
  border_toggle= gtk_check_button_new_with_label(_("border"));
  gtk_container_add(GTK_CONTAINER(hbox_text),border_toggle);
  gtk_widget_show(border_toggle);
  header_toggle= gtk_check_button_new_with_label(_("header"));
  gtk_container_add(GTK_CONTAINER(hbox_text),header_toggle);
  gtk_widget_show(header_toggle);


  /* notebook tab 2 label */
  common_notebook_label = gtk_label_new(_("Common Options"));
  gtk_widget_show(common_notebook_label);
  gtk_notebook_set_tab_label(GTK_NOTEBOOK(notebook1),
			     gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook1),
						       1),
			     common_notebook_label);
  /* END NOTEBOOK TAB 2 ITEMS */

  /* scrolled window for printer-specific options */
  local_ppd->opt_window = gtk_scrolled_window_new(NULL, NULL);
  gtk_widget_show(local_ppd->opt_window);
  gtk_container_add(GTK_CONTAINER(notebook1), local_ppd->opt_window);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(local_ppd->opt_window),
				 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);

  /* viewport for printer-specific options */
  local_ppd->opt_viewport = gtk_viewport_new(NULL, NULL);
  gtk_widget_show(local_ppd->opt_viewport);
  gtk_container_add(GTK_CONTAINER(local_ppd->opt_window),
		    local_ppd->opt_viewport);

  /* notebook 3 label */
  advanced_notebook_label = gtk_label_new(_("Printer"));
  gtk_widget_show(advanced_notebook_label);
  gtk_notebook_set_tab_label(GTK_NOTEBOOK(notebook1),
			     gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook1),
						       2),
			     advanced_notebook_label);

  /* buttonbox for "Print" and "Cancel" buttons */
  hbuttonbox1 = gtk_hbutton_box_new();
  gtk_widget_show(hbuttonbox1);
  gtk_box_pack_start(GTK_BOX(vbox1), hbuttonbox1, FALSE, FALSE, 8);
  gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox1), GTK_BUTTONBOX_END);

  /* print button */
  main_print_button = gtk_button_new_with_label(_("Print"));
  gtk_widget_show(main_print_button);
  gtk_container_add(GTK_CONTAINER(hbuttonbox1), main_print_button);
  GTK_WIDGET_SET_FLAGS(main_print_button, GTK_CAN_DEFAULT);

  /* cancel button */
  main_cancel_button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
  //gtk_label_new("CANCEL"); // Gnome_stock_button(GNOME_STOCK_BUTTON_CANCEL);
  gtk_widget_show(main_cancel_button);
  gtk_container_add(GTK_CONTAINER(hbuttonbox1), main_cancel_button);
  GTK_WIDGET_SET_FLAGS(main_cancel_button, GTK_CAN_DEFAULT);

  /* signal handlers for print button */
  gtk_signal_connect(GTK_OBJECT(main_print_button), "clicked",
		     GTK_SIGNAL_FUNC(send_print), (gpointer) local_ppd);

  /*A Mennucc: clean up is called if and only if the program is closed*/
   gtk_signal_connect(GTK_OBJECT(main_print_button), "clicked",
		     GTK_SIGNAL_FUNC(if_no_errors_quit), NULL);
  
  /* signal handler for cancel button */
  gtk_signal_connect(GTK_OBJECT(main_cancel_button), "clicked",
		     GTK_SIGNAL_FUNC(gtk_main_quit), NULL);

  /* signal handler for delete window event trapped from wm */
  gtk_signal_connect(GTK_OBJECT(gpr_main_window), "delete_event",
		     GTK_SIGNAL_FUNC(gtk_main_quit), NULL);

  /* Signal handlers for ppd-file entry box. We put them down
     here because they can't be connected until after the 
     "Advanced Options" tab is created. Otherwise we'll have 
     problems initializing the ppd on startup */
  /* signal handler called when ppd_file entry is changed */
  gtk_signal_connect(
#ifdef USE_GNOMEFILEENTRY
		     GTK_OBJECT(gnome_file_entry_gtk_entry
		      (GNOME_FILE_ENTRY(ppdfile_fileentry)))
		     , "activate",
#else
		     GTK_OBJECT(ppdfile_fileentry)
		     ,"show",//FIXME does this work ?
#endif
		     GTK_SIGNAL_FUNC(init_ppd), (gpointer) local_ppd);

  /* 2nd signal handler called when ppd_file entry is changed */
  gtk_signal_connect_after(
#ifdef USE_GNOMEFILEENTRY
			   GTK_OBJECT(gnome_file_entry_gtk_entry
			    (GNOME_FILE_ENTRY(ppdfile_fileentry)))
			   ,"activate",
#else
			   GTK_OBJECT (ppdfile_fileentry)
			   ,"selection-changed",
#endif
			   GTK_SIGNAL_FUNC(fill_option_menus),
			   (gpointer) local_ppd);

  /* now force the ppd_file entry to emit an activate signal to 
     handle inititialization * on startup */

#ifndef FIXME_SHOULD_PROBABLY_DISABLE_THIS
#ifdef USE_GNOMEFILEENTRY
  gtk_signal_emit_by_name(GTK_OBJECT(gnome_file_entry_gtk_entry
			   (GNOME_FILE_ENTRY(ppdfile_fileentry)))
			  , "activate");
#else
  gtk_signal_emit_by_name(GTK_OBJECT(ppdfile_fileentry),"selection-changed");
#endif
#endif

  return gpr_main_window;
}

/* Creates the Intallable Options popup window for printer 
   configuration */
GtkWidget *create_gpr_inst_options_window(ppd_struct * ppd)
{
  /* window widgets */
  GtkWidget *main_vbox;
  GtkWidget *ok_button;
  GtkWidget *main_buttonbox;
  GtkWidget *gpr_inst_options_window;

  /* local copy of ppd_struct */
  ppd_struct *local_ppd;

  local_ppd = ppd;

  /* main window */
  gpr_inst_options_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_object_set_data(GTK_OBJECT(gpr_inst_options_window),
		      "gpr_inst_options_window", gpr_inst_options_window);

  /* gtk_widget_set_usize (gpr_inst_options_window, 395, 295);
     change the line below once we adjust size of viewport 
     contents */
  //this is a bad idea gtk_widget_set_usize(gpr_inst_options_window, 500, 295);
  gtk_window_set_title(GTK_WINDOW(gpr_inst_options_window),
		       _("Installable Options"));

  /* a container */
  main_vbox = gtk_vbox_new(FALSE, 1);
  gtk_widget_show(main_vbox);
  gtk_container_add(GTK_CONTAINER(gpr_inst_options_window), main_vbox);

  /* installable options window */
  local_ppd->inst_opt_window = gtk_scrolled_window_new(NULL, NULL);
  gtk_widget_show(local_ppd->inst_opt_window);
  // gtk_container_add (GTK_CONTAINER (gpr_inst_options_window),
  // local_ppd->inst_opt_window);
  gtk_box_pack_start(GTK_BOX(main_vbox), local_ppd->inst_opt_window, TRUE, 
		     TRUE,0);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW
				 (local_ppd->inst_opt_window),GTK_POLICY_NEVER,
				 GTK_POLICY_AUTOMATIC);

  /* installable options viewport */
  local_ppd->inst_opt_viewport = gtk_viewport_new(NULL, NULL);
  gtk_widget_show(local_ppd->inst_opt_viewport);
  gtk_container_add(GTK_CONTAINER(local_ppd->inst_opt_window),
		    local_ppd->inst_opt_viewport);

  /* buttonbox for "OK" button */
  main_buttonbox = gtk_hbutton_box_new();
  gtk_widget_show(main_buttonbox);
  gtk_box_pack_start(GTK_BOX(main_vbox), main_buttonbox, FALSE, TRUE, 0);
  gtk_button_box_set_layout(GTK_BUTTON_BOX(main_buttonbox), GTK_BUTTONBOX_END);

  /* ok button to close window */
  ok_button = gtk_button_new_from_stock(GTK_STOCK_OK);
  gtk_widget_show(ok_button);
  gtk_container_add(GTK_CONTAINER(main_buttonbox), ok_button);
  GTK_WIDGET_SET_FLAGS(ok_button, GTK_CAN_DEFAULT);

  /* signal handler for OK button */
  gtk_signal_connect_object(GTK_OBJECT(ok_button), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_hide),
			    GTK_OBJECT(gpr_inst_options_window));

  /* signal handler for delete window event trapped from wm Force
     a hide instead of a delete */
  gtk_signal_connect(GTK_OBJECT(gpr_inst_options_window), "delete_event",
		     GTK_SIGNAL_FUNC(gtk_widget_hide),
		     GTK_OBJECT(gpr_inst_options_window));
  return gpr_inst_options_window;
}

/* Creates the popup dialogs which indicate that there are 
   conflicting choices */
/*A. Mennucc: when the error box is  created,
  sometimes a gtk_main_quit is immediatly following... so it is unreadable!!
  so by this simple trick, we avoid the problem
 */
int messages_refcount=0;

gboolean unref_constraint_messagebox(GtkWidget * w, gpointer  data)
{
  
  messages_refcount--;
  return FALSE;
}

GtkWidget *create_constraint_messagebox(gchar * message)
{
  /* dialog widgets */
  GtkWidget *constraint_messagebox;
  /* GtkWidget *constraint_button; */

  /* main dialog */
#ifdef USE_GNOME
  constraint_messagebox =
    gnome_message_box_new(message, GNOME_MESSAGE_BOX_WARNING, NULL);
  gnome_dialog_set_close(GNOME_DIALOG(constraint_messagebox), TRUE);
  gnome_dialog_append_button(GNOME_DIALOG(constraint_messagebox),
			     GNOME_STOCK_BUTTON_OK);
  /* a container */
  GtkWidget *dialog_vbox2;
  dialog_vbox2 = GNOME_DIALOG(constraint_messagebox)->vbox;
  gtk_object_set_data(GTK_OBJECT(constraint_messagebox), "dialog_vbox2",
		      dialog_vbox2);
  gtk_widget_show(dialog_vbox2);
  GtkWidget *dialog_action_area2;
  
  /* OK button for constraint popup */
  constraint_button =
    g_list_last(GNOME_DIALOG(constraint_messagebox)->buttons)->data;
  gtk_widget_ref(constraint_button);
  gtk_object_set_data_full(GTK_OBJECT(constraint_messagebox),
			   "constraint_button", constraint_button,
			   (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show(constraint_button);
  GTK_WIDGET_SET_FLAGS(constraint_button, GTK_CAN_DEFAULT);


  dialog_action_area2 = GNOME_DIALOG(constraint_messagebox)->action_area;
  gtk_widget_ref(dialog_action_area2);
  gtk_object_set_data_full(GTK_OBJECT(constraint_messagebox),
			   "dialog_action_area2", dialog_action_area2,
			   (GtkDestroyNotify) gtk_widget_unref);
#else
  constraint_messagebox =
    gtk_message_dialog_new(NULL,//GtkWindow *parent,
			   0,//GtkDialogFlags flags,
			   GTK_MESSAGE_WARNING,//GtkMessageType type,
			   GTK_BUTTONS_OK,//GtkButtonsType buttons,
			   message);//const gchar *message_format,...);
  gtk_signal_connect(GTK_OBJECT(constraint_messagebox), "response",
		     GTK_SIGNAL_FUNC(unref_constraint_messagebox), NULL);
  
  g_signal_connect_swapped(GTK_OBJECT(constraint_messagebox),"response",
			   G_CALLBACK (gtk_widget_destroy),constraint_messagebox);
#endif
  /*A.Mennucc*/
  messages_refcount++;
  gtk_signal_connect(GTK_OBJECT(constraint_messagebox), "close",
		     GTK_SIGNAL_FUNC(unref_constraint_messagebox), NULL);

  // gtk_object_set_data(GTK_OBJECT(constraint_messagebox),
  //		      "constraint_messagebox", constraint_messagebox);


  return constraint_messagebox;
}

int get_spooler_type_debian(void)
{
  struct stat buf;
  if ( 0==stat("/usr/share/doc/cupsys-bsd", &buf ) ) {
    return  SPOOLER_CUPS;
  }
  if ( 0==stat("/usr/share/doc/lprng", &buf ) ) {
    return  SPOOLER_LPRNG;
  }
  if ( 0==stat("/usr/share/doc/lpr", &buf ) ) {
    return  SPOOLER_LPR;
  }
  if ( 0==stat("/usr/share/doc/lpr-ppd", &buf ) ) {
    return  SPOOLER_LPR;
  }
  return SPOOLER_UNKNOWN;
  
}


/*----------------------------------------------------------------
  LPRng can be distinguished from lpr by their respective 
  responses to a bad command-line option and a null input file. 
  It would be nice if we could distinguish (via lpr) if it was 
  the hacked (-o) version or unhacked, but so far I've had no 
  luck. <-mpruett>

  Not anymore... this code is useless since nowadays the output is localized <Mennucc>
----------------------------------------------------------------*/
int get_spooler_type_obsolete(void)
{
  FILE *fp;
  char buf[81];

  //Mennucc: in Debian, gpr may divert lpr to a script that calls gpr
  //   this command line avoids looping
  char *lpr = "lpr -= < /dev/null 2>&1";
  {
    struct stat buf;
    if ( 0==stat("/usr/bin/lpr.not.gpr", &buf ) ) {
      lpr = "/usr/bin/lpr.not.gpr -= < /dev/null 2>&1";
    }
  }

  /* Open a pipe to lpr */
  fp = (FILE *) popen(lpr, "r");
  if (fp) {
    
    fgets(buf, 80, fp);
    
    /* PDQ ("lpr" linked to "pdq") or CUPS? */
    if (strstr(buf, "Unknown option")) {
      fgets(buf, 80, fp);
      fgets(buf, 80, fp);
      /* Positive proof of PDQ ("lpr" linked to "pdq"). */
      if (strstr(buf, "[options]")) {
	return SPOOLER_PDQ;
      } else {
	/* Positive proof of CUPS. */
	return SPOOLER_CUPS;
      }
    }
    /* Positive proof of PPR ("lpr" linked to "ppr"). */
    else if (strstr(buf, "rejected")) {
      return SPOOLER_PPR;
    }
    /* Positive proof of LPRng. */
    else if (strstr(buf, "Illegal option")) {
      return SPOOLER_LPRNG;
    }
    /* Hacked or Unhacked version of lpr. */
    else if (strstr(buf, "empty input file")) {
      return SPOOLER_LPR;
    } else {
      return SPOOLER_UNKNOWN;
    }
    fclose(fp);
  } else {
    /* Open a pipe to ppr */
    fp = (FILE *) popen("ppr -= < /dev/null 2>&1", "r");
    if (fp) {
    
      fgets(buf, 50, fp);
      fclose(fp);
      return SPOOLER_PPR;
    } else {
      /* Open a pipe to pdq */
      fp = (FILE *) popen("pdq -= < /dev/null 2>&1", "r");
      if (fp) {
	
	fgets(buf, 50, fp);
	fclose(fp);
	return SPOOLER_PDQ;
      } else {
	/* Open a pipe to directomatic */
	fp = (FILE *) popen("directomatic -= < /dev/null 2>&1", "r");
	if (fp) {
    
	  fgets(buf, 50, fp);
	  fclose(fp);
	  return SPOOLER_FOOMATIC_DIRECT;
	} else {
	  return SPOOLER_UNKNOWN;
	}
      }
    }
  }
}

/*
 * Creates and displays a dialog for error messages
 */
void error_box(gchar * string)
{
  GtkWidget *error_dialog;

  error_dialog = create_constraint_messagebox(string);
  gtk_widget_show(error_dialog);
}

/*
 * BEGIN LOCAL FUNCTIONS
 */

/*
  * Read printcap to find names to fill printer menu and get 
  corresponding spool directories */
static GtkWidget *get_printer_menu(ppd_struct * ppd)
{
  char curr_line[500];		/* a line of text */
  char *end;			/* pointer to the end of a string */
  FILE *printcap;		/* file pointer to the printcap file */
  int num_printers;	    /* number of printers listedin printcap */
  char *printer_name;		/* name of a printer from printcap */
  char *spool_dir;	    /* spool directory associated with a given
			       printer */
  char *ppdfile = NULL;
  char targetstr[50];

  GtkWidget *current_printer_item = NULL;  /* menu of printers in 
					      printcap */
  GtkWidget *printer_menu; /* option menu containing list of 
			      printers */

  ppd_struct *local_ppd;	/* local copy of ppd_struct */

  /* redirect stderr to dialog */
  g_set_printerr_handler((GPrintFunc) error_box);

  local_ppd = ppd;

  printcap = fopen(PRINTCAP, "r");
  if (printcap == NULL) {
    g_printerr
      (_("FATAL ERROR!\n\nCannot open %s.\n\nExit the program and ensure that "
	 "a proper printcap file is present."),
          PRINTCAP);
    return NULL;
  }

  num_printers = 0;
  /* create an empty printer menu */
  printer_menu = gtk_menu_new();
  /* parse the printcap file for each printer and its spool 
     directory */
  for (;;) {
    if (fgets(curr_line, sizeof(curr_line), printcap) == NULL)	
      /* end of file */
      break;
    if (curr_line[0] == '#')	/* a printcap comment */
      continue;
    else if (curr_line[0] == 10)	/* a newline */
      continue;
    else if ((curr_line[0] == 9) || (curr_line[0] == 32)
	     || (curr_line[0] == 58)) {	/* space,tab or colon */
      if (num_printers == 0)
	continue;
      else {
	/* See if this entry is a spool_directory. */
	spool_dir = strstr(curr_line, ":sd=");
	if (spool_dir != NULL) {
	  spool_dir = spool_dir + 4;	/* move 4 spaces to the right */
	  end = strchr(spool_dir, ':');
	  if(end)
	    *end = '\0';
	  else {
	    g_warning("\
The file /etc/printcap is not conformant. As 'man 5 termcap' tells,\n\
       Termcap  entries must be defined on a single logical line,\n\
       with `\\' used to suppress the newline.  Fields  are  sepa­\n\
       rated by `:'.  The first field of each entry starts at the\n\
       left-hand margin, and contains a list  of  names  for  the\n\
       terminal, separated by '|'.\n\
It is actually customary to have one field for line, and to have ':\\'\n\
before the newline. gpr may have failed in parsing your /etc/printcap"); 
	    end = strchr(spool_dir, '\n');
	    if(end)
	      *end = '\0';
	  }

	  if (local_ppd->spool_dir == NULL)
	    local_ppd->spool_dir = g_strdup(spool_dir);

	  gtk_object_set_data(GTK_OBJECT(current_printer_item), SD,
			      g_strdup(spool_dir));
	} else {
	  strcpy(targetstr, ":ppdfile=");
	  ppdfile = strstr(curr_line, targetstr);
	  if (ppdfile) {
	    ppdfile = ppdfile + strlen(targetstr);
	    end = strchr(ppdfile, ':');
	    if(end)
	      end[0] = '\0';

	    gtk_object_set_data(GTK_OBJECT(current_printer_item), PF,
				g_strdup(ppdfile));
	  } else {
	    strcpy(targetstr, ":ppd=");
	    ppdfile = strstr(curr_line, targetstr);
	    if (ppdfile) {
	      ppdfile = ppdfile + strlen(targetstr);
	      end = strchr(ppdfile, ':');
	      if(end)
		end[0] = '\0';
	      
	      gtk_object_set_data(GTK_OBJECT(current_printer_item), PF,
				  g_strdup(ppdfile));
	    }
	  }
	}

	if (spool_dir == NULL)
	  continue;
      }
    } else {/* only thing left is the printer's name */
      printer_name = curr_line;
      /* patch suggested by Dr. Sebastian Bunka to allow for 
	 multiple entries on one line Check to see if there is a 
	 '|' and take the first printer in the list of aliases  */
      if (strchr(printer_name, '|'))
	end = strchr(printer_name, '|');
      else
	/* now back to the original code */
	end = strchr(printer_name, ':');
      if(end)
	*end = '\0';
      else
	g_warning("\
The file /etc/printcap is not conformant. As 'man 5 termcap' tells,\n\
       Termcap  entries must be defined on a single logical line,\n\
       with `\\' used to suppress the newline.  Fields  are  sepa­\n\
       rated by `:'.  The first field of each entry starts at the\n\
       left-hand margin, and contains a list  of  names  for  the\n\
       terminal, separated by '|'.\n\
It is actually customary to have one field for line, and to have ':\\'\n\
before the newline. gpr may have failed in parsing your /etc/printcap"); 

      current_printer_item = gtk_menu_item_new_with_label(printer_name);
      gtk_menu_append(GTK_MENU(printer_menu), current_printer_item);

      /* store the printer name string with the menu item for easy
	 retrieval later */
      gtk_object_set_data(GTK_OBJECT(current_printer_item), PN,
			  g_strdup(printer_name));
      /* deal with command-line options */
      if (local_ppd->printer_name == NULL)
	local_ppd->printer_name = g_strdup(printer_name);
      else if (strcmp(local_ppd->printer_name, printer_name)
	       == 0)
	gtk_menu_set_active(GTK_MENU(printer_menu), num_printers);

      gtk_widget_show(current_printer_item);

      /* call 3 functions each time a new printer is selected */
      gtk_signal_connect(GTK_OBJECT(current_printer_item), "activate",
			 GTK_SIGNAL_FUNC(set_printer_name),
			 (gpointer) local_ppd);

      gtk_signal_connect(GTK_OBJECT(current_printer_item), "activate",
			 GTK_SIGNAL_FUNC(set_spool_dir), (gpointer) local_ppd);

      gtk_signal_connect_after(GTK_OBJECT(current_printer_item), "activate",
			       GTK_SIGNAL_FUNC(grab_default_ppd),
			       (gpointer) local_ppd);

      ++num_printers;
    }
  }
  fclose(printcap);
  return (printer_menu);
}

/*----------------------------------------------------------------
  MLP
  TJH -  Can't move this to callabcks.c until we determine what 
  to do with the global.
----------------------------------------------------------------*/
static void fileentry_combo_popdown(GtkWidget * fileentry, ppd_struct * ppd)
{
  ppd_struct *local_ppd;	/* local copy of ppd struct */

  local_ppd = ppd;
  grab_ppd_file(
#ifdef USE_GNOMEFILEENTRY
		GTK_ENTRY(GLOBAL_ppdfile_fileentry)
#else
		GTK_WIDGET(fileentry)
#endif
		, (gpointer) local_ppd);
  init_ppd(NULL, (gpointer) local_ppd);
  fill_option_menus(NULL, (gpointer) local_ppd);
  return;
}

/* A tooltip helper function. Taken from Havoc Pennington's GGAD 
   book */
/* static void set_tooltip(GtkWidget * w, const gchar * tip){ */
/*   GtkTooltips *t = gtk_tooltips_new(); */

/*   gtk_tooltips_set_tip(t, w, tip, NULL); */
/* } */
// doesn't seem to be used anywhere. -ben 11-21-2001


