X-Git-Url: https://git.deb.at/?a=blobdiff_plain;f=edit.c;h=ef956ef80c364ae4813842ec49335422f8cc3093;hb=31c284414c6effcd85add7a7b19d4464ee0e3625;hp=f5e05845e8022e1abc94f20e4845815a5aa0c8d9;hpb=4909ba20244f55ee7326a40d751cf6737c2bc2b6;p=pkg%2Fabook.git diff --git a/edit.c b/edit.c index f5e0584..ef956ef 100644 --- a/edit.c +++ b/edit.c @@ -29,13 +29,12 @@ * some extern variables */ - -extern int curitem; extern int views_count; -extern int items; WINDOW *editw; +static int parse_date_string(char *s, int *day, int *month, int *year); + static void editor_tab(const int tab) @@ -51,10 +50,7 @@ editor_tab(const int tab) int width = strwidth(tab_name) + 5; if(x_pos + width + 1 > EDITW_COLS) { - statusline_msg(_("Tab name too wide for screen")); - /* Disabling this field */ - /* TODO should be recomputed on window resize */ - views_count--; + statusline_addstr(_("Tab name too wide for screen")); break; } @@ -82,29 +78,33 @@ editor_tab(const int tab) void get_first_email(char *str, int item) { - char *tmp; + char *tmp, *emails = db_email_get(item); - if(!db_email_get(item)) { + if(!*emails) { *str = 0; return; } - strncpy(str, db_email_get(item), MAX_EMAIL_LEN); + strncpy(str, emails, MAX_EMAIL_LEN); + free(emails); if( (tmp = strchr(str, ',')) ) *tmp = 0; else str[MAX_EMAIL_LEN - 1] = 0; } +/* This only rolls emails from the 'email' field, not emails from any + * field of type FIELD_EMAILS. + * TODO: expand to ask for which field to roll if several are present? */ static void roll_emails(int item, enum rotate_dir dir) { - abook_list *emails = csv_to_abook_list(db_email_get(item)); + abook_list *emails = csv_to_abook_list(db_fget(item, EMAIL)); if(!emails) return; - free(db_email_get(item)); + free(db_fget(item, EMAIL)); abook_list_rotate(&emails, dir); db_fput(item, EMAIL, abook_list_to_csv(emails)); abook_list_free(&emails); @@ -181,7 +181,7 @@ print_editor_header(int item) get_first_email(email, item); - if(*db_email_get(item)) + if(*email) snprintf(header, EDITW_COLS, "%s <%s>", db_name_get(item), email); @@ -242,6 +242,25 @@ editor_print_data(int tab, int item) EDITW_COLS - TAB_COLON_POS - 2); } abook_list_free(&emails); + } else if(cur->field->type == FIELD_DATE) { + int day, month, year; + char buf[12]; + + find_field_number(cur->field->key, &nb); + if((str = db_fget_byid(item, nb)) != NULL) + strncpy(buf, str, sizeof(buf)); + + if(str && parse_date_string(buf, &day, &month, &year)) { + if(year) + str = strdup_printf("%04d-%02d-%02d", + year, month, day); + else + str = strdup_printf("--%02d-%02d", + month, day); + mvwaddnstr(editw, y, TAB_COLON_POS + 2, str, + bytes2width(str, FIELD_MAX_WIDTH)); + free(str); + } } else { find_field_number(cur->field->key, &nb); str = safe_str(db_fget_byid(item, nb)); @@ -363,7 +382,7 @@ edit_list(int item, int nb, int isemail) &field, MAX_EMAIL_LEN)) return; /* user cancelled ( C-g ) */ - /* TODO if list item contains commas, sjould use quotes instead */ + /* TODO if list item contains commas, should use quotes instead */ if(field) fix_email_str(field); @@ -380,6 +399,113 @@ edit_list(int item, int nb, int isemail) abook_list_free(&list); } +static int is_valid_date(const int day, const int month, const int year) +{ + int valid = 1; + int month_length[13] = + { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + /* + * leap year + */ + if ((!(year % 4)) && ((year % 100) || !(year % 400))) + month_length[2] = 29; + + if (month < 1 || month > 12) + valid = 0; + else if (day < 1 || day > month_length[month]) + valid = 0; + else if (year < 0) /* we don't accept negative year numbers */ + valid = 0; + + return valid; +} + +static int +parse_date_string(char *s, int *day, int *month, int *year) +{ + int i = 0; + char *p = s; + assert(s && day && month && year); + + if(*s == '-' && *s++ == '-') { /* omitted year */ + *year = 0; + p = ++s; + i++; + } + + while(*s) { + if(isdigit(*s)) { + s++; + continue; + } else if(*s == '-') { + if(++i > 3) + return FALSE; + *s++ = '\0'; + switch(i) { + case 1: *year = safe_atoi(p); break; + case 2: *month = safe_atoi(p); break; + } + p = s; + } else + return FALSE; + } + + if (i != 2 || !*p) + return FALSE; + + *day = atoi(p); + + return is_valid_date(*day, *month, *year); +} + +static int +is_number(char *s) +{ + char *p; + + for(p = s; *p; p++) + if(!isdigit(*p)) + return FALSE; + return TRUE; +} + +static void +edit_date(int item, int nb) +{ + int i, date[3], old = FALSE; + char buf[12], *s = db_fget_byid(item, nb); + char *field[] = { N_("Day: "), N_("Month: "), N_("Year (optional): ") }; + + if(s) { + strncpy(buf, s, sizeof(buf)); + old = parse_date_string(buf, &date[0], &date[1], &date[2]); + } + + for(i = 0; i < 3; i++) { + s = (old && date[i]) ? strdup_printf("%d", date[i]) : NULL; + if(change_field(gettext(field[i]), &s, 5)) + return; /* user aborted with ^G */ + + date[i] = (s && is_number(s)) ? atoi(s) : 0; + + if(!s) { + switch(i) { + case 0: db_fput_byid(item, nb, NULL); /*delete*/ + case 1: /* fall through */ return; + } + } else + xfree(s); + } + + /* ISO 8601 date, of the YYYY-MM-DD or --MM-DD format */ + if(is_valid_date(date[0], date[1], date[2])) { + s = strdup_printf(date[2] ? "%04d-%02d-%02d" : "%c-%02d-%02d", + date[2] ? date[2] : '-', date[1], date[0]); + db_fput_byid(item, nb, xstrdup(s)); + } else + statusline_msg(_("Invalid date")); +} /* input range: 1-9A-Z * output range: 0-34 */ @@ -441,9 +567,8 @@ edit_field(int tab, char c, int item_number) case FIELD_EMAILS: edit_list(item_number, idx, 1); break; - case FIELD_DAY: - statusline_msg(_("sorry, input for this field type is " - "not yet implemented")); + case FIELD_DATE: + edit_date(item_number, idx); return; default: assert(0); @@ -513,17 +638,17 @@ edit_loop(int item) void edit_item(int item) { - if( item < 0 ) { - if( curitem < 0 ) + if(item < 0) { + if(list_get_curitem() < 0) return; else - item = curitem; + item = list_get_curitem(); } init_editor(); while((item = edit_loop(item)) >= 0) - curitem = item; /* hmm, this is not very clean way to go */ + list_set_curitem(item); /* this is not very clean way to go */ close_editor(); } @@ -534,7 +659,7 @@ add_item() char *field = NULL; list_item item = item_create(); - change_field("Name: ", &field, MAX_FIELD_LEN); + change_field(_("Name: "), &field, MAX_FIELD_LEN); if( field == NULL ) return; @@ -544,8 +669,8 @@ add_item() add_item2database(item); item_free(&item); - curitem = LAST_ITEM; + list_set_curitem(last_item()); - edit_item(LAST_ITEM); + edit_item(last_item()); }