[gnome-builder] libide: add IdeBuffer:read-only and IdeBuffer:changed-on-volume
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] libide: add IdeBuffer:read-only and IdeBuffer:changed-on-volume
- Date: Tue, 24 Mar 2015 00:37:15 +0000 (UTC)
commit bddb85cd2e0463c7f80c3f79787328206ed06e4e
Author: Christian Hergert <christian hergert me>
Date: Sun Mar 22 18:45:32 2015 -0700
libide: add IdeBuffer:read-only and IdeBuffer:changed-on-volume
These will help us notify the user of various scenarios that could make
saving the file dangerous.
libide/ide-buffer.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++++-
libide/ide-buffer.h | 3 +
2 files changed, 164 insertions(+), 4 deletions(-)
---
diff --git a/libide/ide-buffer.c b/libide/ide-buffer.c
index 82e640f..b0d98e5 100644
--- a/libide/ide-buffer.c
+++ b/libide/ide-buffer.c
@@ -59,10 +59,15 @@ typedef struct
guint diagnose_timeout;
+ GTimeVal mtime;
+
+ guint changed_on_volume : 1;
guint diagnostics_dirty : 1;
guint highlight_diagnostics : 1;
guint in_diagnose : 1;
guint loading : 1;
+ guint mtime_set : 1;
+ guint read_only : 1;
} IdeBufferPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (IdeBuffer, ide_buffer, GTK_SOURCE_TYPE_BUFFER)
@@ -70,9 +75,11 @@ G_DEFINE_TYPE_WITH_PRIVATE (IdeBuffer, ide_buffer, GTK_SOURCE_TYPE_BUFFER)
enum {
PROP_0,
PROP_BUSY,
+ PROP_CHANGED_ON_VOLUME,
PROP_CONTEXT,
PROP_FILE,
PROP_HIGHLIGHT_DIAGNOSTICS,
+ PROP_READ_ONLY,
PROP_STYLE_SCHEME_NAME,
PROP_TITLE,
LAST_PROP
@@ -762,6 +769,10 @@ ide_buffer_get_property (GObject *object,
g_value_set_boolean (value, ide_buffer_get_busy (self));
break;
+ case PROP_CHANGED_ON_VOLUME:
+ g_value_set_boolean (value, ide_buffer_get_changed_on_volume (self));
+ break;
+
case PROP_CONTEXT:
g_value_set_object (value, ide_buffer_get_context (self));
break;
@@ -774,6 +785,10 @@ ide_buffer_get_property (GObject *object,
g_value_set_boolean (value, ide_buffer_get_highlight_diagnostics (self));
break;
+ case PROP_READ_ONLY:
+ g_value_set_boolean (value, ide_buffer_get_read_only (self));
+ break;
+
case PROP_TITLE:
g_value_set_string (value, ide_buffer_get_title (self));
break;
@@ -841,8 +856,16 @@ ide_buffer_class_init (IdeBufferClass *klass)
_("If the buffer is performing background work."),
FALSE,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_BUSY,
- gParamSpecs [PROP_BUSY]);
+ g_object_class_install_property (object_class, PROP_BUSY, gParamSpecs [PROP_BUSY]);
+
+ gParamSpecs [PROP_CHANGED_ON_VOLUME] =
+ g_param_spec_boolean ("changed-on-volume",
+ _("Changed on Volume"),
+ _("If the file has changed on disk and the buffer is not in sync."),
+ FALSE,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_CHANGED_ON_VOLUME,
+ gParamSpecs [PROP_CHANGED_ON_VOLUME]);
gParamSpecs [PROP_CONTEXT] =
g_param_spec_object ("context",
@@ -852,8 +875,7 @@ ide_buffer_class_init (IdeBufferClass *klass)
(G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_CONTEXT,
- gParamSpecs [PROP_CONTEXT]);
+ g_object_class_install_property (object_class, PROP_CONTEXT, gParamSpecs [PROP_CONTEXT]);
gParamSpecs [PROP_FILE] =
g_param_spec_object ("file",
@@ -872,6 +894,14 @@ ide_buffer_class_init (IdeBufferClass *klass)
g_object_class_install_property (object_class, PROP_HIGHLIGHT_DIAGNOSTICS,
gParamSpecs [PROP_HIGHLIGHT_DIAGNOSTICS]);
+ gParamSpecs [PROP_READ_ONLY] =
+ g_param_spec_boolean ("read-only",
+ _("Read Only"),
+ _("If the underlying file is read only."),
+ FALSE,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_READ_ONLY, gParamSpecs [PROP_READ_ONLY]);
+
gParamSpecs [PROP_STYLE_SCHEME_NAME] =
g_param_spec_string ("style-scheme-name",
_("Style Scheme Name"),
@@ -1411,3 +1441,130 @@ _ide_buffer_set_loading (IdeBuffer *self,
}
}
}
+
+gboolean
+ide_buffer_get_read_only (IdeBuffer *self)
+{
+ IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
+
+ g_return_val_if_fail (IDE_IS_BUFFER (self), FALSE);
+
+ return priv->read_only;
+}
+
+static void
+ide_buffer_set_read_only (IdeBuffer *self,
+ gboolean read_only)
+{
+ IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_BUFFER (self));
+
+ read_only = !!read_only;
+
+ if (read_only != priv->read_only)
+ {
+ priv->read_only = read_only;
+ g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_READ_ONLY]);
+ }
+}
+
+/**
+ * ide_buffer_get_changed_on_volume:
+ * @self: A #IdeBuffer.
+ *
+ * Gets if the file backing the buffer has changed on the underlying storage.
+ *
+ * Use ide_buffer_manager_load_file_async() to reload the buffer.
+ *
+ * Returns: %TRUE if the file has changed.
+ */
+gboolean
+ide_buffer_get_changed_on_volume (IdeBuffer *self)
+{
+ IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
+
+ g_return_val_if_fail (IDE_IS_BUFFER (self), FALSE);
+
+ return priv->changed_on_volume;
+}
+
+static void
+ide_buffer_set_changed_on_volumne (IdeBuffer *self,
+ gboolean changed_on_volume)
+{
+ IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_BUFFER (self));
+
+ changed_on_volume = !!changed_on_volume;
+
+ if (changed_on_volume != priv->changed_on_volume)
+ {
+ priv->changed_on_volume = changed_on_volume;
+ g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_CHANGED_ON_VOLUME]);
+ }
+}
+
+static void
+ide_buffer__check_for_volume_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ g_autoptr(IdeBuffer) self = user_data;
+ IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
+ g_autoptr(GFileInfo) file_info = NULL;
+ GFile *file = (GFile *)object;
+
+ g_assert (IDE_IS_BUFFER (self));
+ g_assert (G_IS_FILE (file));
+
+ file_info = g_file_query_info_finish (file, result, NULL);
+
+ if (file_info != NULL)
+ {
+ if (g_file_info_has_attribute (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
+ {
+ gboolean read_only;
+
+ read_only = !g_file_info_get_attribute_boolean (file_info,
+ G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
+ ide_buffer_set_read_only (self, read_only);
+ }
+
+ if (g_file_info_has_attribute (file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED) && priv->mtime_set)
+ {
+ GTimeVal tv;
+
+ g_file_info_get_modification_time (file_info, &tv);
+
+ if (memcmp (&tv, &priv->mtime, sizeof tv) != 0)
+ ide_buffer_set_changed_on_volumne (self, TRUE);
+ }
+ }
+}
+
+void
+ide_buffer_check_for_volume_change (IdeBuffer *self)
+{
+ IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
+ GFile *location;
+
+ g_return_if_fail (IDE_IS_BUFFER (self));
+
+ if (priv->changed_on_volume)
+ return;
+
+ location = ide_file_get_file (priv->file);
+ if (location == NULL)
+ return;
+
+ g_file_query_info_async (location,
+ G_FILE_ATTRIBUTE_TIME_MODIFIED ","
+ G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
+ G_FILE_QUERY_INFO_NONE,
+ G_PRIORITY_DEFAULT,
+ NULL, /* Plumb to shutdown cancellable? */
+ ide_buffer__check_for_volume_cb,
+ g_object_ref (self));
+}
diff --git a/libide/ide-buffer.h b/libide/ide-buffer.h
index b43ddc4..aa17d8b 100644
--- a/libide/ide-buffer.h
+++ b/libide/ide-buffer.h
@@ -63,6 +63,7 @@ struct _IdeBuffer
G_DEFINE_AUTOPTR_CLEANUP_FUNC (IdeBuffer, g_object_unref)
+gboolean ide_buffer_get_changed_on_volume (IdeBuffer *self);
GBytes *ide_buffer_get_content (IdeBuffer *self);
IdeContext *ide_buffer_get_context (IdeBuffer *self);
IdeDiagnostic *ide_buffer_get_diagnostic_at_iter (IdeBuffer *self,
@@ -70,6 +71,7 @@ IdeDiagnostic *ide_buffer_get_diagnostic_at_iter (IdeBuffer *sel
IdeFile *ide_buffer_get_file (IdeBuffer *self);
IdeBufferLineFlags ide_buffer_get_line_flags (IdeBuffer *buffer,
guint line);
+gboolean ide_buffer_get_read_only (IdeBuffer *self);
gboolean ide_buffer_get_highlight_diagnostics (IdeBuffer *self);
const gchar *ide_buffer_get_style_scheme_name (IdeBuffer *self);
const gchar *ide_buffer_get_title (IdeBuffer *self);
@@ -81,6 +83,7 @@ void ide_buffer_set_highlight_diagnostics (IdeBuffer *sel
void ide_buffer_set_style_scheme_name (IdeBuffer *self,
const gchar *style_scheme_name);
void ide_buffer_trim_trailing_whitespace (IdeBuffer *self);
+void ide_buffer_check_for_volume_change (IdeBuffer *self);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]