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

rule-edit-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/debug.h>
#include <pan/base/pan-glib-extensions.h>
#include <pan/base/pan-i18n.h>
#include <pan/base/serverlist.h>

#include <pan/filter-ui.h>
#include <pan/filters/filter-manager.h>
#include <pan/filters/filter-top.h>

#include <pan/rules/rule.h>
#include <pan/rules/rule-edit-ui.h>

#include <pan/util.h>

/*********************
**********************  Defines / Enumerated types
*********************/

/*********************
**********************  Macros
*********************/

/*********************
**********************  Structures / Typedefs
*********************/

typedef struct
{
      GtkWidget * dialog;

      GtkWidget * name_entry;
      GtkWidget * apply_to_incoming_tb;

      GtkWidget * groups_all_rb;
      GtkWidget * groups_phrase_rb;
      GtkWidget * groups_phrase_entry;
      GtkWidget * groups_list_rb;
      GtkWidget * groups_sub_clist;
      GtkWidget * groups_apply_clist;

      GtkWidget * filter_text;
      GtkWidget * filter_om;
      GtkWidget * filter_edit_filters_button;

      GtkWidget * action_alert_msg_tb;
      GtkWidget * action_alert_msg_entry;
      GtkWidget * action_mark_tb;
      GtkWidget * action_mark_read_rb;
      GtkWidget * action_mark_unread_rb;
      GtkWidget * action_decode_tb;
      GtkWidget * action_decode_path_file_entry;
      GtkWidget * action_flag_tb;
      GtkWidget * action_download_body_tb;
      GtkWidget * action_delete_tb;
      GtkWidget * action_ignore_thread_tb;
      GtkWidget * action_watch_thread_tb;

      gchar * filter_name;
}
RuleEditDialog;

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

/*********************
**********************  Variables
*********************/

/***********
************  Extern
***********/

/***********
************  Public
***********/

/***********
************  Private
***********/

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

/************
*************  PRIVATE
***********/

/*****
******
******  ACTIONS
******
*****/

static GtkWidget*
create_action_tab (RuleEditDialog * d)
{
      gint row;
      GtkWidget *w, *h, *t;
       
      row = -1;

      t = gtk_table_new (10, 3, FALSE);
      gtk_table_set_row_spacings (GTK_TABLE(t), GUI_PAD_SMALL);
      gtk_table_set_col_spacings (GTK_TABLE(t), GUI_PAD_SMALL);
      gtk_container_set_border_width (GTK_CONTAINER(t), GUI_PAD);

      /* show alert */
      ++row;
      w = d->action_alert_msg_tb = gtk_check_button_new_with_mnemonic (_("Show a_lert:"));
      gtk_table_attach (GTK_TABLE(t), w, 0, 1, row, row+1, GTK_FILL, 0, 0, 0);
      w = d->action_alert_msg_entry = gtk_entry_new ();
      gtk_table_attach (GTK_TABLE(t), w, 1, 3, row, row+1, GTK_EXPAND|GTK_FILL, 0, 0, 0);

      /* mark as */
      ++row;
      w = d->action_mark_tb = gtk_check_button_new_with_label (_("Mark as"));
      gtk_table_attach (GTK_TABLE(t), w, 0, 1, row, row+1, GTK_FILL, 0, 0, 0);
      h = gtk_hbox_new (TRUE, 0);
      w = d->action_mark_read_rb = gtk_radio_button_new_with_label (NULL, _("Read"));
      gtk_box_pack_start (GTK_BOX(h), w, FALSE, TRUE, 0);
      w = d->action_mark_unread_rb = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON(w), _("Unread"));
      gtk_box_pack_start (GTK_BOX(h), w, FALSE, TRUE, 0);
      w = gtk_frame_new (NULL);
      gtk_container_add (GTK_CONTAINER(w), h);
      gtk_table_attach (GTK_TABLE(t), w, 1, 2, row, row+1, GTK_EXPAND|GTK_FILL, 0, 0, 0);

      /* decode to */
      ++row;
      w = d->action_decode_tb = gtk_check_button_new_with_mnemonic (_("Save attachments in:"));
      gtk_table_attach (GTK_TABLE(t), w, 0, 1, row, row+1, GTK_FILL, 0, 0, 0);
      w = d->action_decode_path_file_entry = gtk_entry_new ();
      gtk_table_attach (GTK_TABLE(t), w, 1, 2, row, row+1, GTK_EXPAND|GTK_FILL, 0, 0, 0);

      /* flag for retrieval */
      ++row;
      w = d->action_flag_tb = gtk_check_button_new_with_mnemonic (_("_Flag body for download"));
      gtk_table_attach (GTK_TABLE(t), w, 0, 3, row, row+1, GTK_FILL, 0, 0, 0);

      /* download body */
      ++row;
      w = d->action_download_body_tb = gtk_check_button_new_with_mnemonic (_("_Retrieve Body"));
      gtk_table_attach (GTK_TABLE(t), w, 0, 3, row, row+1, GTK_FILL, 0, 0, 0);

      /* watch */
      ++row;
      w = d->action_watch_thread_tb = gtk_check_button_new_with_mnemonic (_("_Watch thread (highlights the thread)"));
      gtk_table_attach (GTK_TABLE(t), w, 0, 3, row, row+1, GTK_FILL, 0, 0, 0);

      /* ignore */
      ++row;
      w = d->action_ignore_thread_tb = gtk_check_button_new_with_mnemonic (_("_Ignore thread (hides the thread by default)"));
      gtk_table_attach (GTK_TABLE(t), w, 0, 3, row, row+1, GTK_FILL, 0, 0, 0);

      /* delete */
      ++row;
      w = d->action_delete_tb = gtk_check_button_new_with_mnemonic (_("_Delete article"));
      gtk_table_attach (GTK_TABLE(t), w, 0, 3, row, row+1, GTK_FILL, 0, 0, 0);

      return t;
}

