add basic easy editor
All checks were successful
build_test / build (push) Successful in 3m18s

This commit is contained in:
PoliEcho 2025-04-15 16:23:38 +02:00
parent 0f7719caeb
commit 57d8b13f19
3 changed files with 300 additions and 34 deletions

253
src/editor_easy.cpp Normal file
View File

@ -0,0 +1,253 @@
#include <cstring>
#include <ctime>
#include <form.h>
#include <format> // C++20/C++23 feature
#include <ncurses.h>
#include <string>
#include <vector>
#define WHITE_ON_BLUE 9
#define BLACK_ON_WHITE 10
[[nodiscard]] std::string vytvorTrestniOznameni() {
// Pomocná funkce pro ořezání mezer (ncurses vyplňuje pole mezerami)
auto trim = [](const char *str) -> std::string {
std::string s(str);
if (s.empty())
return s;
size_t start = s.find_first_not_of(" \t\n\r\f\v");
if (start == std::string::npos)
return "";
size_t end = s.find_last_not_of(" \t\n\r\f\v");
return s.substr(start, end - start + 1);
};
init_pair(WHITE_ON_BLUE, COLOR_WHITE, COLOR_BLUE);
init_pair(BLACK_ON_WHITE, COLOR_BLACK, COLOR_WHITE);
// Velikost terminalu
int max_y, max_x;
getmaxyx(stdscr, max_y, max_x);
echo();
// Nadpis
attron(COLOR_PAIR(WHITE_ON_BLUE));
mvprintw(0, 0, "TRESTNÍ OZNÁMENÍ - ZADÁNÍ ÚDAJŮ");
for (int i = strlen("TRESTNÍ OZNÁMENÍ - ZADÁNÍ ÚDAJŮ"); i < max_x; i++)
addch(' ');
attroff(COLOR_PAIR(WHITE_ON_BLUE));
// Vytvoření polí formuláře
const int NUM_FIELDS = 10;
FIELD *fields[NUM_FIELDS + 1]; // +1 pro NULL terminátor
// Definice popisků a vlastností polí
struct FieldInfo {
const char *label;
int height;
int width;
bool multiline;
};
FieldInfo field_info[NUM_FIELDS] = {
{"Jméno a příjmení:", 1, 40, false},
{"Adresa:", 1, 50, false},
{"Telefon:", 1, 20, false},
{"Email:", 1, 30, false},
{"Místo činu:", 1, 40, false},
{"Datum činu (dd.mm.rrrr):", 1, 15, false},
{"Popis činu:", 5, 60, true},
{"Jméno pachatele (pokud známo):", 1, 40, false},
{"Důkazy:", 4, 60, true},
{"Další informace:", 3, 60, true}};
// Vytvoření polí
int row = 2;
for (int i = 0; i < NUM_FIELDS; i++) {
mvprintw(row, 2, "%s", field_info[i].label);
fields[i] = new_field(field_info[i].height, field_info[i].width, row,
30, // Začátek pole po popisku
0, 0);
// Nastavení vlastností pole
set_field_back(fields[i], A_UNDERLINE);
field_opts_off(fields[i], O_AUTOSKIP);
// Pro víceřádková pole
if (field_info[i].multiline) {
field_opts_off(fields[i], O_STATIC);
field_opts_on(fields[i], O_WRAP);
}
row += field_info[i].height + 1;
}
fields[NUM_FIELDS] = NULL;
// Vytvoření formuláře
FORM *form = new_form(fields);
// Vytvoření oken pro formulář
WINDOW *win_body = newwin(max_y, max_x, 0, 0);
WINDOW *win_form = derwin(win_body, max_y - 5, max_x - 4, 1, 2);
// Přiřazení oken k formuláři
set_form_win(form, win_body);
set_form_sub(form, win_form);
// Zobrazení formuláře
post_form(form);
// Zobrazení instrukcí
mvprintw(max_y - 3, 2,
"Navigace: šipky - pohyb | Tab - další pole | Enter - nový řádek | "
"F10 - uložit");
refresh();
wrefresh(win_body);
// Zpracování vstupu od uživatele
int ch;
while ((ch = getch()) != KEY_F(10)) {
switch (ch) {
case KEY_DOWN:
form_driver(form, REQ_NEXT_FIELD);
form_driver(form, REQ_END_LINE);
break;
case KEY_UP:
form_driver(form, REQ_PREV_FIELD);
form_driver(form, REQ_END_LINE);
break;
case KEY_LEFT:
form_driver(form, REQ_PREV_CHAR);
break;
case KEY_RIGHT:
form_driver(form, REQ_NEXT_CHAR);
break;
case KEY_BACKSPACE:
case 127:
form_driver(form, REQ_DEL_PREV);
break;
case KEY_DC:
form_driver(form, REQ_DEL_CHAR);
break;
case 10: // Enter key
case KEY_ENTER: {
int idx = field_index(current_field(form));
if (field_info[idx].multiline) {
form_driver(form, REQ_NEW_LINE);
} else {
form_driver(form, REQ_NEXT_FIELD);
form_driver(form, REQ_END_LINE);
}
} break;
case '\t':
form_driver(form, REQ_NEXT_FIELD);
form_driver(form, REQ_END_LINE);
break;
case KEY_BTAB:
form_driver(form, REQ_PREV_FIELD);
form_driver(form, REQ_END_LINE);
break;
case KEY_HOME:
form_driver(form, REQ_BEG_LINE);
break;
case KEY_END:
form_driver(form, REQ_END_LINE);
break;
default:
form_driver(form, ch);
break;
}
wrefresh(win_form);
wrefresh(win_body);
}
// Validace před čtením dat (důležité pro získání aktuálních hodnot)[1][5]
form_driver(form, REQ_VALIDATION);
// Sběr dat z formuláře
std::vector<std::string> field_values;
for (int i = 0; i < NUM_FIELDS; i++) {
char *buffer = field_buffer(fields[i], 0);
field_values.push_back(trim(buffer));
}
// Uvolnění prostředků
unpost_form(form);
free_form(form);
for (int i = 0; i < NUM_FIELDS; i++) {
free_field(fields[i]);
}
delwin(win_form);
delwin(win_body);
endwin();
// Aktuální datum
std::time_t t = std::time(nullptr);
std::tm *now = std::localtime(&t);
char date_str[100];
std::strftime(date_str, sizeof(date_str), "%d.%m.%Y", now);
// Formátování trestního oznámení pomocí std::format (C++20/C++23)
std::string complaint =
std::format(R"(
TRESTNÍ OZNÁMENÍ
Policie České republiky
Krajské ředitelství policie
Obvodní oddělení
V {} dne {}
Oznamovatel:
Jméno a příjmení: {}
Adresa: {}
Telefon: {}
Email: {}
Věc: Oznámení o skutečnostech nasvědčujících tomu, že byl spáchán trestný čin
{}
K trestnému činu došlo dne {} v {}.
Popis skutku:
{}
Důkazy:
{}
Další informace:
{}
S úctou,
............................
{}
(podpis oznamovatele)
)",
field_values[4], // Místo
date_str, // Aktuální datum
field_values[0], // Jméno a příjmení
field_values[1], // Adresa
field_values[2], // Telefon
field_values[3], // Email
field_values[7].empty()
? "Tímto podávám trestní oznámení na neznámého pachatele "
"pro podezření ze spáchání trestného činu."
: std::format("Tímto podávám trestní oznámení na: {} pro "
"podezření ze spáchání trestného činu.",
field_values[7]),
field_values[5], // Datum činu
field_values[4], // Místo činu
field_values[6], // Popis činu
field_values[8], // Důkazy
field_values[9], // Další informace
field_values[0] // Jméno pro podpis
);
noecho();
return complaint;
}

