From 05b0f3753902043fa8476a59c9251ab176675945 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Thu, 24 May 2001 21:25:09 +0000 Subject: [PATCH] First attempt of the better interface for filters --- ChangeLog | 1 + abook.c | 2 +- database.c | 60 +++++++++- database.h | 17 ++- edit.c | 1 + filter.c | 319 ++++++++++++++++++++++++++++++----------------------- filter.h | 12 +- ui.c | 25 ++++- 8 files changed, 288 insertions(+), 149 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7935707..333b308 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ - fixed help viewer functions - ability to disable use of non-ascii characters (configuration option) - changed SIGINT behaviour + - html export filter creates now valid html documents 0.4.12 - added man page for abookrc (Alan Ford) diff --git a/abook.c b/abook.c index f61368e..8366cfd 100644 --- a/abook.c +++ b/abook.c @@ -84,7 +84,7 @@ quit_abook() { if( options_get_int("autosave") ) save_database(); - else if( statusline_ask_boolean("Save database", FALSE) ) + else if( statusline_ask_boolean("Save database", TRUE) ) save_database(); close_config(); diff --git a/database.c b/database.c index 2bcda3d..e324810 100644 --- a/database.c +++ b/database.c @@ -139,9 +139,10 @@ load_database(char *filename) } int -write_database(FILE *out) +write_database(FILE *out, struct db_enumerator e) { - int i,j; + int j; + int i = 0; fprintf(out, "# abook addressbook file\n\n"); fprintf(out, "[format]\n"); @@ -149,14 +150,18 @@ write_database(FILE *out) fprintf(out, "version=" VERSION "\n"); fprintf(out, "\n\n"); - for( i = 0; i < items; i++ ) { + db_enumerate_items(e) { fprintf(out, "[%d]\n", i); for(j=0; j LAST_ITEM || item < 0) ? -1 : item; +} + +struct db_enumerator +init_db_enumerator(int mode) +{ + struct db_enumerator new; + + new.item = -1; /* important - means "start from beginning" */ + new.mode = mode; + + return new; +} diff --git a/database.h b/database.h index 0c47fd4..8676f71 100644 --- a/database.h +++ b/database.h @@ -36,8 +36,21 @@ struct abook_field { int tab; }; +enum { + ENUM_ALL, + ENUM_SELECTED +}; + +struct db_enumerator { + int item; + int mode; /* boolean */ /* warning: read only */ +}; + +#define db_enumerate_items(e) \ + while( -1 != (e.item = real_db_enumerate_items(e))) + int parse_database(FILE *in); -int write_database(FILE *out); +int write_database(FILE *out, struct db_enumerator e); int load_database(char *filename); int save_database(); void close_database(); @@ -50,6 +63,8 @@ char *get_surname(char *s); int find_item(char *str, int start); int is_selected(int item); +int real_db_enumerate_items(struct db_enumerator e); +struct db_enumerator init_db_enumerator(int mode); #define LAST_ITEM (items - 1) diff --git a/edit.c b/edit.c index 83f4beb..9ce4a88 100644 --- a/edit.c +++ b/edit.c @@ -354,6 +354,7 @@ edit_loop(int item) werase(editw); headerline(EDITOR_HELPLINE); + refresh_statusline(); print_editor_header(item); editor_tab(tab); editor_print_data(tab, item); diff --git a/filter.c b/filter.c index 4489839..d401bf1 100644 --- a/filter.c +++ b/filter.c @@ -30,22 +30,33 @@ extern struct abook_field abook_fields[]; * function declarations */ +/* + * import filter prototypes + */ + static int ldif_parse_file(FILE *handle); static int mutt_parse_file(FILE *in); static int pine_parse_file(FILE *in); -static int ldif_export_database(FILE *out); -static int html_export_database(FILE *out); -static int pine_export_database(FILE *out); -static int csv_export_database(FILE *out); -static int gcrd_export_database(FILE *out); -static int mutt_alias_export(FILE *out); -static int elm_alias_export(FILE *out); -static int text_export_database(FILE *out); -static int spruce_export_database(FILE *out); +/* + * export filter prototypes + */ + +static int ldif_export_database(FILE *out, struct db_enumerator e); +static int html_export_database(FILE *out, struct db_enumerator e); +static int pine_export_database(FILE *out, struct db_enumerator e); +static int csv_export_database(FILE *out, struct db_enumerator e); +static int gcrd_export_database(FILE *out, struct db_enumerator e); +static int mutt_alias_export(FILE *out, struct db_enumerator e); +static int elm_alias_export(FILE *out, struct db_enumerator e); +static int text_export_database(FILE *out, struct db_enumerator e); +static int spruce_export_database(FILE *out, struct db_enumerator e); +/* + * end of function declarations + */ -struct abook_filter i_filters[] = { +struct abook_input_filter i_filters[] = { { "abook", "abook native format", parse_database }, { "ldif", "ldif / Netscape addressbook", ldif_parse_file }, { "mutt", "mutt alias (beta)", mutt_parse_file }, @@ -53,7 +64,7 @@ struct abook_filter i_filters[] = { { "\0", NULL, NULL } }; -struct abook_filter e_filters[] = { +struct abook_output_filter e_filters[] = { { "abook", "abook native format", write_database }, { "ldif", "ldif / Netscape addressbook (.4ld)", ldif_export_database }, { "mutt", "mutt alias", mutt_alias_export }, @@ -92,11 +103,22 @@ print_filters() } static int -number_of_filters(struct abook_filter * filters) +number_of_output_filters() +{ + int i; + + for(i=0; *e_filters[i].filtname ; i++) + ; + + return i; +} + +static int +number_of_input_filters() { int i; - for(i=0; *filters[i].filtname ; i++) + for(i=0; *i_filters[i].filtname ; i++) ; return i; @@ -160,8 +182,8 @@ import_database() import_screen(); filter = getch() - 'a'; - if(filter == 'x' - 'a' || filter >= number_of_filters(e_filters) || - filter < 0) { + if(filter == 'x' - 'a' || + filter >= number_of_input_filters() || filter < 0) { refresh_screen(); return 1; } @@ -238,7 +260,8 @@ import(char filtname[FILTNAME_LEN], char *filename) * export */ -static int e_write_file(char *filename, int (*func) (FILE *in)); +static int e_write_file(char *filename, + int (*func) (FILE *in, struct db_enumerator e), int mode); static void export_screen() @@ -266,18 +289,32 @@ int export_database() { int filter; + int enum_mode = ENUM_ALL; char *filename; export_screen(); filter = getch() - 'a'; - if(filter == 'x' - 'a' || filter >= number_of_filters(e_filters) || - filter < 0) { + if(filter == 'x' - 'a' || + filter >= number_of_output_filters(e_filters) || filter < 0) { refresh_screen(); return 1; } mvaddstr(5+filter, 2, "->"); + + if( selected_items() ) { + statusline_addstr("Export All/Selected/Cancel (A/s/c)"); + switch( tolower(getch()) ) { + case 's': + enum_mode = ENUM_SELECTED; + break; + case 'c': + clear_statusline(); + return 1; + } + clear_statusline(); + } filename = ask_filename("Filename: ", 0); if( !filename ) { @@ -285,7 +322,7 @@ export_database() return 2; } - if( e_write_file(filename, e_filters[filter].func ) ) + if( e_write_file(filename, e_filters[filter].func, enum_mode ) ) statusline_msg("Error occured while exporting"); refresh_screen(); @@ -295,10 +332,12 @@ export_database() } static int -e_write_file(char *filename, int (*func) (FILE *in)) +e_write_file(char *filename, int (*func) (FILE *in, struct db_enumerator e), + int mode) { FILE *out; int ret = 0; + struct db_enumerator enumerator = init_db_enumerator(mode); if( (out = fopen(filename, "a")) == NULL ) return 1; @@ -306,7 +345,7 @@ e_write_file(char *filename, int (*func) (FILE *in)) if( ftell(out) ) return 1; - ret = (*func) (out); + ret = (*func) (out, enumerator); fclose(out); @@ -314,9 +353,10 @@ e_write_file(char *filename, int (*func) (FILE *in)) } int -fexport(char filtname[FILTNAME_LEN], FILE *handle) +fexport(char filtname[FILTNAME_LEN], FILE *handle, int enum_mode) { int i; + struct db_enumerator e = init_db_enumerator(enum_mode); for(i=0;; i++) { if( ! strncmp(e_filters[i].filtname, filtname, FILTNAME_LEN) ) @@ -327,7 +367,7 @@ fexport(char filtname[FILTNAME_LEN], FILE *handle) } } - return (e_filters[i].func) (handle); + return (e_filters[i].func) (handle, e); } @@ -335,8 +375,10 @@ fexport(char filtname[FILTNAME_LEN], FILE *handle) int export(char filtname[FILTNAME_LEN], char *filename) { + const int mode = ENUM_ALL; int i; int ret = 0; + struct db_enumerator e = init_db_enumerator(mode); for(i=0;; i++) { if( ! strncmp(e_filters[i].filtname, filtname, FILTNAME_LEN) ) @@ -351,9 +393,9 @@ export(char filtname[FILTNAME_LEN], char *filename) return -1; if( !strcmp(filename, "-") ) - ret = (e_filters[i].func) (stdout); + ret = (e_filters[i].func) (stdout, e); else - ret = e_write_file(filename, e_filters[i].func); + ret = e_write_file(filename, e_filters[i].func, mode); return ret; } @@ -699,6 +741,7 @@ mutt_parse_file(FILE *in) * end of mutt alias import filter */ + /* * ldif export filter */ @@ -716,18 +759,18 @@ ldif_fput_type_and_value(FILE *out,char *type, char *value ) } static int -ldif_export_database(FILE *out) +ldif_export_database(FILE *out, struct db_enumerator e) { - int i; char email[MAX_EMAILSTR_LEN]; fprintf(out, "version: 1\n"); - for(i=0; i\n%s\n", tmp, - database[i][NAME] ); + database[e.item][NAME] ); fprintf(out, "%s\n%s\n", - database[i][EMAIL], - safe_str(database[i][extra_column]) ); + database[e.item][EMAIL], + safe_str(database[e.item][extra_column]) ); fprintf(out, "\n\n"); } + html_export_write_tail(out); return 0; @@ -797,6 +841,7 @@ html_export_write_head(FILE *out, int extra_column) { char *realname = get_real_name(); + fprintf(out, "\n"); fprintf(out, "\n\n %s's addressbook", realname ); fprintf(out, "\n\n\n"); @@ -821,6 +866,7 @@ html_export_write_tail(FILE *out) * end of html export filter */ + /* * pine addressbook import filter */ @@ -932,6 +978,7 @@ pine_parse_file(FILE *in) * end of pine addressbook import filter */ + /* * pine addressbook export filter * @@ -940,17 +987,15 @@ pine_parse_file(FILE *in) */ static int -pine_export_database(FILE *out) +pine_export_database(FILE *out, struct db_enumerator e) { - int i; - - for(i=0; i < items; i++ ) { - fprintf(out, have_multiple_emails(i) ? + db_enumerate_items(e) { + fprintf(out, have_multiple_emails(e.item) ? "%s\t%s\t(%s)\t\t%s\n" : "%s\t%s\t%s\t\t%s\n", - safe_str(database[i][NICK]), - safe_str(database[i][NAME]), - safe_str(database[i][EMAIL]), - safe_str(database[i][NOTES]) + safe_str(database[e.item][NICK]), + safe_str(database[e.item][NAME]), + safe_str(database[e.item][EMAIL]), + safe_str(database[e.item][NOTES]) ); } @@ -967,9 +1012,9 @@ pine_export_database(FILE *out) */ static int -csv_export_database(FILE *out) +csv_export_database(FILE *out, struct db_enumerator e) { - int i, j; + int j; int csv_export_fields[] = { NAME, EMAIL, @@ -978,11 +1023,11 @@ csv_export_database(FILE *out) -1 }; - for(i=0; i < items; i++ ) { + db_enumerate_items(e) { for(j = 0; csv_export_fields[j] >= 0; j++) { - fprintf(out, strchr(safe_str(database[i][csv_export_fields[j]]), ',') ? + fprintf(out, strchr(safe_str(database[e.item][csv_export_fields[j]]), ',') ? "\"%s\"" : "%s", - safe_str(database[i][csv_export_fields[j]]) + safe_str(database[e.item][csv_export_fields[j]]) ); if(csv_export_fields[j+1] >= 0) fputc(',', out); @@ -1005,49 +1050,49 @@ csv_export_database(FILE *out) */ static int -gcrd_export_database(FILE *out) +gcrd_export_database(FILE *out, struct db_enumerator e) { char emails[MAX_EMAILS][MAX_EMAIL_LEN]; - int i, j; + int j; char *name; - for(i=0; i < items; i++ ) { + db_enumerate_items(e) { fprintf(out, "BEGIN:VCARD\nFN:%s\n", - safe_str(database[i][NAME])); + safe_str(database[e.item][NAME])); - name = get_surname(database[i][NAME]); - for( j = strlen(database[i][NAME]) - 1; j >= 0; j-- ) { - if(database[i][NAME][j] == ' ') + name = get_surname(database[e.item][NAME]); + for( j = strlen(database[e.item][NAME]) - 1; j >= 0; j-- ) { + if(database[e.item][NAME][j] == ' ') break; } fprintf(out, "N:%s;%.*s\n", safe_str(name), j, - safe_str(database[i][NAME]) + safe_str(database[e.item][NAME]) ); free(name); - if ( database[i][ADDRESS] ) + if ( database[e.item][ADDRESS] ) fprintf(out, "ADR:;;%s;%s;%s;%s;%s\n", - safe_str(database[i][ADDRESS]), - safe_str(database[i][CITY]), - safe_str(database[i][STATE]), - safe_str(database[i][ZIP]), - safe_str(database[i][COUNTRY]) + safe_str(database[e.item][ADDRESS]), + safe_str(database[e.item][CITY]), + safe_str(database[e.item][STATE]), + safe_str(database[e.item][ZIP]), + safe_str(database[e.item][COUNTRY]) ); - if (database[i][PHONE]) - fprintf(out, "TEL;HOME:%s\n", database[i][PHONE]); - if (database[i][WORKPHONE]) - fprintf(out, "TEL;WORK:%s\n", database[i][WORKPHONE]); - if (database[i][FAX]) - fprintf(out, "TEL;FAX:%s\n", database[i][FAX]); - if (database[i][MOBILEPHONE]) - fprintf(out, "TEL;CELL:%s\n", database[i][MOBILEPHONE]); - - if ( database[i][EMAIL] ) { - split_emailstr(i, emails); + if (database[e.item][PHONE]) + fprintf(out, "TEL;HOME:%s\n", database[e.item][PHONE]); + if (database[e.item][WORKPHONE]) + fprintf(out, "TEL;WORK:%s\n", database[e.item][WORKPHONE]); + if (database[e.item][FAX]) + fprintf(out, "TEL;FAX:%s\n", database[e.item][FAX]); + if (database[e.item][MOBILEPHONE]) + fprintf(out, "TEL;CELL:%s\n", database[e.item][MOBILEPHONE]); + + if ( database[e.item][EMAIL] ) { + split_emailstr(e.item, emails); for(j=0; j < MAX_EMAILS ; j++) { if ( *emails[j] ) fprintf(out, "EMAIL;INTERNET:%s\n", @@ -1055,10 +1100,10 @@ gcrd_export_database(FILE *out) } } - if ( database[i][NOTES] ) - fprintf(out, "NOTE:%s\n", database[i][NOTES]); - if (database[i][URL]) - fprintf(out, "URL:%s\n", database[i][URL]); + if ( database[e.item][NOTES] ) + fprintf(out, "NOTE:%s\n", database[e.item][NOTES]); + if (database[e.item][URL]) + fprintf(out, "URL:%s\n", database[e.item][URL]); fprintf(out, "END:VCARD\n\n"); @@ -1095,19 +1140,18 @@ mutt_alias_genalias(int i) } static int -mutt_alias_export(FILE *out) +mutt_alias_export(FILE *out, struct db_enumerator e) { - int i; char email[MAX_EMAIL_LEN]; char *alias = NULL; - for(i=0; i\n": "alias %s %s%s\n", alias, - database[i][NAME], + database[e.item][NAME], email); my_free(alias); } @@ -1125,10 +1169,10 @@ mutt_alias_export(FILE *out) */ static int -text_export_database(FILE * out) +text_export_database(FILE * out, struct db_enumerator e) { char emails[MAX_EMAILS][MAX_EMAIL_LEN]; - int i, j; + int j; char *realname = get_real_name(); char *style = options_get_str("address_style"); @@ -1138,76 +1182,79 @@ text_export_database(FILE * out) realname); free(realname); - for (i = 0; i < items; i++) { + db_enumerate_items(e) { fprintf(out, "-----------------------------------------\n\n"); - fprintf(out, "%s", database[i][NAME]); - if (database[i][NICK]) - fprintf(out, "\n(%s)", database[i][NICK]); + fprintf(out, "%s", database[e.item][NAME]); + if (database[e.item][NICK]) + fprintf(out, "\n(%s)", database[e.item][NICK]); fprintf(out, "\n"); - if (*database[i][EMAIL]) { + if (*database[e.item][EMAIL]) { fprintf(out, "\n"); - split_emailstr(i, emails); + split_emailstr(e.item, emails); for (j = 0; j < MAX_EMAILS; j++) if (*emails[j]) fprintf(out, "%s\n", emails[j]); } /* Print address */ - if (database[i][ADDRESS]) { + if (database[e.item][ADDRESS]) { if (!safe_strcmp(style, "us")) { /* US like */ - fprintf(out, "\n%s", database[i][ADDRESS]); - if (database[i][CITY]) + fprintf(out, "\n%s", database[e.item][ADDRESS]); + if (database[e.item][CITY]) fprintf(out, "\n%s", - database[i][CITY]); - if (database[i][STATE] || database[i][ZIP]) + database[e.item][CITY]); + if (database[e.item][STATE] || database[e.item][ZIP]) fprintf(out, "\n%s %s", - safe_str(database[i] + safe_str(database[e.item] [STATE]), - safe_str(database[i] + safe_str(database[e.item] [ZIP])); - if (database[i][COUNTRY]) + if (database[e.item][COUNTRY]) fprintf(out, "\n%s", - database[i][COUNTRY]); + database[e.item][COUNTRY]); } else if (!safe_strcmp(style, "uk")) { /* UK like */ for (j = ADDRESS; j <= COUNTRY; j++) - if (database[i][j]) + if (database[e.item][j]) fprintf(out, "\n%s", - database[i][j]); + database[e.item][j]); } else { /* EU like */ - fprintf(out, "\n%s", database[i][ADDRESS]); - if (database[i][ZIP] || database[i][CITY]) + fprintf(out, "\n%s", database[e.item][ADDRESS]); + if (database[e.item][ZIP] || + database[e.item][CITY]) fprintf(out, "\n%s %s", - safe_str(database[i][ZIP]), - safe_str(database[i] + safe_str(database[e.item][ZIP]), + safe_str(database[e.item] [CITY])); - if (database[i][STATE]) + if (database[e.item][STATE]) fprintf(out, "\n%s", - database[i][STATE]); - if (database[i][COUNTRY]) + database[e.item][STATE]); + if (database[e.item][COUNTRY]) fprintf(out, "\n%s", - database[i][COUNTRY]); + database[e.item][COUNTRY]); } fprintf(out, "\n"); } - if ((database[i][PHONE]) || (database[i][WORKPHONE]) || - (database[i][FAX]) || (database[i][MOBILEPHONE])) { + if ((database[e.item][PHONE]) || + (database[e.item][WORKPHONE]) || + (database[e.item][FAX]) || + (database[e.item][MOBILEPHONE])) { fprintf(out, "\n"); for (j = PHONE; j <= MOBILEPHONE; j++) - if (database[i][j]) + if (database[e.item][j]) fprintf(out, "%s: %s\n", abook_fields[j].name, - database[i][j]); + database[e.item][j]); } - if (database[i][URL]) - fprintf(out, "\n%s\n", database[i][URL]); - if (database[i][NOTES]) - fprintf(out, "\n%s\n", database[i][NOTES]); + if (database[e.item][URL]) + fprintf(out, "\n%s\n", database[e.item][URL]); + if (database[e.item][NOTES]) + fprintf(out, "\n%s\n", database[e.item][NOTES]); fprintf(out, "\n"); } @@ -1226,18 +1273,17 @@ text_export_database(FILE * out) */ static int -elm_alias_export(FILE *out) +elm_alias_export(FILE *out, struct db_enumerator e) { - int i; char email[MAX_EMAIL_LEN]; char *alias = NULL; - for(i=0; i