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

save-ui.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
 */

/*********************
**********************  Includes
*********************/

#include <config.h>

#include <string.h>

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

#include <pan/base/base-prefs.h>
#include <pan/base/debug.h>
#include <pan/base/log.h>
#include <pan/base/pan-i18n.h>
#include <pan/base/pan-glib-extensions.h>
#include <pan/base/util-file.h>

#include <pan/globals.h>
#include <pan/prefs.h>
#include <pan/queue.h>
#include <pan/pan-file-entry.h>
#include <pan/task-bodies.h>
#include <pan/task-save.h>
#include <pan/save-ui.h>
#include <pan/text.h>
#include <pan/util.h>

/*********************
**********************  Private Function Prototypes
*********************/

static gchar * _path = NULL;
static gboolean _high_priority = FALSE;
static gboolean _save_attachments = TRUE;
static gboolean _save_text = FALSE;

typedef enum
{
      SAVE_AS,
      MANUAL_DECODE
}
SaveMode;

#define SAVE_MODE_KEY "save_mode"

/*********************
**********************  BEGINNING OF SOURCE
*********************/

typedef struct
{
      GtkWidget * dialog;

      GtkWidget * save_text_check;
      GtkWidget * save_attachments_check;
      GtkWidget * directory_entry;

      GtkWidget * priority_high_radio;
      GtkWidget * priority_low_radio;

      GSList *gslists_of_unowned_articles;
}
SaveAsDialogStruct;

#define IS_ACTIVE(w) gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))

static void
save_attachment_as_dialog_response_cb (GtkDialog   * dialog,
                                       int           response,
                                       gpointer      user_data)
{
      const SaveMode save_mode = GPOINTER_TO_INT (g_object_get_data (G_OBJECT(dialog), SAVE_MODE_KEY));
      SaveAsDialogStruct* save = (SaveAsDialogStruct*)user_data;
      GSList * l;
      GSList * tasks = NULL;
      char * path;
      debug_enter ("save_attachment_as_dialog_clicked_cb");

      if (response == GTK_RESPONSE_DELETE_EVENT ||
          response == GTK_RESPONSE_CANCEL)
      {
            pan_lock();
            gtk_widget_destroy (GTK_WIDGET(dialog));
            pan_unlock();
            return;
      }

      /**
      ***  Get Path
      **/

      path = pan_file_normalize (pan_file_entry_get (save->directory_entry), NULL);

      /**
      ***  Get Body Filename
      **/

      _save_text = IS_ACTIVE(save->save_text_check);

      _save_attachments = IS_ACTIVE(save->save_attachments_check);

      /**
      ***  Queue 'em
      **/

      for (l=save->gslists_of_unowned_articles; l!=NULL; l=l->next)
      {
            GSList * m;
            GSList * articles = (GSList*) l->data;
            const Article * article = ARTICLE(articles->data);
            char * expanded_path = NULL;
            GPtrArray * tmp;
            PanObject * task;

            /* make an array of articles */
            tmp = g_ptr_array_sized_new (64);
            for (m=(GSList*)l->data; m!=NULL; m=m->next)
                  g_ptr_array_add (tmp, m->data);
            if (save_mode != MANUAL_DECODE)
                  task_save_weed_duplicates (tmp);
            task = task_save_new_from_articles ((const Article**)tmp->pdata, tmp->len);
            g_ptr_array_free (tmp, TRUE);

            expanded_path = expand_download_dir (path, group_get_name(article->group));

            if (_save_attachments)
                  task_save_set_attachments (TASK_SAVE(task), expanded_path, NULL);

            if (_save_text)
                  task_save_set_bodies (TASK_SAVE(task), expanded_path, NULL);

            tasks = g_slist_prepend (tasks, task);

            g_free (expanded_path);
      }

      if (tasks != NULL)
      {
            tasks = g_slist_reverse (tasks);
            queue_insert_tasks (tasks, _high_priority ? 0 : -1);
      }

      /* cleanup */
      g_free (path);
      pan_lock();
      gtk_widget_destroy (GTK_WIDGET(dialog));
      pan_unlock();
      debug_exit ("save_attachment_as_dialog_clicked_cb");
}

