Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/editor.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ void editor_fileinfo_update (GuEditor* ec, const gchar* filename) {
struct stat attr;
stat(fname, &attr);
ec->last_modtime = attr.st_mtime;
ec->last_external_modtime = ec->last_modtime;

g_free (fname);
g_free (base);
Expand Down Expand Up @@ -305,6 +306,25 @@ void editor_fileinfo_cleanup (GuEditor* ec) {
ec->basename = NULL;
}

void editor_modtime_update (GuEditor* ec, gboolean loaded) {
struct stat attr;
stat(ec->filename, &attr);
if (loaded) ec->last_modtime = attr.st_mtime;
ec->last_external_modtime = attr.st_mtime;
}

gboolean editor_externally_modified (GuEditor* ec, gboolean since_loaded) {
struct stat attr;
stat(ec->filename, &attr);
time_t ref_time;
if (since_loaded) {
ref_time = ec->last_modtime;
} else {
ref_time = ec->last_external_modtime;
}
return difftime (ref_time, attr.st_mtime) != 0.0 && ref_time != 0.0;
}

void editor_sourceview_config (GuEditor* ec) {
GtkWrapMode wrapmode = 0;

Expand Down
5 changes: 4 additions & 1 deletion src/editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ struct _GuEditor {
gchar* bibfile;
gchar* projfile;
time_t last_modtime;
time_t last_external_modtime;

/* GUI related members */
GtkSourceView* view;
Expand All @@ -76,8 +77,10 @@ struct _GuEditor {

GuEditor* editor_new (GuMotion* mc);
void editor_fileinfo_update (GuEditor* ec, const gchar* filename);
void editor_fileinfo_cleanup (GuEditor* ec);
gboolean editor_fileinfo_update_biblio (GuEditor* ec, const gchar* filename);
void editor_fileinfo_cleanup (GuEditor* ec);
void editor_modtime_update (GuEditor* ec, gboolean external);
gboolean editor_externally_modified (GuEditor* ec, gboolean since_loaded);
void editor_destroy (GuEditor* ec);
void editor_sourceview_config (GuEditor* ec);
void editor_activate_spellchecking (GuEditor* ec, gboolean status);
Expand Down
78 changes: 53 additions & 25 deletions src/gui/gui-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,45 @@ void gui_set_window_title (const gchar* filename, const gchar* text) {
g_free (title);
}

gboolean on_focus_in_view (GtkWidget* widget, GdkEventFocus* event, GuTabContext* tab) {
slog (L_WARNING, "Focused in '%s' view.\n", tab->editor->filename);
if (editor_externally_modified (tab->editor, FALSE)) {
gui_external_changes_enable (tab);
}
return GDK_EVENT_PROPAGATE;
}

void on_reload_infobar_response (GtkInfoBar* bar, gint res, gpointer data) {
GuEditor* ec = data;
gboolean reload = res == GTK_RESPONSE_YES;
if (reload) {
tabmanager_set_content (A_LOAD, ec->filename, NULL);
}
editor_modtime_update (ec, reload);
gui_recovery_mode_disable (bar);
}

// based on gedit's external changes infobar
void gui_external_changes_enable (GuTabContext* tab) {
slog (L_WARNING, "The file '%s' changed on disk.\n", tab->editor->filename);
gchar* action_msg;
if (editor_buffer_changed (tab->editor)) {
action_msg = "Drop changes and reload?";
} else {
action_msg = "Reload?";
}
gchar* msg = g_strdup_printf ("The file %s changed on disk. %s", tab->editor->filename, action_msg);
gtk_label_set_text (GTK_LABEL (tab->page->barlabel), msg);
g_free (msg);

tab->page->infosignal =
g_signal_connect (g_active_tab->page->infobar, "response",
G_CALLBACK (on_reload_infobar_response), (gpointer)tab->editor);

gtk_widget_set_sensitive (GTK_WIDGET (tab->editor->view), FALSE);
gtk_widget_show (tab->page->infobar);
}

void on_recovery_infobar_response (GtkInfoBar* bar, gint res, gpointer filename) {
gchar* prev_workfile = iofunctions_get_swapfile (filename);

Expand All @@ -348,9 +387,10 @@ void on_recovery_infobar_response (GtkInfoBar* bar, gint res, gpointer filename)
void gui_recovery_mode_enable (GuTabContext* tab, const gchar* filename) {
gchar* prev_workfile = iofunctions_get_swapfile (filename);

slog (L_WARNING, "Swap file `%s' found.\n", prev_workfile);
gchar* msg = g_strdup_printf (_("Swap file exists for %s, "
"do you want to recover from it?"), filename);
slog (L_WARNING, "Swap file '%s' found.\n", prev_workfile);
gchar* msg = g_strdup_printf (
_("Swap file exists for %s. "
"Do you want to recover from it?"), filename);
gtk_label_set_text (GTK_LABEL (tab->page->barlabel), msg);
g_free (msg);

Expand All @@ -363,6 +403,7 @@ void gui_recovery_mode_enable (GuTabContext* tab, const gchar* filename) {
gtk_widget_show (tab->page->infobar);
}

// also used for external changes infobar. rename?
void gui_recovery_mode_disable (GtkInfoBar *infobar) {
gint id = g_active_tab->page->infosignal;
g_signal_handler_disconnect (infobar, id);
Expand Down Expand Up @@ -410,27 +451,17 @@ void gui_save_file (GuTabContext* tab, gboolean saveas) {
gchar *text;
GtkWidget* focus = NULL;

// check whether the file has been changed by (some) external program
double lastmod;
struct stat attr;
stat(filename, &attr);
lastmod = difftime (tab->editor->last_modtime, attr.st_mtime);

if (lastmod != 0.0 && tab->editor->last_modtime != 0.0 ) {
if (!new && editor_externally_modified (tab->editor, TRUE)) {
// ask the user whether he want to save or reload
ret = utils_save_reload_dialog (
ret = utils_save_confirmation_dialog (
_("The content of the file has been changed externally. "
"Saving will remove any external modifications."));
if (ret == GTK_RESPONSE_YES) {
tabmanager_set_content (A_LOAD, filename, NULL);
// resets modtime
stat(filename, &attr);
tab->editor->last_modtime = attr.st_mtime;
goto cleanup;
} else if (ret != GTK_RESPONSE_NO) {
// cancel means: do nothing
goto cleanup;
}
// clicking "Cancel" (which returns GTK_RESPONSE_NO) and pressing escape
// (which treturns something else) should both cancel the save. no
// cleanup is required, becaue `pdfname` hasn't had a chance to be
// allocated yet, and `!new` should guarantee that `filename` wasn't
// allocated earlier
if (ret != GTK_RESPONSE_YES) return;
}

focus = gtk_window_get_focus (gummi_get_gui ()->mainwindow);
Expand All @@ -447,10 +478,7 @@ void gui_save_file (GuTabContext* tab, gboolean saveas) {
if (new) tabmanager_update_tab (filename);
gui_set_filename_display (tab, TRUE, TRUE);
gtk_widget_grab_focus (GTK_WIDGET (tab->editor->view));

// Resets modtime
stat(filename, &attr);
tab->editor->last_modtime = attr.st_mtime;
editor_modtime_update (tab->editor, TRUE);

cleanup:
if (new) g_free (filename);
Expand Down
9 changes: 7 additions & 2 deletions src/gui/gui-main.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ void gui_open_file (const gchar* filename);
void gui_save_file (GuTabContext* tab, gboolean saveas);
void gui_set_hastabs_sensitive (gboolean enable);

void on_tab_notebook_switch_page (GtkNotebook *notebook, GtkWidget* nbpage, int pagenr, void* data);
void on_tab_notebook_switch_page (GtkNotebook *notebook, GtkWidget* nbpage,
int pagenr, void* data);
void on_tool_textstyle_bold_activate (GtkWidget* widget, void* user);
void on_tool_textstyle_italic_activate (GtkWidget* widget, void* user);
void on_tool_textstyle_underline_activate (GtkWidget* widget, void* user);
Expand All @@ -136,7 +137,6 @@ void on_button_template_open_clicked (GtkWidget* widget, void* user);
void on_button_template_close_clicked (GtkWidget* widget, void* user);
void on_template_rowitem_edited (GtkWidget* widget, gchar *path, gchar* filenm,
void* user);
void gui_recover_from_swapfile (const gchar* filename);
void on_menu_autosync_toggled (GtkCheckMenuItem *menu_autosync, void* user);

void on_button_biblio_compile_clicked (GtkWidget* widget, void* user);
Expand All @@ -146,6 +146,11 @@ void on_bibreference_clicked (GtkTreeView* view, GtkTreePath* Path,
void on_biblio_filter_changed (GtkWidget* widget, void* user);
gboolean on_bibprogressbar_update (void* data);

gboolean on_focus_in_view (GtkWidget* widget, GdkEventFocus* event, GuTabContext* tab);
void on_reload_infobar_response (GtkInfoBar* bar, gint res, gpointer filename);
void gui_external_changes_enable (GuTabContext* tab);
/* void gui_external_changes_disable (GtkInfoBar *infobar); */ // would currently be identical to gui_external_changes_disable

void on_recovery_infobar_response (GtkInfoBar* bar, gint res, gpointer filename);
void gui_recovery_mode_enable (GuTabContext* tab, const gchar* filename);
void gui_recovery_mode_disable (GtkInfoBar *infobar);
Expand Down
3 changes: 3 additions & 0 deletions src/gui/gui-tabmanager.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ int tabmanagergui_create_page (GuTabContext* tc, GuEditor* editor) {
gtk_box_pack_start (GTK_BOX (tp->editorbox), tp->infobar, FALSE, FALSE, 0);
gtk_box_pack_end (GTK_BOX (tp->editorbox), tp->scrollw, TRUE, TRUE, 0);

g_signal_connect_after (editor->view, "focus-in-event", G_CALLBACK (on_focus_in_view), tc);

pos = gtk_notebook_append_page (GTK_NOTEBOOK (g_tabnotebook),
tp->editorbox, GTK_WIDGET (tp->labelbox));

Expand Down Expand Up @@ -156,6 +158,7 @@ gint tabmanagergui_replace_page (GuTabContext* tc, GuEditor* newec) {
editor_destroy (g_active_editor);
gtk_container_add (GTK_CONTAINER (tc->page->scrollw),
GTK_WIDGET (newec->view));
g_signal_connect_after (newec->view, "focus-in-event", G_CALLBACK (on_focus_in_view), tc);
gtk_widget_show (GTK_WIDGET(newec->view));

int pos = gtk_notebook_page_num (g_tabnotebook,
Expand Down
4 changes: 2 additions & 2 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ void slog (gint level, const gchar *fmt, ...) {
exit (1);
}

gint utils_save_reload_dialog (const gchar* message) {
gint utils_save_confirmation_dialog (const gchar* message) {
GtkWidget* dialog;
gint ret = 0;

Expand All @@ -153,7 +153,7 @@ gint utils_save_reload_dialog (const gchar* message) {
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_NONE,
"%s", message);
gtk_dialog_add_buttons(GTK_DIALOG (dialog), "Reload", GTK_RESPONSE_YES, "Save", GTK_RESPONSE_NO, NULL);
gtk_dialog_add_buttons(GTK_DIALOG (dialog), "Cancel", GTK_RESPONSE_NO, "Save Anyway", GTK_RESPONSE_YES, NULL);

gtk_window_set_title (GTK_WINDOW (dialog), _("Confirmation"));
ret = gtk_dialog_run (GTK_DIALOG (dialog));
Expand Down
2 changes: 1 addition & 1 deletion src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ gboolean in_debug_mode();
void slog_set_gui_parent (GtkWindow* p);
void slog (gint level, const gchar *fmt, ...);
gint utils_yes_no_dialog (const gchar* message);
gint utils_save_reload_dialog (const gchar* message);
gint utils_save_confirmation_dialog (const gchar* message);
gboolean utils_path_exists (const gchar* path);
gboolean utils_uri_path_exists (const gchar* uri);
gboolean utils_set_file_contents (const gchar *filename, const gchar *text, gssize length);
Expand Down