mirror of
https://gitlab.gnome.org/World/Authenticator.git
synced 2025-03-04 08:44:40 +01:00
add a UrlRow widget & use it
just a wrapper around ActionRow that opens the uri when activated
This commit is contained in:
parent
e927a7bb6b
commit
6be97a815f
7 changed files with 150 additions and 57 deletions
|
@ -138,32 +138,6 @@
|
|||
<object class="GtkListBox" id="more_list">
|
||||
<property name="visible">False</property>
|
||||
<property name="selection_mode">none</property>
|
||||
<child>
|
||||
<object class="HdyActionRow" id="provider_website_row">
|
||||
<property name="title" translatable="yes">Website</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="icon-name">link-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HdyActionRow" id="provider_help_row">
|
||||
<property name="title" translatable="yes">How to setup</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="icon-name">help-page-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HdyActionRow" id="algorithm_row">
|
||||
<property name="title" translatable="yes">Algorithm</property>
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
<property name="margin-start">8</property>
|
||||
<property name="margin-end">8</property>
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<object class="GtkListBox" id="list">
|
||||
<property name="selection_mode">none</property>
|
||||
<child>
|
||||
<object class="HdyActionRow">
|
||||
|
@ -55,19 +55,6 @@
|
|||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HdyActionRow" id="provider_website_row">
|
||||
<property name="title" translatable="yes">Website</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="icon-name">link-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="content"/>
|
||||
</style>
|
||||
|
|
|
@ -73,6 +73,7 @@ sources = files(
|
|||
'widgets/providers/page.rs',
|
||||
'widgets/providers/row.rs',
|
||||
'widgets/mod.rs',
|
||||
'widgets/url_row.rs',
|
||||
'widgets/window.rs',
|
||||
'application.rs',
|
||||
'config.rs',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::helpers::qrcode;
|
||||
use crate::models::{Account, OTPMethod, OTPUri, Provider, ProvidersModel};
|
||||
use crate::widgets::{ProviderImage, ProviderImageSize};
|
||||
use crate::widgets::{ProviderImage, ProviderImageSize, UrlRow};
|
||||
use anyhow::Result;
|
||||
use gio::prelude::*;
|
||||
use gio::{subclass::ObjectSubclass, ActionMapExt};
|
||||
|
@ -9,7 +9,6 @@ use glib::subclass::prelude::*;
|
|||
use glib::{clone, glib_object_subclass, glib_wrapper};
|
||||
use gtk::{prelude::*, CompositeTemplate};
|
||||
use gtk_macros::{action, get_action};
|
||||
use libhandy::ActionRowExt;
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
mod imp {
|
||||
|
@ -24,6 +23,8 @@ mod imp {
|
|||
pub selected_provider: RefCell<Option<Provider>>,
|
||||
pub actions: gio::SimpleActionGroup,
|
||||
pub image: ProviderImage,
|
||||
pub provider_website_row: UrlRow,
|
||||
pub provider_help_row: UrlRow,
|
||||
#[template_child]
|
||||
pub main_container: TemplateChild<gtk::Box>,
|
||||
#[template_child]
|
||||
|
@ -41,10 +42,6 @@ mod imp {
|
|||
#[template_child]
|
||||
pub method_label: TemplateChild<gtk::Label>,
|
||||
#[template_child]
|
||||
pub provider_website_row: TemplateChild<libhandy::ActionRow>,
|
||||
#[template_child]
|
||||
pub provider_help_row: TemplateChild<libhandy::ActionRow>,
|
||||
#[template_child]
|
||||
pub algorithm_label: TemplateChild<gtk::Label>,
|
||||
#[template_child]
|
||||
pub counter_row: TemplateChild<libhandy::ActionRow>,
|
||||
|
@ -65,10 +62,14 @@ mod imp {
|
|||
|
||||
fn new() -> Self {
|
||||
let actions = gio::SimpleActionGroup::new();
|
||||
let provider_website_row = UrlRow::new("Website", "link-symbolic");
|
||||
let provider_help_row = UrlRow::new("How to setup", "help-page-symbolic");
|
||||
|
||||
Self {
|
||||
actions,
|
||||
image: ProviderImage::new(ProviderImageSize::Large),
|
||||
provider_website_row,
|
||||
provider_help_row,
|
||||
model: OnceCell::new(),
|
||||
selected_provider: RefCell::new(None),
|
||||
main_container: TemplateChild::default(),
|
||||
|
@ -79,8 +80,6 @@ mod imp {
|
|||
digits_label: TemplateChild::default(),
|
||||
provider_entry: TemplateChild::default(),
|
||||
method_label: TemplateChild::default(),
|
||||
provider_website_row: TemplateChild::default(),
|
||||
provider_help_row: TemplateChild::default(),
|
||||
provider_completion: TemplateChild::default(),
|
||||
algorithm_label: TemplateChild::default(),
|
||||
counter_row: TemplateChild::default(),
|
||||
|
@ -246,10 +245,10 @@ impl AccountAddDialog {
|
|||
};
|
||||
|
||||
if let Some(ref website) = provider.website() {
|
||||
self_.provider_website_row.get().set_subtitle(Some(website));
|
||||
self_.provider_website_row.set_uri(website);
|
||||
}
|
||||
if let Some(ref help_url) = provider.help_url() {
|
||||
self_.provider_help_row.get().set_subtitle(Some(help_url));
|
||||
self_.provider_help_row.set_uri(help_url);
|
||||
}
|
||||
self_.selected_provider.borrow_mut().replace(provider);
|
||||
}
|
||||
|
@ -291,6 +290,9 @@ impl AccountAddDialog {
|
|||
.get()
|
||||
.set_model(Some(&self_.model.get().unwrap().completion_model()));
|
||||
|
||||
self_.more_list.get().prepend(&self_.provider_help_row);
|
||||
self_.more_list.get().prepend(&self_.provider_website_row);
|
||||
|
||||
self_.main_container.get().prepend(&self_.image);
|
||||
|
||||
self_.provider_completion.get().connect_match_selected(
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::models::Account;
|
||||
use crate::widgets::UrlRow;
|
||||
use gio::{subclass::ObjectSubclass, FileExt};
|
||||
use glib::subclass::prelude::*;
|
||||
use glib::{glib_object_subclass, glib_wrapper};
|
||||
use gtk::{prelude::*, CompositeTemplate};
|
||||
use libhandy::prelude::*;
|
||||
|
||||
mod imp {
|
||||
use super::*;
|
||||
|
@ -12,14 +12,15 @@ mod imp {
|
|||
|
||||
#[derive(Debug, CompositeTemplate)]
|
||||
pub struct QRCodePage {
|
||||
pub website_row: UrlRow,
|
||||
#[template_child]
|
||||
pub image: TemplateChild<gtk::Image>,
|
||||
#[template_child]
|
||||
pub provider_label: TemplateChild<gtk::Label>,
|
||||
#[template_child]
|
||||
pub account_label: TemplateChild<gtk::Label>,
|
||||
#[template_child(id = "provider_website_row")]
|
||||
pub website_row: TemplateChild<libhandy::ActionRow>,
|
||||
#[template_child(id = "list")]
|
||||
pub listbox: TemplateChild<gtk::ListBox>,
|
||||
}
|
||||
|
||||
impl ObjectSubclass for QRCodePage {
|
||||
|
@ -36,7 +37,8 @@ mod imp {
|
|||
image: TemplateChild::default(),
|
||||
account_label: TemplateChild::default(),
|
||||
provider_label: TemplateChild::default(),
|
||||
website_row: TemplateChild::default(),
|
||||
website_row: UrlRow::new("Website", "link-symbolic"),
|
||||
listbox: TemplateChild::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,6 +53,7 @@ mod imp {
|
|||
impl ObjectImpl for QRCodePage {
|
||||
fn constructed(&self, obj: &Self::Type) {
|
||||
obj.init_template();
|
||||
obj.setup_widgets();
|
||||
self.parent_constructed(obj);
|
||||
}
|
||||
}
|
||||
|
@ -87,10 +90,16 @@ impl QRCodePage {
|
|||
.set_text(&account.provider().name());
|
||||
|
||||
if let Some(ref website) = account.provider().website() {
|
||||
self_.website_row.get().set_subtitle(Some(website));
|
||||
self_.website_row.get().show();
|
||||
self_.website_row.set_uri(website);
|
||||
self_.website_row.show();
|
||||
} else {
|
||||
self_.website_row.get().hide();
|
||||
self_.website_row.hide();
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_widgets(&self) {
|
||||
let self_ = imp::QRCodePage::from_instance(self);
|
||||
|
||||
self_.listbox.get().append(&self_.website_row);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
mod accounts;
|
||||
mod preferences;
|
||||
mod providers;
|
||||
mod url_row;
|
||||
mod window;
|
||||
|
||||
pub use self::accounts::AccountAddDialog;
|
||||
pub use self::preferences::PreferencesWindow;
|
||||
pub use self::providers::{ProviderImage, ProviderImageSize, ProvidersDialog, ProvidersList};
|
||||
pub use self::url_row::UrlRow;
|
||||
pub use self::window::{View, Window};
|
||||
|
|
118
src/widgets/url_row.rs
Normal file
118
src/widgets/url_row.rs
Normal file
|
@ -0,0 +1,118 @@
|
|||
use gio::subclass::ObjectSubclass;
|
||||
use glib::{clone, glib_wrapper, Cast, ObjectExt, StaticType, ToValue};
|
||||
use gtk::WidgetExt;
|
||||
use libhandy::ActionRowExt;
|
||||
|
||||
mod imp {
|
||||
use super::*;
|
||||
use glib::{glib_object_subclass, subclass};
|
||||
use gtk::subclass::prelude::*;
|
||||
use libhandy::subclass::action_row::ActionRowImpl;
|
||||
use std::cell::RefCell;
|
||||
|
||||
static PROPERTIES: [subclass::Property; 1] = [subclass::Property("uri", |name| {
|
||||
glib::ParamSpec::string(
|
||||
name,
|
||||
"uri",
|
||||
"The Row URI",
|
||||
None,
|
||||
glib::ParamFlags::READWRITE,
|
||||
)
|
||||
})];
|
||||
|
||||
pub struct UrlRow {
|
||||
pub uri: RefCell<Option<String>>,
|
||||
}
|
||||
|
||||
impl ObjectSubclass for UrlRow {
|
||||
const NAME: &'static str = "UrlRow";
|
||||
type Type = super::UrlRow;
|
||||
type ParentType = libhandy::ActionRow;
|
||||
type Instance = subclass::simple::InstanceStruct<Self>;
|
||||
type Class = subclass::simple::ClassStruct<Self>;
|
||||
|
||||
glib_object_subclass!();
|
||||
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
uri: RefCell::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
klass.install_properties(&PROPERTIES);
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectImpl for UrlRow {
|
||||
fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
|
||||
let prop = &PROPERTIES[id];
|
||||
|
||||
match *prop {
|
||||
subclass::Property("uri", ..) => {
|
||||
let uri = value.get().unwrap();
|
||||
self.uri.replace(uri);
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
|
||||
let prop = &PROPERTIES[id];
|
||||
match *prop {
|
||||
subclass::Property("uri", ..) => self.uri.borrow().to_value(),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn constructed(&self, obj: &Self::Type) {
|
||||
self.parent_constructed(obj);
|
||||
}
|
||||
}
|
||||
impl WidgetImpl for UrlRow {}
|
||||
impl ListBoxRowImpl for UrlRow {}
|
||||
impl ActionRowImpl for UrlRow {}
|
||||
}
|
||||
|
||||
glib_wrapper! {
|
||||
pub struct UrlRow(ObjectSubclass<imp::UrlRow>) @extends gtk::Widget, gtk::ListBoxRow, libhandy::ActionRow;
|
||||
}
|
||||
|
||||
impl UrlRow {
|
||||
#[allow(clippy::new_without_default)]
|
||||
pub fn new(title: &str, icon_name: &str) -> Self {
|
||||
let row = glib::Object::new(Self::static_type(), &[])
|
||||
.expect("Failed to create UrlRow")
|
||||
.downcast::<UrlRow>()
|
||||
.expect("Created object is of wrong type");
|
||||
row.setup_widgets(title, icon_name);
|
||||
row
|
||||
}
|
||||
|
||||
fn setup_widgets(&self, title: &str, icon_name: &str) {
|
||||
self.set_property("title", &title).unwrap();
|
||||
|
||||
let gesture = gtk::GestureClick::new();
|
||||
gesture.connect_pressed(clone!(@weak self as row => move |_,_,_,_| {
|
||||
row.open_uri();
|
||||
}));
|
||||
|
||||
self.add_controller(&gesture);
|
||||
|
||||
let image = gtk::Image::from_icon_name(Some(icon_name));
|
||||
self.add_suffix(&image);
|
||||
}
|
||||
|
||||
fn open_uri(&self) {
|
||||
let self_ = imp::UrlRow::from_instance(self);
|
||||
if let Some(ref uri) = *self_.uri.borrow() {
|
||||
gtk::show_uri(gtk::NONE_WINDOW, uri, 0);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_uri(&self, uri: &str) {
|
||||
self.set_subtitle(Some(uri));
|
||||
let self_ = imp::UrlRow::from_instance(self);
|
||||
self_.uri.borrow_mut().replace(uri.to_string());
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue