]> git.deb.at Git - pkg/abook.git/blobdiff - edit.c
Upload 0.6.1-2 to unstable
[pkg/abook.git] / edit.c
diff --git a/edit.c b/edit.c
index 940a57db0b05739be47997ce61d00c756652158b..9a76c8a8970aadda843bd1b7ab7638f3e2c84ec1 100644 (file)
--- a/edit.c
+++ b/edit.c
@@ -21,6 +21,7 @@
 #include "misc.h"
 #include "views.h"
 #include "xmalloc.h"
+#include "color.h"
 #ifdef HAVE_CONFIG_H
 #      include "config.h"
 #endif
@@ -47,6 +48,7 @@ editor_tab(const int tab)
        int x_pos = 2; /* current x pos */
        char *tab_name;
 
+       wattrset(editw, COLOR_PAIR(CP_TAB_BORDER));
        mvwhline(editw, TABLINE + 1, 0, UI_HLINE_CHAR, EDITW_COLS);
 
        for(i = 0; i < views_count; i++) {
@@ -63,7 +65,9 @@ editor_tab(const int tab)
 
                mvwaddch(editw,  TABLINE, x_pos,  UI_ULCORNER_CHAR);
                mvwaddch(editw,  TABLINE, x_pos + 1,  UI_LBOXLINE_CHAR);
+               wattrset(editw, COLOR_PAIR(CP_TAB_LABEL));
                mvwaddstr(editw, TABLINE, x_pos + 2,  tab_name);
+               wattrset(editw, COLOR_PAIR(CP_TAB_BORDER));
                mvwaddch(editw,  TABLINE, x_pos + width - 3, UI_RBOXLINE_CHAR);
                mvwaddch(editw,  TABLINE, x_pos + width - 2, UI_URCORNER_CHAR);
 
@@ -100,7 +104,7 @@ get_first_email(char *str, int item)
 /* 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
+void
 roll_emails(int item, enum rotate_dir dir)
 {
        abook_list *emails = csv_to_abook_list(db_fget(item, EMAIL));
@@ -192,6 +196,7 @@ print_editor_header(int item)
        else
                snprintf(header, EDITW_COLS, "%s", db_name_get(item));
 
+       wattrset(editw, COLOR_PAIR(CP_TAB_LABEL));
        mvwaddstr(editw, 0, (EDITW_COLS - strwidth(header)) / 2, header);
 
        free(header);
@@ -215,6 +220,7 @@ editor_print_data(int tab, int item)
                } else
                        y = FIELDS_START_Y;
 
+               wattrset(editw, COLOR_PAIR(CP_FIELD_NAME));
                mvwprintw(editw, y, FIELDS_START_X, "%c - ",
                                (j < 10) ? '0' + j : 'A' + j - 10);
                mvwaddnstr(editw, y, FIELDS_START_X + 4, cur->field->name,
@@ -222,6 +228,7 @@ editor_print_data(int tab, int item)
                                        FIELDNAME_MAX_WIDTH));
                mvwaddch(editw, y, TAB_COLON_POS, ':');
 
+               wattrset(editw, COLOR_PAIR(CP_FIELD_VALUE));
                if((cur->field->type == FIELD_EMAILS) ||
                                (cur->field->type == FIELD_LIST)) {
                        abook_list *emails, *e;
@@ -250,12 +257,10 @@ editor_print_data(int tab, int item)
                        int day, month, year;
                        char buf[64];
 
-                       /* put raw representation of date in buf */
                        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)) {
+                       str = db_fget_byid(item, nb);
+                       
+                       if(parse_date_string(str, &day, &month, &year)) {
                                /* put locale representation of date in buf */
                                locale_date(buf, sizeof(buf), year, month, day);
                                mvwaddnstr(editw, y, TAB_COLON_POS + 2, buf,
@@ -400,33 +405,18 @@ edit_list(int item, int nb, int isemail)
 }
 
 /*
- * str is a buffer of max length str_len, which, after calling, will
- * contain a representation of the given [y, m, d] date using the
- * current locale (as defined by LC_TIME).
- *
- * Default is an ISO 8601 representation.
- *
- * %-sequences available to translators: %y, %Y, %m, %M, %d, %D represent
- * year, month, and day (the uppercase version telling to fill with leading
- * zeros if necessary)
+ * available %-sequences:
+ *   - %y, %Y, %m, %M, %d, %D represent year, month, and day
+ *     (the uppercase version telling to fill with leading zeros
+ *     if necessary)
+ *   - %I for ISO 8601 representation
  */
-static void
-locale_date(char *str, size_t str_len, int year, int month, int day)
+static size_t
+format_date(char *str, size_t str_len, char *fmt, int year, int month, int day)
 {
-       char *s = str, *fmt;
+       char *s = str;
        size_t len;
 
-#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
-       fmt = year ?    dcgettext(PACKAGE, "%Y-%M-%D", LC_TIME) :
-                       dcgettext(PACKAGE, "--%M-%D", LC_TIME);
-#else
-       if(year)
-               snprintf(str, str_len, "%04d-%02d-%02d", year, month, day);
-       else
-               snprintf(str, str_len, "--%02d-%02d", month, day);
-       return;
-#endif
-
        while(*fmt && (s - str + 1 < str_len)) {
                if(*fmt != '%') {
                        *s++ = *fmt++;
@@ -441,15 +431,38 @@ locale_date(char *str, size_t str_len, int year, int month, int day)
                        case 'M': s += snprintf(s, len, "%02d", month); break;
                        case 'd': s += snprintf(s, len, "%d", day); break;
                        case 'D': s += snprintf(s, len, "%02d", day); break;
-                       case '%': /* fall through */
-                       default:
-                               *s++ = '%';
-                               *s++ = *fmt;
-                               break;
+                       case 'I': s += format_date(s, len,
+                                                 year ? "%Y-%M-%D" : "--%M-%D",
+                                                 year, month, day);
+                                 break;
+                       case '%': *s++ = '%'; break;
+                       default: *s++ = '%'; *s++ = *fmt; break;
                }
                fmt++;
        }
-       *++s = 0;
+       *s = 0;
+       return s - str;
+}
+
+/*
+ * str is a buffer of max length str_len, which, after calling, will
+ * contain a representation of the given [y, m, d] date using the
+ * current locale (as defined by LC_TIME).
+ *
+ * In the absence of any localization, use an ISO 8601 representation.
+ */
+static void
+locale_date(char *str, size_t str_len, int year, int month, int day)
+{
+       char *fmt;
+
+#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
+       fmt = year ?    dcgettext(PACKAGE, "%Y-%M-%D", LC_TIME) :
+                       dcgettext(PACKAGE, "--%M-%D", LC_TIME);
+#else
+       fmt = "%I";
+#endif
+       format_date(str, str_len, fmt, year, month, day);
 }
 
 static int is_valid_date(const int day, const int month, const int year)
@@ -475,11 +488,17 @@ static int is_valid_date(const int day, const int month, const int year)
 }
 
 int
-parse_date_string(char *s, int *day, int *month, int *year)
+parse_date_string(char *str, int *day, int *month, int *year)
 {
        int i = 0;
-       char *p = s;
-       assert(s && day && month && year);
+       char buf[12], *s, *p;
+
+       assert(day && month && year);
+
+       if(!str || !*str)
+               return FALSE;
+
+       p = s = strncpy(buf, str, sizeof(buf));
 
        if(*s == '-' && *s++ == '-') { /* omitted year */
                *year = 0;
@@ -501,7 +520,7 @@ parse_date_string(char *s, int *day, int *month, int *year)
                        }
                        p = s;
                } else
-               return FALSE;
+                       return FALSE;
        }
 
        if (i != 2 || !*p)
