[ghex] ui: tweaks; hex-doc: _read_async api.



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]