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:
2025-05-18 00:49:59 +02:00
parent 9e7fa91180
commit 1650a741b2
4 changed files with 293 additions and 24 deletions
+2
View File
@@ -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();
+274 -11
View File
@@ -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
View File
@@ -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;