5 * by JH <jheinonen@users.sourceforge.net>
7 * Copyright (C) Jaakko Heinonen
26 int first_list_item = -1;
28 char *selected = NULL;
30 extern abook_field_list *fields_list;
31 struct index_elem *index_elements = NULL;
33 static WINDOW *list = NULL;
37 index_elem_add(int type, char *a, char *b)
39 struct index_elem *tmp = NULL, *cur, *cur2;
47 tmp = xmalloc(sizeof(struct index_elem));
48 tmp->d.text = xstrdup(a);
50 case INDEX_FIELD: /* fall through */
52 find_field_number(a, &field);
55 len = (b && *b && is_number(b)) ? atoi(b) : 0;
56 tmp = xmalloc(sizeof(struct index_elem));
57 tmp->d.field.id = field;
58 tmp->d.field.len = len;
65 tmp->d.field.next = NULL;
67 if(!index_elements) { /* first element */
72 for(cur = index_elements; cur->next; cur = cur->next)
74 if(type != INDEX_ALT_FIELD)
76 else { /* add as an alternate field */
77 tmp->d.field.len = cur->d.field.len;
78 for(cur2 = cur; cur2->d.field.next; cur2 = cur2->d.field.next)
80 cur2->d.field.next = tmp;
85 parse_index_format(char *s)
87 char *p, *start, *lstart = NULL;
88 int in_field = 0, in_alternate = 0, in_length = 0, type;
93 if(*p == '{' && !in_field) {
95 index_elem_add(INDEX_TEXT, start, NULL);
98 } else if(*p == ':' && in_field && !in_alternate) {
102 } else if(*p == '|' && in_field) {
104 type = in_alternate ? INDEX_ALT_FIELD : INDEX_FIELD;
105 index_elem_add(type, start, in_length ? lstart : NULL);
109 } else if(*p == '}' && in_field) {
111 type = in_alternate ? INDEX_ALT_FIELD : INDEX_FIELD;
112 index_elem_add(type, start, in_length ? lstart : NULL);
114 in_field = in_alternate = in_length = 0;
119 index_elem_add(INDEX_TEXT, start, NULL);
125 assert(!index_elements);
126 parse_index_format(opt_get_str(STR_INDEX_FORMAT));
132 list = newwin(LIST_LINES, LIST_COLS, LIST_TOP, 0);
133 scrollok(list, TRUE);
134 scroll_speed = abs(opt_get_int(INT_SCROLL_SPEED));
145 get_list_field(int item, struct index_elem *e, struct list_field *res)
149 res->data = s = NULL;
151 do { /* find first non-empty field data in the alternate fields list */
152 s = db_fget_byid(item, e->d.field.id);
153 } while(!(s && *s) && ((e = e->d.field.next) != NULL));
159 get_field_info(e->d.field.id, NULL, NULL, &res->type);
163 print_list_field(int item, int line, int *x_pos, struct index_elem *e)
166 int width, x_start, mustfree = FALSE, len = abs(e->d.field.len);
169 get_list_field(item, e, &f);
177 if(f.type == FIELD_EMAILS && !opt_get_bool(BOOL_SHOW_ALL_EMAILS))
178 if((p = strchr(s, ',')) != NULL) {
179 s = xstrndup(s, p - s);
183 width = len ? bytes2width(s, len) : strwidth(s);
184 x_start = *x_pos + ((e->d.field.len < 0) ? len - width : 0);
185 if(width + x_start >= COLS)
186 width = bytes2width(s, COLS - x_start);
189 mvwaddnstr(list, line, x_start, s, width);
194 *x_pos += len ? len : width;
198 highlight_line(WINDOW *win, int line)
200 wattrset(win, COLOR_PAIR(CP_LIST_HIGHLIGHT));
201 if(!opt_get_bool(BOOL_USE_COLORS)) {
206 * this is a tricky one
210 mvwchgat(win, line, 0, -1, A_STANDOUT, 0, NULL);
213 * buggy function: FIXME
215 scrollok(win, FALSE);
219 for(i = 0; i < COLS; i++)
221 /*wattrset(win, 0);*/
228 print_list_line(int item, int line, int highlight)
230 struct index_elem *cur;
234 wattrset(list, COLOR_PAIR(CP_LIST_EVEN));
236 wattrset(list, COLOR_PAIR(CP_LIST_ODD));
237 scrollok(list, FALSE);
239 highlight_line(list, line);
242 mvwaddch(list, line, 0, '*' );
244 for(cur = index_elements; cur; cur = cur->next)
247 mvwaddstr(list, line, x_pos, cur->d.text);
248 x_pos += strwidth(cur->d.text);
251 print_list_field(item, line, &x_pos, cur);
257 scrollok(list, TRUE);
269 ui_print_number_of_items();
271 if(list_is_empty()) {
280 if(first_list_item < 0)
283 if(curitem < first_list_item)
284 first_list_item = curitem;
285 else if(curitem > LAST_LIST_ITEM)
286 first_list_item = max(curitem - LIST_LINES + 1, 0);
288 for(line = 0, i = first_list_item;
289 i <= LAST_LIST_ITEM && i < db_n_items();
292 print_list_line(i, line, i == curitem);
295 if(opt_get_bool(BOOL_SHOW_CURSOR)) {
296 wmove(list, curitem - first_list_item, 0);
297 /* need to call refresh() to update the cursor positions */
306 struct index_elem *e;
307 int x_pos = 1, width;
310 #if defined(A_BOLD) && defined(A_NORMAL)
313 attrset(COLOR_PAIR(CP_LIST_HEADER));
314 mvhline(2, 0, ' ', COLS);
316 for(e = index_elements; e; e = e->next)
317 if(e->type == INDEX_TEXT)
318 x_pos += strwidth(e->d.text);
319 else if(e->type == INDEX_FIELD) {
320 get_field_info(e->d.field.id, NULL, &str, NULL);
321 width = e->d.field.len ?
322 abs(e->d.field.len) : strwidth(str);
323 if(width + x_pos > COLS)
324 width = bytes2width(str, COLS - x_pos);
325 mvaddnstr(2, x_pos, str, width);
330 #if defined(A_BOLD) && defined(A_NORMAL)
349 if(curitem > db_n_items() - 2)
360 if(first_list_item <= 0) {
368 first_list_item -= scroll_speed;
369 if(first_list_item < 0) {
372 if(curitem > LAST_LIST_ITEM) {
373 curitem = LAST_LIST_ITEM;
382 if(LAST_LIST_ITEM > db_n_items() - 2) {
383 if(curitem < LAST_LIST_ITEM) {
390 first_list_item += scroll_speed;
391 if(LAST_LIST_ITEM > db_n_items() - 1) {
392 first_list_item = db_n_items() - LIST_LINES;
394 if(curitem < first_list_item) {
395 curitem = first_list_item;
407 curitem = curitem == first_list_item ?
408 ((curitem -= LIST_LINES) < 0 ? 0 : curitem) : first_list_item;
416 if(curitem > db_n_items() - 2)
419 if(curitem == LAST_LIST_ITEM) {
420 if((curitem += LIST_LINES) > last_item())
421 curitem = last_item();
423 curitem = min(LAST_LIST_ITEM, last_item());
432 memset(selected, 0, db_n_items());
438 memset(selected, 1, db_n_items());
442 list_set_selection(int item, int value)
444 assert(is_valid_item(item));
446 selected[item] = !!value;
450 list_invert_curitem_selection()
452 assert(is_valid_item(curitem));
454 selected[curitem] = !selected[curitem];
458 move_curitem(int direction)
462 if(curitem < 0 || curitem > last_item())
466 item_copy(tmp, db_item_get(curitem));
472 item_copy(db_item_get(curitem),
473 db_item_get(curitem - 1));
474 item_copy(db_item_get(curitem-1), tmp);
479 if(curitem >= last_item())
481 item_copy(db_item_get(curitem),
482 db_item_get(curitem + 1));
483 item_copy(db_item_get(curitem + 1), tmp);
505 curitem = last_item();
515 for(i = 0; i < db_n_items(); i++)
530 for(i = 0; i < db_n_items(); i++)
531 selected[i] = !selected[i];
537 return db_n_items() < 1;
549 return first_list_item;
553 list_set_curitem(int i)
566 item = item_create();
567 item_duplicate(item, db_item_get(curitem));
568 if(add_item2database(item)) {
574 curitem = last_item();