[ghex] ui: tweaks; hex-doc: _read_async api.
- From: Logan Rathbone <larathbone src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ghex] ui: tweaks; hex-doc: _read_async api.
- Date: Mon, 20 Dec 2021 23:43:01 +0000 (UTC)
commit 6578f28594c191455b8d47efa97837c22fe232d2
Author: Logan Rathbone <poprocks gmail com>
Date: Mon Dec 20 15:17:14 2021 -0500
ui: tweaks; hex-doc: _read_async api.
src/ghex-application-window.c | 135 ++++++++++++++++++++++++++++--------------
src/gtkhex.c | 3 +-
src/hex-buffer-mmap.c | 9 ++-
src/hex-document.c | 49 ++++++++++++---
src/hex-document.h | 8 ++-
5 files changed, 148 insertions(+), 56 deletions(-)
---
diff --git a/src/ghex-application-window.c b/src/ghex-application-window.c
index cdb90e8..c8ca6b6 100644
--- a/src/ghex-application-window.c
+++ b/src/ghex-application-window.c
@@ -40,6 +40,9 @@
static GFile *tmp_global_gfile_for_nag_screen;
#endif
+/* This is dumb, but right now I can't think of a simpler solution. */
+static gpointer extra_user_data;
+
/* ----------------------- */
/* MAIN GOBJECT DEFINITION */
/* ----------------------- */
@@ -658,13 +661,27 @@ assess_can_save (HexDocument *doc)
}
static void
-do_doc_loading_spinner (GHexApplicationWindow *self)
+show_hex_notebook (GHexApplicationWindow *self)
+{
+ gtk_widget_hide (self->doc_loading_spinner);
+ gtk_widget_hide (self->no_doc_label);
+ gtk_widget_show (self->hex_notebook);
+}
+
+static void
+show_no_file_loaded_label (GHexApplicationWindow *self)
{
- gtk_widget_hide (self->no_doc_label);
- gtk_widget_hide (self->hex_notebook);
+ gtk_widget_hide (self->hex_notebook);
+ gtk_widget_hide (self->doc_loading_spinner);
+ gtk_widget_show (self->no_doc_label);
+}
- gtk_spinner_start (GTK_SPINNER(self->doc_loading_spinner));
- gtk_widget_show (self->doc_loading_spinner);
+static void
+show_doc_loading_spinner (GHexApplicationWindow *self)
+{
+ gtk_widget_hide (self->no_doc_label);
+ gtk_widget_hide (self->hex_notebook);
+ gtk_widget_show (self->doc_loading_spinner);
}
static void
@@ -694,15 +711,11 @@ document_loaded_or_saved_common (GHexApplicationWindow *self,
}
static void
-file_loaded_cb (HexDocument *doc, GHexApplicationWindow *self)
+file_loaded (HexDocument *doc, GHexApplicationWindow *self)
{
g_return_if_fail (GHEX_IS_APPLICATION_WINDOW (self));
- gtk_spinner_stop (GTK_SPINNER(self->doc_loading_spinner));
- gtk_widget_hide (self->doc_loading_spinner);
- gtk_widget_hide (self->no_doc_label);
- gtk_widget_show (self->hex_notebook);
-
+ show_hex_notebook (self);
document_loaded_or_saved_common (self, doc);
}
@@ -770,7 +783,6 @@ notebook_page_added_cb (GtkNotebook *notebook,
/* Let's play this super dumb. If a page is added, that will generally
* mean we don't have to count the pages to see if we have > 0.
*/
- do_doc_loading_spinner (self);
enable_main_actions (self, TRUE);
}
@@ -792,10 +804,7 @@ notebook_page_removed_cb (GtkNotebook *notebook,
ghex_application_window_set_show_chartable (self, FALSE);
ghex_application_window_set_show_converter (self, FALSE);
- gtk_widget_hide (self->hex_notebook);
- gtk_widget_hide (self->doc_loading_spinner);
- gtk_spinner_stop (GTK_SPINNER(self->doc_loading_spinner));
- gtk_widget_show (self->no_doc_label);
+ show_no_file_loaded_label (self);
}
}
@@ -1068,7 +1077,7 @@ save_as_response_cb (GtkNativeDialog *dialog,
if (hex_document_set_file (doc, gfile))
{
- do_doc_loading_spinner (self);
+ show_doc_loading_spinner (self);
}
else
{
@@ -1126,8 +1135,10 @@ revert_response_cb (GtkDialog *dialog,
doc = gtk_hex_get_document (ACTIVE_GH);
- do_doc_loading_spinner (self);
- hex_document_read (doc);
+ show_doc_loading_spinner (self);
+
+ /* FIXME - error handling */
+ hex_document_read_async (doc, NULL, NULL, NULL);
end:
gtk_window_destroy (GTK_WINDOW(dialog));
@@ -1221,22 +1232,7 @@ new_file (GtkWidget *widget,
refresh_dialogs (self);
ghex_application_window_activate_tab (self, gh);
ghex_application_window_set_insert_mode (self, TRUE);
- file_loaded_cb (doc, self);
-}
-
-static GtkHex *
-new_gh_from_gfile (GFile *file)
-{
- HexDocument *doc;
- GtkHex *gh;
-
- doc = hex_document_new_from_file (file);
- if (! doc)
- return NULL;
-
- gh = GTK_HEX(gtk_hex_new (doc));
-
- return gh;
+ file_loaded (doc, self);
}
static void
@@ -1520,6 +1516,9 @@ ghex_application_window_init (GHexApplicationWindow *self)
gtk_widget_init_template (widget);
+ /* FIXME - setting this property doesn't seem to work in the UI file? */
+ gtk_spinner_start (GTK_SPINNER(self->doc_loading_spinner));
+
/* Cache system default of prefer-dark-mode; gtk does not do this. This
* is run here as it cannot be done until we have a 'screen'. */
get_sys_default_is_dark ();
@@ -1991,9 +1990,6 @@ ghex_application_window_add_hex (GHexApplicationWindow *self,
g_signal_connect (gh, "cursor-moved",
G_CALLBACK(cursor_moved_cb), self);
- g_signal_connect (doc, "file-loaded",
- G_CALLBACK(file_loaded_cb), self);
-
g_signal_connect (doc, "document-changed",
G_CALLBACK(document_changed_cb), self);
@@ -2049,10 +2045,54 @@ do_nag_screen (GHexApplicationWindow *self)
}
#endif
+
+static void
+doc_read_ready_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(user_data);
+ GtkHex *gh = GTK_HEX(extra_user_data);
+ HexDocument *doc = HEX_DOCUMENT(source_object);
+ gboolean result;
+ GError *local_error = NULL;
+
+ result = hex_document_read_finish (doc, res, &local_error);
+
+ if (result)
+ {
+ refresh_dialogs (self);
+ ghex_application_window_activate_tab (self, gh);
+ /* FIXME - RENAME / CLEANUP */
+ file_loaded (doc, self);
+ }
+ else
+ {
+ if (local_error)
+ {
+ ghex_application_window_remove_tab (self,
+ ghex_application_window_get_current_tab (self));
+ show_no_file_loaded_label (self);
+ display_error_dialog (GTK_WINDOW(self), local_error->message);
+ g_error_free (local_error);
+ }
+ else
+ {
+ char *generic_errmsg = N_("There was an error reading the file.");
+
+ display_error_dialog (GTK_WINDOW(self), generic_errmsg);
+ }
+ }
+ extra_user_data = NULL;
+}
+
+
+
void
ghex_application_window_open_file (GHexApplicationWindow *self, GFile *file)
{
- GtkHex *gh;
+ HexDocument *doc;
+ GtkHex *gh = NULL;
#ifndef EXPERIMENTAL_MMAP
static gboolean nag_screen_shown = FALSE;
#endif
@@ -2077,10 +2117,13 @@ ghex_application_window_open_file (GHexApplicationWindow *self, GFile *file)
* to hold onto it.
*/
g_object_ref (file);
-
- gh = new_gh_from_gfile (file);
+ doc = hex_document_new_from_file (file);
g_object_unref (file);
+ if (doc)
+ gh = GTK_HEX(gtk_hex_new (doc));
+
+ /* Display a fairly generic error message if we can't even get this far. */
if (! gh)
{
char *error_msg = N_("There was an error loading the requested file. "
@@ -2094,12 +2137,16 @@ ghex_application_window_open_file (GHexApplicationWindow *self, GFile *file)
return;
}
+ /* FIXME - this is kind of cheap and will block all the *other* tabs
+ * as well, even though there's no need to. But it will do for now.
+ */
+ show_doc_loading_spinner (self);
+ extra_user_data = gh;
ghex_application_window_add_hex (self, gh);
- refresh_dialogs (self);
- ghex_application_window_activate_tab (self, gh);
+ hex_document_read_async (doc, NULL, doc_read_ready_cb, self);
}
-
+
GtkHex *
ghex_application_window_get_hex (GHexApplicationWindow *self)
{
diff --git a/src/gtkhex.c b/src/gtkhex.c
index d3e6f61..53bae30 100644
--- a/src/gtkhex.c
+++ b/src/gtkhex.c
@@ -2328,7 +2328,8 @@ gtk_hex_dispose (GObject *object)
g_clear_object (&gh->alayout);
g_clear_object (&gh->olayout);
- g_clear_object (&gh->document);
+ g_object_unref (gh->document);
+// g_clear_object (&gh->document);
/* Chain up */
G_OBJECT_CLASS(gtk_hex_parent_class)->dispose(object);
diff --git a/src/hex-buffer-mmap.c b/src/hex-buffer-mmap.c
index 90d1704..d813bc1 100644
--- a/src/hex-buffer-mmap.c
+++ b/src/hex-buffer-mmap.c
@@ -567,8 +567,11 @@ hex_buffer_mmap_read (HexBuffer *buf)
self->clean_bytes = bytes;
self->clean = NULL;
- if (!pages)
+ if (! pages)
+ {
+ set_error (self, _("Error reading file"));
return FALSE;
+ }
tmp_clean_fd = create_fd_from_path (self, file_path);
if (tmp_clean_fd < 0)
@@ -576,11 +579,15 @@ hex_buffer_mmap_read (HexBuffer *buf)
self->clean_fd = tmp_clean_fd;
+ errno = 0;
p = mmap (0, pages * self->pagesize, PROT_READ, MAP_SHARED,
self->clean_fd, 0);
if (p == MAP_FAILED)
+ {
+ set_error (self, _("An error has occurred"));
return FALSE;
+ }
self->clean = p;
diff --git a/src/hex-document.c b/src/hex-document.c
index cc66942..31a9f8e 100644
--- a/src/hex-document.c
+++ b/src/hex-document.c
@@ -335,8 +335,6 @@ hex_document_set_file (HexDocument *doc, GFile *file)
if (had_prev_file)
g_signal_emit (G_OBJECT(doc), hex_signals[FILE_NAME_CHANGED], 0);
- hex_document_read (doc);
-
return TRUE;
}
@@ -465,23 +463,45 @@ hex_document_delete_data (HexDocument *doc,
hex_document_set_data (doc, offset, 0, len, NULL, undoable);
}
-void
+gboolean
+hex_document_read_finish (HexDocument *doc,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (HEX_IS_DOCUMENT (doc), FALSE);
+ g_return_val_if_fail (G_IS_TASK (result), FALSE);
+
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+
+static void
document_ready_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
+ static HexChangeData change_data;
+
gboolean success;
GError *local_error = NULL;
HexBuffer *buf = HEX_BUFFER(source_object);
- HexDocument *doc = HEX_DOCUMENT(user_data);
- static HexChangeData change_data;
+ GTask *task = G_TASK (user_data);
gint64 payload;
+ HexDocument *doc;
+ doc = HEX_DOCUMENT(g_task_get_task_data (task));
success = hex_buffer_read_finish (buf, res, &local_error);
g_debug ("%s: DONE -- result: %d", __func__, success);
- if (local_error)
- g_warning (local_error->message);
+ if (! success)
+ {
+ if (local_error)
+ g_task_return_error (task, local_error);
+ else
+ g_task_return_boolean (task, FALSE);
+
+ goto cleanup;
+ }
/* Initialize data for new doc */
@@ -495,18 +515,29 @@ document_ready_cb (GObject *source_object,
doc->changed = FALSE;
hex_document_changed (doc, &change_data, FALSE);
g_signal_emit (G_OBJECT(doc), hex_signals[FILE_LOADED], 0);
+ g_task_return_boolean (task, TRUE);
+
+cleanup:
+ g_object_unref (task);
}
void
-hex_document_read (HexDocument *doc)
+hex_document_read_async (HexDocument *doc,
+ GCancellable *cancellable, /* FIXME: presently ignored */
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
static HexChangeData change_data;
+ GTask *task;
gint64 payload;
g_return_if_fail (G_IS_FILE (doc->file));
+ task = g_task_new (doc, cancellable, callback, user_data);
+ g_task_set_task_data (task, doc, NULL);
+
/* Read the actual file on disk into the buffer */
- hex_buffer_read_async (doc->buffer, NULL, document_ready_cb, doc);
+ hex_buffer_read_async (doc->buffer, NULL, document_ready_cb, task);
}
gboolean
diff --git a/src/hex-document.h b/src/hex-document.h
index 71326bf..0226ffc 100644
--- a/src/hex-document.h
+++ b/src/hex-document.h
@@ -75,7 +75,13 @@ void hex_document_set_nibble (HexDocument *doc, char val, gint64 offset,
gboolean lower_nibble, gboolean insert, gboolean undoable);
void hex_document_delete_data (HexDocument *doc, gint64 offset,
size_t len, gboolean undoable);
-void hex_document_read (HexDocument *doc);
+//void hex_document_read (HexDocument *doc);
+
+void hex_document_read_async (HexDocument *doc, GCancellable *cancellable,
+ GAsyncReadyCallback callback, gpointer user_data);
+gboolean hex_document_read_finish (HexDocument *doc, GAsyncResult *result,
+ GError **error);
+
gboolean hex_document_write (HexDocument *doc);
gboolean hex_document_write_to_file (HexDocument *doc, GFile *file);
gboolean hex_document_export_html (HexDocument *doc, char *html_path,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]