[gedit] Gives a warning and allows cancelling the load of a file when the file too big



commit b88ea7a28c1c2ef52e4e267eb5454b5a0e02c803
Author: Jordi Mas <jmas softcatala org>
Date:   Sat Mar 27 18:13:09 2021 +0000

    Gives a warning and allows cancelling the load of a file when the file too big

 gedit/gedit-io-error-info-bar.c | 108 +++++++++++++++++++++++++++++-----------
 gedit/gedit-tab.c               |  96 +++++++++++++++++++++++++++++++++++
 2 files changed, 175 insertions(+), 29 deletions(-)
---
diff --git a/gedit/gedit-io-error-info-bar.c b/gedit/gedit-io-error-info-bar.c
index 1edbe313a..77ca04d7b 100644
--- a/gedit/gedit-io-error-info-bar.c
+++ b/gedit/gedit-io-error-info-bar.c
@@ -395,6 +395,67 @@ create_combo_box (GtkWidget *info_bar,
        gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
 }
 
+static void
+create_primary_and_secondary_widgets_info_bar(GtkWidget *vbox, const gchar *primary_text,
+                                 const gchar *secondary_text)
+{
+       gchar *primary_markup;
+       gchar *secondary_markup;
+       GtkWidget *primary_label;
+       GtkWidget *secondary_label;
+
+       primary_markup = g_strdup_printf ("<b>%s</b>", primary_text);
+       primary_label = gtk_label_new (primary_markup);
+       g_free (primary_markup);
+       gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
+       gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
+       gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
+       gtk_widget_set_halign (primary_label, GTK_ALIGN_START);
+       gtk_widget_set_can_focus (primary_label, TRUE);
+       gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
+
+       if (secondary_text != NULL)
+       {
+               secondary_markup = g_strdup_printf ("<small>%s</small>",
+                                                   secondary_text);
+               secondary_label = gtk_label_new (secondary_markup);
+               g_free (secondary_markup);
+               gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
+               gtk_widget_set_can_focus (secondary_label, TRUE);
+               gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
+               gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
+               gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
+               gtk_widget_set_halign (secondary_label, GTK_ALIGN_START);
+       }
+}
+
+static GtkWidget *
+create_file_too_big_error_info_bar (const gchar *primary_text,
+                                 const gchar *secondary_text)
+{
+       GtkWidget *info_bar;
+       GtkWidget *hbox_content;
+       GtkWidget *vbox;
+
+       info_bar = gtk_info_bar_new ();
+       gtk_info_bar_set_show_close_button (GTK_INFO_BAR (info_bar), TRUE);
+
+       gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
+                                _("_Continue loading"),
+                                GTK_RESPONSE_ACCEPT);
+
+       hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
+
+       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+       gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0);
+
+       create_primary_and_secondary_widgets_info_bar (vbox, primary_text, secondary_text);
+       gtk_widget_show_all (hbox_content);
+       set_contents (info_bar, hbox_content);
+
+       return info_bar;
+}
+
 static GtkWidget *
 create_conversion_error_info_bar (const gchar *primary_text,
                                  const gchar *secondary_text,
@@ -403,10 +464,6 @@ create_conversion_error_info_bar (const gchar *primary_text,
        GtkWidget *info_bar;
        GtkWidget *hbox_content;
        GtkWidget *vbox;
-       gchar *primary_markup;
-       gchar *secondary_markup;
-       GtkWidget *primary_label;
-       GtkWidget *secondary_label;
 
        info_bar = gtk_info_bar_new ();
        gtk_info_bar_set_show_close_button (GTK_INFO_BAR (info_bar), TRUE);
@@ -436,30 +493,7 @@ create_conversion_error_info_bar (const gchar *primary_text,
        vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
        gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0);
 
-       primary_markup = g_strdup_printf ("<b>%s</b>", primary_text);
-       primary_label = gtk_label_new (primary_markup);
-       g_free (primary_markup);
-       gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
-       gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
-       gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
-       gtk_widget_set_halign (primary_label, GTK_ALIGN_START);
-       gtk_widget_set_can_focus (primary_label, TRUE);
-       gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
-
-       if (secondary_text != NULL)
-       {
-               secondary_markup = g_strdup_printf ("<small>%s</small>",
-                                                   secondary_text);
-               secondary_label = gtk_label_new (secondary_markup);
-               g_free (secondary_markup);
-               gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
-               gtk_widget_set_can_focus (secondary_label, TRUE);
-               gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
-               gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
-               gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
-               gtk_widget_set_halign (secondary_label, GTK_ALIGN_START);
-       }
-
+       create_primary_and_secondary_widgets_info_bar (vbox, primary_text, secondary_text);
        create_combo_box (info_bar, vbox);
        gtk_widget_show_all (hbox_content);
        set_contents (info_bar, hbox_content);
@@ -480,6 +514,7 @@ gedit_io_loading_error_info_bar_new (GFile                   *location,
        GtkWidget *info_bar;
        gboolean edit_anyway = FALSE;
        gboolean convert_error = FALSE;
+       gboolean file_too_big = FALSE;
 
        g_return_val_if_fail (error != NULL, NULL);
        g_return_val_if_fail (error->domain == GTK_SOURCE_FILE_LOADER_ERROR ||
@@ -549,6 +584,16 @@ gedit_io_loading_error_info_bar_new (GFile                   *location,
 
                g_free (encoding_name);
        }
+       else if (error->domain == GTK_SOURCE_FILE_LOADER_ERROR &&
+                error->code == GTK_SOURCE_FILE_LOADER_ERROR_TOO_BIG)
+       {
+               error_message = g_strdup_printf (_("The file ā€œ%sā€ is very big."),
+                                                uri_for_display);
+               message_details = g_strconcat (_("Large files can make gedit slow or unresponsive. "
+                                              "You can continue loading this file at your own risk"),
+                                              NULL);
+               file_too_big = TRUE;
+       }
        else
        {
                parse_error (error, &error_message, &message_details, location, uri_for_display);
@@ -560,7 +605,12 @@ gedit_io_loading_error_info_bar_new (GFile                   *location,
                                                 uri_for_display);
        }
 
-       if (convert_error)
+       if (file_too_big)
+       {
+               info_bar = create_file_too_big_error_info_bar (error_message,
+                                                            message_details);
+       }
+       else if (convert_error)
        {
                info_bar = create_conversion_error_info_bar (error_message,
                                                             message_details,
diff --git a/gedit/gedit-tab.c b/gedit/gedit-tab.c
index af72864e2..8bff54690 100644
--- a/gedit/gedit-tab.c
+++ b/gedit/gedit-tab.c
@@ -143,6 +143,9 @@ static void launch_loader (GTask                   *loading_task,
 
 static void launch_saver (GTask *saving_task);
 
+static void continue_loading(GTask     *loading_task);
+
+
 static SaverData *
 saver_data_new (void)
 {
@@ -688,6 +691,14 @@ io_loading_error_info_bar_response (GtkWidget *info_bar,
                        g_object_unref (loading_task);
                        break;
 
+
+               case GTK_RESPONSE_ACCEPT:
+                       set_info_bar (data->tab, NULL, GTK_RESPONSE_NONE);
+                       gedit_tab_set_state (data->tab, GEDIT_TAB_STATE_LOADING);
+
+                       continue_loading (loading_task);
+                       break;
+
                default:
                        if (location != NULL)
                        {
@@ -1978,6 +1989,48 @@ get_candidate_encodings (GeditTab *tab)
        return candidates;
 }
 
+static void
+continue_loading(GTask     *loading_task)
+{
+       LoaderData *data = g_task_get_task_data (loading_task);
+       // Pre loader
+       gtk_source_file_loader_load_async (data->loader,
+                                          G_PRIORITY_DEFAULT,
+                                          g_task_get_cancellable (loading_task),
+                                          (GFileProgressCallback) loader_progress_cb,
+                                          loading_task,
+                                          NULL,
+                                          (GAsyncReadyCallback) load_cb,
+                                          loading_task);
+}
+
+
+
+static
+guint64 get_file_size (GFile *file)
+{
+       GFileInfo *info;
+       GError *error = NULL;
+       guint64 res = 0;
+
+       if (file == NULL)
+       {
+               return 0;
+       }
+
+       info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, &error);
+
+       if (error)
+       {
+               g_error_free (error);
+               return 0;
+       }
+
+       res = g_file_info_get_size(info);
+       g_object_unref (info);
+       return res;
+}
+
 static void
 launch_loader (GTask                   *loading_task,
               const GtkSourceEncoding *encoding)
@@ -1985,6 +2038,8 @@ launch_loader (GTask                   *loading_task,
        LoaderData *data = g_task_get_task_data (loading_task);
        GSList *candidate_encodings = NULL;
        GeditDocument *doc;
+       const int MB = 1024*1024;
+       const int FILE_TOO_LARGE = 100*MB;
 
        if (encoding != NULL)
        {
@@ -2010,6 +2065,47 @@ launch_loader (GTask                   *loading_task,
 
        data->timer = g_timer_new ();
 
+
+       GFile * file = gtk_source_file_loader_get_location (data->loader);
+       guint64 size = get_file_size (file);
+
+       if (size > FILE_TOO_LARGE)
+       {
+               GtkWidget *info_bar;
+               GError *error = NULL;
+               GFile *location = gtk_source_file_loader_get_location (data->loader);
+               set_editable (data->tab, FALSE);
+
+               error = g_error_new_literal (GTK_SOURCE_FILE_LOADER_ERROR, 0, "");
+               error->code = GTK_SOURCE_FILE_LOADER_ERROR_TOO_BIG;
+
+               info_bar = gedit_io_loading_error_info_bar_new (location, NULL, error);
+
+               g_signal_connect (info_bar,
+                                 "response",
+                                 G_CALLBACK (io_loading_error_info_bar_response),
+                                 loading_task);
+
+               set_info_bar (data->tab, info_bar, GTK_RESPONSE_CANCEL);
+
+               if (data->tab->state == GEDIT_TAB_STATE_LOADING)
+               {
+                       gtk_widget_show (GTK_WIDGET (data->tab->frame));
+                       gedit_tab_set_state (data->tab, GEDIT_TAB_STATE_LOADING_ERROR);
+               }
+               else
+               {
+                       gedit_tab_set_state (data->tab, GEDIT_TAB_STATE_REVERTING_ERROR);
+               }
+
+               successful_load (loading_task);
+               gedit_recent_add_document (doc);
+
+               g_error_free (error);
+               return;
+       }
+
+       // Pre loader
        gtk_source_file_loader_load_async (data->loader,
                                           G_PRIORITY_DEFAULT,
                                           g_task_get_cancellable (loading_task),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]