static void
save_toggled_cb (GtkToggleButton    * togglebutton,
                 gpointer              user_data)
{
      SaveAsDialogStruct * save = (SaveAsDialogStruct*) user_data;

      gtk_dialog_set_response_sensitive (GTK_DIALOG(save->dialog),
                                         GTK_RESPONSE_OK, 
                                         IS_ACTIVE(save->save_text_check) || IS_ACTIVE(save->save_attachments_check));
}

static void
priority_toggled_cb (GtkToggleButton    * togglebutton,
                     gpointer              user_data)
{
      SaveAsDialogStruct *save = (SaveAsDialogStruct*) user_data;
      gboolean b = gtk_toggle_button_get_active (togglebutton);
      _high_priority = togglebutton==GTK_TOGGLE_BUTTON(save->priority_high_radio) ? b : !b;
}

static void
save_attachment_as_dialog_destroy_cb (GtkDialog * d, gpointer user_data)
{
      GSList * l;
      SaveAsDialogStruct *save = (SaveAsDialogStruct*) user_data;

      /* free the save-as-dialog utility structure */
      for (l=save->gslists_of_unowned_articles; l!=NULL; l=l->next)
            g_slist_free ((GSList*)l->data);

      /* cleanup */
      g_slist_free (save->gslists_of_unowned_articles);
      g_free (save);
}

static void
user_specified_path_changed_cb (GtkEditable   * editable,
                                gpointer        user_data)
{
      replace_gstr (&_path,
                    gtk_editable_get_chars (GTK_EDITABLE(editable), 0, -1));
}

static void
directory_entry_activate_cb (GtkEntry * entry, gpointer user_data)
{
      SaveAsDialogStruct * data = (SaveAsDialogStruct*) user_data;
      gtk_dialog_response (GTK_DIALOG(data->dialog), GTK_RESPONSE_OK);
}

