Enhance user management: update CSV data, refactor UUID search function, and implement person listing and search functionalities in the TUI.

This commit is contained in:
2025-05-15 23:19:35 +02:00
parent 2662415ed5
commit 7bc938aa69
6 changed files with 320 additions and 31 deletions
+253
View File
@@ -2,6 +2,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "main.h"
#include "tui.h"
@@ -173,6 +174,12 @@ void mainMenu(list_t *person_list, int terminal_x, int terminal_y)
{
switch (highlight)
{
case 0:
personListing(person_list, terminal_x, terminal_y);
break;
case 1:
personSearch(person_list, terminal_x, terminal_y);
case 5:
if (keboard_input == '\n')
@@ -190,3 +197,249 @@ void mainMenu(list_t *person_list, int terminal_x, int terminal_y)
}
}
}
void personListing(list_t *person_list, int terminal_x, int terminal_y)
{
int win_height = 20;
int win_width = 76;
int start_y = (terminal_y - win_height) / 2;
int start_x = (terminal_x - win_width) / 2;
start_color();
WINDOW *personlisting = newwin(win_height, win_width, start_y, start_x);
wbkgd(personlisting, COLOR_PAIR(1));
box(personlisting, 0, 0);
wattron(personlisting, COLOR_PAIR(1));
wattron(personlisting, A_BOLD);
mvwprintw(personlisting, 0, (win_width - strlen("Filtered list")) / 2, "%s", "Filtered list");
wattroff(personlisting, A_BOLD);
wattroff(personlisting, COLOR_PAIR(1));
keypad(personlisting, TRUE);
int max_rows = win_height - 2;
int total_count = 0;
node_t *current = person_list->head;
while (current)
{
total_count++;
current = current->next;
}
int offset = 0;
int highlight = 0;
int keboard_input;
while (1)
{
werase(personlisting);
box(personlisting, 0, 0);
wattron(personlisting, COLOR_PAIR(1));
wattron(personlisting, A_BOLD);
mvwprintw(personlisting, 0, (win_width - strlen("Filtered list")) / 2, "%s", "Filtered list");
wattroff(personlisting, A_BOLD);
wattroff(personlisting, COLOR_PAIR(1));
wattron(personlisting, A_BOLD);
mvwprintw(personlisting, 1, 2, "UUID Surname Name Available");
wattroff(personlisting, A_BOLD);
current = person_list->head;
int idx = 0, row = 2;
while (current && row < win_height - 1)
{
if (current->user.uuid)
if (idx >= offset && row < win_height - 1)
{
if (idx == highlight)
wattron(personlisting, COLOR_PAIR(2));
mvwprintw(personlisting, row, 2, "%-10hu %-20s %-20s %s",
current->user.uuid,
current->user.surname,
current->user.name,
current->user.available ? "Yes " : "No ");
if (idx == highlight)
wattroff(personlisting, COLOR_PAIR(2));
row++;
}
idx++;
current = current->next;
}
wrefresh(personlisting);
keboard_input = wgetch(personlisting);
if (keboard_input == KEY_UP)
{
if (highlight > 0)
{
highlight--;
if (highlight < offset)
offset--;
}
}
else if (keboard_input == KEY_DOWN)
{
if (highlight < total_count - 1)
{
highlight++;
if (highlight >= offset + max_rows)
offset++;
}
}
else if (keboard_input == '\n')
{
int idx = 0;
node_t *selected = person_list->head;
while (selected && idx < highlight)
{
selected = selected->next;
idx++;
}
}
else if (keboard_input == 27)
{
break;
}
}
delwin(personlisting);
touchwin(stdscr);
refresh();
}
void personSearch(list_t *person_list, int terminal_x, int terminal_y)
{
int win_height = 20;
int win_width = 76;
int start_y = (terminal_y - win_height) / 2;
int start_x = (terminal_x - win_width) / 2;
char buttons[2][10] = {"<Search>", "<Back>"};
char prompts[2][10] = {"Name ", "Surname "};
start_color();
WINDOW *searchdialog = newwin(win_height, win_width, start_y, start_x);
wbkgd(searchdialog, COLOR_PAIR(1));
box(searchdialog, 0, 0);
wattron(searchdialog, COLOR_PAIR(1));
wattron(searchdialog, A_BOLD);
mvwprintw(searchdialog, 0, (win_width - strlen("Search")) / 2, "%s", "Search");
wattroff(searchdialog, A_BOLD);
wattroff(searchdialog, COLOR_PAIR(1));
keypad(searchdialog, TRUE);
char choice;
int highlight = 0;
int field_y = 2;
int field_x = 4;
static char name[32] = "";
static char surname[32] = "";
char *fields[2] = {name, surname};
int field_lens[2] = {31, 31};
uint16_t * uuids_found;
while (1)
{
for (int i = 0; i < 2; i++)
{
if (highlight == i)
wattron(searchdialog, COLOR_PAIR(2));
else
wattron(searchdialog, COLOR_PAIR(1));
mvwprintw(searchdialog, field_y + i * 2, field_x, "%s [%30s]", prompts[i], fields[i]);
if (highlight == i)
wattroff(searchdialog, COLOR_PAIR(2));
else
wattroff(searchdialog, COLOR_PAIR(1));
}
int button_y = field_y + 7;
int button_x = field_x;
for (int i = 0; i < 2; i++)
{
if (highlight == 2 + i)
wattron(searchdialog, COLOR_PAIR(2));
else
wattron(searchdialog, COLOR_PAIR(1));
wattron(searchdialog, A_BOLD);
mvwprintw(searchdialog, button_y, button_x + i * 12, "%s", buttons[i]);
wattroff(searchdialog, A_BOLD);
if (highlight == 2 + i)
wattroff(searchdialog, COLOR_PAIR(2));
else
wattroff(searchdialog, COLOR_PAIR(1));
}
wrefresh(searchdialog);
choice = wgetch(searchdialog);
if (choice == '\t')
{
if (highlight < 3)
{
highlight++;
}
else
highlight = 0;
}
else if (choice == '\n')
{
if (highlight < 2)
{
echo();
curs_set(1);
mvwprintw(searchdialog, field_y + highlight * 2, field_x + strlen(prompts[highlight]) + 3, "%-30s", "");
wmove(searchdialog, field_y + highlight * 2, field_x + strlen(prompts[highlight]) + 4);
wgetnstr(searchdialog, fields[highlight], field_lens[highlight]);
curs_set(0);
noecho();
}
else if (highlight == 2)
{
uint16_t count = searchUUIDByName(person_list, name, surname, uuids_found);
list_t found_pesons;
found_pesons.head = NULL;
node_t **last_ptr = &found_pesons.head;
for (uint16_t i = 0; i < count; i++) {
node_t *cur = person_list->head;
while (cur) {
if (cur->user.uuid == uuids_found[i]) {
node_t *new_node = malloc(sizeof(node_t));
if (new_node) {
new_node->user = cur->user;
new_node->next = NULL;
*last_ptr = new_node;
last_ptr = &new_node->next;
}
break;
}
cur = cur->next;
}
}
personListing(&found_pesons, terminal_x, terminal_y);
}
else if (highlight == 3)
{
delwin(searchdialog);
touchwin(stdscr);
refresh();
break;
}
}
else if (choice == 27)
{ // ESC
delwin(searchdialog);
touchwin(stdscr);
refresh();
break;
}
}
}
+30 -28
View File
@@ -56,49 +56,51 @@ node_t *searchPersonByUUID(
return NULL;
}
uint16_t *searchUUIDByName(
uint16_t searchUUIDByName(
list_t *_list,
char *_name,
char *_surname)
const char *_name,
const char *_surname,
uint16_t **_uuids_found)
{
int sum = 0;
uint16_t *uuids = malloc(sizeof(uint16_t));
pthread_mutex_lock(&_list->lock);
node_t *current = _list->head;
if (_list->head == NULL)
{
if (_list == NULL || _name == NULL || _surname == NULL || _uuids_found == NULL) {
return 0;
}
if (uuids == NULL)
{
puts("Fatal error: free memory is not sufficient for this operation");
exit(EXIT_FAILURE);
}
uint16_t *uuids = NULL;
size_t sum = 0;
size_t capacity = 0;
pthread_mutex_lock(&_list->lock);
node_t *current = _list->head;
while (current != NULL)
{
if (strcmp(_name, current->user.name) == 0 && strcmp(_surname, current->user.surname) == 0)
if (current->user.name != NULL && current->user.surname != NULL)
{
sum++;
uuids = realloc(uuids, sum * sizeof(uint16_t));
if (uuids == NULL)
if (strcmp(_name, current->user.name) == 0 && strcmp(_surname, current->user.surname) == 0)
{
puts("Fatal error: free memory is not sufficient for this operation");
exit(EXIT_FAILURE);
if (sum >= capacity) {
capacity = (capacity == 0) ? 1 : capacity * 2;
uint16_t *tmp = realloc(uuids, capacity * sizeof(uint16_t));
if (tmp == NULL)
{
pthread_mutex_unlock(&_list->lock);
free(uuids);
fprintf(stderr, "Fatal error: insufficient memory for this operation\n");
*_uuids_found = NULL;
return 0;
}
uuids = tmp;
}
uuids[sum++] = current->user.uuid;
}
uuids[sum - 1] = current->user.uuid;
}
current = current->next;
}
pthread_mutex_unlock(&_list->lock);
if (sum == 0)
return NULL;
return uuids;
*_uuids_found = uuids;
return (uint16_t)sum;
}
int addPersonToList(