/*
* Maketool - GTK-based front end for gmake
* Copyright (c) 1999-2003 Greg Banks
*
* 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 "maketool.h"
#include "log.h"
#include "ui.h"
#include "util.h"
CVSID("$Id: print.c,v 1.15 2003/09/29 01:07:20 gnb Exp $");
static GtkWidget *print_shell = 0;
typedef enum { D_PRINTER, D_FILE, D_NUM_DESTS } DEST;
static GtkWidget *dest_radio[D_NUM_DESTS];
static GtkWidget *file_entry;
static GtkWidget *printer_entry;
/*
* List of strings which are the simple names of printers
* TODO: handle separate name/description
*/
static GList *lpr_printers = 0;
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
static gboolean _lpr_initialised = FALSE;
static void
_lpr_add_printer(const char *name)
{
#if DEBUG > 5
fprintf(stderr, "Adding printer \"%s\"\n", name);
#endif
lpr_printers = g_list_append(lpr_printers, g_strdup(name));
}
/*
* UNIX print system specific functions.
*/
#if HAVE_ETC_PRINTCAP
/* TODO: have a default-printer variable & assign it here */
void
lpr_init(void)
{
FILE *fp;
gboolean in_entry = FALSE;
char buf[1024];
if (_lpr_initialised)
return;
_lpr_initialised = TRUE;
if ((fp = fopen("/etc/printcap", "r")) == 0)
{
perror("/etc/printcap");
return;
}
while (fgets(buf, sizeof(buf), fp) != 0)
{
char *x;
if ((x = strchr(buf, '\n')) != 0)
*x = 0;
if ((x = strchr(buf, '\r')) != 0)
*x = 0;
if (buf[0] == '#')
continue; /* comment line */
if (in_entry && buf[strlen(buf)-1] == '\\')
continue; /* ignore everything except the first line */
if (isspace(buf[0]))
continue; /* ignore empty lines */
/* first :-seperated field is list of names |-seperated */
x = strchr(buf, ':');
if (x != 0)
*x = '\0';
x = strchr(buf, '|');
if (x != 0)
*x = '\0';
_lpr_add_printer(buf);
}
fclose(fp);
}
static char *
_lpr_job_command(const char *printer)
{
return g_strdup_printf("lpr -P\"%s\"", printer);
}
#elif HAVE_LPSTAT
void
lpr_init(void)
{
FILE *fp;
char *cmd;
char buf[1024];
if (_lpr_initialised)
return;
_lpr_initialised = TRUE;
/* TODO: check that lpstat -c (IIRC) and output are correct */
cmd = g_strdup_printf("%s -c", LPSTAT_COMMAND);
fp = popen(cmd, "r");
g_free(cmd);
if (fp == 0)
{
perror(LPSTAT_COMMAND);
return;
}
while (fgets(buf, sizeof(buf), fp) != 0)
{
char *x;
if ((x = strchr(buf, '\n')) != 0)
*x = 0;
if ((x = strchr(buf, '\r')) != 0)
*x = 0;
_lpr_add_printer(buf);
}
pclose(fp);
}
static char *
_lpr_job_command(const char *printer)
{
return g_strdup_printf("lp -d \"%s\"", printer);
}
#else
void
lpr_init(void)
{
fprintf(stderr, "No printer support compiled into this executable\n");
}
static char *
_lpr_job_command(const char *printer)
{
return g_strdup("echo No printer support compiled into this executable");
}
#endif
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
FILE *
lpr_job_begin(const char *printer)
{
FILE *fp;
char *cmd;
cmd = _lpr_job_command(printer);
message("Printing using: %s", cmd);
fp = popen(cmd, "w");
g_free(cmd);
return fp;
}
void
lpr_job_end(FILE *fp)
{
pclose(fp);
}
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
static DEST
print_get_dest(void)
{
int i;
for (i=0 ; i<D_NUM_DESTS ; i++)
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dest_radio[i])))
return (DEST)i;
return (DEST)0; /* default value */
}
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
static void
print_ok_cb(GtkWidget *w, gpointer data)
{
FILE *fp;
const char *printer;
const char *file;
DEST dest = print_get_dest();
switch (dest)
{
case D_PRINTER:
printer = gtk_entry_get_text(GTK_ENTRY(printer_entry));
if ((fp = lpr_job_begin(printer)) == 0)
{
/* TODO: lpr_ API should allow us an error message */
message(_("Can't create job on printer `%s'"), printer);
return;
}
log_print(fp);
lpr_job_end(fp);
break;
case D_FILE:
/* TODO: check filename */
file = gtk_entry_get_text(GTK_ENTRY(file_entry));
message("Printing to file %s", file);
fp = fopen(file, "w");
log_print(fp);
fclose(fp);
break;
default:
fprintf(stderr, "Unknown destination %d\n", (int)dest);
break;
}
gtk_widget_hide(print_shell);
}
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
static void
print_cancel_cb(GtkWidget *w, gpointer data)
{
gtk_widget_hide(print_shell);
}
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
static void
print_file_func(const char *filename)
{
gtk_entry_set_text(GTK_ENTRY(file_entry), filename);
}
static void
print_file_browse_cb(GtkWidget *w, gpointer data)
{
static GtkWidget *filesel = 0;
if (filesel == 0)
{
filesel = ui_create_file_sel(
toplevel,
_("Maketool: Choose Output File"),
print_file_func,
gtk_entry_get_text(GTK_ENTRY(file_entry)));
}
/* TODO: set current filename from file_entry *every* time */
/* TODO: modal popup */
gtk_widget_show(filesel);
}
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
static void
print_dest_changed_cb(GtkWidget *w, gpointer data)
{
DEST dest = print_get_dest();
int i;
for (i=0 ; i<D_NUM_DESTS ; i++)
ui_group_set_sensitive(GR_PRINT_PRINTER+i, (i == (int)dest));
}
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
static void
create_print_shell(void)
{
GtkWidget *table;
GtkWidget *combo;
GtkWidget *button;
GList *list;
int row = 0;
/* get list of printers from system */
lpr_init();
print_shell = ui_create_dialog(toplevel, _("Maketool: Print"));
ui_set_help_tag(print_shell, "print-window");
gtk_container_border_width(GTK_CONTAINER(GTK_DIALOG(print_shell)->vbox), SPACING);
table = gtk_table_new(3, 2, FALSE);
gtk_container_border_width(GTK_CONTAINER(table), SPACING);
gtk_table_set_row_spacings(GTK_TABLE(table), SPACING);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(print_shell)->vbox), table);
gtk_widget_show(table);
dest_radio[D_PRINTER] = gtk_radio_button_new_with_label_from_widget(
0, _("Print to printer"));
gtk_signal_connect(GTK_OBJECT(dest_radio[D_PRINTER]), "toggled",
GTK_SIGNAL_FUNC(print_dest_changed_cb), 0);
gtk_table_attach_defaults(GTK_TABLE(table), dest_radio[D_PRINTER], 0, 1, row, row+1);
gtk_widget_show(dest_radio[D_PRINTER]);
combo = gtk_combo_new();
list = 0;
if (lpr_printers != 0)
list = g_list_copy(lpr_printers);
else
list = g_list_append(list, _("no printers on this system"));
gtk_combo_set_popdown_strings(GTK_COMBO(combo), list);
gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(combo)->entry), FALSE);
gtk_table_attach_defaults(GTK_TABLE(table), combo, 1, 3, row, row+1);
gtk_widget_show(combo);
printer_entry = GTK_COMBO(combo)->entry;
ui_group_add(GR_PRINT_PRINTER, combo);
row++;
dest_radio[D_FILE] = gtk_radio_button_new_with_label_from_widget(
GTK_RADIO_BUTTON(dest_radio[D_PRINTER]), _("Print to file"));
gtk_signal_connect(GTK_OBJECT(dest_radio[D_PRINTER]), "toggled",
GTK_SIGNAL_FUNC(print_dest_changed_cb), 0);
gtk_table_attach_defaults(GTK_TABLE(table), dest_radio[D_FILE], 0, 1, row, row+1);
gtk_widget_show(dest_radio[D_FILE]);
combo = gtk_combo_new();
list = 0;
list = g_list_append(list, "maketool.ps");
gtk_combo_set_popdown_strings(GTK_COMBO(combo), list);
gtk_table_attach_defaults(GTK_TABLE(table), combo, 1, 2, row, row+1);
gtk_widget_show(combo);
file_entry = GTK_COMBO(combo)->entry;
ui_group_add(GR_PRINT_FILE, combo);
button = gtk_button_new_with_label(_("Browse..."));
gtk_signal_connect(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(print_file_browse_cb), 0);
gtk_table_attach(GTK_TABLE(table), button, 2, 3, row, row+1,
(GtkAttachOptions)0, (GtkAttachOptions)0,
SPACING, 0);
gtk_widget_show(button);
ui_group_add(GR_PRINT_FILE, button);
row++;
ui_dialog_create_button(print_shell, _("OK"),
print_ok_cb, (gpointer)0);
ui_dialog_create_button(print_shell, _("Page Setup..."),
print_page_setup_cb, (gpointer)0);
ui_dialog_create_button(print_shell, _("Cancel"),
print_cancel_cb, (gpointer)0);
if (lpr_printers == 0)
{
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dest_radio[D_FILE]), TRUE);
gtk_widget_set_sensitive(dest_radio[D_PRINTER], FALSE);
}
print_dest_changed_cb((GtkWidget*)0, (gpointer)0);
}
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
void
file_print_cb(GtkWidget *w, gpointer data)
{
if (print_shell == 0)
create_print_shell();
gtk_widget_show(print_shell);
}
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
/*END*/
syntax highlighted by Code2HTML, v. 0.9.1