static void
create_save_attachment_as_dialog (GSList       * gslists_of_unowned_articles,
                                  const char   * optional_download_dir,
                                  SaveMode       save_mode)
{
      int row;
      GtkWidget * t;
      GtkWidget * w;
      GtkWidget * h;
      GtkWidget * dialog;
      SaveAsDialogStruct * data;
      const char * cpch;

      data = g_new0 (SaveAsDialogStruct, 1);
      data->gslists_of_unowned_articles = gslists_of_unowned_articles;

      pan_lock ();

      switch (save_mode) {
            case MANUAL_DECODE: cpch = _("Pan: Manual Decode"); break;
            default: cpch = _("Pan: Save As"); break;
      }

      /* create & parent the dialog */
      dialog = gtk_dialog_new_with_buttons (cpch,
                                            GTK_WINDOW(Pan.window),
                                            GTK_DIALOG_DESTROY_WITH_PARENT,
                                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                            GTK_STOCK_SAVE, GTK_RESPONSE_OK,
                                            NULL);
      g_object_set_data (G_OBJECT(dialog), SAVE_MODE_KEY, GINT_TO_POINTER(save_mode));
      data->dialog = dialog;
      gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL);

      row = 0;
      t = pan_hig_workarea_create ();
      gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), t, TRUE, TRUE, 0);

      pan_hig_workarea_add_section_title (t, &row, _("Files"));

            pan_hig_workarea_add_section_spacer (t, row, 2);

            w = pan_hig_workarea_add_wide_checkbutton (t, &row, _("Save Te_xt"),  _save_text);
            data->save_text_check = w;

            w = pan_hig_workarea_add_wide_checkbutton (t, &row, _("Save _Attachments"),  _save_attachments);
            data->save_attachments_check = w;

            /* directory entry */
            h = gtk_hbox_new (FALSE, GUI_PAD_SMALL);
            w = data->directory_entry = pan_file_entry_new (_("Save Files in Directory"));
            gtk_box_pack_start (GTK_BOX(h), w, TRUE, TRUE, 0);
            if (is_nonempty_string(_path))
                  cpch = _path;
            else if (is_nonempty_string (optional_download_dir))
                  cpch = optional_download_dir;
            else
                  cpch = download_dir;
            pan_file_entry_set (w, cpch);
            gtk_widget_set_usize (GTK_WIDGET(w), 400, 0);
            w = gtk_button_new_with_mnemonic (_("_Help"));
            gtk_box_pack_start (GTK_BOX(h), w, FALSE, FALSE, 0);
            g_signal_connect_swapped (w, "clicked", G_CALLBACK (show_group_substitution_help_dialog), dialog);
            pan_hig_workarea_add_row (t, &row, _("_Directory:"), h, pan_file_entry_gtk_entry(data->directory_entry));

      pan_hig_workarea_add_section_divider (t, &row);
      pan_hig_workarea_add_section_title (t, &row, _("Priority"));

            pan_hig_workarea_add_section_spacer (t, row, 2);

            /* front of queue */
            w = data->priority_high_radio = gtk_radio_button_new_with_mnemonic (NULL, _("Add to the _top of the Task Manager's List"));
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), _high_priority);
            gtk_table_attach_defaults (GTK_TABLE(t), w, 1, 4, row, row+1);
            ++row;

            /* back of queue (default) */
            w = gtk_radio_button_new_with_mnemonic_from_widget (
                  GTK_RADIO_BUTTON(w), _("Add to the b_ottom of the Task Manager's List"));
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), !_high_priority);
            data->priority_low_radio = w;
            gtk_table_attach_defaults (GTK_TABLE(t), w, 1, 4, row, row+1);
            ++row;

      /**
      ***  Wire it up
      **/

      g_signal_connect (GTK_OBJECT(dialog), "response",
                        G_CALLBACK(save_attachment_as_dialog_response_cb), data);
      g_signal_connect (GTK_OBJECT(dialog), "destroy",
                        G_CALLBACK(save_attachment_as_dialog_destroy_cb), data); 
      g_signal_connect (GTK_OBJECT(data->priority_low_radio), "toggled",
                        G_CALLBACK(priority_toggled_cb), data);
      g_signal_connect (GTK_OBJECT(data->priority_high_radio), "toggled",
                        G_CALLBACK(priority_toggled_cb), data);
      g_signal_connect (GTK_OBJECT(data->save_text_check), "toggled",
                        G_CALLBACK(save_toggled_cb), data);
      g_signal_connect (GTK_OBJECT(data->save_attachments_check), "toggled",
                        G_CALLBACK(save_toggled_cb), data);
      g_signal_connect (pan_file_entry_gtk_entry(data->directory_entry), "changed",
                        G_CALLBACK(user_specified_path_changed_cb), NULL);
      g_signal_connect (pan_file_entry_gtk_entry(data->directory_entry), "activate",
                        G_CALLBACK(directory_entry_activate_cb), data);
        save_toggled_cb (NULL, data);

      gtk_widget_show_all (dialog);
      pan_unlock ();
}


void
save_attachment_as (GSList      * gslists_of_unowned_articles,
                    const char  * optional_download_dir)
{
      create_save_attachment_as_dialog (gslists_of_unowned_articles,
                                        optional_download_dir,
                                        SAVE_AS);
}

void
manual_decode_attachment_as (GSList      * gslists_of_unowned_articles,
                             const char  * optional_download_dir)
{
      create_save_attachment_as_dialog (gslists_of_unowned_articles,
                                        optional_download_dir,
                                        MANUAL_DECODE);
}

Generated by  Doxygen 1.6.0   Back to index