1 /****************************************************************************
2 * Copyright (c) 1999-2002,2003 Free Software Foundation, Inc. *
4 * Permission is hereby granted, free of charge, to any person obtaining a *
5 * copy of this software and associated documentation files (the *
6 * "Software"), to deal in the Software without restriction, including *
7 * without limitation the rights to use, copy, modify, merge, publish, *
8 * distribute, distribute with modifications, sublicense, and/or sell *
9 * copies of the Software, and to permit persons to whom the Software is *
10 * furnished to do so, subject to the following conditions: *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
23 * Except as contained in this notice, the name(s) of the above copyright *
24 * holders shall not be used in advertising or otherwise to promote the *
25 * sale, use or other dealings in this Software without prior written *
27 ****************************************************************************/
30 * Author: Thomas E. Dickey <dickey@clark.net> 1999
32 * $Id: cardfile.c,v 1.23 2003/04/26 16:43:56 tom Exp $
34 * File format: text beginning in column 1 is a title; other text is content.
37 #include <test.priv.h>
39 #if USE_LIBFORM && USE_LIBPANEL
44 #define VISIBLE_CARDS 10
48 MY_CTRL_x
= MAX_FORM_COMMAND
55 typedef struct _card
{
63 static CARD
*all_cards
;
64 static char default_name
[] = "cardfile.dat";
67 #define strdup my_strdup
71 char *p
= (char *) malloc(strlen(s
) + 1);
76 #endif /* not HAVE_STRDUP */
79 skip(const char *buffer
)
81 while (isspace(UChar(*buffer
)))
89 unsigned n
= strlen(buffer
);
90 while (n
-- && isspace(UChar(buffer
[n
])))
94 /*******************************************************************************/
97 add_title(const char *title
)
101 for (p
= all_cards
, q
= 0; p
!= 0; q
= p
, p
= p
->link
) {
102 int cmp
= strcmp(p
->title
, title
);
109 card
= (CARD
*) calloc(1, sizeof(CARD
));
110 card
->title
= strdup(title
);
111 card
->content
= strdup("");
114 card
->link
= all_cards
;
117 card
->link
= q
->link
;
125 add_content(CARD
* card
, const char *content
)
127 unsigned total
, offset
;
129 content
= skip(content
);
130 if ((total
= strlen(content
)) != 0) {
131 if ((offset
= strlen(card
->content
)) != 0) {
133 card
->content
= (char *) realloc(card
->content
, total
+ 1);
134 strcpy(card
->content
+ offset
++, " ");
136 if (card
->content
!= 0)
138 card
->content
= (char *) malloc(total
+ 1);
140 strcpy(card
->content
+ offset
, content
);
147 CARD
*card
= add_title("");
148 add_content(card
, "");
153 find_card(char *title
)
157 for (card
= all_cards
; card
!= 0; card
= card
->link
)
158 if (!strcmp(card
->title
, title
))
165 read_data(char *fname
)
171 if ((fp
= fopen(fname
, "r")) != 0) {
172 while (fgets(buffer
, sizeof(buffer
), fp
)) {
174 if (isspace(UChar(*buffer
))) {
176 card
= add_title("");
177 add_content(card
, buffer
);
178 } else if ((card
= find_card(buffer
)) == 0) {
179 card
= add_title(buffer
);
186 /*******************************************************************************/
189 write_data(const char *fname
)
195 if (!strcmp(fname
, default_name
))
196 fname
= "cardfile.out";
198 if ((fp
= fopen(fname
, "w")) != 0) {
199 for (p
= all_cards
; p
!= 0; p
= p
->link
) {
200 FIELD
**f
= form_fields(p
->form
);
201 for (n
= 0; f
[n
] != 0; n
++) {
202 char *s
= field_buffer(f
[n
], 0);
204 && (s
= strdup(s
)) != 0) {
206 fprintf(fp
, "%s%s\n", n
? "\t" : "", s
);
215 /*******************************************************************************/
226 for (p
= all_cards
; p
!= 0; p
= p
->link
)
233 * Shuffle the panels to keep them in a natural hierarchy.
236 order_cards(CARD
* first
, int depth
)
239 if (depth
&& first
->link
)
240 order_cards(first
->link
, depth
- 1);
241 top_panel(first
->panel
);
246 * Return the next card in the list
249 next_card(CARD
* now
)
257 * Return the previous card in the list
260 prev_card(CARD
* now
)
263 for (p
= all_cards
; p
!= 0; p
= p
->link
)
269 /*******************************************************************************/
272 form_virtualize(WINDOW
*w
)
288 return (REQ_DEL_PREV
);
290 return (REQ_DEL_CHAR
);
292 return (REQ_LEFT_CHAR
);
294 return (REQ_RIGHT_CHAR
);
298 return (REQ_NEXT_FIELD
);
301 return (REQ_PREV_FIELD
);
309 make_fields(CARD
* p
, int form_high
, int form_wide
)
311 FIELD
**f
= (FIELD
**) calloc(3, sizeof(FIELD
*));
313 f
[0] = new_field(1, form_wide
, 0, 0, 0, 0);
314 set_field_back(f
[0], A_REVERSE
);
315 set_field_buffer(f
[0], 0, p
->title
);
316 field_opts_off(f
[0], O_BLANK
);
318 f
[1] = new_field(form_high
- 1, form_wide
, 1, 0, 0, 0);
319 set_field_buffer(f
[1], 0, p
->content
);
320 set_field_just(f
[1], JUSTIFY_LEFT
);
321 field_opts_off(f
[1], O_BLANK
);
332 addstr("^Q/ESC -- exit form ^W -- writes data to file\n");
333 addstr("^N -- go to next card ^P -- go to previous card\n");
334 addstr("Arrow keys move left/right within a field, up/down between fields");
337 #if (defined(KEY_RESIZE) && HAVE_WRESIZE) || NO_LEAKS
339 free_form_fields(FIELD
** f
)
343 for (n
= 0; f
[n
] != 0; ++n
) {
350 /*******************************************************************************/
353 cardfile(char *fname
)
358 int visible_cards
= count_cards();
359 int panel_wide
= COLS
- (visible_cards
* OFFSET_CARD
);
360 int panel_high
= LINES
- (visible_cards
* OFFSET_CARD
) - 5;
361 int form_wide
= panel_wide
- 2;
362 int form_high
= panel_high
- 2;
363 int y
= (visible_cards
- 1) * OFFSET_CARD
;
367 int finished
= FALSE
;
371 /* make a panel for each CARD */
372 for (p
= all_cards
; p
!= 0; p
= p
->link
) {
374 win
= newwin(panel_high
, panel_wide
, y
, x
);
376 p
->panel
= new_panel(win
);
379 p
->form
= new_form(make_fields(p
, form_high
, form_wide
));
380 set_form_win(p
->form
, win
);
381 set_form_sub(p
->form
, derwin(win
, form_high
, form_wide
, 1, 1));
388 order_cards(top_card
= all_cards
, visible_cards
);
395 ch
= form_virtualize(panel_window(top_card
->panel
));
396 switch (form_driver(top_card
->form
, ch
)) {
399 case E_UNKNOWN_COMMAND
:
405 top_card
= prev_card(top_card
);
406 order_cards(top_card
, visible_cards
);
409 top_card
= next_card(top_card
);
410 order_cards(top_card
, visible_cards
);
413 form_driver(top_card
->form
, REQ_VALIDATION
);
416 #if defined(KEY_RESIZE) && HAVE_WRESIZE
418 /* resizeterm already did "something" reasonable, but it cannot
419 * know much about layout. So let's make it nicer.
421 panel_wide
= COLS
- (visible_cards
* OFFSET_CARD
);
422 panel_high
= LINES
- (visible_cards
* OFFSET_CARD
) - 5;
424 form_wide
= panel_wide
- 2;
425 form_high
= panel_high
- 2;
427 y
= (visible_cards
- 1) * OFFSET_CARD
;
431 for (p
= all_cards
; p
!= 0; p
= p
->link
) {
432 FIELD
**oldf
= form_fields(p
->form
);
433 WINDOW
*olds
= form_sub(p
->form
);
435 win
= form_win(p
->form
);
437 /* move and resize the card as needed
438 * FIXME: if the windows are shrunk too much, this won't do
441 wresize(win
, panel_high
, panel_wide
);
443 /* reconstruct each form. Forms are not resizable, and
444 * there appears to be no good way to reload the text in
449 unpost_form(p
->form
);
452 p
->form
= new_form(make_fields(p
, form_high
, form_wide
));
453 set_form_win(p
->form
, win
);
454 set_form_sub(p
->form
, derwin(win
, form_high
, form_wide
,
458 free_form_fields(oldf
);
479 while (all_cards
!= 0) {
484 all_cards
= all_cards
->link
;
486 f
= form_fields(p
->form
);
487 count
= field_count(p
->form
);
489 unpost_form(p
->form
); /* ...so we can free it */
490 free_form(p
->form
); /* this also disconnects the fields */
502 /*******************************************************************************/
505 main(int argc
, char *argv
[])
509 setlocale(LC_ALL
, "");
516 for (n
= 1; n
< argc
; n
++)
518 if (count_cards() == 0)
522 read_data(default_name
);
523 if (count_cards() == 0)
525 cardfile(default_name
);
530 ExitProgram(EXIT_SUCCESS
);
536 printf("This program requires the curses form and panel libraries\n");
537 ExitProgram(EXIT_FAILURE
);