editldap.c editldap.h \
editldap_basedn.c editldap_basedn.h \
addressadd.c addressadd.h \
+ addrharvest.c addrharvest.h \
+ addrgather.c addrgather.h \
filesel.c filesel.h \
foldersel.c foldersel.h \
statusbar.c statusbar.h \
#include "addrselect.h"
#include "addrclip.h"
+#include "addrgather.h"
typedef enum
{
}
}
+/*
+* Gather addresses.
+* Enter: folderItem Folder to import.
+*/
+void addressbook_gather( FolderItem *folderItem ) {
+ AddressDataSource *ds = NULL;
+ AdapterDSource *ads = NULL;
+ AddressBookFile *abf = NULL;
+ AdapterInterface *adapter;
+ GtkCTreeNode *newNode;
+
+ abf = addrgather_dlg_execute( folderItem, _addressIndex_ );
+ if( abf ) {
+ ds = addrindex_index_add_datasource(
+ _addressIndex_, ADDR_IF_BOOK, abf );
+
+ adapter = addrbookctl_find_interface( ADDR_IF_BOOK );
+ if( adapter ) {
+ if( adapter->treeNode ) {
+ ads = addressbook_create_ds_adapter(
+ ds, ADDR_BOOK, addrbook_get_name( abf ) );
+ newNode = addressbook_add_object(
+ adapter->treeNode,
+ ADDRESS_OBJECT(ads) );
+ }
+ }
+
+ /* Notify address completion */
+ invalidate_address_completion();
+ }
+}
+
/*
* End of Source.
*/
gboolean addressbook_load_completion ( gint (*callBackFunc) ( const gchar *, const gchar * ) );
+void addressbook_gather ( FolderItem *folderItem );
+
#endif /* __ADDRESSBOOK_H__ */
--- /dev/null
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2002 Match Grun
+ *
+ * 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.
+ */
+
+/*
+* Dialog for gathering EMail addresses from mail folder.
+*/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "defs.h"
+
+#include <glib.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkhbbox.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkfilesel.h>
+#include <gtk/gtksignal.h>
+
+#include "intl.h"
+#include "main.h"
+#include "inc.h"
+#include "mbox.h"
+#include "filesel.h"
+#include "foldersel.h"
+#include "gtkutils.h"
+#include "alertpanel.h"
+#include "manage_window.h"
+#include "folder.h"
+#include "utils.h"
+
+#include "addrharvest.h"
+#include "addrindex.h"
+#include "addrbook.h"
+
+#define PAGE_WARNING 0
+#define PAGE_FIELDS 1
+#define PAGE_FINISH 2
+
+#define NUM_FIELDS 6
+
+#define FIELDS_N_COLS 2
+#define FIELDS_COL_WIDTH_HEADER 100
+#define FIELDS_COL_WIDTH_COUNT 140
+
+#define MIN_FOLDER_SIZE 20
+#define DFL_FOLDER_SIZE 50
+
+typedef enum {
+ FIELD_COL_HEADER = 0,
+ FIELD_COL_COUNT = 1
+} AddrGather_FieldColPos;
+
+/*
+* The dialog.
+*/
+static struct _AddrGather_Dlg_ {
+ GtkWidget *window;
+ GtkWidget *notebook;
+ GtkWidget *labelFolder;
+ GtkWidget *entryBook;
+ GtkWidget *checkHeader[ NUM_FIELDS ];
+ GtkWidget *spinbtnFolder;
+ GtkWidget *btnOk;
+ GtkWidget *btnCancel;
+ GtkWidget *statusbar;
+ gint status_cid;
+ gboolean cancelled;
+ gchar *folderPath;
+ GtkWidget *clistCount;
+} addrgather_dlg;
+
+static AddressIndex *_harv_addressIndex_;
+static AddressBookFile *_harv_addressBook_;
+static gchar *_harv_headerNames_[] = {
+ HEADER_FROM,
+ HEADER_REPLY_TO,
+ HEADER_SENDER,
+ HEADER_TO,
+ HEADER_CC,
+ HEADER_ERRORS_TO
+};
+
+void addrgather_dlg_status_show( gchar *msg ) {
+ if( addrgather_dlg.statusbar != NULL ) {
+ gtk_statusbar_pop( GTK_STATUSBAR(addrgather_dlg.statusbar),
+ addrgather_dlg.status_cid );
+ if( msg ) {
+ gtk_statusbar_push(
+ GTK_STATUSBAR(addrgather_dlg.statusbar),
+ addrgather_dlg.status_cid, msg );
+ }
+ }
+}
+
+static gint addrgather_dlg_delete_event(
+ GtkWidget *widget, GdkEventAny *event, gpointer data )
+{
+ addrgather_dlg.cancelled = TRUE;
+ gtk_main_quit();
+ return TRUE;
+}
+
+static void addrgather_dlg_key_pressed(
+ GtkWidget *widget, GdkEventKey *event, gpointer data )
+{
+ if( event && event->keyval == GDK_Escape ) {
+ addrgather_dlg.cancelled = TRUE;
+ gtk_main_quit();
+ }
+}
+
+#define FMT_BUFSIZE 32
+
+static gboolean addrgather_dlg_harvest() {
+ GtkCList *clist;
+ gchar *text[ FIELDS_N_COLS ];
+ AddressHarvester *harvester;
+ AddressBookFile *abf;
+ gchar *name;
+ gchar *newFile;
+ gchar str[ FMT_BUFSIZE ];
+ gint cnt;
+ gint i;
+ gint sz;
+
+ name = gtk_editable_get_chars( GTK_EDITABLE(addrgather_dlg.entryBook), 0, -1 );
+ if( name == NULL || strlen( name ) < 1 ) {
+ addrgather_dlg_status_show(
+ _( "Please specify name for address book." ) );
+ g_free( name );
+ return FALSE;
+ }
+
+ /* Create harvest helper */
+ harvester = addrharvest_create();
+ addrharvest_set_path( harvester, addrgather_dlg.folderPath );
+
+ for( i = 0; i < NUM_FIELDS; i++ ) {
+ addrharvest_set_header( harvester, _harv_headerNames_[i],
+ gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(addrgather_dlg.checkHeader[i]) ) );
+ }
+
+ if( addrharvest_check_header( harvester ) == FALSE ) {
+ addrgather_dlg_status_show(
+ _( "Please select the mail headers to search." ) );
+ addrharvest_free( harvester );
+ return FALSE;
+ }
+
+ sz = gtk_spin_button_get_value_as_int(
+ GTK_SPIN_BUTTON( addrgather_dlg.spinbtnFolder ) );
+ addrharvest_set_folder_size( harvester, sz );
+
+ /* Create address book */
+ abf = addrbook_create_book();
+ addrbook_set_path( abf, _harv_addressIndex_->filePath );
+ newFile = addrbook_guess_next_file( abf );
+ addrbook_set_file( abf, newFile );
+ addrbook_set_name( abf, name );
+ g_free( newFile );
+ g_free( name );
+
+ /* Harvest addresses */
+ addrharvest_harvest( harvester, abf->addressCache );
+ addrbook_save_data( abf );
+ _harv_addressBook_ = abf;
+
+ /* Update summary count */
+ clist = GTK_CLIST(addrgather_dlg.clistCount);
+ gtk_clist_clear( clist );
+ for( i = 0; i < NUM_FIELDS; i++ ) {
+ cnt = addrharvest_get_count( harvester, _harv_headerNames_[i] );
+ if( cnt < 1 ) {
+ strcpy( str, "-" );
+ }
+ else {
+ sprintf( str, "%d", cnt );
+ }
+ text[ FIELD_COL_HEADER ] = _harv_headerNames_[i];
+ text[ FIELD_COL_COUNT ] = str;
+ gtk_clist_append( clist, text );
+ }
+
+ addrharvest_free( harvester );
+
+ addrgather_dlg_status_show( _("Addresses gathered successfully.") );
+
+ /* Display summary page */
+ gtk_notebook_set_page(
+ GTK_NOTEBOOK(addrgather_dlg.notebook), PAGE_FINISH );
+ gtk_widget_set_sensitive( addrgather_dlg.btnOk, FALSE );
+ gtk_widget_grab_default( addrgather_dlg.btnCancel );
+
+ return TRUE;
+}
+
+static void addrgather_dlg_ok( GtkWidget *widget, gpointer data ) {
+ if( addrgather_dlg_harvest() ) {
+ addrgather_dlg.cancelled = FALSE;
+ }
+}
+
+static void addrgather_dlg_cancel( GtkWidget *widget, gpointer data ) {
+ gtk_main_quit();
+}
+
+#define PACK_CHECK_BUTTON(box, chkbtn, label) \
+{ \
+ chkbtn = gtk_check_button_new_with_label(label); \
+ gtk_widget_show(chkbtn); \
+ gtk_box_pack_start(GTK_BOX(box), chkbtn, FALSE, TRUE, 0); \
+}
+
+/*
+ * Create notebook page for warning message.
+ * Enter: pageNum Page number.
+ * pageLbl Page label.
+ */
+static void addrgather_page_warning( gint pageNum, gchar *pageLbl ) {
+ GtkWidget *vbox;
+ GtkWidget *table;
+ GtkWidget *label;
+ gint top;
+
+ vbox = gtk_vbox_new(FALSE, 8);
+ gtk_container_add( GTK_CONTAINER( addrgather_dlg.notebook ), vbox );
+ gtk_container_set_border_width( GTK_CONTAINER (vbox), BORDER_WIDTH );
+
+ label = gtk_label_new( pageLbl );
+ gtk_widget_show( label );
+ gtk_notebook_set_tab_label(
+ GTK_NOTEBOOK( addrgather_dlg.notebook ),
+ gtk_notebook_get_nth_page( GTK_NOTEBOOK( addrgather_dlg.notebook ), pageNum ),
+ label );
+
+ table = gtk_table_new(3, 2, FALSE);
+ gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
+ gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
+ gtk_table_set_row_spacings(GTK_TABLE(table), 8);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 8 );
+
+ /* First row */
+ top = 0;
+ label = gtk_label_new(_(""));
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ /* First row */
+ top++;
+ label = gtk_label_new(_("No folder was selected."));
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ /* Second row */
+ top++;
+ label = gtk_label_new(_("Please select a folder to process from the folder list."));
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+}
+
+/*
+ * Create notebook page for mail headers.
+ * Enter: pageNum Page number.
+ * pageLbl Page label.
+ */
+static void addrgather_page_fields( gint pageNum, gchar *pageLbl ) {
+ GtkWidget *vbox;
+ GtkWidget *vboxf;
+ GtkWidget *hboxs;
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *labelFolder;
+ GtkWidget *entryBook;
+ GtkWidget *frameHeader;
+ GtkWidget *checkHeader[ NUM_FIELDS ];
+ GtkWidget *spinbtnFolder;
+ GtkObject *adjFolder;
+ gint top;
+ gint i;
+
+ /* Container */
+ vbox = gtk_vbox_new(FALSE, 8);
+ gtk_container_add( GTK_CONTAINER( addrgather_dlg.notebook ), vbox );
+ gtk_container_set_border_width( GTK_CONTAINER (vbox), 4 );
+
+ /* Notebook page */
+ label = gtk_label_new( pageLbl );
+ gtk_widget_show( label );
+ gtk_notebook_set_tab_label(
+ GTK_NOTEBOOK( addrgather_dlg.notebook ),
+ gtk_notebook_get_nth_page( GTK_NOTEBOOK( addrgather_dlg.notebook ), pageNum ),
+ label );
+
+ /* Upper area - Field list */
+ table = gtk_table_new( 4, 2, FALSE);
+ gtk_box_pack_start( GTK_BOX(vbox), table, FALSE, FALSE, 0 );
+ gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
+ gtk_table_set_row_spacings( GTK_TABLE(table), 8 );
+ gtk_table_set_col_spacings( GTK_TABLE(table), 8 );
+
+ /* First row */
+ top = 0;
+ label = gtk_label_new( _("Folder :") );
+ gtk_table_attach( GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0 );
+ gtk_misc_set_alignment( GTK_MISC(label), 1.0, 0.5 );
+
+ labelFolder = gtk_label_new( "" );
+ gtk_table_attach( GTK_TABLE(table), labelFolder, 1, 2, top, (top + 1),
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0 );
+ gtk_misc_set_alignment( GTK_MISC(labelFolder), 0, 0.5 );
+
+ /* Second row */
+ top = 1;
+ label = gtk_label_new( _("Address Book :") );
+ gtk_table_attach( GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0 );
+ gtk_misc_set_alignment( GTK_MISC(label), 1.0, 0.5 );
+
+ entryBook = gtk_entry_new();
+ gtk_table_attach( GTK_TABLE(table), entryBook, 1, 2, top, (top + 1),
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0 );
+
+ /* Third row */
+ top = 2;
+ label = gtk_label_new( _("Folder Size :") );
+ gtk_table_attach( GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0 );
+ gtk_misc_set_alignment( GTK_MISC(label), 1.0, 0.5 );
+
+ hboxs = gtk_hbox_new( FALSE, 8 );
+ adjFolder =
+ gtk_adjustment_new( DFL_FOLDER_SIZE, MIN_FOLDER_SIZE, G_MAXINT, 1, 10, 100 );
+ spinbtnFolder = gtk_spin_button_new( GTK_ADJUSTMENT(adjFolder), 1, 0 );
+ gtk_box_pack_start( GTK_BOX(hboxs), spinbtnFolder, FALSE, FALSE, 0);
+ gtk_widget_set_usize( spinbtnFolder, 100, -1);
+ gtk_spin_button_set_numeric( GTK_SPIN_BUTTON(spinbtnFolder), TRUE );
+ gtk_table_attach( GTK_TABLE(table), hboxs, 1, 2, top, (top + 1), GTK_FILL, 0, 0, 0 );
+
+ /* Fourth row */
+ top = 3;
+ frameHeader = gtk_frame_new( _("Process these mail header fields") );
+ gtk_widget_show( frameHeader );
+ gtk_table_attach( GTK_TABLE(table), frameHeader, 0, 2, top, (top + 4), GTK_FILL, 0, 0, 0 );
+ gtk_frame_set_label_align( GTK_FRAME(frameHeader), 0.01, 0.5 );
+
+ /* Check boxes */
+ vboxf = gtk_vbox_new( FALSE, 0 );
+ gtk_widget_show( vboxf );
+ gtk_container_add( GTK_CONTAINER( frameHeader ), vboxf );
+ gtk_container_set_border_width (GTK_CONTAINER( vboxf ), 8);
+
+ for( i = 0; i < NUM_FIELDS; i++ ) {
+ PACK_CHECK_BUTTON( vboxf, checkHeader[i], _harv_headerNames_[i] );
+ addrgather_dlg.checkHeader[i] = checkHeader[i];
+ }
+
+ addrgather_dlg.labelFolder = labelFolder;
+ addrgather_dlg.entryBook = entryBook;
+ addrgather_dlg.spinbtnFolder = spinbtnFolder;
+}
+
+/*
+ * Create notebook page for summary counts.
+ * Enter: pageNum Page number.
+ * pageLbl Page label.
+ */
+static void addrgather_page_finish( gint pageNum, gchar *pageLbl ) {
+ GtkWidget *label;
+ GtkWidget *vbox;
+ GtkWidget *clistSWin;
+ GtkWidget *clistCount;
+ gchar *titles[ FIELDS_N_COLS ];
+ gint i;
+
+ titles[ FIELD_COL_HEADER ] = _("Header Name");
+ titles[ FIELD_COL_COUNT ] = _("Address Count");
+
+ vbox = gtk_vbox_new(FALSE, 8);
+ gtk_container_add( GTK_CONTAINER( addrgather_dlg.notebook ), vbox );
+ gtk_container_set_border_width( GTK_CONTAINER (vbox), 8 );
+
+ label = gtk_label_new( pageLbl );
+ gtk_widget_show( label );
+ gtk_notebook_set_tab_label(
+ GTK_NOTEBOOK( addrgather_dlg.notebook ),
+ gtk_notebook_get_nth_page( GTK_NOTEBOOK( addrgather_dlg.notebook ), pageNum ),
+ label );
+
+ /* Summary count */
+ clistSWin = gtk_scrolled_window_new( NULL, NULL );
+ gtk_container_add( GTK_CONTAINER(vbox), clistSWin );
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(clistSWin),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_ALWAYS);
+
+ clistCount = gtk_clist_new_with_titles( FIELDS_N_COLS, titles );
+ gtk_container_add( GTK_CONTAINER(clistSWin), clistCount );
+ gtk_clist_set_selection_mode( GTK_CLIST(clistCount), GTK_SELECTION_BROWSE );
+ gtk_clist_set_column_width(
+ GTK_CLIST(clistCount), FIELD_COL_HEADER, FIELDS_COL_WIDTH_HEADER );
+ gtk_clist_set_column_width(
+ GTK_CLIST(clistCount), FIELD_COL_COUNT, FIELDS_COL_WIDTH_COUNT );
+
+ for( i = 0; i < FIELDS_N_COLS; i++ )
+ GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clistCount)->column[i].button, GTK_CAN_FOCUS);
+
+ addrgather_dlg.clistCount = clistCount;
+}
+
+/*
+ * Create notebook page for warning message.
+ * Enter: pageNum Page number.
+ * pageLbl Page label.
+ */
+static void addrgather_dlg_create( void ) {
+ GtkWidget *window;
+ GtkWidget *notebook;
+ GtkWidget *btnOk;
+ GtkWidget *btnCancel;
+ GtkWidget *statusbar;
+ GtkWidget *vbox;
+ GtkWidget *vnbox;
+ GtkWidget *hbbox;
+ GtkWidget *hsbox;
+
+ window = gtk_window_new( GTK_WINDOW_DIALOG );
+ gtk_widget_set_usize( window, 380, -1 );
+ gtk_container_set_border_width(GTK_CONTAINER(window), 0);
+ gtk_window_set_title( GTK_WINDOW(window), _("Gather E-Mail Addresses") );
+ gtk_window_set_position( GTK_WINDOW(window), GTK_WIN_POS_CENTER );
+ gtk_window_set_modal( GTK_WINDOW(window), TRUE );
+ gtk_signal_connect( GTK_OBJECT(window), "delete_event",
+ GTK_SIGNAL_FUNC( addrgather_dlg_delete_event ), NULL );
+ gtk_signal_connect( GTK_OBJECT(window), "key_press_event",
+ GTK_SIGNAL_FUNC( addrgather_dlg_key_pressed ), NULL );
+
+ vbox = gtk_vbox_new( FALSE, 8 );
+ gtk_container_add( GTK_CONTAINER(window), vbox );
+ gtk_container_set_border_width( GTK_CONTAINER(vbox), 0 );
+
+ vnbox = gtk_vbox_new(FALSE, 4);
+ gtk_container_set_border_width(GTK_CONTAINER(vnbox), 4);
+ gtk_widget_show(vnbox);
+ gtk_box_pack_start(GTK_BOX(vbox), vnbox, TRUE, TRUE, 0);
+
+ /* Notebook */
+ notebook = gtk_notebook_new();
+ gtk_notebook_set_show_tabs( GTK_NOTEBOOK(notebook), FALSE );
+ gtk_widget_show(notebook);
+ gtk_box_pack_start(GTK_BOX(vnbox), notebook, TRUE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(notebook), 6);
+
+ /* Status line */
+ hsbox = gtk_hbox_new( FALSE, 0 );
+ gtk_box_pack_end( GTK_BOX(vbox), hsbox, FALSE, FALSE, BORDER_WIDTH );
+ statusbar = gtk_statusbar_new();
+ gtk_box_pack_start( GTK_BOX(hsbox), statusbar, TRUE, TRUE, BORDER_WIDTH );
+
+ /* Button panel */
+ gtkut_button_set_create( &hbbox, &btnOk, _("OK"),
+ &btnCancel, _("Cancel"), NULL, NULL );
+ gtk_box_pack_end( GTK_BOX(vbox), hbbox, FALSE, FALSE, 0 );
+ gtk_container_set_border_width( GTK_CONTAINER(hbbox), 0 );
+
+ /* Signal handlers */
+ gtk_signal_connect( GTK_OBJECT(btnOk), "clicked",
+ GTK_SIGNAL_FUNC(addrgather_dlg_ok), NULL );
+ gtk_signal_connect( GTK_OBJECT(btnCancel), "clicked",
+ GTK_SIGNAL_FUNC(addrgather_dlg_cancel), NULL );
+
+ gtk_widget_show_all( vbox );
+ addrgather_dlg.window = window;
+ addrgather_dlg.notebook = notebook;
+ addrgather_dlg.btnOk = btnOk;
+ addrgather_dlg.btnCancel = btnCancel;
+ addrgather_dlg.statusbar = statusbar;
+ addrgather_dlg.status_cid = gtk_statusbar_get_context_id(
+ GTK_STATUSBAR(statusbar), "Gather E-Mail Address Dialog" );
+
+ /* Create notebook pages */
+ addrgather_page_warning( PAGE_WARNING, _( "Warning" ) );
+ addrgather_page_fields( PAGE_FIELDS, _( "Header Fields" ) );
+ addrgather_page_finish( PAGE_FINISH, _( "Finish" ) );
+ gtk_widget_show_all( addrgather_dlg.window );
+}
+
+/*
+* Gather addresses main window.
+* Enter: folderItem Source folder.
+* addrIndex Address index.
+* Return: Populated address book file, or NULL if none created.
+*/
+AddressBookFile *addrgather_dlg_execute( FolderItem *folderItem, AddressIndex *addrIndex ) {
+ gboolean errFlag;
+ gint i;
+
+ _harv_addressIndex_ = addrIndex;
+ _harv_addressBook_ = NULL;
+
+ /* Create dialog */
+ if( ! addrgather_dlg.window ) {
+ addrgather_dlg_create();
+ }
+
+ errFlag = TRUE;
+ if( folderItem && folderItem->path ) {
+ gtk_notebook_set_page(
+ GTK_NOTEBOOK(addrgather_dlg.notebook), PAGE_FIELDS );
+ addrgather_dlg.folderPath = folder_item_get_path( folderItem );
+
+ /* Setup some default values */
+ gtk_label_set_text(
+ GTK_LABEL(addrgather_dlg.labelFolder), folderItem->path );
+ gtk_entry_set_text(
+ GTK_ENTRY(addrgather_dlg.entryBook), folderItem->path );
+
+ for( i = 0; i < NUM_FIELDS; i++ ) {
+ gtk_toggle_button_set_active(
+ GTK_TOGGLE_BUTTON(addrgather_dlg.checkHeader[i]),
+ FALSE );
+ if( g_strcasecmp( _harv_headerNames_[i], HEADER_FROM ) == 0 ) {
+ gtk_toggle_button_set_active(
+ GTK_TOGGLE_BUTTON(addrgather_dlg.checkHeader[i]),
+ TRUE );
+ }
+ }
+
+ gtk_widget_set_sensitive( addrgather_dlg.btnOk, TRUE );
+ gtk_widget_grab_default( addrgather_dlg.btnOk );
+ errFlag = FALSE;
+ }
+ else {
+ gtk_notebook_set_page(
+ GTK_NOTEBOOK(addrgather_dlg.notebook), PAGE_WARNING );
+ gtk_widget_set_sensitive( addrgather_dlg.btnOk, FALSE );
+ gtk_widget_grab_default( addrgather_dlg.btnCancel );
+ }
+
+ addrgather_dlg_status_show( "" );
+ gtk_widget_show( addrgather_dlg.window );
+
+ gtk_widget_grab_focus( addrgather_dlg.entryBook );
+ manage_window_set_transient( GTK_WINDOW(addrgather_dlg.window) );
+ gtk_main();
+
+ if( ! errFlag ) {
+ g_free( addrgather_dlg.folderPath );
+ addrgather_dlg.folderPath = NULL;
+ }
+ gtk_widget_hide( addrgather_dlg.window );
+ _harv_addressIndex_ = NULL;
+
+ if( addrgather_dlg.cancelled == TRUE ) return NULL;
+
+ return _harv_addressBook_;
+}
+
+/*
+* End of Source.
+*/
+
+
--- /dev/null
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2002 Match Grun
+ *
+ * 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.
+ */
+
+/*
+ * Gather addresses.
+ */
+
+#ifndef __ADDR_GATHER_H__
+#define __ADDR_GATHER_H__
+
+/* Function prototypes */
+AddressBookFile *addrgather_dlg_execute( FolderItem *folderItem,
+ AddressIndex *addrIndex );
+
+#endif /* __ADDR_GATHER_H__ */
+
+/*
+* End of Source.
+*/
+
--- /dev/null
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2002 Match Grun
+ *
+ * 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.
+ */
+
+/*
+ * Functions for an E-Mail address harvester.
+ * Code still needs some work. Address parsing not strictly correct.
+ */
+
+#include <sys/stat.h>
+#include <dirent.h>
+#include <glib.h>
+#include <string.h>
+
+#include "utils.h"
+#include "mgutils.h"
+#include "addrharvest.h"
+#include "addritem.h"
+
+/* Mail header names of interest */
+static gchar *_headerFrom_ = HEADER_FROM;
+static gchar *_headerReplyTo_ = HEADER_REPLY_TO;
+static gchar *_headerSender_ = HEADER_SENDER;
+static gchar *_headerErrorsTo_ = HEADER_ERRORS_TO;
+static gchar *_headerCC_ = HEADER_CC;
+static gchar *_headerTo_ = HEADER_TO;
+
+static gchar *_emptyString_ = "";
+
+#define MSG_BUFFSIZE 8192
+#define DFL_FOLDER_SIZE 20
+
+/*
+ * Header entry.
+ */
+typedef struct _HeaderEntry HeaderEntry;
+struct _HeaderEntry {
+ gchar *header;
+ gboolean selected;
+ ItemFolder *folder;
+ gint count;
+};
+
+/*
+ * Build header table entry.
+ * Enter: harvester Harvester object.
+ * name Header name.
+ */
+static void *addrharvest_build_entry(
+ AddressHarvester* harvester, gchar *name )
+{
+ HeaderEntry *entry;
+
+ entry = g_new0( HeaderEntry, 1 );
+ entry->header = name;
+ entry->selected = FALSE;
+ entry->folder = NULL;
+ entry->count = 0;
+ harvester->headerTable = g_list_append( harvester->headerTable, entry );
+}
+
+static void addrharvest_print_hdrentry( HeaderEntry *entry, FILE *stream ) {
+ fprintf( stream, "Header Entry\n" );
+ fprintf( stream, " name : %s\n", entry->header );
+ fprintf( stream, "selected : %s\n", entry->selected ? "yes" : "no" );
+}
+
+/*
+ * Free key in table.
+ */
+static gint addrharvest_free_table_vis( gpointer key, gpointer value, gpointer data ) {
+ g_free( key );
+ key = NULL;
+ value = NULL;
+ return TRUE;
+}
+
+/*
+ * Free lookup table.
+ */
+static void addrharvest_free_table( AddressHarvester* harvester ) {
+ GList *node;
+ HeaderEntry *entry;
+
+ /* Free header list */
+ node = harvester->headerTable;
+ while( node ) {
+ entry = ( HeaderEntry * ) node->data;
+ entry->header = NULL;
+ entry->selected = FALSE;
+ entry->folder = NULL;
+ entry->count = 0;
+ g_free( entry );
+ node = g_list_next( node );
+ }
+ g_list_free( harvester->headerTable );
+ harvester->headerTable = NULL;
+
+ /* Free duplicate table */
+ g_hash_table_freeze( harvester->dupTable );
+ g_hash_table_foreach_remove( harvester->dupTable, addrharvest_free_table_vis, NULL );
+ g_hash_table_thaw( harvester->dupTable );
+ g_hash_table_destroy( harvester->dupTable );
+ harvester->dupTable = NULL;
+}
+
+/*
+* Create new object.
+* Return: Harvester.
+*/
+AddressHarvester *addrharvest_create( void ) {
+ AddressHarvester *harvester;
+
+ harvester = g_new0( AddressHarvester, 1 );
+ harvester->path = NULL;
+ harvester->bufptr = harvester->buffer;
+ harvester->dupTable = g_hash_table_new( g_str_hash, g_str_equal );
+ harvester->folderSize = DFL_FOLDER_SIZE;
+ harvester->retVal = MGU_SUCCESS;
+
+ /* Build header table */
+ harvester->headerTable = NULL;
+ addrharvest_build_entry( harvester, _headerFrom_ );
+ addrharvest_build_entry( harvester, _headerReplyTo_ );
+ addrharvest_build_entry( harvester, _headerSender_ );
+ addrharvest_build_entry( harvester, _headerErrorsTo_ );
+ addrharvest_build_entry( harvester, _headerCC_ );
+ addrharvest_build_entry( harvester, _headerTo_ );
+
+ return harvester;
+}
+
+/*
+* Properties...
+*/
+/*
+ * Specify path to folder that will be harvested.
+ * Entry: harvester Harvester object.
+ * value Full directory path.
+ */
+void addrharvest_set_path( AddressHarvester* harvester, const gchar *value ) {
+ g_return_if_fail( harvester != NULL );
+ harvester->path = mgu_replace_string( harvester->path, value );
+ g_strstrip( harvester->path );
+}
+
+/*
+ * Specify maximum folder size.
+ * Entry: harvester Harvester object.
+ * value Folder size.
+ */
+void addrharvest_set_folder_size( AddressHarvester* harvester, const gint value ) {
+ g_return_if_fail( harvester != NULL );
+ if( value > 0 ) {
+ harvester->folderSize = value;
+ }
+}
+
+/*
+ * Search (case insensitive) for header entry with specified name.
+ * Enter: harvester Harvester.
+ * name Header name.
+ * Return: Header, or NULL if not found.
+ */
+static HeaderEntry *addrharvest_find(
+ AddressHarvester* harvester, const gchar *name ) {
+ HeaderEntry *retVal;
+ GList *node;
+
+ retVal = NULL;
+ node = harvester->headerTable;
+ while( node ) {
+ HeaderEntry *entry;
+
+ entry = node->data;
+ if( g_strcasecmp( entry->header, name ) == 0 ) {
+ retVal = entry;
+ break;
+ }
+ node = g_list_next( node );
+ }
+ return retVal;
+}
+
+/*
+ * Set selection for specified heaader.
+ * Enter: harvester Harvester.
+ * name Header name.
+ * value Value to set.
+ */
+void addrharvest_set_header(
+ AddressHarvester* harvester, const gchar *name, const gboolean value )
+{
+ HeaderEntry *entry;
+
+ g_return_if_fail( harvester != NULL );
+ entry = addrharvest_find( harvester, name );
+ if( entry != NULL ) {
+ entry->selected = value;
+ }
+}
+
+/*
+ * Get address count
+ * Enter: harvester Harvester.
+ * name Header name.
+ * Return: Address count, or -1 if header not found.
+ */
+gint addrharvest_get_count(
+ AddressHarvester* harvester, const gchar *name )
+{
+ HeaderEntry *entry;
+ gint count;
+
+ count = -1;
+ g_return_val_if_fail( harvester != NULL, count );
+ entry = addrharvest_find( harvester, name );
+ if( entry != NULL ) {
+ count = entry->count;
+ }
+ return count;
+}
+
+/*
+* Free up object by releasing internal memory.
+* Enter: harvester Harvester.
+*/
+void addrharvest_free( AddressHarvester *harvester ) {
+ g_return_if_fail( harvester != NULL );
+
+ /* Free internal stuff */
+ addrharvest_free_table( harvester );
+ g_free( harvester->path );
+
+ /* Clear pointers */
+ harvester->path = NULL;
+ harvester->retVal = MGU_SUCCESS;
+ harvester->headerTable = NULL;
+
+ harvester->folderSize = 0;
+
+ /* Now release object */
+ g_free( harvester );
+}
+
+/*
+* Display object to specified stream.
+* Enter: harvester Harvester.
+* stream Output stream.
+*/
+void addrharvest_print( AddressHarvester *harvester, FILE *stream ) {
+ GList *node;
+ HeaderEntry *entry;
+
+ g_return_if_fail( harvester != NULL );
+ fprintf( stream, "Address Harvester:\n" );
+ fprintf( stream, " file path: '%s'\n", harvester->path );
+ fprintf( stream, "max folder: %d'\n", harvester->folderSize );
+
+ node = harvester->headerTable;
+ while( node ) {
+ entry = node->data;
+ fprintf( stream, " header: %s", entry->header );
+ fprintf( stream, "\t: %s", entry->selected ? "yes" : "no" );
+ fprintf( stream, "\t: %d\n", entry->count );
+ node = g_list_next( node );
+ }
+ fprintf( stream, " ret val: %d\n", harvester->retVal );
+}
+
+#ifdef STANDALONE
+gint to_number(const gchar *nstr) {
+ register const gchar *p;
+ if (*nstr == '\0') return -1;
+ for( p = nstr; *p != '\0'; p++ )
+ if (!isdigit(*p)) return -1;
+ return atoi(nstr);
+}
+#endif
+
+/*
+ * Replace leading and trailing characters (quotes) in input string
+ * with spaces. Only matching non-blank characters that appear at both
+ * start and end of string are replaces. Control characters are also
+ * replaced with spaces.
+ * Enter: str String to process.
+ * ch Character to remove.
+ */
+static void addrutil_strip_char( gchar *str, gchar ch ) {
+ gchar *as;
+ gchar *ae;
+
+ /* Search forwards for first non-space match */
+ as = str;
+ ae = -1 + str + strlen( str );
+ while( as < ae ) {
+ if( *as != ' ' ) {
+ if( *as == ch ) {
+ /* Search backwards from end for match */
+ while( ae > as ) {
+ if( *ae != ' ' ) {
+ if( *ae == ch ) {
+ *as = ' ';
+ *ae = ' ';
+ return;
+ }
+ if( *ae < 32 ) {
+ *ae = ' ';
+ }
+ else if( *ae == 127 ) {
+ *ae = ' ';
+ }
+ else {
+ return;
+ }
+ }
+ ae--;
+ }
+ }
+ if( *as < 32 ) {
+ *as = ' ';
+ }
+ else if( *as == 127 ) {
+ *as = ' ';
+ }
+ else {
+ return;
+ }
+ }
+ as++;
+ }
+ return;
+}
+
+/*
+ * Remove backslash character from input string.
+ * Enter: str String to process.
+ */
+static void addrutil_unescape( gchar *str ) {
+ gchar *p;
+ gint ilen;
+
+ p = str;
+ while( *p ) {
+ if( *p == '\\' ) {
+ ilen = strlen( p + 1 );
+ memmove( p, p + 1, ilen );
+ }
+ p++;
+ }
+}
+
+/*
+ * Parse name from email address string.
+ * Enter: buf Start address of buffer to process (not modified).
+ * atp Pointer to email at (@) character.
+ * ap Pointer to start of email address returned.
+ * ep Pointer to end of email address returned.
+ * Return: Parsed name or NULL if not present. This should be g_free'd
+ * when done.
+ */
+static gchar *addrutil_parse_name(
+ const gchar *buf, const gchar *atp, const gchar **ap,
+ const gchar **ep )
+{
+ gchar *name;
+ const gchar *pos;
+ const gchar *tmp;
+ const gchar *bp;
+ gint ilen;
+
+ name = NULL;
+ *ap = NULL;
+ *ep = NULL;
+
+ /* Find first non-separator char */
+ bp = buf;
+ while( TRUE ) {
+ if( strchr( ",; \n\r", *bp ) == NULL ) break;
+ bp++;
+ }
+
+ /* Search back for start of name */
+ tmp = atp;
+ pos = atp;
+ while( pos >= bp ) {
+ tmp = pos;
+ if( *pos == '<' ) {
+ /* Found start of address/end of name part */
+ ilen = -1 + ( size_t ) ( pos - bp );
+ name = g_strndup( bp, ilen + 1 );
+ *(name + ilen + 1) = '\0';
+
+ /* Remove leading trailing quotes and spaces */
+ addrutil_strip_char( name, '\"' );
+ addrutil_strip_char( name, '\'' );
+ addrutil_strip_char( name, '\"' );
+ addrutil_unescape( name );
+ g_strstrip( name );
+ break;
+ }
+ pos--;
+ }
+ *ap = tmp;
+
+ /* Search forward for end of address */
+ pos = atp + 1;
+ while( TRUE ) {
+ if( *pos == '>' ) {
+ pos++;
+ break;
+ }
+ if( strchr( ",; \'\n\r", *pos ) ) break;
+ pos++;
+ }
+ *ep = pos;
+
+ return name;
+
+}
+
+/*
+ * Insert address into cache.
+ * Enter: harvester Harvester object.
+ * entry Header object.
+ * cache Address cache to load.
+ * name Name.
+ * address eMail address.
+ * Return: Person inserted.
+ */
+static ItemPerson *addrharvest_insert_cache(
+ AddressHarvester *harvester, HeaderEntry *entry,
+ AddressCache *cache, const gchar *name,
+ const gchar *address )
+{
+ ItemPerson *person;
+ ItemFolder *folder;
+ gchar *folderName;
+ gboolean newFolder;
+ gint cnt;
+
+ newFolder = FALSE;
+ folder = entry->folder;
+ if( folder == NULL ) {
+ newFolder = TRUE; /* No folder yet */
+ }
+ if( entry->count % harvester->folderSize == 0 ) {
+ newFolder = TRUE; /* Folder is full */
+ }
+
+ if( newFolder ) {
+ cnt = 1 + ( entry->count / harvester->folderSize );
+ folderName = g_strdup_printf( "%s (%d)", entry->header, cnt );
+ folder = addritem_create_item_folder();
+ addritem_folder_set_name( folder, folderName );
+ addritem_folder_set_remarks( folder, "" );
+ addrcache_id_folder( cache, folder );
+ addrcache_add_folder( cache, folder );
+ entry->folder = folder;
+ g_free( folderName );
+ }
+
+ person = addrcache_add_contact( cache, folder, name, address, "" );
+ entry->count++;
+ return person;
+}
+
+#define ATCHAR "@"
+
+/*
+ * Parse address from header buffer creating address in cache.
+ * Enter: harvester Harvester object.
+ * entry Header object.
+ * cache Address cache to load.
+ * hdrBuf Pointer to header buffer.
+ */
+static void addrharvest_parse_address(
+ AddressHarvester *harvester, HeaderEntry *entry,
+ AddressCache *cache, const gchar *hdrBuf )
+{
+ gchar addr[ MSG_BUFFSIZE ];
+ const gchar *bp;
+ const gchar *ep;
+ gchar *atCh;
+ gchar *name;
+ gchar *value;
+ gchar *key;
+ gint addrLen;
+ ItemPerson *person;
+
+ /* printf( "hdrBuf :%s:\n", hdrBuf ); */
+ /* Search for an address */
+ while( atCh = strcasestr( hdrBuf, ATCHAR ) ) {
+ name = addrutil_parse_name( hdrBuf, atCh, &bp, &ep );
+ addrLen = ( size_t ) ( ep - bp );
+ strncpy( addr, bp, addrLen );
+ addr[ addrLen ] = '\0';
+ extract_address( addr );
+ /* printf( "name/addr :%s:\t:%s:\n", addr, name ); */
+ hdrBuf = ep;
+ if( atCh == ep ) {
+ hdrBuf++;
+ }
+ if( strlen( addr ) > 0 ) {
+ if( name == NULL ) {
+ name = g_strdup( _emptyString_ );
+ }
+ g_strdown( addr );
+ /* printf( "name/addr :%s:\t:%s:\n", addr, name ); */
+ person = g_hash_table_lookup(
+ harvester->dupTable, addr );
+ if( person ) {
+ /* Use longest name */
+ value = ADDRITEM_NAME(person);
+ if( strlen( name ) > strlen( value ) ) {
+ addritem_person_set_common_name(
+ person, name );
+ }
+ }
+ else {
+ /* Insert entry */
+ key = g_strdup( addr );
+ person = addrharvest_insert_cache(
+ harvester, entry, cache, name, addr );
+ g_hash_table_insert(
+ harvester->dupTable, key, person );
+ }
+ }
+ g_free( name );
+ }
+}
+
+/*
+ * Read specified file into address book.
+ * Enter: harvester Harvester object.
+ * fileName File to read.
+ * cache Address cache to load.
+ * Return: Status.
+ */
+static gint addrharvest_readfile(
+ AddressHarvester *harvester, const gchar *fileName,
+ AddressCache *cache )
+{
+ gint retVal;
+ FILE *msgFile;
+ gchar buf[ MSG_BUFFSIZE ], tmp[ MSG_BUFFSIZE ];
+ HeaderEntry *entry;
+
+ msgFile = fopen( fileName, "r" );
+ if( ! msgFile ) {
+ /* Cannot open file */
+ retVal = MGU_OPEN_FILE;
+ return retVal;
+ }
+
+ for( ;; ) {
+ gint val;
+ gchar *p;
+
+ val = procheader_get_one_field( buf, sizeof(buf), msgFile, NULL );
+ if( val == -1 ) {
+ break;
+ }
+ conv_unmime_header( tmp, sizeof(tmp), buf, NULL );
+ if(( p = strchr( tmp, ':' ) ) != NULL ) {
+ const gchar *hdr;
+
+ *p = '\0';
+ hdr = p + 1;
+ entry = addrharvest_find( harvester, tmp );
+ if( entry && entry->selected ) {
+ addrharvest_parse_address(
+ harvester, entry, cache, hdr );
+ }
+ }
+ }
+
+ fclose( msgFile );
+ return MGU_SUCCESS;
+}
+
+#undef ATCHAR
+
+/*
+ * ============================================================================
+ * Read all files in specified directory into address book.
+ * Enter: harvester Harvester object.
+ * cache Address cache to load.
+ * Return: Status.
+ * ============================================================================
+ */
+gint addrharvest_harvest( AddressHarvester *harvester, AddressCache *cache ) {
+ gint retVal;
+ DIR *dp;
+ struct dirent *d;
+ struct stat s;
+ gint num;
+
+ retVal = MGU_BAD_ARGS;
+ g_return_val_if_fail( harvester != NULL, retVal );
+ g_return_val_if_fail( cache != NULL, retVal );
+ g_return_val_if_fail( harvester->path != NULL, retVal );
+
+ /* Clear cache */
+ addrcache_clear( cache );
+ cache->dataRead = FALSE;
+
+ if( chdir( harvester->path ) < 0 ) {
+ printf( "Error changing dir\n" );
+ return retVal;
+ }
+
+ if( ( dp = opendir( harvester->path ) ) == NULL ) {
+ printf( "Error opening dir\n" );
+ return retVal;
+ }
+
+ while( ( d = readdir( dp ) ) != NULL ) {
+ stat( d->d_name, &s );
+ if( S_ISREG( s.st_mode ) ) {
+ if( ( num = to_number( d->d_name ) ) >= 0 ) {
+ addrharvest_readfile( harvester, d->d_name, cache );
+ }
+ }
+ }
+
+ closedir( dp );
+
+ /* Mark cache */
+ cache->modified = FALSE;
+ cache->dataRead = TRUE;
+
+ return retVal;
+}
+
+/*
+ * ============================================================================
+ * Test whether any headers have been selected for processing.
+ * Enter: harvester Harvester object.
+ * Return: TRUE if a header was selected, FALSE if none were selected.
+ * ============================================================================
+ */
+gboolean addrharvest_check_header( AddressHarvester *harvester ) {
+ gboolean retVal;
+ GList *node;
+
+ retVal = FALSE;
+ g_return_val_if_fail( harvester != NULL, retVal );
+
+ node = harvester->headerTable;
+ while( node ) {
+ HeaderEntry *entry;
+
+ entry = ( HeaderEntry * ) node->data;
+ if( entry->selected ) return TRUE;
+ node = g_list_next( node );
+ }
+ return retVal;
+}
+
+/*
+ * ============================================================================
+ * End of Source.
+ * ============================================================================
+ */
+
+
--- /dev/null
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2002 Match Grun
+ *
+ * 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.
+ */
+
+/*
+ * Definitions for an E-Mail address harvester.
+ */
+
+#ifndef __ADDRHARVEST_H__
+#define __ADDRHARVEST_H__
+
+#include <stdio.h>
+#include <glib.h>
+#include "addrbook.h"
+
+/* Headers that will be recognized */
+#define HEADER_FROM "From"
+#define HEADER_REPLY_TO "Reply-to"
+#define HEADER_SENDER "Sender"
+#define HEADER_ERRORS_TO "Errors-to"
+#define HEADER_CC "Cc"
+#define HEADER_TO "To"
+
+#define MESSAGEBUFSIZE 2048
+
+/* Harvester file object */
+typedef struct _AddressHarvester AddressHarvester;
+struct _AddressHarvester {
+ GList *headerTable;
+ gchar *path;
+ gchar *bufptr;
+ GHashTable *dupTable;
+ gint folderSize;
+ gchar buffer[ MESSAGEBUFSIZE ];
+ gint retVal;
+};
+
+/* Function prototypes */
+AddressHarvester *addrharvest_create ( void );
+void addrharvest_free ( AddressHarvester *harvester );
+void addrharvest_set_path ( AddressHarvester *harvester,
+ const gchar *value );
+void addrharvest_set_folder_size ( AddressHarvester* harvester,
+ const gint value );
+void addrharvest_set_header ( AddressHarvester* harvester,
+ const gchar *name,
+ const gboolean value );
+gint addrharvest_get_count ( AddressHarvester* harvester,
+ const gchar *name );
+void addrharvest_print ( AddressHarvester *harvester,
+ FILE *stream );
+gint addrharvest_harvest ( AddressHarvester *harvester,
+ AddressCache *cache );
+gboolean addrharvest_check_header ( AddressHarvester *harvester );
+
+#endif /* __ADDRHARVEST_H__ */
+
static void set_toolbar_style(MainWindow *mainwin);
+static void addr_gather_cb ( MainWindow *mainwin,
+ guint action,
+ GtkWidget *widget );
+
#define SEPARATE_ACTION 667
static GtkItemFactoryEntry mainwin_entries[] =
{N_("/_File/_Import mbox file..."), NULL, import_mbox_cb, 0, NULL},
{N_("/_File/_Export to mbox file..."), NULL, export_mbox_cb, 0, NULL},
{N_("/_File/Empty _trash"), "<shift>D", empty_trash_cb, 0, NULL},
+ {N_("/_File/_Gather addresses..."), NULL, addr_gather_cb, 0, NULL},
{N_("/_File/---"), NULL, NULL, 0, "<Separator>"},
{N_("/_File/_Save as..."), "<control>S", save_as_cb, 0, NULL},
{N_("/_File/_Print..."), NULL, print_cb, 0, NULL},
{"/File/Import mbox file..." , M_UNLOCKED},
{"/File/Export to mbox file...", M_UNLOCKED},
{"/File/Empty trash" , M_UNLOCKED},
+ {"/File/Gather addresses...", M_SINGLE_TARGET_EXIST|M_UNLOCKED},
{"/File/Save as...", M_SINGLE_TARGET_EXIST|M_UNLOCKED},
{"/File/Print..." , M_TARGET_EXIST|M_UNLOCKED},
/* {"/File/Close", M_UNLOCKED}, */
}
}
+static void addr_gather_cb( MainWindow *mainwin,
+ guint action,
+ GtkWidget *widget )
+{
+ addressbook_gather( mainwin->summaryview->folder_item );
+}
+
+/*
+* End of Source.
+*/
+