static void
populate_actions_tab (RuleEditDialog * d, const Rule * r)
{
      gboolean b;
      gboolean b2;
      GtkWidget * w;

      /* alert message */
      w = d->action_alert_msg_tb;
      b = r!=NULL && (r->action->flags & RULE_ACTION_SHOW_ALERT) != 0;
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(w), b);
      w = d->action_alert_msg_entry;
      pan_gtk_entry_set_text (w, b ? r->action->alert_message : "");

      /* mark read/unread */
      b  = r!=NULL && (r->action->flags & RULE_ACTION_MARK_READ) != 0;
      b2 = r!=NULL && (r->action->flags & RULE_ACTION_MARK_UNREAD) != 0;
      w = d->action_mark_tb;
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(w), b || b2);
      w = d->action_mark_read_rb;
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(w), b);
      w = d->action_mark_unread_rb;
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(w), b2);

      /* decode */
      b = r!=NULL && (r->action->flags & RULE_ACTION_DECODE) != 0;
      w = d->action_decode_tb;
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(w), b);
      w = d->action_decode_path_file_entry;
      pan_gtk_entry_set_text (w, b ? r->action->decode_path : "");

      /* tag for retrieval */
      b = r!=NULL && (r->action->flags & RULE_ACTION_TAG_FOR_RETRIEVAL) != 0;
      w = d->action_flag_tb;
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(w), b);

      /* retrieve body */
      b = r!=NULL && (r->action->flags & RULE_ACTION_RETREIVE_BODY) != 0;
      w = d->action_download_body_tb;
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(w), b);

      /* watch */
      b = r!=NULL && (r->action->flags & RULE_ACTION_WATCH) != 0;
      w = d->action_watch_thread_tb;
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(w), b);

      /* ignore */
      b = r!=NULL && (r->action->flags & RULE_ACTION_IGNORE) != 0;
      w = d->action_ignore_thread_tb;
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(w), b);

      /* discard */
      b = r!=NULL && (r->action->flags & RULE_ACTION_DISCARD) != 0;
      w = d->action_delete_tb;
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(w), b);
}

