#include #include #include #include #include #ifdef unix /* #include */ #else #include #include #endif #define MAXMENUITEMS 256 #define KEY_ESCAPE 27 #define KEY_RETURN 13 #define MAXCOLS 80 #define MAXPOLJA 128 #define MAXFORMAT 80 #define MAXBUF 4096 struct { char item[MAXCOLS]; int row; int col; char klett; char action[MAXCOLS]; } menu[MAXMENUITEMS]; int nitems; struct { int x; int y; char format[MAXFORMAT+1]; int duljinad; char tekst[MAXFORMAT+1]; } maska[MAXPOLJA]; int npolja = 0, ukupno = 0; char zapis[MAXBUF+1]; FILE *fi, *fdtext, *fdbin, *fdmask; /* void tracex(char *fmt, ...) { FILE *fp; va_list argptr; if ((fp = fopen("trace", "a")) != NULL) { va_start (argptr, fmt); (void) vfprintf (fp, fmt, argptr); va_end (argptr); fclose(fp); } }*/ void initcurses (void) { #ifdef unix WINDOW *win; win = initscr (); keypad (win, 1); #else initscr (); #endif raw (); cbreak (); noecho (); nonl (); } void endcurses (void) { clear (); refresh (); endwin (); #ifdef unix /* delscreen (); */ #endif } void activate (int iitem) { move (menu[iitem].row, menu[iitem].col); attron (A_REVERSE); addstr (menu[iitem].item); attroff (A_REVERSE); move (menu[iitem].row, menu[iitem].col); refresh (); } void deactivate (int iitem) { move (menu[iitem].row, menu[iitem].col); addstr (menu[iitem].item); move (menu[iitem].row, menu[iitem].col); refresh (); } void repaint (int iitem) { int i; for (i = 0; i < nitems; i++) { move (menu[i].row, menu[i].col); addstr (menu[i].item); } activate (iitem); } void translate (char *source, char *s1, char *s2) { char *start; int ilen1, ilen2; if ((start = strstr (source, s1)) == NULL) return; ilen1 = strlen (s1); ilen2 = strlen (s2); memmove (start + ilen2, start + ilen1, strlen (start + ilen1) + 1); memcpy (start, s2, ilen2); return; } void prikaz(FILE *fdtext, FILE *fdmask) { if (fread (zapis, ukupno, 1, fi) == 1) { int i, poz; int varint; long varlong; float varfloat; double vardouble; char polje[MAXFORMAT]; // sscanf ("97.", "%lf", &vardouble); clear (); for (i = 0, poz = 0; i < npolja; i++) { /* ne moze zbog call by value! printf (maska[i].format, &zapis[poz]); */ if (strstr (maska[i].format, "ld")) { memcpy (&varlong, &zapis[poz], sizeof (long)); sprintf (polje, maska[i].format, varlong); } else if (strstr (maska[i].format, "d")) { memcpy (&varint, &zapis[poz], sizeof (int)); sprintf (polje, maska[i].format, varint); } else if (strstr (maska[i].format, "lf")) { memcpy (&vardouble, &zapis[poz], sizeof (double)); sprintf (polje, maska[i].format, vardouble); } else if (strstr (maska[i].format, "f")) { memcpy (&varfloat, &zapis[poz], sizeof (float)); sprintf (polje, maska[i].format, varfloat); } else { sprintf (polje, maska[i].format, &zapis[poz]); } move (maska[i].x, maska[i].y); addstr (maska[i].tekst); addstr (" "); addstr (polje); poz += maska[i].duljinad; } } else addstr("Nema vishe zapisa!\n"); endcurses(); } void prepisi(FILE *fdtext, FILE *fdbin, FILE *fdmask) {} void nadjiduzinu(FILE *fdmask) { while (npolja < MAXPOLJA && fscanf (fdmask, "%d %d %s %d %80[^\n]", &maska[npolja].x, &maska[npolja].y, maska[npolja].format, &maska[npolja].duljinad, maska[npolja].tekst) == 5) { translate (maska[npolja].format, "\\n", "\n"); ukupno += maska[npolja].duljinad; npolja++; } } void execute (int iitem) { endcurses (); if (!strcmp(menu[iitem].action, "kraj")) exit(0); else if (!strcmp(menu[iitem].action, "prvi")) { fseek(fdtext, 0, SEEK_SET); prikaz(fdbin, fdmask); } else if (!strcmp(menu[iitem].action, "slijedeci")) prikaz(fdbin, fdmask); else if (!strcmp(menu[iitem].action, "prijepis")) prepisi(fdtext, fdbin, fdmask); else if (!strcmp(menu[iitem].action, "prethodni")) { fseek(fdtext, -2*ukupno, SEEK_CUR); prikaz(fdbin, fdmask); } else if (!strcmp(menu[iitem].action, "zadnji")) { fseek(fdtext, -1*ukupno, SEEK_END); prikaz(fdbin, fdmask); } else system(menu[iitem].action); initcurses (); repaint (iitem); } int main (int argc, char *argv[]) { int i, j, c; /* ime datoteke u kojoj je define menija (menu.def) */ fi = fopen (argv[1], "r"); /* ime textualne izlazne datoteke (slijedna) */ fdtext=fopen(argv[2], "w"); /* ime binarne ulazne dadoteke (binarna) */ fdbin=fopen(argv[3], "rb"); /* ime ulazne maske za list i prijepis (maska) */ fdmask=fopen(argv[4], "r"); nadjiduzinu(fdmask); if (!fi || !fdbin || !fdmask || !fdtext) { fprintf (stderr, "Ne mogu otvoriti dadoteku.\n"); exit (1); } nitems = 0; while (nitems < MAXMENUITEMS && fscanf (fi, "%d#%d#%c#%80[^#]%*c%80[^\n]%*c", &menu[nitems].row, &menu[nitems].col, &menu[nitems].klett, menu[nitems].item, menu[nitems].action) > 0) { /* tracex ("%d %d %c %s %s\n", menu[nitems].row, menu[nitems].col, menu[nitems].klett, menu[nitems].item, menu[nitems].action); */ nitems++; } initcurses (); i = 0; repaint (i); while (1) { c = getch (); #ifndef unix if (c == 0 ) c = 255+getch (); #endif switch (c) { case KEY_ESCAPE: endcurses (); exit (1); case KEY_DOWN: /* down */ deactivate (i); i = (i + 1) % nitems; activate (i); break; case KEY_UP: /* up */ deactivate (i); if (i == 0) i = nitems - 1; else i--; activate (i); break; case KEY_RETURN: execute (i); break; default: /* klett */ for (j = 0; j < nitems; j++) { if (toupper(menu[j].klett) == toupper(c)) { deactivate (i); i = j; activate (i); execute (i); break; } } } } }