Pull upstream fixes for gtk and gtksourceview changes
* fix errors in xed-metadata-manager * upstream changes for file loading and saving * modernize some code in xed-document Closes https://github.com/linuxmint/xed/issues/146
This commit is contained in:
parent
4c813f2c7f
commit
ef9294aae2
|
@ -149,8 +149,8 @@ PKG_CHECK_MODULES(XED, [
|
||||||
$GMODULE_ADD
|
$GMODULE_ADD
|
||||||
gthread-2.0 >= 2.13.0
|
gthread-2.0 >= 2.13.0
|
||||||
gio-2.0 >= 2.40.0
|
gio-2.0 >= 2.40.0
|
||||||
gtk+-3.0 >= 3.18.0
|
gtk+-3.0 >= 3.19.3
|
||||||
gtksourceview-3.0 >= 3.18.0
|
gtksourceview-3.0 >= 3.19.0
|
||||||
libpeas-1.0 >= 1.12.0
|
libpeas-1.0 >= 1.12.0
|
||||||
libpeas-gtk-1.0 >= 1.12.0
|
libpeas-gtk-1.0 >= 1.12.0
|
||||||
])
|
])
|
||||||
|
|
|
@ -40,10 +40,12 @@ NOINST_H_FILES = \
|
||||||
xed-close-button.h \
|
xed-close-button.h \
|
||||||
xed-close-confirmation-dialog.h \
|
xed-close-confirmation-dialog.h \
|
||||||
xed-dirs.h \
|
xed-dirs.h \
|
||||||
|
xed-document-private.h \
|
||||||
xed-documents-panel.h \
|
xed-documents-panel.h \
|
||||||
xed-encodings-dialog.h \
|
xed-encodings-dialog.h \
|
||||||
xed-history-entry.h \
|
xed-history-entry.h \
|
||||||
xed-io-error-info-bar.h \
|
xed-io-error-info-bar.h \
|
||||||
|
xed-metadata-manager.h \
|
||||||
xed-paned.h \
|
xed-paned.h \
|
||||||
xed-plugins-engine.h \
|
xed-plugins-engine.h \
|
||||||
xed-preferences-dialog.h \
|
xed-preferences-dialog.h \
|
||||||
|
@ -80,10 +82,6 @@ INST_H_FILES = \
|
||||||
xed-window.h \
|
xed-window.h \
|
||||||
xed-window-activatable.h
|
xed-window-activatable.h
|
||||||
|
|
||||||
if !ENABLE_GVFS_METADATA
|
|
||||||
NOINST_H_FILES += xed-metadata-manager.h
|
|
||||||
endif
|
|
||||||
|
|
||||||
headerdir = $(prefix)/include/xed
|
headerdir = $(prefix)/include/xed
|
||||||
|
|
||||||
header_DATA = \
|
header_DATA = \
|
||||||
|
@ -119,6 +117,7 @@ libxed_c_files = \
|
||||||
xed-message-bus.c \
|
xed-message-bus.c \
|
||||||
xed-message-type.c \
|
xed-message-type.c \
|
||||||
xed-message.c \
|
xed-message.c \
|
||||||
|
xed-metadata-manager.c \
|
||||||
xed-notebook.c \
|
xed-notebook.c \
|
||||||
xed-paned.c \
|
xed-paned.c \
|
||||||
xed-panel.c \
|
xed-panel.c \
|
||||||
|
@ -146,10 +145,6 @@ libxed_la_SOURCES = \
|
||||||
$(NOINST_H_FILES) \
|
$(NOINST_H_FILES) \
|
||||||
$(INST_H_FILES)
|
$(INST_H_FILES)
|
||||||
|
|
||||||
if !ENABLE_GVFS_METADATA
|
|
||||||
libxed_la_SOURCES += xed-metadata-manager.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
xed-enum-types.h: xed-enum-types.h.template $(INST_H_FILES) $(GLIB_MKENUMS)
|
xed-enum-types.h: xed-enum-types.h.template $(INST_H_FILES) $(GLIB_MKENUMS)
|
||||||
$(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template xed-enum-types.h.template $(INST_H_FILES)) > $@
|
$(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template xed-enum-types.h.template $(INST_H_FILES)) > $@
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,13 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "xed-close-confirmation-dialog.h"
|
||||||
|
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
#include "xed-close-confirmation-dialog.h"
|
|
||||||
#include <xed/xed-app.h>
|
#include <xed/xed-app.h>
|
||||||
|
#include <xed/xed-document.h>
|
||||||
|
#include <xed/xed-document-private.h>
|
||||||
#include <xed/xed-utils.h>
|
#include <xed/xed-utils.h>
|
||||||
#include <xed/xed-window.h>
|
#include <xed/xed-window.h>
|
||||||
|
|
||||||
|
|
|
@ -38,31 +38,27 @@
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "xed-debug.h"
|
||||||
|
#include "xed-document.h"
|
||||||
|
#include "xed-document-private.h"
|
||||||
#include "xed-commands.h"
|
#include "xed-commands.h"
|
||||||
#include "xed-window.h"
|
#include "xed-window.h"
|
||||||
#include "xed-window-private.h"
|
#include "xed-window-private.h"
|
||||||
#include "xed-statusbar.h"
|
#include "xed-statusbar.h"
|
||||||
#include "xed-debug.h"
|
|
||||||
#include "xed-utils.h"
|
#include "xed-utils.h"
|
||||||
#include "xed-file-chooser-dialog.h"
|
#include "xed-file-chooser-dialog.h"
|
||||||
#include "xed-close-confirmation-dialog.h"
|
#include "xed-close-confirmation-dialog.h"
|
||||||
|
|
||||||
/* Defined constants */
|
/* Defined constants */
|
||||||
#define XED_OPEN_DIALOG_KEY "xed-open-dialog-key"
|
#define XED_OPEN_DIALOG_KEY "xed-open-dialog-key"
|
||||||
#define XED_TAB_TO_SAVE_AS "xed-tab-to-save-as"
|
|
||||||
#define XED_LIST_OF_TABS_TO_SAVE_AS "xed-list-of-tabs-to-save-as"
|
|
||||||
#define XED_IS_CLOSING_ALL "xed-is-closing-all"
|
#define XED_IS_CLOSING_ALL "xed-is-closing-all"
|
||||||
#define XED_IS_QUITTING "xed-is-quitting"
|
#define XED_IS_QUITTING "xed-is-quitting"
|
||||||
#define XED_IS_CLOSING_TAB "xed-is-closing-tab"
|
|
||||||
#define XED_IS_QUITTING_ALL "xed-is-quitting-all"
|
#define XED_IS_QUITTING_ALL "xed-is-quitting-all"
|
||||||
|
|
||||||
static void tab_state_changed_while_saving (XedTab *tab,
|
static void tab_state_changed_while_saving (XedTab *tab,
|
||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
XedWindow *window);
|
XedWindow *window);
|
||||||
|
|
||||||
static void save_as_tab (XedTab *tab,
|
|
||||||
XedWindow *window);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_xed_cmd_file_new (GtkAction *action,
|
_xed_cmd_file_new (GtkAction *action,
|
||||||
XedWindow *window)
|
XedWindow *window)
|
||||||
|
@ -521,110 +517,73 @@ replace_read_only_file (GtkWindow *parent,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
save_finish_cb (XedTab *tab,
|
tab_save_as_ready_cb (XedTab *tab,
|
||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
gpointer user_data)
|
GTask *task)
|
||||||
{
|
{
|
||||||
_xed_tab_save_finish (tab, result);
|
gboolean success = _xed_tab_save_finish (tab, result);
|
||||||
|
g_task_return_boolean (task, success);
|
||||||
|
g_object_unref (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
save_dialog_response_cb (XedFileChooserDialog *dialog,
|
save_dialog_response_cb (XedFileChooserDialog *dialog,
|
||||||
gint response_id,
|
gint response_id,
|
||||||
XedWindow *window)
|
GTask *task)
|
||||||
{
|
{
|
||||||
XedTab *tab;
|
XedTab *tab;
|
||||||
gpointer data;
|
XedWindow *window;
|
||||||
GSList *tabs_to_save_as;
|
XedDocument *doc;
|
||||||
|
GtkSourceFile *file;
|
||||||
|
GFile *location;
|
||||||
|
gchar *parse_name;
|
||||||
|
GtkSourceNewlineType newline_type;
|
||||||
|
const GtkSourceEncoding *encoding;
|
||||||
|
|
||||||
xed_debug (DEBUG_COMMANDS);
|
xed_debug (DEBUG_COMMANDS);
|
||||||
|
|
||||||
tab = XED_TAB (g_object_get_data (G_OBJECT (dialog), XED_TAB_TO_SAVE_AS));
|
tab = g_task_get_source_object (task);
|
||||||
|
window = g_task_get_task_data (task);
|
||||||
|
|
||||||
if (response_id != GTK_RESPONSE_OK)
|
if (response_id != GTK_RESPONSE_OK)
|
||||||
{
|
{
|
||||||
gtk_widget_destroy (GTK_WIDGET (dialog));
|
gtk_widget_destroy (GTK_WIDGET (dialog));
|
||||||
|
|
||||||
goto save_next_tab;
|
g_task_return_boolean (task, FALSE);
|
||||||
}
|
g_object_unref (task);
|
||||||
|
|
||||||
if (tab != NULL)
|
|
||||||
{
|
|
||||||
GFile *location;
|
|
||||||
XedDocument *doc;
|
|
||||||
gchar *parse_name;
|
|
||||||
GtkSourceNewlineType newline_type;
|
|
||||||
const GtkSourceEncoding *encoding;
|
|
||||||
|
|
||||||
doc = xed_tab_get_document (tab);
|
|
||||||
|
|
||||||
location = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
|
||||||
g_return_if_fail (location != NULL);
|
|
||||||
|
|
||||||
encoding = xed_file_chooser_dialog_get_encoding (dialog);
|
|
||||||
newline_type = xed_file_chooser_dialog_get_newline_type (dialog);
|
|
||||||
|
|
||||||
gtk_widget_destroy (GTK_WIDGET (dialog));
|
|
||||||
|
|
||||||
doc = xed_tab_get_document (tab);
|
|
||||||
g_return_if_fail (XED_IS_DOCUMENT (doc));
|
|
||||||
|
|
||||||
parse_name = g_file_get_parse_name (location);
|
|
||||||
|
|
||||||
xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar),
|
|
||||||
window->priv->generic_message_cid,
|
|
||||||
_("Saving file '%s'\342\200\246"),
|
|
||||||
parse_name);
|
|
||||||
|
|
||||||
g_free (parse_name);
|
|
||||||
|
|
||||||
/* let's remember the dir we navigated too,
|
|
||||||
* even if the saving fails... */
|
|
||||||
_xed_window_set_default_location (window, location);
|
|
||||||
|
|
||||||
_xed_tab_save_as_async (tab,
|
|
||||||
location,
|
|
||||||
encoding,
|
|
||||||
newline_type,
|
|
||||||
NULL,
|
|
||||||
(GAsyncReadyCallback) save_finish_cb,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
g_object_unref (location);
|
|
||||||
}
|
|
||||||
|
|
||||||
save_next_tab:
|
|
||||||
|
|
||||||
data = g_object_get_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS);
|
|
||||||
if (data == NULL)
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save As the next tab of the list (we are Saving All files) */
|
doc = xed_tab_get_document (tab);
|
||||||
tabs_to_save_as = (GSList *)data;
|
location = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||||
g_return_if_fail (tab == XED_TAB (tabs_to_save_as->data));
|
g_return_if_fail (location != NULL);
|
||||||
|
|
||||||
/* Remove the first item of the list */
|
encoding = xed_file_chooser_dialog_get_encoding (dialog);
|
||||||
tabs_to_save_as = g_slist_delete_link (tabs_to_save_as, tabs_to_save_as);
|
newline_type = xed_file_chooser_dialog_get_newline_type (dialog);
|
||||||
|
|
||||||
g_object_set_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS, tabs_to_save_as);
|
gtk_widget_destroy (GTK_WIDGET (dialog));
|
||||||
|
|
||||||
if (tabs_to_save_as != NULL)
|
parse_name = g_file_get_parse_name (location);
|
||||||
{
|
|
||||||
tab = XED_TAB (tabs_to_save_as->data);
|
|
||||||
|
|
||||||
if (GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (tab), XED_IS_CLOSING_TAB)) == TRUE)
|
xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar),
|
||||||
{
|
window->priv->generic_message_cid,
|
||||||
g_object_set_data (G_OBJECT (tab), XED_IS_CLOSING_TAB, NULL);
|
_("Saving file '%s'\342\200\246"),
|
||||||
|
parse_name);
|
||||||
|
|
||||||
/* Trace tab state changes */
|
g_free (parse_name);
|
||||||
g_signal_connect (tab, "notify::state", G_CALLBACK (tab_state_changed_while_saving), window);
|
|
||||||
}
|
|
||||||
|
|
||||||
xed_window_set_active_tab (window, tab);
|
/* let's remember the dir we navigated too, even if the saving fails... */
|
||||||
save_as_tab (tab, window);
|
_xed_window_set_default_location (window, location);
|
||||||
}
|
|
||||||
|
_xed_tab_save_as_async (tab,
|
||||||
|
location,
|
||||||
|
encoding,
|
||||||
|
newline_type,
|
||||||
|
g_task_get_cancellable (task),
|
||||||
|
(GAsyncReadyCallback) tab_save_as_ready_cb,
|
||||||
|
task);
|
||||||
|
|
||||||
|
g_object_unref (location);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkFileChooserConfirmation
|
static GtkFileChooserConfirmation
|
||||||
|
@ -663,16 +622,20 @@ confirm_overwrite_callback (GtkFileChooser *dialog,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Call save_as_tab_finish() in @callback. */
|
||||||
static void
|
static void
|
||||||
save_as_tab (XedTab *tab,
|
save_as_tab_async (XedTab *tab,
|
||||||
XedWindow *window)
|
XedWindow *window,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
GTask *task;
|
||||||
GtkWidget *save_dialog;
|
GtkWidget *save_dialog;
|
||||||
GtkWindowGroup *wg;
|
GtkWindowGroup *wg;
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
GtkSourceFile *file;
|
GtkSourceFile *file;
|
||||||
GFile *location;
|
GFile *location;
|
||||||
gboolean uri_set = FALSE;
|
|
||||||
const GtkSourceEncoding *encoding;
|
const GtkSourceEncoding *encoding;
|
||||||
GtkSourceNewlineType newline_type;
|
GtkSourceNewlineType newline_type;
|
||||||
|
|
||||||
|
@ -681,6 +644,9 @@ save_as_tab (XedTab *tab,
|
||||||
|
|
||||||
xed_debug (DEBUG_COMMANDS);
|
xed_debug (DEBUG_COMMANDS);
|
||||||
|
|
||||||
|
task = g_task_new (tab, cancellable, callback, user_data);
|
||||||
|
g_task_set_task_data (task, g_object_ref (window), g_object_unref);
|
||||||
|
|
||||||
save_dialog = xed_file_chooser_dialog_new (_("Save As\342\200\246"),
|
save_dialog = xed_file_chooser_dialog_new (_("Save As\342\200\246"),
|
||||||
GTK_WINDOW (window),
|
GTK_WINDOW (window),
|
||||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||||
|
@ -706,11 +672,11 @@ save_as_tab (XedTab *tab,
|
||||||
|
|
||||||
if (location != NULL)
|
if (location != NULL)
|
||||||
{
|
{
|
||||||
uri_set = gtk_file_chooser_set_file (GTK_FILE_CHOOSER (save_dialog), location, NULL);
|
gtk_file_chooser_set_file (GTK_FILE_CHOOSER (save_dialog), location, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!uri_set)
|
else
|
||||||
{
|
{
|
||||||
GFile *default_path;
|
GFile *default_path;
|
||||||
gchar *docname;
|
gchar *docname;
|
||||||
|
@ -734,7 +700,7 @@ save_as_tab (XedTab *tab,
|
||||||
g_free (docname);
|
g_free (docname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set suggested encoding */
|
/* Set suggested encoding and newline type */
|
||||||
encoding = gtk_source_file_get_encoding (file);
|
encoding = gtk_source_file_get_encoding (file);
|
||||||
|
|
||||||
if (encoding == NULL)
|
if (encoding == NULL)
|
||||||
|
@ -748,39 +714,94 @@ save_as_tab (XedTab *tab,
|
||||||
|
|
||||||
xed_file_chooser_dialog_set_newline_type (XED_FILE_CHOOSER_DIALOG (save_dialog), newline_type);
|
xed_file_chooser_dialog_set_newline_type (XED_FILE_CHOOSER_DIALOG (save_dialog), newline_type);
|
||||||
|
|
||||||
g_object_set_data (G_OBJECT (save_dialog), XED_TAB_TO_SAVE_AS, tab);
|
g_signal_connect (save_dialog, "response", G_CALLBACK (save_dialog_response_cb), task);
|
||||||
|
|
||||||
g_signal_connect (save_dialog, "response", G_CALLBACK (save_dialog_response_cb), window);
|
|
||||||
|
|
||||||
gtk_widget_show (save_dialog);
|
gtk_widget_show (save_dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
save_tab (XedTab *tab,
|
save_as_tab_finish (XedTab *tab,
|
||||||
XedWindow *window)
|
GAsyncResult *result)
|
||||||
{
|
{
|
||||||
XedDocument *doc;
|
g_return_val_if_fail (g_task_is_valid (result, tab), FALSE);
|
||||||
|
|
||||||
|
return g_task_propagate_boolean (G_TASK (result), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
save_as_tab_ready_cb (XedTab *tab,
|
||||||
|
GAsyncResult *result,
|
||||||
|
GTask *task)
|
||||||
|
{
|
||||||
|
gboolean success = save_as_tab_finish (tab, result);
|
||||||
|
|
||||||
|
g_task_return_boolean (task, success);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tab_save_ready_cb (XedTab *tab,
|
||||||
|
GAsyncResult *result,
|
||||||
|
GTask *task)
|
||||||
|
{
|
||||||
|
gboolean success = _xed_tab_save_finish (tab, result);
|
||||||
|
|
||||||
|
g_task_return_boolean (task, success);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xed_commands_save_document_async:
|
||||||
|
* @document: the #XedDocument to save.
|
||||||
|
* @window: a #XedWindow.
|
||||||
|
* @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
|
||||||
|
* @callback: (scope async): a #GAsyncReadyCallback to call when the operation
|
||||||
|
* is finished.
|
||||||
|
* @user_data: (closure): the data to pass to the @callback function.
|
||||||
|
*
|
||||||
|
* Asynchronously save the @document. @document must belong to @window. The
|
||||||
|
* source object of the async task is @document (which will be the first
|
||||||
|
* parameter of the #GAsyncReadyCallback).
|
||||||
|
*
|
||||||
|
* When the operation is finished, @callback will be called. You can then call
|
||||||
|
* xed_commands_save_document_finish() to get the result of the operation.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xed_commands_save_document_async (XedDocument *document,
|
||||||
|
XedWindow *window,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GTask *task;
|
||||||
|
XedTab *tab;
|
||||||
gchar *uri_for_display;
|
gchar *uri_for_display;
|
||||||
|
|
||||||
xed_debug (DEBUG_COMMANDS);
|
xed_debug (DEBUG_COMMANDS);
|
||||||
|
|
||||||
g_return_if_fail (XED_IS_TAB (tab));
|
g_return_if_fail (XED_IS_DOCUMENT (document));
|
||||||
g_return_if_fail (XED_IS_WINDOW (window));
|
g_return_if_fail (XED_IS_WINDOW (window));
|
||||||
|
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||||
|
|
||||||
doc = xed_tab_get_document (tab);
|
task = g_task_new (document, cancellable, callback, user_data);
|
||||||
g_return_if_fail (XED_IS_DOCUMENT (doc));
|
|
||||||
|
|
||||||
if (xed_document_is_untitled (doc) ||
|
tab = xed_tab_get_from_document (document);
|
||||||
xed_document_get_readonly (doc))
|
|
||||||
|
if (xed_document_is_untitled (document) ||
|
||||||
|
xed_document_get_readonly (document))
|
||||||
{
|
{
|
||||||
xed_debug_message (DEBUG_COMMANDS, "Untitled or Readonly");
|
xed_debug_message (DEBUG_COMMANDS, "Untitled or Readonly");
|
||||||
|
|
||||||
save_as_tab (tab, window);
|
save_as_tab_async (tab,
|
||||||
|
window,
|
||||||
|
cancellable,
|
||||||
|
(GAsyncReadyCallback) save_as_tab_ready_cb,
|
||||||
|
task);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uri_for_display = xed_document_get_uri_for_display (doc);
|
uri_for_display = xed_document_get_uri_for_display (document);
|
||||||
xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar),
|
xed_statusbar_flash_message (XED_STATUSBAR (window->priv->statusbar),
|
||||||
window->priv->generic_message_cid,
|
window->priv->generic_message_cid,
|
||||||
_("Saving file '%s'\342\200\246"),
|
_("Saving file '%s'\342\200\246"),
|
||||||
|
@ -789,9 +810,53 @@ save_tab (XedTab *tab,
|
||||||
g_free (uri_for_display);
|
g_free (uri_for_display);
|
||||||
|
|
||||||
_xed_tab_save_async (tab,
|
_xed_tab_save_async (tab,
|
||||||
NULL,
|
cancellable,
|
||||||
(GAsyncReadyCallback) save_finish_cb,
|
(GAsyncReadyCallback) tab_save_ready_cb,
|
||||||
NULL);
|
task);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xed_commands_save_document_finish:
|
||||||
|
* @document: a #XedDocument.
|
||||||
|
* @result: a #GAsyncResult.
|
||||||
|
*
|
||||||
|
* Finishes an asynchronous document saving operation started with
|
||||||
|
* xed_commands_save_document_async().
|
||||||
|
*
|
||||||
|
* Note that there is no error parameter because the errors are already handled
|
||||||
|
* by xed.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the document has been correctly saved, %FALSE otherwise.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
xed_commands_save_document_finish (XedDocument *document,
|
||||||
|
GAsyncResult *result)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (g_task_is_valid (result, document), FALSE);
|
||||||
|
|
||||||
|
return g_task_propagate_boolean (G_TASK (result), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
save_tab_ready_cb (XedDocument *doc,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
xed_commands_save_document_finish (doc, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save tab asynchronously, but without results. */
|
||||||
|
static void
|
||||||
|
save_tab (XedTab *tab,
|
||||||
|
XedWindow *window)
|
||||||
|
{
|
||||||
|
XedDocument *doc = xed_tab_get_document (tab);
|
||||||
|
|
||||||
|
xed_commands_save_document_async (doc,
|
||||||
|
window,
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback) save_tab_ready_cb,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -803,12 +868,18 @@ _xed_cmd_file_save (GtkAction *action,
|
||||||
xed_debug (DEBUG_COMMANDS);
|
xed_debug (DEBUG_COMMANDS);
|
||||||
|
|
||||||
tab = xed_window_get_active_tab (window);
|
tab = xed_window_get_active_tab (window);
|
||||||
if (tab == NULL)
|
if (tab != NULL)
|
||||||
{
|
{
|
||||||
return;
|
save_tab (tab, window);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
save_tab (tab, window);
|
static void
|
||||||
|
_xed_cmd_file_save_as_cb (XedTab *tab,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
save_as_tab_finish (tab, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -820,12 +891,149 @@ _xed_cmd_file_save_as (GtkAction *action,
|
||||||
xed_debug (DEBUG_COMMANDS);
|
xed_debug (DEBUG_COMMANDS);
|
||||||
|
|
||||||
tab = xed_window_get_active_tab (window);
|
tab = xed_window_get_active_tab (window);
|
||||||
if (tab == NULL)
|
if (tab != NULL)
|
||||||
|
{
|
||||||
|
save_as_tab_async (tab,
|
||||||
|
window,
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback) _xed_cmd_file_save_as_cb,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
quit_if_needed (XedWindow *window)
|
||||||
|
{
|
||||||
|
gboolean is_quitting;
|
||||||
|
gboolean is_quitting_all;
|
||||||
|
|
||||||
|
is_quitting = GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (window), XED_IS_QUITTING));
|
||||||
|
|
||||||
|
is_quitting_all = GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (window), XED_IS_QUITTING_ALL));
|
||||||
|
|
||||||
|
if (is_quitting)
|
||||||
|
{
|
||||||
|
gtk_widget_destroy (GTK_WIDGET (window));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_quitting_all)
|
||||||
|
{
|
||||||
|
GtkApplication *app;
|
||||||
|
|
||||||
|
app = GTK_APPLICATION (g_application_get_default ());
|
||||||
|
|
||||||
|
if (gtk_application_get_windows (app) == NULL)
|
||||||
|
{
|
||||||
|
g_application_quit (G_APPLICATION (app));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
really_close_tab (XedTab *tab)
|
||||||
|
{
|
||||||
|
GtkWidget *toplevel;
|
||||||
|
XedWindow *window;
|
||||||
|
|
||||||
|
xed_debug (DEBUG_COMMANDS);
|
||||||
|
|
||||||
|
g_return_val_if_fail (xed_tab_get_state (tab) == XED_TAB_STATE_CLOSING, FALSE);
|
||||||
|
|
||||||
|
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (tab));
|
||||||
|
g_return_val_if_fail (XED_IS_WINDOW (toplevel), FALSE);
|
||||||
|
|
||||||
|
window = XED_WINDOW (toplevel);
|
||||||
|
|
||||||
|
xed_window_close_tab (window, tab);
|
||||||
|
|
||||||
|
if (xed_window_get_active_tab (window) == NULL)
|
||||||
|
{
|
||||||
|
quit_if_needed (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
close_tab (XedTab *tab)
|
||||||
|
{
|
||||||
|
XedDocument *doc;
|
||||||
|
|
||||||
|
doc = xed_tab_get_document (tab);
|
||||||
|
g_return_if_fail (doc != NULL);
|
||||||
|
|
||||||
|
/* If the user has modified again the document, do not close the tab. */
|
||||||
|
if (_xed_document_needs_saving (doc))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
save_as_tab (tab, window);
|
/* Close the document only if it has been succesfully saved.
|
||||||
|
* Tab state is set to CLOSING (it is a state without exiting
|
||||||
|
* transitions) and the tab is closed in an idle handler.
|
||||||
|
*/
|
||||||
|
_xed_tab_mark_for_closing (tab);
|
||||||
|
|
||||||
|
g_idle_add_full (G_PRIORITY_HIGH_IDLE,
|
||||||
|
(GSourceFunc) really_close_tab,
|
||||||
|
tab,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _SaveAsData SaveAsData;
|
||||||
|
|
||||||
|
struct _SaveAsData
|
||||||
|
{
|
||||||
|
/* Reffed */
|
||||||
|
XedWindow *window;
|
||||||
|
|
||||||
|
/* List of reffed GeditTab's */
|
||||||
|
GSList *tabs_to_save_as;
|
||||||
|
|
||||||
|
guint close_tabs : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void save_as_documents_list (SaveAsData *data);
|
||||||
|
|
||||||
|
static void
|
||||||
|
save_as_documents_list_cb (XedTab *tab,
|
||||||
|
GAsyncResult *result,
|
||||||
|
SaveAsData *data)
|
||||||
|
{
|
||||||
|
gboolean saved = save_as_tab_finish (tab, result);
|
||||||
|
|
||||||
|
if (saved && data->close_tabs)
|
||||||
|
{
|
||||||
|
close_tab (tab);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_return_if_fail (tab == XED_TAB (data->tabs_to_save_as->data));
|
||||||
|
g_object_unref (data->tabs_to_save_as->data);
|
||||||
|
data->tabs_to_save_as = g_slist_delete_link (data->tabs_to_save_as, data->tabs_to_save_as);
|
||||||
|
|
||||||
|
if (data->tabs_to_save_as != NULL)
|
||||||
|
{
|
||||||
|
save_as_documents_list (data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_object_unref (data->window);
|
||||||
|
g_slice_free (SaveAsData, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
save_as_documents_list (SaveAsData *data)
|
||||||
|
{
|
||||||
|
XedTab *next_tab = XED_TAB (data->tabs_to_save_as->data);
|
||||||
|
|
||||||
|
xed_window_set_active_tab (data->window, next_tab);
|
||||||
|
|
||||||
|
save_as_tab_async (next_tab,
|
||||||
|
data->window,
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback) save_as_documents_list_cb,
|
||||||
|
data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -835,8 +1043,8 @@ static void
|
||||||
save_documents_list (XedWindow *window,
|
save_documents_list (XedWindow *window,
|
||||||
GList *docs)
|
GList *docs)
|
||||||
{
|
{
|
||||||
|
SaveAsData *data = NULL;
|
||||||
GList *l;
|
GList *l;
|
||||||
GSList *tabs_to_save_as = NULL;
|
|
||||||
|
|
||||||
xed_debug (DEBUG_COMMANDS);
|
xed_debug (DEBUG_COMMANDS);
|
||||||
|
|
||||||
|
@ -868,9 +1076,17 @@ save_documents_list (XedWindow *window,
|
||||||
if (xed_document_is_untitled (doc) || xed_document_get_readonly (doc))
|
if (xed_document_is_untitled (doc) || xed_document_get_readonly (doc))
|
||||||
{
|
{
|
||||||
if (_xed_document_needs_saving (doc))
|
if (_xed_document_needs_saving (doc))
|
||||||
|
{
|
||||||
|
if (data == NULL)
|
||||||
{
|
{
|
||||||
tabs_to_save_as = g_slist_prepend (tabs_to_save_as, t);
|
data = g_slice_new (SaveAsData);
|
||||||
|
data->window = g_object_ref (window);
|
||||||
|
data->tabs_to_save_as = NULL;
|
||||||
|
data->close_tabs = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data->tabs_to_save_as = g_slist_prepend (data->tabs_to_save_as, g_object_ref (t));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -913,23 +1129,21 @@ save_documents_list (XedWindow *window,
|
||||||
l = g_list_next (l);
|
l = g_list_next (l);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tabs_to_save_as != NULL)
|
if (data != NULL)
|
||||||
{
|
{
|
||||||
XedTab *tab;
|
data->tabs_to_save_as = g_slist_reverse (data->tabs_to_save_as);
|
||||||
|
save_as_documents_list (data);
|
||||||
tabs_to_save_as = g_slist_reverse (tabs_to_save_as );
|
|
||||||
|
|
||||||
g_return_if_fail (g_object_get_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS) == NULL);
|
|
||||||
|
|
||||||
g_object_set_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS, tabs_to_save_as);
|
|
||||||
|
|
||||||
tab = XED_TAB (tabs_to_save_as->data);
|
|
||||||
|
|
||||||
xed_window_set_active_tab (window, tab);
|
|
||||||
save_as_tab (tab, window);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xed_commands_save_all_documents:
|
||||||
|
* @window: a #XedWindow.
|
||||||
|
*
|
||||||
|
* Asynchronously save all documents belonging to @window. The result of the
|
||||||
|
* operation is not available, so it's difficult to know whether all the
|
||||||
|
* documents are correctly saved.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
xed_commands_save_all_documents (XedWindow *window)
|
xed_commands_save_all_documents (XedWindow *window)
|
||||||
{
|
{
|
||||||
|
@ -953,6 +1167,14 @@ _xed_cmd_file_save_all (GtkAction *action,
|
||||||
xed_commands_save_all_documents (window);
|
xed_commands_save_all_documents (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xed_commands_save_document:
|
||||||
|
* @window: a #XedWindow.
|
||||||
|
* @document: the #XedDocument to save.
|
||||||
|
*
|
||||||
|
* Asynchronously save @document. @document must belong to @window. If you need
|
||||||
|
* the result of the operation, use xed_commands_save_document_async().
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
xed_commands_save_document (XedWindow *window,
|
xed_commands_save_document (XedWindow *window,
|
||||||
XedDocument *document)
|
XedDocument *document)
|
||||||
|
@ -1161,39 +1383,6 @@ _xed_cmd_file_revert (GtkAction *action,
|
||||||
gtk_widget_show (dialog);
|
gtk_widget_show (dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close tab */
|
|
||||||
static gboolean
|
|
||||||
really_close_tab (XedTab *tab)
|
|
||||||
{
|
|
||||||
GtkWidget *toplevel;
|
|
||||||
XedWindow *window;
|
|
||||||
|
|
||||||
xed_debug (DEBUG_COMMANDS);
|
|
||||||
|
|
||||||
g_return_val_if_fail (xed_tab_get_state (tab) == XED_TAB_STATE_CLOSING, FALSE);
|
|
||||||
|
|
||||||
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (tab));
|
|
||||||
g_return_val_if_fail (XED_IS_WINDOW (toplevel), FALSE);
|
|
||||||
|
|
||||||
window = XED_WINDOW (toplevel);
|
|
||||||
|
|
||||||
xed_window_close_tab (window, tab);
|
|
||||||
|
|
||||||
if (xed_window_get_active_tab (window) == NULL)
|
|
||||||
{
|
|
||||||
gboolean is_quitting;
|
|
||||||
|
|
||||||
is_quitting = GPOINTER_TO_BOOLEAN (g_object_get_data (G_OBJECT (window), XED_IS_QUITTING));
|
|
||||||
|
|
||||||
if (is_quitting)
|
|
||||||
{
|
|
||||||
gtk_widget_destroy (GTK_WIDGET (window));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tab_state_changed_while_saving (XedTab *tab,
|
tab_state_changed_while_saving (XedTab *tab,
|
||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
|
@ -1209,26 +1398,9 @@ tab_state_changed_while_saving (XedTab *tab,
|
||||||
finished */
|
finished */
|
||||||
if (ts == XED_TAB_STATE_NORMAL)
|
if (ts == XED_TAB_STATE_NORMAL)
|
||||||
{
|
{
|
||||||
XedDocument *doc;
|
|
||||||
|
|
||||||
g_signal_handlers_disconnect_by_func (tab, G_CALLBACK (tab_state_changed_while_saving), window);
|
g_signal_handlers_disconnect_by_func (tab, G_CALLBACK (tab_state_changed_while_saving), window);
|
||||||
|
|
||||||
doc = xed_tab_get_document (tab);
|
close_tab (tab);
|
||||||
g_return_if_fail (doc != NULL);
|
|
||||||
|
|
||||||
/* If the saving operation failed or was interrupted, then the
|
|
||||||
document is still "modified" -> do not close the tab */
|
|
||||||
if (_xed_document_needs_saving (doc))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the document only if it has been succesfully saved.
|
|
||||||
Tab state is set to CLOSING (it is a state without exiting
|
|
||||||
transitions) and the tab is closed in a idle handler */
|
|
||||||
_xed_tab_mark_for_closing (tab);
|
|
||||||
|
|
||||||
g_idle_add_full (G_PRIORITY_HIGH_IDLE, (GSourceFunc)really_close_tab, tab, NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1244,21 +1416,6 @@ save_and_close (XedTab *tab,
|
||||||
save_tab (tab, window);
|
save_tab (tab, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
save_as_and_close (XedTab *tab,
|
|
||||||
XedWindow *window)
|
|
||||||
{
|
|
||||||
xed_debug (DEBUG_COMMANDS);
|
|
||||||
|
|
||||||
g_object_set_data (G_OBJECT (tab), XED_IS_CLOSING_TAB, NULL);
|
|
||||||
|
|
||||||
/* Trace tab state changes */
|
|
||||||
g_signal_connect (tab, "notify::state", G_CALLBACK (tab_state_changed_while_saving), window);
|
|
||||||
|
|
||||||
xed_window_set_active_tab (window, tab);
|
|
||||||
save_as_tab (tab, window);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
save_and_close_all_documents (const GList *docs,
|
save_and_close_all_documents (const GList *docs,
|
||||||
XedWindow *window)
|
XedWindow *window)
|
||||||
|
@ -1266,9 +1423,9 @@ save_and_close_all_documents (const GList *docs,
|
||||||
GList *tabs;
|
GList *tabs;
|
||||||
GList *l;
|
GList *l;
|
||||||
GSList *sl;
|
GSList *sl;
|
||||||
GSList *tabs_to_save_as;
|
SaveAsData *data = NULL;
|
||||||
GSList *tabs_to_save_and_close;
|
GSList *tabs_to_save_and_close = NULL;
|
||||||
GList *tabs_to_close;
|
GList *tabs_to_close = NULL;
|
||||||
|
|
||||||
xed_debug (DEBUG_COMMANDS);
|
xed_debug (DEBUG_COMMANDS);
|
||||||
|
|
||||||
|
@ -1276,19 +1433,13 @@ save_and_close_all_documents (const GList *docs,
|
||||||
|
|
||||||
tabs = gtk_container_get_children (GTK_CONTAINER (_xed_window_get_notebook (window)));
|
tabs = gtk_container_get_children (GTK_CONTAINER (_xed_window_get_notebook (window)));
|
||||||
|
|
||||||
tabs_to_save_as = NULL;
|
|
||||||
tabs_to_save_and_close = NULL;
|
|
||||||
tabs_to_close = NULL;
|
|
||||||
|
|
||||||
l = tabs;
|
l = tabs;
|
||||||
while (l != NULL)
|
while (l != NULL)
|
||||||
{
|
{
|
||||||
XedTab *t;
|
XedTab *t = XED_TAB (l->data);;
|
||||||
XedTabState state;
|
XedTabState state;
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
|
|
||||||
t = XED_TAB (l->data);
|
|
||||||
|
|
||||||
state = xed_tab_get_state (t);
|
state = xed_tab_get_state (t);
|
||||||
doc = xed_tab_get_document (t);
|
doc = xed_tab_get_document (t);
|
||||||
|
|
||||||
|
@ -1337,9 +1488,15 @@ save_and_close_all_documents (const GList *docs,
|
||||||
user is running xed - Paolo (Dec. 8, 2005) */
|
user is running xed - Paolo (Dec. 8, 2005) */
|
||||||
if (xed_document_is_untitled (doc) || xed_document_get_readonly (doc))
|
if (xed_document_is_untitled (doc) || xed_document_get_readonly (doc))
|
||||||
{
|
{
|
||||||
g_object_set_data (G_OBJECT (t), XED_IS_CLOSING_TAB, GBOOLEAN_TO_POINTER (TRUE));
|
if (data == NULL)
|
||||||
|
{
|
||||||
|
data = g_slice_new (SaveAsData);
|
||||||
|
data->window = g_object_ref (window);
|
||||||
|
data->tabs_to_save_as = NULL;
|
||||||
|
data->close_tabs = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
tabs_to_save_as = g_slist_prepend (tabs_to_save_as, t);
|
data->tabs_to_save_as = g_slist_prepend (data->tabs_to_save_as, g_object_ref (t));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1371,20 +1528,11 @@ save_and_close_all_documents (const GList *docs,
|
||||||
}
|
}
|
||||||
g_slist_free (tabs_to_save_and_close);
|
g_slist_free (tabs_to_save_and_close);
|
||||||
|
|
||||||
/* Save As and close all the files in tabs_to_save_as */
|
/* Save As and close all the files in data->tabs_to_save_as. */
|
||||||
if (tabs_to_save_as != NULL)
|
if (data != NULL)
|
||||||
{
|
{
|
||||||
XedTab *tab;
|
data->tabs_to_save_as = g_slist_reverse (data->tabs_to_save_as);
|
||||||
|
save_as_documents_list (data);
|
||||||
tabs_to_save_as = g_slist_reverse (tabs_to_save_as );
|
|
||||||
|
|
||||||
g_return_if_fail (g_object_get_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS) == NULL);
|
|
||||||
|
|
||||||
g_object_set_data (G_OBJECT (window), XED_LIST_OF_TABS_TO_SAVE_AS, tabs_to_save_as);
|
|
||||||
|
|
||||||
tab = XED_TAB (tabs_to_save_as->data);
|
|
||||||
|
|
||||||
save_as_and_close (tab, window);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ void xed_commands_load_location (XedWindow *window, GFile *location, const GtkSo
|
||||||
/* Ignore non-existing URIs */
|
/* Ignore non-existing URIs */
|
||||||
GSList *xed_commands_load_locations (XedWindow *window, const GSList *locations, const GtkSourceEncoding *encoding, gint line_pos);
|
GSList *xed_commands_load_locations (XedWindow *window, const GSList *locations, const GtkSourceEncoding *encoding, gint line_pos);
|
||||||
void xed_commands_save_document (XedWindow *window, XedDocument *document);
|
void xed_commands_save_document (XedWindow *window, XedDocument *document);
|
||||||
|
void xed_commands_save_document_async (XedDocument *document, XedWindow *window, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
|
||||||
|
gboolean xed_commands_save_document_finish (XedDocument *document, GAsyncResult *result);
|
||||||
void xed_commands_save_all_documents (XedWindow *window);
|
void xed_commands_save_all_documents (XedWindow *window);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef __XED_DOCUMENT_PRIVATE_H__
|
||||||
|
#define __XED_DOCUMENT_PRIVATE_H__
|
||||||
|
|
||||||
|
#include "xed-document.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
glong _xed_document_get_seconds_since_last_save_or_load (XedDocument *doc);
|
||||||
|
|
||||||
|
gboolean _xed_document_needs_saving (XedDocument *doc);
|
||||||
|
|
||||||
|
gboolean _xed_document_get_empty_search (XedDocument *doc);
|
||||||
|
|
||||||
|
void _xed_document_set_create (XedDocument *doc,
|
||||||
|
gboolean create);
|
||||||
|
|
||||||
|
gboolean _xed_document_get_create (XedDocument *doc);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __XED_DOCUMENT_PRIVATE_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -37,29 +37,14 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define XED_TYPE_DOCUMENT (xed_document_get_type())
|
#define XED_TYPE_DOCUMENT (xed_document_get_type())
|
||||||
#define XED_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_DOCUMENT, XedDocument))
|
|
||||||
#define XED_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_DOCUMENT, XedDocumentClass))
|
G_DECLARE_DERIVABLE_TYPE (XedDocument, xed_document, XED, DOCUMENT, GtkSourceBuffer)
|
||||||
#define XED_IS_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_DOCUMENT))
|
|
||||||
#define XED_IS_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_DOCUMENT))
|
|
||||||
#define XED_DOCUMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_DOCUMENT, XedDocumentClass))
|
|
||||||
|
|
||||||
#define XED_METADATA_ATTRIBUTE_POSITION "metadata::xed-position"
|
#define XED_METADATA_ATTRIBUTE_POSITION "metadata::xed-position"
|
||||||
#define XED_METADATA_ATTRIBUTE_ENCODING "metadata::xed-encoding"
|
#define XED_METADATA_ATTRIBUTE_ENCODING "metadata::xed-encoding"
|
||||||
#define XED_METADATA_ATTRIBUTE_LANGUAGE "metadata::xed-language"
|
#define XED_METADATA_ATTRIBUTE_LANGUAGE "metadata::xed-language"
|
||||||
|
|
||||||
typedef struct _XedDocument XedDocument;
|
|
||||||
typedef struct _XedDocumentPrivate XedDocumentPrivate;
|
|
||||||
typedef struct _XedDocumentClass XedDocumentClass;
|
|
||||||
|
|
||||||
struct _XedDocument
|
|
||||||
{
|
|
||||||
GtkSourceBuffer buffer;
|
|
||||||
|
|
||||||
/*< private > */
|
|
||||||
XedDocumentPrivate *priv;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _XedDocumentClass
|
struct _XedDocumentClass
|
||||||
{
|
{
|
||||||
GtkSourceBufferClass parent_class;
|
GtkSourceBufferClass parent_class;
|
||||||
|
@ -77,8 +62,6 @@ struct _XedDocumentClass
|
||||||
void (* saved) (XedDocument *document);
|
void (* saved) (XedDocument *document);
|
||||||
};
|
};
|
||||||
|
|
||||||
GType xed_document_get_type (void) G_GNUC_CONST;
|
|
||||||
|
|
||||||
XedDocument *xed_document_new (void);
|
XedDocument *xed_document_new (void);
|
||||||
|
|
||||||
GtkSourceFile *xed_document_get_file (XedDocument *doc);
|
GtkSourceFile *xed_document_get_file (XedDocument *doc);
|
||||||
|
@ -138,24 +121,6 @@ void xed_document_set_search_context (XedDocument *doc,
|
||||||
|
|
||||||
GtkSourceSearchContext *xed_document_get_search_context (XedDocument *doc);
|
GtkSourceSearchContext *xed_document_get_search_context (XedDocument *doc);
|
||||||
|
|
||||||
/* Non exported functions */
|
|
||||||
|
|
||||||
glong _xed_document_get_seconds_since_last_save_or_load (XedDocument *doc);
|
|
||||||
|
|
||||||
void _xed_document_apply_error_style (XedDocument *doc,
|
|
||||||
GtkTextIter *start,
|
|
||||||
GtkTextIter *end);
|
|
||||||
|
|
||||||
/* Note: this is a sync stat: use only on local files */
|
|
||||||
gboolean _xed_document_check_externally_modified (XedDocument *doc);
|
|
||||||
|
|
||||||
gboolean _xed_document_needs_saving (XedDocument *doc);
|
|
||||||
|
|
||||||
void _xed_document_set_create (XedDocument *doc,
|
|
||||||
gboolean create);
|
|
||||||
|
|
||||||
gboolean _xed_document_get_create (XedDocument *doc);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __XED_DOCUMENT_H__ */
|
#endif /* __XED_DOCUMENT_H__ */
|
||||||
|
|
|
@ -21,23 +21,15 @@
|
||||||
* Boston, MA 02110-1301, USA.
|
* Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Modified by the xed Team, 2003-2007. See the AUTHORS file for a
|
|
||||||
* list of people on the xed Team.
|
|
||||||
* See the ChangeLog files for a list of changes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <libxml/xmlreader.h>
|
#include <libxml/xmlreader.h>
|
||||||
#include "xed-metadata-manager.h"
|
#include "xed-metadata-manager.h"
|
||||||
#include "xed-debug.h"
|
#include "xed-debug.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define XED_METADATA_VERBOSE_DEBUG 1
|
#define XED_METADATA_VERBOSE_DEBUG 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MAX_ITEMS 50
|
#define MAX_ITEMS 50
|
||||||
|
|
||||||
typedef struct _XedMetadataManager XedMetadataManager;
|
typedef struct _XedMetadataManager XedMetadataManager;
|
||||||
|
|
||||||
|
@ -45,21 +37,21 @@ typedef struct _Item Item;
|
||||||
|
|
||||||
struct _Item
|
struct _Item
|
||||||
{
|
{
|
||||||
time_t atime; /* time of last access */
|
gint64 atime; /* time of last access in seconds since January 1, 1970 UTC */
|
||||||
|
|
||||||
GHashTable *values;
|
GHashTable *values;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _XedMetadataManager
|
struct _XedMetadataManager
|
||||||
{
|
{
|
||||||
gboolean values_loaded; /* It is true if the file
|
gboolean values_loaded; /* It is true if the file
|
||||||
has been read */
|
has been read */
|
||||||
|
|
||||||
guint timeout_id;
|
guint timeout_id;
|
||||||
|
|
||||||
GHashTable *items;
|
GHashTable *items;
|
||||||
|
|
||||||
gchar *metadata_filename;
|
gchar *metadata_filename;
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean xed_metadata_manager_save (gpointer data);
|
static gboolean xed_metadata_manager_save (gpointer data);
|
||||||
|
@ -70,34 +62,34 @@ static XedMetadataManager *xed_metadata_manager = NULL;
|
||||||
static void
|
static void
|
||||||
item_free (gpointer data)
|
item_free (gpointer data)
|
||||||
{
|
{
|
||||||
Item *item;
|
Item *item;
|
||||||
|
|
||||||
g_return_if_fail (data != NULL);
|
g_return_if_fail (data != NULL);
|
||||||
|
|
||||||
#ifdef XED_METADATA_VERBOSE_DEBUG
|
#ifdef XED_METADATA_VERBOSE_DEBUG
|
||||||
xed_debug (DEBUG_METADATA);
|
xed_debug (DEBUG_METADATA);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
item = (Item *)data;
|
item = (Item *)data;
|
||||||
|
|
||||||
if (item->values != NULL)
|
if (item->values != NULL)
|
||||||
g_hash_table_destroy (item->values);
|
g_hash_table_destroy (item->values);
|
||||||
|
|
||||||
g_free (item);
|
g_free (item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xed_metadata_manager_arm_timeout (void)
|
xed_metadata_manager_arm_timeout (void)
|
||||||
{
|
{
|
||||||
if (xed_metadata_manager->timeout_id == 0)
|
if (xed_metadata_manager->timeout_id == 0)
|
||||||
{
|
{
|
||||||
xed_metadata_manager->timeout_id =
|
xed_metadata_manager->timeout_id =
|
||||||
g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE,
|
g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE,
|
||||||
2,
|
2,
|
||||||
(GSourceFunc)xed_metadata_manager_save,
|
(GSourceFunc)xed_metadata_manager_save,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,22 +102,22 @@ xed_metadata_manager_arm_timeout (void)
|
||||||
void
|
void
|
||||||
xed_metadata_manager_init (const gchar *metadata_filename)
|
xed_metadata_manager_init (const gchar *metadata_filename)
|
||||||
{
|
{
|
||||||
xed_debug (DEBUG_METADATA);
|
xed_debug (DEBUG_METADATA);
|
||||||
|
|
||||||
if (xed_metadata_manager != NULL)
|
if (xed_metadata_manager != NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xed_metadata_manager = g_new0 (XedMetadataManager, 1);
|
xed_metadata_manager = g_new0 (XedMetadataManager, 1);
|
||||||
|
|
||||||
xed_metadata_manager->values_loaded = FALSE;
|
xed_metadata_manager->values_loaded = FALSE;
|
||||||
|
|
||||||
xed_metadata_manager->items =
|
xed_metadata_manager->items =
|
||||||
g_hash_table_new_full (g_str_hash,
|
g_hash_table_new_full (g_str_hash,
|
||||||
g_str_equal,
|
g_str_equal,
|
||||||
g_free,
|
g_free,
|
||||||
item_free);
|
item_free);
|
||||||
|
|
||||||
xed_metadata_manager->metadata_filename = g_strdup (metadata_filename);
|
xed_metadata_manager->metadata_filename = g_strdup (metadata_filename);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -139,154 +131,159 @@ xed_metadata_manager_init (const gchar *metadata_filename)
|
||||||
void
|
void
|
||||||
xed_metadata_manager_shutdown (void)
|
xed_metadata_manager_shutdown (void)
|
||||||
{
|
{
|
||||||
xed_debug (DEBUG_METADATA);
|
xed_debug (DEBUG_METADATA);
|
||||||
|
|
||||||
if (xed_metadata_manager == NULL)
|
if (xed_metadata_manager == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (xed_metadata_manager->timeout_id)
|
if (xed_metadata_manager->timeout_id)
|
||||||
{
|
{
|
||||||
g_source_remove (xed_metadata_manager->timeout_id);
|
g_source_remove (xed_metadata_manager->timeout_id);
|
||||||
xed_metadata_manager->timeout_id = 0;
|
xed_metadata_manager->timeout_id = 0;
|
||||||
xed_metadata_manager_save (NULL);
|
xed_metadata_manager_save (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xed_metadata_manager->items != NULL)
|
if (xed_metadata_manager->items != NULL)
|
||||||
g_hash_table_destroy (xed_metadata_manager->items);
|
g_hash_table_destroy (xed_metadata_manager->items);
|
||||||
|
|
||||||
g_free (gedit_metadata_manager->metadata_filename);
|
g_free (xed_metadata_manager->metadata_filename);
|
||||||
g_free (xed_metadata_manager);
|
g_free (xed_metadata_manager);
|
||||||
xed_metadata_manager = NULL;
|
xed_metadata_manager = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parseItem (xmlDocPtr doc, xmlNodePtr cur)
|
parseItem (xmlDocPtr doc, xmlNodePtr cur)
|
||||||
{
|
{
|
||||||
Item *item;
|
Item *item;
|
||||||
|
|
||||||
xmlChar *uri;
|
xmlChar *uri;
|
||||||
xmlChar *atime;
|
xmlChar *atime;
|
||||||
|
|
||||||
#ifdef XED_METADATA_VERBOSE_DEBUG
|
#ifdef XED_METADATA_VERBOSE_DEBUG
|
||||||
xed_debug (DEBUG_METADATA);
|
xed_debug (DEBUG_METADATA);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (xmlStrcmp (cur->name, (const xmlChar *)"document") != 0)
|
if (xmlStrcmp (cur->name, (const xmlChar *)"document") != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uri = xmlGetProp (cur, (const xmlChar *)"uri");
|
uri = xmlGetProp (cur, (const xmlChar *)"uri");
|
||||||
if (uri == NULL)
|
if (uri == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
atime = xmlGetProp (cur, (const xmlChar *)"atime");
|
atime = xmlGetProp (cur, (const xmlChar *)"atime");
|
||||||
if (atime == NULL)
|
if (atime == NULL)
|
||||||
{
|
{
|
||||||
xmlFree (uri);
|
xmlFree (uri);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
item = g_new0 (Item, 1);
|
item = g_new0 (Item, 1);
|
||||||
|
|
||||||
item->atime = g_ascii_strtoull ((char *)atime, NULL, 0);
|
item->atime = g_ascii_strtoll ((char *)atime, NULL, 0);
|
||||||
|
|
||||||
item->values = g_hash_table_new_full (g_str_hash,
|
item->values = g_hash_table_new_full (g_str_hash,
|
||||||
g_str_equal,
|
g_str_equal,
|
||||||
g_free,
|
g_free,
|
||||||
g_free);
|
g_free);
|
||||||
|
|
||||||
cur = cur->xmlChildrenNode;
|
cur = cur->xmlChildrenNode;
|
||||||
|
|
||||||
while (cur != NULL)
|
while (cur != NULL)
|
||||||
{
|
{
|
||||||
if (xmlStrcmp (cur->name, (const xmlChar *)"entry") == 0)
|
if (xmlStrcmp (cur->name, (const xmlChar *)"entry") == 0)
|
||||||
{
|
{
|
||||||
xmlChar *key;
|
xmlChar *key;
|
||||||
xmlChar *value;
|
xmlChar *value;
|
||||||
|
|
||||||
key = xmlGetProp (cur, (const xmlChar *)"key");
|
key = xmlGetProp (cur, (const xmlChar *)"key");
|
||||||
value = xmlGetProp (cur, (const xmlChar *)"value");
|
value = xmlGetProp (cur, (const xmlChar *)"value");
|
||||||
|
|
||||||
if ((key != NULL) && (value != NULL))
|
if ((key != NULL) && (value != NULL))
|
||||||
g_hash_table_insert (item->values,
|
g_hash_table_insert (item->values,
|
||||||
g_strdup ((gchar *)key),
|
g_strdup ((gchar *)key),
|
||||||
g_strdup ((gchar *)value));
|
g_strdup ((gchar *)value));
|
||||||
|
|
||||||
if (key != NULL)
|
if (key != NULL)
|
||||||
xmlFree (key);
|
xmlFree (key);
|
||||||
if (value != NULL)
|
if (value != NULL)
|
||||||
xmlFree (value);
|
xmlFree (value);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_insert (xed_metadata_manager->items,
|
g_hash_table_insert (xed_metadata_manager->items,
|
||||||
g_strdup ((gchar *)uri),
|
g_strdup ((gchar *)uri),
|
||||||
item);
|
item);
|
||||||
|
|
||||||
xmlFree (uri);
|
xmlFree (uri);
|
||||||
xmlFree (atime);
|
xmlFree (atime);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
load_values (void)
|
load_values (void)
|
||||||
{
|
{
|
||||||
xmlDocPtr doc;
|
xmlDocPtr doc;
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
|
|
||||||
xed_debug (DEBUG_METADATA);
|
xed_debug (DEBUG_METADATA);
|
||||||
|
|
||||||
g_return_val_if_fail (xed_metadata_manager != NULL, FALSE);
|
g_return_val_if_fail (xed_metadata_manager != NULL, FALSE);
|
||||||
g_return_val_if_fail (xed_metadata_manager->values_loaded == FALSE, FALSE);
|
g_return_val_if_fail (xed_metadata_manager->values_loaded == FALSE, FALSE);
|
||||||
|
|
||||||
xed_metadata_manager->values_loaded = TRUE;
|
xed_metadata_manager->values_loaded = TRUE;
|
||||||
|
|
||||||
xmlKeepBlanksDefault (0);
|
xmlKeepBlanksDefault (0);
|
||||||
|
|
||||||
/* FIXME: file locking - Paolo */
|
/* FIXME: file locking - Paolo */
|
||||||
if ((xed_metadata_manager->metadata_filename == NULL) ||
|
if (xed_metadata_manager->metadata_filename == NULL)
|
||||||
(!g_file_test (xed_metadata_manager->metadata_filename, G_FILE_TEST_EXISTS)))
|
{
|
||||||
{
|
return FALSE;
|
||||||
return FALSE;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
doc = xmlParseFile (xed_metadata_manager->metadata_filename);
|
/* TODO: avoid races */
|
||||||
|
if (!g_file_test (xed_metadata_manager->metadata_filename, G_FILE_TEST_EXISTS))
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (doc == NULL)
|
doc = xmlParseFile (xed_metadata_manager->metadata_filename);
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur = xmlDocGetRootElement (doc);
|
if (doc == NULL)
|
||||||
if (cur == NULL)
|
{
|
||||||
{
|
return FALSE;
|
||||||
g_message ("The metadata file '%s' is empty", g_path_get_basename (xed_metadata_manager->metadata_filename));
|
}
|
||||||
xmlFreeDoc (doc);
|
|
||||||
|
|
||||||
return FALSE;
|
cur = xmlDocGetRootElement (doc);
|
||||||
}
|
if (cur == NULL)
|
||||||
|
{
|
||||||
|
g_message ("The metadata file '%s' is empty", g_path_get_basename (xed_metadata_manager->metadata_filename));
|
||||||
|
xmlFreeDoc (doc);
|
||||||
|
|
||||||
if (xmlStrcmp (cur->name, (const xmlChar *) "metadata"))
|
return TRUE;
|
||||||
{
|
}
|
||||||
g_message ("File '%s' is of the wrong type", g_path_get_basename (xed_metadata_manager->metadata_filename));
|
|
||||||
xmlFreeDoc (doc);
|
|
||||||
|
|
||||||
return FALSE;
|
if (xmlStrcmp (cur->name, (const xmlChar *) "metadata"))
|
||||||
}
|
{
|
||||||
|
g_message ("File '%s' is of the wrong type", g_path_get_basename (xed_metadata_manager->metadata_filename));
|
||||||
|
xmlFreeDoc (doc);
|
||||||
|
|
||||||
cur = xmlDocGetRootElement (doc);
|
return FALSE;
|
||||||
cur = cur->xmlChildrenNode;
|
}
|
||||||
|
|
||||||
while (cur != NULL)
|
cur = xmlDocGetRootElement (doc);
|
||||||
{
|
cur = cur->xmlChildrenNode;
|
||||||
parseItem (doc, cur);
|
|
||||||
|
|
||||||
cur = cur->next;
|
while (cur != NULL)
|
||||||
}
|
{
|
||||||
|
parseItem (doc, cur);
|
||||||
|
|
||||||
xmlFreeDoc (doc);
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
xmlFreeDoc (doc);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -298,48 +295,51 @@ load_values (void)
|
||||||
*/
|
*/
|
||||||
gchar *
|
gchar *
|
||||||
xed_metadata_manager_get (GFile *location,
|
xed_metadata_manager_get (GFile *location,
|
||||||
const gchar *key)
|
const gchar *key)
|
||||||
{
|
{
|
||||||
Item *item;
|
Item *item;
|
||||||
gchar *value;
|
gchar *value;
|
||||||
gchar *uri;
|
gchar *uri;
|
||||||
|
|
||||||
g_return_val_if_fail (G_IS_FILE (location), NULL);
|
g_return_val_if_fail (G_IS_FILE (location), NULL);
|
||||||
g_return_val_if_fail (key != NULL, NULL);
|
g_return_val_if_fail (key != NULL, NULL);
|
||||||
|
|
||||||
uri = g_file_get_uri (location);
|
uri = g_file_get_uri (location);
|
||||||
|
|
||||||
xed_debug_message (DEBUG_METADATA, "URI: %s --- key: %s", uri, key );
|
xed_debug_message (DEBUG_METADATA, "URI: %s --- key: %s", uri, key );
|
||||||
|
|
||||||
if (!xed_metadata_manager->values_loaded)
|
if (!xed_metadata_manager->values_loaded)
|
||||||
{
|
{
|
||||||
gboolean res;
|
gboolean res;
|
||||||
|
|
||||||
res = load_values ();
|
res = load_values ();
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
return NULL;
|
{
|
||||||
}
|
g_free (uri);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
item = (Item *)g_hash_table_lookup (xed_metadata_manager->items,
|
item = (Item *)g_hash_table_lookup (xed_metadata_manager->items,
|
||||||
uri);
|
uri);
|
||||||
|
|
||||||
g_free (uri);
|
g_free (uri);
|
||||||
|
|
||||||
if (item == NULL)
|
if (item == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
item->atime = time (NULL);
|
item->atime = g_get_real_time () / 1000;
|
||||||
|
|
||||||
if (item->values == NULL)
|
if (item->values == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
value = g_hash_table_lookup (item->values, key);
|
value = g_hash_table_lookup (item->values, key);
|
||||||
|
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
return g_strdup (value);
|
return g_strdup (value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -352,219 +352,221 @@ xed_metadata_manager_get (GFile *location,
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
xed_metadata_manager_set (GFile *location,
|
xed_metadata_manager_set (GFile *location,
|
||||||
const gchar *key,
|
const gchar *key,
|
||||||
const gchar *value)
|
const gchar *value)
|
||||||
{
|
{
|
||||||
Item *item;
|
Item *item;
|
||||||
gchar *uri;
|
gchar *uri;
|
||||||
|
|
||||||
g_return_if_fail (G_IS_FILE (location));
|
g_return_if_fail (G_IS_FILE (location));
|
||||||
g_return_if_fail (key != NULL);
|
g_return_if_fail (key != NULL);
|
||||||
|
|
||||||
uri = g_file_get_uri (location);
|
uri = g_file_get_uri (location);
|
||||||
|
|
||||||
xed_debug_message (DEBUG_METADATA, "URI: %s --- key: %s --- value: %s", uri, key, value);
|
xed_debug_message (DEBUG_METADATA, "URI: %s --- key: %s --- value: %s", uri, key, value);
|
||||||
|
|
||||||
if (!xed_metadata_manager->values_loaded)
|
if (!xed_metadata_manager->values_loaded)
|
||||||
{
|
{
|
||||||
gboolean res;
|
gboolean ok;
|
||||||
|
|
||||||
res = load_values ();
|
ok = load_values ();
|
||||||
|
|
||||||
if (!res)
|
if (!ok)
|
||||||
return;
|
{
|
||||||
}
|
g_free (uri);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
item = (Item *)g_hash_table_lookup (xed_metadata_manager->items,
|
item = (Item *)g_hash_table_lookup (xed_metadata_manager->items,
|
||||||
uri);
|
uri);
|
||||||
|
|
||||||
if (item == NULL)
|
if (item == NULL)
|
||||||
{
|
{
|
||||||
item = g_new0 (Item, 1);
|
item = g_new0 (Item, 1);
|
||||||
|
|
||||||
g_hash_table_insert (xed_metadata_manager->items,
|
g_hash_table_insert (xed_metadata_manager->items,
|
||||||
g_strdup (uri),
|
g_strdup (uri),
|
||||||
item);
|
item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item->values == NULL)
|
if (item->values == NULL)
|
||||||
item->values = g_hash_table_new_full (g_str_hash,
|
item->values = g_hash_table_new_full (g_str_hash,
|
||||||
g_str_equal,
|
g_str_equal,
|
||||||
g_free,
|
g_free,
|
||||||
g_free);
|
g_free);
|
||||||
if (value != NULL)
|
if (value != NULL)
|
||||||
g_hash_table_insert (item->values,
|
g_hash_table_insert (item->values,
|
||||||
g_strdup (key),
|
g_strdup (key),
|
||||||
g_strdup (value));
|
g_strdup (value));
|
||||||
else
|
else
|
||||||
g_hash_table_remove (item->values,
|
g_hash_table_remove (item->values,
|
||||||
key);
|
key);
|
||||||
|
|
||||||
item->atime = time (NULL);
|
item->atime = g_get_real_time () / 1000;
|
||||||
|
|
||||||
g_free (uri);
|
g_free (uri);
|
||||||
|
|
||||||
xed_metadata_manager_arm_timeout ();
|
xed_metadata_manager_arm_timeout ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
save_values (const gchar *key, const gchar *value, xmlNodePtr parent)
|
save_values (const gchar *key, const gchar *value, xmlNodePtr parent)
|
||||||
{
|
{
|
||||||
xmlNodePtr xml_node;
|
xmlNodePtr xml_node;
|
||||||
|
|
||||||
#ifdef XED_METADATA_VERBOSE_DEBUG
|
#ifdef XED_METADATA_VERBOSE_DEBUG
|
||||||
xed_debug (DEBUG_METADATA);
|
xed_debug (DEBUG_METADATA);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_return_if_fail (key != NULL);
|
g_return_if_fail (key != NULL);
|
||||||
|
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xml_node = xmlNewChild (parent,
|
xml_node = xmlNewChild (parent,
|
||||||
NULL,
|
NULL,
|
||||||
(const xmlChar *)"entry",
|
(const xmlChar *)"entry",
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
xmlSetProp (xml_node,
|
xmlSetProp (xml_node,
|
||||||
(const xmlChar *)"key",
|
(const xmlChar *)"key",
|
||||||
(const xmlChar *)key);
|
(const xmlChar *)key);
|
||||||
xmlSetProp (xml_node,
|
xmlSetProp (xml_node,
|
||||||
(const xmlChar *)"value",
|
(const xmlChar *)"value",
|
||||||
(const xmlChar *)value);
|
(const xmlChar *)value);
|
||||||
|
|
||||||
#ifdef XED_METADATA_VERBOSE_DEBUG
|
#ifdef XED_METADATA_VERBOSE_DEBUG
|
||||||
xed_debug_message (DEBUG_METADATA, "entry: %s = %s", key, value);
|
xed_debug_message (DEBUG_METADATA, "entry: %s = %s", key, value);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
save_item (const gchar *key, const gpointer *data, xmlNodePtr parent)
|
save_item (const gchar *key, const gpointer *data, xmlNodePtr parent)
|
||||||
{
|
{
|
||||||
xmlNodePtr xml_node;
|
xmlNodePtr xml_node;
|
||||||
const Item *item = (const Item *)data;
|
const Item *item = (const Item *)data;
|
||||||
gchar *atime;
|
gchar *atime;
|
||||||
|
|
||||||
#ifdef XED_METADATA_VERBOSE_DEBUG
|
#ifdef XED_METADATA_VERBOSE_DEBUG
|
||||||
xed_debug (DEBUG_METADATA);
|
xed_debug (DEBUG_METADATA);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_return_if_fail (key != NULL);
|
g_return_if_fail (key != NULL);
|
||||||
|
|
||||||
if (item == NULL)
|
if (item == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xml_node = xmlNewChild (parent, NULL, (const xmlChar *)"document", NULL);
|
xml_node = xmlNewChild (parent, NULL, (const xmlChar *)"document", NULL);
|
||||||
|
|
||||||
xmlSetProp (xml_node, (const xmlChar *)"uri", (const xmlChar *)key);
|
xmlSetProp (xml_node, (const xmlChar *)"uri", (const xmlChar *)key);
|
||||||
|
|
||||||
#ifdef XED_METADATA_VERBOSE_DEBUG
|
#ifdef XED_METADATA_VERBOSE_DEBUG
|
||||||
xed_debug_message (DEBUG_METADATA, "uri: %s", key);
|
xed_debug_message (DEBUG_METADATA, "uri: %s", key);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
atime = g_strdup_printf ("%ld", item->atime);
|
atime = g_strdup_printf ("%" G_GINT64_FORMAT, item->atime);
|
||||||
xmlSetProp (xml_node, (const xmlChar *)"atime", (const xmlChar *)atime);
|
xmlSetProp (xml_node, (const xmlChar *)"atime", (const xmlChar *)atime);
|
||||||
|
|
||||||
#ifdef XED_METADATA_VERBOSE_DEBUG
|
#ifdef XED_METADATA_VERBOSE_DEBUG
|
||||||
xed_debug_message (DEBUG_METADATA, "atime: %s", atime);
|
xed_debug_message (DEBUG_METADATA, "atime: %s", atime);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_free (atime);
|
g_free (atime);
|
||||||
|
|
||||||
g_hash_table_foreach (item->values,
|
g_hash_table_foreach (item->values,
|
||||||
(GHFunc)save_values,
|
(GHFunc)save_values,
|
||||||
xml_node);
|
xml_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_oldest (const gchar *key, const gpointer value, const gchar ** key_to_remove)
|
get_oldest (const gchar *key, const gpointer value, const gchar ** key_to_remove)
|
||||||
{
|
{
|
||||||
const Item *item = (const Item *)value;
|
const Item *item = (const Item *)value;
|
||||||
|
|
||||||
if (*key_to_remove == NULL)
|
if (*key_to_remove == NULL)
|
||||||
{
|
{
|
||||||
*key_to_remove = key;
|
*key_to_remove = key;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const Item *item_to_remove =
|
const Item *item_to_remove =
|
||||||
g_hash_table_lookup (xed_metadata_manager->items,
|
g_hash_table_lookup (xed_metadata_manager->items,
|
||||||
*key_to_remove);
|
*key_to_remove);
|
||||||
|
|
||||||
g_return_if_fail (item_to_remove != NULL);
|
g_return_if_fail (item_to_remove != NULL);
|
||||||
|
|
||||||
if (item->atime < item_to_remove->atime)
|
if (item->atime < item_to_remove->atime)
|
||||||
{
|
{
|
||||||
*key_to_remove = key;
|
*key_to_remove = key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
resize_items (void)
|
resize_items (void)
|
||||||
{
|
{
|
||||||
while (g_hash_table_size (xed_metadata_manager->items) > MAX_ITEMS)
|
while (g_hash_table_size (xed_metadata_manager->items) > MAX_ITEMS)
|
||||||
{
|
{
|
||||||
gpointer key_to_remove = NULL;
|
gpointer key_to_remove = NULL;
|
||||||
|
|
||||||
g_hash_table_foreach (xed_metadata_manager->items,
|
g_hash_table_foreach (xed_metadata_manager->items,
|
||||||
(GHFunc)get_oldest,
|
(GHFunc)get_oldest,
|
||||||
&key_to_remove);
|
&key_to_remove);
|
||||||
|
|
||||||
g_return_if_fail (key_to_remove != NULL);
|
g_return_if_fail (key_to_remove != NULL);
|
||||||
|
|
||||||
g_hash_table_remove (xed_metadata_manager->items,
|
g_hash_table_remove (xed_metadata_manager->items,
|
||||||
key_to_remove);
|
key_to_remove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
xed_metadata_manager_save (gpointer data)
|
xed_metadata_manager_save (gpointer data)
|
||||||
{
|
{
|
||||||
xmlDocPtr doc;
|
xmlDocPtr doc;
|
||||||
xmlNodePtr root;
|
xmlNodePtr root;
|
||||||
|
|
||||||
xed_debug (DEBUG_METADATA);
|
xed_debug (DEBUG_METADATA);
|
||||||
|
|
||||||
xed_metadata_manager->timeout_id = 0;
|
xed_metadata_manager->timeout_id = 0;
|
||||||
|
|
||||||
resize_items ();
|
resize_items ();
|
||||||
|
|
||||||
xmlIndentTreeOutput = TRUE;
|
xmlIndentTreeOutput = TRUE;
|
||||||
|
|
||||||
doc = xmlNewDoc ((const xmlChar *)"1.0");
|
doc = xmlNewDoc ((const xmlChar *)"1.0");
|
||||||
if (doc == NULL)
|
if (doc == NULL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* Create metadata root */
|
/* Create metadata root */
|
||||||
root = xmlNewDocNode (doc, NULL, (const xmlChar *)"metadata", NULL);
|
root = xmlNewDocNode (doc, NULL, (const xmlChar *)"metadata", NULL);
|
||||||
xmlDocSetRootElement (doc, root);
|
xmlDocSetRootElement (doc, root);
|
||||||
|
|
||||||
g_hash_table_foreach (xed_metadata_manager->items,
|
g_hash_table_foreach (xed_metadata_manager->items,
|
||||||
(GHFunc)save_item,
|
(GHFunc)save_item,
|
||||||
root);
|
root);
|
||||||
|
|
||||||
/* FIXME: lock file - Paolo */
|
/* FIXME: lock file - Paolo */
|
||||||
if (xed_metadata_manager->metadata_filename != NULL)
|
if (xed_metadata_manager->metadata_filename != NULL)
|
||||||
{
|
{
|
||||||
gchar *cache_dir;
|
gchar *cache_dir;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
/* make sure the cache dir exists */
|
/* make sure the cache dir exists */
|
||||||
cache_dir = g_path_get_dirname (xed_metadata_manager->metadata_filename);
|
cache_dir = g_path_get_dirname (xed_metadata_manager->metadata_filename);
|
||||||
res = g_mkdir_with_parents (cache_dir, 0755);
|
res = g_mkdir_with_parents (cache_dir, 0755);
|
||||||
if (res != -1)
|
if (res != -1)
|
||||||
{
|
{
|
||||||
xmlSaveFormatFile (xed_metadata_manager->metadata_filename, doc, 1);
|
xmlSaveFormatFile (xed_metadata_manager->metadata_filename, doc, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (cache_dir);
|
g_free (cache_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlFreeDoc (doc);
|
xmlFreeDoc (doc);
|
||||||
|
|
||||||
xed_debug_message (DEBUG_METADATA, "DONE");
|
xed_debug_message (DEBUG_METADATA, "DONE");
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#ifndef __XED_METADATA_MANAGER_H__
|
#ifndef __XED_METADATA_MANAGER_H__
|
||||||
#define __XED_METADATA_MANAGER_H__
|
#define __XED_METADATA_MANAGER_H__
|
||||||
|
|
||||||
#include <glib.h>
|
#include <gio/gio.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,8 @@
|
||||||
#include "xed-print-preview.h"
|
#include "xed-print-preview.h"
|
||||||
#include "xed-progress-info-bar.h"
|
#include "xed-progress-info-bar.h"
|
||||||
#include "xed-debug.h"
|
#include "xed-debug.h"
|
||||||
|
#include "xed-document.h"
|
||||||
|
#include "xed-document-private.h"
|
||||||
#include "xed-enum-types.h"
|
#include "xed-enum-types.h"
|
||||||
#include "xed-settings.h"
|
#include "xed-settings.h"
|
||||||
#include "xed-view-frame.h"
|
#include "xed-view-frame.h"
|
||||||
|
@ -1112,39 +1114,39 @@ view_focused_in (GtkWidget *widget,
|
||||||
XedTab *tab)
|
XedTab *tab)
|
||||||
{
|
{
|
||||||
XedDocument *doc;
|
XedDocument *doc;
|
||||||
|
GtkSourceFile *file;
|
||||||
|
|
||||||
g_return_val_if_fail (XED_IS_TAB (tab), FALSE);
|
g_return_val_if_fail (XED_IS_TAB (tab), FALSE);
|
||||||
|
|
||||||
/* we try to detect file changes only in the normal state */
|
/* we try to detect file changes only in the normal state */
|
||||||
if (tab->priv->state != XED_TAB_STATE_NORMAL)
|
if (tab->priv->state != XED_TAB_STATE_NORMAL)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return GDK_EVENT_PROPAGATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we already asked, don't bug the user again */
|
/* we already asked, don't bug the user again */
|
||||||
if (!tab->priv->ask_if_externally_modified)
|
if (!tab->priv->ask_if_externally_modified)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return GDK_EVENT_PROPAGATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
doc = xed_tab_get_document (tab);
|
doc = xed_tab_get_document (tab);
|
||||||
|
file = xed_document_get_file (doc);
|
||||||
|
|
||||||
/* If file was never saved or is remote we do not check */
|
/* If file was never saved or is remote we do not check */
|
||||||
if (!xed_document_is_local (doc))
|
if (gtk_source_file_is_local (file))
|
||||||
{
|
{
|
||||||
return FALSE;
|
gtk_source_file_check_file_on_disk (file);
|
||||||
|
|
||||||
|
if (gtk_source_file_is_externally_modified (file))
|
||||||
|
{
|
||||||
|
xed_tab_set_state (tab, XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION);
|
||||||
|
|
||||||
|
display_externally_modified_notification (tab);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_xed_document_check_externally_modified (doc))
|
return GDK_EVENT_PROPAGATE;
|
||||||
{
|
|
||||||
xed_tab_set_state (tab, XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION);
|
|
||||||
|
|
||||||
display_externally_modified_notification (tab);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "xed-utils.h"
|
#include "xed-utils.h"
|
||||||
#include "xed-commands.h"
|
#include "xed-commands.h"
|
||||||
#include "xed-debug.h"
|
#include "xed-debug.h"
|
||||||
|
#include "xed-document.h"
|
||||||
|
#include "xed-document-private.h"
|
||||||
#include "xed-panel.h"
|
#include "xed-panel.h"
|
||||||
#include "xed-documents-panel.h"
|
#include "xed-documents-panel.h"
|
||||||
#include "xed-plugins-engine.h"
|
#include "xed-plugins-engine.h"
|
||||||
|
|
Loading…
Reference in New Issue