static void
rule_from_action_tab (RuleEditDialog * d, Rule * r)
{
      GtkWidget * w;
      gchar * pch;

      r->action->flags = 0;

      /* alert */
      w = d->action_alert_msg_tb;
      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w))) {
            r->action->flags |= RULE_ACTION_SHOW_ALERT;
            w = d->action_alert_msg_entry;
            pch = gtk_editable_get_chars (GTK_EDITABLE(w), 0, -1);
            replace_gstr (&r->action->alert_message, pch);
      }

      /* mark */
      w = d->action_mark_tb;
      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w))) {
            w = d->action_mark_read_rb;
            if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w)))
                  r->action->flags |= RULE_ACTION_MARK_READ;
            else
                  r->action->flags |= RULE_ACTION_MARK_UNREAD;
      }

      /* decode */
      w = d->action_decode_tb;
      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w))) {
            r->action->flags |= RULE_ACTION_DECODE;
            w = d->action_decode_path_file_entry;
            pch = gtk_editable_get_chars (GTK_EDITABLE(w), 0, -1);
            replace_gstr (&r->action->decode_path, pch);
      }

      /* flag */
      w = d->action_flag_tb;
      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w)))
            r->action->flags |= RULE_ACTION_TAG_FOR_RETRIEVAL;

      /* download */
      w = d->action_download_body_tb;
      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w)))
            r->action->flags |= RULE_ACTION_RETREIVE_BODY;

      /* watch */
      w = d->action_watch_thread_tb;
      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w)))
            r->action->flags |= RULE_ACTION_WATCH;

      /* ignore */
      w = d->action_ignore_thread_tb;
      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w)))
            r->action->flags |= RULE_ACTION_IGNORE;

      /* discard */
      w = d->action_delete_tb;
      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(w)))
            r->action->flags |= RULE_ACTION_DISCARD;
}

/*****
******
******  FILTERS
******
*****/

static void
populate_filter_text (RuleEditDialog * d, const gchar * filter_name)
{
      Filter * f = filter_manager_get_named_filter (filter_name);
      char * pch = filter_to_string_deep (f);

      /* update the text */

      pan_lock ();
      gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW(d->filter_text)), pch, -1);
      pan_unlock ();

      /* cleanup */
      pan_object_unref (PAN_OBJECT(f));
      g_free (pch);
}

static void
set_filter_cb (GtkMenuItem * item, gpointer data)
{
      RuleEditDialog * d = (RuleEditDialog*) data;
      const gchar * filter_name = (const gchar*) gtk_object_get_data (GTK_OBJECT(item), "filter_name");
      replace_gstr (&d->filter_name, g_strdup(filter_name));
      populate_filter_text (d, filter_name);
}

static void
populate_filter_tab (RuleEditDialog * d, const gchar * filter_name)
{
      gint i;
      gint index = 0;
      GtkWidget * menu = gtk_menu_new ();
      GPtrArray * a = g_ptr_array_new ();
      FilterTop * ft;

      /* populate the option menu */
      filter_manager_get_filters (a);
      for (i=0; i<a->len; ++i)
      {
            GtkWidget * item;
            FilterTop * ft = FILTER_TOP(g_ptr_array_index(a,i));
            if (ft==NULL)
                  continue;

            if (!pan_strcmp (ft->name, filter_name))
                  index = i;

            item = gtk_menu_item_new_with_label (ft->name);
            gtk_object_set_data_full (GTK_OBJECT(item), "filter_name", g_strdup(ft->name), g_free);
            gtk_signal_connect (GTK_OBJECT(item), "activate", (GtkSignalFunc)set_filter_cb, d);
            gtk_widget_show (item);
            gtk_menu_append (GTK_MENU(menu), item);
      }
      gtk_option_menu_set_menu (GTK_OPTION_MENU(d->filter_om), menu);
      gtk_option_menu_set_history(GTK_OPTION_MENU(d->filter_om), index);
      gtk_widget_show_all (GTK_WIDGET(d->filter_om));

      /* populate the text window */
      if (a->len)
      {
            ft = FILTER_TOP(g_ptr_array_index(a,index));
            replace_gstr (&d->filter_name, g_strdup(ft->name));
            populate_filter_text (d, d->filter_name);
      }

      /* cleanup */
      pan_g_ptr_array_foreach (a, (GFunc)pan_object_unref, NULL);
      g_ptr_array_free (a, TRUE);
}

static void
edit_filters_cb (GtkButton * button, gpointer data)
{
      RuleEditDialog * d = (RuleEditDialog*) data;
        GtkWidget * w = filter_dialog_new (GTK_WINDOW(d->dialog));
      gtk_widget_show_all (w);
}

static void
filters_changed_cb (gpointer a, gpointer b, gpointer c)
{
      RuleEditDialog * d = (RuleEditDialog*)c;
      populate_filter_tab (d, d->filter_name);
}

