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