/*
* grn_mhdrwin.c: message header window functions
*
* $Id: grn_mhdrwin.c,v 1.11 2000/06/28 11:28:28 sc Exp $
*/
/* Copyright (C) 1999-2000 Sergey Chernikov (sc@ivvs.ul.ru)
*
* Authors: Sergey Chernikov <sc@ivvs.ul.ru>
*
* 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 "grn_consts.h"
#include <gnome.h>
#include "grn_vars.h"
#include "grn_util.h"
#include "grn_misc.h"
#include "grn_config.h"
#include "grn_msgwin.h"
void mhdredit_refresh(GtkWidget *, t_msgheaders *);
static void evt_mhw_destroy(GtkWidget *w, gpointer data)
{
gtk_object_remove_data(GTK_OBJECT(GRN->window), KEY_MHWIN);
}
static gboolean evt_mhw_delete(GtkWidget *w)
{
grn_save_ws(1, w);
return FALSE;
}
static void scroll_line(GtkAdjustment *adj, gint offset)
{
gfloat new_val = adj->value + offset * adj->step_increment;
if (new_val < adj->lower) new_val = adj->lower;
if (new_val > (adj->upper - adj->page_size))
new_val = adj->upper - adj->page_size;
gtk_adjustment_set_value(adj, new_val);
}
static gint evt_mhw_keypress(GtkWidget *w, GdkEventKey *event, gpointer data)
{
GtkWidget *scrwin;
GtkAdjustment *vadj = NULL;
gint offset = 0;
g_return_val_if_fail(event != NULL, FALSE);
g_return_val_if_fail(w != NULL, FALSE);
scrwin = gtk_object_get_data(GTK_OBJECT(w), KEY_MHWIN_SW);
if (scrwin) vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrwin));
switch (event->keyval)
{
case GDK_Escape:
if (! evt_mhw_delete(w)) gtk_widget_destroy(w);
break;
case GDK_Up:
offset = -1;
break;
case GDK_Down:
offset = 1;
break;
default: return FALSE;
}
gtk_signal_emit_stop_by_name(GTK_OBJECT(w), "key_press_event");
if (vadj && offset) scroll_line(vadj, offset);
return TRUE;
}
void mhwin_create()
{
GtkWindow *wnd=NULL;
GtkWidget *scrwin;
gpointer tmp;
grn_lock();
tmp = gtk_object_get_data(GTK_OBJECT(GRN->window), KEY_MHWIN);
grn_unlock();
if (tmp) return;
grn_lock();
wnd = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
gtk_window_set_default_size(wnd, grn_prefs.ws[1].width, grn_prefs.ws[1].height);
gtk_widget_set_uposition(GTK_WIDGET(wnd), grn_prefs.ws[1].x, grn_prefs.ws[1].y);
grn_unlock();
grn_set_title(wnd, _("Message headers"));
grn_lock();
scrwin = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(wnd), scrwin);
gtk_signal_connect(GTK_OBJECT(wnd), "delete_event",
GTK_SIGNAL_FUNC(evt_mhw_delete), NULL);
gtk_signal_connect(GTK_OBJECT(wnd), "destroy",
GTK_SIGNAL_FUNC(evt_mhw_destroy), NULL);
gtk_signal_connect(GTK_OBJECT(wnd), "key_press_event",
GTK_SIGNAL_FUNC(evt_mhw_keypress), NULL);
gtk_object_set_data(GTK_OBJECT(wnd), KEY_MHWIN_SW, scrwin);
gtk_object_set_data(GTK_OBJECT(wnd), KEY_MHWIN_TBL, NULL);
gtk_object_set_data(GTK_OBJECT(GRN->window), KEY_MHWIN, wnd);
gtk_widget_show_all(GTK_WIDGET(wnd));
grn_unlock();
}
static void mhwin_add_header(GtkWidget *table, gint pos, gchar *name, gchar *value)
{
GtkWidget *label, *en;
if (! value) return;
if (! name) return;
grn_lock();
label = gtk_label_new(name);
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0);
gtk_table_attach(GTK_TABLE(table), label, 0,1, pos, pos + 1,
GTK_FILL, GTK_FILL, 2, 3);
if (strchr(value, '\n'))
{
en = gtk_text_new(NULL, NULL);
gtk_text_set_editable(GTK_TEXT(en), FALSE);
gtk_text_set_line_wrap(GTK_TEXT(en), FALSE);
gtk_text_insert(GTK_TEXT(en), NULL, NULL, NULL, value, strlen(value));
gtk_text_set_point(GTK_TEXT(en), 0);
}
else {
en = gtk_entry_new();
gtk_entry_set_editable(GTK_ENTRY(en), FALSE);
gtk_entry_set_text(GTK_ENTRY(en), value);
gtk_entry_set_position(GTK_ENTRY(en), 0);
}
gtk_table_attach(GTK_TABLE(table), en, 1,2, pos, pos + 1,
GTK_EXPAND|GTK_FILL, GTK_EXPAND|GTK_FILL, 2, 3);
grn_unlock();
}
static gint compare_mhdrs(t_msgheader *mh1, t_msgheader *mh2)
{
if (! mh2) return (mh1 != NULL);
if (! mh1) return (-1);
return strcmp(mh1->name, mh2->name);
}
static void add_hdr(gchar *key, gchar *data, GList **l)
{
t_msgheader *mhdr = g_new(t_msgheader, 1);
mhdr->name = key; mhdr->value = data;
*l = g_list_insert_sorted(*l, mhdr, (GCompareFunc) compare_mhdrs);
}
static void mhwin_add_extra_hdrs(GtkWidget *table, gint pos, GHashTable *eh)
{
GList *mh_list = NULL, *l;
gint row = pos;
if (! eh) return;
g_hash_table_foreach(eh, (GHFunc) add_hdr, &mh_list);
for (l=mh_list; l; l=l->next)
{
t_msgheader *mhdr = l->data;
if (! mhdr) continue;
if (str_check(mhdr->name) && str_check(mhdr->value))
{
gchar *buf = g_strconcat(mhdr->name, ":", NULL);
mhwin_add_header(table, row++, buf, mhdr->value);
str_free(&buf);
}
g_free(mhdr);
}
g_list_free(mh_list);
}
void mhdrwin_refresh(t_msgheaders *mh)
{
GtkWindow *mhwin;
GtkWidget *table, *scrwin;
mhwin = GTK_WINDOW(gtk_object_get_data(GTK_OBJECT(GRN->window), KEY_MHWIN));
if (! mhwin) return;
grn_lock();
table = gtk_object_get_data(GTK_OBJECT(mhwin), KEY_MHWIN_TBL);
scrwin = gtk_object_get_data(GTK_OBJECT(mhwin), KEY_MHWIN_SW);
grn_unlock();
if (! scrwin) return;
if (table)
{
grn_lock();
gtk_widget_destroy(table);
grn_unlock();
}
if (mh)
{
gchar buf[100];
if (mh->xref) grn_set_title(mhwin, _("Headers for '%s'"), mh->xref);
else grn_set_title(mhwin, _("Headers for msg #%ld in %s"), mh->number, mh->grp->name);
grn_lock();
table = gtk_table_new(2, 2, FALSE);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrwin), table);
grn_unlock();
mhwin_add_header(table, 0, "From:", mh->from);
mhwin_add_header(table, 1, "Date:", mh->date);
mhwin_add_header(table, 2, "Subject:", mh->subject);
mhwin_add_header(table, 3, "Newsgroups:", mh->newsgroups);
mhwin_add_header(table, 4, "Message-ID:", mh->id);
mhwin_add_header(table, 5, "References:", mh->ref);
mhwin_add_header(table, 6, "Path:", mh->path);
snprintf(buf, 99, "%ld", mh->lines);
mhwin_add_header(table, 7, "Lines:", buf);
mhwin_add_header(table, 8, "Xref:", mh->xref);
grn_lock();
gtk_table_attach(GTK_TABLE(table), gtk_hseparator_new(), 0,2,9,10, GTK_FILL, GTK_FILL, 2,3);
grn_unlock();
mhwin_add_extra_hdrs(table, 10, mh->extra_hdrs);
grn_lock();
gtk_object_set_data(GTK_OBJECT(mhwin), KEY_MHWIN_TBL, table);
gtk_widget_show_all(table);
grn_unlock();
}
else {
grn_set_title(mhwin, _("Message headers"));
grn_lock();
gtk_object_set_data(GTK_OBJECT(mhwin), KEY_MHWIN_TBL, NULL);
grn_unlock();
}
}
void evt_mhwin_show(GtkWidget *w)
{
t_message *msg;
g_return_if_fail(w != NULL);
mhwin_create();
if (! GRN->msgwin) return;
grn_lock();
msg = (t_message *) gtk_object_get_data(GTK_OBJECT(GRN->msgwin), KEY_MSG);
grn_unlock();
if (! msg) return;
mhdrwin_refresh(msg->mh);
}
static void hdr_sel(GtkCList *clist, gint row, gint col, GdkEventButton *ev, GtkWidget *mhe)
{
gchar *rd = (gchar *) gtk_clist_get_row_data(clist, row);
t_msgheaders *mh = gtk_object_get_data(GTK_OBJECT(mhe), KEY_MH);
gchar *value;
GtkEntry *en_hdr, *en_val;
GtkWidget *btn_del, *btn_add, *btn_edit;
if ((! mh) || (! rd)) return;
value = t_msgheaders_get_hdr(mh, rd);
en_hdr = (GtkEntry *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_HEADER);
en_val = (GtkEntry *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_VALUE);
gtk_entry_set_text(en_hdr, rd);
gtk_entry_set_text(en_val, value);
btn_del = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_BTN_DEL);
btn_add = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_BTN_ADD);
btn_edit = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_BTN_EDIT);
gtk_widget_set_sensitive(btn_del, TRUE);
gtk_widget_set_sensitive(btn_add, FALSE);
gtk_widget_set_sensitive(btn_edit, FALSE);
}
static void hdr_changed(GtkWidget *w, GtkWidget *mhe)
{
GtkWidget *btn_add, *btn_edit;
btn_add = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_BTN_ADD);
btn_edit = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_BTN_EDIT);
gtk_widget_set_sensitive(btn_add, TRUE);
gtk_widget_set_sensitive(btn_edit, FALSE);
}
static void val_changed(GtkWidget *w, GtkWidget *mhe)
{
GtkWidget *btn_edit;
btn_edit = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_BTN_EDIT);
gtk_widget_set_sensitive(btn_edit, TRUE);
}
static void mhe_edit(GtkWidget *w, GtkWidget *mhe)
{
GtkEntry *en_hdr, *en_val;
t_msgheaders *mh;
gchar *hdr, *val;
g_return_if_fail(mhe != NULL);
mh = gtk_object_get_data(GTK_OBJECT(mhe), KEY_MH);
if (! mh) return;
en_hdr = (GtkEntry *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_HEADER);
en_val = (GtkEntry *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_VALUE);
hdr = gtk_entry_get_text(en_hdr);
val = gtk_entry_get_text(en_val);
t_msgheaders_set_hdr(mh, hdr, val);
mhdredit_refresh(mhe, mh);
}
static void mhe_del(GtkWidget *w, GtkWidget *mhe)
{
GtkEntry *en_hdr;
t_msgheaders *mh;
gchar *hdr;
g_return_if_fail(mhe != NULL);
mh = gtk_object_get_data(GTK_OBJECT(mhe), KEY_MH);
if (! mh) return;
en_hdr = (GtkEntry *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_HEADER);
hdr = gtk_entry_get_text(en_hdr);
t_msgheaders_rm_hdr(mh, hdr);
mhdredit_refresh(mhe, mh);
}
GtkWidget *mhdredit_create(void)
{
gchar *ttl[2] = {_("Header"), _("Value")};
GtkWidget *vbox, *scrwin, *hbox, *w, *bbox, *en_hdr, *en_val;
GtkCList *clist;
grn_lock();
vbox = gtk_vbox_new(FALSE, FALSE);
clist = GTK_CLIST(gtk_clist_new_with_titles(2, ttl));
gtk_widget_set_usize(GTK_WIDGET(clist), 400, 250);
gtk_clist_column_titles_passive(clist);
gtk_clist_set_selection_mode(clist, GTK_SELECTION_BROWSE);
scrwin = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(scrwin), GTK_WIDGET(clist));
gtk_box_pack_start(GTK_BOX(vbox), scrwin, TRUE, TRUE, 0);
gtk_object_set_data(GTK_OBJECT(vbox), KEY_CLIST, clist);
hbox = gtk_hbox_new(FALSE, FALSE);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
w = gtk_label_new(_("Header:"));
gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 3);
en_hdr = gtk_entry_new();
gtk_widget_set_usize(en_hdr, 150, -1);
gtk_box_pack_start(GTK_BOX(hbox), en_hdr, FALSE, FALSE, 0);
gtk_object_set_data(GTK_OBJECT(vbox), KEY_HEADER, en_hdr);
w = gtk_label_new(_("Value:"));
gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 3);
en_val = gtk_entry_new();
gtk_widget_set_usize(en_val, 150, -1);
gtk_box_pack_start(GTK_BOX(hbox), en_val, TRUE, TRUE, 0);
gtk_object_set_data(GTK_OBJECT(vbox), KEY_VALUE, en_val);
bbox = gtk_hbutton_box_new();
gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), gnome_preferences_get_button_layout());
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), GNOME_PAD);
gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 2);
w = gnome_pixmap_button(gnome_stock_pixmap_widget(NULL, GNOME_STOCK_PIXMAP_ADD), _("Add"));
gtk_box_pack_start(GTK_BOX(bbox), w, TRUE, TRUE, 0);
gtk_object_set_data(GTK_OBJECT(vbox), KEY_BTN_ADD, w);
gtk_signal_connect(GTK_OBJECT(w), "clicked",
GTK_SIGNAL_FUNC(mhe_edit), vbox);
w = gnome_pixmap_button(gnome_stock_pixmap_widget(NULL, GNOME_STOCK_PIXMAP_PROPERTIES), _("Modify"));
gtk_box_pack_start(GTK_BOX(bbox), w, TRUE, TRUE, 0);
gtk_object_set_data(GTK_OBJECT(vbox), KEY_BTN_EDIT, w);
gtk_signal_connect(GTK_OBJECT(w), "clicked",
GTK_SIGNAL_FUNC(mhe_edit), vbox);
w = gnome_pixmap_button(gnome_stock_pixmap_widget(NULL, GNOME_STOCK_PIXMAP_REMOVE), _("Delete"));
gtk_box_pack_start(GTK_BOX(bbox), w, TRUE, TRUE, 0);
gtk_object_set_data(GTK_OBJECT(vbox), KEY_BTN_DEL, w);
gtk_signal_connect(GTK_OBJECT(w), "clicked",
GTK_SIGNAL_FUNC(mhe_del), vbox);
gtk_signal_connect(GTK_OBJECT(clist), "select_row",
GTK_SIGNAL_FUNC(hdr_sel), vbox);
gtk_signal_connect(GTK_OBJECT(en_hdr), "changed",
GTK_SIGNAL_FUNC(hdr_changed), vbox);
gtk_signal_connect(GTK_OBJECT(en_val), "changed",
GTK_SIGNAL_FUNC(val_changed), vbox);
grn_unlock();
return vbox;
}
static void add_mh_hdr(GtkCList *clist, gchar *hname, gchar *hval)
{
gchar *row[2];
gint idx;
if ((! str_check(hname)) || (! str_check(hval))) return;
row[0] = g_strdup(hname); row[1] = g_strdup(hval);
grn_lock();
idx = gtk_clist_append(clist, row);
gtk_clist_set_row_data_full(clist, idx, row[0], (GtkDestroyNotify) str_destroy);
grn_unlock();
str_free(&row[1]);
}
static void add_extra_hdr(gpointer key, gpointer data, GtkCList *clist)
{
add_mh_hdr(clist, key, data);
}
void mhdredit_refresh(GtkWidget *mhe, t_msgheaders *mh)
{
GtkWidget *btn_add, *btn_edit, *btn_del;
GtkEntry *en_hdr, *en_val;
GtkCList *clist;
t_msgheaders *mh1;
g_return_if_fail(mh != NULL);
grn_lock();
clist = GTK_CLIST(gtk_object_get_data(GTK_OBJECT(mhe), KEY_CLIST));
mh1 = gtk_object_get_data(GTK_OBJECT(mhe), KEY_MH);
if (mh1) gtk_object_remove_data(GTK_OBJECT(mhe), KEY_MH);
gtk_object_set_data(GTK_OBJECT(mhe), KEY_MH, mh);
grn_unlock();
if (! clist) return;
gtk_clist_freeze(clist);
gtk_clist_clear(clist);
add_mh_hdr(clist, "From", mh->from);
add_mh_hdr(clist, "To", mh->to);
add_mh_hdr(clist, "Subject", mh->subject);
add_mh_hdr(clist, "Date", mh->date);
add_mh_hdr(clist, "Newsgroups", mh->newsgroups);
add_mh_hdr(clist, "Message-ID", mh->id);
add_mh_hdr(clist, "References", mh->ref);
add_mh_hdr(clist, "Xref", mh->xref);
add_mh_hdr(clist, "Path", mh->path);
if (mh->extra_hdrs)
g_hash_table_foreach(mh->extra_hdrs, (GHFunc) add_extra_hdr, clist);
gtk_clist_columns_autosize(clist);
gtk_clist_thaw(clist);
btn_add = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_BTN_ADD);
btn_edit = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_BTN_EDIT);
btn_del = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_BTN_DEL);
en_hdr = (GtkEntry *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_HEADER);
en_val = (GtkEntry *) gtk_object_get_data(GTK_OBJECT(mhe), KEY_VALUE);
gtk_entry_set_text(en_hdr, ""); gtk_entry_set_text(en_val, "");
gtk_widget_set_sensitive(btn_add, FALSE);
gtk_widget_set_sensitive(btn_edit, FALSE);
gtk_widget_set_sensitive(btn_del, FALSE);
}
static gboolean mhdredit_dlg_delete(GtkWidget *w)
{
grn_save_ws(4, w);
return FALSE;
}
static void btn_event(GtkWidget *btn, GtkWidget *w)
{
mhdredit_dlg_delete(w);
}
GtkWidget *mhdredit_dlg_create(t_msgheaders *mh)
{
GtkWidget *dlg, *mhe;
grn_lock();
dlg = gnome_dialog_new(_("Edit headers"), GNOME_STOCK_BUTTON_CLOSE, NULL);
gnome_dialog_set_close(GNOME_DIALOG(dlg), TRUE);
gtk_window_set_policy(GTK_WINDOW(dlg), FALSE, TRUE, FALSE);
gtk_window_set_default_size(GTK_WINDOW(dlg), grn_prefs.ws[4].width, grn_prefs.ws[4].height);
gtk_widget_set_uposition(dlg, grn_prefs.ws[4].x, grn_prefs.ws[4].y);
gtk_signal_connect(GTK_OBJECT(dlg), "delete_event",
GTK_SIGNAL_FUNC(mhdredit_dlg_delete), NULL);
gnome_dialog_button_connect(GNOME_DIALOG(dlg), 0,
GTK_SIGNAL_FUNC(btn_event), dlg);
grn_unlock();
mhe = mhdredit_create();
grn_lock();
gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dlg)->vbox), mhe, TRUE, TRUE, 0);
gtk_widget_show_all(dlg);
grn_unlock();
mhdredit_refresh(mhe, mh);
return dlg;
}
syntax highlighted by Code2HTML, v. 0.9.1