diff --git a/src/editor_hard.cpp b/src/editor_hard.cpp new file mode 100644 index 0000000..c58903c --- /dev/null +++ b/src/editor_hard.cpp @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "strings.h" +using nlohmann::json; + +void save_document(std::string& text, std::vector& lines) { + text = ""; + for (const std::string& line : lines) { + text.append(line); + text.append("\n"); + } +} + +void editor_hard(std::string& text) { + uint16_t cursor_x = 0; + uint16_t cursor_y = 0; + std::vector lines; + char mode = 'n'; + uint16_t window_height, window_width; + + mode = 'n'; + + noecho(); + curs_set(1); + cbreak(); + keypad(stdscr, TRUE); + getmaxyx(stdscr, window_height, window_width); + + // Parse the multi-line string into individual lines + lines.clear(); + std::stringstream ss(text); + std::string line; + + while (std::getline(ss, line)) { + lines.push_back(line); + } + + // Ensure at least one empty line exists + if (lines.empty()) { + lines.push_back(""); + } + while (true) { + clear(); + // Draw text lines + for (size_t i = 0; i < window_height - 1 && i < lines.size(); i++) { + mvprintw(i, 0, "%s", lines[i].c_str()); + } + + // Draw status line + std::string status = "Mode: " + std::string(1, mode); + mvprintw(window_height - 1, 0, "%s", status.c_str()); + + move(cursor_y, cursor_x); + refresh(); + { + int ch = getch(); + switch (mode) { + case 'n': // Normal mode + switch (ch) { + case 'h': + if (cursor_x > 0) { + cursor_x--; + } + break; + case 'j': + if (cursor_y < lines.size() - 1) { + cursor_y++; + if (cursor_x > lines[cursor_y].length()) { + cursor_x = lines[cursor_y].length(); + } + } + break; + case 'k': + if (cursor_y > 0) { + cursor_y--; + if (cursor_x > lines[cursor_y].length()) { + cursor_x = lines[cursor_y].length(); + } + } + + break; + case 'l': + if (cursor_x < lines[cursor_y].length()) { + cursor_x++; + } + break; + case 'i': + case 'a': + mode = 'i'; + break; + case 'x': + if (cursor_x < lines[cursor_y].length()) { + lines[cursor_y].erase(cursor_x, 1); + } + break; + case ':': { + // Enter command mode + std::string command = ""; + int cmd_ch; + // Show command prompt + mvprintw(window_height - 1, 0, ":%s", command.c_str()); + clrtoeol(); + refresh(); + + while ((cmd_ch = getch()) != '\n' && cmd_ch != '\r') { + if (cmd_ch == 27) { // ESC - cancel command + break; + } else if (cmd_ch == KEY_BACKSPACE || cmd_ch == 127) { + if (!command.empty()) { + command.pop_back(); + } + } else if (cmd_ch >= 32 && cmd_ch <= 126) { + command += static_cast(cmd_ch); + } + + mvprintw(window_height - 1, 0, ":%s", command.c_str()); + clrtoeol(); + refresh(); + } + + // Execute command + if (cmd_ch != 27) { // If not cancelled + switch (hash_djb2a(command)) { + case "q"_sh: + return; + break; + case "w"_sh: + save_document(text, lines); + break; + + case "wq"_sh: + case "x"_sh: + save_document(text, lines); + return; + break; + + case "q!"_sh: + return; + break; + } + } + } break; + } + break; + + case 'i': // Insert mode + switch (ch) { + case 27: // ESC + mode = 'n'; + if (cursor_x > 0) + cursor_x--; + break; + case KEY_BACKSPACE: + case 127: + if (mode == 'i' && cursor_x > 0) { + lines[cursor_y].erase(cursor_x - 1, 1); + cursor_x--; + } + break; + case '\n': + case '\r': { + // Insert new line + std::string new_line = lines[cursor_y].substr(cursor_x); + lines[cursor_y] = lines[cursor_y].substr(0, cursor_x); + lines.insert(lines.begin() + cursor_y + 1, new_line); + cursor_y++; + cursor_x = 0; + break; + } + default: + if (ch >= 32 && ch <= 126) { + if (mode == 'i') { + lines[cursor_y].insert(cursor_x, 1, ch); + cursor_x++; + } + } + break; + } + break; + } + } + } +} diff --git a/src/editor_hard.h b/src/editor_hard.h new file mode 100644 index 0000000..61cfd6b --- /dev/null +++ b/src/editor_hard.h @@ -0,0 +1,5 @@ +#ifndef PARADOCS_EDEH_H_ +#define PARADOCS_EDEH_H_ +#include +void editor_hard(std::string& text); +#endif \ No newline at end of file diff --git a/src/menu.cpp b/src/menu.cpp index a1383a8..bb0fdf2 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -17,15 +17,26 @@ #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 main_menu_allocated; #define COMPLAINTS_DIR "complaints" + +std::array get_name_date_from_item(ITEM* item) { + std::stringstream ss(item_description(item)); + std::array 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 */ @@ -165,6 +176,37 @@ void menu() { break; } + case "eh"_sh: { + std::array 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(); + 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)); @@ -172,11 +214,8 @@ void menu() { } break; case 'm': { - std::stringstream item_desc_ss( - item_description(current_item(main_menu.menu))); - std::string name_date[2]; - name_date[0] = item_name(current_item(main_menu.menu)); - std::getline(item_desc_ss, name_date[1], ' '); + std::array name_date = + get_name_date_from_item(current_item(main_menu.menu)); { uint8_t n = 0;