diff options
-rw-r--r-- | po/POTFILES | 2 | ||||
-rw-r--r-- | src/furtherance.gresource.xml | 2 | ||||
-rw-r--r-- | src/gtk/csv_export_dialog.ui | 110 | ||||
-rw-r--r-- | src/gtk/dialogs.ui | 101 | ||||
-rw-r--r-- | src/ui/window.rs | 78 |
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) { |