]> git.deb.at Git - pkg/abook.git/blob - list.c
- don't use items variable outside of database.c
[pkg/abook.git] / list.c
1
2 /*
3  * $Id$
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];
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                 mvwaddnstr(list, line, EMAILPOS, db_email_get(i),
136                                 bytes2width(db_email_get(i), real_emaillen));
137         else {
138                 get_first_email(tmp, i);
139                 mvwaddnstr(list, line, EMAILPOS, tmp,
140                                 bytes2width(tmp, real_emaillen));
141         }
142
143         if(extra < 0 || !db_fget_byid(i, extra))
144                 extra = extra_alternative;
145         if(extra >= 0)
146                 mvwaddnstr(list, line, EXTRAPOS,
147                         safe_str(db_fget_byid(i, extra)),
148                         bytes2width(safe_str(db_fget_byid(i, extra)),
149                         EXTRALEN));
150
151         scrollok(list, TRUE);
152         if(highlight)
153                 wstandend(list);
154 }
155
156 void
157 list_headerline()
158 {
159         char *str = NULL;
160
161 #if defined(A_BOLD) && defined(A_NORMAL)
162         attrset(A_BOLD);
163 #endif
164
165         mvaddstr(2, NAMEPOS, find_field("name", NULL)->name);
166         mvaddstr(2, EMAILPOS, find_field("email", NULL)->name);
167         if(extra_column > 0) {
168                 get_field_keyname(extra_column, NULL, &str);
169                 mvaddnstr(2, EXTRAPOS, str, COLS - EXTRAPOS);
170         }
171
172 #if defined(A_BOLD) && defined(A_NORMAL)
173         attrset(A_NORMAL);
174 #endif
175 }
176
177 void
178 scroll_up()
179 {
180         if(curitem < 1)
181                 return;
182
183         curitem--;
184
185         refresh_list();
186 }
187
188 void
189 scroll_down()
190 {
191         if(curitem > db_n_items() - 2)
192                 return;
193
194         curitem++;
195
196         refresh_list();
197 }
198
199
200 void
201 page_up()
202 {
203         if(curitem < 1)
204                 return;
205
206         curitem = curitem == first_list_item ?
207                 ((curitem -= LIST_LINES) < 0 ? 0 : curitem) : first_list_item;
208
209         refresh_list();
210 }
211
212 void
213 page_down()
214 {
215         if(curitem > db_n_items() - 2)
216                 return;
217
218         if(curitem == LAST_LIST_ITEM) {
219                 if((curitem += LIST_LINES) > last_item())
220                         curitem = last_item();
221         } else {
222                 curitem = min(LAST_LIST_ITEM, last_item());
223         }
224
225         refresh_list();
226 }
227
228 void
229 select_none()
230 {
231         memset(selected, 0, db_n_items());
232 }
233
234 void
235 select_all()
236 {
237         memset(selected, 1, db_n_items());
238 }
239
240 void
241 list_set_selection(int item, int value)
242 {
243         assert(is_valid_item(item));
244
245         selected[item] = !!value;
246 }
247
248 void
249 list_invert_curitem_selection()
250 {
251         assert(is_valid_item(curitem));
252
253         selected[curitem] = !selected[curitem];
254 }
255
256 void
257 move_curitem(int direction)
258 {
259         list_item tmp;
260
261         if(curitem < 0 || curitem > last_item())
262                 return;
263
264         tmp = item_create();
265         item_copy(tmp, db_item_get(curitem));
266
267         switch(direction) {
268                 case MOVE_ITEM_UP:
269                         if( curitem < 1 )
270                                 goto out_move;
271                         item_copy(db_item_get(curitem),
272                                         db_item_get(curitem - 1));
273                         item_copy(db_item_get(curitem-1), tmp);
274                         scroll_up();
275                         break;
276
277                 case MOVE_ITEM_DOWN:
278                         if(curitem >= last_item())
279                                 goto out_move;
280                         item_copy(db_item_get(curitem),
281                                         db_item_get(curitem + 1));
282                         item_copy(db_item_get(curitem + 1), tmp);
283                         scroll_down();
284                         break;
285         }
286
287 out_move:
288         item_free(&tmp);
289 }
290
291 void
292 goto_home()
293 {
294         if(db_n_items() > 0)
295                 curitem = 0;
296
297         refresh_list();
298 }
299
300 void
301 goto_end()
302 {
303         if(db_n_items() > 0)
304                 curitem = last_item();
305
306         refresh_list();
307 }
308
309 void
310 highlight_line(WINDOW *win, int line)
311 {
312         wstandout(win);
313
314         /*
315          * this is a tricky one
316          */
317 #if 0
318 /*#ifdef mvwchgat*/
319         mvwchgat(win, line, 0, -1,  A_STANDOUT, 0, NULL);
320 #else
321         /*
322          * buggy function: FIXME
323          */
324         scrollok(win, FALSE);
325         {
326                 int i;
327                 wmove(win, line, 0);
328                 for(i = 0; i < COLS; i++)
329                         waddch(win, ' ');
330         /*wattrset(win, 0);*/
331         }
332         scrollok(win, TRUE);
333 #endif
334 }
335
336 int
337 selected_items()
338 {
339         int i, n = 0;
340
341         for(i = 0; i < db_n_items(); i++)
342                 if(selected[i])
343                         n++;
344
345         return n;
346 }
347
348 void
349 invert_selection()
350 {
351         int i;
352
353         if(list_is_empty())
354                 return;
355
356         for(i = 0; i < db_n_items(); i++)
357                 selected[i] = !selected[i];
358 }
359
360 int
361 list_is_empty()
362 {
363         return db_n_items() < 1;
364 }
365
366 int
367 list_get_curitem()
368 {
369         return curitem;
370 }
371
372 void
373 list_set_curitem(int i)
374 {
375         curitem = i;
376 }
377
378 int
379 duplicate_item()
380 {
381         list_item item;
382         
383         if(curitem < 0)
384                 return 1;
385
386         item = item_create();
387         item_duplicate(item, db_item_get(curitem));
388         if(add_item2database(item)) {
389                 item_free(&item);
390                 return 1;
391         }
392         item_free(&item);
393
394         curitem = last_item();
395         refresh_list();
396
397         return 0;
398 }
399