Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework Save-As; Abort saving if rename fails #1194

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
78 changes: 19 additions & 59 deletions src/dialogs.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,72 +487,29 @@ void dialogs_show_open_file(void)
}


static gboolean handle_save_as(const gchar *utf8_filename, gboolean rename_file)
{
GeanyDocument *doc = document_get_current();
gboolean success = FALSE;

g_return_val_if_fail(!EMPTY(utf8_filename), FALSE);

if (doc->file_name != NULL)
{
if (rename_file)
{
document_rename_file(doc, utf8_filename);
}
if (doc->tm_file)
{
/* create a new tm_source_file object otherwise tagmanager won't work correctly */
tm_workspace_remove_source_file(doc->tm_file);
tm_source_file_free(doc->tm_file);
doc->tm_file = NULL;
}
}
success = document_save_file_as(doc, utf8_filename);

build_menu_update(doc);
return success;
}


static gboolean save_as_dialog_handle_response(GtkWidget *dialog, gint response)
{
gboolean rename_file = FALSE;
gboolean success = FALSE;
if (response == GTK_RESPONSE_DELETE_EVENT || response == GTK_RESPONSE_CANCEL)
return TRUE;

gchar *new_filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
gboolean success = FALSE;

switch (response)
if (G_UNLIKELY(EMPTY(new_filename)))
utils_beep();
else
{
case GEANY_RESPONSE_RENAME:
/* rename doesn't check for empty filename or overwriting */
if (G_UNLIKELY(EMPTY(new_filename)))
{
utils_beep();
break;
}
if (g_file_test(new_filename, G_FILE_TEST_EXISTS) &&
!dialogs_show_question_full(NULL, NULL, NULL,
_("Overwrite?"),
_("Filename already exists!")))
break;
rename_file = TRUE;
/* fall through */
case GTK_RESPONSE_ACCEPT:
{
gchar *utf8_filename;
gchar *utf8_filename = utils_get_utf8_from_locale(new_filename);

utf8_filename = utils_get_utf8_from_locale(new_filename);
success = handle_save_as(utf8_filename, rename_file);
g_free(utf8_filename);
break;
}
case GTK_RESPONSE_DELETE_EVENT:
case GTK_RESPONSE_CANCEL:
success = TRUE;
break;
if (response == GEANY_RESPONSE_RENAME)
success = document_rename_and_save(document_get_current(), utf8_filename, TRUE);
else if (response == GTK_RESPONSE_ACCEPT)
success = document_save_file_as(document_get_current(), utf8_filename);

g_free(utf8_filename);
}
g_free(new_filename);

g_free(new_filename);
return success;
}

Expand Down Expand Up @@ -678,7 +635,10 @@ gboolean dialogs_show_save_as(void)
gchar *utf8_name = win32_show_document_save_as_dialog(GTK_WINDOW(main_widgets.window),
_("Save File"), doc);
if (utf8_name != NULL)
result = handle_save_as(utf8_name, FALSE);
{
result = document_save_file_as(doc, utf8_name);
g_free(utf8_name);
}
}
else
#endif
Expand Down
81 changes: 81 additions & 0 deletions src/document.c
Original file line number Diff line number Diff line change
Expand Up @@ -1764,6 +1764,76 @@ void document_rename_file(GeanyDocument *doc, const gchar *new_filename)
}


gboolean document_rename_file_and_save(GeanyDocument *doc, const gchar *new_filename)
{
g_return_val_if_fail(DOC_VALID(doc), FALSE);
g_return_val_if_fail(doc->file_name != NULL, FALSE);
g_return_val_if_fail(doc->real_path != NULL, FALSE);
g_return_val_if_fail(new_filename != NULL, FALSE);

gchar *old_locale_filename = utils_get_locale_from_utf8(doc->file_name);
gchar *new_locale_filename = utils_get_locale_from_utf8(new_filename);

FileDiskStatus orig_file_disk_status = doc->priv->file_disk_status;
document_stop_file_monitoring(doc);

gboolean success = g_rename(old_locale_filename, new_locale_filename) == 0;

if (success)
{
doc->priv->file_disk_status = FILE_CHANGED;
success = document_save_file_as(doc, new_filename);
}
else
{
dialogs_show_msgbox_with_secondary(GTK_MESSAGE_ERROR,
_("Error renaming file."), g_strerror(errno));
monitor_file_setup(doc);
doc->priv->file_disk_status = orig_file_disk_status;
}

g_free(new_locale_filename);
g_free(old_locale_filename);

return success;
}


gboolean document_rename_and_save(GeanyDocument *doc, const gchar *new_filename, gboolean ask_overwrite)
{
g_return_val_if_fail(DOC_VALID(doc), FALSE);
g_return_val_if_fail(new_filename != NULL, FALSE);

gchar *new_locale_filename = utils_get_locale_from_utf8(new_filename);
gboolean ret = FALSE;

if (g_file_test(new_locale_filename, G_FILE_TEST_EXISTS))
{
if (g_file_test(new_locale_filename, G_FILE_TEST_IS_DIR))
{
dialogs_show_msgbox(GTK_MESSAGE_ERROR,
_("A directory with the same name already exists."));
goto cleanup;
}

if (ask_overwrite)
if (!dialogs_show_question_full(main_widgets.window, NULL, NULL, _("Overwrite?"),
_("Filename already exists!")))
goto cleanup;
}

if (doc->file_name && doc->real_path)
ret = document_rename_file_and_save(doc, new_filename);
else
ret = document_save_file_as(doc, new_filename);

cleanup:
g_free(new_locale_filename);

return ret;
}


static void protect_document(GeanyDocument *doc)
{
/* do not call queue_colourise because to we want to keep the text-changed indication! */
Expand Down Expand Up @@ -1844,6 +1914,14 @@ gboolean document_save_file_as(GeanyDocument *doc, const gchar *utf8_fname)
doc->readonly = FALSE;
if (doc->priv->protected > 0)
unprotect_document(doc);

if (doc->tm_file)
{
/* create a new tm_source_file object otherwise tagmanager won't work correctly. */
tm_workspace_remove_source_file(doc->tm_file);
tm_source_file_free(doc->tm_file);
doc->tm_file = NULL;
}
}

replace_header_filename(doc);
Expand All @@ -1857,6 +1935,9 @@ gboolean document_save_file_as(GeanyDocument *doc, const gchar *utf8_fname)

if (ret)
ui_add_recent_document(doc);

build_menu_update(doc);

return ret;
}

Expand Down
4 changes: 4 additions & 0 deletions src/document.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@ void document_set_data(GeanyDocument *doc, const gchar *key, gpointer data);
void document_set_data_full(GeanyDocument *doc, const gchar *key,
gpointer data, GDestroyNotify free_func);

gboolean document_rename_file_and_save(GeanyDocument *doc, const gchar *new_filename);

gboolean document_rename_and_save(GeanyDocument *doc, const gchar *new_filename, gboolean ask_overwrite);

#endif /* GEANY_PRIVATE */

G_END_DECLS
Expand Down