static GtkWidget*
create_filter_tab (RuleEditDialog * d)
{
      GtkWidget     * h;
      GtkWidget     * w;
      GtkWidget     * top;
      GtkWidget     * text_parent;
      GtkPolicyType   policy = GTK_POLICY_AUTOMATIC;

      top = gtk_vbox_new (FALSE, GUI_PAD_SMALL);
      gtk_container_set_border_width (GTK_CONTAINER(top), GUI_PAD);

      /* filter optionmenu */
      d->filter_om = gtk_option_menu_new ();

      /* filter view */
      d->filter_text = gtk_text_view_new ();

      text_parent = gtk_scrolled_window_new (NULL, NULL);
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(text_parent),
            policy, policy);
      gtk_container_add (GTK_CONTAINER(text_parent), d->filter_text);
      
      /* "edit filters" button */
      h = gtk_hbox_new (FALSE, GUI_PAD_SMALL);
      gtk_container_set_border_width (GTK_CONTAINER(h), GUI_PAD_SMALL);
      w = gtk_image_new_from_stock (GTK_STOCK_PROPERTIES, GTK_ICON_SIZE_BUTTON);
      gtk_box_pack_start (GTK_BOX(h), w, 0, 0, 0);
      w = gtk_label_new (_("Edit Filters"));
      gtk_box_pack_start (GTK_BOX(h), w, 0, 0, 0);
      d->filter_edit_filters_button = w = gtk_button_new ();
      gtk_signal_connect (GTK_OBJECT(w), "clicked", GTK_SIGNAL_FUNC(edit_filters_cb), d);
      gtk_container_add (GTK_CONTAINER(w), h);

      /* lay it all out */
      h = gtk_hbox_new (FALSE, GUI_PAD);
      gtk_box_pack_start (GTK_BOX(h), gtk_label_new(_("Select Filter:")), FALSE, FALSE, 0);
      gtk_box_pack_start (GTK_BOX(h), d->filter_om, TRUE, TRUE, 0);
      gtk_box_pack_start (GTK_BOX(h), gtk_label_new("      "), FALSE, FALSE, 0);
      gtk_box_pack_start (GTK_BOX(h), d->filter_edit_filters_button, FALSE, FALSE, 0);
      gtk_box_pack_start (GTK_BOX(top), h, FALSE, FALSE, 0);
      gtk_box_pack_start (GTK_BOX(top), text_parent, TRUE, TRUE, 0);

      /* listen for changes to filter manager */
      pan_callback_add (filter_manager_get_filters_changed_callback(),
                        filters_changed_cb, d);

      return top;
}

static void
rule_from_filter_tab (RuleEditDialog * d, Rule * r)
{
      /*odebug1 ("filter name [%s]", d->filter_name);*/
      replace_gstr (&r->filter_name, g_strdup(d->filter_name));
}

/*****
******
******  NEWSGROUPS
******
*****/

static void
move_selected_newsgroups (GtkCList * from, GtkCList * to)
{
      GPtrArray * selected = g_ptr_array_new ();
      GList     * l;
      gint        i;

      g_return_if_fail (from!=NULL);
      g_return_if_fail (to!=NULL);

      pan_lock ();

      for (l=from->selection; l!=NULL; l=l->next)
            g_ptr_array_add (selected, gtk_clist_get_row_data(from,
                  GPOINTER_TO_INT(l->data)));

      gtk_clist_freeze (from);
      gtk_clist_freeze (to);

      for (i=0; i<selected->len; i++)
      {
            gint       from_row, to_row;
            gchar    * name;
            gpointer * data;

            data = g_ptr_array_index (selected, i);

            from_row  = gtk_clist_find_row_from_data (from, data);
            gtk_clist_get_text (from, from_row, 0, &name);
            
              to_row = gtk_clist_append (to, &name);
                gtk_clist_set_row_data (to, to_row, data);

            gtk_clist_remove (from, from_row);
      }
      gtk_clist_thaw (to);
      gtk_clist_thaw (from);

      pan_unlock ();

      g_ptr_array_free (selected, TRUE);
}


static void
apply_newsgroups_cb (GtkButton * button, gpointer data)
{
      RuleEditDialog * d = (RuleEditDialog *) data;

      g_return_if_fail (d!=NULL);

      move_selected_newsgroups (GTK_CLIST(d->groups_sub_clist), 
            GTK_CLIST(d->groups_apply_clist));
}

static void
unapply_newsgroups_cb (GtkButton * button, gpointer data)
{
      RuleEditDialog * d = (RuleEditDialog *) data;

      g_return_if_fail (d!=NULL);

      move_selected_newsgroups (GTK_CLIST(d->groups_apply_clist),
            GTK_CLIST(d->groups_sub_clist));
}

