Skip to content

Commit

Permalink
Upgrade to GTK 4.12. Get rid of deprecation warnings.
Browse files Browse the repository at this point in the history
  • Loading branch information
andy128k committed Oct 29, 2023
1 parent 777d03a commit 8359466
Show file tree
Hide file tree
Showing 24 changed files with 317 additions and 209 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ quick-xml = "0.31"
toml = "0.8"
serde = { version = "1", features = ["derive"] }

gtk = { package = "gtk4", version = "0.7", features = ["v4_6"] }
gtk = { package = "gtk4", version = "0.7", features = ["v4_12"] }
awesome-glib = "0.3"
awesome-gtk = "0.3"

Expand Down
2 changes: 1 addition & 1 deletion src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,6 @@ impl PSApplication {
#[action(name = "shortcuts")]
fn action_shortcuts(&self) {
let window = shortcuts_window(self.active_window().as_ref(), crate::shortcuts::SHORTCUTS);
window.show();
window.present();
}
}
15 changes: 4 additions & 11 deletions src/main_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::ui::dashboard::PSDashboard;
use crate::ui::dialogs::ask_save::{ask_save, AskSave};
use crate::ui::dialogs::change_password::change_password;
use crate::ui::dialogs::file_chooser;
use crate::ui::dialogs::say::say_error;
use crate::ui::dialogs::say::say;
use crate::ui::edit_record::dialog::edit_record;
use crate::ui::forms::entry::form_password_entry;
use crate::ui::open_file::OpenFile;
Expand Down Expand Up @@ -340,7 +340,7 @@ impl PSMainWindow {
async fn save_data(&self, filename: &Path, password: &str) -> bool {
let save_result = format::save_file(filename, password, &self.imp().file_pane.file());
if let Err(error) = save_result {
say_error(self.upcast_ref(), &error.to_string()).await;
say(self.upcast_ref(), &error.to_string()).await;
return false;
}

Expand Down Expand Up @@ -450,7 +450,7 @@ impl PSMainWindow {
win.imp().search_bar.configure(new_config.search_in_secrets);
}));

win.show();
win.present();
win.imp().set_mode(imp::AppMode::Initial);
crate::css::load_css(&win.display());
win
Expand Down Expand Up @@ -564,14 +564,7 @@ async fn new_password(parent_window: &gtk::Window) -> Option<String> {
// TODO: ADD confirmation
let mut form = ui::forms::form::Form::new();
form.add("Password", Box::new(form_password_entry()), true);
let result = ui::edit_object::edit_object(
None,
form,
parent_window,
"Enter password",
"password-storage",
)
.await;
let result = ui::edit_object::edit_object(None, form, parent_window, "Enter password").await;
result.map(|mut values| values.remove(0))
}

