[nautilus] file-conflict-dialog: Port to GtkBuilder



commit e1ade201dc4dae774f5f6cfd7b119949a320cd3a
Author: Joshua Lee <lee son wai gmail com>
Date:   Tue Nov 9 23:16:13 2021 +0000

    file-conflict-dialog: Port to GtkBuilder
    
    Modify the dialog to be built declarartively to enhance maintainability and aid
    in porting to GTK 4.
    
    This introduces a minor UI change with the 'Replace'/'Rename' and 'Skip'
    buttons swapping places, with the suggested action now the endmost button as
    is standard practice.

 po/POTFILES.in                                    |   1 +
 src/nautilus-file-conflict-dialog.c               | 195 ++++------------------
 src/resources/css/nautilus.css                    |   4 +
 src/resources/nautilus.gresource.xml              |   1 +
 src/resources/ui/nautilus-file-conflict-dialog.ui | 171 +++++++++++++++++++
 5 files changed, 212 insertions(+), 160 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 8d1c3df66..859e7efcf 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -81,6 +81,7 @@ src/resources/ui/nautilus-batch-rename-dialog.ui
 src/resources/ui/nautilus-column-chooser.ui
 src/resources/ui/nautilus-compress-dialog.ui
 src/resources/ui/nautilus-create-folder-dialog.ui
+src/resources/ui/nautilus-file-conflict-dialog.ui
 src/resources/ui/nautilus-file-properties-change-permissions.ui
 src/resources/ui/nautilus-files-view-context-menus.ui
 src/resources/ui/nautilus-folder-is-empty.ui
diff --git a/src/nautilus-file-conflict-dialog.c b/src/nautilus-file-conflict-dialog.c
index 5832dbfce..727b09806 100644
--- a/src/nautilus-file-conflict-dialog.c
+++ b/src/nautilus-file-conflict-dialog.c
@@ -41,9 +41,10 @@ struct _NautilusFileConflictDialog
     gchar *suggested_name;
 
     /* UI objects */
-    GtkWidget *titles_vbox;
-    GtkWidget *first_hbox;
-    GtkWidget *second_hbox;
+    GtkWidget *primary_label;
+    GtkWidget *secondary_label;
+    GtkWidget *dest_label;
+    GtkWidget *src_label;
     GtkWidget *expander;
     GtkWidget *entry;
     GtkWidget *checkbox;
@@ -56,38 +57,13 @@ struct _NautilusFileConflictDialog
 
 G_DEFINE_TYPE (NautilusFileConflictDialog, nautilus_file_conflict_dialog, GTK_TYPE_DIALOG);
 
-#define MAX_LABEL_WIDTH 50
-
 void
 nautilus_file_conflict_dialog_set_text (NautilusFileConflictDialog *fcd,
                                         gchar                      *primary_text,
                                         gchar                      *secondary_text)
 {
-    GtkWidget *label;
-    PangoAttrList *attr_list;
-
-    label = gtk_label_new (primary_text);
-    gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
-    gtk_label_set_line_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD_CHAR);
-    gtk_label_set_xalign (GTK_LABEL (label), 0.0);
-    gtk_label_set_max_width_chars (GTK_LABEL (label), MAX_LABEL_WIDTH);
-    gtk_box_pack_start (GTK_BOX (fcd->titles_vbox), label, FALSE, FALSE, 0);
-    gtk_widget_show (label);
-
-    attr_list = pango_attr_list_new ();
-    pango_attr_list_insert (attr_list, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
-    pango_attr_list_insert (attr_list, pango_attr_scale_new (PANGO_SCALE_LARGE));
-    g_object_set (label, "attributes", attr_list, NULL);
-
-    pango_attr_list_unref (attr_list);
-
-    label = gtk_label_new (secondary_text);
-    gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
-    gtk_label_set_line_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD_CHAR);
-    gtk_label_set_xalign (GTK_LABEL (label), 0.0);
-    gtk_label_set_max_width_chars (GTK_LABEL (label), MAX_LABEL_WIDTH);
-    gtk_box_pack_start (GTK_BOX (fcd->titles_vbox), label, FALSE, FALSE, 0);
-    gtk_widget_show (label);
+    gtk_label_set_text (GTK_LABEL (fcd->primary_label), primary_text);
+    gtk_label_set_text (GTK_LABEL (fcd->secondary_label), secondary_text);
 }
 
 void