static GtkWidget*
create_newsgroup_tab (RuleEditDialog * d)
{
      GtkWidget *w, *h, *t, *s, *v, *v2, *top, *v_rb;

      top = gtk_vbox_new (FALSE, GUI_PAD);
      gtk_container_set_border_width (GTK_CONTAINER(top), 5);

      /* rule applies to... */
      v_rb = gtk_vbox_new (FALSE, 0);
      gtk_box_pack_start (GTK_BOX(top), v_rb, FALSE, FALSE, 0);

      /* rule applies to all */
      d->groups_all_rb = w = gtk_radio_button_new_with_label (NULL, _("Rule applies to all newsgroups"));
      gtk_box_pack_start (GTK_BOX(v_rb), w, FALSE, FALSE, 0);

      /* rule applies to phrase */
      h = gtk_hbox_new (FALSE, GUI_PAD);
      d->groups_phrase_rb = w = gtk_radio_button_new_with_label_from_widget (
            GTK_RADIO_BUTTON(w), _("Wildcard group specification:"));
      gtk_box_pack_start (GTK_BOX(h), w, FALSE, FALSE, 0);
      gtk_box_pack_start (GTK_BOX(h), d->groups_phrase_entry = gtk_entry_new (), TRUE, TRUE, 0);
      gtk_box_pack_start (GTK_BOX(h), gtk_label_new (_("(e.g., *anime*)")), FALSE, FALSE, 0);
      gtk_box_pack_start (GTK_BOX(v_rb), h, FALSE, FALSE, 0);

      /* rule applies to specific newsgroups */
      d->groups_list_rb = w = gtk_radio_button_new_with_label_from_widget (
            GTK_RADIO_BUTTON(w), _("Rule applies to specific newsgroups:"));
      gtk_box_pack_start (GTK_BOX(v_rb), w, FALSE, FALSE, 0);

      /* specific newsgroups... */
      t = gtk_table_new (1, 3, FALSE);
      gtk_box_pack_start (GTK_BOX (top), t, TRUE, TRUE, 0);

      /* sub list */
      s = gtk_scrolled_window_new (NULL, NULL);
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(s), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
      gtk_table_attach (GTK_TABLE(t), s, 0, 1, 0, 1,
                        GTK_EXPAND|GTK_FILL,
                        GTK_EXPAND|GTK_FILL, 0, 0);
      d->groups_sub_clist = w = gtk_clist_new (1); 
      gtk_container_add (GTK_CONTAINER(s), w);
      gtk_clist_set_column_width (GTK_CLIST(w), 0, 80);
      gtk_clist_set_selection_mode (GTK_CLIST(w), GTK_SELECTION_EXTENDED);
      gtk_clist_set_column_widget (GTK_CLIST(w), 0, gtk_label_new (_("Subscribed Newsgroups")));
      gtk_clist_set_sort_column (GTK_CLIST(w), 0);
      gtk_clist_set_auto_sort (GTK_CLIST(w), TRUE);
      gtk_clist_column_titles_show (GTK_CLIST(w));

      /* apply list */
      s = gtk_scrolled_window_new (NULL, NULL);
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(s), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
      gtk_table_attach (GTK_TABLE(t), s, 2, 3, 0, 1,
                        GTK_EXPAND|GTK_FILL,
                        GTK_EXPAND|GTK_FILL, 0, 0);
      d->groups_apply_clist = w = gtk_clist_new (1); 
      gtk_container_add (GTK_CONTAINER(s), w);
      gtk_clist_set_column_width (GTK_CLIST(w), 0, 80);
      gtk_clist_set_selection_mode (GTK_CLIST(w), GTK_SELECTION_EXTENDED);
      gtk_clist_set_column_widget (GTK_CLIST(w), 0, gtk_label_new (_("Rule applies to:")));
      gtk_clist_set_sort_column (GTK_CLIST(w), 0);
      gtk_clist_set_auto_sort (GTK_CLIST(w), TRUE);
      gtk_clist_column_titles_show (GTK_CLIST(w));

      /* add group buttons */
      v = gtk_vbox_new (FALSE, GUI_PAD_BIG);
      gtk_table_attach (GTK_TABLE (t), v, 1, 2, 0, 1,
                        GTK_FILL, GTK_EXPAND|GTK_FILL, 5, 0);
      v2 = gtk_vbox_new (FALSE, 0);
      gtk_box_pack_start (GTK_BOX(v), v2, TRUE, TRUE, 0);
      w = gtk_button_new ();
      gtk_container_add (GTK_CONTAINER(w), gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_OUT));
      gtk_signal_connect (GTK_OBJECT(w), "clicked", GTK_SIGNAL_FUNC(apply_newsgroups_cb), d);
      gtk_box_pack_end (GTK_BOX(v2), w, FALSE, FALSE, 0);
      v2 = gtk_vbox_new (FALSE, 0);
      gtk_box_pack_start (GTK_BOX(v), v2, TRUE, TRUE, 0);
      w = gtk_button_new ();
      gtk_container_add (GTK_CONTAINER(w), gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_OUT));
      gtk_signal_connect (GTK_OBJECT(w), "clicked", GTK_SIGNAL_FUNC(unapply_newsgroups_cb), d);
      gtk_box_pack_start (GTK_BOX(v2), w, FALSE, FALSE, 0);


      return top;
}