Expand Down
4 changes: 2 additions & 2 deletions src/ui/dashboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ impl Default for PSDashboard {

impl PSDashboard {
pub fn update(&self, cache: &Cache) {
self.listbox.hide();
self.listbox.set_visible(false);
for child in self.listbox.children() {
if let Some(row) = child.downcast_ref::<gtk::ListBoxRow>() {
self.listbox.remove(row);
Expand Down Expand Up @@ -205,7 +205,7 @@ impl PSDashboard {
}
}
}
self.listbox.show();
self.listbox.set_visible(true);
if let Some(row) = first_row {
self.listbox.select_row(Some(&row));
row.grab_focus();
Expand Down
2 changes: 1 addition & 1 deletion src/ui/dialogs/about.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ pub async fn about(parent: Option<&gtk::Window>) {
.website("https://password-storage.andy128k.dev")
.build();
dlg.set_transient_for(parent);
dlg.show();
dlg.present();
}
26 changes: 0 additions & 26 deletions src/ui/dialogs/ask.rs

This file was deleted.

28 changes: 10 additions & 18 deletions src/ui/dialogs/ask_save.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,22 @@
use gtk::prelude::*;

pub enum AskSave {
Discard,
Cancel,
Save,
}

pub async fn ask_save(parent_window: &gtk::Window, message: &str) -> AskSave {
let dlg = gtk::MessageDialog::builder()
let answer = gtk::AlertDialog::builder()
.modal(true)
.transient_for(parent_window)
.title("Password Storage")
.icon_name("password-storage")
.message_type(gtk::MessageType::Warning)
.use_markup(false)
.text(message)
.build();
dlg.add_button("_Discard changes", gtk::ResponseType::Reject);
dlg.add_button("_Cancel", gtk::ResponseType::Cancel);
dlg.add_button("_Save", gtk::ResponseType::Ok);
dlg.set_default_response(gtk::ResponseType::Ok);
let answer = dlg.run_future().await;
dlg.close();
.buttons(["Discard changes", "Cancel", "Save"])
.default_button(2)
.cancel_button(1)
.message(message)
.build()
.choose_future(Some(parent_window))
.await;
match answer {
gtk::ResponseType::Reject => AskSave::Discard,
gtk::ResponseType::Ok => AskSave::Save,
Ok(0) => AskSave::Discard,
Ok(2) => AskSave::Save,
_ => AskSave::Cancel,
}
}
9 changes: 1 addition & 8 deletions src/ui/dialogs/change_password.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@ pub async fn change_password(parent_window: &gtk::Window) -> Option<String> {
ValidationResult::Invalid("Passwords are not identical".to_string())
}
}));
let result = edit_object(
None,
form,
parent_window,
"Change password",
"password-storage",
)
.await;
let result = edit_object(None, form, parent_window, "Change password").await;
result.map(|values| values[0].clone())
}
38 changes: 16 additions & 22 deletions src/ui/dialogs/file_chooser.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,24 @@
use gtk::prelude::*;
use std::path::PathBuf;

async fn choose_file(
action: gtk::FileChooserAction,
title: &str,
parent_window: &gtk::Window,
) -> Option<PathBuf> {
let dlg = gtk::FileChooserNative::builder()
.modal(true)
.action(action)
.title(title)
.transient_for(parent_window)
.build();
let answer = dlg.run_future().await;
dlg.hide();
if answer == gtk::ResponseType::Accept {
dlg.file().and_then(|f| f.path())
} else {
None
}
}

pub async fn open_file(parent_window: &gtk::Window) -> Option<PathBuf> {
choose_file(gtk::FileChooserAction::Open, "Open file", parent_window).await
gtk::FileDialog::builder()
.modal(true)
.title("Open file")
.build()
.open_future(Some(parent_window))
.await
.ok()
.and_then(|f| f.path())
}

pub async fn save_file(parent_window: &gtk::Window) -> Option<PathBuf> {
choose_file(gtk::FileChooserAction::Save, "Save file", parent_window).await
gtk::FileDialog::builder()
.modal(true)
.title("Save file")
.build()
.save_future(Some(parent_window))
.await
.ok()
.and_then(|f| f.path())
}
152 changes: 152 additions & 0 deletions src/ui/dialogs/generic_dialog.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
use crate::compat::accel::PRIMARY_MODIFIER;
use gtk::{gdk, glib, prelude::*, subclass::prelude::*};

