]> git.deb.at Git - pkg/abook.git/blob - list.c
Imported Upstream version 0.5.3
[pkg/abook.git] / list.c
1
2 /*
3  * $Id: list.c,v 1.21 2004/06/30 19:47:43 jheinonen 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 "list.h"
18 #include "misc.h"
19 #include "options.h"
20
21 #define MIN_EXTRA_COLUMN        ADDRESS /* 2 */
22 #define MAX_EXTRA_COLUMN        LAST_FIELD
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 int items;
32 extern list_item *database;
33 extern struct abook_field abook_fields[];
34
35 WINDOW *list = NULL;
36
37 static int
38 init_extra_field(enum str_opts option)
39 {
40         int i, ret = -1;
41         char *option_str;
42
43         option_str = opt_get_str(option);
44
45         if(option_str && *option_str) {
46                 for(i = 0; i < ITEM_FIELDS; i++) {
47                         if(!strcasecmp(option_str, abook_fields[i].key)) {
48                                 ret = i;
49                                 break;
50                         }
51                 }
52                 if(ret < MIN_EXTRA_COLUMN || ret > MAX_EXTRA_COLUMN) {
53                         ret = -1;
54                 }
55         }
56
57         return ret;
58 }
59
60 void
61 init_list()
62 {
63         list = newwin(LIST_LINES, LIST_COLS, LIST_TOP, 0);
64         scrollok(list, TRUE);
65
66         /*
67          * init extra_column and extra alternative
68          */
69
70         extra_column = init_extra_field(STR_EXTRA_COLUMN);
71         extra_alternative = init_extra_field(STR_EXTRA_ALTERNATIVE);
72 }
73
74 void
75 close_list()
76 {
77         delwin(list);
78         list = NULL;
79 }
80
81 void
82 refresh_list()
83 {
84         int i, line;
85         
86         werase(list);
87
88         ui_print_number_of_items();
89         
90         if(items < 1) {
91                 refresh();
92                 wrefresh(list);
93                 return;
94         }
95         
96         if(curitem < 0)
97                 curitem = 0;
98
99         if(first_list_item < 0)
100                 first_list_item = 0;
101
102         if(curitem < first_list_item)
103                 first_list_item = curitem;
104         else if(curitem > LAST_LIST_ITEM)
105                 first_list_item = max(curitem - LIST_LINES + 1, 0);
106
107         for( line = 0, i = first_list_item ; i <= LAST_LIST_ITEM && i < items;
108                         line++, i++ ) {
109
110                 print_list_line(i, line, i == curitem);
111         }
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, database[i][NAME],
132                 bytes2width(database[i][NAME], NAMELEN));
133         if(opt_get_bool(BOOL_SHOW_ALL_EMAILS))
134                 mvwaddnstr(list, line, EMAILPOS, database[i][EMAIL],
135                                 bytes2width(database[i][EMAIL], real_emaillen));
136         else {
137                 get_first_email(tmp, i);
138                 mvwaddnstr(list, line, EMAILPOS, tmp,
139                         bytes2width(tmp, real_emaillen));
140         }
141
142         if(extra < 0 || !database[i][extra])
143                 extra = extra_alternative;
144         if(extra >= 0)
145                 mvwaddnstr(list, line, EXTRAPOS,
146                         safe_str(database[i][extra]),
147                         bytes2width(safe_str(database[i][extra]), EXTRALEN));
148
149         scrollok(list, TRUE);
150         if(highlight)
151                 wstandend(list);
152 }
153         
154
155 void
156 list_headerline()
157 {
158 #if defined(A_BOLD) && defined(A_NORMAL)
159         attrset(A_BOLD);
160 #endif
161         mvaddstr(2, NAMEPOS, abook_fields[NAME].name);
162         mvaddstr(2, EMAILPOS, abook_fields[EMAIL].name);
163         if(extra_column > 0)
164                 mvaddnstr(2, EXTRAPOS, abook_fields[extra_column].name,
165                                 COLS-EXTRAPOS);
166 #if defined(A_BOLD) && defined(A_NORMAL)
167         attrset(A_NORMAL);
168 #endif
169 }
170
171 void
172 scroll_up()
173 {
174         if(curitem < 1)
175                 return;
176
177         curitem--;
178
179         refresh_list();
180 }
181
182 void
183 scroll_down()
184 {
185         if(curitem > items - 2)
186                 return;
187
188         curitem++;
189
190         refresh_list();
191 }
192
193
194 void
195 page_up()
196 {
197         if(curitem < 1)
198                 return;
199         
200         curitem = curitem == first_list_item ?
201                 ((curitem -= LIST_LINES) < 0 ? 0 : curitem) : first_list_item;
202         
203         refresh_list();
204 }
205
206 void
207 page_down()
208 {
209         if(curitem > items - 2)
210                 return;
211
212         curitem = curitem == LAST_LIST_ITEM ?
213                 ((curitem += LIST_LINES) > LAST_ITEM ? LAST_ITEM : curitem) :
214                 min(LAST_LIST_ITEM, LAST_ITEM);
215
216         refresh_list();
217 }
218
219 void
220 select_none()
221 {
222         memset(selected, 0, items);
223 }
224
225 void
226 select_all()
227 {
228         memset(selected, 1, items);
229 }
230
231 void
232 move_curitem(int direction)
233 {
234         list_item tmp;
235
236         if( curitem < 0 || curitem > LAST_ITEM )
237                 return;
238
239         itemcpy(tmp, database[curitem]);
240
241         switch(direction) {
242                 case MOVE_ITEM_UP:
243                         if( curitem < 1 )
244                                 return;
245                         itemcpy(database[curitem], database[curitem - 1]);
246                         itemcpy(database[curitem-1], tmp);
247                         scroll_up();
248                         break;
249
250                 case MOVE_ITEM_DOWN:
251                         if( curitem >= LAST_ITEM )
252                                 return;
253                         itemcpy(database[curitem], database[curitem + 1]);
254                         itemcpy(database[curitem+1], tmp);
255                         scroll_down();
256                         break;
257         }
258 }
259
260 void
261 goto_home()
262 {
263         if(items > 0)
264                 curitem = 0;
265         
266         refresh_list();
267 }
268
269 void
270 goto_end()
271 {
272         if(items > 0)
273                 curitem = LAST_ITEM;
274
275         refresh_list();
276 }
277
278
279 void
280 highlight_line(WINDOW *win, int line)
281 {
282         wstandout(win);
283
284         /*
285          * this is a tricky one
286          */
287 #if 0
288 /*#ifdef mvwchgat*/
289         mvwchgat(win, line, 0, -1,  A_STANDOUT, 0, NULL);
290 #else
291         /*
292          * buggy function: FIXME
293          */
294         scrollok(win, FALSE);
295         {
296                 int i;
297                 wmove(win, line, 0);
298                 for(i = 0; i < COLS; i++)
299                         waddch(win, ' ');
300         /*wattrset(win, 0);*/
301         }
302         scrollok(win, TRUE);
303 #endif
304 }
305
306 int
307 selected_items()
308 {
309         int i, n = 0;
310
311         for(i = 0; i < items; i++)
312                 if(selected[i])
313                         n++;
314
315         return n;
316 }
317
318 void
319 invert_selection()
320 {
321         int i;
322
323         if(items < 1)
324                 return;
325
326         for(i = 0; i < items; i++)
327                 selected[i] = !selected[i];
328 }
329
330 int
331 list_current_item()
332 {
333         return curitem;
334 }
335
336 int
337 list_is_empty()
338 {
339         return items < 1;
340 }
341
342 int
343 duplicate_item()
344 {
345         int i;
346         list_item item;
347
348         if(curitem < 0)
349                 return 1;
350
351         for(i = 0; i < ITEM_FIELDS; i++)
352                 item[i] = database[curitem][i] ? strdup(database[curitem][i]) :
353                         NULL;
354
355         if(add_item2database(item))
356                 return 1;
357
358         curitem = LAST_ITEM;
359         refresh_list();
360
361         return 0;
362 }
363