static void
populate_newsgroup_tab (RuleEditDialog * d, const Rule * r)
{
      guint i;
      gboolean b;
      GtkWidget * w;
      Server * server;
      GPtrArray * groups;
      GtkCList * sub;
      GtkCList * app;

      /* groups radiobuttons */
      w = d->groups_all_rb;
      if (r!=NULL) {
            switch (r->group_type) {
                  case RULE_GROUP_WILDCARD:
                        w = d->groups_phrase_rb; break;
                  case RULE_GROUP_LIST:
                        w = d->groups_list_rb; break;
                  case RULE_GROUP_ALL:
                        w = d->groups_all_rb; break;
                  default:
                        pan_warn_if_reached ();
            }
      }
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(w), TRUE);

      /* phrase */
      b = r!=NULL && r->group_type==RULE_GROUP_WILDCARD;
      pan_gtk_entry_set_text (d->groups_phrase_entry, b ? r->group_wildcard :"");

      /* populate the two group clists */
      server = serverlist_get_active_server ();
      groups = server_get_groups (server, SERVER_GROUPS_SUBSCRIBED);
      sub = GTK_CLIST(d->groups_sub_clist);
      gtk_clist_freeze (sub);
      gtk_clist_clear (sub);
      app = GTK_CLIST(d->groups_apply_clist);
      gtk_clist_freeze (app);
      gtk_clist_clear (app);
      for (i=0; i!=groups->len; ++i) {
            Group * g = GROUP(g_ptr_array_index(groups,i));
            char * name = (char*) group_get_name (g);
            GtkCList * c = r!=NULL && r->group_type==RULE_GROUP_LIST && rule_test_group(r,&g->name) ? app : sub;
            gint row = gtk_clist_insert (c, -1, &name);
            gtk_clist_set_row_data (c, row, g);
      }
      g_ptr_array_free (groups, TRUE);
      gtk_clist_thaw (sub);
      gtk_clist_thaw (app);
}

static void
rule_from_newsgroup_tab (RuleEditDialog * d, Rule * r)
{
      /* clear out the old wildcard */
      replace_gstr (&r->group_wildcard, NULL);

      /* clear out the old list */
      if (r->group_list != NULL) {
            pan_g_ptr_array_foreach (r->group_list, (GFunc)g_free, NULL);
            g_ptr_array_free (r->group_list, TRUE);
            r->group_list = NULL;
      }

      /* update from ui */
      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(d->groups_phrase_rb))) {
            r->group_type = RULE_GROUP_WILDCARD; 
            r->group_wildcard = gtk_editable_get_chars (GTK_EDITABLE(d->groups_phrase_entry), 0, -1);
      }
      else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(d->groups_all_rb))) {
            r->group_type = RULE_GROUP_ALL;
      }
      else { /* use clist */
            gint i;
            GtkCList * apply = GTK_CLIST(d->groups_apply_clist);
            r->group_type = RULE_GROUP_LIST;
            r->group_list = g_ptr_array_new ();
            for (i=0; i!=apply->rows; ++i) {
                  Group * g = GROUP(gtk_clist_get_row_data (apply, i));
                  if (g)
                        g_ptr_array_add (r->group_list, g_strndup(g->name.str, g->name.len));
            }
      }
}

/*****
******
******  
******
*****/