@@ -95,27 +71,8 @@ nautilus_file_conflict_dialog_set_images (NautilusFileConflictDialog *fcd,
                                           GdkPixbuf                  *destination_pixbuf,
                                           GdkPixbuf                  *source_pixbuf)
 {
-    if (fcd->dest_image == NULL)
-    {
-        fcd->dest_image = gtk_image_new_from_pixbuf (destination_pixbuf);
-        gtk_box_pack_start (GTK_BOX (fcd->first_hbox), fcd->dest_image, FALSE, FALSE, 0);
-        gtk_widget_show (fcd->dest_image);
-    }
-    else
-    {
-        gtk_image_set_from_pixbuf (GTK_IMAGE (fcd->dest_image), destination_pixbuf);
-    }
-
-    if (fcd->src_image == NULL)
-    {
-        fcd->src_image = gtk_image_new_from_pixbuf (source_pixbuf);
-        gtk_box_pack_start (GTK_BOX (fcd->second_hbox), fcd->src_image, FALSE, FALSE, 0);
-        gtk_widget_show (fcd->src_image);
-    }
-    else
-    {
-        gtk_image_set_from_pixbuf (GTK_IMAGE (fcd->src_image), source_pixbuf);
-    }
+    gtk_image_set_from_pixbuf (GTK_IMAGE (fcd->dest_image), destination_pixbuf);
+    gtk_image_set_from_pixbuf (GTK_IMAGE (fcd->src_image), source_pixbuf);
 }
 
 void
@@ -123,17 +80,8 @@ nautilus_file_conflict_dialog_set_file_labels (NautilusFileConflictDialog *fcd,
                                                gchar                      *destination_label,
                                                gchar                      *source_label)
 {
-    GtkWidget *label;
-
-    label = gtk_label_new (NULL);
-    gtk_label_set_markup (GTK_LABEL (label), destination_label);
-    gtk_box_pack_start (GTK_BOX (fcd->first_hbox), label, FALSE, FALSE, 0);
-    gtk_widget_show (label);
-
-    label = gtk_label_new (NULL);
-    gtk_label_set_markup (GTK_LABEL (label), source_label);
-    gtk_box_pack_start (GTK_BOX (fcd->second_hbox), label, FALSE, FALSE, 0);
-    gtk_widget_show (label);
+    gtk_label_set_markup (GTK_LABEL (fcd->dest_label), destination_label);
+    gtk_label_set_markup (GTK_LABEL (fcd->src_label), source_label);
 }
 
 void
@@ -270,94 +218,7 @@ reset_button_clicked_cb (GtkButton                  *w,
 static void
 nautilus_file_conflict_dialog_init (NautilusFileConflictDialog *fcd)
 {
-    GtkWidget *hbox, *vbox, *vbox2;
-    GtkWidget *widget, *dialog_area;
-    GtkDialog *dialog;
-
-    dialog = GTK_DIALOG (fcd);
-
-    /* Setup the vbox containing the dialog body */
-    vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
-    dialog_area = gtk_dialog_get_content_area (dialog);
-    gtk_box_pack_start (GTK_BOX (dialog_area), vbox, FALSE, FALSE, 0);
-
-    /* Setup the vbox for the dialog labels */
-    widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
-    gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
-    fcd->titles_vbox = widget;
-
-    /* Setup the hboxes to pack file infos into */
-    vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
-    gtk_widget_set_halign (vbox2, GTK_ALIGN_START);
-    gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
-
-    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
-    gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
-    fcd->first_hbox = hbox;
-
-    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
-    gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
-    fcd->second_hbox = hbox;
-
-    /* Setup the expander for the rename action */
-    fcd->expander = gtk_expander_new_with_mnemonic (_("_Select a new name for the destination"));
-    gtk_box_pack_start (GTK_BOX (vbox2), fcd->expander, FALSE, FALSE, 0);
-    g_signal_connect (fcd->expander, "notify::expanded",
-                      G_CALLBACK (on_expanded_notify), dialog);
-
-    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-    gtk_container_add (GTK_CONTAINER (fcd->expander), hbox);
-
-    widget = gtk_entry_new ();
-    gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 6);
-    fcd->entry = widget;
-    g_signal_connect (widget, "changed",
-                      G_CALLBACK (entry_text_changed_cb), dialog);
-    gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
-
-    widget = gtk_button_new_with_label (_("Reset"));
-    gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 6);
-    g_signal_connect (widget, "clicked",
-                      G_CALLBACK (reset_button_clicked_cb), dialog);
-
-    gtk_widget_show_all (vbox2);
-
-    /* Setup the checkbox to apply the action to all files */
-    widget = gtk_check_button_new_with_mnemonic (_("Apply this action to all files and folders"));
-
-    gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
-    fcd->checkbox = widget;
-    g_signal_connect (widget, "toggled",
-                      G_CALLBACK (checkbox_toggled_cb), dialog);
-
-    /* Add buttons */
-    gtk_dialog_add_button (dialog, _("_Cancel"), GTK_RESPONSE_CANCEL);
-
-    fcd->skip_button = gtk_dialog_add_button (dialog,
-                                              _("_Skip"),
-                                              CONFLICT_RESPONSE_SKIP);
-
-    fcd->rename_button = gtk_dialog_add_button (dialog,
-                                                _("Re_name"),
-                                                CONFLICT_RESPONSE_RENAME);
-    gtk_widget_hide (fcd->rename_button);
-    gtk_widget_set_no_show_all (fcd->rename_button, TRUE);
-
-    fcd->replace_button = gtk_dialog_add_button (dialog,
-                                                 _("Re_place"),
-                                                 CONFLICT_RESPONSE_REPLACE);
-    gtk_widget_grab_focus (fcd->replace_button);
-
-    /* Setup HIG properties */
-    g_object_set (dialog_area,
-                  "margin-top", 18,
-                  "margin-bottom", 18,
-                  "margin-start", 18,
-                  "margin-end", 18,
-                  NULL);
-    gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
-
-    gtk_widget_show_all (dialog_area);
+    gtk_widget_init_template (GTK_WIDGET (fcd));
 }
 
 static void
