providers: prepare for greatness

make sure we all i18n ready
This commit is contained in:
Bilal Elmoussaoui 2021-01-30 11:43:10 +01:00
parent be4b00e39b
commit 11d6464bd6
10 changed files with 150 additions and 111 deletions

View file

@ -1 +1,7 @@
i18n.gettext(gettext_package, preset: 'glib')
i18n.gettext(
gettext_package,
args: [
'--keyword=i18n_f'
],
preset: 'glib'
)

View file

@ -33,6 +33,7 @@ sources = files(
'models/algorithm.rs',
'models/database.rs',
'models/favicon.rs',
'models/i18n.rs',
'models/keyring.rs',
'models/mod.rs',
'models/otp.rs',

15
src/models/i18n.rs Normal file
View file

@ -0,0 +1,15 @@
use gettextrs::gettext;
fn freplace(input: String, args: &[&str]) -> String {
let mut parts = input.split("{}");
let mut output = parts.next().unwrap_or("").to_string();
for (p, a) in parts.zip(args.iter()) {
output += &(a.to_string() + &p.to_string());
}
output
}
pub(crate) fn i18n_f(format: &str, args: &[&str]) -> String {
let s = gettext(format);
freplace(s, args)
}

View file

@ -5,6 +5,7 @@ mod accounts;
mod algorithm;
pub mod database;
mod favicon;
pub mod i18n;
mod keyring;
pub mod otp;
mod otp_uri;

View file

@ -187,7 +187,7 @@ impl AccountAddDialog {
otp_uri.digits,
otp_uri.counter,
)
.unwrap();
.ok();
self.set_provider(provider);
}
@ -214,43 +214,47 @@ impl AccountAddDialog {
Ok(())
}
fn set_provider(&self, provider: Provider) {
fn set_provider(&self, provider: Option<Provider>) {
let self_ = imp::AccountAddDialog::from_instance(self);
self_.more_list.show();
self_.provider_entry.set_text(&provider.name());
self_.period_label.set_text(&provider.period().to_string());
if let Some(provider) = provider {
self_.more_list.show();
self_.provider_entry.set_text(&provider.name());
self_.period_label.set_text(&provider.period().to_string());
self_.image.set_provider(&provider);
self_.image.set_provider(Some(&provider));
self_
.method_label
.set_text(&provider.method().to_locale_string());
self_
.method_label
.set_text(&provider.method().to_locale_string());
self_
.algorithm_label
.set_text(&provider.algorithm().to_locale_string());
self_
.algorithm_label
.set_text(&provider.algorithm().to_locale_string());
self_.digits_label.set_text(&provider.digits().to_string());
self_.digits_label.set_text(&provider.digits().to_string());
match provider.method() {
OTPMethod::TOTP => {
self_.counter_row.hide();
self_.period_row.show();
match provider.method() {
OTPMethod::TOTP => {
self_.counter_row.hide();
self_.period_row.show();
}
OTPMethod::HOTP => {
self_.counter_row.show();
self_.period_row.hide();
}
OTPMethod::Steam => {}
};
if let Some(ref website) = provider.website() {
self_.provider_website_row.set_uri(website);
}
OTPMethod::HOTP => {
self_.counter_row.show();
self_.period_row.hide();
if let Some(ref help_url) = provider.help_url() {
self_.provider_help_row.set_uri(help_url);
}
OTPMethod::Steam => {}
};
if let Some(ref website) = provider.website() {
self_.provider_website_row.set_uri(website);
self_.selected_provider.borrow_mut().replace(provider);
} else {
self_.selected_provider.borrow_mut().take();
}
if let Some(ref help_url) = provider.help_url() {
self_.provider_help_row.set_uri(help_url);
}
self_.selected_provider.borrow_mut().replace(provider);
}
fn setup_actions(&self) {
@ -300,7 +304,7 @@ impl AccountAddDialog {
self_.provider_completion.connect_match_selected(
clone!(@weak self as dialog, @strong self_.model as model => move |_, store, iter| {
let provider_id = store.get_value(iter, 0).get_some::<u32>().unwrap();
let provider = model.get().unwrap().find_by_id(provider_id).unwrap();
let provider = model.get().unwrap().find_by_id(provider_id);
dialog.set_provider(provider);
Inhibit(false)

View file

@ -1,4 +1,4 @@
use super::{ProviderPage, ProviderPageMode};
use super::ProviderPage;
use crate::models::{Provider, ProviderSorter, ProvidersModel};
use glib::clone;
use gtk::{gio, glib, prelude::*, subclass::prelude::*, CompositeTemplate};
@ -186,14 +186,14 @@ impl ProvidersDialog {
fn add_provider(&self) {
let self_ = imp::ProvidersDialog::from_instance(self);
self_.deck.set_visible_child_name("provider");
self_.page.set_mode(ProviderPageMode::Create);
// By not setting the current provider we implicitly say it's for creating a new one
self_.page.set_provider(None);
}
fn edit_provider(&self, provider: Provider) {
let self_ = imp::ProvidersDialog::from_instance(self);
self_.deck.set_visible_child_name("provider");
self_.page.set_provider(provider);
self_.page.set_mode(ProviderPageMode::Edit);
self_.page.set_provider(Some(provider));
}
}

View file

@ -132,37 +132,43 @@ impl ProviderImage {
glib::Object::new(&[]).expect("Failed to create ProviderImage")
}
pub fn set_provider(&self, provider: &Provider) {
pub fn set_provider(&self, provider: Option<&Provider>) {
let self_ = imp::ProviderImage::from_instance(self);
self_.stack.set_visible_child_name("loading");
self_.spinner.start();
if let Some(provider) = provider {
self_.stack.set_visible_child_name("loading");
self_.spinner.start();
self.set_property("provider", &provider.clone()).unwrap();
self.set_property("provider", &provider.clone()).unwrap();
match provider.image_uri() {
Some(uri) => {
// Very dirty hack to store that we couldn't find an icon
// to avoid re-hitting the website every time we have to display it
if uri == "invalid" {
self_
.image
.set_from_icon_name(Some("image-missing-symbolic"));
match provider.image_uri() {
Some(uri) => {
// Very dirty hack to store that we couldn't find an icon
// to avoid re-hitting the website every time we have to display it
if uri == "invalid" {
self_
.image
.set_from_icon_name(Some("image-missing-symbolic"));
self_.stack.set_visible_child_name("image");
return;
}
let file = gio::File::new_for_uri(&uri);
if !file.query_exists(gio::NONE_CANCELLABLE) {
self.fetch();
return;
}
self_.image.set_from_file(file.get_path().unwrap());
self_.stack.set_visible_child_name("image");
return;
}
let file = gio::File::new_for_uri(&uri);
if !file.query_exists(gio::NONE_CANCELLABLE) {
_ => {
self.fetch();
return;
}
self_.image.set_from_file(file.get_path().unwrap());
self_.stack.set_visible_child_name("image");
}
_ => {
self.fetch();
}
} else {
self_
.image
.set_from_icon_name(Some("image-missing-symbolic"));
}
}

View file

@ -7,6 +7,6 @@ pub use self::{
dialog::ProvidersDialog,
image::ProviderImage,
list::{ProvidersList, ProvidersListView},
page::{ProviderPage, ProviderPageMode},
page::ProviderPage,
row::ProviderRow,
};

View file

@ -1,5 +1,5 @@
use crate::{
models::{otp, Algorithm, OTPMethod, Provider},
models::{i18n, otp, Algorithm, OTPMethod, Provider},
widgets::ProviderImage,
};
use adw::ComboRowExt;
@ -7,11 +7,6 @@ use gettextrs::gettext;
use glib::{clone, translate::ToGlib};
use gtk::{glib, prelude::*, subclass::prelude::*, CompositeTemplate};
pub enum ProviderPageMode {
Create,
Edit,
}
mod imp {
use crate::models::OTPMethod;
@ -112,40 +107,69 @@ impl ProviderPage {
glib::Object::new(&[]).expect("Failed to create ProviderPage")
}
pub fn set_provider(&self, provider: Provider) {
pub fn set_provider(&self, provider: Option<Provider>) {
let self_ = imp::ProviderPage::from_instance(self);
self_.name_entry.set_text(&provider.name());
self_.period_spinbutton.set_value(provider.period() as f64);
if let Some(provider) = provider {
self_.name_entry.set_text(&provider.name());
self_.period_spinbutton.set_value(provider.period() as f64);
if let Some(ref website) = provider.website() {
self_.provider_website_entry.set_text(website);
}
if let Some(ref website) = provider.website() {
self_.provider_website_entry.set_text(website);
}
if let Some(ref website) = provider.help_url() {
self_.provider_help_entry.set_text(website);
}
if let Some(ref website) = provider.help_url() {
self_.provider_help_entry.set_text(website);
}
self_.algorithm_comborow.set_selected(
self_
.algorithms_model
.find_position(provider.algorithm().to_glib()),
);
self_.algorithm_comborow.set_selected(
self_
.algorithms_model
.find_position(provider.algorithm().to_glib()),
);
self.on_method_changed();
.default_counter_spinbutton
.set_value(provider.default_counter() as f64);
self_.digits_spinbutton.set_value(provider.digits() as f64);
self_
.default_counter_spinbutton
.set_value(provider.default_counter() as f64);
self_.digits_spinbutton.set_value(provider.digits() as f64);
self_.method_comborow.set_selected(
self_.method_comborow.set_selected(
self_
.methods_model
.find_position(provider.method().to_glib()),
);
self_.image.set_provider(Some(&provider));
self_
.methods_model
.find_position(provider.method().to_glib()),
);
self_.image.set_provider(&provider);
self_
.title
.set_text(&format!("Editing provider: {}", provider.name()));
.title
.set_text(&i18n::i18n_f("Editing Provider: {}", &[&provider.name()]));
} else {
self_.name_entry.set_text("");
self_
.period_spinbutton
.set_value(otp::TOTP_DEFAULT_PERIOD as f64);
self_.provider_website_entry.set_text("");
self_.provider_help_entry.set_text("");
self_.algorithm_comborow.set_selected(
self_
.algorithms_model
.find_position(Algorithm::default().to_glib()),
);
self_
.default_counter_spinbutton
.set_value(otp::HOTP_DEFAULT_COUNTER as f64);
self_
.digits_spinbutton
.set_value(otp::DEFAULT_DIGITS as f64);
self_.method_comborow.set_selected(
self_
.methods_model
.find_position(OTPMethod::default().to_glib()),
);
self_.image.set_provider(None);
self_.title.set_text(&gettext("New Provider"));
}
}
fn setup_widgets(&self) {
@ -178,22 +202,4 @@ impl ProviderPage {
OTPMethod::Steam => {}
}
}
pub fn set_mode(&self, mode: ProviderPageMode) {
let self_ = imp::ProviderPage::from_instance(self);
match mode {
ProviderPageMode::Create => {
self_.title.set_label(&gettext("New Provider"));
self_.name_entry.set_text("");
self_
.period_spinbutton
.set_value(otp::TOTP_DEFAULT_PERIOD as f64);
self_.provider_website_entry.set_text("");
self_.provider_help_entry.set_text("");
self_.method_comborow.set_selected(0);
}
ProviderPageMode::Edit => {}
}
}
}

View file

@ -232,7 +232,7 @@ impl ProviderRow {
self.add_css_class(&self.provider().method().to_string());
self_.image.set_provider(&self.provider());
self_.image.set_provider(Some(&self.provider()));
self.restart();
if self.provider().method() == OTPMethod::TOTP {