Branch: refs/heads/master
Author: Thomas Martitz <kugel(a)rockbox.org>
Committer: Thomas Martitz <kugel(a)rockbox.org>
Date: Sat, 24 May 2014 13:05:33 UTC
Commit: 100e0e1bf17e496dbe728a3637d199157d93b10e
https://github.com/geany/geany/commit/100e0e1bf17e496dbe728a3637d199157d93b…
Log Message:
-----------
infobars: Intercept some keys when the info bar is shown to allow interacting with it using the keyboard only.
When the info bar is shown tab/shift+tab and escape are intercepted.
* tab/shift+tab change the focus to the info bar buttons which can then be
cycled through with more tab presses
* escape closes the info bar (same as clicking cancel)
Both keys aren't needed for the document because it's read-only. Other keys,
such arrow/page up/down, remain to the document for navigating.
Modified Paths:
--------------
src/document.c
Modified: src/document.c
43 lines changed, 43 insertions(+), 0 deletions(-)
===================================================================
@@ -75,6 +75,8 @@
/*#define USE_GIO_FILEMON 1*/
#include <gio/gio.h>
+#include <gdk/gdkkeysyms.h>
+
GeanyFilePrefs file_prefs;
@@ -3152,6 +3154,45 @@ static void on_monitor_reload_file_response(GtkWidget *bar, gint response_id, Ge
doc->priv->info_bars[MSG_TYPE_RELOAD] = NULL;
}
+static gboolean on_sci_key(GtkWidget *w, GdkEventKey *event, gpointer data)
+{
+ GtkInfoBar *bar = GTK_INFO_BAR(data);
+
+ g_return_val_if_fail(event->type == GDK_KEY_PRESS, FALSE);
+
+ switch (event->keyval)
+ {
+ case GDK_KEY_Tab:
+ case GDK_KEY_ISO_Left_Tab:
+ {
+ GtkWidget *w = gtk_info_bar_get_action_area(bar);
+ GtkDirectionType dir = event->keyval == GDK_KEY_Tab ? GTK_DIR_TAB_FORWARD : GTK_DIR_TAB_BACKWARD;
+ gtk_widget_child_focus(w, dir);
+ return TRUE;
+ }
+ case GDK_KEY_Escape:
+ {
+ gtk_info_bar_response(bar, GTK_RESPONSE_CANCEL);
+ return TRUE;
+ }
+ default:
+ return FALSE;
+ }
+}
+
+/* g_signal_handlers_disconnect_by_data is a macro that cannot be used as GCallback */
+static gint nonmacro_g_signal_handlers_disconnect_by_data(gpointer instance, gpointer data)
+{
+ return g_signal_handlers_disconnect_by_data(instance, data);
+}
+
+static void enable_key_intercept(GeanyDocument *doc, GtkWidget *bar)
+{
+ g_signal_connect(doc->editor->sci, "key-press-event", G_CALLBACK(on_sci_key), bar);
+ /* make the signal disconnect automatically */
+ g_signal_connect_swapped(bar, "unrealize",
+ G_CALLBACK(nonmacro_g_signal_handlers_disconnect_by_data), doc->editor->sci);
+}
static void monitor_reload_file(GeanyDocument *doc)
{
@@ -3172,6 +3213,7 @@ static void monitor_reload_file(GeanyDocument *doc)
protect_document(doc);
doc->priv->info_bars[MSG_TYPE_RELOAD] = bar;
+ enable_key_intercept(doc, bar);
}
g_free(base_name);
}
@@ -3221,6 +3263,7 @@ static void monitor_resave_missing_file(GeanyDocument *doc)
protect_document(doc);
doc->priv->info_bars[MSG_TYPE_RESAVE] = bar;
+ enable_key_intercept(doc, bar);
}
}
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Thomas Martitz <kugel(a)rockbox.org>
Committer: Thomas Martitz <kugel(a)rockbox.org>
Date: Sat, 24 May 2014 13:05:15 UTC
Commit: 1dc96f1e50fad6d68ef1d27aa44ef25a9652db38
https://github.com/geany/geany/commit/1dc96f1e50fad6d68ef1d27aa44ef25a9652d…
Log Message:
-----------
infobars: Cancel "reload file" dialog when spawning the "resave file" one.
When the file was deleted from disk the message that the file is newer on
disk has become out of date and irrelevent.
Modified Paths:
--------------
src/document.c
Modified: src/document.c
3 lines changed, 3 insertions(+), 0 deletions(-)
===================================================================
@@ -3206,6 +3206,9 @@ static void monitor_resave_missing_file(GeanyDocument *doc)
if (doc->priv->info_bars[MSG_TYPE_RESAVE] == NULL)
{
GtkWidget *bar;
+ bar = doc->priv->info_bars[MSG_TYPE_RELOAD];
+ if (bar != NULL) /* the "file on disk is newer" warning is now moot */
+ gtk_info_bar_response(GTK_INFO_BAR(bar), GTK_RESPONSE_CANCEL);
bar = document_show_message(doc, GTK_MESSAGE_WARNING,
on_monitor_resave_missing_file_response,
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Thomas Martitz <kugel(a)rockbox.org>
Committer: Thomas Martitz <kugel(a)rockbox.org>
Date: Sat, 24 May 2014 13:05:14 UTC
Commit: 5117940ff6e6457b24e7ee0989d3092ff38bac7d
https://github.com/geany/geany/commit/5117940ff6e6457b24e7ee0989d3092ff38ba…
Log Message:
-----------
infobars: Make document read-only while infobar is shown.
This avoids accidental changes the file until the infobar is ackowledged. The
document can still be viewed and scrolled through but modifications and saving
are disabled. Of course ignoring the document by changing to another one is
also possible.
Modified Paths:
--------------
src/document.c
src/documentprivate.h
Modified: src/document.c
42 lines changed, 39 insertions(+), 3 deletions(-)
===================================================================
@@ -1238,6 +1238,7 @@ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename
doc->readonly = readonly || filedata.readonly;
sci_set_readonly(doc->editor->sci, doc->readonly);
+ doc->priv->protected = 0;
/* update line number margin width */
doc->priv->line_count = sci_get_line_count(doc->editor->sci);
@@ -1491,6 +1492,22 @@ void document_rename_file(GeanyDocument *doc, const gchar *new_filename)
}
+static void protect_document(GeanyDocument *doc)
+{
+ /* do not call queue_colourise because to we want to keep the text-changed indication! */
+ if (!doc->priv->protected++)
+ sci_set_readonly(doc->editor->sci, TRUE);
+}
+
+static void unprotect_document(GeanyDocument *doc)
+{
+ g_return_if_fail(doc->priv->protected > 0);
+
+ if (!--doc->priv->protected && doc->readonly == FALSE)
+ sci_set_readonly(doc->editor->sci, FALSE);
+}
+
+
/* Return TRUE if the document doesn't have a full filename set.
* This makes filenames without a path show the save as dialog, e.g. for file templates.
* Otherwise just use the set filename instead of asking the user - e.g. for command-line
@@ -1517,9 +1534,11 @@ gboolean document_need_save_as(GeanyDocument *doc)
gboolean document_save_file_as(GeanyDocument *doc, const gchar *utf8_fname)
{
gboolean ret;
+ gboolean new_file;
g_return_val_if_fail(doc != NULL, FALSE);
+ new_file = document_need_save_as(doc) || (utf8_fname != NULL && !strcmp(doc->file_name, utf8_fname));
if (utf8_fname != NULL)
SETPTR(doc->file_name, g_strdup(utf8_fname));
@@ -1539,6 +1558,15 @@ gboolean document_save_file_as(GeanyDocument *doc, const gchar *utf8_fname)
ignore_callback = FALSE;
}
}
+
+ if (new_file)
+ {
+ sci_set_readonly(doc->editor->sci, FALSE);
+ doc->readonly = FALSE;
+ if (doc->priv->protected > 0)
+ unprotect_document(doc);
+ }
+
replace_header_filename(doc);
ret = document_save_file(doc, TRUE);
@@ -1729,7 +1757,6 @@ static gchar *save_doc(GeanyDocument *doc, const gchar *locale_filename,
return NULL;
}
-
/**
* Saves the document.
* Also shows the Save As dialog if necessary.
@@ -1773,7 +1800,9 @@ gboolean document_save_file(GeanyDocument *doc, gboolean force)
}
/* the "changed" flag should exclude the "readonly" flag, but check it anyway for safety */
- if (! force && (! doc->changed || doc->readonly))
+ if (doc->readonly || doc->priv->protected)
+ return FALSE;
+ if (!force && !doc->changed)
return FALSE;
fp = project_get_file_prefs();
@@ -2928,6 +2957,7 @@ GeanyDocument *document_clone(GeanyDocument *old_doc)
old_doc->editor->indent_width);
doc->readonly = old_doc->readonly;
doc->has_bom = old_doc->has_bom;
+ doc->priv->protected = 0;
document_set_encoding(doc, old_doc->encoding);
sci_set_lines_wrapped(doc->editor->sci, doc->editor->line_wrapping);
sci_set_readonly(doc->editor->sci, doc->readonly);
@@ -3114,6 +3144,8 @@ static GtkWidget* document_show_message(GeanyDocument *doc, GtkMessageType msgty
static void on_monitor_reload_file_response(GtkWidget *bar, gint response_id, GeanyDocument *doc)
{
+ unprotect_document(doc);
+
if (response_id == GTK_RESPONSE_ACCEPT)
document_reload_file(doc, doc->encoding);
}
@@ -3131,7 +3163,7 @@ static void monitor_reload_file(GeanyDocument *doc)
_("The file '%s' on the disk is more recent than the current buffer."),
base_name);
- document_set_text_changed(doc, TRUE);
+ protect_document(doc);
g_free(base_name);
}
@@ -3143,6 +3175,8 @@ static void on_monitor_resave_missing_file_response(GtkWidget *bar,
{
gboolean file_saved = FALSE;
+ unprotect_document(doc);
+
if (response_id == GTK_RESPONSE_ACCEPT)
file_saved = dialogs_show_save_as();
@@ -3164,6 +3198,8 @@ static void monitor_resave_missing_file(GeanyDocument *doc)
_("Try to resave the file?"),
_("File \"%s\" was not found on disk!"),
doc->file_name);
+
+ protect_document(doc);
}
Modified: src/documentprivate.h
3 lines changed, 3 insertions(+), 0 deletions(-)
===================================================================
@@ -86,6 +86,9 @@ typedef struct GeanyDocumentPrivate
time_t mtime;
/* ID of the idle callback updating the tag list */
guint tag_list_update_source;
+ /* Whether it's temoporarily protected (read-only and saving is prevented). Does
+ * not imply doc->readonly as writable files can be protected */
+ gint protected;
}
GeanyDocumentPrivate;
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).