@@ -515,14 +534,11 @@ parse_date_string(char *s, int *day, int *month, int *year)
 static void
 edit_date(int item, int nb)
 {
-       int i, date[3], old = FALSE;
-       char buf[12], *s = db_fget_byid(item, nb);
+       int i, date[3], old;
+       char *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]);
-       }
+       old = parse_date_string(s, &date[0], &date[1], &date[2]);
 
        for(i = 0; i < 3; i++) {
                s = (old && date[i]) ? strdup_printf("%d", date[i]) : NULL;
@@ -572,13 +588,14 @@ key_to_field_number(char c)
 static void
 edit_field(int tab, char c, int item_number)
 {
+       ui_enable_mouse(FALSE);
        int i = 0, number, idx;
        char *msg;
        abook_field_list *f;
        list_item item;
 
        if((number = key_to_field_number(c)) < 0)
-               return;
+               goto detachfield;
 
        edit_undo(item_number, BACKUP_ITEM);
 
@@ -586,7 +603,7 @@ edit_field(int tab, char c, int item_number)
 
        while(1) {
                if(!f)
-                       return;
+                       goto detachfield;
 
                if(i == number)
                        break;
@@ -615,10 +632,14 @@ edit_field(int tab, char c, int item_number)
                        break;
                case FIELD_DATE:
                        edit_date(item_number, idx);
-                       return;
+                       goto detachfield;
                default:
                        assert(0);
        }
+
+ detachfield:
+       if(opt_get_bool(BOOL_USE_MOUSE))
+         ui_enable_mouse(TRUE);
 }
 
 static int
@@ -652,6 +673,53 @@ edit_loop(int item)
 
                return item;
        }
