mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-15 14:50:06 +00:00
Merge branch 'node-editor-autosave' into 'main'
node-editor: Add autosave See merge request GNOME/gtk!6748
This commit is contained in:
commit
df2cdb6913
@ -19,6 +19,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#ifdef HAVE_PANGOFT
|
||||
#include <pango/pangofc-fontmap.h>
|
||||
#endif
|
||||
@ -287,11 +289,63 @@ node_editor_application_class_init (NodeEditorApplicationClass *class)
|
||||
application_class->open = node_editor_application_open;
|
||||
}
|
||||
|
||||
static void
|
||||
print_version (void)
|
||||
{
|
||||
g_print ("gtk4-node-editor %s%s%s\n",
|
||||
PACKAGE_VERSION,
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? "-" : "",
|
||||
g_strcmp0 (PROFILE, "devel") == 0 ? VCS_TAG : "");
|
||||
}
|
||||
|
||||
static int
|
||||
local_options (GApplication *app,
|
||||
GVariantDict *options,
|
||||
gpointer data)
|
||||
{
|
||||
gboolean version = FALSE;
|
||||
gboolean reset = FALSE;
|
||||
|
||||
g_variant_dict_lookup (options, "version", "b", &version);
|
||||
|
||||
if (version)
|
||||
{
|
||||
print_version ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_variant_dict_lookup (options, "reset", "b", &reset);
|
||||
|
||||
if (reset)
|
||||
{
|
||||
char *path;
|
||||
|
||||
path = get_autosave_path ("-unsafe");
|
||||
g_remove (path);
|
||||
g_free (path);
|
||||
path = get_autosave_path (NULL);
|
||||
g_remove (path);
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
NodeEditorApplication *
|
||||
node_editor_application_new (void)
|
||||
{
|
||||
return g_object_new (NODE_EDITOR_APPLICATION_TYPE,
|
||||
NodeEditorApplication *app;
|
||||
|
||||
app = g_object_new (NODE_EDITOR_APPLICATION_TYPE,
|
||||
"application-id", "org.gtk.gtk4.NodeEditor",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
NULL);
|
||||
|
||||
g_application_add_main_option (G_APPLICATION (app), "version", 0, 0,G_OPTION_ARG_NONE, "Show program version", NULL);
|
||||
g_application_add_main_option (G_APPLICATION (app), "reset", 0, 0,G_OPTION_ARG_NONE, "Remove autosave content", NULL);
|
||||
|
||||
g_signal_connect (app, "handle-local-options", G_CALLBACK (local_options), NULL);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "gsk/broadway/gskbroadwayrenderer.h"
|
||||
#endif
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include <cairo.h>
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
#include <cairo-svg.h>
|
||||
@ -64,6 +66,8 @@ struct _NodeEditorWindow
|
||||
GFileMonitor *file_monitor;
|
||||
|
||||
GArray *errors;
|
||||
|
||||
guint update_timeout;
|
||||
};
|
||||
|
||||
struct _NodeEditorWindowClass
|
||||
@ -1101,6 +1105,9 @@ node_editor_window_finalize (GObject *object)
|
||||
{
|
||||
NodeEditorWindow *self = (NodeEditorWindow *)object;
|
||||
|
||||
if (self->update_timeout)
|
||||
g_source_remove (self->update_timeout);
|
||||
|
||||
g_array_free (self->errors, TRUE);
|
||||
|
||||
g_clear_pointer (&self->node, gsk_render_node_unref);
|
||||
@ -1540,6 +1547,72 @@ edit_action_cb (GtkWidget *widget,
|
||||
node_editor_window_edit (self, &start);
|
||||
}
|
||||
|
||||
static void
|
||||
dialog_response (GtkWidget *dialog,
|
||||
int response_id,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
gtk_window_destroy (GTK_WINDOW (dialog));
|
||||
|
||||
if (response_id == GTK_RESPONSE_OK)
|
||||
{
|
||||
char *path = get_autosave_path ("-unsafe");
|
||||
char *contents;
|
||||
gsize len;
|
||||
|
||||
if (g_file_get_contents (path, &contents, &len, NULL))
|
||||
{
|
||||
gtk_text_buffer_set_text (self->text_buffer, contents, len);
|
||||
g_free (contents);
|
||||
}
|
||||
|
||||
g_remove (path);
|
||||
g_free (path);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_window_map (GtkWidget *widget)
|
||||
{
|
||||
char *path;
|
||||
|
||||
GTK_WIDGET_CLASS (node_editor_window_parent_class)->map (widget);
|
||||
|
||||
path = get_autosave_path (NULL);
|
||||
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_free (path);
|
||||
return;
|
||||
}
|
||||
|
||||
g_free (path);
|
||||
|
||||
path = get_autosave_path ("-unsafe");
|
||||
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_message_dialog_new (GTK_WINDOW (widget),
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_BUTTONS_NONE,
|
||||
"The application may have crashed.\n"
|
||||
"Restore auto-saved content anyway ?");
|
||||
|
||||
gtk_dialog_add_button (GTK_DIALOG (dialog), "Cancel", GTK_RESPONSE_CANCEL);
|
||||
gtk_dialog_add_button (GTK_DIALOG (dialog), "Restore", GTK_RESPONSE_OK);
|
||||
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (dialog_response), widget);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (dialog));
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
}
|
||||
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_window_class_init (NodeEditorWindowClass *class)
|
||||
{
|
||||
@ -1558,6 +1631,8 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
|
||||
widget_class->realize = node_editor_window_realize;
|
||||
widget_class->unrealize = node_editor_window_unrealize;
|
||||
|
||||
widget_class->map = node_editor_window_map;
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, text_view);
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, picture);
|
||||
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, renderer_listbox);
|
||||
@ -1630,6 +1705,114 @@ static GActionEntry win_entries[] = {
|
||||
{ "open", window_open, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
char *
|
||||
get_autosave_path (const char *suffix)
|
||||
{
|
||||
char *path;
|
||||
char *name;
|
||||
|
||||
name = g_strconcat ("autosave", suffix, NULL);
|
||||
path = g_build_filename (g_get_user_cache_dir (), "gtk4-node-editor", name, NULL);
|
||||
g_free (name);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static void
|
||||
set_initial_text (NodeEditorWindow *self)
|
||||
{
|
||||
char *path;
|
||||
char *initial_text;
|
||||
gsize len;
|
||||
|
||||
path = get_autosave_path (NULL);
|
||||
|
||||
if (g_file_get_contents (path, &initial_text, &len, NULL))
|
||||
{
|
||||
gtk_text_buffer_set_text (self->text_buffer, initial_text, len);
|
||||
g_free (initial_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Default */
|
||||
gtk_text_buffer_set_text (self->text_buffer,
|
||||
"shadow {\n"
|
||||
" child: texture {\n"
|
||||
" bounds: 0 0 128 128;\n"
|
||||
" texture: url(\"resource:///org/gtk/gtk4/node-editor/icons/apps/org.gtk.gtk4.NodeEditor.svg\");\n"
|
||||
" }\n"
|
||||
" shadows: rgba(0,0,0,0.5) 0 1 12;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"transform {\n"
|
||||
" child: text {\n"
|
||||
" color: rgb(46,52,54);\n"
|
||||
" font: \"Cantarell Bold 11\";\n"
|
||||
" glyphs: \"GTK Node Editor\";\n"
|
||||
" offset: 8 14.418;\n"
|
||||
" }\n"
|
||||
" transform: translate(0, 140);\n"
|
||||
"}", -1);
|
||||
}
|
||||
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
static void
|
||||
autosave_contents (NodeEditorWindow *self)
|
||||
{
|
||||
char *path = NULL;
|
||||
char *dir = NULL;
|
||||
char *contents;
|
||||
GtkTextIter start, end;
|
||||
|
||||
gtk_text_buffer_get_bounds (self->text_buffer, &start, &end);
|
||||
contents = gtk_text_buffer_get_text (self->text_buffer, &start, &end, TRUE);
|
||||
path = get_autosave_path ("-unsafe");
|
||||
dir = g_path_get_dirname (path);
|
||||
g_mkdir_with_parents (dir, 0755);
|
||||
g_file_set_contents (path, contents, -1, NULL);
|
||||
|
||||
g_free (dir);
|
||||
g_free (path);
|
||||
g_free (contents);
|
||||
}
|
||||
|
||||
static void
|
||||
mark_autosave_as_safe (void)
|
||||
{
|
||||
char *path1 = NULL;
|
||||
char *path2 = NULL;
|
||||
|
||||
path1 = get_autosave_path ("-unsafe");
|
||||
path2 = get_autosave_path (NULL);
|
||||
|
||||
g_rename (path1, path2);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_timeout_cb (gpointer data)
|
||||
{
|
||||
NodeEditorWindow *self = data;
|
||||
|
||||
self->update_timeout = 0;
|
||||
|
||||
mark_autosave_as_safe ();
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
initiate_autosave (NodeEditorWindow *self)
|
||||
{
|
||||
autosave_contents (self);
|
||||
|
||||
if (self->update_timeout != 0)
|
||||
g_source_remove (self->update_timeout);
|
||||
|
||||
self->update_timeout = g_timeout_add (100, update_timeout_cb, self);
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_window_init (NodeEditorWindow *self)
|
||||
{
|
||||
@ -1684,25 +1867,9 @@ node_editor_window_init (NodeEditorWindow *self)
|
||||
g_signal_connect (self->scale_scale, "notify::value", G_CALLBACK (scale_changed), self);
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (self->text_view), self->text_buffer);
|
||||
|
||||
/* Default */
|
||||
gtk_text_buffer_set_text (self->text_buffer,
|
||||
"shadow {\n"
|
||||
" child: texture {\n"
|
||||
" bounds: 0 0 128 128;\n"
|
||||
" texture: url(\"resource:///org/gtk/gtk4/node-editor/icons/apps/org.gtk.gtk4.NodeEditor.svg\");\n"
|
||||
" }\n"
|
||||
" shadows: rgba(0,0,0,0.5) 0 1 12;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"transform {\n"
|
||||
" child: text {\n"
|
||||
" color: rgb(46,52,54);\n"
|
||||
" font: \"Cantarell Bold 11\";\n"
|
||||
" glyphs: \"GTK Node Editor\";\n"
|
||||
" offset: 8 14.418;\n"
|
||||
" }\n"
|
||||
" transform: translate(0, 140);\n"
|
||||
"}", -1);
|
||||
set_initial_text (self);
|
||||
|
||||
g_signal_connect_swapped (self->text_buffer, "changed", G_CALLBACK (initiate_autosave), self);
|
||||
|
||||
if (g_getenv ("GSK_RENDERER"))
|
||||
{
|
||||
|
@ -37,3 +37,5 @@ NodeEditorWindow * node_editor_window_new (NodeEditorApplication
|
||||
|
||||
gboolean node_editor_window_load (NodeEditorWindow *self,
|
||||
GFile *file);
|
||||
|
||||
char * get_autosave_path (const char *suffix);
|
||||
|
@ -30,6 +30,14 @@ OPTIONS
|
||||
|
||||
Show the application help.
|
||||
|
||||
``--version``
|
||||
|
||||
Show the program version.
|
||||
|
||||
``--reset``
|
||||
|
||||
Don't restore autosaved content and remove autosave files.
|
||||
|
||||
ENVIRONMENT
|
||||
-----------
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user