5 * by JH <jheinonen@users.sourceforge.net>
7 * Copyright (C) Jaakko Heinonen
26 int first_list_item = -1;
27 char *selected = NULL;
29 extern abook_field_list *fields_list;
30 struct index_elem *index_elements = NULL;
32 static WINDOW *list = NULL;
36 index_elem_add(int type, char *a, char *b)
38 struct index_elem *tmp = NULL, *cur, *cur2;
46 tmp = xmalloc(sizeof(struct index_elem));
47 tmp->d.text = xstrdup(a);
49 case INDEX_FIELD: /* fall through */
51 find_field_number(a, &field);
54 len = (b && *b && is_number(b)) ? atoi(b) : 0;
55 tmp = xmalloc(sizeof(struct index_elem));
56 tmp->d.field.id = field;
57 tmp->d.field.len = len;
64 tmp->d.field.next = NULL;
66 if(!index_elements) { /* first element */
71 for(cur = index_elements; cur->next; cur = cur->next)
73 if(type != INDEX_ALT_FIELD)
75 else { /* add as an alternate field */
76 tmp->d.field.len = cur->d.field.len;
77 for(cur2 = cur; cur2->d.field.next; cur2 = cur2->d.field.next)
79 cur2->d.field.next = tmp;
84 parse_index_format(char *s)
86 char *p, *start, *lstart = NULL;
87 int in_field = 0, in_alternate = 0, in_length = 0, type;
92 if(*p == '{' && !in_field) {
94 index_elem_add(INDEX_TEXT, start, NULL);
97 } else if(*p == ':' && in_field && !in_alternate) {
101 } else if(*p == '|' && in_field) {
103 type = in_alternate ? INDEX_ALT_FIELD : INDEX_FIELD;
104 index_elem_add(type, start, in_length ? lstart : NULL);
108 } else if(*p == '}' && in_field) {
110 type = in_alternate ? INDEX_ALT_FIELD : INDEX_FIELD;
111 index_elem_add(type, start, in_length ? lstart : NULL);
113 in_field = in_alternate = in_length = 0;
118 index_elem_add(INDEX_TEXT, start, NULL);
124 assert(!index_elements);
125 parse_index_format(opt_get_str(STR_INDEX_FORMAT));
131 list = newwin(LIST_LINES, LIST_COLS, LIST_TOP, 0);
132 scrollok(list, TRUE);
143 get_list_field(int item, struct index_elem *e, struct list_field *res)
147 res->data = s = NULL;
149 do { /* find first non-empty field data in the alternate fields list */
150 s = db_fget_byid(item, e->d.field.id);
151 } while(!(s && *s) && ((e = e->d.field.next) != NULL));
157 get_field_info(e->d.field.id, NULL, NULL, &res->type);
161 print_list_field(int item, int line, int *x_pos, struct index_elem *e)
164 int width, x_start, mustfree = FALSE, len = abs(e->d.field.len);
167 get_list_field(item, e, &f);
175 if(f.type == FIELD_EMAILS && !opt_get_bool(BOOL_SHOW_ALL_EMAILS))
176 if((p = strchr(s, ',')) != NULL) {
177 s = xstrndup(s, p - s);
181 width = len ? bytes2width(s, len) : strwidth(s);
182 x_start = *x_pos + ((e->d.field.len < 0) ? len - width : 0);
183 if(width + x_start >= COLS)
184 width = bytes2width(s, COLS - x_start);
187 mvwaddnstr(list, line, x_start, s, width);
192 *x_pos += len ? len : width;
196 highlight_line(WINDOW *win, int line)
198 wattrset(win, COLOR_PAIR(CP_LIST_HIGHLIGHT));
199 if(!opt_get_bool(BOOL_USE_COLORS)) {
204 * this is a tricky one
208 mvwchgat(win, line, 0, -1, A_STANDOUT, 0, NULL);
211 * buggy function: FIXME
213 scrollok(win, FALSE);
217 for(i = 0; i < COLS; i++)
219 /*wattrset(win, 0);*/
226 print_list_line(int item, int line, int highlight)
228 struct index_elem *cur;
232 wattrset(list, COLOR_PAIR(CP_LIST_EVEN));
234 wattrset(list, COLOR_PAIR(CP_LIST_ODD));
235 scrollok(list, FALSE);
237 highlight_line(list, line);
240 mvwaddch(list, line, 0, '*' );
242 for(cur = index_elements; cur; cur = cur->next)
245 mvwaddstr(list, line, x_pos, cur->d.text);
246 x_pos += strwidth(cur->d.text);
249 print_list_field(item, line, &x_pos, cur);
255 scrollok(list, TRUE);
267 ui_print_number_of_items();
269 if(list_is_empty()) {
278 if(first_list_item < 0)
281 if(curitem < first_list_item)
282 first_list_item = curitem;
283 else if(curitem > LAST_LIST_ITEM)
284 first_list_item = max(curitem - LIST_LINES + 1, 0);
286 for(line = 0, i = first_list_item;
287 i <= LAST_LIST_ITEM && i < db_n_items();
290 print_list_line(i, line, i == curitem);
293 if(opt_get_bool(BOOL_SHOW_CURSOR)) {
294 wmove(list, curitem - first_list_item, 0);
295 /* need to call refresh() to update the cursor positions */
304 struct index_elem *e;
305 int x_pos = 1, width;
308 #if defined(A_BOLD) && defined(A_NORMAL)
311 attrset(COLOR_PAIR(CP_LIST_HEADER));
312 mvhline(2, 0, ' ', COLS);
314 for(e = index_elements; e; e = e->next)
315 if(e->type == INDEX_TEXT)
316 x_pos += strwidth(e->d.text);
317 else if(e->type == INDEX_FIELD) {
318 get_field_info(e->d.field.id, NULL, &str, NULL);
319 width = e->d.field.len ?
320 abs(e->d.field.len) : strwidth(str);
321 if(width + x_pos > COLS)
322 width = bytes2width(str, COLS - x_pos);
323 mvaddnstr(2, x_pos, str, width);
328 #if defined(A_BOLD) && defined(A_NORMAL)
347 if(curitem > db_n_items() - 2)
362 curitem = curitem == first_list_item ?
363 ((curitem -= LIST_LINES) < 0 ? 0 : curitem) : first_list_item;
371 if(curitem > db_n_items() - 2)
374 if(curitem == LAST_LIST_ITEM) {
375 if((curitem += LIST_LINES) > last_item())
376 curitem = last_item();
378 curitem = min(LAST_LIST_ITEM, last_item());
387 memset(selected, 0, db_n_items());
393 memset(selected, 1, db_n_items());
397 list_set_selection(int item, int value)
399 assert(is_valid_item(item));
401 selected[item] = !!value;
405 list_invert_curitem_selection()
407 assert(is_valid_item(curitem));
409 selected[curitem] = !selected[curitem];
413 move_curitem(int direction)
417 if(curitem < 0 || curitem > last_item())
421 item_copy(tmp, db_item_get(curitem));
427 item_copy(db_item_get(curitem),
428 db_item_get(curitem - 1));
429 item_copy(db_item_get(curitem-1), tmp);
434 if(curitem >= last_item())
436 item_copy(db_item_get(curitem),
437 db_item_get(curitem + 1));
438 item_copy(db_item_get(curitem + 1), tmp);
460 curitem = last_item();
470 for(i = 0; i < db_n_items(); i++)
485 for(i = 0; i < db_n_items(); i++)
486 selected[i] = !selected[i];
492 return db_n_items() < 1;
504 return first_list_item;
508 list_set_curitem(int i)
521 item = item_create();
522 item_duplicate(item, db_item_get(curitem));
523 if(add_item2database(item)) {
529 curitem = last_item();