about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--po/POTFILES2
-rw-r--r--src/furtherance.gresource.xml2
-rw-r--r--src/gtk/csv_export_dialog.ui110
-rw-r--r--src/gtk/dialogs.ui101
-rw-r--r--src/ui/window.rs78
5 files changed, 150 insertions, 143 deletions
diff --git a/po/POTFILES b/po/POTFILES
index 6489d4e..bb94ba6 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -3,7 +3,7 @@ data/com.lakoliu.Furtherance.appdata.xml.in
 data/com.lakoliu.Furtherance.desktop.in
 
 # UI files
-src/gtk/dialogs.ui
+src/gtk/csv_export_dialog.ui
 src/gtk/history_box.ui
 src/gtk/preferences_dialog.ui
 src/gtk/report.ui
diff --git a/src/furtherance.gresource.xml b/src/furtherance.gresource.xml
index 96f7f67..5a3878a 100644
--- a/src/furtherance.gresource.xml
+++ b/src/furtherance.gresource.xml
@@ -9,7 +9,7 @@
     <file>gtk/tasks_group.ui</file>
     <file>gtk/tasks_page.ui</file>
     <file>gtk/task_row.ui</file>
-    <file>gtk/dialogs.ui</file>
+    <file>gtk/csv_export_dialog.ui</file>
     <file>gtk/window.ui</file>
   </gresource>
 </gresources>
