Logo Search packages:      
Sourcecode: pan version File versions  Download package

print.c

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
 * Pan - A Newsreader for Gtk+
 * Copyright (C) 2002  Charles Kerr <charles@rebelbase.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; version 2 of the License.
 *
 * 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 <stdlib.h>
#include <stdio.h>

#include <glib.h>
#include <gtk/gtk.h>

#include <pan/base/article.h>
#include <pan/base/pan-config.h>
#include <pan/base/pan-i18n.h>
#include <pan/base/pan-glib-extensions.h>

#include <pan/globals.h>
#include <pan/prefs.h>
#include <pan/print.h>
#include <pan/text.h>
#include <pan/util.h>


/* private structure for a print dialog */
typedef struct
{
      GtkWidget     * window;           /* GtkDialog */
      GtkWidget     * print_command;    /* entry box, should likely be 'lpr' */
      GMimeMessage  * message;
}
PrintDialog;

static void print_dialog_print_clicked (PrintDialog *dialog);
static void print_dialog_destroy (PrintDialog *dialog);
static int print_execute (const char *command, const char *message);
static void print_dialog (GMimeMessage *);


/* Thanks to Tim Roberts for the rewrite of this function.
 * @return 0 for success, -1 for any error encountered
 */
static int
print_execute (const char *command, const char *message)
{
        FILE * fp = popen (command, "w");
      if (!fp) {
            g_warning ("print_execute(): error in popen()\n");
            return -1;
      }

      /* dump the message to the pipe */
      fputs (message, fp);
      fflush (fp);
      fclose (fp);
      return 0;
}


/* Destroy the dialog and free used memory */
static void
print_dialog_destroy (PrintDialog *dialog)
{
      gtk_widget_destroy (dialog->window);
      g_object_unref (dialog->message);
      g_free (dialog);
}


/* The user pressed the Print button, build the message and call for it
 * to be printed with the provided print command
 */
static void
print_dialog_print_clicked (PrintDialog * dialog)
{
      char * text;
      char * command;

      g_return_if_fail (dialog != NULL);
      g_return_if_fail (GMIME_IS_MESSAGE (dialog->message));

      /* build the message we'll be printing */
      text = g_mime_message_to_string (dialog->message);

      /* find out how to execute it */
      command = gtk_editable_get_chars (GTK_EDITABLE(dialog->print_command), 0, -1);

      /* execute */
      if (!print_execute (command, text))
            pan_config_set_string (KEY_APP_PRINT_COMMAND, command);
      else
            pan_error_dialog_parented (dialog->window,
                                       "Printing of message \"%s\" failed!",
                                       dialog->message->subject);

      /* cleanup */
      print_dialog_destroy (dialog);
      g_free (text);
      g_free (command);
}


/* The user pressed a button. Lets like, do things and stuff. Dude. */
static void
print_dialog_cb (GtkDialog * dialog, int response, gpointer user_data)
{
      g_return_if_fail (user_data);

      switch (response)
      {
            case GTK_RESPONSE_OK:
                  print_dialog_print_clicked (user_data);
                  break;
            case GTK_RESPONSE_CANCEL:
            case GTK_RESPONSE_DELETE_EVENT:
                  print_dialog_destroy (user_data);
                  break;
            default:
                  pan_warn_if_reached ();
                  break;
      }
}


/* Make the dialog with Print and Cancel buttons */
static void
print_dialog (GMimeMessage * message)
{
      char * p;
      GtkWidget * table;
      GtkWidget * label;
      PrintDialog * dialog;

      g_return_if_fail (GMIME_IS_MESSAGE(message));
      g_object_ref (message);

      /* dialog object */
      dialog = g_new0 (PrintDialog, 1);
      dialog->message = message;
      dialog->window = gtk_dialog_new_with_buttons (_("Pan: Print"),
                                                    GTK_WINDOW(Pan.window),
                                                    GTK_DIALOG_DESTROY_WITH_PARENT,
                                                    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                                    GTK_STOCK_PRINT, GTK_RESPONSE_OK,
                                          NULL);

      /* dialog table */
      table = gtk_table_new (1, 2, FALSE);
      gtk_container_set_border_width (GTK_CONTAINER(table), GUI_PAD_SMALL);
        gtk_table_set_row_spacings (GTK_TABLE(table), GUI_PAD_SMALL);
        gtk_table_set_col_spacings (GTK_TABLE(table), GUI_PAD_SMALL);

      /* print command label */
      label = gtk_label_new (_("Print Command:"));
      gtk_misc_set_alignment (GTK_MISC(label), 1.0, 0.5);
      gtk_table_attach (GTK_TABLE (table),
                        label,
                        0, 1, 0, 1,
                        GTK_FILL, GTK_FILL,
                        4, 0);

      /* print command edit field */
      dialog->print_command = gtk_entry_new ();
      p = pan_config_get_string (KEY_APP_PRINT_COMMAND, DEFAULT_VALUE_APP_PRINT_COMMAND);
      pan_gtk_entry_set_text (dialog->print_command, p);
      g_free (p);
      gtk_table_attach (GTK_TABLE(table),
                        dialog->print_command,
                        1, 2, 0, 1,
                        GTK_FILL, GTK_FILL,
                        4, 0);

      /* add the main dialog table to the dialog */
      gtk_container_add (GTK_CONTAINER(GTK_DIALOG(dialog->window)->vbox),
                         table);
      g_signal_connect (GTK_OBJECT(dialog->window), "response",
                        G_CALLBACK(print_dialog_cb), dialog);

      gtk_widget_show_all (dialog->window);
}


/**
 * The only public routine, gets called from the Print button on the toolbar
 * of a message window or File->Print from any menu in Pan.
 **/
void
print_cb (GtkWidget * widget_notused,
          gpointer    data_notused)
{
      GMimeMessage * message = get_current_message ();

      if (message != NULL)
            print_dialog (message);
      else
            pan_error_dialog (_("You haven't loaded an article to print."));
}

#ifdef HAVE_GNOME_PRINT
void
pan_gnome_print_cb (void)
{
      /* FIXME(csk): gnome-print stuff goes here */
      print_cb (NULL, NULL);
}

void
pan_gnome_print_preview_cb (void)
{
      /* FIXME(csk): gnome-print stuff goes here */
      print_cb (NULL, NULL);
}
#endif

Generated by  Doxygen 1.6.0   Back to index