Enhance database management and TUI functionality: update person data in CSV, add edit and delete options in TUI, and improve mutex handling in user functions.
This commit is contained in:
@@ -55,6 +55,7 @@ int main(int argc, char const **argv)
|
||||
puts("Corrupted and/or empty list. Exiting...\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
pthread_mutex_unlock(&person_list.lock);
|
||||
|
||||
noecho();
|
||||
noraw();
|
||||
@@ -118,6 +119,7 @@ int main(int argc, char const **argv)
|
||||
|
||||
pthread_join(uart_thread, NULL);
|
||||
free(args);
|
||||
pthread_mutex_destroy(&person_list.lock);
|
||||
|
||||
clear();
|
||||
endwin();
|
||||
|
||||
@@ -216,6 +216,10 @@ void mainMenu(list_t *person_list, char *db_filename, int terminal_x, int termin
|
||||
case 1:
|
||||
personSearch(person_list, terminal_x, terminal_y);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
editDatabaseMenu(person_list, terminal_x, terminal_y);
|
||||
break;
|
||||
case 3:
|
||||
if (!saveListToCSV(db_filename, person_list))
|
||||
dialogWindow(3, "Unknown error while saving.", terminal_x, terminal_y);
|
||||
@@ -249,7 +253,7 @@ void mainMenu(list_t *person_list, char *db_filename, int terminal_x, int termin
|
||||
|
||||
void personListing(list_t *person_list, int terminal_x, int terminal_y)
|
||||
{
|
||||
int win_height = 20;
|
||||
int win_height = 22;
|
||||
int win_width = 76;
|
||||
int start_y = (terminal_y - win_height) / 2;
|
||||
int start_x = (terminal_x - win_width) / 2;
|
||||
@@ -279,10 +283,9 @@ void personListing(list_t *person_list, int terminal_x, int terminal_y)
|
||||
|
||||
current = person_list->head;
|
||||
int idx = 0, row = 2;
|
||||
while (current && row < win_height)
|
||||
while (current && row < win_height -1)
|
||||
{
|
||||
|
||||
if (idx >= offset && row < win_height - 1)
|
||||
if (idx >= offset)
|
||||
{
|
||||
if (idx == highlight)
|
||||
wattron(personlisting, COLOR_PAIR(2));
|
||||
@@ -298,6 +301,7 @@ void personListing(list_t *person_list, int terminal_x, int terminal_y)
|
||||
idx++;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
|
||||
wrefresh(personlisting);
|
||||
|
||||
@@ -489,10 +493,7 @@ void personInfo(list_t *_list, node_t *_person, int terminal_x, int terminal_y)
|
||||
|
||||
WINDOW *personinfodialog = newwin(win_height, win_width, start_y, start_x);
|
||||
|
||||
int max_rows = win_height - 2;
|
||||
int total_count = 0;
|
||||
|
||||
char buttons[3][20] = {"<Print to file...>", "<Add Time Event>", "<Back>"};
|
||||
char buttons[3][20] = {"<Print to file>", "<Add Time Event>", "<Back>"};
|
||||
char prompts[6][32] = {"Name", "Surname", "Department", "Last time event", "Total time", "Available"};
|
||||
|
||||
char keyboard_input;
|
||||
@@ -500,8 +501,7 @@ void personInfo(list_t *_list, node_t *_person, int terminal_x, int terminal_y)
|
||||
|
||||
int field_y = 2;
|
||||
int field_x = 4;
|
||||
int button_y = field_y + 15;
|
||||
int button_x = field_x;
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
@@ -556,7 +556,10 @@ void personInfo(list_t *_list, node_t *_person, int terminal_x, int terminal_y)
|
||||
{
|
||||
if (highlight == 0)
|
||||
{
|
||||
exportPersonInfo(_person);
|
||||
if (exportPersonInfo(_person))
|
||||
dialogWindow(1, "Export succesfully created", terminal_x, terminal_y);
|
||||
else
|
||||
dialogWindow(3, "Unknown error", terminal_x, terminal_y);
|
||||
}
|
||||
else if (highlight == 1)
|
||||
{
|
||||
@@ -686,14 +689,274 @@ int exportDialog(list_t *_list, int terminal_x, int terminal_y)
|
||||
|
||||
void editDatabaseMenu(list_t *_person_list, int terminal_x, int terminal_y)
|
||||
{
|
||||
|
||||
int win_height = 10;
|
||||
int win_width = 50;
|
||||
int start_y = (terminal_y - win_height) / 2;
|
||||
int start_x = (terminal_x - win_width) / 2;
|
||||
|
||||
char choices[4][30] = {"Add person to database", "Remove person from database", "Log time event", "Back"};
|
||||
|
||||
char keyboard_input;
|
||||
int highlight = 0;
|
||||
|
||||
start_color();
|
||||
|
||||
WINDOW *mainmenu = newwin(win_height, win_width, start_y, start_x);
|
||||
|
||||
while (1)
|
||||
{
|
||||
initWindow(mainmenu, win_width, terminal_x, terminal_y, STANDARD_WIN_COLOUR, "Database Editing");
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (i == highlight)
|
||||
wattron(mainmenu, COLOR_PAIR(2));
|
||||
else
|
||||
wattron(mainmenu, COLOR_PAIR(1));
|
||||
wattron(mainmenu, A_BOLD);
|
||||
mvwprintw(mainmenu, 2 + i, (win_width - strlen(choices[i])) / 2, "%s", choices[i]);
|
||||
wattroff(mainmenu, A_BOLD);
|
||||
|
||||
if (i == highlight)
|
||||
wattroff(mainmenu, COLOR_PAIR(2));
|
||||
else
|
||||
wattroff(mainmenu, COLOR_PAIR(1));
|
||||
}
|
||||
wrefresh(mainmenu);
|
||||
flushinp();
|
||||
keyboard_input = wgetch(mainmenu);
|
||||
|
||||
if (keyboard_input == '\t')
|
||||
{
|
||||
if (highlight < 3)
|
||||
highlight++;
|
||||
else
|
||||
highlight = 0;
|
||||
}
|
||||
|
||||
else if (keyboard_input == '\n')
|
||||
{
|
||||
switch (highlight)
|
||||
{
|
||||
case 0:
|
||||
addPersonDialog(_person_list, terminal_x, terminal_y);
|
||||
break;
|
||||
case 1:
|
||||
deletePersonDialog(_person_list, terminal_x, terminal_y);
|
||||
break;
|
||||
case 2:
|
||||
dialogWindow(2, "You can add time event for existing user from main menu", terminal_x, terminal_y);
|
||||
break;
|
||||
case 3:
|
||||
if (keyboard_input == '\n')
|
||||
{
|
||||
wclear(mainmenu);
|
||||
wrefresh(mainmenu);
|
||||
touchwin(stdscr);
|
||||
refresh();
|
||||
delwin(mainmenu);
|
||||
refresh();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addPersonDialog(list_t *_person_list, int terminal_x, int terminal_y)
|
||||
{
|
||||
int win_height = 14;
|
||||
int win_width = 60;
|
||||
int start_y = (terminal_y - win_height) / 2;
|
||||
int start_x = (terminal_x - win_width) / 2;
|
||||
|
||||
WINDOW *addwin = newwin(win_height, win_width, start_y, start_x);
|
||||
initWindow(addwin, win_width, terminal_x, terminal_y, STANDARD_WIN_COLOUR, "Add Person");
|
||||
|
||||
char name[32] = "";
|
||||
char surname[32] = "";
|
||||
char department[8] = "";
|
||||
int highlight = 0;
|
||||
char *fields[3] = {name, surname, department};
|
||||
int field_lens[3] = {31, 31, 7};
|
||||
char *prompts[3] = {"Name", "Surname", "Department"};
|
||||
char *buttons[2] = {"<Add>", "<Back>"};
|
||||
|
||||
while (1)
|
||||
{
|
||||
werase(addwin);
|
||||
initWindow(addwin, win_width, terminal_x, terminal_y, STANDARD_WIN_COLOUR, "Add Person");
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (highlight == i)
|
||||
wattron(addwin, COLOR_PAIR(2));
|
||||
else
|
||||
wattron(addwin, COLOR_PAIR(1));
|
||||
mvwprintw(addwin, 2 + i * 2, 4, "%s: [%s]", prompts[i], fields[i][0] ? fields[i] : "______________________________");
|
||||
if (highlight == i)
|
||||
wattroff(addwin, COLOR_PAIR(2));
|
||||
else
|
||||
wattroff(addwin, COLOR_PAIR(1));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (highlight == 3 + i)
|
||||
wattron(addwin, COLOR_PAIR(2) | A_BOLD);
|
||||
else
|
||||
wattron(addwin, COLOR_PAIR(1) | A_BOLD);
|
||||
mvwprintw(addwin, 10, 4 + i * 16, "%s", buttons[i]);
|
||||
if (highlight == 3 + i)
|
||||
wattroff(addwin, COLOR_PAIR(2) | A_BOLD);
|
||||
else
|
||||
wattroff(addwin, COLOR_PAIR(1) | A_BOLD);
|
||||
}
|
||||
|
||||
wrefresh(addwin);
|
||||
|
||||
int ch = wgetch(addwin);
|
||||
if (ch == '\t')
|
||||
{
|
||||
highlight = (highlight + 1) % 5;
|
||||
}
|
||||
else if (ch == '\n')
|
||||
{
|
||||
if (highlight < 3)
|
||||
{
|
||||
echo();
|
||||
curs_set(1);
|
||||
mvwprintw(addwin, 2 + highlight * 2, 7 + strlen(prompts[highlight]), "%-30s", "");
|
||||
wmove(addwin, 2 + highlight * 2, 7 + strlen(prompts[highlight]));
|
||||
wgetnstr(addwin, fields[highlight], field_lens[highlight]);
|
||||
curs_set(0);
|
||||
noecho();
|
||||
}
|
||||
else if (highlight == 3)
|
||||
{
|
||||
if (strlen(name) == 0 || strlen(surname) == 0 || strlen(department) == 0)
|
||||
{
|
||||
dialogWindow(3, "All fields must be filled.", terminal_x, terminal_y);
|
||||
continue;
|
||||
}
|
||||
if (addPersonToList(_person_list, name, surname, atoi(department)))
|
||||
{
|
||||
dialogWindow(1, "Person added successfully.", terminal_x, terminal_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
dialogWindow(3, "Failed to add person.", terminal_x, terminal_y);
|
||||
}
|
||||
delwin(addwin);
|
||||
touchwin(stdscr);
|
||||
refresh();
|
||||
return;
|
||||
}
|
||||
else if (highlight == 4)
|
||||
{
|
||||
delwin(addwin);
|
||||
touchwin(stdscr);
|
||||
refresh();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (ch == 27 || ch == 'q')
|
||||
{
|
||||
delwin(addwin);
|
||||
touchwin(stdscr);
|
||||
refresh();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void deletePersonDialog(list_t *_person_list, int terminal_x, int terminal_y)
|
||||
{
|
||||
int win_height = 8;
|
||||
int win_width = 50;
|
||||
int start_y = (terminal_y - win_height) / 2;
|
||||
int start_x = (terminal_x - win_width) / 2;
|
||||
|
||||
WINDOW *delwin_dialog = newwin(win_height, win_width, start_y, start_x);
|
||||
initWindow(delwin_dialog, win_width, terminal_x, terminal_y, STANDARD_WIN_COLOUR, "Delete Person");
|
||||
|
||||
char prompt[] = "Enter UUID of person to delete:";
|
||||
char input[16] = "";
|
||||
int highlight = 0;
|
||||
int button_x = (win_width - 7) / 2;
|
||||
int text_x = (win_width - 18) / 2;
|
||||
|
||||
while (1)
|
||||
{
|
||||
werase(delwin_dialog);
|
||||
initWindow(delwin_dialog, win_width, terminal_x, terminal_y, STANDARD_WIN_COLOUR, "Delete Person");
|
||||
|
||||
mvwprintw(delwin_dialog, 2, (win_width - strlen(prompt)) / 2, "%s", prompt);
|
||||
|
||||
if (highlight == 0)
|
||||
wattron(delwin_dialog, COLOR_PAIR(2));
|
||||
else
|
||||
wattron(delwin_dialog, COLOR_PAIR(1));
|
||||
mvwprintw(delwin_dialog, 4, text_x, "[%15s]", input);
|
||||
if (highlight == 0)
|
||||
wattroff(delwin_dialog, COLOR_PAIR(2));
|
||||
else
|
||||
wattroff(delwin_dialog, COLOR_PAIR(1));
|
||||
|
||||
if (highlight == 1)
|
||||
wattron(delwin_dialog, COLOR_PAIR(2) | A_BOLD);
|
||||
else
|
||||
wattron(delwin_dialog, COLOR_PAIR(1) | A_BOLD);
|
||||
mvwprintw(delwin_dialog, 6, button_x, "<Delete>");
|
||||
if (highlight == 1)
|
||||
wattroff(delwin_dialog, COLOR_PAIR(2) | A_BOLD);
|
||||
else
|
||||
wattroff(delwin_dialog, COLOR_PAIR(1) | A_BOLD);
|
||||
|
||||
wrefresh(delwin_dialog);
|
||||
|
||||
int ch = wgetch(delwin_dialog);
|
||||
if (ch == '\t')
|
||||
{
|
||||
highlight = !highlight;
|
||||
}
|
||||
else if (ch == '\n')
|
||||
{
|
||||
if (highlight == 0)
|
||||
{
|
||||
echo();
|
||||
curs_set(1);
|
||||
mvwprintw(delwin_dialog, 4, text_x + 1, "%-15s", "");
|
||||
wmove(delwin_dialog, 4, text_x + 1);
|
||||
wgetnstr(delwin_dialog, input, 15);
|
||||
curs_set(0);
|
||||
noecho();
|
||||
}
|
||||
else if (highlight == 1)
|
||||
{
|
||||
uint16_t uuid = (uint16_t)atoi(input);
|
||||
node_t *for_delete = searchPersonByUUID(_person_list, uuid);
|
||||
if (removePersonFromList(_person_list, &for_delete))
|
||||
{
|
||||
dialogWindow(1, "Person deleted successfully.", terminal_x, terminal_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
dialogWindow(3, "Person not found.", terminal_x, terminal_y);
|
||||
}
|
||||
delwin(delwin_dialog);
|
||||
touchwin(stdscr);
|
||||
refresh();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (ch == 27 || ch == 'q')
|
||||
{
|
||||
delwin(delwin_dialog);
|
||||
touchwin(stdscr);
|
||||
refresh();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-7
@@ -15,12 +15,11 @@ uint16_t generateUUID(
|
||||
{
|
||||
uint16_t uuid;
|
||||
int found;
|
||||
pthread_mutex_lock(&_list->lock);
|
||||
do
|
||||
{
|
||||
found = 0;
|
||||
uuid = (uint16_t)(rand() % (UINT16_MAX + 1));
|
||||
|
||||
pthread_mutex_lock(&_list->lock);
|
||||
node_t *current = _list->head;
|
||||
while (current != NULL)
|
||||
{
|
||||
@@ -60,7 +59,8 @@ uint16_t searchUUIDByName(list_t *_list, char *_name, char *_surname, uint16_t *
|
||||
{
|
||||
uint16_t sum = 0;
|
||||
uint16_t *uuids = malloc(sizeof(uint16_t));
|
||||
if (uuids == NULL) {
|
||||
if (uuids == NULL)
|
||||
{
|
||||
*_uuids_found = NULL;
|
||||
return 0;
|
||||
}
|
||||
@@ -127,7 +127,7 @@ int addPersonToList(
|
||||
strcpy(new_node->user.name, _name);
|
||||
strcpy(new_node->user.surname, _surname);
|
||||
new_node->user.department = _department;
|
||||
new_node->user.last_time_event = -255;
|
||||
new_node->user.last_time_event = 0;
|
||||
new_node->user.total = 0;
|
||||
new_node->user.available = FALSE;
|
||||
|
||||
@@ -166,7 +166,8 @@ int loadPersonToList(list_t *_list, uint16_t _uuid, char *_name, char *_surname,
|
||||
if (_list->head == NULL)
|
||||
{
|
||||
_list->head = (node_t *)malloc(sizeof(node_t));
|
||||
if (_list->head == NULL) {
|
||||
if (_list->head == NULL)
|
||||
{
|
||||
pthread_mutex_unlock(&_list->lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -236,7 +237,6 @@ int loadPersonToList(list_t *_list, uint16_t _uuid, char *_name, char *_surname,
|
||||
}
|
||||
current->next = new_node;
|
||||
pthread_mutex_unlock(&_list->lock);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -254,7 +254,8 @@ int addTimeEvent(
|
||||
pthread_mutex_lock(&_list->lock);
|
||||
if (_person->user.available)
|
||||
{
|
||||
if (current_time > _person->user.last_time_event) {
|
||||
if (current_time > _person->user.last_time_event)
|
||||
{
|
||||
_person->user.total += (current_time - _person->user.last_time_event);
|
||||
}
|
||||
}
|
||||
@@ -291,6 +292,7 @@ int removePersonFromList(list_t *_list, node_t **_person)
|
||||
free(current->user.surname);
|
||||
free(current);
|
||||
*_person = NULL;
|
||||
pthread_mutex_unlock(&_list->lock);
|
||||
return 1;
|
||||
}
|
||||
prev = current;
|
||||
|
||||
Reference in New Issue
Block a user