From 65087f82753a12e330fa0e6fc0c0e4b70c6a6c63 Mon Sep 17 00:00:00 2001 From: ache Date: Sat, 11 Nov 2017 03:57:47 +0000 Subject: PoC menu Contact --- Makefile | 2 +- basic_curses.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++ basic_curses.h | 15 +++++ contactList.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ contactList.h | 58 ++++++++++++++++++++ main.c | 31 +++++++++-- main.h | 3 + wind.c | 17 ++++-- wind.h | 5 ++ 9 files changed, 444 insertions(+), 9 deletions(-) create mode 100644 basic_curses.c create mode 100644 basic_curses.h create mode 100644 contactList.c create mode 100644 contactList.h diff --git a/Makefile b/Makefile index 17c5f37..91efb80 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ CC=gcc PROG=mesms LIBS=-lcurses -lreadline HEADERS=$(wildcard *.h) -FILES=readline.c wind.c +FILES=readline.c wind.c contactList.c basic_curses.c OBJ_FILES := $(FILES:.c=.o) CFLAGS+=-std=gnu99 diff --git a/basic_curses.c b/basic_curses.c new file mode 100644 index 0000000..1a48b8d --- /dev/null +++ b/basic_curses.c @@ -0,0 +1,152 @@ +/* + * Ache - 2017-08-14 - GPLv3 + */ + +#include "basic_curses.h" + +/* + * Set of functions to easy print on the ncurse interface + */ + + + +void printfc(char* fstrc, int max_length, ...) { + int i = 0; + int nbC = 0; + char* tmp = NULL; + int toP = 0; + + + va_list ap; + va_start(ap, max_length); + + + while(fstrc[i] && nbC < max_length) { + if( strchr( "${<%>}#", fstrc[i]) ) { + if( tmp ) { + printw("%.*s", toP, tmp); + tmp=NULL; + toP=0; + } + switch( fstrc[i] ) { + case '$': + if( fstrc[i+1] ) { + if( isdigit(fstrc[i+1]) ) { + if( fstrc[i+1] == '9') { + ; + }else + attrset( COLOR_PAIR(fstrc[i+1]-'0') | A_NORMAL); + }else{ +#ifdef DEBUG + fprintf(stderr,"%c isn't a color, skipping", fstrc[i+1]); +#endif + } + }else{ +#ifdef DEBUG + fprintf(stderr,"end of line by '$', expect a color after '$'"); +#endif + return; + } + i+=2; + break; + case '%': + { + int j = 1; + char format[10] = "%"; + while(j < 9 && !strchr("diouxXeEfFgGaAcsp%", format[j] = fstrc[i+j]) ); + if( j == 9 ) { +#ifdef DEBUG + fprintf(stderr,"format too long %s...",format); +#endif + return; + } + if( strchr("di", format[j] ) ) { + printw(format, va_arg(ap, int)); + }else if( strchr("ouxX", format[j]) ) { + printw(format, va_arg(ap, unsigned int)); + }else if( strchr("eE", format[j]) ) { + printw(format, va_arg(ap, double)); + }else if( strchr("fF", format[j]) ) { + printw(format, va_arg(ap, double)); + }else if( strchr("gG", format[j]) ) { + printw(format, va_arg(ap, double)); + }else if( strchr("aA", format[j]) ) { + printw(format, va_arg(ap, double)); + }else if( strchr("c", format[j]) ) { + printw(format, va_arg(ap, int)); + }else if( strchr("s", format[j]) ) { + printw(format, va_arg(ap, const char*)); + }else if( strchr("p", format[j]) ) { + printw(format, va_arg(ap, void*)); + }else if( strchr("%", format[j]) ) { + printw("%%"); + } +// nbC+= + + i+=j; + } + } + }else{ + if( ! tmp ) + tmp = fstrc+i; + toP += 1; + nbC++; + i++; + } + } + if(tmp) + printw("%.*s", toP, tmp); + fflush(NULL); +} + +void printc(char* fstrc, int max_length) { + int i = 0; + int nbC = 0; + char* tmp = NULL; + int toP = 0; + while(fstrc[i] && nbC < max_length) { + if( strchr( "${<>}#", fstrc[i]) ) { + if( tmp ) { + printw("%.*s", toP, tmp); + tmp=NULL; + toP=0; + } + switch( fstrc[i] ) { + case '$': + if( fstrc[i+1] ) { + if( isdigit(fstrc[i+1]) ) { + if( fstrc[i+1] == '9') { + ; + }else + attrset( COLOR_PAIR(fstrc[i+1]-'0') | A_NORMAL); + }else{ +#ifdef DEBUG + fprintf(stderr,"%c isn't a color, skipping", fstrc[i+1]); +#endif + } + }else{ +#ifdef DEBUG + fprintf(stderr,"end of line by '$', expect a color after '$'"); +#endif + return; + } + i+=2; + } + }else{ + if( ! tmp ) + tmp = fstrc+i; + toP += 1; + nbC++; + i++; + } + } + if(tmp) + printw("%.*s", toP, tmp); + fflush(NULL); +} +void mvprintc(int x, int y, char* fstrc, int max_length) { + move(y, x); + printc(fstrc, max_length); +} + + diff --git a/basic_curses.h b/basic_curses.h new file mode 100644 index 0000000..00be967 --- /dev/null +++ b/basic_curses.h @@ -0,0 +1,15 @@ + +#ifndef BASIC_CURSES_H +#define BASIC_CURSES_H + +#include "main.h" + +void printfc(char* fstrc, int max_length, ...); + +void printc(char* fstrc, int max_length); +void mvprintc(int x, int y, char* fstrc, int max_length); + + +#define mvprintfc( x, y, fstrc, max, ...) (move((y),(x)),printfc(fstrc, max, __VA_ARGS__ )) + +#endif diff --git a/contactList.c b/contactList.c new file mode 100644 index 0000000..85369a9 --- /dev/null +++ b/contactList.c @@ -0,0 +1,170 @@ +#include +#include +#include"contactList.h" + +contact* contactList; +size_t nbContacts; + + +int x_menuContact = 1,y_menuContact = 1; +int w_menuContact,h_menuContact; + +int contactListSelection; +int firstConctactShow; + + + +void selectNextContact(void) { + if( contactListSelection < nbContacts - 1) + contactListSelection++; + clearContactListW(); +} +void selectPreviousContact(void) { + if( contactListSelection > 0) + contactListSelection--; + clearContactListW(); +} + +void clearContactListW(void) { + for(int i = firstConctactShow; i < h_menuContact && i < nbContacts; i++) { + move(y_menuContact+i,x_menuContact); + printw("%*s", w_menuContact, " "); + } +} + +int fillContactList(char* filename) { + FILE* file = fopen(filename, "r"); + + nbContacts = 0; + if( contactList ) { + free(contactList); + } + + if( !file ) + return 1; + + int c = 0; + int v = 0; + while( (c = fgetc(file)) != EOF ) { + if( c == ';' ) { + v++; + if( v == 3) + return 2; // Invalid + } + if( c == '\n' ) { + if( v == 2 ) { + v = 0; + nbContacts++; + } + else // Pas assez + return 2; // Invalid format + } + } + if( v == 1 ) + nbContacts++; + + contactList = malloc( nbContacts * sizeof *contactList); + + rewind(file); + + int nameLength, numberLength, display_nameLength, i; + nameLength = numberLength = display_nameLength = i = 0; + contactList[0].hasNewMessage = 0; + while( (c = fgetc(file)) != EOF ) { + if( c == ';' ) { + v++; + switch(v) { + case 1: + contactList[i].name[nameLength] = 0; + nameLength = 0; + break; + case 2: + contactList[i].name[display_nameLength] = 0; + display_nameLength = 0; + break; + default: + return 2; // Invalid + } + } else if( c == '\n' ) { + if( v == 2 ) { + v = 0; + contactList[i].number[numberLength] = 0; + numberLength = 0; + i++; + contactList[i].hasNewMessage = 0; + } + else + return 2; // Invalid format + } else { + if( v == 0) { + contactList[i].name[nameLength++] = c; + if( nameLength > (sizeof contactList[i].name -1) ) { + return 3; + } + }else if( v == 1) { + contactList[i].display_name[display_nameLength++] = c; + if( display_nameLength > (sizeof contactList[i].display_name -1) ) { + return 9; + } + } else { + contactList[i].number[numberLength++] = c; + if( numberLength > (sizeof contactList[i].number -1) ) { + puts(contactList[i].number); + return 27+i; + } + } + } + } + + return 0; +} + +void showContactListW(void) { + + int x = x_menuContact; + int y = y_menuContact; + int w = w_menuContact; + int h = h_menuContact; + int s = nbContacts; + + if( contactListSelection < firstConctactShow ) { + firstConctactShow-=h/2; + if( firstConctactShow < 0 ) + firstConctactShow = 0; + + clearContactListW(); + } + + if( contactListSelection >= firstConctactShow + h ) { + attrset(0 | A_NORMAL ); + firstConctactShow+=h/2; + if( firstConctactShow > nbContacts-1 ) + firstConctactShow = nbContacts-1; + + clearContactListW(); + } + + + int i; + for(i = firstConctactShow ; i < (h+firstConctactShow) && i < s ; i++) { + int color = 0, attr = A_NORMAL; +// if( it[i].opt == 1 ) +// color = COLOR_BLUE+1; + if( contactList[i].hasNewMessage ) + attr |= A_BOLD; + if( i == contactListSelection ) { + attr |= A_REVERSE; + } + + attrset( COLOR_PAIR(color) | attr); + move(y,x); + printw("%*s", w, " "); + mvprintc(x,y++,contactList[i].display_name, w); + attrset(0 | A_NORMAL); + } + for( ; i < s ; i++){ // Clear + + } +} + + diff --git a/contactList.h b/contactList.h new file mode 100644 index 0000000..12d69ed --- /dev/null +++ b/contactList.h @@ -0,0 +1,58 @@ +#ifndef CONTACT_LIST_H +#define CONTACT_LIST_H + +#include +#include +#include "basic_curses.h" + +typedef struct contact { + char name[100]; + char display_name[100]; + char number[50]; + int hasNewMessage; +} contact ; + + + + +// Params: The CSV filename (separator ';', unexcaped string, so ';' is forbiden in value) +// Return: 0 if success, >0 if error +int fillContactList(char* cvs_file_in); + + +// Params: A valide filename +// Return: 0 if success, >0 if error +int writeContactList(char* cvs_file_in); + +// Add a contact +// Params: A contact struct +// Return: 0 if success, >0 otherwise +int addContact(const contact*); + +// Delete a contact +// Params: A String which is a valide contact SIM number +// Return: 0 if success, >0 otherwise +int deleteContactFromNumber(const char*); + + +// Delete a contact from his name +// Params: A String which is a valide contact SIM number +// Return: 0 if success, >0 otherwise +int deleteContactFromName(const char*); + + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + +// Window contact + +void clearContactListW(void); +void showContactListW(void); +void refreshContactListW(void); + +void selectNextContact(void); +void selectPreviousContact(void); + + +#endif diff --git a/main.c b/main.c index 3c5a6f5..a75a553 100644 --- a/main.c +++ b/main.c @@ -41,6 +41,7 @@ WINDOW *sep_win; char status[10]; + void fail_exit(const char *msg) { if (visual_mode) endwin(); @@ -99,10 +100,10 @@ int main(int argc, char* argv[]){ CHECK(start_color); } - CHECK(cbreak); CHECK(noecho); CHECK(nonl); - CHECK(intrflush, NULL, FALSE); + CHECK(intrflush, stdscr, FALSE); + CHECK(keypad, stdscr, TRUE); visual_mode = true; curs_set(0); @@ -115,23 +116,45 @@ int main(int argc, char* argv[]){ CHECK(wrefresh, sep_win); init_readline(); + int r = 0; + if( r = fillContactList("contact.csv") ) { + return r; + } + for(int i = 0 ; i < 9 ; i++) { init_pair( i+1, i, COLOR_BLACK); } /* Premier affichage */ + resize(); /* Event loop */ while( c = getch() ) { if (c == KEY_RESIZE) { + resize(); + refresh(); continue; } + if ( c == 'q' ) { + break; + } + switch( c ) { + case KEY_DOWN: + case KEY_RIGHT: + case 'j': + selectNextContact(); + break; + case KEY_UP: + case KEY_LEFT: + case 'k': + selectPreviousContact(); + break; + } - refresh(); + resize(); } refresh(); - getch(); end: endwin(); diff --git a/main.h b/main.h index cd72393..b0ff58c 100644 --- a/main.h +++ b/main.h @@ -17,6 +17,9 @@ #include #include +#include "contactList.h" +#include "wind.h" + #define HIDDEN 1 diff --git a/wind.c b/wind.c index 0051cd4..138d837 100644 --- a/wind.c +++ b/wind.c @@ -6,11 +6,20 @@ /* Managed windows */ - +extern int w_menuContact,h_menuContact; static short my_fg = COLOR_WHITE; static short my_bg = COLOR_BLACK; -extern char status[10]; -extern WINDOW *cmd_win; -extern WINDOW *sep_win; +//extern char status[10]; +//extern WINDOW *cmd_win; +//extern WINDOW *sep_win; + +void resize() { + h_menuContact = LINES-2; + w_menuContact = COLS/5-1; + showContactListW(); + move(1,COLS/2); +} + + diff --git a/wind.h b/wind.h index 8fc3c3c..c2b835f 100644 --- a/wind.h +++ b/wind.h @@ -4,6 +4,11 @@ #include "main.h" #include "readline.h" +#include "contactList.h" + + + +void resize(); #endif -- cgit v1.2.3