aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorache <ache@ache.one>2017-11-11 03:57:47 +0000
committerache <ache@ache.one>2017-11-11 03:57:47 +0000
commit65087f82753a12e330fa0e6fc0c0e4b70c6a6c63 (patch)
tree00c4f4a5a022ab5a631ff738315eb830a039922b
parentInit commit (diff)
PoC menu Contact
-rw-r--r--Makefile2
-rw-r--r--basic_curses.c152
-rw-r--r--basic_curses.h15
-rw-r--r--contactList.c170
-rw-r--r--contactList.h58
-rw-r--r--main.c31
-rw-r--r--main.h3
-rw-r--r--wind.c17
-rw-r--r--wind.h5
9 files changed, 444 insertions, 9 deletions
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 <stdlib.h>
+#include <stdio.h>
+#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 <ncurses.h>
+#include <stdio.h>
+#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 <ncurses.h>
#include <getopt.h>
+#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