]> git.deb.at Git - pkg/abook.git/blob - list.c
Imported Upstream version 0.5.6+cvs1
[pkg/abook.git] / list.c
1
2 /*
3  * $Id: list.c,v 1.30 2006/08/07 19:20:26 cduval Exp $
4  *
5  * by JH <jheinonen@users.sourceforge.net>
6  *
7  * Copyright (C) Jaakko Heinonen
8  */
9
10 #include <stdio.h>
11 #include <string.h>
12 #include "abook.h"
13 #include <assert.h>
14 #include "ui.h"
15 #include "database.h"
16 #include "edit.h"
17 #include "gettext.h"
18 #include "list.h"
19 #include "misc.h"
20 #include "options.h"
21 #include "xmalloc.h"
22
23
24 int curitem = -1;
25 int first_list_item = -1;
26 char *selected = NULL;
27
28 int extra_column = -1;
29 int extra_alternative = -1;
30
31 extern abook_field_list *fields_list;
32
33 static WINDOW *list = NULL;
34
35
36 int
37 init_extra_field(enum str_opts option)
38 {
39         int ret = -1;
40         char *option_str;
41
42         option_str = opt_get_str(option);
43
44         if(option_str && *option_str) {
45                 find_field_number(option_str, &ret);
46
47                 if(!strcmp(option_str, "name") || !strcmp(option_str, "email"))
48                         ret = -1;
49         }
50
51         return ret;
52 }
53
54 void
55 init_list()
56 {
57         list = newwin(LIST_LINES, LIST_COLS, LIST_TOP, 0);
58         scrollok(list, TRUE);
59
60         /*
61          * init extra_column and extra alternative
62          */
63
64         extra_column = init_extra_field(STR_EXTRA_COLUMN);
65         extra_alternative = init_extra_field(STR_EXTRA_ALTERNATIVE);
66 }
67
68 void
69 close_list()
70 {
71         delwin(list);
72         list = NULL;
73 }
74
75 void
76 refresh_list()
77 {
78         int i, line;
79
80         werase(list);
81
82         ui_print_number_of_items();
83
84         if(list_is_empty()) {
85                 refresh();
86                 wrefresh(list);
87                 return;
88         }
89
90         if(curitem < 0)
91                 curitem = 0;
92
93         if(first_list_item < 0)
94                 first_list_item = 0;
95
96         if(curitem < first_list_item)
97                 first_list_item = curitem;
98         else if(curitem > LAST_LIST_ITEM)
99                 first_list_item = max(curitem - LIST_LINES + 1, 0);
100
101         for(line = 0, i = first_list_item;
102                         i <= LAST_LIST_ITEM && i < db_n_items();
103                         line++, i++) {
104
105                 print_list_line(i, line, i == curitem);
106         }
107
108         if(opt_get_bool(BOOL_SHOW_CURSOR)) {
109                 wmove(list, curitem - first_list_item, 0);
110                 /* need to call refresh() to update the cursor positions */
111                 refresh();
112         }
113         wrefresh(list);
114 }
115
116 void
117 print_list_line(int i, int line, int highlight)
118 {
119         int extra = extra_column;
120         char tmp[MAX_EMAILSTR_LEN], *emails;
121         int real_emaillen = (extra_column > 0 || extra_alternative > 0) ?
122                 EMAILLEN : COLS - EMAILPOS;
123
124         scrollok(list, FALSE);
125         if(highlight)
126                 highlight_line(list, line);
127
128         if(selected[i])
129                 mvwaddch(list, line, 0, '*' );
130
131         mvwaddnstr(list, line, NAMEPOS, db_name_get(i),
132                 bytes2width(db_name_get(i), NAMELEN));
133
134         if(opt_get_bool(BOOL_SHOW_ALL_EMAILS)) {
135                 emails = db_email_get(i);
136                 mvwaddnstr(list, line, EMAILPOS, emails,
137                                 bytes2width(emails, real_emaillen));
138                 free(emails);
139         } else {
140                 get_first_email(tmp, i);
141                 mvwaddnstr(list, line, EMAILPOS, tmp,
142                                 bytes2width(tmp, real_emaillen));
143         }
144
145         if(extra < 0 || !db_fget_byid(i, extra))
146                 extra = extra_alternative;
147         if(extra >= 0)
148                 mvwaddnstr(list, line, EXTRAPOS,
149                         safe_str(db_fget_byid(i, extra)),
150                         bytes2width(safe_str(db_fget_byid(i, extra)),
151                         EXTRALEN));
152
153         scrollok(list, TRUE);
154         if(highlight)
155                 wstandend(list);
156 }
157
158 void
159 list_headerline()
160 {
161         char *str = NULL;
162
163 #if defined(A_BOLD) && defined(A_NORMAL)
164         attrset(A_BOLD);
165 #endif
166
167         mvaddstr(2, NAMEPOS, find_field("name", NULL)->name);
168         mvaddstr(2, EMAILPOS, find_field("email", NULL)->name);
169         if(extra_column > 0) {
170                 get_field_keyname(extra_column, NULL, &str);
171                 mvaddnstr(2, EXTRAPOS, str, COLS - EXTRAPOS);
172         }
173
174 #if defined(A_BOLD) && defined(A_NORMAL)
175         attrset(A_NORMAL);
176 #endif
177 }
178
179 void
180 scroll_up()
181 {
182         if(curitem < 1)
183                 return;
184
185         curitem--;
186
187         refresh_list();
188 }
189
190 void
191 scroll_down()
192 {
193         if(curitem > db_n_items() - 2)
194                 return;
195
196         curitem++;
197
198         refresh_list();
199 }
200
201
202 void
203 page_up()
204 {
205         if(curitem < 1)
206                 return;
207
208         curitem = curitem == first_list_item ?
209                 ((curitem -= LIST_LINES) < 0 ? 0 : curitem) : first_list_item;
210
211         refresh_list();
212 }
213
214 void
215 page_down()
216 {
217         if(curitem > db_n_items() - 2)
218                 return;
219
220         if(curitem == LAST_LIST_ITEM) {
221                 if((curitem += LIST_LINES) > last_item())
222                         curitem = last_item();
223         } else {
224                 curitem = min(LAST_LIST_ITEM, last_item());
225         }
226
227         refresh_list();
228 }
229
230 void
231 select_none()
232 {
233         memset(selected, 0, db_n_items());
234 }
235
236 void
237 select_all()
238 {
239         memset(selected, 1, db_n_items());
240 }
241
242 void
243 list_set_selection(int item, int value)
244 {
245         assert(is_valid_item(item));
246
247         selected[item] = !!value;
248 }
249
250 void
251 list_invert_curitem_selection()
252 {
253         assert(is_valid_item(curitem));
254
255         selected[curitem] = !selected[curitem];
256 }
257
258 void
259 move_curitem(int direction)
260 {
261         list_item tmp;
262
263         if(curitem < 0 || curitem > last_item())
264                 return;
265
266         tmp = item_create();
267         item_copy(tmp, db_item_get(curitem));
268
269         switch(direction) {
270                 case MOVE_ITEM_UP:
271                         if( curitem < 1 )
272                                 goto out_move;
273                         item_copy(db_item_get(curitem),
274                                         db_item_get(curitem - 1));
275                         item_copy(db_item_get(curitem-1), tmp);
276                         scroll_up();
277                         break;
278
279                 case MOVE_ITEM_DOWN:
280                         if(curitem >= last_item())
281                                 goto out_move;
282                         item_copy(db_item_get(curitem),
283                                         db_item_get(curitem + 1));
284                         item_copy(db_item_get(curitem + 1), tmp);
285                         scroll_down();
286                         break;
287         }
288
289 out_move:
290         item_free(&tmp);
291 }
292
293 void
294 goto_home()
295 {
296         if(db_n_items() > 0)
297                 curitem = 0;
298
299         refresh_list();
300 }
301
302 void
303 goto_end()
304 {
305         if(db_n_items() > 0)
306                 curitem = last_item();
307
308         refresh_list();
309 }
310
311 void
312 highlight_line(WINDOW *win, int line)
313 {
314         wstandout(win);
315
316         /*
317          * this is a tricky one
318          */
319 #if 0
320 /*#ifdef mvwchgat*/
321         mvwchgat(win, line, 0, -1,  A_STANDOUT, 0, NULL);
322 #else
323         /*
324          * buggy function: FIXME
325          */
326         scrollok(win, FALSE);
327         {
328                 int i;
329                 wmove(win, line, 0);
330                 for(i = 0; i < COLS; i++)
331                         waddch(win, ' ');
332         /*wattrset(win, 0);*/
333         }
334         scrollok(win, TRUE);
335 #endif
336 }
337
338 int
339 selected_items()
340 {
341         int i, n = 0;
342
343         for(i = 0; i < db_n_items(); i++)
344                 if(selected[i])
345                         n++;
346
347         return n;
348 }
349
350 void
351 invert_selection()
352 {
353         int i;
354
355         if(list_is_empty())
356                 return;
357
358         for(i = 0; i < db_n_items(); i++)
359                 selected[i] = !selected[i];
360 }
361
362 int
363 list_is_empty()
364 {
365         return db_n_items() < 1;
366 }
367
368 int
369 list_get_curitem()
370 {
371         return curitem;
372 }
373
374 void
375 list_set_curitem(int i)
376 {
377         curitem = i;
378 }
379
380 int
381 duplicate_item()
382 {
383         list_item item;
384         
385         if(curitem < 0)
386                 return 1;
387
388         item = item_create();
389         item_duplicate(item, db_item_get(curitem));
390         if(add_item2database(item)) {
391                 item_free(&item);
392                 return 1;
393         }
394         item_free(&item);
395
396         curitem = last_item();
397         refresh_list();
398
399         return 0;
400 }
401