mirror of
https://gitlab.gnome.org/World/Authenticator.git
synced 2025-03-04 08:44:40 +01:00
move TypePriv inside imp
This commit is contained in:
parent
882d4db477
commit
aaee00a511
6 changed files with 587 additions and 621 deletions
|
@ -4,213 +4,222 @@ use crate::models::ProvidersModel;
|
|||
use crate::widgets::{PreferencesWindow, ProvidersDialog, Window};
|
||||
use gettextrs::gettext;
|
||||
use gio::prelude::*;
|
||||
use glib::subclass::prelude::*;
|
||||
use glib::{subclass, WeakRef};
|
||||
use gio::subclass::ObjectSubclass;
|
||||
use gtk::prelude::*;
|
||||
use gtk::subclass::prelude::{ApplicationImpl, ApplicationImplExt, GtkApplicationImpl};
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::env;
|
||||
|
||||
pub struct ApplicationPrivate {
|
||||
window: RefCell<Option<WeakRef<Window>>>,
|
||||
model: ProvidersModel,
|
||||
locked: Cell<bool>,
|
||||
can_be_locked: Cell<bool>,
|
||||
}
|
||||
static PROPERTIES: [subclass::Property; 2] = [
|
||||
subclass::Property("locked", |name| {
|
||||
glib::ParamSpec::boolean(name, "locked", "locked", false, glib::ParamFlags::READWRITE)
|
||||
}),
|
||||
subclass::Property("can-be-locked", |name| {
|
||||
glib::ParamSpec::boolean(
|
||||
name,
|
||||
"can_be_locked",
|
||||
"can be locked",
|
||||
false,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
];
|
||||
impl ObjectSubclass for ApplicationPrivate {
|
||||
const NAME: &'static str = "Application";
|
||||
type ParentType = gtk::Application;
|
||||
type Type = super::Application;
|
||||
type Instance = subclass::simple::InstanceStruct<Self>;
|
||||
type Class = subclass::simple::ClassStruct<Self>;
|
||||
mod imp {
|
||||
use super::*;
|
||||
use glib::subclass::prelude::*;
|
||||
use glib::{subclass, WeakRef};
|
||||
use gtk::subclass::prelude::{ApplicationImpl, ApplicationImplExt, GtkApplicationImpl};
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
||||
glib_object_subclass!();
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
klass.install_properties(&PROPERTIES);
|
||||
pub struct Application {
|
||||
pub window: RefCell<Option<WeakRef<Window>>>,
|
||||
pub model: ProvidersModel,
|
||||
pub locked: Cell<bool>,
|
||||
pub can_be_locked: Cell<bool>,
|
||||
}
|
||||
|
||||
fn new() -> Self {
|
||||
let model = ProvidersModel::new();
|
||||
static PROPERTIES: [subclass::Property; 2] = [
|
||||
subclass::Property("locked", |name| {
|
||||
glib::ParamSpec::boolean(name, "locked", "locked", false, glib::ParamFlags::READWRITE)
|
||||
}),
|
||||
subclass::Property("can-be-locked", |name| {
|
||||
glib::ParamSpec::boolean(
|
||||
name,
|
||||
"can_be_locked",
|
||||
"can be locked",
|
||||
false,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
];
|
||||
impl ObjectSubclass for Application {
|
||||
const NAME: &'static str = "Application";
|
||||
type ParentType = gtk::Application;
|
||||
type Type = super::Application;
|
||||
type Instance = subclass::simple::InstanceStruct<Self>;
|
||||
type Class = subclass::simple::ClassStruct<Self>;
|
||||
|
||||
Self {
|
||||
window: RefCell::new(None),
|
||||
model,
|
||||
can_be_locked: Cell::new(false),
|
||||
locked: Cell::new(false),
|
||||
glib_object_subclass!();
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
klass.install_properties(&PROPERTIES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectImpl for ApplicationPrivate {
|
||||
fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
|
||||
let prop = &PROPERTIES[id];
|
||||
fn new() -> Self {
|
||||
let model = ProvidersModel::new();
|
||||
|
||||
match *prop {
|
||||
subclass::Property("locked", ..) => {
|
||||
let locked = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`")
|
||||
.unwrap();
|
||||
self.locked.set(locked);
|
||||
Self {
|
||||
window: RefCell::new(None),
|
||||
model,
|
||||
can_be_locked: Cell::new(false),
|
||||
locked: Cell::new(false),
|
||||
}
|
||||
subclass::Property("can-be-locked", ..) => {
|
||||
let can_be_locked = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`")
|
||||
.unwrap();
|
||||
self.can_be_locked.set(can_be_locked);
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectImpl for Application {
|
||||
fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
|
||||
let prop = &PROPERTIES[id];
|
||||
|
||||
match *prop {
|
||||
subclass::Property("locked", ..) => {
|
||||
let locked = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`")
|
||||
.unwrap();
|
||||
self.locked.set(locked);
|
||||
}
|
||||
subclass::Property("can-be-locked", ..) => {
|
||||
let can_be_locked = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`")
|
||||
.unwrap();
|
||||
self.can_be_locked.set(can_be_locked);
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
|
||||
let prop = &PROPERTIES[id];
|
||||
|
||||
match *prop {
|
||||
subclass::Property("locked", ..) => self.locked.get().to_value(),
|
||||
subclass::Property("can-be-locked", ..) => self.can_be_locked.get().to_value(),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
|
||||
let prop = &PROPERTIES[id];
|
||||
impl GtkApplicationImpl for Application {}
|
||||
impl ApplicationImpl for Application {
|
||||
fn startup(&self, app: &Self::Type) {
|
||||
self.parent_startup(app);
|
||||
|
||||
match *prop {
|
||||
subclass::Property("locked", ..) => self.locked.get().to_value(),
|
||||
subclass::Property("can-be-locked", ..) => self.can_be_locked.get().to_value(),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
libhandy::functions::init();
|
||||
|
||||
impl GtkApplicationImpl for ApplicationPrivate {}
|
||||
impl ApplicationImpl for ApplicationPrivate {
|
||||
fn startup(&self, app: &Self::Type) {
|
||||
self.parent_startup(app);
|
||||
let app = app.downcast_ref::<super::Application>().unwrap();
|
||||
if let Some(ref display) = gdk::Display::get_default() {
|
||||
let p = gtk::CssProvider::new();
|
||||
gtk::CssProvider::load_from_resource(
|
||||
&p,
|
||||
"/com/belmoussaoui/Authenticator/style.css",
|
||||
);
|
||||
gtk::StyleContext::add_provider_for_display(display, &p, 500);
|
||||
let theme = gtk::IconTheme::get_for_display(display).unwrap();
|
||||
theme.add_resource_path("/com/belmoussaoui/Authenticator/icons/");
|
||||
}
|
||||
|
||||
libhandy::functions::init();
|
||||
action!(app, "quit", clone!(@weak app => move |_, _| app.quit()));
|
||||
|
||||
let app = app.downcast_ref::<Application>().unwrap();
|
||||
if let Some(ref display) = gdk::Display::get_default() {
|
||||
let p = gtk::CssProvider::new();
|
||||
gtk::CssProvider::load_from_resource(&p, "/com/belmoussaoui/Authenticator/style.css");
|
||||
gtk::StyleContext::add_provider_for_display(display, &p, 500);
|
||||
let theme = gtk::IconTheme::get_for_display(display).unwrap();
|
||||
theme.add_resource_path("/com/belmoussaoui/Authenticator/icons/");
|
||||
action!(
|
||||
app,
|
||||
"preferences",
|
||||
clone!(@weak app, @weak self.model as model => move |_,_| {
|
||||
let active_window = app.get_active_window().unwrap();
|
||||
let win = active_window.downcast_ref::<Window>().unwrap();
|
||||
|
||||
let preferences = PreferencesWindow::new(model);
|
||||
preferences.connect_local("restore-completed", false, clone!(@weak win => move |_| {
|
||||
win.providers().refilter();
|
||||
None
|
||||
}));
|
||||
preferences.set_transient_for(Some(&active_window));
|
||||
preferences.show();
|
||||
})
|
||||
);
|
||||
|
||||
// About
|
||||
action!(
|
||||
app,
|
||||
"about",
|
||||
clone!(@weak app => move |_, _| {
|
||||
let window = app.get_active_window().unwrap();
|
||||
let about_dialog = gtk::AboutDialogBuilder::new()
|
||||
.program_name(&gettext("Authenticator"))
|
||||
.modal(true)
|
||||
.version(config::VERSION)
|
||||
.comments(&gettext("Generate Two-Factor codes"))
|
||||
.website("https://gitlab.gnome.org/World/Authenticator")
|
||||
.authors(vec!["Bilal Elmoussaoui".to_string()])
|
||||
.artists(vec!["Alexandros Felekidis".to_string(), "Tobias Bernard".to_string()])
|
||||
.translator_credits(&gettext("translator-credits"))
|
||||
.logo_icon_name(config::APP_ID)
|
||||
.license_type(gtk::License::Gpl30)
|
||||
.transient_for(&window)
|
||||
.build();
|
||||
|
||||
about_dialog.show();
|
||||
})
|
||||
);
|
||||
action!(
|
||||
app,
|
||||
"providers",
|
||||
clone!(@weak app, @weak self.model as model => move |_, _| {
|
||||
let window = app.get_active_window().unwrap();
|
||||
let providers = ProvidersDialog::new(model);
|
||||
providers.set_transient_for(Some(&window));
|
||||
providers.show();
|
||||
})
|
||||
);
|
||||
|
||||
action!(
|
||||
app,
|
||||
"lock",
|
||||
clone!(@weak app => move |_, _| {
|
||||
app.set_locked(true);
|
||||
})
|
||||
);
|
||||
app.bind_property("can-be-locked", &get_action!(app, @lock), "enabled")
|
||||
.flags(glib::BindingFlags::DEFAULT | glib::BindingFlags::SYNC_CREATE)
|
||||
.build();
|
||||
app.bind_property("locked", &get_action!(app, @preferences), "enabled")
|
||||
.flags(glib::BindingFlags::INVERT_BOOLEAN | glib::BindingFlags::SYNC_CREATE)
|
||||
.build();
|
||||
app.bind_property("locked", &get_action!(app, @providers), "enabled")
|
||||
.flags(glib::BindingFlags::INVERT_BOOLEAN | glib::BindingFlags::SYNC_CREATE)
|
||||
.build();
|
||||
}
|
||||
|
||||
action!(app, "quit", clone!(@weak app => move |_, _| app.quit()));
|
||||
fn activate(&self, app: &Self::Type) {
|
||||
if let Some(ref win) = *self.window.borrow() {
|
||||
let window = win.upgrade().unwrap();
|
||||
window.present();
|
||||
return;
|
||||
}
|
||||
|
||||
action!(
|
||||
app,
|
||||
"preferences",
|
||||
clone!(@weak app, @weak self.model as model => move |_,_| {
|
||||
let active_window = app.get_active_window().unwrap();
|
||||
let win = active_window.downcast_ref::<Window>().unwrap();
|
||||
|
||||
let preferences = PreferencesWindow::new(model);
|
||||
preferences.connect_local("restore-completed", false, clone!(@weak win => move |_| {
|
||||
win.providers().refilter();
|
||||
None
|
||||
}));
|
||||
preferences.set_transient_for(Some(&active_window));
|
||||
preferences.show();
|
||||
})
|
||||
);
|
||||
|
||||
// About
|
||||
action!(
|
||||
app,
|
||||
"about",
|
||||
clone!(@weak app => move |_, _| {
|
||||
let window = app.get_active_window().unwrap();
|
||||
let about_dialog = gtk::AboutDialogBuilder::new()
|
||||
.program_name(&gettext("Authenticator"))
|
||||
.modal(true)
|
||||
.version(config::VERSION)
|
||||
.comments(&gettext("A Two-Factor Authentication application"))
|
||||
.website("https://gitlab.gnome.org/World/Authenticator")
|
||||
.authors(vec!["Bilal Elmoussaoui".to_string()])
|
||||
.artists(vec!["Alexandros Felekidis".to_string(), "Tobias Bernard".to_string()])
|
||||
.translator_credits(&gettext("translator-credits"))
|
||||
.logo_icon_name(config::APP_ID)
|
||||
.license_type(gtk::License::Gpl30)
|
||||
.transient_for(&window)
|
||||
.build();
|
||||
|
||||
about_dialog.show();
|
||||
})
|
||||
);
|
||||
action!(
|
||||
app,
|
||||
"providers",
|
||||
clone!(@weak app, @weak self.model as model => move |_, _| {
|
||||
let window = app.get_active_window().unwrap();
|
||||
let providers = ProvidersDialog::new(model);
|
||||
providers.set_transient_for(Some(&window));
|
||||
providers.show();
|
||||
})
|
||||
);
|
||||
|
||||
action!(
|
||||
app,
|
||||
"lock",
|
||||
clone!(@weak app => move |_, _| {
|
||||
app.set_locked(true);
|
||||
})
|
||||
);
|
||||
app.bind_property("can-be-locked", &get_action!(app, @lock), "enabled")
|
||||
.flags(glib::BindingFlags::DEFAULT | glib::BindingFlags::SYNC_CREATE)
|
||||
.build();
|
||||
app.bind_property("locked", &get_action!(app, @preferences), "enabled")
|
||||
.flags(glib::BindingFlags::INVERT_BOOLEAN | glib::BindingFlags::SYNC_CREATE)
|
||||
.build();
|
||||
app.bind_property("locked", &get_action!(app, @providers), "enabled")
|
||||
.flags(glib::BindingFlags::INVERT_BOOLEAN | glib::BindingFlags::SYNC_CREATE)
|
||||
.build();
|
||||
}
|
||||
|
||||
fn activate(&self, app: &Self::Type) {
|
||||
if let Some(ref win) = *self.window.borrow() {
|
||||
let window = win.upgrade().unwrap();
|
||||
let app = app.downcast_ref::<super::Application>().unwrap();
|
||||
let window = app.create_window();
|
||||
window.present();
|
||||
return;
|
||||
self.window.replace(Some(window.downgrade()));
|
||||
|
||||
Keyring::ensure_unlocked()
|
||||
.expect("Authenticator couldn't reach a secret service provider or unlock it");
|
||||
|
||||
let has_set_password = Keyring::has_set_password().unwrap_or_else(|_| false);
|
||||
|
||||
app.set_resource_base_path(Some("/com/belmoussaoui/Authenticator"));
|
||||
app.set_accels_for_action("app.quit", &["<primary>q"]);
|
||||
app.set_accels_for_action("app.lock", &["<primary>l"]);
|
||||
app.set_accels_for_action("app.providers", &["<primary>p"]);
|
||||
app.set_accels_for_action("app.preferences", &["<primary>comma"]);
|
||||
app.set_accels_for_action("win.show-help-overlay", &["<primary>question"]);
|
||||
app.set_accels_for_action("win.search", &["<primary>f"]);
|
||||
app.set_accels_for_action("win.add-account", &["<primary>n"]);
|
||||
app.set_accels_for_action("add.scan-qr", &["<primary>t"]);
|
||||
|
||||
app.set_locked(has_set_password);
|
||||
app.set_can_be_locked(has_set_password);
|
||||
}
|
||||
|
||||
let app = app.downcast_ref::<Application>().unwrap();
|
||||
let window = app.create_window();
|
||||
window.present();
|
||||
self.window.replace(Some(window.downgrade()));
|
||||
|
||||
Keyring::ensure_unlocked()
|
||||
.expect("Authenticator couldn't reach a secret service provider or unlock it");
|
||||
|
||||
let has_set_password = Keyring::has_set_password().unwrap_or_else(|_| false);
|
||||
|
||||
app.set_resource_base_path(Some("/com/belmoussaoui/Authenticator"));
|
||||
app.set_accels_for_action("app.quit", &["<primary>q"]);
|
||||
app.set_accels_for_action("app.lock", &["<primary>l"]);
|
||||
app.set_accels_for_action("app.providers", &["<primary>p"]);
|
||||
app.set_accels_for_action("app.preferences", &["<primary>comma"]);
|
||||
app.set_accels_for_action("win.show-help-overlay", &["<primary>question"]);
|
||||
app.set_accels_for_action("win.search", &["<primary>f"]);
|
||||
app.set_accels_for_action("win.add-account", &["<primary>n"]);
|
||||
app.set_accels_for_action("add.scan-qr", &["<primary>t"]);
|
||||
|
||||
app.set_locked(has_set_password);
|
||||
app.set_can_be_locked(has_set_password);
|
||||
}
|
||||
}
|
||||
|
||||
glib_wrapper! {
|
||||
pub struct Application(ObjectSubclass<ApplicationPrivate>)
|
||||
pub struct Application(ObjectSubclass<imp::Application>)
|
||||
@extends gio::Application, gtk::Application, gio::ActionMap;
|
||||
}
|
||||
|
||||
|
@ -236,7 +245,7 @@ impl Application {
|
|||
}
|
||||
|
||||
pub fn locked(&self) -> bool {
|
||||
let self_ = ApplicationPrivate::from_instance(self);
|
||||
let self_ = imp::Application::from_instance(self);
|
||||
return self_.locked.get();
|
||||
}
|
||||
|
||||
|
@ -251,7 +260,7 @@ impl Application {
|
|||
}
|
||||
|
||||
fn create_window(&self) -> Window {
|
||||
let self_ = ApplicationPrivate::from_instance(self);
|
||||
let self_ = imp::Application::from_instance(self);
|
||||
let window = Window::new(self_.model.clone(), &self.clone());
|
||||
|
||||
window
|
||||
|
|
|
@ -9,8 +9,7 @@ use anyhow::Result;
|
|||
use byteorder::{BigEndian, ReadBytesExt};
|
||||
use core::cmp::Ordering;
|
||||
use diesel::{BelongingToDsl, ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||
use gio::FileExt;
|
||||
use glib::subclass::{self, prelude::*};
|
||||
use gio::{subclass::ObjectSubclass, FileExt};
|
||||
use glib::{Cast, ObjectExt, StaticType, ToValue};
|
||||
use once_cell::sync::OnceCell;
|
||||
use qrcode::QrCode;
|
||||
|
@ -38,164 +37,150 @@ pub struct DiAccount {
|
|||
pub provider_id: i32,
|
||||
}
|
||||
|
||||
pub struct AccountPriv {
|
||||
pub id: Cell<i32>,
|
||||
pub otp: RefCell<String>,
|
||||
pub name: RefCell<String>,
|
||||
pub counter: Cell<i32>,
|
||||
pub token: OnceCell<String>,
|
||||
pub token_id: RefCell<String>,
|
||||
pub provider: RefCell<Option<Provider>>,
|
||||
}
|
||||
mod imp {
|
||||
use super::*;
|
||||
use glib::subclass::{self, prelude::*};
|
||||
|
||||
static PROPERTIES: [subclass::Property; 6] = [
|
||||
subclass::Property("id", |name| {
|
||||
glib::ParamSpec::int(
|
||||
name,
|
||||
"id",
|
||||
"Id",
|
||||
0,
|
||||
i32::MAX,
|
||||
0,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("counter", |name| {
|
||||
glib::ParamSpec::int(
|
||||
name,
|
||||
"counter",
|
||||
"Counter",
|
||||
0,
|
||||
i32::MAX,
|
||||
0,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("name", |name| {
|
||||
glib::ParamSpec::string(name, "name", "Name", None, glib::ParamFlags::READWRITE)
|
||||
}),
|
||||
subclass::Property("token-id", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"token-id",
|
||||
"token id",
|
||||
None,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("otp", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"otp",
|
||||
"The One Time Password",
|
||||
None,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("provider", |name| {
|
||||
glib::ParamSpec::object(
|
||||
name,
|
||||
"provider",
|
||||
"The account provider",
|
||||
Provider::static_type(),
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
];
|
||||
|
||||
impl ObjectSubclass for AccountPriv {
|
||||
const NAME: &'static str = "Account";
|
||||
type Type = super::Account;
|
||||
type ParentType = glib::Object;
|
||||
type Instance = subclass::simple::InstanceStruct<Self>;
|
||||
type Class = subclass::simple::ClassStruct<Self>;
|
||||
|
||||
glib_object_subclass!();
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
klass.install_properties(&PROPERTIES);
|
||||
static PROPERTIES: [subclass::Property; 6] = [
|
||||
subclass::Property("id", |name| {
|
||||
glib::ParamSpec::int(
|
||||
name,
|
||||
"id",
|
||||
"Id",
|
||||
0,
|
||||
i32::MAX,
|
||||
0,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("counter", |name| {
|
||||
glib::ParamSpec::int(
|
||||
name,
|
||||
"counter",
|
||||
"Counter",
|
||||
0,
|
||||
i32::MAX,
|
||||
0,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("name", |name| {
|
||||
glib::ParamSpec::string(name, "name", "Name", None, glib::ParamFlags::READWRITE)
|
||||
}),
|
||||
subclass::Property("token-id", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"token-id",
|
||||
"token id",
|
||||
None,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("otp", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"otp",
|
||||
"The One Time Password",
|
||||
None,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("provider", |name| {
|
||||
glib::ParamSpec::object(
|
||||
name,
|
||||
"provider",
|
||||
"The account provider",
|
||||
Provider::static_type(),
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
];
|
||||
pub struct Account {
|
||||
pub id: Cell<i32>,
|
||||
pub otp: RefCell<String>,
|
||||
pub name: RefCell<String>,
|
||||
pub counter: Cell<i32>,
|
||||
pub token: OnceCell<String>,
|
||||
pub token_id: RefCell<String>,
|
||||
pub provider: RefCell<Option<Provider>>,
|
||||
}
|
||||
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
id: Cell::new(0),
|
||||
counter: Cell::new(1),
|
||||
name: RefCell::new("".to_string()),
|
||||
otp: RefCell::new("".to_string()),
|
||||
token_id: RefCell::new("".to_string()),
|
||||
provider: RefCell::new(None),
|
||||
token: OnceCell::new(),
|
||||
impl ObjectSubclass for Account {
|
||||
const NAME: &'static str = "Account";
|
||||
type Type = super::Account;
|
||||
type ParentType = glib::Object;
|
||||
type Instance = subclass::simple::InstanceStruct<Self>;
|
||||
type Class = subclass::simple::ClassStruct<Self>;
|
||||
|
||||
glib_object_subclass!();
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
klass.install_properties(&PROPERTIES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectImpl for AccountPriv {
|
||||
fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
|
||||
let prop = &PROPERTIES[id];
|
||||
|
||||
match *prop {
|
||||
subclass::Property("id", ..) => {
|
||||
let id = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`")
|
||||
.unwrap();
|
||||
self.id.replace(id);
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
id: Cell::new(0),
|
||||
counter: Cell::new(1),
|
||||
name: RefCell::new("".to_string()),
|
||||
otp: RefCell::new("".to_string()),
|
||||
token_id: RefCell::new("".to_string()),
|
||||
provider: RefCell::new(None),
|
||||
token: OnceCell::new(),
|
||||
}
|
||||
subclass::Property("name", ..) => {
|
||||
let name = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`")
|
||||
.unwrap();
|
||||
self.name.replace(name);
|
||||
}
|
||||
subclass::Property("counter", ..) => {
|
||||
let counter = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`")
|
||||
.unwrap();
|
||||
self.counter.replace(counter);
|
||||
}
|
||||
subclass::Property("otp", ..) => {
|
||||
let otp = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`")
|
||||
.unwrap();
|
||||
self.otp.replace(otp);
|
||||
}
|
||||
subclass::Property("token-id", ..) => {
|
||||
let token_id = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`")
|
||||
.unwrap();
|
||||
self.token_id.replace(token_id);
|
||||
}
|
||||
subclass::Property("provider", ..) => {
|
||||
let provider = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`");
|
||||
self.provider.replace(provider);
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
|
||||
let prop = &PROPERTIES[id];
|
||||
impl ObjectImpl for Account {
|
||||
fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
|
||||
let prop = &PROPERTIES[id];
|
||||
|
||||
match *prop {
|
||||
subclass::Property("id", ..) => self.id.get().to_value(),
|
||||
subclass::Property("name", ..) => self.name.borrow().to_value(),
|
||||
subclass::Property("counter", ..) => self.counter.get().to_value(),
|
||||
subclass::Property("otp", ..) => self.otp.borrow().to_value(),
|
||||
subclass::Property("token-id", ..) => self.token_id.borrow().to_value(),
|
||||
subclass::Property("provider", ..) => self.provider.borrow().to_value(),
|
||||
_ => unimplemented!(),
|
||||
match *prop {
|
||||
subclass::Property("id", ..) => {
|
||||
let id = value.get().unwrap().unwrap();
|
||||
self.id.replace(id);
|
||||
}
|
||||
subclass::Property("name", ..) => {
|
||||
let name = value.get().unwrap().unwrap();
|
||||
self.name.replace(name);
|
||||
}
|
||||
subclass::Property("counter", ..) => {
|
||||
let counter = value.get().unwrap().unwrap();
|
||||
self.counter.replace(counter);
|
||||
}
|
||||
subclass::Property("otp", ..) => {
|
||||
let otp = value.get().unwrap().unwrap();
|
||||
self.otp.replace(otp);
|
||||
}
|
||||
subclass::Property("token-id", ..) => {
|
||||
let token_id = value.get().unwrap().unwrap();
|
||||
self.token_id.replace(token_id);
|
||||
}
|
||||
subclass::Property("provider", ..) => {
|
||||
let provider = value.get().unwrap();
|
||||
self.provider.replace(provider);
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
|
||||
let prop = &PROPERTIES[id];
|
||||
|
||||
match *prop {
|
||||
subclass::Property("id", ..) => self.id.get().to_value(),
|
||||
subclass::Property("name", ..) => self.name.borrow().to_value(),
|
||||
subclass::Property("counter", ..) => self.counter.get().to_value(),
|
||||
subclass::Property("otp", ..) => self.otp.borrow().to_value(),
|
||||
subclass::Property("token-id", ..) => self.token_id.borrow().to_value(),
|
||||
subclass::Property("provider", ..) => self.provider.borrow().to_value(),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glib_wrapper! {
|
||||
pub struct Account(ObjectSubclass<AccountPriv>);
|
||||
pub struct Account(ObjectSubclass<imp::Account>);
|
||||
}
|
||||
|
||||
impl Account {
|
||||
|
@ -274,8 +259,8 @@ impl Account {
|
|||
.expect("Created account is of wrong type");
|
||||
|
||||
let token = Keyring::token(token_id).unwrap().unwrap();
|
||||
let priv_ = AccountPriv::from_instance(&account);
|
||||
priv_.token.set(token);
|
||||
let self_ = imp::Account::from_instance(&account);
|
||||
self_.token.set(token);
|
||||
|
||||
account.init();
|
||||
account
|
||||
|
@ -326,9 +311,9 @@ impl Account {
|
|||
|
||||
fn increment_counter(&self) -> Result<()> {
|
||||
// For security reasons, never re-use the same counter for HOTP
|
||||
let priv_ = AccountPriv::from_instance(self);
|
||||
let self_ = imp::Account::from_instance(self);
|
||||
let new_value = self.counter() + 1;
|
||||
priv_.counter.set(new_value);
|
||||
self_.counter.set(new_value);
|
||||
|
||||
let db = database::connection();
|
||||
let conn = db.get()?;
|
||||
|
@ -343,8 +328,8 @@ impl Account {
|
|||
pub fn copy_otp(&self) {
|
||||
let display = gdk::Display::get_default().unwrap();
|
||||
let clipboard = display.get_clipboard();
|
||||
let priv_ = AccountPriv::from_instance(self);
|
||||
clipboard.set_text(&priv_.otp.borrow());
|
||||
let self_ = imp::Account::from_instance(self);
|
||||
clipboard.set_text(&self_.otp.borrow());
|
||||
|
||||
// Indirectly increment the counter once the token was copied
|
||||
if self.provider().method() == OTPMethod::HOTP {
|
||||
|
@ -353,8 +338,8 @@ impl Account {
|
|||
}
|
||||
|
||||
pub fn id(&self) -> i32 {
|
||||
let priv_ = AccountPriv::from_instance(self);
|
||||
priv_.id.get()
|
||||
let self_ = imp::Account::from_instance(self);
|
||||
self_.id.get()
|
||||
}
|
||||
|
||||
pub fn provider(&self) -> Provider {
|
||||
|
@ -363,23 +348,23 @@ impl Account {
|
|||
}
|
||||
|
||||
pub fn counter(&self) -> i32 {
|
||||
let priv_ = AccountPriv::from_instance(self);
|
||||
priv_.counter.get()
|
||||
let self_ = imp::Account::from_instance(self);
|
||||
self_.counter.get()
|
||||
}
|
||||
|
||||
pub fn name(&self) -> String {
|
||||
let priv_ = AccountPriv::from_instance(self);
|
||||
priv_.name.borrow().clone()
|
||||
let self_ = imp::Account::from_instance(self);
|
||||
self_.name.borrow().clone()
|
||||
}
|
||||
|
||||
pub fn token(&self) -> String {
|
||||
let priv_ = AccountPriv::from_instance(self);
|
||||
priv_.token.get().unwrap().clone()
|
||||
let self_ = imp::Account::from_instance(self);
|
||||
self_.token.get().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn token_id(&self) -> String {
|
||||
let priv_ = AccountPriv::from_instance(self);
|
||||
priv_.token_id.borrow().clone()
|
||||
let self_ = imp::Account::from_instance(self);
|
||||
self_.token_id.borrow().clone()
|
||||
}
|
||||
|
||||
pub fn otp_uri(&self) -> OTPUri {
|
||||
|
|
|
@ -6,10 +6,9 @@ use anyhow::Result;
|
|||
use core::cmp::Ordering;
|
||||
use diesel::{QueryDsl, RunQueryDsl};
|
||||
use gio::prelude::*;
|
||||
use gio::FileExt;
|
||||
use glib::subclass::{self, prelude::*};
|
||||
use gio::subclass::ObjectSubclass;
|
||||
use glib::{Cast, StaticType, ToValue};
|
||||
use gtk::FilterListModelExt;
|
||||
use gtk::prelude::*;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::str::FromStr;
|
||||
use std::string::ToString;
|
||||
|
@ -44,252 +43,231 @@ pub struct DiProvider {
|
|||
pub algorithm: String,
|
||||
pub method: String,
|
||||
}
|
||||
mod imp {
|
||||
use super::*;
|
||||
use glib::subclass::{self, prelude::*};
|
||||
|
||||
pub struct ProviderPriv {
|
||||
pub id: Cell<i32>,
|
||||
pub name: RefCell<String>,
|
||||
pub period: Cell<i32>,
|
||||
pub method: RefCell<String>,
|
||||
pub default_counter: Cell<i32>,
|
||||
pub algorithm: RefCell<String>,
|
||||
pub digits: Cell<i32>,
|
||||
pub website: RefCell<Option<String>>,
|
||||
pub help_url: RefCell<Option<String>>,
|
||||
pub image_uri: RefCell<Option<String>>,
|
||||
pub accounts: AccountsModel,
|
||||
pub filter_model: gtk::FilterListModel,
|
||||
}
|
||||
|
||||
static PROPERTIES: [subclass::Property; 11] = [
|
||||
subclass::Property("id", |name| {
|
||||
glib::ParamSpec::int(
|
||||
name,
|
||||
"id",
|
||||
"Id",
|
||||
0,
|
||||
i32::MAX,
|
||||
0,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("name", |name| {
|
||||
glib::ParamSpec::string(name, "name", "Name", None, glib::ParamFlags::READWRITE)
|
||||
}),
|
||||
subclass::Property("accounts", |name| {
|
||||
glib::ParamSpec::object(
|
||||
name,
|
||||
"accounts",
|
||||
"accounts",
|
||||
AccountsModel::static_type(),
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("period", |name| {
|
||||
glib::ParamSpec::int(
|
||||
name,
|
||||
"period",
|
||||
"Period",
|
||||
0,
|
||||
1000,
|
||||
30,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("digits", |name| {
|
||||
glib::ParamSpec::int(
|
||||
name,
|
||||
"digits",
|
||||
"Digits",
|
||||
0,
|
||||
1000,
|
||||
6,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("default-counter", |name| {
|
||||
glib::ParamSpec::int(
|
||||
name,
|
||||
"default_counter",
|
||||
"default_counter",
|
||||
0,
|
||||
i32::MAX,
|
||||
1,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("algorithm", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"algorithm",
|
||||
"Algorithm",
|
||||
Some(&Algorithm::default().to_string()),
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("method", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"method",
|
||||
"Method",
|
||||
Some(&OTPMethod::default().to_string()),
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("website", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"website",
|
||||
"Website",
|
||||
None,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("help-url", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"help url",
|
||||
"Help URL",
|
||||
None,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("image-uri", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"image uri",
|
||||
"Image URI",
|
||||
None,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
];
|
||||
|
||||
impl ObjectSubclass for ProviderPriv {
|
||||
const NAME: &'static str = "Provider";
|
||||
type Type = super::Provider;
|
||||
type ParentType = glib::Object;
|
||||
type Instance = subclass::simple::InstanceStruct<Self>;
|
||||
type Class = subclass::simple::ClassStruct<Self>;
|
||||
|
||||
glib_object_subclass!();
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
klass.install_properties(&PROPERTIES);
|
||||
static PROPERTIES: [subclass::Property; 11] = [
|
||||
subclass::Property("id", |name| {
|
||||
glib::ParamSpec::int(
|
||||
name,
|
||||
"id",
|
||||
"Id",
|
||||
0,
|
||||
i32::MAX,
|
||||
0,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("name", |name| {
|
||||
glib::ParamSpec::string(name, "name", "Name", None, glib::ParamFlags::READWRITE)
|
||||
}),
|
||||
subclass::Property("accounts", |name| {
|
||||
glib::ParamSpec::object(
|
||||
name,
|
||||
"accounts",
|
||||
"accounts",
|
||||
AccountsModel::static_type(),
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("period", |name| {
|
||||
glib::ParamSpec::int(
|
||||
name,
|
||||
"period",
|
||||
"Period",
|
||||
0,
|
||||
1000,
|
||||
30,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("digits", |name| {
|
||||
glib::ParamSpec::int(
|
||||
name,
|
||||
"digits",
|
||||
"Digits",
|
||||
0,
|
||||
1000,
|
||||
6,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("default-counter", |name| {
|
||||
glib::ParamSpec::int(
|
||||
name,
|
||||
"default_counter",
|
||||
"default_counter",
|
||||
0,
|
||||
i32::MAX,
|
||||
1,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("algorithm", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"algorithm",
|
||||
"Algorithm",
|
||||
Some(&Algorithm::default().to_string()),
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("method", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"method",
|
||||
"Method",
|
||||
Some(&OTPMethod::default().to_string()),
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("website", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"website",
|
||||
"Website",
|
||||
None,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("help-url", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"help url",
|
||||
"Help URL",
|
||||
None,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
subclass::Property("image-uri", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"image uri",
|
||||
"Image URI",
|
||||
None,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
}),
|
||||
];
|
||||
pub struct Provider {
|
||||
pub id: Cell<i32>,
|
||||
pub name: RefCell<String>,
|
||||
pub period: Cell<i32>,
|
||||
pub method: RefCell<String>,
|
||||
pub default_counter: Cell<i32>,
|
||||
pub algorithm: RefCell<String>,
|
||||
pub digits: Cell<i32>,
|
||||
pub website: RefCell<Option<String>>,
|
||||
pub help_url: RefCell<Option<String>>,
|
||||
pub image_uri: RefCell<Option<String>>,
|
||||
pub accounts: AccountsModel,
|
||||
pub filter_model: gtk::FilterListModel,
|
||||
}
|
||||
|
||||
fn new() -> Self {
|
||||
let model = AccountsModel::new();
|
||||
Self {
|
||||
id: Cell::new(0),
|
||||
default_counter: Cell::new(1),
|
||||
algorithm: RefCell::new(Algorithm::default().to_string()),
|
||||
digits: Cell::new(6),
|
||||
name: RefCell::new("".to_string()),
|
||||
website: RefCell::new(None),
|
||||
help_url: RefCell::new(None),
|
||||
image_uri: RefCell::new(None),
|
||||
method: RefCell::new(OTPMethod::default().to_string()),
|
||||
period: Cell::new(30),
|
||||
filter_model: gtk::FilterListModel::new(Some(&model), gtk::NONE_FILTER),
|
||||
accounts: model,
|
||||
impl ObjectSubclass for Provider {
|
||||
const NAME: &'static str = "Provider";
|
||||
type Type = super::Provider;
|
||||
type ParentType = glib::Object;
|
||||
type Instance = subclass::simple::InstanceStruct<Self>;
|
||||
type Class = subclass::simple::ClassStruct<Self>;
|
||||
|
||||
glib_object_subclass!();
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
klass.install_properties(&PROPERTIES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectImpl for ProviderPriv {
|
||||
fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
|
||||
let prop = &PROPERTIES[id];
|
||||
|
||||
match *prop {
|
||||
subclass::Property("id", ..) => {
|
||||
let id = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`")
|
||||
.unwrap();
|
||||
self.id.replace(id);
|
||||
fn new() -> Self {
|
||||
let model = AccountsModel::new();
|
||||
Self {
|
||||
id: Cell::new(0),
|
||||
default_counter: Cell::new(1),
|
||||
algorithm: RefCell::new(Algorithm::default().to_string()),
|
||||
digits: Cell::new(6),
|
||||
name: RefCell::new("".to_string()),
|
||||
website: RefCell::new(None),
|
||||
help_url: RefCell::new(None),
|
||||
image_uri: RefCell::new(None),
|
||||
method: RefCell::new(OTPMethod::default().to_string()),
|
||||
period: Cell::new(30),
|
||||
filter_model: gtk::FilterListModel::new(Some(&model), gtk::NONE_FILTER),
|
||||
accounts: model,
|
||||
}
|
||||
subclass::Property("name", ..) => {
|
||||
let name = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`")
|
||||
.unwrap();
|
||||
self.name.replace(name);
|
||||
}
|
||||
subclass::Property("period", ..) => {
|
||||
let period = value
|
||||
.get_some()
|
||||
.expect("type conformity checked by `Object::set_property`");
|
||||
self.period.replace(period);
|
||||
}
|
||||
subclass::Property("method", ..) => {
|
||||
let method = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`")
|
||||
.unwrap();
|
||||
self.method.replace(method);
|
||||
}
|
||||
subclass::Property("digits", ..) => {
|
||||
let digits = value
|
||||
.get_some()
|
||||
.expect("type conformity checked by `Object::set_property`");
|
||||
self.digits.replace(digits);
|
||||
}
|
||||
subclass::Property("algorithm", ..) => {
|
||||
let algorithm = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`")
|
||||
.unwrap();
|
||||
self.algorithm.replace(algorithm);
|
||||
}
|
||||
subclass::Property("default-counter", ..) => {
|
||||
let default_counter = value
|
||||
.get_some()
|
||||
.expect("type conformity checked by `Object::set_property`");
|
||||
self.default_counter.replace(default_counter);
|
||||
}
|
||||
subclass::Property("website", ..) => {
|
||||
let website = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`");
|
||||
self.website.replace(website);
|
||||
}
|
||||
subclass::Property("help-url", ..) => {
|
||||
let help_url = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`");
|
||||
self.help_url.replace(help_url);
|
||||
}
|
||||
subclass::Property("image-uri", ..) => {
|
||||
let image_uri = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`");
|
||||
self.image_uri.replace(image_uri);
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
|
||||
let prop = &PROPERTIES[id];
|
||||
impl ObjectImpl for Provider {
|
||||
fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
|
||||
let prop = &PROPERTIES[id];
|
||||
|
||||
match *prop {
|
||||
subclass::Property("id", ..) => self.id.get().to_value(),
|
||||
subclass::Property("name", ..) => self.name.borrow().to_value(),
|
||||
subclass::Property("period", ..) => self.period.get().to_value(),
|
||||
subclass::Property("method", ..) => self.method.borrow().to_value(),
|
||||
subclass::Property("digits", ..) => self.digits.get().to_value(),
|
||||
subclass::Property("algorithm", ..) => self.algorithm.borrow().to_value(),
|
||||
subclass::Property("default-counter", ..) => self.default_counter.get().to_value(),
|
||||
subclass::Property("website", ..) => self.website.borrow().to_value(),
|
||||
subclass::Property("help-url", ..) => self.help_url.borrow().to_value(),
|
||||
subclass::Property("image-uri", ..) => self.image_uri.borrow().to_value(),
|
||||
_ => unimplemented!(),
|
||||
match *prop {
|
||||
subclass::Property("id", ..) => {
|
||||
let id = value.get().unwrap().unwrap();
|
||||
self.id.replace(id);
|
||||
}
|
||||
subclass::Property("name", ..) => {
|
||||
let name = value.get().unwrap().unwrap();
|
||||
self.name.replace(name);
|
||||
}
|
||||
subclass::Property("period", ..) => {
|
||||
let period = value.get_some().unwrap();
|
||||
self.period.replace(period);
|
||||
}
|
||||
subclass::Property("method", ..) => {
|
||||
let method = value.get().unwrap().unwrap();
|
||||
self.method.replace(method);
|
||||
}
|
||||
subclass::Property("digits", ..) => {
|
||||
let digits = value.get_some().unwrap();
|
||||
self.digits.replace(digits);
|
||||
}
|
||||
subclass::Property("algorithm", ..) => {
|
||||
let algorithm = value.get().unwrap().unwrap();
|
||||
self.algorithm.replace(algorithm);
|
||||
}
|
||||
subclass::Property("default-counter", ..) => {
|
||||
let default_counter = value.get_some().unwrap();
|
||||
self.default_counter.replace(default_counter);
|
||||
}
|
||||
subclass::Property("website", ..) => {
|
||||
let website = value.get().unwrap();
|
||||
self.website.replace(website);
|
||||
}
|
||||
subclass::Property("help-url", ..) => {
|
||||
let help_url = value.get().unwrap();
|
||||
self.help_url.replace(help_url);
|
||||
}
|
||||
subclass::Property("image-uri", ..) => {
|
||||
let image_uri = value.get().unwrap();
|
||||
self.image_uri.replace(image_uri);
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
|
||||
let prop = &PROPERTIES[id];
|
||||
|
||||
match *prop {
|
||||
subclass::Property("id", ..) => self.id.get().to_value(),
|
||||
subclass::Property("name", ..) => self.name.borrow().to_value(),
|
||||
subclass::Property("period", ..) => self.period.get().to_value(),
|
||||
subclass::Property("method", ..) => self.method.borrow().to_value(),
|
||||
subclass::Property("digits", ..) => self.digits.get().to_value(),
|
||||
subclass::Property("algorithm", ..) => self.algorithm.borrow().to_value(),
|
||||
subclass::Property("default-counter", ..) => self.default_counter.get().to_value(),
|
||||
subclass::Property("website", ..) => self.website.borrow().to_value(),
|
||||
subclass::Property("help-url", ..) => self.help_url.borrow().to_value(),
|
||||
subclass::Property("image-uri", ..) => self.image_uri.borrow().to_value(),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glib_wrapper! {
|
||||
pub struct Provider(ObjectSubclass<ProviderPriv>);
|
||||
pub struct Provider(ObjectSubclass<imp::Provider>);
|
||||
}
|
||||
|
||||
impl Provider {
|
||||
|
@ -412,48 +390,48 @@ impl Provider {
|
|||
}
|
||||
|
||||
pub fn id(&self) -> i32 {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
priv_.id.get()
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
self_.id.get()
|
||||
}
|
||||
|
||||
pub fn name(&self) -> String {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
priv_.name.borrow().clone()
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
self_.name.borrow().clone()
|
||||
}
|
||||
|
||||
pub fn digits(&self) -> i32 {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
priv_.digits.get()
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
self_.digits.get()
|
||||
}
|
||||
|
||||
pub fn default_counter(&self) -> i32 {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
priv_.default_counter.get()
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
self_.default_counter.get()
|
||||
}
|
||||
|
||||
pub fn period(&self) -> i32 {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
priv_.period.get()
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
self_.period.get()
|
||||
}
|
||||
|
||||
pub fn algorithm(&self) -> Algorithm {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
Algorithm::from_str(&priv_.algorithm.borrow().clone()).unwrap()
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
Algorithm::from_str(&self_.algorithm.borrow().clone()).unwrap()
|
||||
}
|
||||
|
||||
pub fn method(&self) -> OTPMethod {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
OTPMethod::from_str(&priv_.method.borrow().clone()).unwrap()
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
OTPMethod::from_str(&self_.method.borrow().clone()).unwrap()
|
||||
}
|
||||
|
||||
pub fn website(&self) -> Option<String> {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
priv_.website.borrow().clone()
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
self_.website.borrow().clone()
|
||||
}
|
||||
|
||||
pub fn help_url(&self) -> Option<String> {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
priv_.help_url.borrow().clone()
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
self_.help_url.borrow().clone()
|
||||
}
|
||||
|
||||
pub fn set_image_uri(&self, uri: &str) -> Result<()> {
|
||||
|
@ -470,8 +448,8 @@ impl Provider {
|
|||
}
|
||||
|
||||
pub fn image_uri(&self) -> Option<String> {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
priv_.image_uri.borrow().clone()
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
self_.image_uri.borrow().clone()
|
||||
}
|
||||
|
||||
pub fn open_help(&self) {
|
||||
|
@ -481,43 +459,43 @@ impl Provider {
|
|||
}
|
||||
|
||||
pub fn has_account(&self, account: &Account) -> Option<u32> {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
priv_.accounts.find_by_id(account.id())
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
self_.accounts.find_by_id(account.id())
|
||||
}
|
||||
|
||||
pub fn has_accounts(&self) -> bool {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
priv_.accounts.get_n_items() != 0
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
self_.accounts.get_n_items() != 0
|
||||
}
|
||||
|
||||
pub fn add_account(&self, account: &Account) {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
priv_.accounts.insert(account);
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
self_.accounts.insert(account);
|
||||
}
|
||||
|
||||
pub fn accounts_model(&self) -> &AccountsModel {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
&priv_.accounts
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
&self_.accounts
|
||||
}
|
||||
|
||||
pub fn accounts(&self) -> >k::FilterListModel {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
&priv_.filter_model
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
&self_.filter_model
|
||||
}
|
||||
|
||||
pub fn filter(&self, text: String) {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
let filter = gtk::CustomFilter::new(Some(Box::new(move |obj| {
|
||||
let account = obj.downcast_ref::<Account>().unwrap();
|
||||
account.name().contains(&text)
|
||||
})));
|
||||
priv_.filter_model.set_filter(Some(&filter));
|
||||
self_.filter_model.set_filter(Some(&filter));
|
||||
}
|
||||
|
||||
pub fn remove_account(&self, account: Account) {
|
||||
let priv_ = ProviderPriv::from_instance(self);
|
||||
if let Some(pos) = priv_.accounts.find_by_id(account.id()) {
|
||||
priv_.accounts.remove(pos);
|
||||
let self_ = imp::Provider::from_instance(self);
|
||||
if let Some(pos) = self_.accounts.find_by_id(account.id()) {
|
||||
self_.accounts.remove(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,9 +74,7 @@ mod imp {
|
|||
|
||||
match *prop {
|
||||
subclass::Property("account", ..) => {
|
||||
let account = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`");
|
||||
let account = value.get().unwrap();
|
||||
self.account.replace(account);
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
|
|
|
@ -85,9 +85,7 @@ mod imp {
|
|||
|
||||
match *prop {
|
||||
subclass::Property("provider", ..) => {
|
||||
let provider = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`");
|
||||
let provider = value.get().unwrap();
|
||||
self.provider.replace(provider);
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
|
|
|
@ -75,9 +75,7 @@ mod imp {
|
|||
|
||||
match *prop {
|
||||
subclass::Property("provider", ..) => {
|
||||
let provider = value
|
||||
.get()
|
||||
.expect("type conformity checked by `Object::set_property`");
|
||||
let provider = value.get().unwrap();
|
||||
self.provider.replace(provider);
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
|
|
Loading…
Add table
Reference in a new issue