summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2021-01-30 11:52:25 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2021-01-30 11:52:25 -0500
commita61d90c32d4d6448148894872ebd91eb8f10fc2e (patch)
tree44d24f9b86064ba6ff706e4700865ebea65521a2
parent55fd631d86769e719f81206901bc1c3fb598fb5e (diff)
warn when closing tab with unsaved changes
-rw-r--r--command.c28
-rw-r--r--main.c2
-rw-r--r--menu.c60
-rw-r--r--ted.c3
-rw-r--r--ted.h8
5 files changed, 85 insertions, 16 deletions
diff --git a/command.c b/command.c
index 5acd922..a7ff287 100644
--- a/command.c
+++ b/command.c
@@ -111,6 +111,7 @@ void command_execute(Ted *ted, Command c, i64 argument) {
case MENU_SAVE_AS: {
ted->file_selector.submitted = true;
} break;
+ case MENU_WARN_UNSAVED: break;
}
} else {
buffer_newline(buffer);
@@ -173,8 +174,7 @@ void command_execute(Ted *ted, Command c, i64 argument) {
break;
case CMD_CUT:
if (buffer) buffer_cut(buffer);
- break;
- case CMD_PASTE:
+ break; case CMD_PASTE:
if (buffer) buffer_paste(buffer);
break;
@@ -194,12 +194,26 @@ void command_execute(Ted *ted, Command c, i64 argument) {
} break;
case CMD_TAB_CLOSE: {
- Node *node = ted->active_node;
- if (node) {
- node_tab_close(ted, node, node->active_tab);
+ if (ted->menu) {
+ menu_close(ted, true);
} else {
- command_execute(ted, CMD_QUIT, 1);
- return;
+ Node *node = ted->active_node;
+ if (node) {
+ u16 tab_idx = node->active_tab;
+ buffer = &ted->buffers[node->tabs[tab_idx]];
+ // (an argument of 2 overrides the unsaved changes dialog)
+ if (argument != 2 && buffer_unsaved_changes(buffer)) {
+ // there are unsaved changes!
+ ted->warn_unsaved = CMD_TAB_CLOSE;
+ strbuf_printf(ted->warn_unsaved_names, "%s", path_filename(buffer->filename));
+ menu_open(ted, MENU_WARN_UNSAVED);
+ } else {
+ node_tab_close(ted, node, node->active_tab);
+ }
+ } else {
+ command_execute(ted, CMD_QUIT, 1);
+ return;
+ }
}
} break;
case CMD_TAB_NEXT:
diff --git a/main.c b/main.c
index c7e12f7..8ef9aa2 100644
--- a/main.c
+++ b/main.c
@@ -47,9 +47,9 @@ no_warn_end
#include "ted.c"
#include "ui.c"
#include "node.c"
+#include "menu.c"
#include "command.c"
#include "config.c"
-#include "menu.c"
static void die(char const *fmt, ...) {
char buf[256] = {0};
diff --git a/menu.c b/menu.c
index 415b547..df3c7a0 100644
--- a/menu.c
+++ b/menu.c
@@ -13,15 +13,29 @@ static void menu_open(Ted *ted, Menu menu) {
ted->active_buffer = &ted->line_buffer;
ted->file_selector.create_menu = true;
break;
+ case MENU_WARN_UNSAVED:
+ assert(ted->warn_unsaved);
+ assert(*ted->warn_unsaved_names);
+ break;
}
}
static void menu_close(Ted *ted, bool restore_prev_active_buffer) {
- ted->menu = MENU_NONE;
if (restore_prev_active_buffer) ted->active_buffer = ted->prev_active_buffer;
ted->prev_active_buffer = NULL;
- file_selector_free(&ted->file_selector);
- buffer_clear(&ted->line_buffer);
+ switch (ted->menu) {
+ case MENU_NONE: assert(0); break;
+ case MENU_OPEN:
+ case MENU_SAVE_AS:
+ file_selector_free(&ted->file_selector);
+ buffer_clear(&ted->line_buffer);
+ break;
+ case MENU_WARN_UNSAVED:
+ ted->warn_unsaved = 0;
+ *ted->warn_unsaved_names = 0;
+ break;
+ }
+ ted->menu = MENU_NONE;
}
static void menu_escape(Ted *ted) {
@@ -108,6 +122,37 @@ static void menu_update(Ted *ted, Menu menu) {
free(selected_file);
}
} break;
+ case MENU_WARN_UNSAVED:
+ switch (popup_update(ted)) {
+ case POPUP_NONE: break;
+ case POPUP_YES:
+ // save changes
+ switch (ted->warn_unsaved) {
+ case CMD_TAB_CLOSE:
+ if (buffer_save(ted->prev_active_buffer)) {
+ menu_close(ted, true);
+ command_execute(ted, CMD_TAB_CLOSE, 1);
+ }
+ break;
+ case CMD_QUIT:
+ assert(0); // @TODO!
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ break;
+ case POPUP_NO: {
+ // pass in an argument of 2 to override dialog
+ Command cmd = ted->warn_unsaved;
+ menu_close(ted, true);
+ command_execute(ted, cmd, 2);
+ } break;
+ case POPUP_CANCEL:
+ menu_close(ted, true);
+ break;
+ }
+ break;
}
}
@@ -127,12 +172,19 @@ static void menu_render(Ted *ted, Menu menu) {
if (*ted->warn_overwrite) {
char const *path = ted->warn_overwrite;
char const *filename = path_filename(path);
- char title[32] = {0}, body[256] = {0};
+ char title[64] = {0}, body[1024] = {0};
strbuf_printf(title, "Overwrite %s?", filename);
strbuf_printf(body, "Are you sure you want to overwrite %s?", path);
popup_render(ted, title, body);
return;
}
+ if (menu == MENU_WARN_UNSAVED) {
+ char title[64] = {0}, body[1024] = {0};
+ strbuf_printf(title, "Save changes?");
+ strbuf_printf(body, "Do you want to save your changes to %s?", ted->warn_unsaved_names);
+ popup_render(ted, title, body);
+ return;
+ }
if (menu == MENU_OPEN || menu == MENU_SAVE_AS) {
float padding = settings->padding;
diff --git a/ted.c b/ted.c
index bc34123..431768e 100644
--- a/ted.c
+++ b/ted.c
@@ -196,6 +196,3 @@ static bool ted_new_file(Ted *ted) {
return false;
}
}
-
-static void menu_open(Ted *ted, Menu menu);
-static void menu_escape(Ted *ted);
diff --git a/ted.h b/ted.h
index 6271a6d..74b5145 100644
--- a/ted.h
+++ b/ted.h
@@ -79,7 +79,8 @@ typedef struct {
ENUM_U16 {
MENU_NONE,
MENU_OPEN,
- MENU_SAVE_AS
+ MENU_SAVE_AS,
+ MENU_WARN_UNSAVED // warn about unsaved changes
} ENUM_U16_END(Menu);
// file entries for file selectors
@@ -139,6 +140,8 @@ typedef struct Ted {
KeyAction key_actions[KEY_COMBO_COUNT];
bool search_cwd; // should the working directory be searched for files? set to true if the executable isn't "installed"
bool quit; // if set to true, the window will close next frame. NOTE: this doesn't check for unsaved changes!!
+ Command warn_unsaved; // if non-zero, the user is trying to execute this command, but there are unsaved changes
+ char warn_unsaved_names[TED_PATH_MAX]; // comma-separated list of files with unsaved changes (only applicable if warn_unsaved != 0)
char warn_overwrite[TED_PATH_MAX]; // file name user is trying to overwrite
char local_data_dir[TED_PATH_MAX];
char global_data_dir[TED_PATH_MAX];
@@ -151,3 +154,6 @@ typedef struct Ted {
char error[512];
char error_shown[512]; // error display in box on screen
} Ted;
+
+// forward declarations
+void command_execute(Ted *ted, Command c, i64 argument);