static gint
dialog_close_cb (GtkDialog * dialog, gpointer data)
{
      RuleEditDialog * d = (RuleEditDialog*) data;
      pan_callback_remove (filter_manager_get_filters_changed_callback(),
                           filters_changed_cb, d);
      g_free (d->filter_name);
      g_free (d);
      return FALSE;
}

GtkWidget*
rule_edit_dialog_create (GtkWindow * parent, const Rule * rule)
{
      GtkWidget *n, *w, *h, *d_v;
      RuleEditDialog * d;
      GtkTooltips * tips = gtk_tooltips_new ();

      d = g_new0 (RuleEditDialog, 1);

      /* dialog */
      w = d->dialog = gtk_dialog_new_with_buttons (_("Pan: Edit Rule"),
            parent,
            GTK_DIALOG_DESTROY_WITH_PARENT,
            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
            GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
            GTK_STOCK_OK, GTK_RESPONSE_OK,
              NULL);
      d_v = GTK_DIALOG(w)->vbox;
      gtk_window_set_policy (GTK_WINDOW(w), TRUE, TRUE, TRUE);
      gtk_signal_connect (GTK_OBJECT(w), "destroy", GTK_SIGNAL_FUNC(dialog_close_cb), d);
      gtk_object_set_user_data (GTK_OBJECT(w), d);

      /* name */
      h = gtk_hbox_new (FALSE, GUI_PAD);
      w = gtk_label_new (_("Rule Name:"));
      gtk_box_pack_start (GTK_BOX(h), w, FALSE, FALSE, 0);
      w = d->name_entry = gtk_entry_new ();
      gtk_box_pack_start (GTK_BOX(h), w, TRUE, TRUE, 0);
      gtk_box_pack_start (GTK_BOX(d_v), h, FALSE, FALSE, 0);
      w = gtk_label_new ("       ");
      gtk_box_pack_start (GTK_BOX(h), w, FALSE, FALSE, 0);
      w = gtk_check_button_new_with_label (_("Apply to Incoming"));
      gtk_box_pack_start (GTK_BOX(h), w, FALSE, FALSE, 0);
      gtk_tooltips_set_tip (tips, w, _("If enabled, this rule will be applied to headers when they are downloaded."), NULL);
      d->apply_to_incoming_tb = w;

      /* separator */
      gtk_box_pack_start (GTK_BOX(d_v), gtk_hseparator_new(), FALSE, FALSE, 0);

      /* notebook */
      n = gtk_notebook_new ();
      w = create_newsgroup_tab (d);
      gtk_container_add (GTK_CONTAINER(n), w);
      gtk_notebook_set_tab_label (GTK_NOTEBOOK(n), w, gtk_label_new(_("Newsgroups")));
      w = create_filter_tab (d);
      gtk_container_add (GTK_CONTAINER(n), w);
      gtk_notebook_set_tab_label (GTK_NOTEBOOK(n), w, gtk_label_new(_("Filters")));
      w = create_action_tab (d);
      gtk_container_add (GTK_CONTAINER(n), w);
      gtk_notebook_set_tab_label (GTK_NOTEBOOK(n), w, gtk_label_new(_("Actions")));
      gtk_box_pack_start (GTK_BOX(d_v), n, TRUE, TRUE, GUI_PAD_SMALL);

      /* populate */
      pan_gtk_entry_set_text (d->name_entry, rule==NULL || rule->name==NULL ? _("New Rule") : rule->name);
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(d->apply_to_incoming_tb), rule==NULL ? FALSE : rule->apply_to_incoming);
      populate_newsgroup_tab (d, rule);
      populate_filter_tab (d, rule==NULL ? NULL : rule->filter_name);
      populate_actions_tab (d, rule);

      return d->dialog;
}

Rule*
rule_edit_dialog_get_rule (GtkWidget * w)
{
      RuleEditDialog * d = (RuleEditDialog*) gtk_object_get_user_data (GTK_OBJECT(w));
      Rule * r = rule_new ();
      replace_gstr (&r->name, gtk_editable_get_chars (GTK_EDITABLE(d->name_entry), 0, -1));
      r->apply_to_incoming = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(d->apply_to_incoming_tb));
      rule_from_action_tab (d, r);
      rule_from_filter_tab (d, r);
      rule_from_newsgroup_tab (d, r);
      /*odebug2 ("returning rule [%s][%lu]", r->name, r->action->flags);*/
      return r;
}

Generated by  Doxygen 1.6.0   Back to index