ParaDocs/src/menu.cpp
PoliEcho dded22125c
Some checks failed
build_test / build (push) Failing after 2m49s
add hard editor
2025-06-02 20:26:58 +02:00

319 lines
11 KiB
C++

#include <curses.h>
#include <menu.h>
#include <ncurses.h>
#include <cerrno>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <nlohmann/json.hpp>
#include <sstream>
#include <string>
#include <vector>
#include "color.h"
#include "const.h"
#include "cups.h"
#include "editor_easy.h"
#include "editor_hard.h"
#include "gameske_funkce.h"
#include "memory.h"
#include "signal.h"
#include "strings.h"
#include "types.h"
using nlohmann::json;
std::vector<allocation> main_menu_allocated;
#define COMPLAINTS_DIR "complaints"
std::array<std::string, 2> get_name_date_from_item(ITEM* item) {
std::stringstream ss(item_description(item));
std::array<std::string, 2> name_date;
name_date[0] = item_name(item);
std::getline(ss, name_date[1], ' ');
return name_date;
}
void menu() {
current_allocated = &main_menu_allocated;
/* Initialize curses */
setlocale(LC_ALL, "");
initscr();
start_color();
cbreak();
noecho();
curs_set(0); // Makes cursor invisible
keypad(stdscr, TRUE);
for (uint8_t i = 0; i < 8; i++) {
init_pair(i, i, COLOR_BLACK);
}
async_clock_init();
// Create items
complete_menu main_menu = {nullptr, nullptr, 0, nullptr};
main_menu_allocated.push_back({COMPLETE_MENU_TYPE, &main_menu, 1});
{
std::vector<ITEM*> items;
if (std::filesystem::exists(COMPLAINTS_DIR)) {
for (const std::filesystem::directory_entry& directroy_entry :
std::filesystem::directory_iterator(COMPLAINTS_DIR)) {
if (directroy_entry.is_regular_file()) {
std::ifstream file(directroy_entry.path());
std::string name_date[2];
std::stringstream ssfn(directroy_entry.path().filename().string());
for (uint8_t i = 0; i < ARRAY_SIZE(name_date); i++) {
std::getline(ssfn, name_date[i], '_');
}
json complaint_json = json::parse(file);
if (complaint_json["status"].is_null() ||
complaint_json["status"].get<size_t>() >= STATUS_COUNT) {
std::cerr << "Invalid status in file: "
<< directroy_entry.path().filename().string()
<< std::endl;
safe_exit(EINVAL);
}
name_date[1].append(" ");
name_date[1].append(
loc_strings
->status_strings[complaint_json["status"].get<uint8_t>()]);
char* name = new char[name_date[0].length() + 1];
main_menu_allocated.push_back({GENERIC_TYPE, name, 1});
char* date = new char[name_date[1].length() + 1];
main_menu_allocated.push_back({GENERIC_TYPE, date, 1});
strcpy(name, name_date[0].c_str());
strcpy(date, name_date[1].c_str());
items.push_back(new_item(name, date));
}
}
} else {
std::filesystem::create_directory(COMPLAINTS_DIR);
}
items.push_back(nullptr);
main_menu.items = new ITEM*[items.size()];
main_menu.items_size = items.size() - 1;
memcpy(main_menu.items, items.data(), (items.size() * sizeof(ITEM*)));
}
/* Crate menu */
main_menu.menu = new_menu(main_menu.items);
/* Create the window to be associated with the menu */
main_menu.win = newwin(10, 40, 4, 4);
keypad(main_menu.win, TRUE);
/* Set main window and sub window */
set_menu_win(main_menu.menu, main_menu.win);
set_menu_sub(main_menu.menu, derwin(main_menu.win, 6, 38, 3, 1));
/* Set menu mark to the string " * " */
set_menu_mark(main_menu.menu, " * ");
/* Print a border around the main window and print a title */
box(main_menu.win, 0, 0);
print_in_middle(main_menu.win, 1, 0, 40, loc_strings->main_menu,
COLOR_PAIR(1));
mvwaddch(main_menu.win, 2, 0, ACS_LTEE);
mvwhline(main_menu.win, 2, 1, ACS_HLINE, 38);
mvwaddch(main_menu.win, 2, 39, ACS_RTEE);
mvprintw(LINES - 2, 0, "%s", loc_strings->f1_to_exit);
refresh();
/* Post the menu */
post_menu(main_menu.menu);
wrefresh(main_menu.win);
int c;
while ((c = wgetch(main_menu.win)) != KEY_F(1)) {
switch (c) {
case KEY_DOWN:
menu_driver(main_menu.menu, REQ_DOWN_ITEM);
break;
case KEY_UP:
menu_driver(main_menu.menu, REQ_UP_ITEM);
break;
case 10:
refresh();
break;
case ':':
switch (hash_djb2a(spawncmd())) {
case "print"_sh:
case "p"_sh:
// DONT FORGET TO PRINT ACTUAL DOCUMENT
printDocument("test");
current_allocated = &main_menu_allocated;
break;
case "easy_edit"_sh:
case "ee"_sh: {
const std::string name = spawncmd(loc_strings->reference_name);
if (name == "") {
print_in_middle(main_menu.win, 10, 0, 40,
loc_strings->invalid_input, COLOR_PAIR(1));
}
const time_t current_time = time(nullptr);
const tm* local_time = localtime(&current_time);
char formatted_date[11];
strftime(formatted_date, sizeof(formatted_date), "%d-%m-%Y",
local_time);
std::ofstream complaint_file(COMPLAINTS_DIR "/" + name + "_" +
formatted_date);
const std::string complaint_text = vytvorTrestniOznameni();
json complaint_json = {{"date", formatted_date},
{"status", NOT_SEND},
{"complaint_text", complaint_text}};
complaint_file << complaint_json;
break;
}
case "eh"_sh: {
std::array<std::string, 2> name_date =
get_name_date_from_item(current_item(main_menu.menu));
std::ifstream selected_file(COMPLAINTS_DIR "/" + name_date[0] +
'_' + name_date[1]);
if (!selected_file.is_open()) {
std::clog << selected_file.rdstate() << "\n";
std::cerr << RED "[ERROR] " RESET << loc_strings->invalid_input
<< "\n"
<< "File: "
<< COMPLAINTS_DIR "/" + name_date[0] + '_' +
name_date[1]
<< "\n";
exit(EINVAL);
}
json selected_file_json = json::parse(selected_file);
selected_file.close();
std::string complaint_text =
selected_file_json["complaint_text"].get<std::string>();
editor_hard(complaint_text);
curs_set(0);
clear();
selected_file_json["complaint_text"] = complaint_text;
std::ofstream selected_file_out(COMPLAINTS_DIR "/" + name_date[0] +
'_' + name_date[1]);
selected_file_out << selected_file_json;
selected_file_out.close();
break;
}
default:
print_in_middle(main_menu.win, 10, 0, 40,
loc_strings->unknown_command, COLOR_PAIR(1));
break;
}
break;
case 'm': {
std::array<std::string, 2> name_date =
get_name_date_from_item(current_item(main_menu.menu));
{
uint8_t n = 0;
size_t indexes[2];
for (size_t i = 0; (i < main_menu_allocated.size()); i++) {
if (main_menu_allocated[i].ptr ==
item_name(current_item(main_menu.menu))) {
delete[] static_cast<char*>(main_menu_allocated[i].ptr);
indexes[0] = i;
n++;
} else if (main_menu_allocated[i].ptr ==
item_description(current_item(main_menu.menu))) {
delete[] static_cast<char*>(main_menu_allocated[i].ptr);
indexes[1] = i;
n++;
}
if (n >= 2) {
break;
}
}
if (indexes[0] > indexes[1]) {
std::swap(indexes[0], indexes[1]);
}
main_menu_allocated.erase(main_menu_allocated.begin() + indexes[1]);
main_menu_allocated.erase(main_menu_allocated.begin() + indexes[0]);
}
{
std::ifstream selected_file(COMPLAINTS_DIR "/" + name_date[0] + '_' +
name_date[1]);
if (!selected_file.is_open()) {
std::clog << selected_file.rdstate() << "\n";
std::cerr << RED "[ERROR] " RESET << loc_strings->invalid_input
<< "\n"
<< "File: "
<< COMPLAINTS_DIR "/" + name_date[0] + '_' + name_date[1]
<< "\n";
exit(EINVAL);
}
json selected_file_json = json::parse(selected_file);
selected_file.close();
if (selected_file_json["status"].is_null() ||
selected_file_json["status"].get<size_t>() < STATUS_COUNT) {
(selected_file_json["status"].get<uint8_t>() + 1 >= STATUS_COUNT)
? selected_file_json["status"] = NOT_SEND
: selected_file_json["status"] =
selected_file_json["status"].get<uint8_t>() + 1;
std::ofstream selected_file(COMPLAINTS_DIR "/" + name_date[0] +
'_' + name_date[1]);
selected_file << selected_file_json;
selected_file.close();
} else {
std::cerr << RED "[ERROR] " RESET << loc_strings->invalid_input
<< "\n";
exit(EINVAL);
}
name_date[1].append(" ");
name_date[1].append(
loc_strings->status_strings[selected_file_json["status"]
.get<uint8_t>()]);
char* date_status = new char[name_date[1].length() + 1];
main_menu_allocated.push_back({GENERIC_TYPE, date_status, 1});
strlcpy(date_status, name_date[1].c_str(), name_date[1].length() + 1);
char* name = new char[name_date[0].length() + 1];
main_menu_allocated.push_back({GENERIC_TYPE, name, 1});
strlcpy(name, name_date[0].c_str(), name_date[0].length() + 1);
for (size_t i = 0; i < main_menu.items_size; i++) {
if (main_menu.items[i] == current_item(main_menu.menu)) {
free_item(main_menu.items[i]);
main_menu.items[i] = new_item(name, date_status);
break;
}
}
}
WINDOW* old_win_sub = menu_sub(main_menu.menu);
unpost_menu(main_menu.menu);
free_menu(main_menu.menu);
main_menu.menu = new_menu(main_menu.items);
set_menu_win(main_menu.menu, main_menu.win);
set_menu_sub(main_menu.menu, old_win_sub);
set_menu_format(main_menu.menu, 7, 1);
set_menu_mark(main_menu.menu, " * ");
post_menu(main_menu.menu);
break;
}
}
wrefresh(main_menu.win);
refresh();
redrawwin(main_menu.win);
wrefresh(main_menu.win);
}
unpost_menu(main_menu.menu);
delete_all(&main_menu_allocated);
endwin();
}