[file-roller/wip/gtk4: 46/54] extract dialog: ported to FrFileSelector




commit 3e735a04607cb3ae3819a7ba844f42bb2fcbd8f9
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun Oct 2 10:54:51 2022 +0200

    extract dialog: ported to FrFileSelector
    
    Added a special selection mode to FrFileSelector
    to select a folder.

 data/org.gnome.FileRoller.gschema.xml |   6 ++
 src/dlg-extract.c                     |  26 ++++----
 src/fr-file-selector-dialog.c         | 108 +++++++++++++++++++++++++++++++++-
 src/fr-file-selector-dialog.h         |   4 +-
 src/fr-location-bar.c                 |   9 ++-
 src/typedefs.h                        |   5 ++
 src/ui/extract-dialog-options.ui      |  92 ++++++++++-------------------
 src/ui/file-selector.ui               |   4 +-
 8 files changed, 171 insertions(+), 83 deletions(-)
---
diff --git a/data/org.gnome.FileRoller.gschema.xml b/data/org.gnome.FileRoller.gschema.xml
index 2ccd2cef..0f8da8e0 100644
--- a/data/org.gnome.FileRoller.gschema.xml
+++ b/data/org.gnome.FileRoller.gschema.xml
@@ -158,6 +158,12 @@
       <default>true</default>
       <summary>Recreate the folders stored in the archive</summary>
     </key>
+    <key name="width" type="i">
+      <default>1000</default>
+    </key>
+    <key name="height" type="i">
+      <default>800</default>
+    </key>
   </schema>
 
   <schema id="org.gnome.FileRoller.Dialogs.New" path="/org/gnome/file-roller/dialogs/new/" 
gettext-domain="file-roller">
diff --git a/src/dlg-extract.c b/src/dlg-extract.c
index 758d6298..267fa4d4 100644
--- a/src/dlg-extract.c
+++ b/src/dlg-extract.c
@@ -24,6 +24,7 @@
 #include <unistd.h>
 #include "file-utils.h"
 #include "fr-init.h"
+#include "fr-file-selector-dialog.h"
 #include "glib-utils.h"
 #include "gtk-utils.h"
 #include "fr-window.h"
@@ -77,7 +78,7 @@ extract_cb (GtkDialog   *dialog,
 
        /* collect extraction options. */
 
-       data->destination = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (data->dialog));
+       data->destination = fr_file_selector_dialog_get_current_folder (FR_FILE_SELECTOR_DIALOG 
(data->dialog));
 
        /* check directory existence. */
 
@@ -283,6 +284,8 @@ file_selector_response_cb (GtkDialog    *dialog,
                      int           response,
                      DialogData   *data)
 {
+       pref_util_save_window_geometry (GTK_WINDOW (data->dialog), "Extract");
+
        if ((response == GTK_RESPONSE_CANCEL) || (response == GTK_RESPONSE_DELETE_EVENT)) {
                gtk_window_destroy (GTK_WINDOW (data->dialog));
        } else if (response == GTK_RESPONSE_OK) {
@@ -316,24 +319,23 @@ dlg_extract__common (FrWindow *window,
        data->do_not_extract = FALSE;
        data->destination = NULL;
 
-       data->dialog = gtk_file_chooser_dialog_new (C_("Window title", "Extract"),
-                                                   GTK_WINDOW (data->window),
-                                                   GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-                                                   _GTK_LABEL_CANCEL, GTK_RESPONSE_CANCEL,
-                                                   _GTK_LABEL_EXTRACT, GTK_RESPONSE_OK,
-                                                   NULL);
+       data->dialog = fr_file_selector_dialog_new (FR_FILE_SELECTOR_MODE_FOLDER,
+                                                   C_("Window title", "Extract"),
+                                                   GTK_WINDOW (data->window));
+
+       gtk_dialog_add_button (GTK_DIALOG (data->dialog), _GTK_LABEL_CANCEL, GTK_RESPONSE_CANCEL);
+       GtkWidget *button = gtk_dialog_add_button (GTK_DIALOG (data->dialog), _GTK_LABEL_EXTRACT, 
GTK_RESPONSE_OK);
+       gtk_style_context_add_class (gtk_widget_get_style_context (button), "suggested-action");
 
        gtk_window_set_default_size (GTK_WINDOW (data->dialog), 530, 510);
-       gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (data->dialog), FALSE);
-       gtk_file_chooser_set_create_folders (GTK_FILE_CHOOSER (data->dialog), TRUE);
        gtk_dialog_set_default_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_OK);
 
        data->builder = gtk_builder_new_from_resource (FILE_ROLLER_RESOURCE_UI_PATH 
"extract-dialog-options.ui");
-       //gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (data->dialog), GET_WIDGET ("extra_widget"));
+       fr_file_selector_dialog_set_extra_widget (FR_FILE_SELECTOR_DIALOG (data->dialog), GET_WIDGET 
("extra_widget"));
 
        /* Set widgets data. */
 
-       gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (data->dialog), 
fr_window_get_extract_default_dir (window), NULL);
+       fr_file_selector_dialog_set_current_folder (FR_FILE_SELECTOR_DIALOG (data->dialog), 
fr_window_get_extract_default_dir (window));
 
        if (data->selected_files != NULL)
                gtk_check_button_set_active (GTK_CHECK_BUTTON (GET_WIDGET ("selected_files_radiobutton")), 
TRUE);
@@ -363,7 +365,7 @@ dlg_extract__common (FrWindow *window,
        /* Run dialog. */
 
        gtk_window_set_modal (GTK_WINDOW (data->dialog),TRUE);
-       gtk_widget_show (data->dialog);
+       pref_util_restore_window_geometry (GTK_WINDOW (data->dialog), "Extract");
 }
 
 