@@ -374,6 +235,26 @@ do_finalize (GObject *self)
 static void
 nautilus_file_conflict_dialog_class_init (NautilusFileConflictDialogClass *klass)
 {
+    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+    gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/nautilus/ui/nautilus-file-conflict-dialog.ui");
+    gtk_widget_class_bind_template_child (widget_class, NautilusFileConflictDialog, primary_label);
+    gtk_widget_class_bind_template_child (widget_class, NautilusFileConflictDialog, secondary_label);
+    gtk_widget_class_bind_template_child (widget_class, NautilusFileConflictDialog, dest_label);
+    gtk_widget_class_bind_template_child (widget_class, NautilusFileConflictDialog, src_label);
+    gtk_widget_class_bind_template_child (widget_class, NautilusFileConflictDialog, expander);
+    gtk_widget_class_bind_template_child (widget_class, NautilusFileConflictDialog, entry);
+    gtk_widget_class_bind_template_child (widget_class, NautilusFileConflictDialog, checkbox);
+    gtk_widget_class_bind_template_child (widget_class, NautilusFileConflictDialog, rename_button);
+    gtk_widget_class_bind_template_child (widget_class, NautilusFileConflictDialog, replace_button);
+    gtk_widget_class_bind_template_child (widget_class, NautilusFileConflictDialog, skip_button);
+    gtk_widget_class_bind_template_child (widget_class, NautilusFileConflictDialog, dest_image);
+    gtk_widget_class_bind_template_child (widget_class, NautilusFileConflictDialog, src_image);
+    gtk_widget_class_bind_template_callback (widget_class, entry_text_changed_cb);
+    gtk_widget_class_bind_template_callback (widget_class, on_expanded_notify);
+    gtk_widget_class_bind_template_callback (widget_class, checkbox_toggled_cb);
+    gtk_widget_class_bind_template_callback (widget_class, reset_button_clicked_cb);
+
     G_OBJECT_CLASS (klass)->finalize = do_finalize;
 }
 