+       if(c == KEY_MOUSE) {
+               MEVENT event;
+               if(getmouse(&event) == OK) {
+                       if(event.bstate & BUTTON1_CLICKED
+                          || event.bstate & BUTTON1_DOUBLE_CLICKED) {
+                               int window_y, window_x;
+                               getbegyx(editw, window_y, window_x);
+                               if(event.y == 0) {
+                                       /* if first row is selected, then go back to list */
+                                       return -1;
+                               } else if(event.y == window_y + TABLINE
+                                  || event.y == window_y + TABLINE + 1) {
+                                       char* tab_name;
+                                       int mouse_x = event.x;
+                                       int xpos = 2 + 1; /* look at editor_tab() and try out */
+                                       int clicked_tab = 0;
+                                       while(clicked_tab < views_count) {
+                                               view_info(clicked_tab, &tab_name, NULL);
+                                               xpos += strwidth(tab_name) + 5;
+                                               /* fprintf(stderr, "trying tab %d\n", clicked_tab); */
+                                               if(xpos >= mouse_x) {
+                                                       break; /* clicked tab was found */
+                                               } else {
+                                                       /* try next tab */
+                                                       clicked_tab++;
+                                               }
+                                       }
+                                       if(clicked_tab < views_count) {
+                                               tab = clicked_tab;
+                                       }
+                               } else if(event.y >= window_y + FIELDS_START_Y) {
+                                       /* is mouse in field area? */
+                                       int j = 1 + event.y - window_y - FIELDS_START_Y;
+                                       /* field numbers start with 1, but if j='0', then char='0' */
+                                       /* so fix this, by adding 1 to j */
+                                       int field_char = (j < 10) ? '0' + j : 'A' + j - 10;
+                                       edit_field(tab, field_char, item);
+                               }
+                       } else if(event.bstate & BUTTON4_PRESSED) {
+                               tab = tab == 0 ? views_count - 1 : tab - 1;
+                       }
+                       else if(event.bstate & BUTTON5_PRESSED) {
+                               tab = tab == views_count - 1 ? 0 : tab + 1;
+                       }
+                       return item;
+               }
+       }
 
        /* No uppercase nor numeric key should be used in this menu,
         * as they are reserved for field selection */