diff --git a/src/gtk/csv_export_dialog.ui b/src/gtk/csv_export_dialog.ui
new file mode 100644
index 0000000..7e37882
--- /dev/null
+++ b/src/gtk/csv_export_dialog.ui
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <object class="AdwDialog" id="csv_export_dialog">
+    <property name="title" translatable="yes">Export as CSV</property>
+    <property name="child">
+      <object class="AdwToolbarView">
+        <child type="top">
+          <object class="AdwHeaderBar">
+            <property name="show-start-title-buttons">false</property>
+            <property name="show-end-title-buttons">false</property>
+            <child type="start">
+              <object class="GtkButton" id="cancel_button">
+                <property name="label" translatable="yes">_Cancel</property>
+                <property name="use_underline">true</property>
+              </object>
+            </child>
+            <child type="end">
+              <object class="GtkButton" id="export_button">
+                <property name="label" translatable="yes">_Export</property>
+                <property name="use_underline">true</property>
+                <property name="sensitive">false</property>
+                <style>
+                  <class name="suggested-action" />
+                </style>
+              </object>
+            </child>
+          </object>
+        </child>
+        <property name="content">
+          <object class="AdwClamp">
+            <property name="maximum-size">800</property>
+            <property name="tightening-threshold">600</property>
+            <property name="hexpand">true</property>
+            <property name="vexpand">false</property>
+            <property name="valign">fill</property>
+            <property name="halign">fill</property>
+            <child>
+              <object class="GtkBox">
+                <property name="orientation">vertical</property>
+                <property name="spacing">24</property>
+                <property name="margin-start">12</property>
+                <property name="margin-end">12</property>
+                <property name="margin-top">12</property>
+                <property name="margin-bottom">12</property>
+                <child>
+                  <object class="GtkBox">
+                    <property name="orientation">horizontal</property>
+                    <property name="spacing">12</property>
+                    <child>
+                      <object class="GtkLabel" id="selected_file_label">
+                        <property translatable="yes" name="label"> - No File Selected - </property>
+                        <property name="hexpand">true</property>
+                        <property name="halign">start</property>
+                        <property name="ellipsize">start</property>
+                        <style>
+                          <class name="dim-label" />
+                        </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="filechooser_button">
+                        <property name="icon-name">folder-open-symbolic</property>
+                        <property name="tooltip-text" translatable="yes">Select File</property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="AdwPreferencesGroup">
+                    <property name="title" translatable="yes">Export Preferences</property>
+                    <property name="halign">fill</property>
+                    <child>
+                      <object class="AdwComboRow" id="tasksort_row">
+                        <property name="title" translatable="yes">Sort _By</property>
+                        <property name="use_underline">true</property>
+                        <property name="model">
+                          <object class="GtkStringList">
+                            <items>
+                              <item translatable="yes">Start Time</item>
+                              <item translatable="yes">Stop Time</item>
+                              <item translatable="yes">Task Name</item>
+                            </items>
+                          </object>
+                        </property>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="AdwComboRow" id="sortorder_row">
+                        <property name="title" translatable="yes">Sort _Order</property>
+                        <property name="use_underline">true</property>
+                        <property name="model">
+                          <object class="GtkStringList">
+                            <items>
+                              <item translatable="yes">Ascending</item>
+                              <item translatable="yes">Descending</item>
+                            </items>
+                          </object>
+                        </property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </property>
+      </object>
+    </property>
+  </object>
+</interface>
diff --git a/src/gtk/dialogs.ui b/src/gtk/dialogs.ui
deleted file mode 100644
index ef141e0..0000000
--- a/src/gtk/dialogs.ui
+++ /dev/null
@@ -1,101 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
-
-  <object class="GtkDialog" id="dialog_csv_export">
-    <property name="use-header-bar">1</property>
-    <property name="modal">true</property>
-    <property name="title" translatable="yes">Export as CSV</property>
-    <child type="action">
-      <object class="GtkButton" id="csv_export_cancelbutton">
-        <property name="label" translatable="yes">Cancel</property>
-      </object>
-    </child>
-    <child type="action">
-      <object class="GtkButton" id="csv_export_applybutton">
-        <property name="label" translatable="yes">Export</property>
-        <style>
-          <class name="suggested-action" />
-        </style>
-      </object>
-    </child>
-    <action-widgets>
-      <action-widget response="cancel">csv_export_cancelbutton</action-widget>
-      <action-widget response="apply" default="true">csv_export_applybutton</action-widget>
-    </action-widgets>
-    <child>
-      <object class="AdwClamp">
-        <property name="maximum-size">800</property>
-        <property name="tightening-threshold">600</property>
-        <property name="hexpand">true</property>
-        <property name="vexpand">false</property>
-        <property name="valign">fill</property>
-        <property name="halign">fill</property>
-        <child>
-          <object class="GtkBox">
-            <property name="orientation">vertical</property>
-            <property name="spacing">24</property>
-            <property name="margin-start">12</property>
-            <property name="margin-end">12</property>
-            <property name="margin-top">12</property>
-            <property name="margin-bottom">12</property>
-            <child>
-              <object class="GtkBox">
-                <property name="orientation">horizontal</property>
-                <property name="spacing">12</property>
-                <child>
-                  <object class="GtkLabel" id="csv_export_chosenfile_label">
-                    <property translatable="yes" name="label"> - no file selected - </property>
-                    <property name="hexpand">true</property>
-                    <property name="halign">start</property>
-                    <property name="ellipsize">start</property>
-                    <style>
-                      <class name="dim-label" />
-                    </style>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkButton" id="csv_export_filechooser_button">
-                    <property name="icon-name">folder-open-symbolic</property>
-                  </object>
-                </child>
-              </object>
-            </child>
-            <child>
-              <object class="AdwPreferencesGroup">
-                <property name="title" translatable="yes">CSV export preferences</property>
-                <property name="halign">fill</property>
-                <child>
-                  <object class="AdwComboRow" id="csv_export_tasksort_row">
-                    <property name="title" translatable="yes">Sort by</property>
-                    <property name="model">
-                      <object class="GtkStringList">
-                        <items>
-                          <item translatable="yes">Start time</item>
-                          <item translatable="yes">Stop time</item>
-                          <item translatable="yes">Task name</item>
-                        </items>
-                      </object>
-                    </property>
-                  </object>
-                </child>
-                <child>
-                  <object class="AdwComboRow" id="csv_export_sortorder_row">
-                    <property name="title" translatable="yes">Sort order</property>
-                    <property name="model">
-                      <object class="GtkStringList">
-                        <items>
-                          <item translatable="yes">Ascending</item>
-                          <item translatable="yes">Descending</item>
-                        </items>
-                      </object>
-                    </property>
-                  </object>
-                </child>
-              </object>
-            </child>
-          </object>
-        </child>
-      </object>
-    </child>
-  </object>
-</interface>
\ No newline at end of file
diff --git a/src/ui/window.rs b/src/ui/window.rs
index 01d3052..9b49ed6 100644
--- a/src/ui/window.rs
+++ b/src/ui/window.rs
@@ -47,8 +47,6 @@ mod imp {
     pub struct FurtheranceWindow {
         // Template widgets
         #[template_child]
-        pub header_bar: TemplateChild<adw::HeaderBar>,
-        #[template_child]
         pub add_task: TemplateChild<gtk::Button>,
 
         #[template_child]
@@ -911,27 +909,32 @@ impl FurtheranceWindow {
     }
 
     pub fn open_csv_export_dialog(&self) {
-        let builder = gtk::Builder::from_resource("/com/lakoliu/Furtherance/gtk/dialogs.ui");
-        let dialog = builder.object::<gtk::Dialog>("dialog_csv_export").unwrap();
+        let builder = gtk::Builder::from_resource("/com/lakoliu/Furtherance/gtk/csv_export_dialog.ui");
+        let dialog = builder.object::<adw::Dialog>("csv_export_dialog").unwrap();
         let tasksort_row = builder
-            .object::<adw::ComboRow>("csv_export_tasksort_row")
+            .object::<adw::ComboRow>("tasksort_row")
             .unwrap();
         let sortorder_row = builder
-            .object::<adw::ComboRow>("csv_export_sortorder_row")
+            .object::<adw::ComboRow>("sortorder_row")
             .unwrap();
         let filechooser_button = builder
-            .object::<gtk::Button>("csv_export_filechooser_button")
+            .object::<gtk::Button>("filechooser_button")
             .unwrap();
-        let chosenfile_label = builder
-            .object::<gtk::Label>("csv_export_chosenfile_label")
+        let selected_file_label = builder
+            .object::<gtk::Label>("selected_file_label")
+            .unwrap();
+        let cancel_button = builder
+            .object::<gtk::Button>("cancel_button")
+            .unwrap();
+        let export_button = builder
+            .object::<gtk::Button>("export_button")
             .unwrap();
-
-        dialog.set_transient_for(Some(self));
 
         let filefilter = gtk::FileFilter::new();
         filefilter.add_mime_type("text/csv");
         filefilter.add_pattern("*.csv");
 
+        // TODO: Deprecated since 4.10. Use GtkFileDialog instead.
         let filechooser = gtk::FileChooserNative::builder()
             .title(&gettext("Create or choose a CSV file"))
             .modal(true)
@@ -946,52 +949,47 @@ impl FurtheranceWindow {
         filechooser.set_current_name("data.csv");
 
         filechooser_button.connect_clicked(
-            clone!(@weak self as window, @weak filechooser, @weak dialog => move |_| {
-                dialog.hide();
+            clone!(@weak self as window, @weak filechooser => move |_| {
                 filechooser.show();
             }),
         );
 
         filechooser.connect_response(
-            clone!(@weak dialog, @weak chosenfile_label => move |filechooser, response| {
+            clone!(@weak selected_file_label, @weak export_button => move |filechooser, response| {
                 if response == gtk::ResponseType::Accept {
                     if let Some(path) = filechooser.file().and_then(|file| file.path()) {
-                        chosenfile_label.set_label(&path.to_string_lossy());
-                    } else {
-                        chosenfile_label.set_label(&gettext(" - no file selected - "));
+                        selected_file_label.set_label(&path.to_string_lossy());
+                        export_button.set_sensitive(true);
                     }
                 }
-
-                dialog.show();
             }),
         );
 
-        dialog.connect_response(clone!(@weak self as window, @weak filechooser, @weak tasksort_row, @weak sortorder_row => move |dialog, response| {
-            match response {
-                gtk::ResponseType::Apply => {
-                    let sort = TaskSort::try_from(tasksort_row.selected()).unwrap_or_default();
-                    let order = SortOrder::try_from(sortorder_row.selected()).unwrap_or_default();
-
-                    if let Some(file) = filechooser.file() {
-                        glib::MainContext::default().spawn_local(clone!(@strong window, @strong file => async move {
-                            if let Err(e) = FurtheranceWindow::export_csv_to_file(sort, order, &file).await {
-                                log::error!("replace file {:?} failed, Err {}", file, e);
-                                window.display_toast(&gettext("Exporting as CSV failed."));
-                            } else {
-                                window.display_toast(&gettext("Exported as CSV successfully."));
-                            };
-                        }));
-                    }
-                }
-                _ => {}
-            }
-
+        cancel_button.connect_clicked(clone!(@weak dialog => move |_| {
             dialog.close();
         }));
 
+        export_button.connect_clicked(clone!(@weak self as window, @weak dialog, @weak filechooser, @weak tasksort_row, @weak sortorder_row => move |_| {
+            let sort = TaskSort::try_from(tasksort_row.selected()).unwrap_or_default();
+            let order = SortOrder::try_from(sortorder_row.selected()).unwrap_or_default();
+
+            if let Some(file) = filechooser.file() {
+                glib::MainContext::default().spawn_local(clone!(@strong window, @strong file => async move {
+                    if let Err(e) = FurtheranceWindow::export_csv_to_file(sort, order, &file).await {
+                        log::error!("replace file {:?} failed, Err {}", file, e);
+                        window.display_toast(&gettext("Exporting as CSV failed."));
+                    } else {
+                        window.display_toast(&gettext("Exported as CSV successfully."));
+                    };
+                }));
+
+                dialog.close();
+            }
+        }));
+
         *self.imp().filechooser.borrow_mut() = filechooser;
 
-        dialog.show()
+        dialog.present(self);
     }
 
     pub fn vertical_align(&self, align: gtk::Align) {