Skip to content

Commit e548efc

Browse files
author
yggverse
committed
implement proxy settings dialog (rules tab)
1 parent b548fb1 commit e548efc

12 files changed

Lines changed: 660 additions & 12 deletions

File tree

src/app/browser.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
mod about;
22
mod action;
33
mod database;
4+
mod proxy;
45
mod widget;
56
pub mod window;
67

78
use about::About;
89
use action::Action;
10+
use proxy::Proxy;
911
use widget::Widget;
1012
use window::Window;
1113

1214
use crate::Profile;
13-
use adw::{AboutDialog, Application, prelude::AdwDialogExt};
15+
use adw::{AboutDialog, Application, PreferencesDialog, prelude::AdwDialogExt};
1416
use anyhow::Result;
1517
use gtk::{
1618
FileLauncher,
@@ -91,6 +93,12 @@ impl Browser {
9193
}
9294
});
9395

96+
action.proxy.connect_activate({
97+
let profile = profile.clone();
98+
let window = window.clone();
99+
move || PreferencesDialog::proxy(&profile).present(Some(&window.g_box))
100+
});
101+
94102
// Return new activated `Self`
95103
Self {
96104
action,

src/app/browser/action.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ mod about;
22
mod close;
33
mod debug;
44
mod profile;
5+
mod proxy;
56

67
use about::About;
78
use close::Close;
89
use debug::Debug;
910
use profile::Profile;
11+
use proxy::Proxy;
1012

1113
use gtk::{
1214
gio::SimpleActionGroup,
@@ -22,6 +24,7 @@ pub struct Action {
2224
pub close: Rc<Close>,
2325
pub debug: Rc<Debug>,
2426
pub profile: Rc<Profile>,
27+
pub proxy: Rc<Proxy>,
2528
// Group
2629
pub id: GString,
2730
pub simple_action_group: SimpleActionGroup,
@@ -43,6 +46,7 @@ impl Action {
4346
let close = Rc::new(Close::new());
4447
let debug = Rc::new(Debug::new());
4548
let profile = Rc::new(Profile::new());
49+
let proxy = Rc::new(Proxy::new());
4650

4751
// Generate unique group ID
4852
let id = uuid_string_random();
@@ -55,13 +59,15 @@ impl Action {
5559
simple_action_group.add_action(&close.simple_action);
5660
simple_action_group.add_action(&debug.simple_action);
5761
simple_action_group.add_action(&profile.simple_action);
62+
simple_action_group.add_action(&proxy.simple_action);
5863

5964
// Done
6065
Self {
6166
about,
6267
close,
6368
debug,
6469
profile,
70+
proxy,
6571
id,
6672
simple_action_group,
6773
}

src/app/browser/action/proxy.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use gtk::{gio::SimpleAction, glib::uuid_string_random};
2+
3+
/// [SimpleAction](https://docs.gtk.org/gio/class.SimpleAction.html) wrapper for `Profile` action of `Browser` group
4+
pub struct Proxy {
5+
pub simple_action: SimpleAction,
6+
}
7+
8+
impl Default for Proxy {
9+
fn default() -> Self {
10+
Self::new()
11+
}
12+
}
13+
14+
impl Proxy {
15+
// Constructors
16+
17+
/// Create new `Self`
18+
pub fn new() -> Self {
19+
Self {
20+
simple_action: SimpleAction::new(&uuid_string_random(), None),
21+
}
22+
}
23+
24+
// Events
25+
26+
/// Define callback function for
27+
/// [SimpleAction::activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal
28+
pub fn connect_activate(&self, callback: impl Fn() + 'static) {
29+
self.simple_action.connect_activate(move |_, _| callback());
30+
}
31+
}

src/app/browser/proxy.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//! Proxy settings dialog
2+
3+
mod rules;
4+
5+
use super::Profile;
6+
use adw::{
7+
PreferencesGroup, PreferencesPage,
8+
prelude::{AdwDialogExt, PreferencesDialogExt, PreferencesGroupExt, PreferencesPageExt},
9+
};
10+
use rules::Rules;
11+
use std::rc::Rc;
12+
13+
pub trait Proxy {
14+
fn proxy(profile: &Rc<Profile>) -> Self;
15+
}
16+
17+
impl Proxy for adw::PreferencesDialog {
18+
fn proxy(profile: &Rc<Profile>) -> Self {
19+
// Init components
20+
let rules = Rules::build(profile);
21+
22+
// Init widget
23+
let d = adw::PreferencesDialog::builder()
24+
.search_enabled(true)
25+
.title("Proxy")
26+
.build();
27+
28+
d.add(&{
29+
let p = PreferencesPage::builder()
30+
.title("Rules")
31+
.icon_name("system-run-symbolic")
32+
.build();
33+
p.add(&{
34+
let g = PreferencesGroup::new();
35+
g.add(&rules.widget);
36+
g
37+
});
38+
/* @TODO URL entry p.add(&{
39+
let g = PreferencesGroup::builder().title("Test").build();
40+
//g.add(&Box::rules(profile));
41+
g
42+
});*/
43+
p
44+
});
45+
46+
d.add(
47+
&PreferencesPage::builder()
48+
.title("Exceptions")
49+
.icon_name("action-unavailable-symbolic")
50+
.build(),
51+
);
52+
53+
d.add(
54+
&PreferencesPage::builder()
55+
.title("Interface")
56+
.icon_name("preferences-desktop-display-symbolic")
57+
.build(),
58+
);
59+
60+
d.connect_closed({
61+
let profile = profile.clone();
62+
move |_| {
63+
profile.proxy.clear();
64+
for rule in rules.take() {
65+
if rule.validate() {
66+
profile.proxy.add_rule(
67+
rule.id,
68+
rule.is_enabled(),
69+
rule.priority(),
70+
rule.request().to_string(),
71+
rule.url().to_string(),
72+
rule.time,
73+
)
74+
}
75+
}
76+
}
77+
});
78+
d
79+
}
80+
}

src/app/browser/proxy/rules.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
mod rule;
2+
3+
use std::{cell::RefCell, collections::HashMap, rc::Rc};
4+
5+
use super::Profile;
6+
use gtk::{
7+
Box,
8+
glib::{GString, uuid_string_random},
9+
prelude::BoxExt,
10+
};
11+
use rule::Rule;
12+
13+
pub struct Rules {
14+
pub widget: Box,
15+
rules: Rc<RefCell<HashMap<GString, Rule>>>,
16+
}
17+
18+
impl Rules {
19+
pub fn build(profile: &Rc<Profile>) -> Self {
20+
let config = profile.proxy.rules();
21+
22+
let rules: Rc<RefCell<HashMap<GString, Rule>>> =
23+
Rc::new(RefCell::new(HashMap::with_capacity(config.len())));
24+
25+
let form = Box::builder()
26+
.orientation(gtk::Orientation::Vertical)
27+
.spacing(8)
28+
.build();
29+
30+
{
31+
let mut r = rules.borrow_mut();
32+
33+
for proxy in config {
34+
let key = uuid_string_random();
35+
let rule = Rule::build(
36+
proxy.id,
37+
Some(&proxy.time),
38+
Some(&proxy.request),
39+
Some(&proxy.url),
40+
Some(proxy.priority),
41+
proxy.is_enabled,
42+
{
43+
let rules = rules.clone();
44+
let key = key.clone();
45+
let form = form.clone();
46+
move || form.remove(&rules.borrow_mut().remove(&key).unwrap().widget)
47+
},
48+
);
49+
rule.validate();
50+
form.append(&rule.widget);
51+
assert!(r.insert(key, rule).is_none())
52+
}
53+
}
54+
55+
let add = {
56+
let b = Box::builder()
57+
.orientation(gtk::Orientation::Vertical)
58+
.spacing(8)
59+
.build();
60+
61+
b.append(&rule::new({
62+
let rules = rules.clone();
63+
let form = form.clone();
64+
move || {
65+
let key = uuid_string_random();
66+
let rule = Rule::build(None, None, None, None, None, false, {
67+
let rules = rules.clone();
68+
let key = key.clone();
69+
let form = form.clone();
70+
move || form.remove(&rules.borrow_mut().remove(&key).unwrap().widget)
71+
});
72+
form.append(&rule.widget);
73+
assert!(rules.borrow_mut().insert(key, rule).is_none())
74+
}
75+
}));
76+
b
77+
};
78+
79+
let widget = Box::builder()
80+
.orientation(gtk::Orientation::Vertical)
81+
.spacing(8)
82+
.build();
83+
84+
widget.append(&form);
85+
widget.append(&add);
86+
87+
Self { rules, widget }
88+
}
89+
90+
pub fn take(&self) -> Vec<Rule> {
91+
self.rules.take().into_values().collect()
92+
}
93+
}

0 commit comments

Comments
 (0)