mod imp {
use super::*;
use crate::utils::ui::title;
use futures::channel::mpsc::{channel, Receiver, Sender};
use futures::stream::StreamExt;
use std::cell::RefCell;

pub struct GenericDialog {
pub title: gtk::Label,
pub cancel_button: gtk::Button,
pub ok_button: gtk::Button,
pub sender: RefCell<Option<Sender<gtk::ResponseType>>>,
pub receiver: RefCell<Option<Receiver<gtk::ResponseType>>>,
}

#[glib::object_subclass]
impl ObjectSubclass for GenericDialog {
const NAME: &'static str = "PSGenericDialog";
type Type = super::GenericDialog;
type ParentType = gtk::Window;

fn new() -> Self {
let title = title("");

let cancel_button = gtk::Button::builder().label("Cancel").build();

let ok_button = gtk::Button::builder()
.label("OK")
.receives_default(true)
.build();
ok_button.add_css_class("suggested-action");

Self {
title,
cancel_button,
ok_button,
sender: Default::default(),
receiver: Default::default(),
}
}
}

impl ObjectImpl for GenericDialog {
fn constructed(&self) {
self.parent_constructed();

let header = gtk::HeaderBar::builder()
.title_widget(&self.title)
.show_title_buttons(false)
.build();

let (sender, receiver) = channel::<gtk::ResponseType>(0);
*self.sender.borrow_mut() = Some(sender.clone());
*self.receiver.borrow_mut() = Some(receiver);

self.cancel_button.connect_clicked(
glib::clone!(@weak self as imp => move |_| imp.send(gtk::ResponseType::Cancel)),
);
header.pack_start(&self.cancel_button);

self.ok_button.connect_clicked(
glib::clone!(@weak self as imp => move |_| imp.send(gtk::ResponseType::Ok)),
);
header.pack_end(&self.ok_button);

self.obj().set_modal(true);
self.obj().set_resizable(true);
self.obj().set_titlebar(Some(&header));
self.obj().set_icon_name(Some("password-storage"));

let key_controller = gtk::EventControllerKey::new();
key_controller.connect_key_pressed(
glib::clone!(@weak self as imp => @default-return glib::Propagation::Proceed, move |_controller, key, _keycode, modifier| {
const NO_MODIFIER: gdk::ModifierType = gdk::ModifierType::empty();
match (key, modifier) {
(gdk::Key::Escape, NO_MODIFIER)
| (gdk::Key::w, PRIMARY_MODIFIER)
| (gdk::Key::W, PRIMARY_MODIFIER) => {
imp.send(gtk::ResponseType::Cancel);
glib::Propagation::Stop
}
(gdk::Key::Return, NO_MODIFIER) => {
imp.ok_button.activate();
glib::Propagation::Stop
}
_ => glib::Propagation::Proceed,
}
}),
);
self.obj().add_controller(key_controller);
}
}

impl WidgetImpl for GenericDialog {}
impl WindowImpl for GenericDialog {}

impl GenericDialog {
pub fn send(&self, response: gtk::ResponseType) {
let mut sender_opt = self.sender.borrow_mut();
let Some(sender) = sender_opt.as_mut() else {
eprintln!("No sender");
return;
};
if let Err(err) = sender.try_send(response) {
eprintln!("Cannot send response {}. {}", response, err);
}
}

pub async fn next_response(&self) -> Option<gtk::ResponseType> {
self.receiver.borrow_mut().as_mut()?.next().await
}
}
}

glib::wrapper! {
pub struct GenericDialog(ObjectSubclass<imp::GenericDialog>)
@extends gtk::Widget, gtk::Window;
}

impl Default for GenericDialog {
fn default() -> Self {
glib::Object::builder().build()
}
}

impl GenericDialog {
pub fn set_title(&self, title: &str) {
self.imp().title.set_label(title);
}

pub fn set_ok_label(&self, label: &str) {
self.imp().ok_button.set_label(label);
}

pub fn set_ok_sensitive(&self, sensitive: bool) {
self.imp().ok_button.set_sensitive(sensitive);
}

pub fn emit_response(&self, response: gtk::ResponseType) {
self.imp().send(response);
}

pub async fn run(&self) -> Option<gtk::ResponseType> {
self.present();
let result = self.imp().next_response().await;
self.set_visible(false);
result
}
}
3 changes: 2 additions & 1 deletion src/ui/dialogs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
pub mod about;
pub mod ask;
pub mod ask_save;
pub mod change_password;
pub mod file_chooser;
pub mod generic_dialog;
pub mod preferences;
pub mod say;
pub mod shortcuts;
pub mod show_uri;
9 changes: 1 addition & 8 deletions src/ui/dialogs/preferences.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,5 @@ impl FormWidget<Config> for ConfigForm {

pub async fn preferences(parent_window: &gtk::Window, config: &Config) -> Option<Config> {
let form = ConfigForm::new();
edit_object(
Some(config),
form,
parent_window,
"Preferences",
"password-storage",
)
.await
edit_object(Some(config), form, parent_window, "Preferences").await
}
Loading

0 comments on commit 8359466

Please sign in to comment.