diff --git a/src/fr-file-selector-dialog.c b/src/fr-file-selector-dialog.c
index 811cd9c6..331d9c27 100644
--- a/src/fr-file-selector-dialog.c
+++ b/src/fr-file-selector-dialog.c
@@ -20,6 +20,7 @@
  */
 
 #include <config.h>
+#include "fr-enum-types.h"
 #include "fr-file-selector-dialog.h"
 #include "fr-location-bar.h"
 #include "gio-utils.h"
@@ -35,6 +36,10 @@
 #define FILE_LIST_CHARS 60
 #define SIDEBAR_CHARS   12
 
+enum {
+       PROP_0,
+       PROP_SELECTION_MODE,
+};
 
 enum {
        FILE_LIST_COLUMN_ICON,
@@ -107,12 +112,64 @@ struct _FrFileSelectorDialog {
        GSimpleActionGroup *action_map;
        GtkPopover         *file_context_menu;
        GtkWidget          *location_bar;
+       FrFileSelectorMode  selection_mode;
 };
 
 
 G_DEFINE_TYPE (FrFileSelectorDialog, fr_file_selector_dialog, GTK_TYPE_DIALOG)
 
 
+static void
+set_selection_mode (FrFileSelectorDialog *self,
+                   FrFileSelectorMode    mode)
+{
+       self->selection_mode = mode;
+       gtk_cell_renderer_set_visible (GTK_CELL_RENDERER (GET_WIDGET ("is_selected_cellrenderertoggle")),
+                                      (self->selection_mode == FR_FILE_SELECTOR_MODE_FILES));
+       gtk_tree_view_column_set_visible (GTK_TREE_VIEW_COLUMN (GET_WIDGET ("treeviewcolumn_size")),
+                                         (self->selection_mode == FR_FILE_SELECTOR_MODE_FILES));
+}
+
+
+static void
+fr_file_selector_set_property (GObject      *object,
+                              guint         property_id,
+                              const GValue *value,
+                              GParamSpec   *pspec)
+{
+       FrFileSelectorDialog *self = FR_FILE_SELECTOR_DIALOG (object);
+
+       switch (property_id) {
+       case PROP_SELECTION_MODE:
+               set_selection_mode (self, g_value_get_enum (value));
+               break;
+
+       default:
+               break;
+       }
+}
+
+
+static void
+fr_file_selector_get_property (GObject    *object,
+                              guint       property_id,
+                              GValue     *value,
+                              GParamSpec *pspec)
+{
+       FrFileSelectorDialog *self = FR_FILE_SELECTOR_DIALOG (object);
+
+       switch (property_id) {
+       case PROP_SELECTION_MODE:
+               g_value_set_enum (value, self->selection_mode);
+               break;
+
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+               break;
+       }
+}
+
+
 static void
 fr_file_selector_dialog_finalize (GObject *object)
 {
@@ -234,11 +291,22 @@ fr_file_selector_dialog_class_init (FrFileSelectorDialogClass *klass)
        GtkWidgetClass *widget_class;
 
        object_class = (GObjectClass*) klass;
+       object_class->set_property = fr_file_selector_set_property;
+       object_class->get_property = fr_file_selector_get_property;
        object_class->finalize = fr_file_selector_dialog_finalize;
 
        widget_class = (GtkWidgetClass *) klass;
        widget_class->realize = fr_file_selector_dialog_realize;
        widget_class->unmap = fr_file_selector_dialog_unmap;
+
+       g_object_class_install_property (object_class,
+                                        PROP_SELECTION_MODE,
+                                        g_param_spec_enum ("selection-mode",
+                                                           "Selection mode",
+                                                           "The selection mode",
+                                                           FR_TYPE_FILE_SELECTOR_MODE,
+                                                           FR_FILE_SELECTOR_MODE_FILES,
+                                                           G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
 }
 
 
@@ -370,7 +438,7 @@ files_modified_column_sort_func (GtkTreeModel *model,
 
 
 static gboolean
-_fr_file_selector_dialog_is_file_selected (FrFileSelectorDialog *self)
+_fr_file_selector_dialog_is_file_checked (FrFileSelectorDialog *self)
 {
        GtkListStore *list_store;
        GtkTreeIter   iter;
@@ -394,6 +462,16 @@ _fr_file_selector_dialog_is_file_selected (FrFileSelectorDialog *self)
 }
 
 
+static gboolean
+_fr_file_selector_dialog_is_file_selected (FrFileSelectorDialog *self)
+{
+       if (self->selection_mode == FR_FILE_SELECTOR_MODE_FILES)
+               return _fr_file_selector_dialog_is_file_checked (self);
+       else
+               return self->current_folder != NULL;
+}
+
+
 static void
 _update_sensitivity (FrFileSelectorDialog *self)
 {
@@ -434,6 +512,19 @@ is_selected_cellrenderertoggle_toggled_cb (GtkCellRendererToggle *cell_renderer,
 }
 
 
+static void
+files_treeview_selection_changed_cb (GtkTreeView *tree_view,
+                                    gpointer     user_data)
+{
+       FrFileSelectorDialog *self = user_data;
+
+       if (self->selection_mode != FR_FILE_SELECTOR_MODE_FOLDER)
+               return;
+
+       _update_sensitivity (self);
+}
+
+
 static void
 files_treeview_row_activated_cb (GtkTreeView       *tree_view,
                                 GtkTreePath       *path,
@@ -629,6 +720,10 @@ fr_file_selector_dialog_init (FrFileSelectorDialog *self)
                          "row-activated",
                          G_CALLBACK (files_treeview_row_activated_cb),
                          self);
+       g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (GET_WIDGET ("files_treeview"))),
+                         "changed",
+                         G_CALLBACK (files_treeview_selection_changed_cb),
+                         self);
        /*g_signal_connect (GTK_PLACES_SIDEBAR (GET_WIDGET ("places_sidebar")),
                          "open-location",
                          G_CALLBACK (places_sidebar_open_location_cb),
@@ -654,10 +749,12 @@ fr_file_selector_dialog_init (FrFileSelectorDialog *self)
 
 
 GtkWidget *
-fr_file_selector_dialog_new (const char *title,
-                            GtkWindow  *parent)
+fr_file_selector_dialog_new (FrFileSelectorMode  mode,
+                            const char         *title,
+                            GtkWindow          *parent)
 {
        return (GtkWidget *) g_object_new (fr_file_selector_dialog_get_type (),
+                                          "selection-mode", mode,
                                           "title", title,
                                           "transient-for", parent,
                                           "use-header-bar", _gtk_settings_get_dialogs_use_header (),
@@ -852,6 +949,10 @@ get_folder_content_for_each_child_cb (GFile     *file,
        LoadData *load_data = user_data;
        FileInfo *file_info;
 
+       if (load_data->dialog->selection_mode == FR_FILE_SELECTOR_MODE_FOLDER)
+               if (g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY)
+                       return;
+
        file_info = file_info_new (file, info);
        load_data->files = g_list_prepend (load_data->files, file_info);
 }
@@ -868,6 +969,7 @@ _get_folder_list (LoadData *load_data)
                                    G_FILE_ATTRIBUTE_STANDARD_SIZE ","
                                    G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
                                    G_FILE_ATTRIBUTE_STANDARD_ICON ","
+                                   G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON ","
                                    G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN ","
                                    G_FILE_ATTRIBUTE_TIME_MODIFIED ","
                                    G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC),
diff --git a/src/fr-file-selector-dialog.h b/src/fr-file-selector-dialog.h
index 971b2fa0..ee6596c9 100644
--- a/src/fr-file-selector-dialog.h
+++ b/src/fr-file-selector-dialog.h
@@ -23,10 +23,12 @@
 #define FR_FILE_SELECTOR_DIALOG_H
 
 #include <gtk/gtk.h>
+#include "typedefs.h"
 
 G_DECLARE_FINAL_TYPE (FrFileSelectorDialog, fr_file_selector_dialog, FR, FILE_SELECTOR_DIALOG, GtkDialog)
 
-GtkWidget *     fr_file_selector_dialog_new                 (const char             *title,
+GtkWidget *     fr_file_selector_dialog_new                 (FrFileSelectorMode      mode,
+                                                            const char             *title,
                                                             GtkWindow              *parent);
 void            fr_file_selector_dialog_set_extra_widget    (FrFileSelectorDialog   *dialog,
                                                             GtkWidget              *extra_widget);
diff --git a/src/fr-location-bar.c b/src/fr-location-bar.c
index 88887668..49caf18c 100644
--- a/src/fr-location-bar.c
+++ b/src/fr-location-bar.c
@@ -207,7 +207,6 @@ fr_location_bar_init (FrLocationBar *self)
        GtkWidget *navigation_commands = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
        gtk_style_context_add_class (gtk_widget_get_style_context (navigation_commands), "raised");
        gtk_style_context_add_class (gtk_widget_get_style_context (navigation_commands), "linked");
-       gtk_box_append (GTK_BOX (self), navigation_commands);
 
        GtkWidget *button;
 
@@ -229,14 +228,12 @@ fr_location_bar_init (FrLocationBar *self)
 
        private->parent_location_button = button = gtk_button_new_from_icon_name ("go-up-symbolic");
        gtk_widget_set_tooltip_text (button, _("Open the parent location"));
-       gtk_box_append (GTK_BOX (self), button);
        g_signal_connect (button,
                          "clicked",
                          G_CALLBACK (parent_location_button_clicked_cb),
                          self);
 
        GtkWidget *location_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-       _gtk_box_pack_end (GTK_BOX (self), location_box, TRUE, FALSE);
 
        /* Translators: after the colon there is a folder name. */
        GtkWidget *location_label = gtk_label_new_with_mnemonic (_("_Location:"));
@@ -255,6 +252,12 @@ fr_location_bar_init (FrLocationBar *self)
        gtk_widget_set_margin_start (private->location_entry, 5);
        gtk_widget_set_margin_end (private->location_entry, 5);
        _gtk_box_pack_end (GTK_BOX (location_box), private->location_entry, TRUE, FALSE);
+
+       /* Pack widgets */
+
+       _gtk_box_pack_end (GTK_BOX (self), location_box, TRUE, FALSE);
+       gtk_box_append (GTK_BOX (self), navigation_commands);
+       gtk_box_append (GTK_BOX (self), private->parent_location_button);
 }
 
 
diff --git a/src/typedefs.h b/src/typedefs.h
index 481e6a71..122602a2 100644
--- a/src/typedefs.h
+++ b/src/typedefs.h
@@ -97,4 +97,9 @@ typedef struct {
        const char *mime_type;
 } FrExtensionType;
 
+typedef enum {
+       FR_FILE_SELECTOR_MODE_FILES,
+       FR_FILE_SELECTOR_MODE_FOLDER
+} FrFileSelectorMode;
+
 #endif /* TYPEDEFS_H */
diff --git a/src/ui/extract-dialog-options.ui b/src/ui/extract-dialog-options.ui
index 686be579..130e922a 100644
--- a/src/ui/extract-dialog-options.ui
+++ b/src/ui/extract-dialog-options.ui
@@ -2,7 +2,7 @@
 <interface>
   <requires lib="gtk" version="4.0"/>
   <object class="GtkBox" id="extra_widget">
-    <property name="spacing">12</property>
+    <property name="spacing">10</property>
     <style>
       <class name="extra-widget"/>
     </style>
@@ -12,30 +12,28 @@
         <property name="orientation">vertical</property>
         <property name="spacing">6</property>
         <child>
-          <object class="GtkLabel" id="label1">
-            <property name="label" translatable="1" context="Action">Extract</property>
+          <object class="GtkCheckButton" id="all_files_radiobutton">
+            <property name="label" translatable="1">_All files</property>
+            <property name="use_underline">1</property>
             <property name="halign">start</property>
-            <attributes>
-              <attribute name="weight" value="bold"></attribute>
-            </attributes>
+            <property name="active">1</property>
           </object>
         </child>
         <child>
-          <object class="GtkBox" id="box3">
-            <property name="margin-start">12</property>
-            <property name="orientation">vertical</property>
+          <object class="GtkCheckButton" id="selected_files_radiobutton">
+            <property name="label" translatable="1">_Selected files</property>
+            <property name="use_underline">1</property>
+            <property name="halign">start</property>
+            <property name="active">1</property>
+            <property name="group">all_files_radiobutton</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox" id="box4">
             <property name="spacing">6</property>
             <child>
-              <object class="GtkCheckButton" id="all_files_radiobutton">
-                <property name="label" translatable="1">_All files</property>
-                <property name="use_underline">1</property>
-                <property name="halign">start</property>
-                <property name="active">1</property>
-              </object>
-            </child>
-            <child>
-              <object class="GtkCheckButton" id="selected_files_radiobutton">
-                <property name="label" translatable="1">_Selected files</property>
+              <object class="GtkCheckButton" id="file_pattern_radiobutton">
+                <property name="label" translatable="1">_Files:</property>
                 <property name="use_underline">1</property>
                 <property name="halign">start</property>
                 <property name="active">1</property>
@@ -43,24 +41,10 @@
               </object>
             </child>
             <child>
-              <object class="GtkBox" id="box4">
-                <property name="spacing">6</property>
-                <child>
-                  <object class="GtkCheckButton" id="file_pattern_radiobutton">
-                    <property name="label" translatable="1">_Files:</property>
-                    <property name="use_underline">1</property>
-                    <property name="halign">start</property>
-                    <property name="active">1</property>
-                    <property name="group">all_files_radiobutton</property>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkEntry" id="file_pattern_entry">
-                    <property name="focusable">1</property>
-                    <property name="placeholder_text" translatable="1">*.o; *.bak</property>
-                    <property name="invisible_char">●</property>
-                  </object>
-                </child>
+              <object class="GtkEntry" id="file_pattern_entry">
+                <property name="focusable">1</property>
+                <property name="placeholder_text" translatable="1">*.o; *.bak</property>
+                <property name="max_width_chars">20</property>
               </object>
             </child>
           </object>
@@ -73,35 +57,19 @@
         <property name="orientation">vertical</property>
         <property name="spacing">6</property>
         <child>
-          <object class="GtkLabel" id="label2">
-            <property name="label" translatable="1">Actions</property>
+          <object class="GtkCheckButton" id="keep_structure_checkbutton">
+            <property name="label" translatable="1">_Keep directory structure</property>
+            <property name="focusable">1</property>
+            <property name="use_underline">1</property>
             <property name="halign">start</property>
-            <attributes>
-              <attribute name="weight" value="bold"></attribute>
-            </attributes>
           </object>
         </child>
         <child>
-          <object class="GtkBox" id="box6">
-            <property name="margin-start">12</property>
-            <property name="orientation">vertical</property>
-            <property name="spacing">6</property>
-            <child>
-              <object class="GtkCheckButton" id="keep_structure_checkbutton">
-                <property name="label" translatable="1">_Keep directory structure</property>
-                <property name="focusable">1</property>
-                <property name="use_underline">1</property>
-                <property name="halign">start</property>
-              </object>
-            </child>
-            <child>
-              <object class="GtkCheckButton" id="keep_newer_checkbutton">
-                <property name="label" translatable="1">Do not _overwrite newer files</property>
-                <property name="focusable">1</property>
-                <property name="use_underline">1</property>
-                <property name="halign">start</property>
-              </object>
-            </child>
+          <object class="GtkCheckButton" id="keep_newer_checkbutton">
+            <property name="label" translatable="1">Do not _overwrite newer files</property>
+            <property name="focusable">1</property>
+            <property name="use_underline">1</property>
+            <property name="halign">start</property>
           </object>
         </child>
       </object>
diff --git a/src/ui/file-selector.ui b/src/ui/file-selector.ui
index 6a868f6e..6854a75f 100644
--- a/src/ui/file-selector.ui
+++ b/src/ui/file-selector.ui
@@ -68,7 +68,7 @@
                     <property name="model">files_liststore</property>
                     <child internal-child="selection">
                       <object class="GtkTreeSelection" id="treeview-selection2">
-                        <property name="mode">multiple</property>
+                        <property name="mode">single</property>
                       </object>
                     </child>
                     <child>
@@ -108,7 +108,7 @@
                       </object>
                     </child>
                     <child>
-                      <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+                      <object class="GtkTreeViewColumn" id="treeviewcolumn_size">
                         <property name="resizable">0</property>
                         <property name="sizing">autosize</property>
                         <property name="title" translatable="1" context="File">Size</property>


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