Add drafts support to magiedit

This commit is contained in:
Andrew Pamment 2018-10-20 13:28:44 +10:00
parent 4ba7eda791
commit b2cbfdfd91

View File

@ -12,6 +12,9 @@
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/stat.h>
#include <limits.h>
#include <dirent.h>
char **quote_lines;
int quote_line_count;
@ -22,6 +25,228 @@ char *msgsubj;
char *msgarea;
int msgpriv;
char *draft_filename = NULL;
char *load_draft() {
DIR *dirp;
struct dirent *dent;
char draft_path[PATH_MAX];
char **filenames;
int filename_count = 0;
int redraw = 1;
int start = 0;
int selected = 0;
int i;
tODInputEvent ch;
snprintf(draft_path, PATH_MAX, "drafts/%s", od_control_get()->user_name);
dirp = opendir(draft_path);
if (!dirp) {
od_clr_scr();
od_printf("`bright red`You have no drafts!\r\n`white`");
od_printf("Press a key...");
od_get_key(TRUE);
return NULL;
}
while ((dent = readdir(dirp)) != NULL) {
if (strlen(dent->d_name) > 6 && strcmp(&dent->d_name[strlen(dent->d_name) - 6], ".draft") == 0) {
if (filename_count == 0) {
filenames = (char **)malloc(sizeof(char *));
} else {
filenames = (char **)realloc(filenames, sizeof(char *) * (filename_count + 1));
}
filenames[filename_count] = strndup(dent->d_name, strlen(dent->d_name) - 6);
filename_count++;
}
}
closedir(dirp);
if (filename_count == 0) {
od_clr_scr();
od_printf("`bright red`You have no drafts!\r\n`white`");
od_printf("Press a key...");
od_get_key(TRUE);
return NULL;
}
while (1) {
if (redraw) {
od_set_color(D_GREY, D_BLACK);
od_clr_scr();
od_set_color(D_BLACK, D_CYAN);
od_set_cursor(1, 1);
od_printf("Your Drafts:");
od_clr_line();
od_set_cursor(24, 1);
od_printf("Up/Down Select, Enter confirm, D to Delete");
od_clr_line();
for (i = start;i < start + 22 && i < filename_count; i++) {
if (i == selected) {
od_set_cursor(i - start + 2, 1);
od_set_color(D_BLACK, D_MAGENTA);
od_printf("%s", filenames[i]);
od_clr_line();
} else {
od_set_cursor(i - start + 2, 1);
od_set_color(D_GREY, D_BLACK);
od_printf("%s", filenames[i]);
od_clr_line();
}
}
redraw = 0;
}
od_get_input(&ch, OD_NO_TIMEOUT, GETIN_RAWCTRL);
if (ch.EventType == EVENT_EXTENDED_KEY) {
if (ch.chKeyPress == OD_KEY_UP) {
selected--;
if (selected < 0) {
selected = 0;
}
if (selected < start) {
start = start - 22;
if (start < 0) {
start = 0;
}
redraw = 1;
}
if (!redraw) {
od_set_cursor(selected - start + 2, 1);
od_set_color(D_BLACK, D_MAGENTA);
od_printf("%s", filenames[selected]);
od_clr_line();
if (filename_count > selected + 1) {
od_set_cursor(selected + 1 - start + 2, 1);
od_set_color(D_GREY, D_BLACK);
od_printf("%s", filenames[selected + 1]);
od_clr_line();
}
od_set_cursor(selected - start + 2, 1);
}
}
if (ch.chKeyPress == OD_KEY_DOWN) {
selected++;
if (selected >= filename_count) {
selected = filename_count - 1;
}
if (selected >= start + 22) {
start = start + 22;
if (start + 22 >= filename_count) {
start = filename_count - 22;
}
redraw = 1;
}
if (!redraw) {
od_set_cursor(selected - start + 2, 1);
od_set_color(D_BLACK, D_MAGENTA);
od_printf("%s", filenames[selected]);
od_clr_line();
if (selected - 1 >= 0) {
od_set_cursor(selected - 1 - start + 2, 1);
od_set_color(D_GREY, D_BLACK);
od_printf("%s", filenames[selected - 1]);
od_clr_line();
}
od_set_cursor(selected - start + 2, 1);
}
}
} else {
if (ch.chKeyPress == 27) {
// escape
for (i=0;i<filename_count;i++) {
free(filenames[i]);
}
free(filenames);
return NULL;
} else if (ch.chKeyPress == 13) {
draft_filename = strdup(filenames[selected]);
for (i=0;i<filename_count;i++) {
free(filenames[i]);
}
free(filenames);
return draft_filename;
} else if (ch.chKeyPress == 'd') {
snprintf(draft_path, PATH_MAX, "drafts/%s/%s.draft", od_control_get()->user_name, filenames[selected]);
unlink(draft_path);
free(filenames[selected]);
for (i=selected;i<filename_count - 1; i++) {
filenames[i] = filenames[i+1];
}
filename_count--;
if (filename_count == 0) {
free(filenames);
return NULL;
} else {
filenames = (char **)realloc(filenames, sizeof(char *) * filename_count);
}
redraw = 1;
selected--;
if (selected < 0) {
selected = 0;
}
}
}
}
}
void delete_draft(char *filename) {
char draft_path[PATH_MAX];
snprintf(draft_path, PATH_MAX, "drafts/%s/%s.draft", od_control_get()->user_name, filename);
unlink(draft_path);
}
int check_draft_filename(char *filename) {
struct stat s;
char draft_path[PATH_MAX];
int i;
for (i=0;i<strlen(filename);i++) {
if (!isalnum(filename[i])) {
filename[i] = '_';
}
}
if (stat("drafts", &s) != 0) {
mkdir("drafts", 0700);
}
snprintf(draft_path, PATH_MAX, "drafts/%s", od_control_get()->user_name);
if (stat(draft_path, &s) != 0) {
mkdir(draft_path, 0700);
}
snprintf(draft_path, PATH_MAX, "drafts/%s/%s.draft", od_control_get()->user_name, filename);
if (stat(draft_path, &s) != 0) {
return 1;
}
return 0;
}
char *message_editor() {
char **body_lines;
int body_line_count;
@ -47,6 +272,11 @@ char *message_editor() {
int old_top_of_screen = 0;
int stage = 0;
int qq_start;
int draft_ext;
char draft_path[PATH_MAX];
FILE *fptr;
char d_draft;
position_x = 0;
position_y = 0;
body_line_count = 0;
@ -162,6 +392,172 @@ char *message_editor() {
od_set_cursor(position_y - top_of_screen + 5, position_x + 1);
} else if (ch.chKeyPress == OD_KEY_HOME) {
position_x = 0;
od_set_cursor(position_y - top_of_screen + 5, position_x + 1);
} else if (ch.chKeyPress == OD_KEY_F9) {
// save as draft
if (draft_filename == NULL) {
draft_filename = strdup(msgsubj);
if (!check_draft_filename(draft_filename)) {
draft_ext = 0;
do {
draft_ext++;
free(draft_filename);
draft_filename = (char *)malloc(sizeof(char) * (strlen(msgsubj) + 4));
snprintf(draft_filename, strlen(msgsubj) + 4, "%s_%d", msgsubj, draft_ext);
} while (!check_draft_filename(draft_filename) && draft_ext < 999);
}
if (draft_ext == 1000) {
free(draft_filename);
draft_filename = NULL;
}
}
if (draft_filename != NULL) {
// save
// save message
body_len = 0;
for (i=0;i<position_y;i++) {
body_len = body_len + strlen(body_lines[i]) + 2;
}
body_len = body_len + strlen(line) + 2;
for (i=position_y;i<body_line_count;i++) {
body_len = body_len + strlen(body_lines[i]) + 2;
}
body_len++;
return_body = (char *)malloc(body_len);
memset(return_body, 0, body_len);
for (i=0;i<position_y;i++) {
strcat(return_body, body_lines[i]);
strcat(return_body, "\r\n");
}
strcat(return_body, line);
strcat(return_body, "\r\n");
for (i=position_y;i<body_line_count;i++) {
strcat(return_body, body_lines[i]);
strcat(return_body, "\r\n");
}
// write
snprintf(draft_path, PATH_MAX, "drafts/%s/%s.draft", od_control_get()->user_name, draft_filename);
fptr = fopen(draft_path, "w");
if (!fptr) {
od_printf("`bright red`Unable to save draft!\r\n`white`");
} else {
fwrite(return_body, 1, strlen(return_body), fptr);
fclose(fptr);
od_printf("`bright green`Draft saved as \"%s\".`white`\r\n", draft_filename);
}
free(return_body);
} else {
od_printf("`bright red`Unable to save draft!\r\n`white`");
}
od_printf("Press a key...");
od_get_key(TRUE);
od_set_color(D_GREY, D_BLACK);
// restore screen
od_clr_scr();
od_set_cursor(1, 1);
od_send_file("magiedit.ans");
od_set_color(D_GREY, D_BLACK);
od_set_cursor(2, 13);
od_printf("%-26.26s", msgto);
od_set_cursor(3, 13);
od_printf("%-26.26s", msgsubj);
od_set_cursor(2, 52);
od_printf("%-26.26s", msgarea);
od_set_cursor(5, 1);
if (position_y - top_of_screen > 17) {
top_of_screen = position_y - 17;
}
for (i=top_of_screen;i<top_of_screen + 17;i++) {
od_set_cursor(i - top_of_screen + 5, 1);
if (i < body_line_count) {
od_printf("%s", body_lines[i]);
}
od_clr_line();
}
position_x = 0;
memset(line, 0, 81);
od_set_cursor(position_y - top_of_screen + 5, position_x + 1);
} else if (ch.chKeyPress == OD_KEY_F10) {
// load draft
if (load_draft() != NULL) {
snprintf(draft_path, PATH_MAX, "drafts/%s/%s.draft", od_control_get()->user_name, draft_filename);
fptr = fopen(draft_path, "r");
if (!fptr) {
// error loading draft
} else {
// free body lines;
if (body_line_count > 0) {
for (i=0;i<body_line_count;i++) {
free(body_lines[i]);
}
free(body_lines);
body_line_count = 0;
}
position_x = 0;
position_y = 0;
fgets(line, 80, fptr);
while (!feof(fptr)) {
if (body_line_count == 0) {
body_lines = (char **)malloc(sizeof(char *));
} else {
body_lines = (char **)realloc(body_lines, sizeof(char *) * (body_line_count + 1));
}
body_lines[body_line_count] = (char *)malloc(strlen(line));
snprintf(body_lines[body_line_count], strlen(line) - 1, "%s", line);
body_line_count++;
position_y++;
fgets(line, 80, fptr);
}
fclose(fptr);
}
}
od_set_color(D_GREY, D_BLACK);
// restore screen
od_clr_scr();
od_set_cursor(1, 1);
od_send_file("magiedit.ans");
od_set_color(D_GREY, D_BLACK);
od_set_cursor(2, 13);
od_printf("%-26.26s", msgto);
od_set_cursor(3, 13);
od_printf("%-26.26s", msgsubj);
od_set_cursor(2, 52);
od_printf("%-26.26s", msgarea);
od_set_cursor(5, 1);
if (position_y - top_of_screen > 17) {
top_of_screen = position_y - 17;
}
for (i=top_of_screen;i<top_of_screen + 17;i++) {
od_set_cursor(i - top_of_screen + 5, 1);
if (i < body_line_count) {
od_printf("%s", body_lines[i]);
}
od_clr_line();
}
position_x = 0;
memset(line, 0, 81);
od_set_cursor(position_y - top_of_screen + 5, position_x + 1);
}
} else if (ch.EventType == EVENT_CHARACTER) {
@ -528,13 +924,14 @@ char *message_editor() {
od_set_color(D_BLACK, D_MAGENTA);
od_printf("%s", quote_lines[q_position]);
od_clr_line();
if (q_position + 1 < quote_line_count) {
od_set_cursor(q_position + 1 - q_start + 16, 1);
od_set_color(D_BLACK, D_MAGENTA);
od_printf("%s", quote_lines[q_position + 1]);
od_clr_line();
}
}
}
if (ch.chKeyPress == OD_KEY_DOWN) {
q_position++;
if (q_position >= quote_line_count) {
@ -553,12 +950,14 @@ char *message_editor() {
od_set_color(D_BLACK, D_MAGENTA);
od_printf("%s", quote_lines[q_position]);
od_clr_line();
if (q_position - 1 >= 0) {
od_set_cursor(q_position - 1 - q_start + 16, 1);
od_set_color(D_BLACK, D_MAGENTA);
od_printf("%s", quote_lines[q_position - 1]);
od_clr_line();
}
}
}
} else {
if (ch.chKeyPress == 17) {
// do quote
@ -737,6 +1136,17 @@ char *message_editor() {
free(body_lines);
}
od_clr_scr();
if (draft_filename != NULL) {
od_printf("`bright white`Delete draft \"%s\"? (Y/N) ", draft_filename);
d_draft = od_get_answer("YyNn");
if (tolower(d_draft) == 'y') {
delete_draft(draft_filename);
}
}
return return_body;
} else if (ch.chKeyPress != '\n' && ch.chKeyPress != 0x1b) {
if (position_x >= strlen(line)) {