]> git.deb.at Git - pkg/abook.git/blob - list.c
Support for dynamic views.
[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 int items;
32 extern abook_field_list *fields_list;
33
34 static WINDOW *list = NULL;
35
36
37 int
38 init_extra_field(enum str_opts option)
39 {
40         int ret = -1;
41         char *option_str;
42
43         option_str = opt_get_str(option);
44
45         if(option_str && *option_str) {
46                 find_field_number(option_str, &ret);
47
48                 if(!strcmp(option_str, "name") || !strcmp(option_str, "email"))
49                         ret = -1;
50         }
51
52         return ret;
53 }
54
55 void
56 init_list()
57 {
58         list = newwin(LIST_LINES, LIST_COLS, LIST_TOP, 0);
59         scrollok(list, TRUE);
60
61         /*
62          * init extra_column and extra alternative
63          */
64
65         extra_column = init_extra_field(STR_EXTRA_COLUMN);
66         extra_alternative = init_extra_field(STR_EXTRA_ALTERNATIVE);
67 }
68
69 void
70 close_list()
71 {
72         delwin(list);
73         list = NULL;
74 }
75
76 void
77 refresh_list()
78 {
79         int i, line;
80
81         werase(list);
82
83         ui_print_number_of_items();
84
85         if(list_is_empty()) {
86                 refresh();
87                 wrefresh(list);
88                 return;
89         }
90
91         if(curitem < 0)
92                 curitem = 0;
93
94         if(first_list_item < 0)
95                 first_list_item = 0;
96
97         if(curitem < first_list_item)
98                 first_list_item = curitem;
99         else if(curitem > LAST_LIST_ITEM)
100                 first_list_item = max(curitem - LIST_LINES + 1, 0);
101
102         for( line = 0, i = first_list_item ; i <= LAST_LIST_ITEM && i < 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 > 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 > items - 2)
216                 return;
217
218         curitem = curitem == LAST_LIST_ITEM ?
219                 ((curitem += LIST_LINES) > LAST_ITEM ? LAST_ITEM : curitem) :
220                 min(LAST_LIST_ITEM, LAST_ITEM);
221
222         refresh_list();
223 }
224
225 void
226 select_none()
227 {
228         memset(selected, 0, items);
229 }
230
231 void
232 select_all()
233 {
234         memset(selected, 1, items);
235 }
236
237 void
238 move_curitem(int direction)
239 {
240         list_item tmp;
241
242         if( curitem < 0 || curitem > LAST_ITEM )
243                 return;
244
245         tmp = item_create();
246         item_copy(tmp, db_item_get(curitem));
247
248         switch(direction) {
249                 case MOVE_ITEM_UP:
250                         if( curitem < 1 )
251                                 goto out_move;
252                         item_copy(db_item_get(curitem),
253                                         db_item_get(curitem - 1));
254                         item_copy(db_item_get(curitem-1), tmp);
255                         scroll_up();
256                         break;
257
258                 case MOVE_ITEM_DOWN:
259                         if( curitem >= LAST_ITEM )
260                                 goto out_move;
261                         item_copy(db_item_get(curitem),
262                                         db_item_get(curitem + 1));
263                         item_copy(db_item_get(curitem + 1), tmp);
264                         scroll_down();
265                         break;
266         }
267
268 out_move:
269         item_free(&tmp);
270 }
271
272 void
273 goto_home()
274 {
275         if(items > 0)
276                 curitem = 0;
277
278         refresh_list();
279 }
280
281 void
282 goto_end()
283 {
284         if(items > 0)
285                 curitem = LAST_ITEM;
286
287         refresh_list();
288 }
289
290 void
291 highlight_line(WINDOW *win, int line)
292 {
293         wstandout(win);
294
295         /*
296          * this is a tricky one
297          */
298 #if 0
299 /*#ifdef mvwchgat*/
300         mvwchgat(win, line, 0, -1,  A_STANDOUT, 0, NULL);
301 #else
302         /*
303          * buggy function: FIXME
304          */
305         scrollok(win, FALSE);
306         {
307                 int i;
308                 wmove(win, line, 0);
309                 for(i = 0; i < COLS; i++)
310                         waddch(win, ' ');
311         /*wattrset(win, 0);*/
312         }
313         scrollok(win, TRUE);
314 #endif
315 }
316
317 int
318 selected_items()
319 {
320         int i, n = 0;
321
322         for(i = 0; i < items; i++)
323                 if(selected[i])
324                         n++;
325
326         return n;
327 }
328
329 void
330 invert_selection()
331 {
332         int i;
333
334         if(items < 1)
335                 return;
336
337         for(i = 0; i < items; i++)
338                 selected[i] = !selected[i];
339 }
340
341 int
342 list_current_item()
343 {
344         return curitem;
345 }
346
347 int
348 list_is_empty()
349 {
350         return items < 1;
351 }
352
353 int
354 duplicate_item()
355 {
356         list_item item;
357         
358         if(curitem < 0)
359                 return 1;
360
361         item = item_create();
362         item_duplicate(item, db_item_get(curitem));
363         if(add_item2database(item)) {
364                 item_free(&item);
365                 return 1;
366         }
367         item_free(&item);
368
369         curitem = LAST_ITEM;
370         refresh_list();
371
372         return 0;
373 }
374