SF.net SVN: geany:[3495] trunk
eht16 at users.sourceforge.net
eht16 at xxxxx
Wed Jan 21 15:50:48 UTC 2009
Revision: 3495
http://geany.svn.sourceforge.net/geany/?rev=3495&view=rev
Author: eht16
Date: 2009-01-21 15:50:48 +0000 (Wed, 21 Jan 2009)
Log Message:
-----------
Use an unique "monitor" prefix for file monitoring functions.
Don't check disk status for files which are marked to be ignored.
Reset file disk status when manually reloading a file.
Various improvements to the GIO-based file disk checking code.
Modified Paths:
--------------
trunk/ChangeLog
trunk/src/document.c
trunk/src/documentprivate.h
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2009-01-21 15:50:12 UTC (rev 3494)
+++ trunk/ChangeLog 2009-01-21 15:50:48 UTC (rev 3495)
@@ -2,6 +2,10 @@
* src/document.c:
Reuse the locale-encoded filename in document_save_file().
+ Use an unique "monitor" prefix for file monitoring functions.
+ Don't check disk status for files which are marked to be ignored.
+ Reset file disk status when manually reloading a file.
+ Various improvements to the GIO-based file disk checking code.
2009-01-20 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
Modified: trunk/src/document.c
===================================================================
--- trunk/src/document.c 2009-01-21 15:50:12 UTC (rev 3494)
+++ trunk/src/document.c 2009-01-21 15:50:48 UTC (rev 3495)
@@ -387,7 +387,31 @@
#ifdef HAVE_GIO
-static void file_monitor_changed_cb(G_GNUC_UNUSED GFileMonitor *monitor, G_GNUC_UNUSED GFile *file,
+/* Set the file status to 'changed' after a single 'created' event. */
+static gboolean monitor_finish_pending_create(gpointer doc)
+{
+ g_return_val_if_fail(doc != NULL, FALSE);
+
+ ((GeanyDocument *)doc)->priv->file_disk_status = FILE_CHANGED;
+ ui_update_tab_status(doc);
+
+ return FALSE;
+}
+
+
+/* Resets the 'ignore' file status after a reload action. */
+static gboolean monitor_reset_ignore(gpointer doc)
+{
+ g_return_val_if_fail(doc != NULL, FALSE);
+
+ ((GeanyDocument *)doc)->priv->file_disk_status = FILE_OK;
+ ui_update_tab_status(doc);
+
+ return FALSE;
+}
+
+
+static void monitor_file_changed_cb(G_GNUC_UNUSED GFileMonitor *monitor, G_GNUC_UNUSED GFile *file,
G_GNUC_UNUSED GFile *other_file, GFileMonitorEvent event, GeanyDocument *doc)
{
if (file_prefs.disk_check_timeout == 0)
@@ -395,11 +419,19 @@
switch (event)
{
- case G_FILE_MONITOR_EVENT_CHANGED:
+ case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
{
+ if (doc->priv->file_disk_status == FILE_CREATED_PENDING)
+ {
+ g_source_remove(doc->priv->last_check);
+ doc->priv->file_disk_status = FILE_IGNORE;
+ }
if (doc->priv->file_disk_status == FILE_IGNORE)
{ /* ignore this change completely, used after saving a file */
+ FileDiskStatus old_status = doc->priv->file_disk_status;
doc->priv->file_disk_status = FILE_OK;
+ if (old_status != FILE_OK)
+ ui_update_tab_status(doc);
return;
}
doc->priv->file_disk_status = FILE_CHANGED;
@@ -407,19 +439,42 @@
}
case G_FILE_MONITOR_EVENT_DELETED:
{
- doc->priv->file_disk_status = FILE_MISSING;
+ if (doc->priv->file_disk_status != FILE_IGNORE)
+ doc->priv->file_disk_status = FILE_MISSING;
break;
}
+ case G_FILE_MONITOR_EVENT_CREATED:
+ {
+ if (doc->priv->file_disk_status == FILE_MISSING)
+ { /* When the last state was 'missing', we are most probably in a
+ * delete-create-change set, so set the new state to 'ok' and do the real handling
+ * in the upcoming G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT event. */
+ doc->priv->file_disk_status = FILE_OK;
+ }
+ else
+ { /* In case we have a single 'created' event and not within a set of other events,
+ * we defer the processing into a timeout function which is removed when a
+ * G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT event arrives before. */
+ doc->priv->file_disk_status = FILE_CREATED_PENDING;
+ /* re-use otherwise unused 'last_check' field to store the timeout ID, we need it
+ * to remove the timeout and we need to store it per-document */
+ doc->priv->last_check = g_timeout_add(2000, monitor_finish_pending_create, doc);
+ }
+ if (doc->real_path == NULL)
+ {
+ gchar *locale_filename = g_file_get_path(file);
+ doc->real_path = tm_get_real_path(locale_filename);
+ g_free(locale_filename);
+ }
+ break;
+ }
/* ignore */
- case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+ case G_FILE_MONITOR_EVENT_CHANGED:
case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
case G_FILE_MONITOR_EVENT_UNMOUNTED:
- /* we ignore 'created' for now since it causes trouble when renaming files */
- case G_FILE_MONITOR_EVENT_CREATED:
return;
}
-
if (doc->priv->file_disk_status != FILE_OK)
{
ui_update_tab_status(doc);
@@ -440,7 +495,7 @@
}
-static void file_monitor_setup(GeanyDocument *doc)
+static void monitor_file_setup(GeanyDocument *doc)
{
g_return_if_fail(doc != NULL);
/* Disable file monitoring completely for remote files (i.e. remote GIO files) as GFileMonitor
@@ -460,7 +515,8 @@
/* get a file monitor and connect to the 'changed' signal */
file = g_file_new_for_path(locale_filename);
doc->priv->monitor = g_file_monitor_file(file, G_FILE_MONITOR_NONE, NULL, NULL);
- g_signal_connect(doc->priv->monitor, "changed", G_CALLBACK(file_monitor_changed_cb), doc);
+ g_signal_connect(doc->priv->monitor, "changed",
+ G_CALLBACK(monitor_file_changed_cb), doc);
/* we set the rate limit according to the GUI pref but it's most probably not used */
g_file_monitor_set_rate_limit(doc->priv->monitor, file_prefs.disk_check_timeout * 1000);
@@ -687,7 +743,7 @@
sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin, 0);
sci_goto_pos(doc->editor->sci, 0, TRUE);
- file_monitor_setup(doc);
+ monitor_file_setup(doc);
/* "the" SCI signal (connect after initial setup(i.e. adding text)) */
g_signal_connect(doc->editor->sci, "sci-notify", G_CALLBACK(editor_sci_notify_cb), doc->editor);
@@ -1177,8 +1233,12 @@
doc = document_create(utf8_filename);
g_return_val_if_fail(doc != NULL, NULL); /* really should not happen */
+ /* file exists on disk, set real_path */
+ g_free(doc->real_path);
+ doc->real_path = tm_get_real_path(locale_filename);
+
doc->priv->is_remote = utils_is_remote_path(locale_filename);
- file_monitor_setup(doc);
+ monitor_file_setup(doc);
}
sci_set_undo_collection(doc->editor->sci, FALSE); /* avoid creation of an undo action */
@@ -1214,9 +1274,6 @@
if (! reload)
{
- /* file exists on disk, set real_path */
- g_free(doc->real_path);
- doc->real_path = tm_get_real_path(locale_filename);
/* "the" SCI signal (connect after initial setup(i.e. adding text)) */
g_signal_connect(doc->editor->sci, "sci-notify", G_CALLBACK(editor_sci_notify_cb),
@@ -1321,7 +1378,6 @@
}
}
-
/**
* Reloads the @a document with the specified file encoding
* @a forced_enc or @c NULL to auto-detect the file encoding.
@@ -1343,6 +1399,15 @@
pos = sci_get_current_position(doc->editor->sci);
new_doc = document_open_file_full(doc, NULL, pos, doc->readonly,
doc->file_type, forced_enc);
+#ifdef HAVE_GIO
+ if (new_doc != NULL)
+ {
+ doc->priv->file_disk_status = FILE_IGNORE;
+ /* In case the reload operation didn't produce any events to ignore,
+ * remove the ignore status. */
+ g_timeout_add(5000, monitor_reset_ignore, doc);
+ }
+#endif
return (new_doc != NULL);
}
@@ -1490,7 +1555,7 @@
/* file monitoring support, add file monitoring after the file has been saved
* to ignore any earlier events */
- file_monitor_setup(doc);
+ monitor_file_setup(doc);
doc->priv->file_disk_status = FILE_IGNORE;
if (ret)
@@ -2724,7 +2789,7 @@
}
-static gboolean check_reload(GeanyDocument *doc)
+static gboolean monitor_reload_file(GeanyDocument *doc)
{
gchar *base_name = g_path_get_basename(doc->file_name);
gboolean want_reload;
@@ -2742,7 +2807,7 @@
}
-static gboolean check_resave_missing_file(GeanyDocument *doc)
+static gboolean monitor_resave_missing_file(GeanyDocument *doc)
{
gboolean want_reload = FALSE;
@@ -2762,7 +2827,7 @@
}
-static time_t check_disk_status_real(GeanyDocument *doc, gboolean force)
+static time_t monitor_check_status_real(GeanyDocument *doc, gboolean force)
{
time_t t = 0;
#ifndef HAVE_GIO
@@ -2813,21 +2878,27 @@
if (doc->real_path == NULL || doc->priv->is_remote)
return FALSE;
+ /* when we saved a file recently, we want to ignore any changes */
+ if (doc->priv->file_disk_status == FILE_IGNORE)
+ {
+ return FALSE;
+ }
+
/* check the file's mtime in case we don't have GIO support, otherwise this is a no-op */
- t = check_disk_status_real(doc, force);
+ t = monitor_check_status_real(doc, force);
switch (doc->priv->file_disk_status)
{
case FILE_CHANGED:
{
- check_reload(doc);
+ monitor_reload_file(doc);
doc->priv->mtime = t;
ret = TRUE;
break;
}
case FILE_MISSING:
{
- check_resave_missing_file(doc);
+ monitor_resave_missing_file(doc);
ret = TRUE;
break;
}
Modified: trunk/src/documentprivate.h
===================================================================
--- trunk/src/documentprivate.h 2009-01-21 15:50:12 UTC (rev 3494)
+++ trunk/src/documentprivate.h 2009-01-21 15:50:48 UTC (rev 3495)
@@ -42,6 +42,7 @@
FILE_OK,
FILE_CHANGED,
FILE_MISSING,
+ FILE_CREATED_PENDING,
FILE_IGNORE
}
FileDiskStatus;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Commits
mailing list