1 /*
2 * rolo - contact management software
3 * Copyright (C) 2003 Andrew Hsu
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 * 02111-1307 USA
19 *
20 * $Id: view.c,v 1.15 2003/05/20 01:08:52 ahsu Rel $
21 */
22
23 #include "view.h"
24 #include <assert.h>
25 #include <limits.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/stat.h>
30 #include <sys/types.h>
31
32 #define MENU_BAR_STRING "i:Index h:Help 1:Ident 2:Geo 3:Tel 4:Org 5:Misc"
33 #define HEADING_IDENT_STRING "IDENTIFICATION"
34 #define HEADING_GEO_STRING "GEOGRAPHIC POSITION"
35 #define HEADING_TEL_STRING "TELECOMMUNICATION"
36 #define HEADING_ORG_STRING "ORGANIZATION"
37 #define HEADING_MISC_STRING "MISCELLANEOUS"
38
39 /*** PROTOTYPES ***/
40 static void print_header ();
41 static void print_footer (int entry_number, const char *fn);
42 static void view_ident ();
43 static void view_geo ();
44 static void view_tel ();
45 static void view_org ();
46 static void view_misc ();
47 static char *basename (const char *path);
48 static void view_left ();
49 static void view_right ();
50
51 enum view_modes
52 { VIEW_IDENT = 1, VIEW_GEO, VIEW_TEL, VIEW_ORG, VIEW_MISC };
53
54 /*** STATIC VARIABLES ***/
55 static WINDOW *win = NULL;
56 static WINDOW *sub = NULL;
57 static void (*display_help) (void);
58 static vc_component *g_v = NULL;
59 static int g_mode = 1;
60
61 /***************************************************************************
62 */
63
64 static void
view_left()65 view_left ()
66 {
67 switch (g_mode)
68 {
69 case VIEW_IDENT:
70 view_misc ();
71 break;
72 case VIEW_GEO:
73 view_ident ();
74 break;
75 case VIEW_TEL:
76 view_geo ();
77 break;
78 case VIEW_ORG:
79 view_tel ();
80 break;
81 case VIEW_MISC:
82 view_org ();
83 break;
84 default:
85 break;
86 }
87 }
88
89 /***************************************************************************
90 */
91
92 static void
view_right()93 view_right ()
94 {
95 switch (g_mode)
96 {
97 case VIEW_IDENT:
98 view_geo ();
99 break;
100 case VIEW_GEO:
101 view_tel ();
102 break;
103 case VIEW_TEL:
104 view_org ();
105 break;
106 case VIEW_ORG:
107 view_misc ();
108 break;
109 case VIEW_MISC:
110 view_ident ();
111 break;
112 default:
113 break;
114 }
115 }
116
117 /***************************************************************************
118 Initialize the view window without displaying it to the
119 end-user.
120 */
121
122 void
init_view()123 init_view ()
124 {
125 win = newwin (0, 0, 0, 0);
126 sub = derwin (win, LINES - 3, COLS, 1, 0);
127 print_header ();
128 keypad (win, TRUE); /* enable keypad for use of arrow keys */
129 }
130
131 /***************************************************************************
132 */
133
134 static char *
basename(const char * path)135 basename (const char *path)
136 {
137 char *beginning = NULL;
138 char *retval = NULL;
139
140 beginning = strrchr (path, '/');
141
142 if (NULL == beginning)
143 {
144 retval = strdup (path);
145 }
146 else
147 {
148 retval = strdup (beginning);
149 }
150
151 return retval;
152 }
153
154 /***************************************************************************
155 */
156
157 static void
view_ident()158 view_ident ()
159 {
160 vc_component *vc = NULL;
161 char *val = NULL;
162 int x = 0;
163 int y = 0;
164
165 g_mode = VIEW_IDENT;
166
167 werase (sub);
168
169 x = (COLS - strlen (HEADING_IDENT_STRING)) / 2;
170 y = 1;
171
172 wattron (sub, A_UNDERLINE);
173 mvwprintw (sub, y, x, HEADING_IDENT_STRING);
174 wstandend (sub);
175 wmove (sub, 3, 0);
176
177 vc = vc_get_next_by_name (g_v, VC_FORMATTED_NAME);
178 val = vc_get_value (vc);
179 wprintw (sub, "Name : %s\n", val ? val : "");
180
181 vc = vc_get_next_by_name (g_v, VC_NICKNAME);
182 val = vc_get_value (vc);
183 wprintw (sub, "Nickname : %s\n", val ? val : "");
184
185 vc = vc_get_next_by_name (g_v, VC_BIRTHDAY);
186 val = vc_get_value (vc);
187 wprintw (sub, "Birthday : %s\n", val ? val : "");
188
189 wprintw (sub, "\n");
190
191 vc = vc_get_next_by_name (g_v, VC_URL);
192 val = vc_get_value (vc);
193 wprintw (sub, "URL : %s\n", val ? val : "");
194
195 vc = vc_get_next_by_name (g_v, VC_PHOTO);
196 val = vc_get_value (vc);
197 wprintw (sub, "Photo : %s\n", val ? val : "");
198
199 vc = vc_get_next_by_name (g_v, VC_SOUND);
200 val = vc_get_value (vc);
201 wprintw (sub, "Sound : %s\n", val ? val : "");
202
203 wprintw (sub, "\n");
204
205 vc = vc_get_next_by_name (g_v, VC_CATEGORIES);
206 val = vc_get_value (vc);
207 wprintw (sub, "Categories : %s\n", val ? val : "");
208
209 vc = vc_get_next_by_name (g_v, VC_REVISION);
210 val = vc_get_value (vc);
211 wprintw (sub, "Revision : %s\n", val ? val : "");
212
213 vc = vc_get_next_by_name (g_v, VC_NOTE);
214 val = vc_get_value (vc);
215 wprintw (sub, "Note : %s\n", val ? val : "");
216
217 touchwin (win);
218 wrefresh (sub);
219 wrefresh (win);
220 }
221
222 /***************************************************************************
223 */
224
225 static void
view_geo()226 view_geo ()
227 {
228 vc_component *vc = NULL;
229 char *str = NULL;
230 char *val = NULL;
231 int x = 0;
232 int y = 0;
233
234 g_mode = VIEW_GEO;
235
236 werase (sub);
237
238 x = (COLS - strlen (HEADING_GEO_STRING)) / 2;
239 y = 1;
240
241 wattron (sub, A_UNDERLINE);
242 mvwprintw (sub, y, x, HEADING_GEO_STRING);
243 wstandend (sub);
244 wmove (sub, 3, 0);
245
246 vc = vc_get_next_by_name (g_v, VC_GEOGRAPHIC_POSITION);
247 val = vc_get_value (vc);
248
249 str = get_val_struct_part (val, GEO_LATITUDE);
250 wprintw (sub, "Latitude : %s\n", str ? str : "");
251 free (str);
252
253 str = get_val_struct_part (val, GEO_LONGITUDE);
254 wprintw (sub, "Longitude : %s\n", str ? str : "");
255 free (str);
256
257 wprintw (sub, "\n");
258 vc = vc_get_next_by_name (g_v, VC_TIME_ZONE);
259 val = vc_get_value (vc);
260 wprintw (sub, "Time Zone : %s\n", val ? val : "");
261
262 wprintw (sub, "\n");
263
264 vc = vc_get_next_by_name (g_v, VC_ADDRESS);
265 val = vc_get_value (vc);
266
267 str = get_val_struct_part (val, ADR_PO_BOX);
268 wprintw (sub, "Post Office Box : %s\n", str ? str : "");
269 free (str);
270
271 str = get_val_struct_part (val, ADR_EXT_ADDRESS);
272 wprintw (sub, "Extended Address : %s\n", str ? str : "");
273 free (str);
274
275 str = get_val_struct_part (val, ADR_STREET);
276 wprintw (sub, "Street Address : %s\n", str ? str : "");
277 free (str);
278
279 str = get_val_struct_part (val, ADR_LOCALITY);
280 wprintw (sub, "Locality : %s\n", str ? str : "");
281 free (str);
282
283 str = get_val_struct_part (val, ADR_REGION);
284 wprintw (sub, "Region : %s\n", str ? str : "");
285 free (str);
286
287 str = get_val_struct_part (val, ADR_POSTAL_CODE);
288 wprintw (sub, "Postal Code : %s\n", str ? str : "");
289 free (str);
290
291 str = get_val_struct_part (val, ADR_COUNTRY);
292 wprintw (sub, "Country : %s\n", str ? str : "");
293 free (str);
294
295 wprintw (sub, "\n");
296 touchwin (win);
297 wrefresh (sub);
298 wrefresh (win);
299 }
300
301 /***************************************************************************
302 */
303
304 static void
view_tel()305 view_tel ()
306 {
307 vc_component *vc = NULL;
308 char *val = NULL;
309 int x = 0;
310 int y = 0;
311 int i = 0;
312
313 g_mode = VIEW_TEL;
314
315 werase (sub);
316
317 x = (COLS - strlen (HEADING_TEL_STRING)) / 2;
318 y = 1;
319
320 wattron (sub, A_UNDERLINE);
321 mvwprintw (sub, y, x, HEADING_TEL_STRING);
322 wstandend (sub);
323 wmove (sub, 3, 0);
324
325 for (i = 1, vc = g_v; i <= 5; i++)
326 {
327 vc = vc_get_next_by_name (vc, VC_TELEPHONE);
328 val = vc_get_value (vc);
329 wprintw (sub, "Telephone #%i : %s\n", i, val ? val : "");
330 }
331
332 wprintw (sub, "\n");
333
334 for (i = 1, vc = g_v; i <= 5; i++)
335 {
336 vc = vc_get_next_by_name (vc, VC_EMAIL);
337 val = vc_get_value (vc);
338 wprintw (sub, "Email Address #%i : %s\n", i, val ? val : "");
339 }
340
341 wprintw (sub, "\n");
342
343 vc = vc_get_next_by_name (g_v, VC_MAILER);
344 val = vc_get_value (vc);
345 wprintw (sub, "Email Mailer : %s\n", val ? val : "");
346
347 touchwin (win);
348 wrefresh (sub);
349 wrefresh (win);
350 }
351
352 /***************************************************************************
353 */
354
355 static void
view_org()356 view_org ()
357 {
358 vc_component *vc = NULL;
359 char *str = NULL;
360 char *val = NULL;
361 int x = 0;
362 int y = 0;
363
364 g_mode = VIEW_ORG;
365
366 werase (sub);
367
368 x = (COLS - strlen (HEADING_ORG_STRING)) / 2;
369 y = 1;
370
371 wattron (sub, A_UNDERLINE);
372 mvwprintw (sub, y, x, HEADING_ORG_STRING);
373 wstandend (sub);
374 wmove (sub, 3, 0);
375
376 vc = vc_get_next_by_name (g_v, VC_TITLE);
377 val = vc_get_value (vc);
378 wprintw (sub, "Title : %s\n", val ? val : "");
379
380 vc = vc_get_next_by_name (g_v, VC_ROLE);
381 val = vc_get_value (vc);
382 wprintw (sub, "Role : %s\n", val ? val : "");
383
384 wprintw (sub, "\n");
385
386 vc = vc_get_next_by_name (g_v, VC_ORGANIZATION);
387 val = vc_get_value (vc);
388
389 str = get_val_struct_part (val, ORG_NAME);
390 wprintw (sub, "Organization Name : %s\n", str ? str : "");
391 free (str);
392
393 str = get_val_struct_part (val, ORG_UNIT_1);
394 wprintw (sub, "Organizational Unit #1 : %s\n", str ? str : "");
395 free (str);
396
397 str = get_val_struct_part (val, ORG_UNIT_2);
398 wprintw (sub, "Organizational Unit #2 : %s\n", str ? str : "");
399 free (str);
400
401 str = get_val_struct_part (val, ORG_UNIT_3);
402 wprintw (sub, "Organizational Unit #3 : %s\n", str ? str : "");
403 free (str);
404
405 str = get_val_struct_part (val, ORG_UNIT_4);
406 wprintw (sub, "Organizational Unit #4 : %s\n", str ? str : "");
407 free (str);
408
409 wprintw (sub, "\n");
410
411 vc = vc_get_next_by_name (g_v, VC_LOGO);
412 val = vc_get_value (vc);
413 wprintw (sub, "Logo : %s\n", val ? val : "");
414
415 vc = vc_get_next_by_name (g_v, VC_AGENT);
416 val = vc_get_value (vc);
417 wprintw (sub, "Agent : %s\n", val ? val : "");
418
419 touchwin (win);
420 wrefresh (sub);
421 wrefresh (win);
422 }
423
424 /***************************************************************************
425 */
426
427 static void
view_misc()428 view_misc ()
429 {
430 vc_component *vc = NULL;
431 char *str = NULL;
432 char *val = NULL;
433 int x = 0;
434 int y = 0;
435
436 g_mode = VIEW_MISC;
437
438 werase (sub);
439
440 x = (COLS - strlen (HEADING_MISC_STRING)) / 2;
441 y = 1;
442
443 wattron (sub, A_UNDERLINE);
444 mvwprintw (sub, y, x, HEADING_MISC_STRING);
445 wstandend (sub);
446 wmove (sub, 3, 0);
447
448 vc = vc_get_next_by_name (g_v, VC_SORT_STRING);
449 val = vc_get_value (vc);
450 wprintw (sub, "Sort String : %s\n", val ? val : "");
451
452 vc = vc_get_next_by_name (g_v, VC_CLASS);
453 val = vc_get_value (vc);
454 wprintw (sub, "Class : %s\n", val ? val : "");
455
456 vc = vc_get_next_by_name (g_v, VC_KEY);
457 val = vc_get_value (vc);
458 wprintw (sub, "Public Key : %s\n", val ? val : "");
459
460 touchwin (win);
461 wrefresh (sub);
462 wrefresh (win);
463 }
464
465 /***************************************************************************
466 Display the given vCard to the end-user.
467 */
468
469 void
view_vcard(int entry_number,vc_component * v)470 view_vcard (int entry_number, vc_component * v)
471 {
472 vc_component *vc = NULL;
473 char *val = NULL;
474
475 g_v = v;
476
477 vc = vc_get_next_by_name (g_v, VC_FORMATTED_NAME);
478 val = vc_get_value (vc);
479 print_footer (entry_number, val ? val : "");
480
481 switch (g_mode)
482 {
483 case VIEW_IDENT:
484 view_ident ();
485 break;
486 case VIEW_GEO:
487 view_geo ();
488 break;
489 case VIEW_TEL:
490 view_tel ();
491 break;
492 case VIEW_ORG:
493 view_org ();
494 break;
495 case VIEW_MISC:
496 view_misc ();
497 break;
498 default:
499 break;
500 }
501
502 }
503
504 /***************************************************************************
505 Prints the header to the window buffer, but does not display it
506 to the end-user.
507 */
508
509 static void
print_header()510 print_header ()
511 {
512 char *header_str = NULL;
513 int i = 0;
514
515 header_str = (char *) malloc (sizeof (char) * (COLS + 2));
516
517 strncpy (header_str, MENU_BAR_STRING, COLS);
518
519 for (i = strlen (MENU_BAR_STRING); i < COLS; i++)
520 {
521 header_str[i] = ' ';
522 }
523
524 header_str[COLS] = '\n';
525 header_str[COLS + 1] = '\0';
526
527 wattron (win, A_REVERSE);
528 wprintw (win, header_str);
529 wstandend (win);
530 free (header_str);
531 }
532
533 /***************************************************************************
534 Prints the footer to the window buffer, but does not display it
535 to the end-user. The contents of the footer depends on the
536 width of the screen.
537 */
538
539 static void
print_footer(int entry_number,const char * fn)540 print_footer (int entry_number, const char *fn)
541 {
542 char *footer_str = NULL;
543 char *entry_block = NULL;
544 int entry_block_len = 0;
545 int i = 0;
546
547 footer_str = (char *) malloc (sizeof (char) * (COLS + 2));
548
549 /****************************************
550 initialize the footer string to dashes
551 ****************************************/
552
553 for (i = 0; i < COLS; i++)
554 {
555 footer_str[i] = '-';
556 }
557
558 if (NULL != fn)
559 {
560 entry_block_len = strlen (fn) + 18 + 3; /* 3 for entry_number */
561 }
562 else
563 {
564 entry_block_len = 17 + 3; /* 3 for entry_number */
565 }
566
567 /****************************************************
568 add the `entry' block only if there is enough room
569 ****************************************************/
570
571 if (entry_block_len <= COLS)
572 {
573 entry_block = (char *) malloc (sizeof (char) * (entry_block_len + 1));
574
575 if (NULL != fn)
576 {
577 sprintf (entry_block, "---[ entry %i: %s ]---", entry_number % 1000,
578 fn);
579 }
580 else
581 {
582 sprintf (entry_block, "---[ entry %i ]---", entry_number % 1000);
583 }
584
585 entry_block_len = strlen (entry_block);
586 for (i = 0; i < entry_block_len; i++)
587 {
588 footer_str[i] = entry_block[i];
589 }
590
591 free (entry_block);
592 }
593
594 footer_str[COLS] = '\n';
595 footer_str[COLS + 1] = '\0';
596
597 wattron (win, A_REVERSE);
598 mvwprintw (win, LINES - 2, 0, footer_str);
599 wstandend (win);
600 free (footer_str);
601 }
602
603 /***************************************************************************
604 Handle input from the end-user.
605 */
606
607 int
process_view_commands()608 process_view_commands ()
609 {
610 bool done = FALSE;
611 int ch = 0;
612 int command = 0;
613
614 while (!done)
615 {
616 ch = wgetch (win);
617
618 switch (ch)
619 {
620 case '1':
621 view_ident ();
622 break;
623 case '2':
624 view_geo ();
625 break;
626 case '3':
627 view_tel ();
628 break;
629 case '4':
630 view_org ();
631 break;
632 case '5':
633 view_misc ();
634 break;
635 case KEY_DOWN:
636 case 'j':
637 command = VIEW_COMMAND_NEXT;
638 done = TRUE;
639 break;
640 case KEY_UP:
641 case 'k':
642 command = VIEW_COMMAND_PREVIOUS;
643 done = TRUE;
644 break;
645 case 'e':
646 command = VIEW_COMMAND_EDIT;
647 done = TRUE;
648 break;
649 case 'h':
650 (*display_help) ();
651 touchwin (win);
652 wrefresh (win);
653 wrefresh (sub);
654 break;
655 case 'i':
656 case 'q':
657 command = VIEW_COMMAND_INDEX;
658 g_mode = VIEW_IDENT;
659 done = TRUE;
660 break;
661 case 'V':
662 raw_view (g_v);
663 break;
664 case KEY_LEFT:
665 view_left ();
666 break;
667 case KEY_RIGHT:
668 view_right ();
669 break;
670 default:
671 beep ();
672 break;
673 }
674 }
675 return command;
676 }
677
678 /***************************************************************************
679 */
680
681 void
set_view_help_fcn(void (* fcn)(void))682 set_view_help_fcn (void (*fcn) (void))
683 {
684 display_help = fcn;
685 }
686
687 /***************************************************************************
688 */
689
690 void
raw_view(const vc_component * v)691 raw_view (const vc_component * v)
692 {
693 /* FIXME: have a simple scrolling raw display of the vcard */
694 }
695