8
src/editor_easy.h Normal file
View File

@ -0,0 +1,8 @@
#include <string>
#ifndef PARADOCS_EDEA_H_
#define PARADOCS_EDEA_H_
[[nodiscard]] std::string vytvorTrestniOznameni();
#endif

View File

@ -1,21 +1,22 @@
#include <curses.h>
#include <menu.h>
#include <ncurses.h>
#include "const.h"
#include "cups.h"
#include "editor_easy.h"
#include "gameske_funkce.h"
#include "memory.h"
#include "types.h"
#include <clocale>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include "const.h"
#include "cups.h"
#include "gameske_funkce.h"
#include "memory.h"
#include "types.h"
#include <curses.h>
#include <menu.h>
#include <ncurses.h>
std::vector<allocation> main_menu_allocated;
const char* choices[] = {"paradox", "kompromis", "Stereotyp", "Žena"};
const char* date[] = {"2023-10-01", "2023-10-02", "2023-10-03", "2023-10-04"};
const char* choices2[] = {"PRINT", "EDIT", "DELETE", "Žena"};
const char *choices[] = {"paradox", "kompromis", "Stereotyp", "Žena"};
const char *date[] = {"2023-10-01", "2023-10-02", "2023-10-03", "2023-10-04"};
const char *choices2[] = {"PRINT", "EDIT", "DELETE", "Žena"};
void menu() {
current_allocated = &main_menu_allocated;
@ -25,7 +26,7 @@ void menu() {
start_color();
cbreak();
noecho();
curs_set(0); // Makes cursor invisible
curs_set(0); // Makes cursor invisible
keypad(stdscr, TRUE);
for (uint8_t i = 0; i < 8; i++) {
init_pair(i, i, COLOR_BLACK);
@ -37,7 +38,7 @@ void menu() {
complete_menu main_menu = {nullptr, nullptr, 0, nullptr};
main_menu_allocated.push_back({COMPLETE_MENU_TYPE, &main_menu, 1});
main_menu.items = new ITEM*[ARRAY_SIZE(choices) + 1];
main_menu.items = new ITEM *[ARRAY_SIZE(choices) + 1];
main_menu.items_size = ARRAY_SIZE(choices) + 1;
for (size_t i = 0; i < n_choices; ++i) {
main_menu.items[i] = new_item(choices[i], date[i]);
@ -74,29 +75,33 @@ void menu() {
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:
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();
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 ':':
switch (hash_djb2a(spawncmd())) {
case "print"_sh:
case "p"_sh:
// DONT FORGET TO PRINT ACTUAL DOCUMENT
printDocument("test");
current_allocated = &main_menu_allocated;
break;
default:
print_in_middle(main_menu.win, 10, 0, 40, "Unknown command",
COLOR_PAIR(1));
break;
}
case "easy_edit"_sh:
case "ee"_sh:
vytvorTrestniOznameni();
break;
default:
print_in_middle(main_menu.win, 10, 0, 40, "Unknown command",
COLOR_PAIR(1));
break;
}
}
wrefresh(main_menu.win);
}