@@ -392,14 +273,8 @@ nautilus_file_conflict_dialog_get_apply_to_all (NautilusFileConflictDialog *dial
 NautilusFileConflictDialog *
 nautilus_file_conflict_dialog_new (GtkWindow *parent)
 {
-    NautilusFileConflictDialog *dialog;
-
-    dialog = NAUTILUS_FILE_CONFLICT_DIALOG (g_object_new (NAUTILUS_TYPE_FILE_CONFLICT_DIALOG,
-                                                          "use-header-bar", TRUE,
-                                                          "modal", TRUE,
-                                                          NULL));
-
-    gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
-
-    return dialog;
+    return NAUTILUS_FILE_CONFLICT_DIALOG (g_object_new (NAUTILUS_TYPE_FILE_CONFLICT_DIALOG,
+                                                        "transient-for", parent,
+                                                        "use-header-bar", TRUE,
+                                                        NULL));
 }
diff --git a/src/resources/css/nautilus.css b/src/resources/css/nautilus.css
index ee25a36a8..927e0b641 100644
--- a/src/resources/css/nautilus.css
+++ b/src/resources/css/nautilus.css
@@ -12,3 +12,7 @@ row.encrypted_zip label.title {
     background-size: 16px 16px;
     padding-right: 24px;
 }
+
+.conflict-dialog-primary-label {
+    font-size: 1.2em;
+}
diff --git a/src/resources/nautilus.gresource.xml b/src/resources/nautilus.gresource.xml
index 66f8f43f1..5188b58c4 100644
--- a/src/resources/nautilus.gresource.xml
+++ b/src/resources/nautilus.gresource.xml
@@ -24,6 +24,7 @@
     <file>ui/nautilus-batch-rename-dialog-menu.ui</file>
     <file>ui/nautilus-properties-window.ui</file>
     <file>ui/nautilus-file-properties-change-permissions.ui</file>
+    <file>ui/nautilus-file-conflict-dialog.ui</file>
     <file alias="gtk/ui/nautilusgtkplacesview.ui">../gtk/nautilusgtkplacesview.ui</file>
     <file alias="gtk/ui/nautilusgtkplacesviewrow.ui">../gtk/nautilusgtkplacesviewrow.ui</file>
     <file alias="icons/thumbnail_frame.png">../../icons/thumbnail_frame.png</file>
diff --git a/src/resources/ui/nautilus-file-conflict-dialog.ui 
b/src/resources/ui/nautilus-file-conflict-dialog.ui
new file mode 100644
index 000000000..fed180fab
--- /dev/null
+++ b/src/resources/ui/nautilus-file-conflict-dialog.ui
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <template class="NautilusFileConflictDialog" parent="GtkDialog">
+    <property name="modal">True</property>
+    <property name="resizable">False</property>
+    <child internal-child="vbox">
+      <object class="GtkBox">
+        <property name="visible">True</property>
+        <property name="margin-top">18</property>
+        <property name="margin-bottom">18</property>
+        <property name="margin-start">18</property>
+        <property name="margin-end">18</property>
+        <property name="spacing">12</property>
+        <child>
+          <object class="GtkBox">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">12</property>
+            <child>
+              <object class="GtkLabel" id="primary_label">
+                <property name="visible">True</property>
+                <property name="max-width-chars">50</property>
+                <property name="wrap">True</property>
+                <property name="wrap-mode">word-char</property>
+                <property name="xalign">0</property>
+                <attributes>
+                  <attribute name="weight" value="PANGO_WEIGHT_BOLD"/>
+                </attributes>
+                <style>
+                  <class name="conflict-dialog-primary-label"/>
+                </style>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel" id="secondary_label">
+                <property name="visible">True</property>
+                <property name="max-width-chars">50</property>
+                <property name="wrap">True</property>
+                <property name="wrap-mode">word-char</property>
+                <property name="xalign">0</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkBox">
+                <property name="visible">True</property>
+                <property name="halign">start</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">12</property>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">True</property>
+                    <property name="spacing">12</property>
+                    <child>
+                      <object class="GtkImage" id="dest_image">
+                        <property name="visible">True</property>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="dest_label">
+                        <property name="visible">True</property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">True</property>
+                    <property name="spacing">12</property>
+                    <child>
+                      <object class="GtkImage" id="src_image">
+                        <property name="visible">True</property>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="src_label">
+                        <property name="visible">True</property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkExpander" id="expander">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">_Select a new name for the 
destination</property>
+                    <property name="use-underline">True</property>
+                    <signal name="notify::expanded" handler="on_expanded_notify"/>
+                    <child>
+                      <object class="GtkBox">
+                        <property name="visible">True</property>
+                        <property name="spacing">6</property>
+                        <child>
+                          <object class="GtkEntry" id="entry">
+                            <property name="visible">True</property>
+                            <property name="activates-default">True</property>
+                            <property name="hexpand">True</property>
+                            <signal name="changed" handler="entry_text_changed_cb"/>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkButton">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">_Reset</property>
+                            <property name="use-underline">True</property>
+                            <signal name="clicked" handler="reset_button_clicked_cb"/>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkCheckButton" id="checkbox">
+                <property name="visible">True</property>
+                <signal name="toggled" handler="checkbox_toggled_cb"/>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Apply this action to all files and 
folders</property>
+                    <property name="use-underline">True</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="cancel_button">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">_Cancel</property>
+        <property name="use-underline">True</property>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="rename_button">
+        <property name="visible">False</property>
+        <property name="can-default">True</property>
+        <property name="label" translatable="yes">Re_name</property>
+        <property name="use-underline">True</property>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="replace_button">
+        <property name="visible">True</property>
+        <property name="can-default">True</property>
+        <property name="label" translatable="yes">Re_place</property>
+        <property name="use-underline">True</property>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="skip_button">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">_Skip</property>
+        <property name="use-underline">True</property>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="cancel">cancel_button</action-widget>
+      <!-- 3 is CONFLICT_RESPONSE_RENAME -->
+      <action-widget response="3">rename_button</action-widget>
+      <!-- 2 is CONFLICT_RESPONSE_REPLACE -->
+      <action-widget response="2" default="true">replace_button</action-widget>
+      <!-- 1 is CONFLICT_RESPONSE_SKIP -->
+      <action-widget response="1">skip_button</action-widget>
+    </action-widgets>
+  </template>
+</interface>


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