Add drafts support to magiedit
This commit is contained in:
parent
4ba7eda791
commit
b2cbfdfd91
@ -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,13 +272,18 @@ 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;
|
||||
done = 0;
|
||||
q_position = 0;
|
||||
q_start = 0;
|
||||
|
||||
|
||||
memset(line, 0, 81);
|
||||
memset(line_cpy, 0, 81);
|
||||
|
||||
@ -163,6 +393,172 @@ char *message_editor() {
|
||||
} 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) {
|
||||
if (ch.chKeyPress == '\r' || (strlen(line) >= 73 && ch.chKeyPress > 31 && ch.chKeyPress != 127)) {
|
||||
@ -528,11 +924,12 @@ char *message_editor() {
|
||||
od_set_color(D_BLACK, D_MAGENTA);
|
||||
od_printf("%s", quote_lines[q_position]);
|
||||
od_clr_line();
|
||||
|
||||
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 (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) {
|
||||
@ -553,10 +950,12 @@ char *message_editor() {
|
||||
od_set_color(D_BLACK, D_MAGENTA);
|
||||
od_printf("%s", quote_lines[q_position]);
|
||||
od_clr_line();
|
||||
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 (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 {
|
||||
@ -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)) {
|
||||
|
Reference in New Issue
Block a user