diff --git a/ChangeLog.claws b/ChangeLog.claws index e0edfd396..99dc0719d 100644 --- a/ChangeLog.claws +++ b/ChangeLog.claws @@ -1,3 +1,9 @@ +2001-08-22 [alte] + * src/Makefile.am, src/compose.[ch], src/defs.h, src/mainwindow.c, + src/prefs_templates.[ch], src/template.[ch], src/template_select.[ch] + initial message templates support + + 2001-08-22 [paul] * configure.in diff --git a/src/Makefile.am b/src/Makefile.am index 28594526e..aa41e4b28 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -100,7 +100,11 @@ sylpheed_SOURCES = \ editldap_basedn.c editldap_basedn.h \ labelcolors.c labelcolors.h \ ssl.c ssl.h \ - gtkspell.c gtkspell.h gtkxtext.h + gtkspell.c gtkspell.h gtkxtext.h \ + template.c template.h \ + prefs_templates.c prefs_templates.h \ + template_select.c template_select.h + EXTRA_DIST = \ quote_fmt_parse.h \ diff --git a/src/compose.c b/src/compose.c index 6b6e624d1..e73b92d6e 100644 --- a/src/compose.c +++ b/src/compose.c @@ -98,6 +98,7 @@ #include "gtkshruler.h" #include "folder.h" #include "addr_compl.h" +#include "template_select.h" #if USE_GPGME # include "rfc2015.h" @@ -241,6 +242,10 @@ static void toolbar_linewrap_cb (GtkWidget *widget, gpointer data); static void toolbar_address_cb (GtkWidget *widget, gpointer data); +static void template_select_cb (gpointer daat, + guint action, + GtkWidget *widget); + static void select_account(Compose * compose, PrefsAccount * ac); static void account_activated (GtkMenuItem *menuitem, @@ -448,6 +453,7 @@ static GtkItemFactoryEntry compose_entries[] = {N_("/_Tool"), NULL, NULL, 0, ""}, {N_("/_Tool/Show _ruler"), NULL, compose_toggle_ruler_cb, 0, ""}, {N_("/_Tool/_Address book"), "A", compose_address_cb, 0, NULL}, + {N_("/_Tool/_Templates ..."), NULL, template_select_cb, 0, NULL}, {N_("/_Help"), NULL, NULL, 0, ""}, {N_("/_Help/_About"), NULL, about_show, 0, NULL} }; @@ -481,6 +487,7 @@ Compose * compose_generic_new(PrefsAccount *account, const gchar *to, FolderItem compose = compose_create(account); compose->mode = COMPOSE_NEW; + compose->replyinfo = NULL; if (prefs_common.auto_sig) compose_insert_sig(compose); @@ -602,6 +609,7 @@ static void compose_generic_reply(MsgInfo *msginfo, gboolean quote, compose = compose_create(reply_account); compose->mode = COMPOSE_REPLY; + compose->replyinfo = msginfo; if (followup_and_reply_to) { @@ -4886,3 +4894,62 @@ static gchar *compose_quote_fmt (Compose *compose, return quote_fmt_get_buffer(); } + +static void template_apply_cb(gchar *s, gpointer data) +{ + Compose *compose = (Compose*)data; + GtkSText *text = GTK_STEXT(compose->text); + gchar *quote_str; + gchar *qmark; + gchar *parsed_text; + gchar *tmpl; + gchar *old_tmpl = s; + + if(!s) return; + + if(compose->replyinfo=NULL) { + gtk_stext_freeze(text); + gtk_stext_set_point(text, 0); + gtk_stext_forward_delete(text, gtk_stext_get_length(text)); + gtk_stext_insert(text, NULL, NULL, NULL, s, -1); + gtk_stext_thaw(text); + g_free(old_tmpl); + return; + } + + parsed_text = g_new(gchar, strlen(s)*2 + 1); + tmpl = parsed_text; + while(*s) { + if (*s == '\n') { + *parsed_text++ = '\\'; + *parsed_text++ = 'n'; + s++; + } else { + *parsed_text++ = *s++; + } + } + *parsed_text = '\0'; + + if (prefs_common.quotemark && *prefs_common.quotemark) + qmark = prefs_common.quotemark; + else + qmark = "> "; + + quote_str = compose_quote_fmt(compose, compose->replyinfo, tmpl, qmark); + if (quote_str != NULL) { + gtk_stext_freeze(text); + gtk_stext_set_point(text, 0); + gtk_stext_forward_delete(text, gtk_stext_get_length(text)); + gtk_stext_insert(text, NULL, NULL, NULL, quote_str, -1); + gtk_stext_thaw(text); + } + + g_free(old_tmpl); + g_free(tmpl); +} + +static void template_select_cb(gpointer data, guint action, + GtkWidget *widget) +{ + template_select(&template_apply_cb, data); +} diff --git a/src/compose.h b/src/compose.h index 8cc78b746..6418862b8 100644 --- a/src/compose.h +++ b/src/compose.h @@ -120,6 +120,7 @@ struct _Compose ComposeReplyMode mode; MsgInfo *targetinfo; + MsgInfo *replyinfo; gchar *replyto; gchar *cc; diff --git a/src/defs.h b/src/defs.h index a25360424..a67922afe 100644 --- a/src/defs.h +++ b/src/defs.h @@ -61,6 +61,7 @@ #define MARK_FILE ".sylpheed_mark" #define CACHE_VERSION 19 #define MARK_VERSION 2 +#define TEMPLATES_DIR "templates" #define DEFAULT_SIGNATURE ".signature" #define DEFAULT_INC_PATH "/usr/bin/mh/inc" diff --git a/src/mainwindow.c b/src/mainwindow.c index 23f20190d..4891cce2d 100644 --- a/src/mainwindow.c +++ b/src/mainwindow.c @@ -74,6 +74,7 @@ #include "codeconv.h" #include "about.h" #include "manual.h" +#include "prefs_templates.h" #define AC_LABEL_WIDTH 240 @@ -368,6 +369,10 @@ static void activate_compose_button (MainWindow *mainwin, ToolbarStyle style, ComposeButtonType type); +static void prefs_templates_open_cb(MainWindow *mainwin, + guint action, + GtkWidget *widget); + #define SEPARATE_ACTION 667 static GtkItemFactoryEntry mainwin_entries[] = @@ -561,6 +566,8 @@ static GtkItemFactoryEntry mainwin_entries[] = NULL, prefs_scoring_open_cb, 0, NULL}, {N_("/_Configuration/_Filtering ..."), NULL, prefs_filtering_open_cb, 0, NULL}, + {N_("/_Configuration/_Templates ..."), + NULL, prefs_templates_open_cb, 0, NULL}, {N_("/_Configuration/_Preferences per account..."), NULL, prefs_account_open_cb, 0, NULL}, {N_("/_Configuration/---"), NULL, NULL, 0, ""}, @@ -2680,3 +2687,8 @@ static void activate_compose_button (MainWindow *mainwin, } } +static void prefs_templates_open_cb(MainWindow *mainwin, guint action, + GtkWidget *widget) +{ + prefs_templates_open(); +} diff --git a/src/prefs_templates.c b/src/prefs_templates.c new file mode 100644 index 000000000..a54fea6ff --- /dev/null +++ b/src/prefs_templates.c @@ -0,0 +1,408 @@ +/* + * Sylpheed templates subsystem + * Copyright (C) 2001 Alexander Barinov + * + * 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 "defs.h" + +#include +#include +#include +#include + +#include "intl.h" +#include "manage_window.h" +#include "main.h" +#include "utils.h" +#include "alertpanel.h" +#include "template.h" + +static struct Templates { + GtkWidget *window; + GtkWidget *ok_btn; + GtkWidget *clist_tmpls; + GtkWidget *entry_name; + GtkWidget *text_value; + + GSList *tmpl_list; +} templates; + +/* widget creating functions */ +static void prefs_templates_create_window(void); +static void prefs_templates_setup_window(void); + +/* callbacks */ +static gint prefs_templates_deleted_cb(GtkWidget *widget, + GdkEventAny *event, + gpointer data); +static void prefs_templates_key_pressed_cb(GtkWidget *widget, + GdkEventKey *event, + gpointer data); +static void prefs_templates_cancel_cb(void); +static void prefs_templates_ok_cb(void); +static void prefs_templates_select_cb(GtkCList *clist, + gint row, + gint column, + GdkEvent *event); +static void prefs_templates_register_cb (void); +static void prefs_templates_substitute_cb (void); +static void prefs_templates_delete_cb (void); + +/* Called from mainwindow.c */ +void prefs_templates_open(void) +{ + templates.tmpl_list = template_read_config(); + + inc_autocheck_timer_remove(); + + if(!templates.window){ + prefs_templates_create_window(); + } + prefs_templates_setup_window(); + gtk_widget_show(templates.window); +} + +void prefs_templates_create_window(void) +{ + /* window structure ;) */ + GtkWidget *window; + GtkWidget *vpaned; + GtkWidget *vbox1; + GtkWidget *hbox1; + GtkWidget *label1; + GtkWidget *entry_name; + GtkWidget *scroll2; + GtkWidget *text_value; + GtkWidget *vbox2; + GtkWidget *hbox2; + GtkWidget *arrow1; + GtkWidget *hbox3; + GtkWidget *reg_btn; + GtkWidget *subst_btn; + GtkWidget *del_btn; + GtkWidget *scroll1; + GtkWidget *clist_tmpls; + GtkWidget *confirm_area; + GtkWidget *ok_btn; + GtkWidget *cancel_btn; + + gchar *title[] = {_("Registered templates")}; + + /* main window */ + window = gtk_window_new(GTK_WINDOW_DIALOG); + gtk_container_set_border_width(GTK_CONTAINER(window), 8); + gtk_window_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); + gtk_window_set_modal(GTK_WINDOW(window), TRUE); + gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, FALSE); + gtk_window_set_default_size(GTK_WINDOW(window), 400, 300); + + /* vpaned to separate template settings from templates list */ + vpaned = gtk_vpaned_new(); + gtk_widget_show(vpaned); + gtk_container_add(GTK_CONTAINER(window), vpaned); + + /* vbox to handle template name and content */ + vbox1 = gtk_vbox_new(FALSE, 6); + gtk_widget_show(vbox1); + gtk_paned_pack1(GTK_PANED(vpaned), vbox1, FALSE, FALSE); + + /* hbox for a label and template name entry */ + hbox1 = gtk_hbox_new(FALSE, 12); + gtk_widget_show(hbox1); + gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(hbox1), 2); + + /* self-documenting */ + label1 = gtk_label_new(_("Template")); + gtk_widget_show(label1); + gtk_box_pack_start(GTK_BOX(hbox1), label1, FALSE, FALSE, 0); + + /* holds template name */ + entry_name = gtk_entry_new(); + gtk_widget_show(entry_name); + gtk_box_pack_start(GTK_BOX(hbox1), entry_name, TRUE, TRUE, 0); + + /* template content */ + scroll2 = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scroll2); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll2), + GTK_POLICY_NEVER, + GTK_POLICY_ALWAYS); + gtk_box_pack_start(GTK_BOX(vbox1), scroll2, TRUE, TRUE, 0); + + text_value = gtk_text_new(NULL, NULL); + gtk_widget_show(text_value); + gtk_container_add(GTK_CONTAINER(scroll2), text_value); + gtk_text_set_editable(GTK_TEXT(text_value), TRUE); + gtk_text_set_word_wrap(GTK_TEXT(text_value), TRUE); + + /* vbox for buttons and templates list */ + vbox2 = gtk_vbox_new(FALSE, 6); + gtk_widget_show(vbox2); + gtk_paned_pack2(GTK_PANED(vpaned), vbox2, TRUE, FALSE); + + /* register | substitute | delete */ + hbox2 = gtk_hbox_new(FALSE, 4); + gtk_widget_show(hbox2); + gtk_box_pack_start(GTK_BOX(vbox2), hbox2, FALSE, FALSE, 0); + + arrow1 = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT); + gtk_widget_show(arrow1); + gtk_box_pack_start(GTK_BOX(hbox2), arrow1, FALSE, FALSE, 0); + gtk_widget_set_usize(arrow1, -1, 16); + + hbox3 = gtk_hbox_new(TRUE, 4); + gtk_widget_show(hbox3); + gtk_box_pack_start(GTK_BOX(hbox2), hbox3, FALSE, FALSE, 0); + + reg_btn = gtk_button_new_with_label(_("Register")); + gtk_widget_show(reg_btn); + gtk_box_pack_start(GTK_BOX(hbox3), reg_btn, FALSE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked", + GTK_SIGNAL_FUNC (prefs_templates_register_cb), NULL); + + subst_btn = gtk_button_new_with_label(_(" Substitute ")); + gtk_widget_show(subst_btn); + gtk_box_pack_start(GTK_BOX(hbox3), subst_btn, FALSE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT(subst_btn), "clicked", + GTK_SIGNAL_FUNC(prefs_templates_substitute_cb), + NULL); + + del_btn = gtk_button_new_with_label(_("Delete")); + gtk_widget_show(del_btn); + gtk_box_pack_start(GTK_BOX(hbox3), del_btn, FALSE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT(del_btn), "clicked", + GTK_SIGNAL_FUNC(prefs_templates_delete_cb), NULL); + + /* templates list */ + scroll1 = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scroll1); + gtk_widget_set_usize(scroll1, -1, 150); + gtk_box_pack_start(GTK_BOX(vbox2), scroll1, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll1), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + clist_tmpls = gtk_clist_new_with_titles(1, title); + gtk_widget_show(clist_tmpls); + gtk_container_add(GTK_CONTAINER(scroll1), clist_tmpls); + gtk_clist_set_column_width(GTK_CLIST(clist_tmpls), 0, 80); + gtk_clist_set_selection_mode(GTK_CLIST(clist_tmpls), GTK_SELECTION_BROWSE); + GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist_tmpls)->column[0].button, + GTK_CAN_FOCUS); + gtk_signal_connect (GTK_OBJECT (clist_tmpls), "select_row", + GTK_SIGNAL_FUNC (prefs_templates_select_cb), NULL); + + /* ok | cancel */ + gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"), + &cancel_btn, _("Cancel"), NULL, NULL); + gtk_widget_show(confirm_area); + gtk_box_pack_end(GTK_BOX(vbox2), confirm_area, FALSE, FALSE, 0); + gtk_widget_grab_default(ok_btn); + + gtk_window_set_title(GTK_WINDOW(window), _("Templates")); + + gtk_signal_connect(GTK_OBJECT(window), "delete_event", + GTK_SIGNAL_FUNC(prefs_templates_deleted_cb), NULL); + gtk_signal_connect(GTK_OBJECT(window), "key_press_event", + GTK_SIGNAL_FUNC(prefs_templates_key_pressed_cb), NULL); + gtk_signal_connect(GTK_OBJECT(window), "focus_in_event", + GTK_SIGNAL_FUNC(manage_window_focus_in), NULL); + gtk_signal_connect(GTK_OBJECT(window), "focus_out_event", + GTK_SIGNAL_FUNC(manage_window_focus_out), NULL); + gtk_signal_connect(GTK_OBJECT(ok_btn), "clicked", + GTK_SIGNAL_FUNC(prefs_templates_ok_cb), NULL); + gtk_signal_connect(GTK_OBJECT(cancel_btn), "clicked", + GTK_SIGNAL_FUNC(prefs_templates_cancel_cb), NULL); + + templates.window = window; + templates.ok_btn = ok_btn; + templates.clist_tmpls = clist_tmpls; + templates.entry_name = entry_name; + templates.text_value = text_value; +} + +void prefs_templates_setup_window(void) +{ + GtkCList *clist = GTK_CLIST(templates.clist_tmpls); + GSList *cur; + gchar *cond_str[1]; + gint row; + Template *tmpl; + + manage_window_set_transient(GTK_WINDOW(templates.window)); + gtk_widget_grab_focus(templates.ok_btn); + + gtk_clist_freeze(clist); + gtk_clist_clear(clist); + + cond_str[0] = _("(New)"); + row = gtk_clist_append(clist, cond_str); + gtk_clist_set_row_data(clist, row, NULL); + + for (cur = templates.tmpl_list; cur != NULL; cur = cur->next) { + tmpl = cur->data; + cond_str[0] = tmpl->name; + row = gtk_clist_append(clist, cond_str); + gtk_clist_set_row_data(clist, row, tmpl); + } + + gtk_clist_thaw(clist); +} + +static gint prefs_templates_deleted_cb(GtkWidget *widget, GdkEventAny *event, + gpointer data) +{ + prefs_templates_cancel_cb(); + return TRUE; +} + +static void prefs_templates_key_pressed_cb(GtkWidget *widget, GdkEventKey *event, + gpointer data) +{ + if (event && event->keyval == GDK_Escape) + prefs_templates_cancel_cb(); +} + +static void prefs_templates_ok_cb(void) +{ + template_write_config(templates.tmpl_list); + template_clear_config(templates.tmpl_list); + gtk_widget_hide(templates.window); + inc_autocheck_timer_set(); +} + +static void prefs_templates_cancel_cb(void) +{ + template_clear_config(templates.tmpl_list); + gtk_widget_hide(templates.window); + inc_autocheck_timer_set(); +} + +static void prefs_templates_select_cb(GtkCList *clist, gint row, gint column, + GdkEvent *event) +{ + Template *tmpl; + Template tmpl_def = {_("Template name"), _("(empty)")}; + + if (!(tmpl = gtk_clist_get_row_data(clist, row))) + tmpl = &tmpl_def; + + gtk_entry_set_text(GTK_ENTRY(templates.entry_name), tmpl->name); + + gtk_text_freeze(GTK_TEXT(templates.text_value)); + gtk_text_set_point(GTK_TEXT(templates.text_value), 0); + gtk_text_forward_delete(GTK_TEXT(templates.text_value), + gtk_text_get_length(GTK_TEXT(templates.text_value))); + gtk_text_insert(GTK_TEXT(templates.text_value), NULL, NULL, NULL, + tmpl->value, -1); + gtk_text_thaw(GTK_TEXT(templates.text_value)); +} + +static void prefs_templates_create_list(void) +{ + gint row = 1; + Template *tmpl; + + g_slist_free(templates.tmpl_list); + templates.tmpl_list = NULL; + + while ((tmpl = gtk_clist_get_row_data(GTK_CLIST(templates.clist_tmpls),row)) != NULL) { + templates.tmpl_list = g_slist_append(templates.tmpl_list, tmpl); + row++; + } +} + +static gint prefs_templates_clist_set_row(gint row) +{ + GtkCList *clist = GTK_CLIST(templates.clist_tmpls); + Template *tmpl; + Template *tmp_tmpl; + gchar *name; + gchar *value; + gchar *tmpl_str[1]; + + g_return_val_if_fail(row != 0, -1); + + name = gtk_editable_get_chars(GTK_EDITABLE(templates.entry_name), + 0, -1); + value = gtk_editable_get_chars(GTK_EDITABLE(templates.text_value), + 0, -1); + + + tmpl = g_new(Template, 1); + tmpl->name = name; + tmpl->value = value; + + tmpl_str[0] = name; + + if (row < 0) { + row = gtk_clist_append(clist, tmpl_str); + } else { + gtk_clist_set_text(clist, row, 0, name); + tmp_tmpl = gtk_clist_get_row_data(clist, row); + if (tmp_tmpl) + template_free(tmp_tmpl); + } + + gtk_clist_set_row_data(clist, row, tmpl); + prefs_templates_create_list(); + return row; +} + +static void prefs_templates_register_cb(void) +{ + prefs_templates_clist_set_row(-1); +} + +static void prefs_templates_substitute_cb(void) +{ + GtkCList *clist = GTK_CLIST(templates.clist_tmpls); + Template *tmpl; + gint row; + + if (!clist->selection) return; + + row = GPOINTER_TO_INT(clist->selection->data); + if (row == 0) return; + + tmpl = gtk_clist_get_row_data(clist, row); + if (!tmpl) return; + + prefs_templates_clist_set_row(row); +} + +static void prefs_templates_delete_cb(void) +{ + GtkCList *clist = GTK_CLIST(templates.clist_tmpls); + Template *tmpl; + gint row; + + if (!clist->selection) return; + row = GPOINTER_TO_INT(clist->selection->data); + if (row == 0) return; + + if (alertpanel(_("Delete template"), + _("Do you really want to delete this template?"), + _("Yes"), _("No"), NULL) == G_ALERTALTERNATE) + return; + + tmpl = gtk_clist_get_row_data(clist, row); + template_free(tmpl); + gtk_clist_remove(clist, row); + templates.tmpl_list = g_slist_remove(templates.tmpl_list, tmpl); +} diff --git a/src/prefs_templates.h b/src/prefs_templates.h new file mode 100644 index 000000000..c8a0c43fe --- /dev/null +++ b/src/prefs_templates.h @@ -0,0 +1,25 @@ +/* + * Sylpheed templates subsystem + * Copyright (C) 2001 Alexander Barinov + * + * 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. + */ + +#ifndef __PREFS_TEMPLATES_H__ +#define __PREFS_TEMPLATES_H__ + +void prefs_templates_open (void); + +#endif /* __PREFS_TEMPLATES_H__ */ diff --git a/src/template.c b/src/template.c new file mode 100644 index 000000000..26b01bdd1 --- /dev/null +++ b/src/template.c @@ -0,0 +1,174 @@ +/* + * Sylpheed templates subsystem + * Copyright (C) 2001 Alexander Barinov + * + * 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 "defs.h" + +#include +#include +#include +#include + +#include "utils.h" +#include "main.h" +#include "template.h" +#include "intl.h" + +static GSList* template_load(GSList *tmpl_list, gchar *filename) +{ + Template *tmpl; + FILE *fp; + char buf[32000]; + gint bytes_read; + + LOG_MESSAGE(_("%s:%d loading template from %s\n"), __FILE__, __LINE__, filename); + + if ((fp = fopen(filename, "r")) == NULL) { + FILE_OP_ERROR(filename, "fopen"); + return tmpl_list; + } + + tmpl = g_new(Template, 1); + + if (fgets(buf, sizeof(buf), fp) == NULL) { + FILE_OP_ERROR(filename, "fgets"); + g_free(tmpl); + LOG_MESSAGE(_("%s:%d exiting\n"), __FILE__, __LINE__); + return tmpl_list; + } + tmpl->name = g_strdup(g_strstrip(buf)); + + memset(buf, 0, sizeof(buf)); + if ((bytes_read = fread(buf, 1, sizeof(buf)-1, fp)) == 0) { + FILE_OP_ERROR(filename, "fread"); + g_free(tmpl->name); + g_free(tmpl); + return tmpl_list; + } + tmpl->value = g_strdup(buf); + + tmpl_list = g_slist_append(tmpl_list, tmpl); + fclose(fp); + return tmpl_list; +} + +void template_free(Template *tmpl) +{ + g_free(tmpl->name); + g_free(tmpl->value); + g_free(tmpl); +} + +void template_clear_config(GSList *tmpl_list) +{ + Template *tmpl; + + while (tmpl_list != NULL) { + tmpl = tmpl_list->data; + template_free(tmpl); + tmpl_list = g_slist_remove(tmpl_list, tmpl); + } +} + +GSList* template_read_config(void) +{ + gchar *path; + gchar *filename; + DIR *dp; + struct dirent *de; + struct stat s; + GSList *tmpl_list = NULL; + + path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, TEMPLATES_DIR, NULL); + LOG_MESSAGE(_("%s:%d reading templates dir %s\n"), __FILE__, __LINE__, path); + + if ((dp = opendir(path)) == NULL) { + FILE_OP_ERROR(path, "opendir"); + return tmpl_list; + } + + while ((de = readdir(dp)) != NULL) { + filename = g_strconcat(path, G_DIR_SEPARATOR_S, de->d_name, NULL); + LOG_MESSAGE(_("%s:%d found file %s\n"), __FILE__, __LINE__, filename); + + if (stat(filename, &s) != 0 || !S_ISREG(s.st_mode) ) { + LOG_MESSAGE(_("%s:%d %s is not an ordinary file\n"), + __FILE__, __LINE__, filename); + continue; + } + + tmpl_list = template_load(tmpl_list, filename); + g_free(filename); + } + + closedir(dp); + g_free(path); + return tmpl_list; +} + +void template_write_config(GSList *tmpl_list) +{ + gchar *path; + gchar *filename; + GSList *cur; + Template *tmpl; + FILE *fp; + gint tmpl_num = 1; + + path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, TEMPLATES_DIR, NULL); + + if (!is_dir_exist(path)) { + if (is_file_exist(path)) { + LOG_MESSAGE(_("%s:%d file %s allready exists\n"), + __FILE__, __LINE__, filename); + g_free(path); + return; + } + if (mkdir(path, S_IRWXU) < 0) { + FILE_OP_ERROR(path, "mkdir"); + g_free(path); + return; + } + } + + remove_all_files(path); + + for (cur = tmpl_list; cur != NULL; cur = cur->next) { + tmpl = cur->data; + + filename = g_strconcat(path, G_DIR_SEPARATOR_S, itos(tmpl_num), NULL); + + if ((fp = fopen(filename, "w")) == NULL) { + FILE_OP_ERROR(filename, "fopen"); + g_free(filename); + g_free(path); + return; + } + + LOG_MESSAGE(_("%s:%d writing template \"%s\" to %s\n"), + __FILE__, __LINE__, tmpl->name, filename); + fputs(tmpl->name, fp); + fputs("\n", fp); + fwrite(tmpl->value, sizeof(gchar), strlen(tmpl->value), fp); + fclose(fp); + + tmpl_num ++; + } + + g_free(path); +} diff --git a/src/template.h b/src/template.h new file mode 100644 index 000000000..a069d60a3 --- /dev/null +++ b/src/template.h @@ -0,0 +1,38 @@ +/* + * Sylpheed templates subsystem + * Copyright (C) 2001 Alexander Barinov + * + * 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. + */ + +#ifndef __TEMPLATE_H__ +#define __TEMPLATE_H__ + +struct _Template { + gchar *name; + gchar *value; +}; + +typedef struct _Template Template; + +#define LOG_MESSAGE \ + debug_mode == 0 ? (debug_mode == debug_mode) : (void)debug_print + +void template_free (Template *tmpl); +void template_clear_config (GSList *tmpl_list); +GSList* template_read_config (void); +void template_write_config (GSList *tmpl_list); + +#endif /* __TEMPLATE_H__ */ diff --git a/src/template_select.c b/src/template_select.c new file mode 100644 index 000000000..aa052d7cd --- /dev/null +++ b/src/template_select.c @@ -0,0 +1,208 @@ +/* + * Sylpheed templates subsystem + * Copyright (C) 2001 Alexander Barinov + * + * 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 "defs.h" + +#include +#include +#include +#include + +#include "intl.h" +#include "manage_window.h" +#include "main.h" +#include "utils.h" +#include "alertpanel.h" +#include "template.h" + +static struct Template_select { + GtkWidget *window; + GtkWidget *ok_btn; + GtkWidget *clist_tmpls; + + GSList *tmpl_list; + void (*template_cb)(gchar *s, gpointer data); + gpointer save_data; +} tmplsl; + +/* widget creating functions */ +static void template_select_create_window(void); +static void template_select_setup_window(void); + +/* callbacks */ +static gint template_select_deleted_cb(GtkWidget *widget, + GdkEventAny *event, + gpointer data); +static void template_select_key_pressed_cb(GtkWidget *widget, + GdkEventKey *event, + gpointer data); +static void template_select_cancel_cb(void); +static void template_select_ok_cb(void); + +/* Called from elsewhere */ +void template_select (void (*template_apply_cb)(gchar *s, gpointer data), + gpointer data) +{ + tmplsl.template_cb = template_apply_cb; + tmplsl.save_data = data; + + tmplsl.tmpl_list = template_read_config(); + + inc_autocheck_timer_remove(); + + if(!tmplsl.window){ + template_select_create_window(); + } + template_select_setup_window(); + gtk_widget_show(tmplsl.window); +} + +void template_select_create_window(void) +{ + /* window structure ;) */ + GtkWidget *window; + GtkWidget *vbox1; + GtkWidget *scroll1; + GtkWidget *clist_tmpls; + GtkWidget *confirm_area; + GtkWidget *ok_btn; + GtkWidget *cancel_btn; + + gchar *title[] = {_("Registered templates")}; + + /* main window */ + window = gtk_window_new(GTK_WINDOW_DIALOG); + gtk_container_set_border_width(GTK_CONTAINER(window), 8); + gtk_window_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); + gtk_window_set_modal(GTK_WINDOW(window), TRUE); + gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, FALSE); + gtk_window_set_default_size(GTK_WINDOW(window), 200, 300); + + /* vbox to handle template name and content */ + vbox1 = gtk_vbox_new(FALSE, 6); + gtk_widget_show(vbox1); + gtk_container_add(GTK_CONTAINER(window), vbox1); + + /* templates list */ + scroll1 = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scroll1); + gtk_widget_set_usize(scroll1, -1, 150); + gtk_box_pack_start(GTK_BOX(vbox1), scroll1, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll1), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + clist_tmpls = gtk_clist_new_with_titles(1, title); + gtk_widget_show(clist_tmpls); + gtk_container_add(GTK_CONTAINER(scroll1), clist_tmpls); + gtk_clist_set_column_width(GTK_CLIST(clist_tmpls), 0, 80); + gtk_clist_set_selection_mode(GTK_CLIST(clist_tmpls), GTK_SELECTION_BROWSE); + GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist_tmpls)->column[0].button, + GTK_CAN_FOCUS); + + /* ok | cancel */ + gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"), + &cancel_btn, _("Cancel"), NULL, NULL); + gtk_widget_show(confirm_area); + gtk_box_pack_end(GTK_BOX(vbox1), confirm_area, FALSE, FALSE, 0); + gtk_widget_grab_default(ok_btn); + + gtk_window_set_title(GTK_WINDOW(window), _("Templates")); + + gtk_signal_connect(GTK_OBJECT(window), "delete_event", + GTK_SIGNAL_FUNC(template_select_deleted_cb), NULL); + gtk_signal_connect(GTK_OBJECT(window), "key_press_event", + GTK_SIGNAL_FUNC(template_select_key_pressed_cb), NULL); + gtk_signal_connect(GTK_OBJECT(window), "focus_in_event", + GTK_SIGNAL_FUNC(manage_window_focus_in), NULL); + gtk_signal_connect(GTK_OBJECT(window), "focus_out_event", + GTK_SIGNAL_FUNC(manage_window_focus_out), NULL); + gtk_signal_connect(GTK_OBJECT(ok_btn), "clicked", + GTK_SIGNAL_FUNC(template_select_ok_cb), NULL); + gtk_signal_connect(GTK_OBJECT(cancel_btn), "clicked", + GTK_SIGNAL_FUNC(template_select_cancel_cb), NULL); + + tmplsl.window = window; + tmplsl.ok_btn = ok_btn; + tmplsl.clist_tmpls = clist_tmpls; +} + +void template_select_setup_window(void) +{ + GtkCList *clist = GTK_CLIST(tmplsl.clist_tmpls); + GSList *cur; + gint row; + Template *tmpl; + gchar *cond_str[1]; + + manage_window_set_transient(GTK_WINDOW(tmplsl.window)); + gtk_widget_grab_focus(tmplsl.ok_btn); + + gtk_clist_freeze(clist); + gtk_clist_clear(clist); + + for (cur = tmplsl.tmpl_list; cur != NULL; cur = cur->next) { + tmpl = cur->data; + cond_str[0] = tmpl->name; + row = gtk_clist_append(clist, cond_str); + gtk_clist_set_row_data(clist, row, tmpl); + } + + gtk_clist_thaw(clist); +} + +static gint template_select_deleted_cb(GtkWidget *widget, GdkEventAny *event, + gpointer data) +{ + template_select_cancel_cb(); + return TRUE; +} + +static void template_select_key_pressed_cb(GtkWidget *widget, GdkEventKey *event, + gpointer data) +{ + if (event && event->keyval == GDK_Escape) + template_select_cancel_cb(); +} + +static void template_select_ok_cb(void) +{ + GtkCList *clist = GTK_CLIST(tmplsl.clist_tmpls); + gchar *s; + Template *tmpl; + gint row; + + if (!clist->selection) return; + row = GPOINTER_TO_INT(clist->selection->data); + tmpl = gtk_clist_get_row_data(clist, row); + s = g_strdup(tmpl->value); + + template_clear_config(tmplsl.tmpl_list); + gtk_widget_hide(tmplsl.window); + inc_autocheck_timer_set(); + tmplsl.template_cb(s, tmplsl.save_data); +} + +static void template_select_cancel_cb(void) +{ + template_clear_config(tmplsl.tmpl_list); + gtk_widget_hide(tmplsl.window); + inc_autocheck_timer_set(); + tmplsl.template_cb(NULL, tmplsl.save_data); +} diff --git a/src/template_select.h b/src/template_select.h new file mode 100644 index 000000000..897771b5a --- /dev/null +++ b/src/template_select.h @@ -0,0 +1,26 @@ +/* + * Sylpheed templates subsystem + * Copyright (C) 2001 Alexander Barinov + * + * 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. + */ + +#ifndef __TEMPLATE_SELECT_H__ +#define __TEMPLATE_SELECT_H__ + +void template_select (void (*template_apply_cb)(gchar *s, gpointer data), + gpointer data); + +#endif /* __TEMPLATE_SELECT_H__ */