mirror of
https://github.com/Xetibo/ReSet.git
synced 2025-04-17 10:18:32 +02:00
chore: snake_case all but UI templates
This commit is contained in:
parent
9f0ca6e8bf
commit
391182607d
|
@ -10,14 +10,14 @@ use glib::{clone, Cast};
|
||||||
use gtk::{gio, StringList, StringObject};
|
use gtk::{gio, StringList, StringObject};
|
||||||
use ReSet_Lib::audio::audio::Card;
|
use ReSet_Lib::audio::audio::Card;
|
||||||
|
|
||||||
use components::utils::createDropdownLabelFactory;
|
use components::utils::create_dropdown_label_factory;
|
||||||
|
|
||||||
use crate::components;
|
use crate::components;
|
||||||
|
|
||||||
use super::cardEntryImpl;
|
use super::card_entry_impl;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct CardEntry(ObjectSubclass<cardEntryImpl::CardEntry>)
|
pub struct CardEntry(ObjectSubclass<card_entry_impl::CardEntry>)
|
||||||
@extends adw::ComboRow, gtk::Widget,
|
@extends adw::ComboRow, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable, adw::PreferencesRow;
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable, adw::PreferencesRow;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ impl CardEntry {
|
||||||
let entry: CardEntry = Object::builder().build();
|
let entry: CardEntry = Object::builder().build();
|
||||||
{
|
{
|
||||||
let imp = entry.imp();
|
let imp = entry.imp();
|
||||||
let mut map = imp.resetCardMap.borrow_mut();
|
let mut map = imp.reset_card_map.borrow_mut();
|
||||||
entry.set_title(&card.name);
|
entry.set_title(&card.name);
|
||||||
let mut index: u32 = 0;
|
let mut index: u32 = 0;
|
||||||
let list = StringList::new(&[]);
|
let list = StringList::new(&[]);
|
||||||
|
@ -52,11 +52,11 @@ impl CardEntry {
|
||||||
let selected = selected.unwrap();
|
let selected = selected.unwrap();
|
||||||
let selected = selected.downcast_ref::<StringObject>().unwrap();
|
let selected = selected.downcast_ref::<StringObject>().unwrap();
|
||||||
let selected = selected.string().to_string();
|
let selected = selected.string().to_string();
|
||||||
let map = imp.resetCardMap.borrow();
|
let map = imp.reset_card_map.borrow();
|
||||||
let (device_index, profile_name) = map.get(&selected).unwrap();
|
let (device_index, profile_name) = map.get(&selected).unwrap();
|
||||||
set_card_profile_of_device(*device_index, profile_name.clone());
|
set_card_profile_of_device(*device_index, profile_name.clone());
|
||||||
}));
|
}));
|
||||||
entry.set_factory(Some(&createDropdownLabelFactory()));
|
entry.set_factory(Some(&create_dropdown_label_factory()));
|
||||||
}
|
}
|
||||||
entry
|
entry
|
||||||
}
|
}
|
|
@ -8,22 +8,21 @@ use std::collections::HashMap;
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, CompositeTemplate};
|
use gtk::{glib, CompositeTemplate};
|
||||||
|
|
||||||
use super::cardEntry;
|
use super::card_entry;
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
#[derive(Default, CompositeTemplate)]
|
#[derive(Default, CompositeTemplate)]
|
||||||
#[template(resource = "/org/Xetibo/ReSet/resetCardEntry.ui")]
|
#[template(resource = "/org/Xetibo/ReSet/resetCardEntry.ui")]
|
||||||
pub struct CardEntry {
|
pub struct CardEntry {
|
||||||
// first string is the alias name, the first return string is the index of the adapter and the
|
// first string is the alias name, the first return string is the index of the adapter and the
|
||||||
// second the name of the profile
|
// second the name of the profile
|
||||||
pub resetCardMap: RefCell<HashMap<String, (u32, String)>>,
|
pub reset_card_map: RefCell<HashMap<String, (u32, String)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
impl ObjectSubclass for CardEntry {
|
impl ObjectSubclass for CardEntry {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetCardEntry";
|
const NAME: &'static str = "resetCardEntry";
|
||||||
type Type = cardEntry::CardEntry;
|
type Type = card_entry::CardEntry;
|
||||||
type ParentType = ComboRow;
|
type ParentType = ComboRow;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
|
@ -1,11 +1,11 @@
|
||||||
use crate::components::base::listEntryImpl;
|
use crate::components::base::list_entry_impl;
|
||||||
use adw::glib;
|
use adw::glib;
|
||||||
use adw::glib::{IsA, Object};
|
use adw::glib::{IsA, Object};
|
||||||
use gtk::prelude::ListBoxRowExt;
|
use gtk::prelude::ListBoxRowExt;
|
||||||
use gtk::Widget;
|
use gtk::Widget;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct ListEntry(ObjectSubclass<listEntryImpl::ListEntry>)
|
pub struct ListEntry(ObjectSubclass<list_entry_impl::ListEntry>)
|
||||||
@extends gtk::ListBoxRow, gtk::Widget,
|
@extends gtk::ListBoxRow, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Actionable;
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Actionable;
|
||||||
}
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
use crate::components::base::listEntry;
|
use crate::components::base::list_entry;
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, CompositeTemplate};
|
use gtk::{glib, CompositeTemplate};
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
#[derive(Default, CompositeTemplate)]
|
#[derive(Default, CompositeTemplate)]
|
||||||
#[template(resource = "/org/Xetibo/ReSet/resetListBoxRow.ui")]
|
#[template(resource = "/org/Xetibo/ReSet/resetListBoxRow.ui")]
|
||||||
pub struct ListEntry {}
|
pub struct ListEntry {}
|
||||||
|
@ -11,7 +10,7 @@ pub struct ListEntry {}
|
||||||
impl ObjectSubclass for ListEntry {
|
impl ObjectSubclass for ListEntry {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetListBoxRow";
|
const NAME: &'static str = "resetListBoxRow";
|
||||||
type Type = listEntry::ListEntry;
|
type Type = list_entry::ListEntry;
|
||||||
type ParentType = gtk::ListBoxRow;
|
type ParentType = gtk::ListBoxRow;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
|
@ -1,9 +1,9 @@
|
||||||
pub mod cardEntry;
|
pub mod card_entry;
|
||||||
pub mod cardEntryImpl;
|
pub mod card_entry_impl;
|
||||||
pub mod listEntry;
|
pub mod list_entry;
|
||||||
pub mod listEntryImpl;
|
pub mod list_entry_impl;
|
||||||
pub mod popup;
|
pub mod popup;
|
||||||
pub mod popupImpl;
|
pub mod popup_impl;
|
||||||
pub mod settingBox;
|
pub mod setting_box;
|
||||||
pub mod settingBoxImpl;
|
pub mod setting_box_impl;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
|
@ -2,10 +2,10 @@ use adw::glib;
|
||||||
use adw::glib::Object;
|
use adw::glib::Object;
|
||||||
use gtk::{gdk, Editable, Popover};
|
use gtk::{gdk, Editable, Popover};
|
||||||
|
|
||||||
use super::popupImpl;
|
use super::popup_impl;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct Popup(ObjectSubclass<popupImpl::Popup>)
|
pub struct Popup(ObjectSubclass<popup_impl::Popup>)
|
||||||
@extends Popover, gtk::Widget,
|
@extends Popover, gtk::Widget,
|
||||||
@implements Editable,gdk::Popup, gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
@implements Editable,gdk::Popup, gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub struct Popup {
|
||||||
pub resetPopupEntry: TemplateChild<PasswordEntry>,
|
pub resetPopupEntry: TemplateChild<PasswordEntry>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub resetPopupButton: TemplateChild<Button>,
|
pub resetPopupButton: TemplateChild<Button>,
|
||||||
pub resetPopupText: Arc<RefCell<PasswordEntryBuffer>>,
|
pub reset_popup_text: Arc<RefCell<PasswordEntryBuffer>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for Popup {}
|
unsafe impl Send for Popup {}
|
|
@ -1,11 +1,11 @@
|
||||||
use crate::components::base::settingBoxImpl;
|
use crate::components::base::setting_box_impl;
|
||||||
use adw::glib;
|
use adw::glib;
|
||||||
use adw::glib::{IsA, Object};
|
use adw::glib::{IsA, Object};
|
||||||
use gtk::prelude::BoxExt;
|
use gtk::prelude::BoxExt;
|
||||||
use gtk::Widget;
|
use gtk::Widget;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct SettingBox(ObjectSubclass<settingBoxImpl::SettingBox>)
|
pub struct SettingBox(ObjectSubclass<setting_box_impl::SettingBox>)
|
||||||
@extends gtk::Box, gtk::Widget,
|
@extends gtk::Box, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
|
||||||
}
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
use crate::components::base::settingBox;
|
use crate::components::base::setting_box;
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, CompositeTemplate};
|
use gtk::{glib, CompositeTemplate};
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
#[derive(Default, CompositeTemplate)]
|
#[derive(Default, CompositeTemplate)]
|
||||||
#[template(resource = "/org/Xetibo/ReSet/resetSettingBox.ui")]
|
#[template(resource = "/org/Xetibo/ReSet/resetSettingBox.ui")]
|
||||||
pub struct SettingBox {}
|
pub struct SettingBox {}
|
||||||
|
@ -11,7 +10,7 @@ pub struct SettingBox {}
|
||||||
impl ObjectSubclass for SettingBox {
|
impl ObjectSubclass for SettingBox {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetSettingBox";
|
const NAME: &'static str = "resetSettingBox";
|
||||||
type Type = settingBox::SettingBox;
|
type Type = setting_box::SettingBox;
|
||||||
type ParentType = gtk::Box;
|
type ParentType = gtk::Box;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
|
@ -19,8 +19,8 @@ use ReSet_Lib::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::components::{
|
use crate::components::{
|
||||||
input::sourceBox::{start_input_box_listener, SourceBox},
|
input::source_box::{start_input_box_listener, SourceBox},
|
||||||
output::sinkBox::{start_output_box_listener, SinkBox},
|
output::sink_box::{start_output_box_listener, SinkBox},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
@ -17,13 +17,13 @@ use gtk::{gio, StringObject, Widget};
|
||||||
use ReSet_Lib::bluetooth::bluetooth::{BluetoothAdapter, BluetoothDevice};
|
use ReSet_Lib::bluetooth::bluetooth::{BluetoothAdapter, BluetoothDevice};
|
||||||
use ReSet_Lib::signals::{BluetoothDeviceAdded, BluetoothDeviceChanged, BluetoothDeviceRemoved};
|
use ReSet_Lib::signals::{BluetoothDeviceAdded, BluetoothDeviceChanged, BluetoothDeviceRemoved};
|
||||||
|
|
||||||
use crate::components::base::listEntry::ListEntry;
|
use crate::components::base::list_entry::ListEntry;
|
||||||
use crate::components::base::utils::Listeners;
|
use crate::components::base::utils::Listeners;
|
||||||
use crate::components::bluetooth::bluetoothBoxImpl;
|
use crate::components::bluetooth::bluetooth_box_impl;
|
||||||
use crate::components::bluetooth::bluetoothEntry::BluetoothEntry;
|
use crate::components::bluetooth::bluetooth_entry::BluetoothEntry;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct BluetoothBox(ObjectSubclass<bluetoothBoxImpl::BluetoothBox>)
|
pub struct BluetoothBox(ObjectSubclass<bluetooth_box_impl::BluetoothBox>)
|
||||||
@extends gtk::Box, gtk::Widget,
|
@extends gtk::Box, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||||
}
|
}
|
||||||
|
@ -34,13 +34,11 @@ unsafe impl Sync for BluetoothBox {}
|
||||||
impl BluetoothBox {
|
impl BluetoothBox {
|
||||||
pub fn new(listeners: Arc<Listeners>) -> Arc<Self> {
|
pub fn new(listeners: Arc<Listeners>) -> Arc<Self> {
|
||||||
let obj: Arc<Self> = Arc::new(Object::builder().build());
|
let obj: Arc<Self> = Arc::new(Object::builder().build());
|
||||||
setupCallbacks(listeners, obj)
|
setup_callbacks(listeners, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setupCallbacks(&self) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setupCallbacks(
|
fn setup_callbacks(
|
||||||
listeners: Arc<Listeners>,
|
listeners: Arc<Listeners>,
|
||||||
bluetooth_box: Arc<BluetoothBox>,
|
bluetooth_box: Arc<BluetoothBox>,
|
||||||
) -> Arc<BluetoothBox> {
|
) -> Arc<BluetoothBox> {
|
||||||
|
@ -58,21 +56,28 @@ fn setupCallbacks(
|
||||||
imp.resetBluetoothSwitch.connect_state_set(move |_, state| {
|
imp.resetBluetoothSwitch.connect_state_set(move |_, state| {
|
||||||
if !state {
|
if !state {
|
||||||
let imp = bluetooth_box_ref.imp();
|
let imp = bluetooth_box_ref.imp();
|
||||||
for x in imp.resetBluetoothConnectedDevices.observe_children().iter::<Object>() {
|
for x in imp
|
||||||
if let Ok(entry) = x { // todo test this
|
.resetBluetoothConnectedDevices
|
||||||
if let Some(item) = entry.downcast_ref::<Widget>() {
|
.observe_children()
|
||||||
imp.resetBluetoothAvailableDevices.remove(item);
|
.iter::<Object>()
|
||||||
}
|
.flatten()
|
||||||
|
{
|
||||||
|
// todo test this
|
||||||
|
if let Some(item) = x.downcast_ref::<Widget>() {
|
||||||
|
imp.resetBluetoothAvailableDevices.remove(item);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
listeners.bluetooth_listener.store(false, Ordering::SeqCst);
|
listeners.bluetooth_listener.store(false, Ordering::SeqCst);
|
||||||
set_adapter_enabled(
|
set_adapter_enabled(
|
||||||
imp.resetCurrentBluetoothAdapter.borrow().path.clone(),
|
imp.reset_current_bluetooth_adapter.borrow().path.clone(),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let imp = bluetooth_box_ref.imp();
|
let imp = bluetooth_box_ref.imp();
|
||||||
set_adapter_enabled(imp.resetCurrentBluetoothAdapter.borrow().path.clone(), true);
|
set_adapter_enabled(
|
||||||
|
imp.reset_current_bluetooth_adapter.borrow().path.clone(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
start_bluetooth_listener(listeners.clone(), bluetooth_box_ref.clone());
|
start_bluetooth_listener(listeners.clone(), bluetooth_box_ref.clone());
|
||||||
}
|
}
|
||||||
glib::Propagation::Proceed
|
glib::Propagation::Proceed
|
||||||
|
@ -87,10 +92,10 @@ pub fn populate_conntected_bluetooth_devices(bluetooth_box: Arc<BluetoothBox>) {
|
||||||
let adapters = get_bluetooth_adapters();
|
let adapters = get_bluetooth_adapters();
|
||||||
{
|
{
|
||||||
let imp = bluetooth_box.imp();
|
let imp = bluetooth_box.imp();
|
||||||
let list = imp.resetModelList.write().unwrap();
|
let list = imp.reset_model_list.write().unwrap();
|
||||||
let mut model_index = imp.resetModelIndex.write().unwrap();
|
let mut model_index = imp.reset_model_index.write().unwrap();
|
||||||
let mut map = imp.resetBluetoothAdapters.write().unwrap();
|
let mut map = imp.reset_bluetooth_adapters.write().unwrap();
|
||||||
imp.resetCurrentBluetoothAdapter
|
imp.reset_current_bluetooth_adapter
|
||||||
.replace(adapters.last().unwrap().clone());
|
.replace(adapters.last().unwrap().clone());
|
||||||
for (index, adapter) in adapters.into_iter().enumerate() {
|
for (index, adapter) in adapters.into_iter().enumerate() {
|
||||||
list.append(&adapter.alias);
|
list.append(&adapter.alias);
|
||||||
|
@ -102,10 +107,10 @@ pub fn populate_conntected_bluetooth_devices(bluetooth_box: Arc<BluetoothBox>) {
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let imp = ref_box.imp();
|
let imp = ref_box.imp();
|
||||||
|
|
||||||
let list = imp.resetModelList.read().unwrap();
|
let list = imp.reset_model_list.read().unwrap();
|
||||||
imp.resetBluetoothAdapter.set_model(Some(&*list));
|
imp.resetBluetoothAdapter.set_model(Some(&*list));
|
||||||
let map = imp.resetBluetoothAdapters.read().unwrap();
|
let map = imp.reset_bluetooth_adapters.read().unwrap();
|
||||||
let device = imp.resetCurrentBluetoothAdapter.borrow();
|
let device = imp.reset_current_bluetooth_adapter.borrow();
|
||||||
if let Some(index) = map.get(&device.alias) {
|
if let Some(index) = map.get(&device.alias) {
|
||||||
imp.resetBluetoothAdapter.set_selected(index.1);
|
imp.resetBluetoothAdapter.set_selected(index.1);
|
||||||
}
|
}
|
||||||
|
@ -119,7 +124,7 @@ pub fn populate_conntected_bluetooth_devices(bluetooth_box: Arc<BluetoothBox>) {
|
||||||
let selected = selected.downcast_ref::<StringObject>().unwrap();
|
let selected = selected.downcast_ref::<StringObject>().unwrap();
|
||||||
let selected = selected.string().to_string();
|
let selected = selected.string().to_string();
|
||||||
|
|
||||||
let device = imp.resetBluetoothAdapters.read().unwrap();
|
let device = imp.reset_bluetooth_adapters.read().unwrap();
|
||||||
let device = device.get(&selected);
|
let device = device.get(&selected);
|
||||||
if device.is_none() {
|
if device.is_none() {
|
||||||
return;
|
return;
|
||||||
|
@ -133,7 +138,7 @@ pub fn populate_conntected_bluetooth_devices(bluetooth_box: Arc<BluetoothBox>) {
|
||||||
let connected = device.connected;
|
let connected = device.connected;
|
||||||
let bluetooth_entry = Arc::new(BluetoothEntry::new(&device));
|
let bluetooth_entry = Arc::new(BluetoothEntry::new(&device));
|
||||||
let entry = Arc::new(ListEntry::new(&*bluetooth_entry));
|
let entry = Arc::new(ListEntry::new(&*bluetooth_entry));
|
||||||
imp.availableDevices
|
imp.available_devices
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.insert(path, (bluetooth_entry.clone(), entry.clone(), device));
|
.insert(path, (bluetooth_entry.clone(), entry.clone(), device));
|
||||||
if connected {
|
if connected {
|
||||||
|
@ -197,7 +202,7 @@ pub fn start_bluetooth_listener(listeners: Arc<Listeners>, bluetooth_box: Arc<Bl
|
||||||
let connected = ir.bluetooth_device.connected;
|
let connected = ir.bluetooth_device.connected;
|
||||||
let bluetooth_entry = Arc::new(BluetoothEntry::new(&ir.bluetooth_device));
|
let bluetooth_entry = Arc::new(BluetoothEntry::new(&ir.bluetooth_device));
|
||||||
let entry = Arc::new(ListEntry::new(&*bluetooth_entry));
|
let entry = Arc::new(ListEntry::new(&*bluetooth_entry));
|
||||||
imp.availableDevices.borrow_mut().insert(
|
imp.available_devices.borrow_mut().insert(
|
||||||
path,
|
path,
|
||||||
(bluetooth_entry.clone(), entry.clone(), ir.bluetooth_device),
|
(bluetooth_entry.clone(), entry.clone(), ir.bluetooth_device),
|
||||||
);
|
);
|
||||||
|
@ -221,7 +226,7 @@ pub fn start_bluetooth_listener(listeners: Arc<Listeners>, bluetooth_box: Arc<Bl
|
||||||
glib::spawn_future(async move {
|
glib::spawn_future(async move {
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let imp = bluetooth_box.imp();
|
let imp = bluetooth_box.imp();
|
||||||
let map = imp.availableDevices.borrow_mut();
|
let map = imp.available_devices.borrow_mut();
|
||||||
if let Some(list_entry) = map.get(&ir.bluetooth_device) {
|
if let Some(list_entry) = map.get(&ir.bluetooth_device) {
|
||||||
imp.resetBluetoothConnectedDevices.remove(&*list_entry.1);
|
imp.resetBluetoothConnectedDevices.remove(&*list_entry.1);
|
||||||
}
|
}
|
||||||
|
@ -240,7 +245,7 @@ pub fn start_bluetooth_listener(listeners: Arc<Listeners>, bluetooth_box: Arc<Bl
|
||||||
glib::spawn_future(async move {
|
glib::spawn_future(async move {
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let imp = bluetooth_box.imp();
|
let imp = bluetooth_box.imp();
|
||||||
let map = imp.availableDevices.borrow_mut();
|
let map = imp.available_devices.borrow_mut();
|
||||||
if let Some(list_entry) = map.get(&ir.bluetooth_device.path) {
|
if let Some(list_entry) = map.get(&ir.bluetooth_device.path) {
|
||||||
if list_entry.2.connected != ir.bluetooth_device.connected {
|
if list_entry.2.connected != ir.bluetooth_device.connected {
|
||||||
if ir.bluetooth_device.connected {
|
if ir.bluetooth_device.connected {
|
||||||
|
@ -279,13 +284,16 @@ pub fn start_bluetooth_listener(listeners: Arc<Listeners>, bluetooth_box: Arc<Bl
|
||||||
glib::spawn_future(async move {
|
glib::spawn_future(async move {
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let imp = loop_box.imp();
|
let imp = loop_box.imp();
|
||||||
for x in imp.resetBluetoothAvailableDevices.observe_children().iter::<Object>() {
|
for x in imp
|
||||||
if let Ok(entry) = x { // todo test this
|
.resetBluetoothAvailableDevices
|
||||||
if let Some(item) = entry.downcast_ref::<Widget>() {
|
.observe_children()
|
||||||
imp.resetBluetoothAvailableDevices.remove(item);
|
.iter::<Object>()
|
||||||
}
|
.flatten()
|
||||||
|
{
|
||||||
|
if let Some(item) = x.downcast_ref::<Widget>() {
|
||||||
|
imp.resetBluetoothAvailableDevices.remove(item);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
println!("stopping bluetooth listener");
|
println!("stopping bluetooth listener");
|
|
@ -1,16 +1,16 @@
|
||||||
use adw::{ActionRow, ComboRow};
|
use adw::{ActionRow, ComboRow};
|
||||||
use dbus::Path;
|
use dbus::Path;
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, CompositeTemplate, ListBox, Switch, Button};
|
use gtk::{glib, Button, CompositeTemplate, Switch};
|
||||||
use gtk::{prelude::*, StringList};
|
use gtk::{prelude::*, StringList};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use ReSet_Lib::bluetooth::bluetooth::{BluetoothAdapter, BluetoothDevice};
|
use ReSet_Lib::bluetooth::bluetooth::{BluetoothAdapter, BluetoothDevice};
|
||||||
|
|
||||||
use crate::components::base::listEntry::ListEntry;
|
use crate::components::base::list_entry::ListEntry;
|
||||||
use crate::components::bluetooth::bluetoothBox;
|
use crate::components::bluetooth::bluetooth_box;
|
||||||
use crate::components::bluetooth::bluetoothEntry::BluetoothEntry;
|
use crate::components::bluetooth::bluetooth_entry::BluetoothEntry;
|
||||||
|
|
||||||
type BluetoothMap =
|
type BluetoothMap =
|
||||||
RefCell<HashMap<Path<'static>, (Arc<BluetoothEntry>, Arc<ListEntry>, BluetoothDevice)>>;
|
RefCell<HashMap<Path<'static>, (Arc<BluetoothEntry>, Arc<ListEntry>, BluetoothDevice)>>;
|
||||||
|
@ -33,19 +33,19 @@ pub struct BluetoothBox {
|
||||||
pub resetVisibility: TemplateChild<ActionRow>,
|
pub resetVisibility: TemplateChild<ActionRow>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub resetBluetoothMainTab: TemplateChild<ListEntry>,
|
pub resetBluetoothMainTab: TemplateChild<ListEntry>,
|
||||||
pub availableDevices: BluetoothMap,
|
pub available_devices: BluetoothMap,
|
||||||
pub connectedDevices: BluetoothMap,
|
pub connected_devices: BluetoothMap,
|
||||||
pub resetBluetoothAdapters: Arc<RwLock<HashMap<String, (BluetoothAdapter, u32)>>>,
|
pub reset_bluetooth_adapters: Arc<RwLock<HashMap<String, (BluetoothAdapter, u32)>>>,
|
||||||
pub resetCurrentBluetoothAdapter: Arc<RefCell<BluetoothAdapter>>,
|
pub reset_current_bluetooth_adapter: Arc<RefCell<BluetoothAdapter>>,
|
||||||
pub resetModelList: Arc<RwLock<StringList>>,
|
pub reset_model_list: Arc<RwLock<StringList>>,
|
||||||
pub resetModelIndex: Arc<RwLock<u32>>,
|
pub reset_model_index: Arc<RwLock<u32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
impl ObjectSubclass for BluetoothBox {
|
impl ObjectSubclass for BluetoothBox {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetBluetooth";
|
const NAME: &'static str = "resetBluetooth";
|
||||||
type Type = bluetoothBox::BluetoothBox;
|
type Type = bluetooth_box::BluetoothBox;
|
||||||
type ParentType = gtk::Box;
|
type ParentType = gtk::Box;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
||||||
|
@ -62,8 +62,6 @@ impl ObjectSubclass for BluetoothBox {
|
||||||
impl ObjectImpl for BluetoothBox {
|
impl ObjectImpl for BluetoothBox {
|
||||||
fn constructed(&self) {
|
fn constructed(&self) {
|
||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
let obj = self.obj();
|
|
||||||
obj.setupCallbacks();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::components::bluetooth::bluetoothEntryImpl;
|
use crate::components::bluetooth::bluetooth_entry_impl;
|
||||||
use adw::glib;
|
use adw::glib;
|
||||||
use adw::glib::Object;
|
use adw::glib::Object;
|
||||||
use adw::subclass::prelude::ObjectSubclassIsExt;
|
use adw::subclass::prelude::ObjectSubclassIsExt;
|
||||||
|
@ -12,7 +12,7 @@ use gtk::{gio, GestureClick};
|
||||||
use ReSet_Lib::bluetooth::bluetooth::BluetoothDevice;
|
use ReSet_Lib::bluetooth::bluetooth::BluetoothDevice;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct BluetoothEntry(ObjectSubclass<bluetoothEntryImpl::BluetoothEntry>)
|
pub struct BluetoothEntry(ObjectSubclass<bluetooth_entry_impl::BluetoothEntry>)
|
||||||
@extends gtk::Box, gtk::Widget,
|
@extends gtk::Box, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::Actionable, gtk::ConstraintTarget;
|
@implements gtk::Accessible, gtk::Buildable, gtk::Actionable, gtk::ConstraintTarget;
|
||||||
}
|
}
|
||||||
|
@ -23,28 +23,28 @@ unsafe impl Sync for BluetoothEntry {}
|
||||||
impl BluetoothEntry {
|
impl BluetoothEntry {
|
||||||
pub fn new(device: &BluetoothDevice) -> Self {
|
pub fn new(device: &BluetoothDevice) -> Self {
|
||||||
let entry: BluetoothEntry = Object::builder().build();
|
let entry: BluetoothEntry = Object::builder().build();
|
||||||
let entryImp = entry.imp();
|
let entry_imp = entry.imp();
|
||||||
entryImp.resetBluetoothLabel.get().set_text(&device.alias);
|
entry_imp.resetBluetoothLabel.get().set_text(&device.alias);
|
||||||
entryImp
|
entry_imp
|
||||||
.resetBluetoothAddress
|
.resetBluetoothAddress
|
||||||
.get()
|
.get()
|
||||||
.set_text(&device.address);
|
.set_text(&device.address);
|
||||||
if device.icon.is_empty() {
|
if device.icon.is_empty() {
|
||||||
entryImp
|
entry_imp
|
||||||
.resetBluetoothDeviceType
|
.resetBluetoothDeviceType
|
||||||
.set_icon_name(Some("dialog-question-symbolic"));
|
.set_icon_name(Some("dialog-question-symbolic"));
|
||||||
} else {
|
} else {
|
||||||
entryImp
|
entry_imp
|
||||||
.resetBluetoothDeviceType
|
.resetBluetoothDeviceType
|
||||||
.set_icon_name(Some(&device.icon));
|
.set_icon_name(Some(&device.icon));
|
||||||
}
|
}
|
||||||
if device.paired {
|
if device.paired {
|
||||||
entryImp.resetBluetoothButton.set_sensitive(true);
|
entry_imp.resetBluetoothButton.set_sensitive(true);
|
||||||
} else {
|
} else {
|
||||||
entryImp.resetBluetoothButton.set_sensitive(false);
|
entry_imp.resetBluetoothButton.set_sensitive(false);
|
||||||
}
|
}
|
||||||
let path = Arc::new(device.path.clone());
|
let path = Arc::new(device.path.clone());
|
||||||
entryImp.resetBluetoothButton.connect_clicked(move |_| {
|
entry_imp.resetBluetoothButton.connect_clicked(move |_| {
|
||||||
remove_device_pairing((*path).clone());
|
remove_device_pairing((*path).clone());
|
||||||
});
|
});
|
||||||
let gesture = GestureClick::new();
|
let gesture = GestureClick::new();
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::components::bluetooth::bluetoothEntry;
|
use crate::components::bluetooth::bluetooth_entry;
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, Button, CompositeTemplate, Image, Label};
|
use gtk::{glib, Button, CompositeTemplate, Image, Label};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
@ -15,14 +15,14 @@ pub struct BluetoothEntry {
|
||||||
pub resetBluetoothAddress: TemplateChild<Label>,
|
pub resetBluetoothAddress: TemplateChild<Label>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub resetBluetoothButton: TemplateChild<Button>,
|
pub resetBluetoothButton: TemplateChild<Button>,
|
||||||
pub deviceName: RefCell<String>,
|
pub device_name: RefCell<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
impl ObjectSubclass for BluetoothEntry {
|
impl ObjectSubclass for BluetoothEntry {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetBluetoothEntry";
|
const NAME: &'static str = "resetBluetoothEntry";
|
||||||
type Type = bluetoothEntry::BluetoothEntry;
|
type Type = bluetooth_entry::BluetoothEntry;
|
||||||
type ParentType = gtk::Box;
|
type ParentType = gtk::Box;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
|
@ -1,5 +1,4 @@
|
||||||
#![allow(non_snake_case)]
|
pub mod bluetooth_box;
|
||||||
pub mod bluetoothBox;
|
pub mod bluetooth_box_impl;
|
||||||
pub mod bluetoothBoxImpl;
|
pub mod bluetooth_entry;
|
||||||
pub mod bluetoothEntry;
|
pub mod bluetooth_entry_impl;
|
||||||
pub mod bluetoothEntryImpl;
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#![allow(non_snake_case)]
|
pub mod output_stream_entry;
|
||||||
pub mod outputStreamEntry;
|
pub mod output_stream_entry_impl;
|
||||||
pub mod outputStreamEntryImpl;
|
pub mod source_box;
|
||||||
pub mod sourceBox;
|
pub mod source_box_impl;
|
||||||
pub mod sourceBoxImpl;
|
pub mod source_entry;
|
||||||
pub mod sourceEntry;
|
pub mod source_entry_impl;
|
||||||
pub mod sourceEntryImpl;
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
use crate::components::utils::{createDropdownLabelFactory, setComboRowEllipsis};
|
use crate::components::utils::{create_dropdown_label_factory, set_combo_row_ellipsis};
|
||||||
use adw::glib;
|
use adw::glib;
|
||||||
use adw::glib::Object;
|
use adw::glib::Object;
|
||||||
use adw::prelude::{ButtonExt, ComboRowExt, PreferencesRowExt, RangeExt};
|
use adw::prelude::{ButtonExt, ComboRowExt, PreferencesRowExt, RangeExt};
|
||||||
|
@ -12,11 +12,11 @@ use glib::{clone, Cast, Propagation};
|
||||||
use gtk::{gio, StringObject};
|
use gtk::{gio, StringObject};
|
||||||
use ReSet_Lib::audio::audio::OutputStream;
|
use ReSet_Lib::audio::audio::OutputStream;
|
||||||
|
|
||||||
use super::outputStreamEntryImpl;
|
use super::output_stream_entry_impl;
|
||||||
use super::sourceBox::SourceBox;
|
use super::source_box::SourceBox;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct OutputStreamEntry(ObjectSubclass<outputStreamEntryImpl::OutputStreamEntry>)
|
pub struct OutputStreamEntry(ObjectSubclass<output_stream_entry_impl::OutputStreamEntry>)
|
||||||
@extends adw::PreferencesGroup, gtk::Widget,
|
@extends adw::PreferencesGroup, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,8 @@ impl OutputStreamEntry {
|
||||||
let name = stream.application_name.clone() + ": " + stream.name.as_str();
|
let name = stream.application_name.clone() + ": " + stream.name.as_str();
|
||||||
imp.resetSourceSelection.set_title(name.as_str());
|
imp.resetSourceSelection.set_title(name.as_str());
|
||||||
imp.resetSourceSelection
|
imp.resetSourceSelection
|
||||||
.set_factory(Some(&createDropdownLabelFactory()));
|
.set_factory(Some(&create_dropdown_label_factory()));
|
||||||
setComboRowEllipsis(imp.resetSourceSelection.get());
|
set_combo_row_ellipsis(imp.resetSourceSelection.get());
|
||||||
let volume = stream.volume.first().unwrap_or(&0_u32);
|
let volume = stream.volume.first().unwrap_or(&0_u32);
|
||||||
let fraction = (*volume as f64 / 655.36).round();
|
let fraction = (*volume as f64 / 655.36).round();
|
||||||
let percentage = (fraction).to_string() + "%";
|
let percentage = (fraction).to_string() + "%";
|
||||||
|
@ -55,7 +55,7 @@ impl OutputStreamEntry {
|
||||||
let index = stream.index;
|
let index = stream.index;
|
||||||
let channels = stream.channels;
|
let channels = stream.channels;
|
||||||
{
|
{
|
||||||
let mut time = imp.volumeTimeStamp.borrow_mut();
|
let mut time = imp.volume_time_stamp.borrow_mut();
|
||||||
if time.is_some()
|
if time.is_some()
|
||||||
&& time.unwrap().elapsed().unwrap() < Duration::from_millis(50)
|
&& time.unwrap().elapsed().unwrap() < Duration::from_millis(50)
|
||||||
{
|
{
|
||||||
|
@ -68,12 +68,12 @@ impl OutputStreamEntry {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
{
|
{
|
||||||
let list = box_imp.resetModelList.read().unwrap();
|
let list = box_imp.reset_model_list.read().unwrap();
|
||||||
imp.resetSourceSelection.set_model(Some(&*list));
|
imp.resetSourceSelection.set_model(Some(&*list));
|
||||||
let map = box_imp.resetSourceMap.write().unwrap();
|
let map = box_imp.reset_source_map.write().unwrap();
|
||||||
let mut name = box_imp.resetDefaultSource.try_borrow();
|
let mut name = box_imp.reset_default_source.try_borrow();
|
||||||
while name.is_err() {
|
while name.is_err() {
|
||||||
name = box_imp.resetDefaultSource.try_borrow();
|
name = box_imp.reset_default_source.try_borrow();
|
||||||
}
|
}
|
||||||
let name = name.unwrap();
|
let name = name.unwrap();
|
||||||
let name = &name.alias;
|
let name = &name.alias;
|
||||||
|
@ -91,7 +91,7 @@ impl OutputStreamEntry {
|
||||||
let selected = selected.unwrap();
|
let selected = selected.unwrap();
|
||||||
let selected = selected.downcast_ref::<StringObject>().unwrap();
|
let selected = selected.downcast_ref::<StringObject>().unwrap();
|
||||||
let selected = selected.string().to_string();
|
let selected = selected.string().to_string();
|
||||||
let source = box_imp.resetSourceMap.write().unwrap();
|
let source = box_imp.reset_source_map.write().unwrap();
|
||||||
let source = source.get(&selected);
|
let source = source.get(&selected);
|
||||||
if source.is_none() {
|
if source.is_none() {
|
||||||
return;
|
return;
|
|
@ -4,7 +4,7 @@ use std::cell::RefCell;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use crate::components::input::outputStreamEntry;
|
use crate::components::input::output_stream_entry;
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, Button, CompositeTemplate, Label, ProgressBar, Scale};
|
use gtk::{glib, Button, CompositeTemplate, Label, ProgressBar, Scale};
|
||||||
use ReSet_Lib::audio::audio::OutputStream;
|
use ReSet_Lib::audio::audio::OutputStream;
|
||||||
|
@ -24,15 +24,15 @@ pub struct OutputStreamEntry {
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub resetVolumeMeter: TemplateChild<ProgressBar>,
|
pub resetVolumeMeter: TemplateChild<ProgressBar>,
|
||||||
pub stream: Arc<RefCell<OutputStream>>,
|
pub stream: Arc<RefCell<OutputStream>>,
|
||||||
pub associatedSource: Arc<RefCell<(u32, String)>>,
|
pub associated_source: Arc<RefCell<(u32, String)>>,
|
||||||
pub volumeTimeStamp: RefCell<Option<SystemTime>>,
|
pub volume_time_stamp: RefCell<Option<SystemTime>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
impl ObjectSubclass for OutputStreamEntry {
|
impl ObjectSubclass for OutputStreamEntry {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetOutputStreamEntry";
|
const NAME: &'static str = "resetOutputStreamEntry";
|
||||||
type Type = outputStreamEntry::OutputStreamEntry;
|
type Type = output_stream_entry::OutputStreamEntry;
|
||||||
type ParentType = PreferencesGroup;
|
type ParentType = PreferencesGroup;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
|
@ -16,21 +16,21 @@ use gtk::prelude::ActionableExt;
|
||||||
use gtk::{gio, StringObject};
|
use gtk::{gio, StringObject};
|
||||||
use ReSet_Lib::audio::audio::{Card, OutputStream, Source};
|
use ReSet_Lib::audio::audio::{Card, OutputStream, Source};
|
||||||
|
|
||||||
use crate::components::base::cardEntry::CardEntry;
|
use crate::components::base::card_entry::CardEntry;
|
||||||
use crate::components::base::listEntry::ListEntry;
|
use crate::components::base::list_entry::ListEntry;
|
||||||
use crate::components::base::utils::{
|
use crate::components::base::utils::{
|
||||||
OutputStreamAdded, OutputStreamChanged, OutputStreamRemoved, SourceAdded, SourceChanged,
|
OutputStreamAdded, OutputStreamChanged, OutputStreamRemoved, SourceAdded, SourceChanged,
|
||||||
SourceRemoved,
|
SourceRemoved,
|
||||||
};
|
};
|
||||||
use crate::components::input::sourceBoxImpl;
|
use crate::components::input::source_box_impl;
|
||||||
use crate::components::input::sourceEntry::set_source_volume;
|
use crate::components::input::source_entry::set_source_volume;
|
||||||
use crate::components::utils::{createDropdownLabelFactory, setComboRowEllipsis};
|
use crate::components::utils::{create_dropdown_label_factory, set_combo_row_ellipsis};
|
||||||
|
|
||||||
use super::outputStreamEntry::OutputStreamEntry;
|
use super::output_stream_entry::OutputStreamEntry;
|
||||||
use super::sourceEntry::{set_default_source, toggle_source_mute, SourceEntry};
|
use super::source_entry::{set_default_source, toggle_source_mute, SourceEntry};
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct SourceBox(ObjectSubclass<sourceBoxImpl::SourceBox>)
|
pub struct SourceBox(ObjectSubclass<source_box_impl::SourceBox>)
|
||||||
@extends gtk::Box, gtk::Widget,
|
@extends gtk::Box, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||||
}
|
}
|
||||||
|
@ -43,37 +43,37 @@ impl SourceBox {
|
||||||
Object::builder().build()
|
Object::builder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setupCallbacks(&self) {
|
pub fn setup_callbacks(&self) {
|
||||||
let selfImp = self.imp();
|
let self_imp = self.imp();
|
||||||
selfImp.resetSourceRow.set_activatable(true);
|
self_imp.resetSourceRow.set_activatable(true);
|
||||||
selfImp
|
self_imp
|
||||||
.resetSourceRow
|
.resetSourceRow
|
||||||
.set_action_name(Some("navigation.push"));
|
.set_action_name(Some("navigation.push"));
|
||||||
selfImp
|
self_imp
|
||||||
.resetSourceRow
|
.resetSourceRow
|
||||||
.set_action_target_value(Some(&Variant::from("sources")));
|
.set_action_target_value(Some(&Variant::from("sources")));
|
||||||
selfImp.resetCardsRow.set_activatable(true);
|
self_imp.resetCardsRow.set_activatable(true);
|
||||||
selfImp
|
self_imp
|
||||||
.resetCardsRow
|
.resetCardsRow
|
||||||
.set_action_name(Some("navigation.push"));
|
.set_action_name(Some("navigation.push"));
|
||||||
selfImp
|
self_imp
|
||||||
.resetCardsRow
|
.resetCardsRow
|
||||||
.set_action_target_value(Some(&Variant::from("profileConfiguration")));
|
.set_action_target_value(Some(&Variant::from("profileConfiguration")));
|
||||||
|
|
||||||
selfImp.resetOutputStreamButton.set_activatable(true);
|
self_imp.resetOutputStreamButton.set_activatable(true);
|
||||||
selfImp
|
self_imp
|
||||||
.resetOutputStreamButton
|
.resetOutputStreamButton
|
||||||
.set_action_name(Some("navigation.pop"));
|
.set_action_name(Some("navigation.pop"));
|
||||||
|
|
||||||
selfImp.resetInputCardsBackButton.set_activatable(true);
|
self_imp.resetInputCardsBackButton.set_activatable(true);
|
||||||
selfImp
|
self_imp
|
||||||
.resetInputCardsBackButton
|
.resetInputCardsBackButton
|
||||||
.set_action_name(Some("navigation.pop"));
|
.set_action_name(Some("navigation.pop"));
|
||||||
|
|
||||||
selfImp
|
self_imp
|
||||||
.resetSourceDropdown
|
.resetSourceDropdown
|
||||||
.set_factory(Some(&createDropdownLabelFactory()));
|
.set_factory(Some(&create_dropdown_label_factory()));
|
||||||
setComboRowEllipsis(selfImp.resetSourceDropdown.get());
|
set_combo_row_ellipsis(self_imp.resetSourceDropdown.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,9 +88,9 @@ pub fn populate_sources(input_box: Arc<SourceBox>) {
|
||||||
let output_box_imp = input_box.imp();
|
let output_box_imp = input_box.imp();
|
||||||
let sources = get_sources();
|
let sources = get_sources();
|
||||||
{
|
{
|
||||||
let list = output_box_imp.resetModelList.write().unwrap();
|
let list = output_box_imp.reset_model_list.write().unwrap();
|
||||||
let mut map = output_box_imp.resetSourceMap.write().unwrap();
|
let mut map = output_box_imp.reset_source_map.write().unwrap();
|
||||||
let mut model_index = output_box_imp.resetModelIndex.write().unwrap();
|
let mut model_index = output_box_imp.reset_model_index.write().unwrap();
|
||||||
for (i, source) in (0_u32..).zip(sources.iter()) {
|
for (i, source) in (0_u32..).zip(sources.iter()) {
|
||||||
list.append(&source.alias);
|
list.append(&source.alias);
|
||||||
map.insert(source.alias.clone(), (source.index, i, source.name.clone()));
|
map.insert(source.alias.clone(), (source.index, i, source.name.clone()));
|
||||||
|
@ -98,7 +98,7 @@ pub fn populate_sources(input_box: Arc<SourceBox>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output_box_imp
|
output_box_imp
|
||||||
.resetDefaultSource
|
.reset_default_source
|
||||||
.replace(get_default_source());
|
.replace(get_default_source());
|
||||||
|
|
||||||
populate_outputstreams(input_box.clone());
|
populate_outputstreams(input_box.clone());
|
||||||
|
@ -110,7 +110,7 @@ pub fn populate_sources(input_box: Arc<SourceBox>) {
|
||||||
let output_box_ref = input_box.clone();
|
let output_box_ref = input_box.clone();
|
||||||
{
|
{
|
||||||
let output_box_imp = output_box_ref.imp();
|
let output_box_imp = output_box_ref.imp();
|
||||||
let default_sink = output_box_imp.resetDefaultSource.clone();
|
let default_sink = output_box_imp.reset_default_source.clone();
|
||||||
let source = default_sink.borrow();
|
let source = default_sink.borrow();
|
||||||
|
|
||||||
let volume = source.volume.first().unwrap_or(&0_u32);
|
let volume = source.volume.first().unwrap_or(&0_u32);
|
||||||
|
@ -118,17 +118,17 @@ pub fn populate_sources(input_box: Arc<SourceBox>) {
|
||||||
let percentage = (fraction).to_string() + "%";
|
let percentage = (fraction).to_string() + "%";
|
||||||
output_box_imp.resetVolumePercentage.set_text(&percentage);
|
output_box_imp.resetVolumePercentage.set_text(&percentage);
|
||||||
output_box_imp.resetVolumeSlider.set_value(*volume as f64);
|
output_box_imp.resetVolumeSlider.set_value(*volume as f64);
|
||||||
let mut list = output_box_imp.resetSourceList.write().unwrap();
|
let mut list = output_box_imp.reset_source_list.write().unwrap();
|
||||||
for stream in sources {
|
for stream in sources {
|
||||||
let index = source.index;
|
let index = source.index;
|
||||||
let alias = source.alias.clone();
|
let alias = source.alias.clone();
|
||||||
let mut is_default = false;
|
let mut is_default = false;
|
||||||
if output_box_imp.resetDefaultSource.borrow().name == stream.name {
|
if output_box_imp.reset_default_source.borrow().name == stream.name {
|
||||||
is_default = true;
|
is_default = true;
|
||||||
}
|
}
|
||||||
let source_entry = Arc::new(SourceEntry::new(
|
let source_entry = Arc::new(SourceEntry::new(
|
||||||
is_default,
|
is_default,
|
||||||
output_box_imp.resetDefaultCheckButton.clone(),
|
output_box_imp.reset_default_check_button.clone(),
|
||||||
stream,
|
stream,
|
||||||
));
|
));
|
||||||
let source_clone = source_entry.clone();
|
let source_clone = source_entry.clone();
|
||||||
|
@ -137,10 +137,10 @@ pub fn populate_sources(input_box: Arc<SourceBox>) {
|
||||||
list.insert(index, (entry.clone(), source_clone, alias));
|
list.insert(index, (entry.clone(), source_clone, alias));
|
||||||
output_box_imp.resetSources.append(&*entry);
|
output_box_imp.resetSources.append(&*entry);
|
||||||
}
|
}
|
||||||
let list = output_box_imp.resetModelList.read().unwrap();
|
let list = output_box_imp.reset_model_list.read().unwrap();
|
||||||
output_box_imp.resetSourceDropdown.set_model(Some(&*list));
|
output_box_imp.resetSourceDropdown.set_model(Some(&*list));
|
||||||
let map = output_box_imp.resetSourceMap.read().unwrap();
|
let map = output_box_imp.reset_source_map.read().unwrap();
|
||||||
let name = output_box_imp.resetDefaultSource.borrow();
|
let name = output_box_imp.reset_default_source.borrow();
|
||||||
if let Some(index) = map.get(&name.alias) {
|
if let Some(index) = map.get(&name.alias) {
|
||||||
output_box_imp.resetSourceDropdown.set_selected(index.1);
|
output_box_imp.resetSourceDropdown.set_selected(index.1);
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ pub fn populate_sources(input_box: Arc<SourceBox>) {
|
||||||
let selected = selected.downcast_ref::<StringObject>().unwrap();
|
let selected = selected.downcast_ref::<StringObject>().unwrap();
|
||||||
let selected = selected.string().to_string();
|
let selected = selected.string().to_string();
|
||||||
|
|
||||||
let source = output_box_imp.resetSourceMap.read().unwrap();
|
let source = output_box_imp.reset_source_map.read().unwrap();
|
||||||
let source = source.get(&selected);
|
let source = source.get(&selected);
|
||||||
if source.is_none() {
|
if source.is_none() {
|
||||||
return;
|
return;
|
||||||
|
@ -172,11 +172,11 @@ pub fn populate_sources(input_box: Arc<SourceBox>) {
|
||||||
let fraction = (value / 655.36).round();
|
let fraction = (value / 655.36).round();
|
||||||
let percentage = (fraction).to_string() + "%";
|
let percentage = (fraction).to_string() + "%";
|
||||||
imp.resetVolumePercentage.set_text(&percentage);
|
imp.resetVolumePercentage.set_text(&percentage);
|
||||||
let source = imp.resetDefaultSource.borrow();
|
let source = imp.reset_default_source.borrow();
|
||||||
let index = source.index;
|
let index = source.index;
|
||||||
let channels = source.channels;
|
let channels = source.channels;
|
||||||
{
|
{
|
||||||
let mut time = imp.volumeTimeStamp.borrow_mut();
|
let mut time = imp.volume_time_stamp.borrow_mut();
|
||||||
if time.is_some()
|
if time.is_some()
|
||||||
&& time.unwrap().elapsed().unwrap() < Duration::from_millis(50)
|
&& time.unwrap().elapsed().unwrap() < Duration::from_millis(50)
|
||||||
{
|
{
|
||||||
|
@ -193,7 +193,7 @@ pub fn populate_sources(input_box: Arc<SourceBox>) {
|
||||||
.resetSourceMute
|
.resetSourceMute
|
||||||
.connect_clicked(move |_| {
|
.connect_clicked(move |_| {
|
||||||
let imp = output_box_ref_mute.imp();
|
let imp = output_box_ref_mute.imp();
|
||||||
let stream = imp.resetDefaultSource.clone();
|
let stream = imp.reset_default_source.clone();
|
||||||
let mut stream = stream.borrow_mut();
|
let mut stream = stream.borrow_mut();
|
||||||
stream.muted = !stream.muted;
|
stream.muted = !stream.muted;
|
||||||
let muted = stream.muted;
|
let muted = stream.muted;
|
||||||
|
@ -220,7 +220,7 @@ pub fn populate_outputstreams(input_box: Arc<SourceBox>) {
|
||||||
glib::spawn_future(async move {
|
glib::spawn_future(async move {
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let input_box_imp = input_box_ref.imp();
|
let input_box_imp = input_box_ref.imp();
|
||||||
let mut list = input_box_imp.resetOutputStreamList.write().unwrap();
|
let mut list = input_box_imp.reset_output_stream_list.write().unwrap();
|
||||||
for stream in streams {
|
for stream in streams {
|
||||||
let index = stream.index;
|
let index = stream.index;
|
||||||
let input_stream = Arc::new(OutputStreamEntry::new(input_box.clone(), stream));
|
let input_stream = Arc::new(OutputStreamEntry::new(input_box.clone(), stream));
|
||||||
|
@ -355,17 +355,17 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let output_box = source_box.clone();
|
let output_box = source_box.clone();
|
||||||
let output_box_imp = output_box.imp();
|
let output_box_imp = output_box.imp();
|
||||||
let mut list = output_box_imp.resetSourceList.write().unwrap();
|
let mut list = output_box_imp.reset_source_list.write().unwrap();
|
||||||
let source_index = ir.source.index;
|
let source_index = ir.source.index;
|
||||||
let alias = ir.source.alias.clone();
|
let alias = ir.source.alias.clone();
|
||||||
let name = ir.source.name.clone();
|
let name = ir.source.name.clone();
|
||||||
let mut is_default = false;
|
let mut is_default = false;
|
||||||
if output_box_imp.resetDefaultSource.borrow().name == ir.source.name {
|
if output_box_imp.reset_default_source.borrow().name == ir.source.name {
|
||||||
is_default = true;
|
is_default = true;
|
||||||
}
|
}
|
||||||
let source_entry = Arc::new(SourceEntry::new(
|
let source_entry = Arc::new(SourceEntry::new(
|
||||||
is_default,
|
is_default,
|
||||||
output_box_imp.resetDefaultCheckButton.clone(),
|
output_box_imp.reset_default_check_button.clone(),
|
||||||
ir.source,
|
ir.source,
|
||||||
));
|
));
|
||||||
let source_clone = source_entry.clone();
|
let source_clone = source_entry.clone();
|
||||||
|
@ -373,10 +373,10 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
||||||
entry.set_activatable(false);
|
entry.set_activatable(false);
|
||||||
list.insert(source_index, (entry.clone(), source_clone, alias.clone()));
|
list.insert(source_index, (entry.clone(), source_clone, alias.clone()));
|
||||||
output_box_imp.resetSources.append(&*entry);
|
output_box_imp.resetSources.append(&*entry);
|
||||||
let mut map = output_box_imp.resetSourceMap.write().unwrap();
|
let mut map = output_box_imp.reset_source_map.write().unwrap();
|
||||||
let mut index = output_box_imp.resetModelIndex.write().unwrap();
|
let mut index = output_box_imp.reset_model_index.write().unwrap();
|
||||||
output_box_imp
|
output_box_imp
|
||||||
.resetModelList
|
.reset_model_list
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.append(&alias);
|
.append(&alias);
|
||||||
|
@ -398,7 +398,7 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let output_box = source_box.clone();
|
let output_box = source_box.clone();
|
||||||
let output_box_imp = output_box.imp();
|
let output_box_imp = output_box.imp();
|
||||||
let mut list = output_box_imp.resetSourceList.write().unwrap();
|
let mut list = output_box_imp.reset_source_list.write().unwrap();
|
||||||
let entry = list.get(&ir.index);
|
let entry = list.get(&ir.index);
|
||||||
if entry.is_none() {
|
if entry.is_none() {
|
||||||
return;
|
return;
|
||||||
|
@ -409,16 +409,16 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
||||||
if alias.is_none() {
|
if alias.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut map = output_box_imp.resetSourceMap.write().unwrap();
|
let mut map = output_box_imp.reset_source_map.write().unwrap();
|
||||||
let entry_index = map.remove(&alias.unwrap().2);
|
let entry_index = map.remove(&alias.unwrap().2);
|
||||||
if let Some(entry_index) = entry_index {
|
if let Some(entry_index) = entry_index {
|
||||||
output_box_imp
|
output_box_imp
|
||||||
.resetModelList
|
.reset_model_list
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.remove(entry_index.1);
|
.remove(entry_index.1);
|
||||||
}
|
}
|
||||||
let mut index = output_box_imp.resetModelIndex.write().unwrap();
|
let mut index = output_box_imp.reset_model_index.write().unwrap();
|
||||||
if *index != 0 {
|
if *index != 0 {
|
||||||
*index -= 1;
|
*index -= 1;
|
||||||
}
|
}
|
||||||
|
@ -442,7 +442,7 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
||||||
let volume = ir.source.volume.first().unwrap_or(&0_u32);
|
let volume = ir.source.volume.first().unwrap_or(&0_u32);
|
||||||
let fraction = (*volume as f64 / 655.36).round();
|
let fraction = (*volume as f64 / 655.36).round();
|
||||||
let percentage = (fraction).to_string() + "%";
|
let percentage = (fraction).to_string() + "%";
|
||||||
let list = output_box_imp.resetSourceList.read().unwrap();
|
let list = output_box_imp.reset_source_list.read().unwrap();
|
||||||
let entry = list.get(&ir.source.index);
|
let entry = list.get(&ir.source.index);
|
||||||
if entry.is_none() {
|
if entry.is_none() {
|
||||||
return;
|
return;
|
||||||
|
@ -474,7 +474,7 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let output_box = source_box.clone();
|
let output_box = source_box.clone();
|
||||||
let output_box_imp = output_box.imp();
|
let output_box_imp = output_box.imp();
|
||||||
let mut list = output_box_imp.resetOutputStreamList.write().unwrap();
|
let mut list = output_box_imp.reset_output_stream_list.write().unwrap();
|
||||||
let index = ir.stream.index;
|
let index = ir.stream.index;
|
||||||
let output_stream = Arc::new(OutputStreamEntry::new(output_box.clone(), ir.stream));
|
let output_stream = Arc::new(OutputStreamEntry::new(output_box.clone(), ir.stream));
|
||||||
let output_stream_clone = output_stream.clone();
|
let output_stream_clone = output_stream.clone();
|
||||||
|
@ -497,7 +497,7 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
||||||
let imp = output_stream_changed_box.imp();
|
let imp = output_stream_changed_box.imp();
|
||||||
let alias: String;
|
let alias: String;
|
||||||
{
|
{
|
||||||
let source_list = imp.resetSourceList.read().unwrap();
|
let source_list = imp.reset_source_list.read().unwrap();
|
||||||
if let Some(alias_opt) = source_list.get(&ir.stream.source_index) {
|
if let Some(alias_opt) = source_list.get(&ir.stream.source_index) {
|
||||||
alias = alias_opt.2.clone();
|
alias = alias_opt.2.clone();
|
||||||
} else {
|
} else {
|
||||||
|
@ -511,7 +511,7 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
||||||
let output_box_imp = output_box.imp();
|
let output_box_imp = output_box.imp();
|
||||||
let entry: Arc<OutputStreamEntry>;
|
let entry: Arc<OutputStreamEntry>;
|
||||||
{
|
{
|
||||||
let list = output_box_imp.resetOutputStreamList.read().unwrap();
|
let list = output_box_imp.reset_output_stream_list.read().unwrap();
|
||||||
let entry_opt = list.get(&ir.stream.index);
|
let entry_opt = list.get(&ir.stream.index);
|
||||||
if entry_opt.is_none() {
|
if entry_opt.is_none() {
|
||||||
return;
|
return;
|
||||||
|
@ -533,7 +533,7 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
||||||
let percentage = (fraction).to_string() + "%";
|
let percentage = (fraction).to_string() + "%";
|
||||||
imp.resetVolumePercentage.set_text(&percentage);
|
imp.resetVolumePercentage.set_text(&percentage);
|
||||||
imp.resetVolumeSlider.set_value(*volume as f64);
|
imp.resetVolumeSlider.set_value(*volume as f64);
|
||||||
let map = output_box_imp.resetSourceMap.read().unwrap();
|
let map = output_box_imp.reset_source_map.read().unwrap();
|
||||||
if let Some(index) = map.get(&alias) {
|
if let Some(index) = map.get(&alias) {
|
||||||
imp.resetSourceSelection.set_selected(index.1);
|
imp.resetSourceSelection.set_selected(index.1);
|
||||||
}
|
}
|
||||||
|
@ -555,7 +555,7 @@ pub fn start_input_box_listener(conn: Connection, source_box: Arc<SourceBox>) ->
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let output_box = source_box.clone();
|
let output_box = source_box.clone();
|
||||||
let output_box_imp = output_box.imp();
|
let output_box_imp = output_box.imp();
|
||||||
let mut list = output_box_imp.resetOutputStreamList.write().unwrap();
|
let mut list = output_box_imp.reset_output_stream_list.write().unwrap();
|
||||||
let entry = list.remove(&ir.index);
|
let entry = list.remove(&ir.index);
|
||||||
if entry.is_none() {
|
if entry.is_none() {
|
||||||
return;
|
return;
|
|
@ -4,15 +4,15 @@ use std::collections::HashMap;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use crate::components::base::listEntry::ListEntry;
|
use crate::components::base::list_entry::ListEntry;
|
||||||
use crate::components::input::sourceBox;
|
use crate::components::input::source_box;
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, CheckButton, CompositeTemplate, StringList, TemplateChild};
|
use gtk::{glib, CheckButton, CompositeTemplate, StringList, TemplateChild};
|
||||||
use gtk::{prelude::*, Button, Label, ProgressBar, Scale};
|
use gtk::{prelude::*, Button, Label, ProgressBar, Scale};
|
||||||
use ReSet_Lib::audio::audio::Source;
|
use ReSet_Lib::audio::audio::Source;
|
||||||
|
|
||||||
use super::outputStreamEntry::OutputStreamEntry;
|
use super::output_stream_entry::OutputStreamEntry;
|
||||||
use super::sourceEntry::SourceEntry;
|
use super::source_entry::SourceEntry;
|
||||||
|
|
||||||
type SourceEntryMap = Arc<RwLock<HashMap<u32, (Arc<ListEntry>, Arc<SourceEntry>, String)>>>;
|
type SourceEntryMap = Arc<RwLock<HashMap<u32, (Arc<ListEntry>, Arc<SourceEntry>, String)>>>;
|
||||||
type OutputStreamEntryMap = Arc<RwLock<HashMap<u32, (Arc<ListEntry>, Arc<OutputStreamEntry>)>>>;
|
type OutputStreamEntryMap = Arc<RwLock<HashMap<u32, (Arc<ListEntry>, Arc<OutputStreamEntry>)>>>;
|
||||||
|
@ -46,23 +46,23 @@ pub struct SourceBox {
|
||||||
pub resetInputCardsBackButton: TemplateChild<ActionRow>,
|
pub resetInputCardsBackButton: TemplateChild<ActionRow>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub resetCards: TemplateChild<PreferencesGroup>,
|
pub resetCards: TemplateChild<PreferencesGroup>,
|
||||||
pub resetDefaultCheckButton: Arc<CheckButton>,
|
pub reset_default_check_button: Arc<CheckButton>,
|
||||||
pub resetDefaultSource: Arc<RefCell<Source>>,
|
pub reset_default_source: Arc<RefCell<Source>>,
|
||||||
pub resetSourceList: SourceEntryMap,
|
pub reset_source_list: SourceEntryMap,
|
||||||
pub resetOutputStreamList: OutputStreamEntryMap,
|
pub reset_output_stream_list: OutputStreamEntryMap,
|
||||||
pub resetModelList: Arc<RwLock<StringList>>,
|
pub reset_model_list: Arc<RwLock<StringList>>,
|
||||||
pub resetModelIndex: Arc<RwLock<u32>>,
|
pub reset_model_index: Arc<RwLock<u32>>,
|
||||||
// first u32 is the index of the source, the second the index in the model list and the third is
|
// first u32 is the index of the source, the second the index in the model list and the third is
|
||||||
// the full name
|
// the full name
|
||||||
pub resetSourceMap: SourceMap,
|
pub reset_source_map: SourceMap,
|
||||||
pub volumeTimeStamp: RefCell<Option<SystemTime>>,
|
pub volume_time_stamp: RefCell<Option<SystemTime>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
impl ObjectSubclass for SourceBox {
|
impl ObjectSubclass for SourceBox {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetAudioInput";
|
const NAME: &'static str = "resetAudioInput";
|
||||||
type Type = sourceBox::SourceBox;
|
type Type = source_box::SourceBox;
|
||||||
type ParentType = gtk::Box;
|
type ParentType = gtk::Box;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
||||||
|
@ -82,7 +82,7 @@ impl BoxImpl for SourceBox {}
|
||||||
impl ObjectImpl for SourceBox {
|
impl ObjectImpl for SourceBox {
|
||||||
fn constructed(&self) {
|
fn constructed(&self) {
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
obj.setupCallbacks();
|
obj.setup_callbacks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,10 @@ use glib::{clone, Propagation};
|
||||||
use gtk::{gio, CheckButton};
|
use gtk::{gio, CheckButton};
|
||||||
use ReSet_Lib::audio::audio::Source;
|
use ReSet_Lib::audio::audio::Source;
|
||||||
|
|
||||||
use super::sourceEntryImpl;
|
use super::source_entry_impl;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct SourceEntry(ObjectSubclass<sourceEntryImpl::SourceEntry>)
|
pub struct SourceEntry(ObjectSubclass<source_entry_impl::SourceEntry>)
|
||||||
@extends adw::PreferencesGroup, gtk::Widget,
|
@extends adw::PreferencesGroup, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ impl SourceEntry {
|
||||||
let index = source.index;
|
let index = source.index;
|
||||||
let channels = source.channels;
|
let channels = source.channels;
|
||||||
{
|
{
|
||||||
let mut time = imp.volumeTimeStamp.borrow_mut();
|
let mut time = imp.volume_time_stamp.borrow_mut();
|
||||||
if time.is_some()
|
if time.is_some()
|
||||||
&& time.unwrap().elapsed().unwrap() < Duration::from_millis(50)
|
&& time.unwrap().elapsed().unwrap() < Duration::from_millis(50)
|
||||||
{
|
{
|
|
@ -8,7 +8,7 @@ use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, Button, CheckButton, CompositeTemplate, Label, ProgressBar, Scale};
|
use gtk::{glib, Button, CheckButton, CompositeTemplate, Label, ProgressBar, Scale};
|
||||||
use ReSet_Lib::audio::audio::Source;
|
use ReSet_Lib::audio::audio::Source;
|
||||||
|
|
||||||
use super::sourceEntry;
|
use super::source_entry;
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[derive(Default, CompositeTemplate)]
|
#[derive(Default, CompositeTemplate)]
|
||||||
|
@ -27,14 +27,14 @@ pub struct SourceEntry {
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub resetVolumeMeter: TemplateChild<ProgressBar>,
|
pub resetVolumeMeter: TemplateChild<ProgressBar>,
|
||||||
pub stream: Arc<RefCell<Source>>,
|
pub stream: Arc<RefCell<Source>>,
|
||||||
pub volumeTimeStamp: RefCell<Option<SystemTime>>,
|
pub volume_time_stamp: RefCell<Option<SystemTime>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
impl ObjectSubclass for SourceEntry {
|
impl ObjectSubclass for SourceEntry {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetSourceEntry";
|
const NAME: &'static str = "resetSourceEntry";
|
||||||
type Type = sourceEntry::SourceEntry;
|
type Type = source_entry::SourceEntry;
|
||||||
type ParentType = PreferencesGroup;
|
type ParentType = PreferencesGroup;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
|
@ -1,7 +1,7 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
use crate::components::utils::{createDropdownLabelFactory, setComboRowEllipsis};
|
use crate::components::utils::{create_dropdown_label_factory, set_combo_row_ellipsis};
|
||||||
use adw::glib;
|
use adw::glib;
|
||||||
use adw::glib::Object;
|
use adw::glib::Object;
|
||||||
use adw::prelude::{ButtonExt, ComboRowExt, PreferencesRowExt, RangeExt};
|
use adw::prelude::{ButtonExt, ComboRowExt, PreferencesRowExt, RangeExt};
|
||||||
|
@ -12,11 +12,11 @@ use glib::{clone, Cast, Propagation};
|
||||||
use gtk::{gio, StringObject};
|
use gtk::{gio, StringObject};
|
||||||
use ReSet_Lib::audio::audio::InputStream;
|
use ReSet_Lib::audio::audio::InputStream;
|
||||||
|
|
||||||
use super::inputStreamEntryImpl;
|
use super::input_stream_entry_impl;
|
||||||
use super::sinkBox::SinkBox;
|
use super::sink_box::SinkBox;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct InputStreamEntry(ObjectSubclass<inputStreamEntryImpl::InputStreamEntry>)
|
pub struct InputStreamEntry(ObjectSubclass<input_stream_entry_impl::InputStreamEntry>)
|
||||||
@extends adw::PreferencesGroup, gtk::Widget,
|
@extends adw::PreferencesGroup, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,8 @@ impl InputStreamEntry {
|
||||||
let name = stream.application_name.clone() + ": " + stream.name.as_str();
|
let name = stream.application_name.clone() + ": " + stream.name.as_str();
|
||||||
imp.resetSinkSelection.set_title(name.as_str());
|
imp.resetSinkSelection.set_title(name.as_str());
|
||||||
imp.resetSinkSelection
|
imp.resetSinkSelection
|
||||||
.set_factory(Some(&createDropdownLabelFactory()));
|
.set_factory(Some(&create_dropdown_label_factory()));
|
||||||
setComboRowEllipsis(imp.resetSinkSelection.get());
|
set_combo_row_ellipsis(imp.resetSinkSelection.get());
|
||||||
let volume = stream.volume.first().unwrap_or(&0_u32);
|
let volume = stream.volume.first().unwrap_or(&0_u32);
|
||||||
let fraction = (*volume as f64 / 655.36).round();
|
let fraction = (*volume as f64 / 655.36).round();
|
||||||
let percentage = (fraction).to_string() + "%";
|
let percentage = (fraction).to_string() + "%";
|
||||||
|
@ -51,8 +51,8 @@ impl InputStreamEntry {
|
||||||
imp.resetVolumeSlider.set_value(*volume as f64);
|
imp.resetVolumeSlider.set_value(*volume as f64);
|
||||||
imp.stream.replace(stream);
|
imp.stream.replace(stream);
|
||||||
{
|
{
|
||||||
let sink = box_imp.resetDefaultSink.borrow();
|
let sink = box_imp.reset_default_sink.borrow();
|
||||||
imp.associatedSink.replace((sink.index, sink.name.clone()));
|
imp.associated_sink.replace((sink.index, sink.name.clone()));
|
||||||
}
|
}
|
||||||
imp.resetVolumeSlider.connect_change_value(
|
imp.resetVolumeSlider.connect_change_value(
|
||||||
clone!(@weak imp => @default-return Propagation::Stop, move |_, _, value| {
|
clone!(@weak imp => @default-return Propagation::Stop, move |_, _, value| {
|
||||||
|
@ -67,7 +67,7 @@ impl InputStreamEntry {
|
||||||
let index = stream.index;
|
let index = stream.index;
|
||||||
let channels = stream.channels;
|
let channels = stream.channels;
|
||||||
{
|
{
|
||||||
let mut time = imp.volumeTimeStamp.borrow_mut();
|
let mut time = imp.volume_time_stamp.borrow_mut();
|
||||||
if time.is_some() && time.unwrap().elapsed().unwrap() < Duration::from_millis(50) {
|
if time.is_some() && time.unwrap().elapsed().unwrap() < Duration::from_millis(50) {
|
||||||
return Propagation::Proceed;
|
return Propagation::Proceed;
|
||||||
}
|
}
|
||||||
|
@ -78,14 +78,14 @@ impl InputStreamEntry {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
{
|
{
|
||||||
let list = box_imp.resetModelList.read().unwrap();
|
let list = box_imp.reset_model_list.read().unwrap();
|
||||||
// while list.is_err() {
|
// while list.is_err() {
|
||||||
// list = box_imp.resetModelList.try_borrow();
|
// list = box_imp.resetModelList.try_borrow();
|
||||||
// }
|
// }
|
||||||
// let list = list.unwrap();
|
// let list = list.unwrap();
|
||||||
imp.resetSinkSelection.set_model(Some(&*list));
|
imp.resetSinkSelection.set_model(Some(&*list));
|
||||||
let map = box_imp.resetSinkMap.read().unwrap();
|
let map = box_imp.reset_sink_map.read().unwrap();
|
||||||
let sink_list = box_imp.resetSinkList.read().unwrap();
|
let sink_list = box_imp.reset_sink_list.read().unwrap();
|
||||||
let name = sink_list.get(&index);
|
let name = sink_list.get(&index);
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
let name = &name.2;
|
let name = &name.2;
|
||||||
|
@ -94,9 +94,9 @@ impl InputStreamEntry {
|
||||||
imp.resetSinkSelection.set_selected(index.1);
|
imp.resetSinkSelection.set_selected(index.1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut name = box_imp.resetDefaultSink.try_borrow();
|
let mut name = box_imp.reset_default_sink.try_borrow();
|
||||||
while name.is_err() {
|
while name.is_err() {
|
||||||
name = box_imp.resetDefaultSink.try_borrow();
|
name = box_imp.reset_default_sink.try_borrow();
|
||||||
}
|
}
|
||||||
let name = &name.unwrap().alias;
|
let name = &name.unwrap().alias;
|
||||||
let index = map.get(name);
|
let index = map.get(name);
|
||||||
|
@ -114,7 +114,7 @@ impl InputStreamEntry {
|
||||||
let selected = selected.unwrap();
|
let selected = selected.unwrap();
|
||||||
let selected = selected.downcast_ref::<StringObject>().unwrap();
|
let selected = selected.downcast_ref::<StringObject>().unwrap();
|
||||||
let selected = selected.string().to_string();
|
let selected = selected.string().to_string();
|
||||||
let sink = box_imp.resetSinkMap.read().unwrap();
|
let sink = box_imp.reset_sink_map.read().unwrap();
|
||||||
// if sink.is_err() {
|
// if sink.is_err() {
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
|
@ -8,7 +8,7 @@ use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, Button, CompositeTemplate, Label, ProgressBar, Scale};
|
use gtk::{glib, Button, CompositeTemplate, Label, ProgressBar, Scale};
|
||||||
use ReSet_Lib::audio::audio::InputStream;
|
use ReSet_Lib::audio::audio::InputStream;
|
||||||
|
|
||||||
use super::inputStreamEntry;
|
use super::input_stream_entry;
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[derive(Default, CompositeTemplate)]
|
#[derive(Default, CompositeTemplate)]
|
||||||
|
@ -25,15 +25,15 @@ pub struct InputStreamEntry {
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub resetVolumeMeter: TemplateChild<ProgressBar>,
|
pub resetVolumeMeter: TemplateChild<ProgressBar>,
|
||||||
pub stream: Arc<RefCell<InputStream>>,
|
pub stream: Arc<RefCell<InputStream>>,
|
||||||
pub associatedSink: Arc<RefCell<(u32, String)>>,
|
pub associated_sink: Arc<RefCell<(u32, String)>>,
|
||||||
pub volumeTimeStamp: RefCell<Option<SystemTime>>,
|
pub volume_time_stamp: RefCell<Option<SystemTime>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
impl ObjectSubclass for InputStreamEntry {
|
impl ObjectSubclass for InputStreamEntry {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetInputStreamEntry";
|
const NAME: &'static str = "resetInputStreamEntry";
|
||||||
type Type = inputStreamEntry::InputStreamEntry;
|
type Type = input_stream_entry::InputStreamEntry;
|
||||||
type ParentType = PreferencesGroup;
|
type ParentType = PreferencesGroup;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
|
@ -1,7 +1,6 @@
|
||||||
#![allow(non_snake_case)]
|
pub mod input_stream_entry;
|
||||||
pub mod inputStreamEntry;
|
pub mod input_stream_entry_impl;
|
||||||
pub mod inputStreamEntryImpl;
|
pub mod sink_box;
|
||||||
pub mod sinkBox;
|
pub mod sink_box_impl;
|
||||||
pub mod sinkBoxImpl;
|
pub mod sink_entry;
|
||||||
pub mod sinkEntry;
|
pub mod sink_entry_impl;
|
||||||
pub mod sinkEntryImpl;
|
|
||||||
|
|
|
@ -15,20 +15,20 @@ use gtk::prelude::ActionableExt;
|
||||||
use gtk::{gio, StringObject};
|
use gtk::{gio, StringObject};
|
||||||
use ReSet_Lib::audio::audio::{Card, InputStream, Sink};
|
use ReSet_Lib::audio::audio::{Card, InputStream, Sink};
|
||||||
|
|
||||||
use crate::components::base::cardEntry::CardEntry;
|
use crate::components::base::card_entry::CardEntry;
|
||||||
use crate::components::base::listEntry::ListEntry;
|
use crate::components::base::list_entry::ListEntry;
|
||||||
use crate::components::base::utils::{
|
use crate::components::base::utils::{
|
||||||
InputStreamAdded, InputStreamChanged, InputStreamRemoved, SinkAdded, SinkChanged, SinkRemoved,
|
InputStreamAdded, InputStreamChanged, InputStreamRemoved, SinkAdded, SinkChanged, SinkRemoved,
|
||||||
};
|
};
|
||||||
use crate::components::output::sinkEntry::set_sink_volume;
|
use crate::components::output::sink_entry::set_sink_volume;
|
||||||
use crate::components::utils::{createDropdownLabelFactory, setComboRowEllipsis};
|
use crate::components::utils::{create_dropdown_label_factory, set_combo_row_ellipsis};
|
||||||
|
|
||||||
use super::inputStreamEntry::InputStreamEntry;
|
use super::input_stream_entry::InputStreamEntry;
|
||||||
use super::sinkBoxImpl;
|
use super::sink_box_impl;
|
||||||
use super::sinkEntry::{set_default_sink, toggle_sink_mute, SinkEntry};
|
use super::sink_entry::{set_default_sink, toggle_sink_mute, SinkEntry};
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct SinkBox(ObjectSubclass<sinkBoxImpl::SinkBox>)
|
pub struct SinkBox(ObjectSubclass<sink_box_impl::SinkBox>)
|
||||||
@extends gtk::Box, gtk::Widget,
|
@extends gtk::Box, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||||
}
|
}
|
||||||
|
@ -41,44 +41,44 @@ impl SinkBox {
|
||||||
let obj: Self = Object::builder().build();
|
let obj: Self = Object::builder().build();
|
||||||
{
|
{
|
||||||
let imp = obj.imp();
|
let imp = obj.imp();
|
||||||
let mut model_index = imp.resetModelIndex.write().unwrap();
|
let mut model_index = imp.reset_model_index.write().unwrap();
|
||||||
*model_index = 0;
|
*model_index = 0;
|
||||||
}
|
}
|
||||||
obj
|
obj
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setupCallbacks(&self) {
|
pub fn setup_callbacks(&self) {
|
||||||
let selfImp = self.imp();
|
let self_imp = self.imp();
|
||||||
selfImp.resetSinksRow.set_activatable(true);
|
self_imp.resetSinksRow.set_activatable(true);
|
||||||
selfImp
|
self_imp
|
||||||
.resetSinksRow
|
.resetSinksRow
|
||||||
.set_action_name(Some("navigation.push"));
|
.set_action_name(Some("navigation.push"));
|
||||||
selfImp
|
self_imp
|
||||||
.resetSinksRow
|
.resetSinksRow
|
||||||
.set_action_target_value(Some(&Variant::from("outputDevices")));
|
.set_action_target_value(Some(&Variant::from("outputDevices")));
|
||||||
selfImp.resetCardsRow.set_activatable(true);
|
self_imp.resetCardsRow.set_activatable(true);
|
||||||
selfImp
|
self_imp
|
||||||
.resetCardsRow
|
.resetCardsRow
|
||||||
.set_action_name(Some("navigation.push"));
|
.set_action_name(Some("navigation.push"));
|
||||||
selfImp
|
self_imp
|
||||||
.resetCardsRow
|
.resetCardsRow
|
||||||
.set_action_target_value(Some(&Variant::from("profileConfiguration")));
|
.set_action_target_value(Some(&Variant::from("profileConfiguration")));
|
||||||
selfImp.resetCardsRow.connect_action_name_notify(|_| {});
|
self_imp.resetCardsRow.connect_action_name_notify(|_| {});
|
||||||
|
|
||||||
selfImp.resetInputStreamButton.set_activatable(true);
|
self_imp.resetInputStreamButton.set_activatable(true);
|
||||||
selfImp
|
self_imp
|
||||||
.resetInputStreamButton
|
.resetInputStreamButton
|
||||||
.set_action_name(Some("navigation.pop"));
|
.set_action_name(Some("navigation.pop"));
|
||||||
|
|
||||||
selfImp.resetInputCardsBackButton.set_activatable(true);
|
self_imp.resetInputCardsBackButton.set_activatable(true);
|
||||||
selfImp
|
self_imp
|
||||||
.resetInputCardsBackButton
|
.resetInputCardsBackButton
|
||||||
.set_action_name(Some("navigation.pop"));
|
.set_action_name(Some("navigation.pop"));
|
||||||
|
|
||||||
selfImp
|
self_imp
|
||||||
.resetSinkDropdown
|
.resetSinkDropdown
|
||||||
.set_factory(Some(&createDropdownLabelFactory()));
|
.set_factory(Some(&create_dropdown_label_factory()));
|
||||||
setComboRowEllipsis(selfImp.resetSinkDropdown.get());
|
set_combo_row_ellipsis(self_imp.resetSinkDropdown.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,10 +94,12 @@ pub fn populate_sinks(output_box: Arc<SinkBox>) {
|
||||||
let sinks = get_sinks();
|
let sinks = get_sinks();
|
||||||
{
|
{
|
||||||
let output_box_imp = output_box.imp();
|
let output_box_imp = output_box.imp();
|
||||||
let mut map = output_box_imp.resetSinkMap.write().unwrap();
|
let mut map = output_box_imp.reset_sink_map.write().unwrap();
|
||||||
let list = output_box_imp.resetModelList.write().unwrap();
|
let list = output_box_imp.reset_model_list.write().unwrap();
|
||||||
let mut model_index = output_box_imp.resetModelIndex.write().unwrap();
|
let mut model_index = output_box_imp.reset_model_index.write().unwrap();
|
||||||
output_box_imp.resetDefaultSink.replace(get_default_sink());
|
output_box_imp
|
||||||
|
.reset_default_sink
|
||||||
|
.replace(get_default_sink());
|
||||||
for (i, sink) in (0_u32..).zip(sinks.iter()) {
|
for (i, sink) in (0_u32..).zip(sinks.iter()) {
|
||||||
list.append(&sink.alias);
|
list.append(&sink.alias);
|
||||||
map.insert(sink.alias.clone(), (sink.index, i, sink.name.clone()));
|
map.insert(sink.alias.clone(), (sink.index, i, sink.name.clone()));
|
||||||
|
@ -112,7 +114,7 @@ pub fn populate_sinks(output_box: Arc<SinkBox>) {
|
||||||
let output_box_ref_mute = output_box.clone();
|
let output_box_ref_mute = output_box.clone();
|
||||||
{
|
{
|
||||||
let output_box_imp = output_box_ref.imp();
|
let output_box_imp = output_box_ref.imp();
|
||||||
let default_sink = output_box_imp.resetDefaultSink.clone();
|
let default_sink = output_box_imp.reset_default_sink.clone();
|
||||||
let sink = default_sink.borrow();
|
let sink = default_sink.borrow();
|
||||||
|
|
||||||
let volume = sink.volume.first().unwrap_or(&0);
|
let volume = sink.volume.first().unwrap_or(&0);
|
||||||
|
@ -120,17 +122,17 @@ pub fn populate_sinks(output_box: Arc<SinkBox>) {
|
||||||
let percentage = (fraction).to_string() + "%";
|
let percentage = (fraction).to_string() + "%";
|
||||||
output_box_imp.resetVolumePercentage.set_text(&percentage);
|
output_box_imp.resetVolumePercentage.set_text(&percentage);
|
||||||
output_box_imp.resetVolumeSlider.set_value(*volume as f64);
|
output_box_imp.resetVolumeSlider.set_value(*volume as f64);
|
||||||
let mut list = output_box_imp.resetSinkList.write().unwrap();
|
let mut list = output_box_imp.reset_sink_list.write().unwrap();
|
||||||
for sink in sinks {
|
for sink in sinks {
|
||||||
let index = sink.index;
|
let index = sink.index;
|
||||||
let alias = sink.alias.clone();
|
let alias = sink.alias.clone();
|
||||||
let mut is_default = false;
|
let mut is_default = false;
|
||||||
if output_box_imp.resetDefaultSink.borrow().name == sink.name {
|
if output_box_imp.reset_default_sink.borrow().name == sink.name {
|
||||||
is_default = true;
|
is_default = true;
|
||||||
}
|
}
|
||||||
let sink_entry = Arc::new(SinkEntry::new(
|
let sink_entry = Arc::new(SinkEntry::new(
|
||||||
is_default,
|
is_default,
|
||||||
output_box_imp.resetDefaultCheckButton.clone(),
|
output_box_imp.reset_default_check_button.clone(),
|
||||||
sink,
|
sink,
|
||||||
));
|
));
|
||||||
let sink_clone = sink_entry.clone();
|
let sink_clone = sink_entry.clone();
|
||||||
|
@ -139,10 +141,10 @@ pub fn populate_sinks(output_box: Arc<SinkBox>) {
|
||||||
list.insert(index, (entry.clone(), sink_clone, alias));
|
list.insert(index, (entry.clone(), sink_clone, alias));
|
||||||
output_box_imp.resetSinks.append(&*entry);
|
output_box_imp.resetSinks.append(&*entry);
|
||||||
}
|
}
|
||||||
let list = output_box_imp.resetModelList.read().unwrap();
|
let list = output_box_imp.reset_model_list.read().unwrap();
|
||||||
output_box_imp.resetSinkDropdown.set_model(Some(&*list));
|
output_box_imp.resetSinkDropdown.set_model(Some(&*list));
|
||||||
let map = output_box_imp.resetSinkMap.read().unwrap();
|
let map = output_box_imp.reset_sink_map.read().unwrap();
|
||||||
let name = output_box_imp.resetDefaultSink.borrow();
|
let name = output_box_imp.reset_default_sink.borrow();
|
||||||
let name = &name.alias;
|
let name = &name.alias;
|
||||||
let index = map.get(name);
|
let index = map.get(name);
|
||||||
if let Some(index) = index {
|
if let Some(index) = index {
|
||||||
|
@ -158,7 +160,7 @@ pub fn populate_sinks(output_box: Arc<SinkBox>) {
|
||||||
let selected = selected.downcast_ref::<StringObject>().unwrap();
|
let selected = selected.downcast_ref::<StringObject>().unwrap();
|
||||||
let selected = selected.string().to_string();
|
let selected = selected.string().to_string();
|
||||||
|
|
||||||
let sink = output_box_imp.resetSinkMap.read().unwrap();
|
let sink = output_box_imp.reset_sink_map.read().unwrap();
|
||||||
let sink = sink.get(&selected);
|
let sink = sink.get(&selected);
|
||||||
if sink.is_none() {
|
if sink.is_none() {
|
||||||
return;
|
return;
|
||||||
|
@ -176,11 +178,11 @@ pub fn populate_sinks(output_box: Arc<SinkBox>) {
|
||||||
let fraction = (value / 655.36).round();
|
let fraction = (value / 655.36).round();
|
||||||
let percentage = (fraction).to_string() + "%";
|
let percentage = (fraction).to_string() + "%";
|
||||||
imp.resetVolumePercentage.set_text(&percentage);
|
imp.resetVolumePercentage.set_text(&percentage);
|
||||||
let sink = imp.resetDefaultSink.borrow();
|
let sink = imp.reset_default_sink.borrow();
|
||||||
let index = sink.index;
|
let index = sink.index;
|
||||||
let channels = sink.channels;
|
let channels = sink.channels;
|
||||||
{
|
{
|
||||||
let mut time = imp.volumeTimeStamp.borrow_mut();
|
let mut time = imp.volume_time_stamp.borrow_mut();
|
||||||
if time.is_some()
|
if time.is_some()
|
||||||
&& time.unwrap().elapsed().unwrap() < Duration::from_millis(50)
|
&& time.unwrap().elapsed().unwrap() < Duration::from_millis(50)
|
||||||
{
|
{
|
||||||
|
@ -196,7 +198,7 @@ pub fn populate_sinks(output_box: Arc<SinkBox>) {
|
||||||
.resetSinkMute
|
.resetSinkMute
|
||||||
.connect_clicked(move |_| {
|
.connect_clicked(move |_| {
|
||||||
let imp = output_box_ref_mute.imp();
|
let imp = output_box_ref_mute.imp();
|
||||||
let stream = imp.resetDefaultSink.clone();
|
let stream = imp.reset_default_sink.clone();
|
||||||
let mut stream = stream.borrow_mut();
|
let mut stream = stream.borrow_mut();
|
||||||
stream.muted = !stream.muted;
|
stream.muted = !stream.muted;
|
||||||
let muted = stream.muted;
|
let muted = stream.muted;
|
||||||
|
@ -223,7 +225,7 @@ pub fn populate_inputstreams(output_box: Arc<SinkBox>) {
|
||||||
glib::spawn_future(async move {
|
glib::spawn_future(async move {
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let output_box_imp = output_box_ref.imp();
|
let output_box_imp = output_box_ref.imp();
|
||||||
let mut list = output_box_imp.resetInputStreamList.write().unwrap();
|
let mut list = output_box_imp.reset_input_stream_list.write().unwrap();
|
||||||
for stream in streams {
|
for stream in streams {
|
||||||
let index = stream.index;
|
let index = stream.index;
|
||||||
let input_stream = Arc::new(InputStreamEntry::new(output_box.clone(), stream));
|
let input_stream = Arc::new(InputStreamEntry::new(output_box.clone(), stream));
|
||||||
|
@ -357,17 +359,17 @@ pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Co
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let output_box = sink_box.clone();
|
let output_box = sink_box.clone();
|
||||||
let output_box_imp = output_box.imp();
|
let output_box_imp = output_box.imp();
|
||||||
let mut list = output_box_imp.resetSinkList.write().unwrap();
|
let mut list = output_box_imp.reset_sink_list.write().unwrap();
|
||||||
let sink_index = ir.sink.index;
|
let sink_index = ir.sink.index;
|
||||||
let alias = ir.sink.alias.clone();
|
let alias = ir.sink.alias.clone();
|
||||||
let name = ir.sink.name.clone();
|
let name = ir.sink.name.clone();
|
||||||
let mut is_default = false;
|
let mut is_default = false;
|
||||||
if output_box_imp.resetDefaultSink.borrow().name == ir.sink.name {
|
if output_box_imp.reset_default_sink.borrow().name == ir.sink.name {
|
||||||
is_default = true;
|
is_default = true;
|
||||||
}
|
}
|
||||||
let sink_entry = Arc::new(SinkEntry::new(
|
let sink_entry = Arc::new(SinkEntry::new(
|
||||||
is_default,
|
is_default,
|
||||||
output_box_imp.resetDefaultCheckButton.clone(),
|
output_box_imp.reset_default_check_button.clone(),
|
||||||
ir.sink,
|
ir.sink,
|
||||||
));
|
));
|
||||||
let sink_clone = sink_entry.clone();
|
let sink_clone = sink_entry.clone();
|
||||||
|
@ -375,10 +377,10 @@ pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Co
|
||||||
entry.set_activatable(false);
|
entry.set_activatable(false);
|
||||||
list.insert(sink_index, (entry.clone(), sink_clone, alias.clone()));
|
list.insert(sink_index, (entry.clone(), sink_clone, alias.clone()));
|
||||||
output_box_imp.resetSinks.append(&*entry);
|
output_box_imp.resetSinks.append(&*entry);
|
||||||
let mut map = output_box_imp.resetSinkMap.write().unwrap();
|
let mut map = output_box_imp.reset_sink_map.write().unwrap();
|
||||||
let mut index = output_box_imp.resetModelIndex.write().unwrap();
|
let mut index = output_box_imp.reset_model_index.write().unwrap();
|
||||||
output_box_imp
|
output_box_imp
|
||||||
.resetModelList
|
.reset_model_list
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.append(&alias);
|
.append(&alias);
|
||||||
|
@ -399,7 +401,7 @@ pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Co
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let output_box = sink_box.clone();
|
let output_box = sink_box.clone();
|
||||||
let output_box_imp = output_box.imp();
|
let output_box_imp = output_box.imp();
|
||||||
let mut list = output_box_imp.resetSinkList.write().unwrap();
|
let mut list = output_box_imp.reset_sink_list.write().unwrap();
|
||||||
let entry = list.get(&ir.index);
|
let entry = list.get(&ir.index);
|
||||||
if entry.is_none() {
|
if entry.is_none() {
|
||||||
return;
|
return;
|
||||||
|
@ -409,16 +411,16 @@ pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Co
|
||||||
if alias.is_none() {
|
if alias.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut map = output_box_imp.resetSinkMap.write().unwrap();
|
let mut map = output_box_imp.reset_sink_map.write().unwrap();
|
||||||
let entry_index = map.remove(&alias.unwrap().2);
|
let entry_index = map.remove(&alias.unwrap().2);
|
||||||
if let Some(entry_index) = entry_index {
|
if let Some(entry_index) = entry_index {
|
||||||
output_box_imp
|
output_box_imp
|
||||||
.resetModelList
|
.reset_model_list
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.remove(entry_index.1);
|
.remove(entry_index.1);
|
||||||
}
|
}
|
||||||
let mut index = output_box_imp.resetModelIndex.write().unwrap();
|
let mut index = output_box_imp.reset_model_index.write().unwrap();
|
||||||
if *index != 0 {
|
if *index != 0 {
|
||||||
*index -= 1;
|
*index -= 1;
|
||||||
}
|
}
|
||||||
|
@ -443,7 +445,7 @@ pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Co
|
||||||
let fraction = (*volume as f64 / 655.36).round();
|
let fraction = (*volume as f64 / 655.36).round();
|
||||||
let percentage = (fraction).to_string() + "%";
|
let percentage = (fraction).to_string() + "%";
|
||||||
|
|
||||||
let list = output_box_imp.resetSinkList.read().unwrap();
|
let list = output_box_imp.reset_sink_list.read().unwrap();
|
||||||
let entry = list.get(&ir.sink.index);
|
let entry = list.get(&ir.sink.index);
|
||||||
if entry.is_none() {
|
if entry.is_none() {
|
||||||
return;
|
return;
|
||||||
|
@ -474,7 +476,7 @@ pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Co
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let output_box = sink_box.clone();
|
let output_box = sink_box.clone();
|
||||||
let output_box_imp = output_box.imp();
|
let output_box_imp = output_box.imp();
|
||||||
let mut list = output_box_imp.resetInputStreamList.write().unwrap();
|
let mut list = output_box_imp.reset_input_stream_list.write().unwrap();
|
||||||
let index = ir.stream.index;
|
let index = ir.stream.index;
|
||||||
let input_stream = Arc::new(InputStreamEntry::new(output_box.clone(), ir.stream));
|
let input_stream = Arc::new(InputStreamEntry::new(output_box.clone(), ir.stream));
|
||||||
let entry = Arc::new(ListEntry::new(&*input_stream));
|
let entry = Arc::new(ListEntry::new(&*input_stream));
|
||||||
|
@ -494,7 +496,7 @@ pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Co
|
||||||
let imp = input_stream_changed_box.imp();
|
let imp = input_stream_changed_box.imp();
|
||||||
let alias: String;
|
let alias: String;
|
||||||
{
|
{
|
||||||
let sink_list = imp.resetSinkList.read().unwrap();
|
let sink_list = imp.reset_sink_list.read().unwrap();
|
||||||
let alias_opt = sink_list.get(&ir.stream.sink_index);
|
let alias_opt = sink_list.get(&ir.stream.sink_index);
|
||||||
if let Some(alias_opt) = alias_opt {
|
if let Some(alias_opt) = alias_opt {
|
||||||
alias = alias_opt.2.clone();
|
alias = alias_opt.2.clone();
|
||||||
|
@ -509,7 +511,7 @@ pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Co
|
||||||
let output_box_imp = output_box.imp();
|
let output_box_imp = output_box.imp();
|
||||||
let entry: Arc<InputStreamEntry>;
|
let entry: Arc<InputStreamEntry>;
|
||||||
{
|
{
|
||||||
let list = output_box_imp.resetInputStreamList.read().unwrap();
|
let list = output_box_imp.reset_input_stream_list.read().unwrap();
|
||||||
let entry_opt = list.get(&ir.stream.index);
|
let entry_opt = list.get(&ir.stream.index);
|
||||||
if entry_opt.is_none() {
|
if entry_opt.is_none() {
|
||||||
return;
|
return;
|
||||||
|
@ -531,7 +533,7 @@ pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Co
|
||||||
let percentage = (fraction).to_string() + "%";
|
let percentage = (fraction).to_string() + "%";
|
||||||
imp.resetVolumePercentage.set_text(&percentage);
|
imp.resetVolumePercentage.set_text(&percentage);
|
||||||
imp.resetVolumeSlider.set_value(*volume as f64);
|
imp.resetVolumeSlider.set_value(*volume as f64);
|
||||||
let map = output_box_imp.resetSinkMap.read().unwrap();
|
let map = output_box_imp.reset_sink_map.read().unwrap();
|
||||||
let index = map.get(&alias);
|
let index = map.get(&alias);
|
||||||
if let Some(index) = index {
|
if let Some(index) = index {
|
||||||
imp.resetSinkSelection.set_selected(index.1);
|
imp.resetSinkSelection.set_selected(index.1);
|
||||||
|
@ -551,7 +553,7 @@ pub fn start_output_box_listener(conn: Connection, sink_box: Arc<SinkBox>) -> Co
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let output_box = sink_box.clone();
|
let output_box = sink_box.clone();
|
||||||
let output_box_imp = output_box.imp();
|
let output_box_imp = output_box.imp();
|
||||||
let mut list = output_box_imp.resetInputStreamList.write().unwrap();
|
let mut list = output_box_imp.reset_input_stream_list.write().unwrap();
|
||||||
let entry = list.get(&ir.index);
|
let entry = list.get(&ir.index);
|
||||||
if entry.is_none() {
|
if entry.is_none() {
|
||||||
return;
|
return;
|
|
@ -4,15 +4,15 @@ use std::collections::HashMap;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use crate::components::base::listEntry::ListEntry;
|
use crate::components::base::list_entry::ListEntry;
|
||||||
use crate::components::output::inputStreamEntry::InputStreamEntry;
|
use crate::components::output::input_stream_entry::InputStreamEntry;
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, Box, Button, CheckButton, CompositeTemplate, Label, StringList, TemplateChild};
|
use gtk::{glib, Box, Button, CheckButton, CompositeTemplate, Label, StringList, TemplateChild};
|
||||||
use gtk::{prelude::*, ProgressBar, Scale};
|
use gtk::{prelude::*, ProgressBar, Scale};
|
||||||
use ReSet_Lib::audio::audio::Sink;
|
use ReSet_Lib::audio::audio::Sink;
|
||||||
|
|
||||||
use super::sinkBox;
|
use super::sink_box;
|
||||||
use super::sinkEntry::SinkEntry;
|
use super::sink_entry::SinkEntry;
|
||||||
|
|
||||||
type SinkEntryMap = Arc<RwLock<HashMap<u32, (Arc<ListEntry>, Arc<SinkEntry>, String)>>>;
|
type SinkEntryMap = Arc<RwLock<HashMap<u32, (Arc<ListEntry>, Arc<SinkEntry>, String)>>>;
|
||||||
type InputStreamEntryMap = Arc<RwLock<HashMap<u32, (Arc<ListEntry>, Arc<InputStreamEntry>)>>>;
|
type InputStreamEntryMap = Arc<RwLock<HashMap<u32, (Arc<ListEntry>, Arc<InputStreamEntry>)>>>;
|
||||||
|
@ -46,23 +46,23 @@ pub struct SinkBox {
|
||||||
pub resetInputCardsBackButton: TemplateChild<ActionRow>,
|
pub resetInputCardsBackButton: TemplateChild<ActionRow>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub resetCards: TemplateChild<PreferencesGroup>,
|
pub resetCards: TemplateChild<PreferencesGroup>,
|
||||||
pub resetDefaultCheckButton: Arc<CheckButton>,
|
pub reset_default_check_button: Arc<CheckButton>,
|
||||||
pub resetDefaultSink: Arc<RefCell<Sink>>,
|
pub reset_default_sink: Arc<RefCell<Sink>>,
|
||||||
pub resetSinkList: SinkEntryMap,
|
pub reset_sink_list: SinkEntryMap,
|
||||||
pub resetInputStreamList: InputStreamEntryMap,
|
pub reset_input_stream_list: InputStreamEntryMap,
|
||||||
pub resetModelList: Arc<RwLock<StringList>>,
|
pub reset_model_list: Arc<RwLock<StringList>>,
|
||||||
pub resetModelIndex: Arc<RwLock<u32>>,
|
pub reset_model_index: Arc<RwLock<u32>>,
|
||||||
// first u32 is the index of the sink, the second the index in the model list and the third is
|
// first u32 is the index of the sink, the second the index in the model list and the third is
|
||||||
// the full name
|
// the full name
|
||||||
pub resetSinkMap: SinkMap,
|
pub reset_sink_map: SinkMap,
|
||||||
pub volumeTimeStamp: RefCell<Option<SystemTime>>,
|
pub volume_time_stamp: RefCell<Option<SystemTime>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
impl ObjectSubclass for SinkBox {
|
impl ObjectSubclass for SinkBox {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetAudioOutput";
|
const NAME: &'static str = "resetAudioOutput";
|
||||||
type Type = sinkBox::SinkBox;
|
type Type = sink_box::SinkBox;
|
||||||
type ParentType = gtk::Box;
|
type ParentType = gtk::Box;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
||||||
|
@ -82,7 +82,7 @@ impl BoxImpl for SinkBox {}
|
||||||
impl ObjectImpl for SinkBox {
|
impl ObjectImpl for SinkBox {
|
||||||
fn constructed(&self) {
|
fn constructed(&self) {
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
obj.setupCallbacks();
|
obj.setup_callbacks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,10 @@ use glib::{clone, Propagation};
|
||||||
use gtk::{gio, CheckButton};
|
use gtk::{gio, CheckButton};
|
||||||
use ReSet_Lib::audio::audio::Sink;
|
use ReSet_Lib::audio::audio::Sink;
|
||||||
|
|
||||||
use super::sinkEntryImpl;
|
use super::sink_entry_impl;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct SinkEntry(ObjectSubclass<sinkEntryImpl::SinkEntry>)
|
pub struct SinkEntry(ObjectSubclass<sink_entry_impl::SinkEntry>)
|
||||||
@extends adw::PreferencesGroup, gtk::Widget,
|
@extends adw::PreferencesGroup, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ impl SinkEntry {
|
||||||
let index = sink.index;
|
let index = sink.index;
|
||||||
let channels = sink.channels;
|
let channels = sink.channels;
|
||||||
{
|
{
|
||||||
let mut time = imp.volumeTimeStamp.borrow_mut();
|
let mut time = imp.volume_time_stamp.borrow_mut();
|
||||||
if time.is_some() && time.unwrap().elapsed().unwrap() < Duration::from_millis(50) {
|
if time.is_some() && time.unwrap().elapsed().unwrap() < Duration::from_millis(50) {
|
||||||
return Propagation::Proceed;
|
return Propagation::Proceed;
|
||||||
}
|
}
|
|
@ -4,7 +4,7 @@ use std::cell::RefCell;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use crate::components::output::sinkEntry;
|
use crate::components::output::sink_entry;
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, Button, CheckButton, CompositeTemplate, Label, ProgressBar, Scale};
|
use gtk::{glib, Button, CheckButton, CompositeTemplate, Label, ProgressBar, Scale};
|
||||||
use ReSet_Lib::audio::audio::Sink;
|
use ReSet_Lib::audio::audio::Sink;
|
||||||
|
@ -26,14 +26,14 @@ pub struct SinkEntry {
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub resetVolumeMeter: TemplateChild<ProgressBar>,
|
pub resetVolumeMeter: TemplateChild<ProgressBar>,
|
||||||
pub stream: Arc<RefCell<Sink>>,
|
pub stream: Arc<RefCell<Sink>>,
|
||||||
pub volumeTimeStamp: RefCell<Option<SystemTime>>,
|
pub volume_time_stamp: RefCell<Option<SystemTime>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
impl ObjectSubclass for SinkEntry {
|
impl ObjectSubclass for SinkEntry {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetSinkEntry";
|
const NAME: &'static str = "resetSinkEntry";
|
||||||
type Type = sinkEntry::SinkEntry;
|
type Type = sink_entry::SinkEntry;
|
||||||
type ParentType = PreferencesGroup;
|
type ParentType = PreferencesGroup;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
|
@ -5,7 +5,7 @@ use glib::{Cast, Object};
|
||||||
use gtk::prelude::{GObjectPropertyExpressionExt, ListBoxRowExt, ListItemExt, WidgetExt};
|
use gtk::prelude::{GObjectPropertyExpressionExt, ListBoxRowExt, ListItemExt, WidgetExt};
|
||||||
use gtk::{Align, SignalListItemFactory, StringObject};
|
use gtk::{Align, SignalListItemFactory, StringObject};
|
||||||
|
|
||||||
pub fn createDropdownLabelFactory() -> SignalListItemFactory {
|
pub fn create_dropdown_label_factory() -> SignalListItemFactory {
|
||||||
let factory = SignalListItemFactory::new();
|
let factory = SignalListItemFactory::new();
|
||||||
factory.connect_setup(|_, item| {
|
factory.connect_setup(|_, item| {
|
||||||
let item = item.downcast_ref::<gtk::ListItem>().unwrap();
|
let item = item.downcast_ref::<gtk::ListItem>().unwrap();
|
||||||
|
@ -19,7 +19,7 @@ pub fn createDropdownLabelFactory() -> SignalListItemFactory {
|
||||||
factory
|
factory
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setComboRowEllipsis(element: ComboRow) {
|
pub fn set_combo_row_ellipsis(element: ComboRow) {
|
||||||
for (i, child) in element
|
for (i, child) in element
|
||||||
.child()
|
.child()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
#![allow(non_snake_case)]
|
pub mod saved_wifi_entry;
|
||||||
pub mod savedWifiEntry;
|
pub mod saved_wifi_entry_impl;
|
||||||
pub mod savedWifiEntryImpl;
|
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
pub mod wifiAddressEntry;
|
pub mod wifi_address_entry;
|
||||||
pub mod wifiAddressEntryImpl;
|
pub mod wifi_address_entry_impl;
|
||||||
pub mod wifiBox;
|
pub mod wifi_box;
|
||||||
pub mod wifiBoxImpl;
|
pub mod wifi_box_impl;
|
||||||
pub mod wifiEntry;
|
pub mod wifi_entry;
|
||||||
pub mod wifiEntryImpl;
|
pub mod wifi_entry_impl;
|
||||||
pub mod wifiOptions;
|
pub mod wifi_options;
|
||||||
pub mod wifiOptionsImpl;
|
pub mod wifi_options_impl;
|
||||||
pub mod wifiRouteEntry;
|
pub mod wifi_route_entry;
|
||||||
pub mod wifiRouteEntryImpl;
|
pub mod wifi_route_entry_impl;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::components::wifi::savedWifiEntryImpl;
|
use crate::components::wifi::saved_wifi_entry_impl;
|
||||||
use crate::components::wifi::wifiBoxImpl::WifiBox;
|
use crate::components::wifi::wifi_box_impl::WifiBox;
|
||||||
use adw::glib;
|
use adw::glib;
|
||||||
use adw::glib::Object;
|
use adw::glib::Object;
|
||||||
use adw::prelude::{ButtonExt, WidgetExt};
|
use adw::prelude::{ButtonExt, WidgetExt};
|
||||||
|
@ -13,30 +13,30 @@ use gtk::gio;
|
||||||
use gtk::prelude::ListBoxRowExt;
|
use gtk::prelude::ListBoxRowExt;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct SavedWifiEntry(ObjectSubclass<savedWifiEntryImpl::SavedWifiEntry>)
|
pub struct SavedWifiEntry(ObjectSubclass<saved_wifi_entry_impl::SavedWifiEntry>)
|
||||||
@extends adw::ActionRow, gtk::Widget,
|
@extends adw::ActionRow, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::Actionable, gtk::ConstraintTarget, gtk::ListBoxRow;
|
@implements gtk::Accessible, gtk::Buildable, gtk::Actionable, gtk::ConstraintTarget, gtk::ListBoxRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SavedWifiEntry {
|
impl SavedWifiEntry {
|
||||||
pub fn new(name: &str, path: Path<'static>, wifiBox: &WifiBox) -> Self {
|
pub fn new(name: &str, path: Path<'static>, wifi_box: &WifiBox) -> Self {
|
||||||
let entry: SavedWifiEntry = Object::builder().build();
|
let entry: SavedWifiEntry = Object::builder().build();
|
||||||
entry.set_activatable(false);
|
entry.set_activatable(false);
|
||||||
let entryImp = entry.imp();
|
let entry_imp = entry.imp();
|
||||||
|
|
||||||
entryImp.resetEditSavedWifiButton.connect_clicked(
|
entry_imp.resetEditSavedWifiButton.connect_clicked(
|
||||||
clone!(@ weak entryImp, @ weak wifiBox => move |_| {
|
clone!(@ weak entry_imp, @ weak wifi_box => move |_| {
|
||||||
// TODO accesspoint has to be saved somewhere i guess
|
// TODO accesspoint has to be saved somewhere i guess
|
||||||
// let _option = getConnectionSettings(entryImp.accessPoint.borrow().associated_connection.clone());
|
// let _option = getConnectionSettings(entryImp.accessPoint.borrow().associated_connection.clone());
|
||||||
// wifiBox.resetWifiNavigation.push(&*WifiOptions::new(_option));
|
// wifiBox.resetWifiNavigation.push(&*WifiOptions::new(_option));
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
entryImp.resetSavedWifiLabel.set_text(name);
|
entry_imp.resetSavedWifiLabel.set_text(name);
|
||||||
entryImp.resetConnectionPath.set(path);
|
entry_imp.reset_connection_path.set(path);
|
||||||
entryImp.resetDeleteSavedWifiButton.connect_clicked(
|
entry_imp.resetDeleteSavedWifiButton.connect_clicked(
|
||||||
clone!(@weak entry as entry => move |_| {
|
clone!(@weak entry as entry => move |_| {
|
||||||
delete_connection(entry.imp().resetConnectionPath.take());
|
delete_connection(entry.imp().reset_connection_path.take());
|
||||||
// TODO handle error
|
// TODO handle error
|
||||||
let parent = entry.parent().unwrap();
|
let parent = entry.parent().unwrap();
|
||||||
parent.set_visible(false);
|
parent.set_visible(false);
|
|
@ -8,7 +8,7 @@ use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, Button, CompositeTemplate, Label};
|
use gtk::{glib, Button, CompositeTemplate, Label};
|
||||||
use ReSet_Lib::network::network::AccessPoint;
|
use ReSet_Lib::network::network::AccessPoint;
|
||||||
|
|
||||||
use super::savedWifiEntry;
|
use super::saved_wifi_entry;
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[derive(Default, CompositeTemplate)]
|
#[derive(Default, CompositeTemplate)]
|
||||||
|
@ -20,8 +20,8 @@ pub struct SavedWifiEntry {
|
||||||
pub resetEditSavedWifiButton: TemplateChild<Button>,
|
pub resetEditSavedWifiButton: TemplateChild<Button>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub resetSavedWifiLabel: TemplateChild<Label>,
|
pub resetSavedWifiLabel: TemplateChild<Label>,
|
||||||
pub resetConnectionPath: RefCell<Path<'static>>,
|
pub reset_connection_path: RefCell<Path<'static>>,
|
||||||
pub accessPoint: RefCell<AccessPoint>,
|
pub access_point: RefCell<AccessPoint>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for SavedWifiEntry {}
|
unsafe impl Send for SavedWifiEntry {}
|
||||||
|
@ -31,7 +31,7 @@ unsafe impl Sync for SavedWifiEntry {}
|
||||||
impl ObjectSubclass for SavedWifiEntry {
|
impl ObjectSubclass for SavedWifiEntry {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetSavedWifiEntry";
|
const NAME: &'static str = "resetSavedWifiEntry";
|
||||||
type Type = savedWifiEntry::SavedWifiEntry;
|
type Type = saved_wifi_entry::SavedWifiEntry;
|
||||||
type ParentType = ActionRow;
|
type ParentType = ActionRow;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
|
@ -16,7 +16,7 @@ pub enum IpProtocol {
|
||||||
type ResultType =
|
type ResultType =
|
||||||
Result<(HashMap<String, HashMap<String, dbus::arg::Variant<Box<dyn RefArg>>>>,), Error>;
|
Result<(HashMap<String, HashMap<String, dbus::arg::Variant<Box<dyn RefArg>>>>,), Error>;
|
||||||
|
|
||||||
pub fn getConnectionSettings(path: Path<'static>) -> ResetConnection {
|
pub fn get_connection_settings(path: Path<'static>) -> ResetConnection {
|
||||||
let conn = Connection::new_session().unwrap();
|
let conn = Connection::new_session().unwrap();
|
||||||
let proxy = conn.with_proxy(
|
let proxy = conn.with_proxy(
|
||||||
"org.Xetibo.ReSetDaemon",
|
"org.Xetibo.ReSetDaemon",
|
||||||
|
|
|
@ -1,160 +0,0 @@
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
|
||||||
use std::rc::Rc;
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use adw::glib;
|
|
||||||
use adw::glib::Object;
|
|
||||||
use adw::prelude::PreferencesRowExt;
|
|
||||||
use glib::clone;
|
|
||||||
use glib::subclass::prelude::ObjectSubclassIsExt;
|
|
||||||
use gtk::prelude::{ButtonExt, EditableExt, WidgetExt};
|
|
||||||
use ReSet_Lib::network::connection::{Address, Connection};
|
|
||||||
|
|
||||||
use crate::components::wifi::utils::IpProtocol;
|
|
||||||
use crate::components::wifi::wifiAddressEntryImpl;
|
|
||||||
use crate::components::wifi::wifiAddressEntryImpl::WifiAddressEntryImpl;
|
|
||||||
|
|
||||||
glib::wrapper! {
|
|
||||||
pub struct WifiAddressEntry(ObjectSubclass<wifiAddressEntryImpl::WifiAddressEntryImpl>)
|
|
||||||
@extends gtk::Box, gtk::Widget,
|
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WifiAddressEntry {
|
|
||||||
pub fn new(
|
|
||||||
address: Option<usize>,
|
|
||||||
conn: Rc<RefCell<Connection>>,
|
|
||||||
protocol: IpProtocol,
|
|
||||||
) -> Self {
|
|
||||||
let entry: WifiAddressEntry = Object::builder().build();
|
|
||||||
let entryImp = entry.imp();
|
|
||||||
|
|
||||||
if let Some(address) = address {
|
|
||||||
let conn = conn.borrow();
|
|
||||||
let address = unsafe { conn.ipv4.address_data.get_unchecked(address) };
|
|
||||||
|
|
||||||
entryImp.resetAddressAddress.set_text(&address.address);
|
|
||||||
entryImp
|
|
||||||
.resetAddressPrefix
|
|
||||||
.set_text(&address.prefix_length.to_string());
|
|
||||||
entryImp
|
|
||||||
.resetAddressRow
|
|
||||||
.set_title(&format!("{}/{}", &*address.address, address.prefix_length));
|
|
||||||
}
|
|
||||||
entryImp.protocol.set(protocol);
|
|
||||||
entry.setupCallbacks(conn);
|
|
||||||
entry
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn setupCallbacks(&self, connection: Rc<RefCell<Connection>>) {
|
|
||||||
let selfImp = self.imp();
|
|
||||||
|
|
||||||
let conn = connection.clone();
|
|
||||||
selfImp.resetAddressAddress.connect_changed(clone!(@weak selfImp => move |entry| {
|
|
||||||
let addressInput = entry.text();
|
|
||||||
let mut conn = conn.borrow_mut();
|
|
||||||
|
|
||||||
if addressInput.is_empty() {
|
|
||||||
selfImp.resetAddressAddress.remove_css_class("error");
|
|
||||||
selfImp.resetAddressRow.set_title("Add new address");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let result = match selfImp.protocol.get() {
|
|
||||||
IpProtocol::IPv4 => Ipv4Addr::from_str(addressInput.as_str()).map(IpAddr::V4),
|
|
||||||
IpProtocol::IPv6 => Ipv6Addr::from_str(addressInput.as_str()).map(IpAddr::V6),
|
|
||||||
};
|
|
||||||
match result {
|
|
||||||
Ok(ipAddr) => {
|
|
||||||
selfImp.resetAddressAddress.remove_css_class("error");
|
|
||||||
let addressData = match selfImp.protocol.get() {
|
|
||||||
IpProtocol::IPv4 => &mut conn.ipv4.address_data,
|
|
||||||
IpProtocol::IPv6 => &mut conn.ipv6.address_data,
|
|
||||||
};
|
|
||||||
addressData.push(Address::theBetterNew(ipAddr.to_string(), selfImp.prefix.get().1 as u32));
|
|
||||||
*selfImp.address.borrow_mut() = (true, ipAddr.to_string());
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
selfImp.resetAddressAddress.add_css_class("error");
|
|
||||||
*selfImp.address.borrow_mut() = (false, String::default());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setRowName(&selfImp);
|
|
||||||
}));
|
|
||||||
|
|
||||||
let conn = connection.clone();
|
|
||||||
selfImp.resetAddressPrefix.connect_changed(clone!(@weak selfImp => move |entry| {
|
|
||||||
let prefixInput = entry.text();
|
|
||||||
let prefix = prefixInput.parse::<u8>();
|
|
||||||
let mut conn = conn.borrow_mut();
|
|
||||||
|
|
||||||
let handleError = || {
|
|
||||||
if selfImp.resetAddressPrefix.text().is_empty() {
|
|
||||||
selfImp.resetAddressPrefix.remove_css_class("error");
|
|
||||||
} else {
|
|
||||||
selfImp.resetAddressPrefix.add_css_class("error");
|
|
||||||
}
|
|
||||||
selfImp.prefix.set((false, 0));
|
|
||||||
setRowName(&selfImp);
|
|
||||||
};
|
|
||||||
|
|
||||||
if prefixInput.is_empty() || prefix.is_err() {
|
|
||||||
handleError();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let prefix = prefix.unwrap();
|
|
||||||
match selfImp.protocol.get() {
|
|
||||||
IpProtocol::IPv4 if prefix <= 32 => {
|
|
||||||
selfImp.prefix.set((true, prefix as u32));
|
|
||||||
selfImp.resetAddressPrefix.remove_css_class("error");
|
|
||||||
if let Ok(address2) = Ipv4Addr::from_str(selfImp.resetAddressAddress.text().as_str()) {
|
|
||||||
if let Some(addr) = conn.ipv4.address_data.iter_mut()
|
|
||||||
.find(|connAddr| *connAddr.address == address2.to_string()) {
|
|
||||||
addr.prefix_length = prefix as u32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IpProtocol::IPv6 if prefix <= 128 => {
|
|
||||||
selfImp.prefix.set((true, prefix as u32));
|
|
||||||
selfImp.resetAddressPrefix.remove_css_class("error");
|
|
||||||
if let Ok(address2) = Ipv6Addr::from_str(selfImp.resetAddressAddress.text().as_str()) {
|
|
||||||
if let Some(addr) = conn.ipv6.address_data.iter_mut()
|
|
||||||
.find(|connAddr| *connAddr.address == address2.to_string()) {
|
|
||||||
addr.prefix_length = prefix as u32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => handleError()
|
|
||||||
}
|
|
||||||
setRowName(&selfImp);
|
|
||||||
}));
|
|
||||||
|
|
||||||
let conn = connection.clone();
|
|
||||||
selfImp.resetAddressRemove.connect_clicked(
|
|
||||||
clone!(@weak selfImp, @weak self as what => move |_| {
|
|
||||||
let address = selfImp.resetAddressAddress.text();
|
|
||||||
let mut conn = conn.borrow_mut();
|
|
||||||
conn.ipv4.address_data.retain(|addr| addr.address != address);
|
|
||||||
what.unparent();
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setRowName(selfImp: &WifiAddressEntryImpl) {
|
|
||||||
if selfImp.resetAddressAddress.text().is_empty() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let address = selfImp.address.borrow();
|
|
||||||
let prefix = selfImp.prefix.get();
|
|
||||||
let title = match (address.0, prefix.0) {
|
|
||||||
(true, true) => {
|
|
||||||
format!("{}/{}", address.1, prefix.1)
|
|
||||||
}
|
|
||||||
(true, false) => "Prefix wrong".to_string(),
|
|
||||||
(false, true) => "Address wrong".to_string(),
|
|
||||||
(false, false) => "Address and Prefix wrong".to_string(),
|
|
||||||
};
|
|
||||||
selfImp.resetAddressRow.set_title(&title);
|
|
||||||
}
|
|
|
@ -1,342 +0,0 @@
|
||||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
|
||||||
use std::str::FromStr;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use adw::{gio, glib};
|
|
||||||
use adw::glib::Object;
|
|
||||||
use adw::prelude::{ActionRowExt, ComboRowExt, PreferencesGroupExt};
|
|
||||||
use adw::subclass::prelude::ObjectSubclassIsExt;
|
|
||||||
use dbus::{Error, Path};
|
|
||||||
use dbus::arg::PropMap;
|
|
||||||
use glib::{clone, PropertySet};
|
|
||||||
use gtk::prelude::{ButtonExt, EditableExt, WidgetExt};
|
|
||||||
use ReSet_Lib::network::connection::{Connection, DNSMethod4, DNSMethod6, Enum, TypeSettings};
|
|
||||||
use IpProtocol::{IPv4, IPv6};
|
|
||||||
|
|
||||||
use crate::components::wifi::utils::IpProtocol;
|
|
||||||
use crate::components::wifi::wifiAddressEntry::WifiAddressEntry;
|
|
||||||
use crate::components::wifi::wifiOptionsImpl;
|
|
||||||
use crate::components::wifi::wifiRouteEntry::WifiRouteEntry;
|
|
||||||
|
|
||||||
glib::wrapper! {
|
|
||||||
pub struct WifiOptions(ObjectSubclass<wifiOptionsImpl::WifiOptions>)
|
|
||||||
@extends adw::NavigationPage, gtk::Widget,
|
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Send for WifiOptions {}
|
|
||||||
unsafe impl Sync for WifiOptions {}
|
|
||||||
|
|
||||||
impl WifiOptions {
|
|
||||||
pub fn new(connection: Connection, accessPoint: Path<'static>) -> Arc<Self> {
|
|
||||||
let wifiOption: Arc<WifiOptions> = Arc::new(Object::builder().build());
|
|
||||||
wifiOption.imp().connection.set(connection);
|
|
||||||
wifiOption.initializeUI();
|
|
||||||
setupCallbacks(&wifiOption, accessPoint);
|
|
||||||
wifiOption
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn initializeUI(&self) {
|
|
||||||
let selfImp = self.imp();
|
|
||||||
let ip4AddressLength;
|
|
||||||
let ip4RouteLength;
|
|
||||||
let ip6AddressLength;
|
|
||||||
let ip6RouteLength;
|
|
||||||
{
|
|
||||||
let conn = selfImp.connection.borrow();
|
|
||||||
ip4AddressLength = conn.ipv4.address_data.len();
|
|
||||||
ip4RouteLength = conn.ipv4.route_data.len();
|
|
||||||
ip6AddressLength = conn.ipv4.address_data.len();
|
|
||||||
ip6RouteLength = conn.ipv4.route_data.len();
|
|
||||||
|
|
||||||
// General
|
|
||||||
selfImp.resetWifiAutoConnect.set_active(conn.settings.autoconnect);
|
|
||||||
selfImp.resetWifiMetered.set_active(conn.settings.metered != -1);
|
|
||||||
match &conn.device {
|
|
||||||
TypeSettings::WIFI(wifi) => {
|
|
||||||
selfImp.resetWifiLinkSpeed.set_visible(false);
|
|
||||||
selfImp.resetWifiIP4Addr.set_visible(false);
|
|
||||||
selfImp.resetWifiIP6Addr.set_visible(false);
|
|
||||||
selfImp.resetWifiDNS.set_visible(false);
|
|
||||||
selfImp.resetWifiGateway.set_visible(false);
|
|
||||||
selfImp.resetWifiLastUsed.set_visible(true);
|
|
||||||
selfImp.resetWifiMac.set_subtitle(&*wifi.cloned_mac_address);
|
|
||||||
selfImp.resetWifiName.set_subtitle(&*String::from_utf8(wifi.ssid.clone())
|
|
||||||
.unwrap_or(String::default()));
|
|
||||||
}
|
|
||||||
TypeSettings::ETHERNET(ethernet) => {
|
|
||||||
selfImp.resetWifiLinkSpeed.set_visible(true);
|
|
||||||
selfImp.resetWifiIP4Addr.set_visible(true);
|
|
||||||
selfImp.resetWifiIP6Addr.set_visible(true);
|
|
||||||
selfImp.resetWifiDNS.set_visible(true);
|
|
||||||
selfImp.resetWifiGateway.set_visible(true);
|
|
||||||
selfImp.resetWifiLastUsed.set_visible(false);
|
|
||||||
selfImp.resetWifiMac.set_subtitle(&*ethernet.cloned_mac_address);
|
|
||||||
selfImp.resetWifiLinkSpeed.set_subtitle(&*ethernet.speed.to_string());
|
|
||||||
}
|
|
||||||
TypeSettings::VPN(_vpn) => {}
|
|
||||||
TypeSettings::None => {}
|
|
||||||
};
|
|
||||||
// IPv4
|
|
||||||
selfImp.resetIP4Method.set_selected(conn.ipv4.dns_method.to_i32() as u32);
|
|
||||||
self.setIP4Visibility(conn.ipv4.dns_method.to_i32() as u32);
|
|
||||||
|
|
||||||
let ipv4Dns: Vec<String> = conn.ipv4.dns.iter().map(|addr| {
|
|
||||||
addr.iter().map(|octet| octet.to_string()).collect::<Vec<String>>().join(".")
|
|
||||||
}).collect();
|
|
||||||
selfImp.resetIP4DNS.set_text(&ipv4Dns.join(", "));
|
|
||||||
selfImp.resetIP4Gateway.set_text(&conn.ipv4.gateway);
|
|
||||||
// IPv6
|
|
||||||
selfImp.resetIP6Method.set_selected(conn.ipv6.dns_method.to_i32() as u32);
|
|
||||||
self.setIP6Visibility(conn.ipv6.dns_method.to_i32() as u32);
|
|
||||||
|
|
||||||
let ipv6Dns: Vec<String> = conn.ipv6.dns.iter().map(|addr| {
|
|
||||||
addr.iter().map(|octet| octet.to_string()).collect::<Vec<String>>().join(":")
|
|
||||||
}).collect();
|
|
||||||
selfImp.resetIP6DNS.set_text(&ipv6Dns.join(", "));
|
|
||||||
selfImp.resetIP6Gateway.set_text(&conn.ipv6.gateway);
|
|
||||||
|
|
||||||
// Security
|
|
||||||
if let TypeSettings::WIFI(wifi) = &conn.device {
|
|
||||||
match wifi.security_settings.key_management.as_str() {
|
|
||||||
"none" => {
|
|
||||||
selfImp.resetWifiSecurityDropdown.set_selected(0);
|
|
||||||
selfImp.resetWifiPassword.set_visible(false);
|
|
||||||
selfImp.resetWifiPassword.set_text("");
|
|
||||||
}
|
|
||||||
"wpa-psk" => {
|
|
||||||
selfImp.resetWifiSecurityDropdown.set_selected(1);
|
|
||||||
selfImp.resetWifiPassword.set_visible(true);
|
|
||||||
selfImp.resetWifiPassword.set_text(&wifi.security_settings.psk);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// IPv4
|
|
||||||
for i in 0..ip4AddressLength {
|
|
||||||
let address = &WifiAddressEntry::new(Some(i), selfImp.connection.clone(), IPv4);
|
|
||||||
selfImp.resetIP4AddressGroup.add(address);
|
|
||||||
}
|
|
||||||
let address = &WifiAddressEntry::new(None, selfImp.connection.clone(), IPv4);
|
|
||||||
selfImp.resetIP4AddressGroup.add(address);
|
|
||||||
|
|
||||||
for i in 0..ip4RouteLength {
|
|
||||||
let route = &WifiRouteEntry::new(Some(i), selfImp.connection.clone(), IPv4);
|
|
||||||
selfImp.resetIP4RoutesGroup.add(route)
|
|
||||||
}
|
|
||||||
let route = &WifiRouteEntry::new(None, selfImp.connection.clone(), IPv4);
|
|
||||||
selfImp.resetIP4RoutesGroup.add(route);
|
|
||||||
|
|
||||||
// IPv6
|
|
||||||
for i in 0..ip6AddressLength {
|
|
||||||
let address = &WifiAddressEntry::new(Some(i), selfImp.connection.clone(), IPv6);
|
|
||||||
selfImp.resetIP6AddressGroup.add(address);
|
|
||||||
}
|
|
||||||
let address = &WifiAddressEntry::new(None, selfImp.connection.clone(), IPv6);
|
|
||||||
selfImp.resetIP6AddressGroup.add(address);
|
|
||||||
|
|
||||||
for i in 0..ip6RouteLength {
|
|
||||||
let route = &WifiRouteEntry::new(Some(i), selfImp.connection.clone(), IPv6);
|
|
||||||
selfImp.resetIP6RoutesGroup.add(route);
|
|
||||||
}
|
|
||||||
let route = &WifiRouteEntry::new(None, selfImp.connection.clone(), IPv6);
|
|
||||||
selfImp.resetIP6RoutesGroup.add(route);
|
|
||||||
// Security
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn setIP4Visibility(&self, method: u32) {
|
|
||||||
let selfImp = self.imp();
|
|
||||||
match method {
|
|
||||||
0 => { // auto
|
|
||||||
selfImp.resetIP4AddressGroup.set_visible(false);
|
|
||||||
selfImp.resetIP4RoutesGroup.set_visible(true);
|
|
||||||
selfImp.resetIP4Gateway.set_visible(false);
|
|
||||||
}
|
|
||||||
1 => { // manual
|
|
||||||
selfImp.resetIP4AddressGroup.set_visible(true);
|
|
||||||
selfImp.resetIP4RoutesGroup.set_visible(true);
|
|
||||||
selfImp.resetIP4Gateway.set_visible(true);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
selfImp.resetIP4AddressGroup.set_visible(false);
|
|
||||||
selfImp.resetIP4RoutesGroup.set_visible(false);
|
|
||||||
selfImp.resetIP4Gateway.set_visible(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn setIP6Visibility(&self, method: u32) {
|
|
||||||
let selfImp = self.imp();
|
|
||||||
match method {
|
|
||||||
0 | 1 => { // auto, dhcp
|
|
||||||
selfImp.resetIP6AddressGroup.set_visible(false);
|
|
||||||
selfImp.resetIP6RoutesGroup.set_visible(true);
|
|
||||||
selfImp.resetIP6Gateway.set_visible(false);
|
|
||||||
}
|
|
||||||
2 => { // manual
|
|
||||||
selfImp.resetIP6AddressGroup.set_visible(true);
|
|
||||||
selfImp.resetIP6RoutesGroup.set_visible(true);
|
|
||||||
selfImp.resetIP6Gateway.set_visible(true);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
selfImp.resetIP6AddressGroup.set_visible(false);
|
|
||||||
selfImp.resetIP6RoutesGroup.set_visible(false);
|
|
||||||
selfImp.resetIP6Gateway.set_visible(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setupCallbacks(wifiOptions: &Arc<WifiOptions>, path: Path<'static>) {
|
|
||||||
let imp = wifiOptions.imp();
|
|
||||||
|
|
||||||
// General
|
|
||||||
imp.resetWifiAutoConnect.connect_active_notify(clone!(@weak imp => move |x| {
|
|
||||||
imp.connection.borrow_mut().settings.autoconnect = x.is_active();
|
|
||||||
}));
|
|
||||||
imp.resetWifiMetered.connect_active_notify(clone!(@weak imp => move |x| {
|
|
||||||
imp.connection.borrow_mut().settings.metered = if x.is_active() { 1 } else { 2 };
|
|
||||||
}));
|
|
||||||
imp.wifiOptionsApplyButton.connect_clicked(clone!(@weak imp => move |_| {
|
|
||||||
let prop = imp.connection.borrow().convert_to_propmap();
|
|
||||||
setConnectionSettings(path.clone(), prop);
|
|
||||||
}));
|
|
||||||
// IPv4
|
|
||||||
let wifiOptionsIP4 = wifiOptions.clone();
|
|
||||||
imp.resetIP4Method.connect_selected_notify(clone!(@weak imp => move |dropdown| {
|
|
||||||
let selected = dropdown.selected();
|
|
||||||
let mut conn = imp.connection.borrow_mut();
|
|
||||||
conn.ipv4.dns_method = DNSMethod4::from_i32(selected as i32);
|
|
||||||
wifiOptionsIP4.setIP4Visibility(selected);
|
|
||||||
}));
|
|
||||||
|
|
||||||
imp.resetIP4DNS.connect_changed(clone!(@weak imp => move |entry| {
|
|
||||||
let dnsInput = entry.text();
|
|
||||||
let mut conn = imp.connection.borrow_mut();
|
|
||||||
conn.ipv4.dns.clear();
|
|
||||||
if dnsInput.is_empty() {
|
|
||||||
imp.resetIP4DNS.remove_css_class("error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for dnsEntry in dnsInput.as_str().split(',').map(|s| s.trim()) {
|
|
||||||
if let Ok(addr) = Ipv4Addr::from_str(dnsEntry) {
|
|
||||||
imp.resetIP4DNS.remove_css_class("error");
|
|
||||||
conn.ipv4.dns.push(addr.octets().to_vec());
|
|
||||||
} else {
|
|
||||||
imp.resetIP4DNS.add_css_class("error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
imp.resetIP4AddressAddButton.connect_clicked(clone!(@weak imp => move |_| {
|
|
||||||
let address = &WifiAddressEntry::new(None, imp.connection.clone(), IpProtocol::IPv4);
|
|
||||||
imp.resetIP4AddressGroup.add(address);
|
|
||||||
}));
|
|
||||||
|
|
||||||
imp.resetIP4Gateway.connect_changed(clone!(@weak imp => move |entry| {
|
|
||||||
let gatewayInput = entry.text();
|
|
||||||
let mut conn = imp.connection.borrow_mut();
|
|
||||||
conn.ipv4.gateway.clear();
|
|
||||||
if gatewayInput.is_empty() {
|
|
||||||
imp.resetIP4Gateway.remove_css_class("error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if let Ok(_) = Ipv4Addr::from_str(gatewayInput.as_str()) {
|
|
||||||
imp.resetIP4Gateway.remove_css_class("error");
|
|
||||||
conn.ipv4.gateway = gatewayInput.to_string();
|
|
||||||
} else {
|
|
||||||
imp.resetIP4Gateway.add_css_class("error");
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
// IPv6
|
|
||||||
let wifiOptionsIP6 = wifiOptions.clone();
|
|
||||||
imp.resetIP6Method.connect_selected_notify(clone!(@weak imp => move |dropdown| {
|
|
||||||
let selected = dropdown.selected();
|
|
||||||
let mut conn = imp.connection.borrow_mut();
|
|
||||||
conn.ipv6.dns_method = DNSMethod6::from_i32(selected as i32);
|
|
||||||
wifiOptionsIP6.setIP6Visibility(selected);
|
|
||||||
}));
|
|
||||||
|
|
||||||
imp.resetIP6DNS.connect_changed(clone!(@weak imp => move |entry| {
|
|
||||||
let dnsInput = entry.text();
|
|
||||||
let mut conn = imp.connection.borrow_mut();
|
|
||||||
conn.ipv6.dns.clear();
|
|
||||||
if dnsInput.is_empty() {
|
|
||||||
imp.resetIP6DNS.remove_css_class("error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for dnsEntry in dnsInput.as_str().split(',').map(|s| s.trim()) {
|
|
||||||
if let Ok(addr) = Ipv6Addr::from_str(dnsEntry) {
|
|
||||||
imp.resetIP6DNS.remove_css_class("error");
|
|
||||||
conn.ipv6.dns.push(addr.octets().to_vec());
|
|
||||||
} else {
|
|
||||||
imp.resetIP6DNS.add_css_class("error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
imp.resetIP6AddressAddButton.connect_clicked(clone!(@weak imp => move |_| {
|
|
||||||
let address = &WifiAddressEntry::new(None, imp.connection.clone(), IpProtocol::IPv4);
|
|
||||||
imp.resetIP6AddressGroup.add(address);
|
|
||||||
}));
|
|
||||||
|
|
||||||
imp.resetIP6Gateway.connect_changed(clone!(@weak imp => move |entry| {
|
|
||||||
let gatewayInput = entry.text();
|
|
||||||
let mut conn = imp.connection.borrow_mut();
|
|
||||||
conn.ipv6.gateway.clear();
|
|
||||||
if gatewayInput.is_empty() {
|
|
||||||
imp.resetIP6Gateway.remove_css_class("error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if let Ok(_) = Ipv6Addr::from_str(gatewayInput.as_str()) {
|
|
||||||
imp.resetIP6Gateway.remove_css_class("error");
|
|
||||||
conn.ipv6.gateway = gatewayInput.to_string();
|
|
||||||
} else {
|
|
||||||
imp.resetIP6Gateway.add_css_class("error");
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Security
|
|
||||||
imp.resetWifiSecurityDropdown.connect_selected_notify(clone!(@weak imp => move |dropdown| {
|
|
||||||
let selected = dropdown.selected();
|
|
||||||
let mut conn = imp.connection.borrow_mut();
|
|
||||||
|
|
||||||
match (selected, &mut conn.device) {
|
|
||||||
(0 , TypeSettings::WIFI(wifi)) => { // None
|
|
||||||
imp.resetWifiPassword.set_visible(false);
|
|
||||||
wifi.security_settings.key_management = String::from("none");
|
|
||||||
wifi.security_settings.authentication_algorithm = String::from("open");
|
|
||||||
},
|
|
||||||
(1 , TypeSettings::WIFI(wifi)) => { // WPA/WPA2 Personal
|
|
||||||
imp.resetWifiPassword.set_visible(true);
|
|
||||||
wifi.security_settings.key_management = String::from("wpa-psk");
|
|
||||||
wifi.security_settings.authentication_algorithm = String::from("");
|
|
||||||
},
|
|
||||||
(_, _) => {}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
imp.resetWifiPassword.connect_changed(clone!(@weak imp => move |entry| {
|
|
||||||
let passwordInput = entry.text();
|
|
||||||
let mut conn = imp.connection.borrow_mut();
|
|
||||||
if let TypeSettings::WIFI(wifi) = &mut conn.device {
|
|
||||||
wifi.security_settings.psk = passwordInput.to_string();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setConnectionSettings(path: Path<'static>, prop: PropMap) {
|
|
||||||
gio::spawn_blocking(move || {
|
|
||||||
let conn = dbus::blocking::Connection::new_session().unwrap();
|
|
||||||
let proxy = conn.with_proxy(
|
|
||||||
"org.Xetibo.ReSetDaemon",
|
|
||||||
"/org/Xetibo/ReSetDaemon",
|
|
||||||
Duration::from_millis(1000),
|
|
||||||
);
|
|
||||||
let _: Result<(bool,), Error> = proxy.method_call(
|
|
||||||
"org.Xetibo.ReSetWireless",
|
|
||||||
"SetConnectionSettings",
|
|
||||||
(path, prop),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,242 +0,0 @@
|
||||||
use crate::components::wifi::utils::IpProtocol;
|
|
||||||
use adw::glib;
|
|
||||||
use adw::glib::Object;
|
|
||||||
use adw::prelude::{ExpanderRowExt, PreferencesRowExt};
|
|
||||||
use glib::clone;
|
|
||||||
use glib::subclass::prelude::ObjectSubclassIsExt;
|
|
||||||
use gtk::prelude::{EditableExt, WidgetExt};
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
|
||||||
use std::rc::Rc;
|
|
||||||
use std::str::FromStr;
|
|
||||||
use ReSet_Lib::network::connection::{Address, Connection};
|
|
||||||
|
|
||||||
use crate::components::wifi::wifiRouteEntryImpl;
|
|
||||||
use crate::components::wifi::wifiRouteEntryImpl::WifiRouteEntryImpl;
|
|
||||||
|
|
||||||
glib::wrapper! {
|
|
||||||
pub struct WifiRouteEntry(ObjectSubclass<wifiRouteEntryImpl::WifiRouteEntryImpl>)
|
|
||||||
@extends gtk::Box, gtk::Widget,
|
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WifiRouteEntry {
|
|
||||||
pub fn new(
|
|
||||||
address: Option<usize>,
|
|
||||||
conn: Rc<RefCell<Connection>>,
|
|
||||||
protocol: IpProtocol,
|
|
||||||
) -> Self {
|
|
||||||
let entry: WifiRouteEntry = Object::builder().build();
|
|
||||||
let entryImp = entry.imp();
|
|
||||||
|
|
||||||
if let Some(address) = address {
|
|
||||||
let conn = conn.borrow();
|
|
||||||
let address = unsafe { conn.ipv4.route_data.get_unchecked(address) };
|
|
||||||
|
|
||||||
entryImp.resetRouteAddress.set_text(&address.address);
|
|
||||||
entryImp
|
|
||||||
.resetRoutePrefix
|
|
||||||
.set_text(&address.prefix_length.to_string());
|
|
||||||
if let Some(gateway) = &address.gateway {
|
|
||||||
entryImp.resetRouteGateway.set_text(gateway);
|
|
||||||
}
|
|
||||||
if let Some(metric) = address.metric {
|
|
||||||
entryImp.resetRouteMetric.set_text(&metric.to_string());
|
|
||||||
}
|
|
||||||
entryImp
|
|
||||||
.resetRouteRow
|
|
||||||
.set_title(&format!("{}/{}", &*address.address, address.prefix_length));
|
|
||||||
}
|
|
||||||
entryImp.protocol.set(protocol);
|
|
||||||
entry.setupCallbacks(conn);
|
|
||||||
entry
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setupCallbacks(&self, connection: Rc<RefCell<Connection>>) {
|
|
||||||
let selfImp = self.imp();
|
|
||||||
|
|
||||||
let conn = connection.clone();
|
|
||||||
selfImp.resetRouteAddress.connect_changed(clone!(@weak selfImp => move |entry| {
|
|
||||||
let addressInput = entry.text();
|
|
||||||
let mut conn = conn.borrow_mut();
|
|
||||||
|
|
||||||
if addressInput.is_empty() {
|
|
||||||
selfImp.resetRouteAddress.remove_css_class("error");
|
|
||||||
selfImp.resetRouteRow.set_title("Add new address");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let result = match selfImp.protocol.get() {
|
|
||||||
IpProtocol::IPv4 => Ipv4Addr::from_str(addressInput.as_str()).map(IpAddr::V4),
|
|
||||||
IpProtocol::IPv6 => Ipv6Addr::from_str(addressInput.as_str()).map(IpAddr::V6),
|
|
||||||
};
|
|
||||||
match result {
|
|
||||||
Ok(ipAddr) => {
|
|
||||||
selfImp.resetRouteAddress.remove_css_class("error");
|
|
||||||
let addressData = match selfImp.protocol.get() {
|
|
||||||
IpProtocol::IPv4 => &mut conn.ipv4.route_data,
|
|
||||||
IpProtocol::IPv6 => &mut conn.ipv6.route_data,
|
|
||||||
};
|
|
||||||
addressData.push(Address::new(ipAddr.to_string(), selfImp.prefix.get().1 as u32, selfImp.gateway.borrow().clone(), selfImp.metric.get()));
|
|
||||||
*selfImp.address.borrow_mut() = (true, ipAddr.to_string());
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
selfImp.resetRouteAddress.add_css_class("error");
|
|
||||||
*selfImp.address.borrow_mut() = (false, String::default());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setRowTitle(&selfImp);
|
|
||||||
}));
|
|
||||||
|
|
||||||
let conn = connection.clone();
|
|
||||||
selfImp.resetRoutePrefix.connect_changed(clone!(@weak selfImp => move |entry| {
|
|
||||||
let prefixInput = entry.text();
|
|
||||||
let prefix = prefixInput.parse::<u8>();
|
|
||||||
let mut conn = conn.borrow_mut();
|
|
||||||
|
|
||||||
let handleError = || {
|
|
||||||
if selfImp.resetRoutePrefix.text().is_empty() {
|
|
||||||
selfImp.resetRoutePrefix.remove_css_class("error");
|
|
||||||
} else {
|
|
||||||
selfImp.resetRoutePrefix.add_css_class("error");
|
|
||||||
}
|
|
||||||
selfImp.prefix.set((false, 0));
|
|
||||||
setRowTitle(&selfImp);
|
|
||||||
};
|
|
||||||
|
|
||||||
if prefixInput.is_empty() || prefix.is_err() {
|
|
||||||
handleError();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let prefix = prefix.unwrap();
|
|
||||||
match selfImp.protocol.get() {
|
|
||||||
IpProtocol::IPv4 if prefix <= 32 => {
|
|
||||||
selfImp.prefix.set((true, prefix as u32));
|
|
||||||
selfImp.resetRoutePrefix.remove_css_class("error");
|
|
||||||
if let Ok(address2) = Ipv4Addr::from_str(selfImp.resetRouteAddress.text().as_str()) {
|
|
||||||
if let Some(addr) = conn.ipv4.route_data.iter_mut()
|
|
||||||
.find(|connAddr| *connAddr.address == address2.to_string()) {
|
|
||||||
addr.prefix_length = prefix as u32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IpProtocol::IPv6 if prefix <= 128 => {
|
|
||||||
selfImp.prefix.set((true, prefix as u32));
|
|
||||||
selfImp.resetRoutePrefix.remove_css_class("error");
|
|
||||||
if let Ok(address2) = Ipv6Addr::from_str(selfImp.resetRouteAddress.text().as_str()) {
|
|
||||||
if let Some(addr) = conn.ipv6.route_data.iter_mut()
|
|
||||||
.find(|connAddr| *connAddr.address == address2.to_string()) {
|
|
||||||
addr.prefix_length = prefix as u32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => handleError()
|
|
||||||
}
|
|
||||||
setRowTitle(&selfImp);
|
|
||||||
}));
|
|
||||||
|
|
||||||
let conn = connection.clone();
|
|
||||||
selfImp
|
|
||||||
.resetRouteGateway
|
|
||||||
.connect_changed(clone!(@weak selfImp => move |entry| {
|
|
||||||
let gatewayInput = entry.text();
|
|
||||||
let mut conn = conn.borrow_mut();
|
|
||||||
|
|
||||||
if gatewayInput.is_empty() {
|
|
||||||
selfImp.resetRouteGateway.remove_css_class("error");
|
|
||||||
*selfImp.gateway.borrow_mut() = None;
|
|
||||||
setRowSubtitle(&selfImp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let result = match selfImp.protocol.get() {
|
|
||||||
IpProtocol::IPv4 => Ipv4Addr::from_str(gatewayInput.as_str()).map(IpAddr::V4),
|
|
||||||
IpProtocol::IPv6 => Ipv6Addr::from_str(gatewayInput.as_str()).map(IpAddr::V6),
|
|
||||||
};
|
|
||||||
match result {
|
|
||||||
Ok(ipAddr) => {
|
|
||||||
selfImp.resetRouteGateway.remove_css_class("error");
|
|
||||||
let addressData = match selfImp.protocol.get() {
|
|
||||||
IpProtocol::IPv4 => &mut conn.ipv4.route_data,
|
|
||||||
IpProtocol::IPv6 => &mut conn.ipv6.route_data,
|
|
||||||
};
|
|
||||||
if let Some(address) = addressData.iter_mut()
|
|
||||||
.find(|connAddr| *connAddr.address == selfImp.resetRouteAddress.text()) {
|
|
||||||
address.gateway = Some(ipAddr.to_string());
|
|
||||||
}
|
|
||||||
*selfImp.gateway.borrow_mut() = Some(ipAddr.to_string());
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
selfImp.resetRouteGateway.add_css_class("error");
|
|
||||||
*selfImp.gateway.borrow_mut() = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setRowSubtitle(&selfImp);
|
|
||||||
}));
|
|
||||||
|
|
||||||
let conn = connection.clone();
|
|
||||||
selfImp
|
|
||||||
.resetRouteMetric
|
|
||||||
.connect_changed(clone!(@weak selfImp => move |entry| {
|
|
||||||
let metricInput = entry.text();
|
|
||||||
let mut conn = conn.borrow_mut();
|
|
||||||
|
|
||||||
if metricInput.is_empty() {
|
|
||||||
selfImp.resetRouteMetric.remove_css_class("error");
|
|
||||||
selfImp.metric.set(None);
|
|
||||||
setRowSubtitle(&selfImp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let result = metricInput.parse::<u32>();
|
|
||||||
match result {
|
|
||||||
Ok(metric) => {
|
|
||||||
selfImp.resetRouteMetric.remove_css_class("error");
|
|
||||||
let addressData = match selfImp.protocol.get() {
|
|
||||||
IpProtocol::IPv4 => &mut conn.ipv4.route_data,
|
|
||||||
IpProtocol::IPv6 => &mut conn.ipv6.route_data,
|
|
||||||
};
|
|
||||||
if let Some(address) = addressData.iter_mut()
|
|
||||||
.find(|connAddr| *connAddr.address == selfImp.resetRouteAddress.text()) {
|
|
||||||
address.metric = Some(metric);
|
|
||||||
}
|
|
||||||
selfImp.metric.set(Some(metric));
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
selfImp.resetRouteMetric.add_css_class("error");
|
|
||||||
selfImp.metric.set(None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setRowSubtitle(&selfImp);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setRowTitle(selfImp: &WifiRouteEntryImpl) {
|
|
||||||
if selfImp.resetRouteAddress.text().is_empty() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let address = selfImp.address.borrow();
|
|
||||||
let prefix = selfImp.prefix.get();
|
|
||||||
let title = match (address.0, prefix.0) {
|
|
||||||
(true, true) => {
|
|
||||||
format!("{}/{}", address.1, prefix.1)
|
|
||||||
}
|
|
||||||
(true, false) => "Prefix wrong".to_string(),
|
|
||||||
(false, true) => "Address wrong".to_string(),
|
|
||||||
(false, false) => "Address and Prefix wrong".to_string(),
|
|
||||||
};
|
|
||||||
selfImp.resetRouteRow.set_title(&title);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setRowSubtitle(selfImp: &WifiRouteEntryImpl) {
|
|
||||||
let gateway = selfImp.gateway.borrow().clone();
|
|
||||||
let metric = selfImp.metric.get();
|
|
||||||
let title = match (gateway, metric) {
|
|
||||||
(Some(gateway), Some(metric)) => {
|
|
||||||
format!("{}, {}", gateway, metric)
|
|
||||||
}
|
|
||||||
(Some(gateway), None) => gateway,
|
|
||||||
(None, Some(metric)) => metric.to_string(),
|
|
||||||
(None, None) => String::default(),
|
|
||||||
};
|
|
||||||
selfImp.resetRouteRow.set_subtitle(&title);
|
|
||||||
}
|
|
160
src/components/wifi/wifi_address_entry.rs
Normal file
160
src/components/wifi/wifi_address_entry.rs
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use adw::glib;
|
||||||
|
use adw::glib::Object;
|
||||||
|
use adw::prelude::PreferencesRowExt;
|
||||||
|
use glib::clone;
|
||||||
|
use glib::subclass::prelude::ObjectSubclassIsExt;
|
||||||
|
use gtk::prelude::{ButtonExt, EditableExt, WidgetExt};
|
||||||
|
use ReSet_Lib::network::connection::{Address, Connection};
|
||||||
|
|
||||||
|
use crate::components::wifi::utils::IpProtocol;
|
||||||
|
use crate::components::wifi::wifi_address_entry_impl;
|
||||||
|
use crate::components::wifi::wifi_address_entry_impl::WifiAddressEntryImpl;
|
||||||
|
|
||||||
|
glib::wrapper! {
|
||||||
|
pub struct WifiAddressEntry(ObjectSubclass<wifi_address_entry_impl::WifiAddressEntryImpl>)
|
||||||
|
@extends gtk::Box, gtk::Widget,
|
||||||
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WifiAddressEntry {
|
||||||
|
pub fn new(
|
||||||
|
address: Option<usize>,
|
||||||
|
conn: Rc<RefCell<Connection>>,
|
||||||
|
protocol: IpProtocol,
|
||||||
|
) -> Self {
|
||||||
|
let entry: WifiAddressEntry = Object::builder().build();
|
||||||
|
let entry_imp = entry.imp();
|
||||||
|
|
||||||
|
if let Some(address) = address {
|
||||||
|
let conn = conn.borrow();
|
||||||
|
let address = unsafe { conn.ipv4.address_data.get_unchecked(address) };
|
||||||
|
|
||||||
|
entry_imp.resetAddressAddress.set_text(&address.address);
|
||||||
|
entry_imp
|
||||||
|
.resetAddressPrefix
|
||||||
|
.set_text(&address.prefix_length.to_string());
|
||||||
|
entry_imp
|
||||||
|
.resetAddressRow
|
||||||
|
.set_title(&format!("{}/{}", &*address.address, address.prefix_length));
|
||||||
|
}
|
||||||
|
entry_imp.protocol.set(protocol);
|
||||||
|
entry.setup_callbacks(conn);
|
||||||
|
entry
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setup_callbacks(&self, connection: Rc<RefCell<Connection>>) {
|
||||||
|
let self_imp = self.imp();
|
||||||
|
|
||||||
|
let conn = connection.clone();
|
||||||
|
self_imp.resetAddressAddress.connect_changed(clone!(@weak self_imp => move |entry| {
|
||||||
|
let address_input = entry.text();
|
||||||
|
let mut conn = conn.borrow_mut();
|
||||||
|
|
||||||
|
if address_input.is_empty() {
|
||||||
|
self_imp.resetAddressAddress.remove_css_class("error");
|
||||||
|
self_imp.resetAddressRow.set_title("Add new address");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let result = match self_imp.protocol.get() {
|
||||||
|
IpProtocol::IPv4 => Ipv4Addr::from_str(address_input.as_str()).map(IpAddr::V4),
|
||||||
|
IpProtocol::IPv6 => Ipv6Addr::from_str(address_input.as_str()).map(IpAddr::V6),
|
||||||
|
};
|
||||||
|
match result {
|
||||||
|
Ok(ip_addr) => {
|
||||||
|
self_imp.resetAddressAddress.remove_css_class("error");
|
||||||
|
let address_data = match self_imp.protocol.get() {
|
||||||
|
IpProtocol::IPv4 => &mut conn.ipv4.address_data,
|
||||||
|
IpProtocol::IPv6 => &mut conn.ipv6.address_data,
|
||||||
|
};
|
||||||
|
address_data.push(Address::theBetterNew(ip_addr.to_string(), self_imp.prefix.get().1 as u32));
|
||||||
|
*self_imp.address.borrow_mut() = (true, ip_addr.to_string());
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
self_imp.resetAddressAddress.add_css_class("error");
|
||||||
|
*self_imp.address.borrow_mut() = (false, String::default());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_row_name(&self_imp);
|
||||||
|
}));
|
||||||
|
|
||||||
|
let conn = connection.clone();
|
||||||
|
self_imp.resetAddressPrefix.connect_changed(clone!(@weak self_imp => move |entry| {
|
||||||
|
let prefix_input = entry.text();
|
||||||
|
let prefix = prefix_input.parse::<u8>();
|
||||||
|
let mut conn = conn.borrow_mut();
|
||||||
|
|
||||||
|
let handle_error = || {
|
||||||
|
if self_imp.resetAddressPrefix.text().is_empty() {
|
||||||
|
self_imp.resetAddressPrefix.remove_css_class("error");
|
||||||
|
} else {
|
||||||
|
self_imp.resetAddressPrefix.add_css_class("error");
|
||||||
|
}
|
||||||
|
self_imp.prefix.set((false, 0));
|
||||||
|
set_row_name(&self_imp);
|
||||||
|
};
|
||||||
|
|
||||||
|
if prefix_input.is_empty() || prefix.is_err() {
|
||||||
|
handle_error();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let prefix = prefix.unwrap();
|
||||||
|
match self_imp.protocol.get() {
|
||||||
|
IpProtocol::IPv4 if prefix <= 32 => {
|
||||||
|
self_imp.prefix.set((true, prefix as u32));
|
||||||
|
self_imp.resetAddressPrefix.remove_css_class("error");
|
||||||
|
if let Ok(address2) = Ipv4Addr::from_str(self_imp.resetAddressAddress.text().as_str()) {
|
||||||
|
if let Some(addr) = conn.ipv4.address_data.iter_mut()
|
||||||
|
.find(|conn_addr| *conn_addr.address == address2.to_string()) {
|
||||||
|
addr.prefix_length = prefix as u32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IpProtocol::IPv6 if prefix <= 128 => {
|
||||||
|
self_imp.prefix.set((true, prefix as u32));
|
||||||
|
self_imp.resetAddressPrefix.remove_css_class("error");
|
||||||
|
if let Ok(address2) = Ipv6Addr::from_str(self_imp.resetAddressAddress.text().as_str()) {
|
||||||
|
if let Some(addr) = conn.ipv6.address_data.iter_mut()
|
||||||
|
.find(|conn_addr| *conn_addr.address == address2.to_string()) {
|
||||||
|
addr.prefix_length = prefix as u32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => handle_error()
|
||||||
|
}
|
||||||
|
set_row_name(&self_imp);
|
||||||
|
}));
|
||||||
|
|
||||||
|
let conn = connection.clone();
|
||||||
|
self_imp.resetAddressRemove.connect_clicked(
|
||||||
|
clone!(@weak self_imp, @weak self as what => move |_| {
|
||||||
|
let address = self_imp.resetAddressAddress.text();
|
||||||
|
let mut conn = conn.borrow_mut();
|
||||||
|
conn.ipv4.address_data.retain(|addr| addr.address != address);
|
||||||
|
what.unparent();
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_row_name(self_imp: &WifiAddressEntryImpl) {
|
||||||
|
if self_imp.resetAddressAddress.text().is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let address = self_imp.address.borrow();
|
||||||
|
let prefix = self_imp.prefix.get();
|
||||||
|
let title = match (address.0, prefix.0) {
|
||||||
|
(true, true) => {
|
||||||
|
format!("{}/{}", address.1, prefix.1)
|
||||||
|
}
|
||||||
|
(true, false) => "Prefix wrong".to_string(),
|
||||||
|
(false, true) => "Address wrong".to_string(),
|
||||||
|
(false, false) => "Address and Prefix wrong".to_string(),
|
||||||
|
};
|
||||||
|
self_imp.resetAddressRow.set_title(&title);
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::components::wifi::utils::IpProtocol;
|
use crate::components::wifi::utils::IpProtocol;
|
||||||
use crate::components::wifi::wifiAddressEntry;
|
use crate::components::wifi::wifi_address_entry;
|
||||||
use adw::{EntryRow, ExpanderRow};
|
use adw::{EntryRow, ExpanderRow};
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, Button, CompositeTemplate};
|
use gtk::{glib, Button, CompositeTemplate};
|
||||||
|
@ -26,7 +26,7 @@ pub struct WifiAddressEntryImpl {
|
||||||
impl ObjectSubclass for WifiAddressEntryImpl {
|
impl ObjectSubclass for WifiAddressEntryImpl {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetWifiAddressEntry";
|
const NAME: &'static str = "resetWifiAddressEntry";
|
||||||
type Type = wifiAddressEntry::WifiAddressEntry;
|
type Type = wifi_address_entry::WifiAddressEntry;
|
||||||
type ParentType = gtk::Box;
|
type ParentType = gtk::Box;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
|
@ -5,7 +5,7 @@ use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::components::base::utils::Listeners;
|
use crate::components::base::utils::Listeners;
|
||||||
use crate::components::utils::setComboRowEllipsis;
|
use crate::components::utils::set_combo_row_ellipsis;
|
||||||
use adw::glib;
|
use adw::glib;
|
||||||
use adw::glib::Object;
|
use adw::glib::Object;
|
||||||
use adw::prelude::{ComboRowExt, ListBoxRowExt, PreferencesGroupExt};
|
use adw::prelude::{ComboRowExt, ListBoxRowExt, PreferencesGroupExt};
|
||||||
|
@ -16,19 +16,19 @@ use dbus::Error;
|
||||||
use dbus::Path;
|
use dbus::Path;
|
||||||
use glib::{clone, Cast, PropertySet};
|
use glib::{clone, Cast, PropertySet};
|
||||||
use gtk::glib::Variant;
|
use gtk::glib::Variant;
|
||||||
use gtk::prelude::{ActionableExt, WidgetExt, BoxExt};
|
use gtk::prelude::{ActionableExt, WidgetExt};
|
||||||
use gtk::{gio, StringObject};
|
use gtk::{gio, StringObject};
|
||||||
use ReSet_Lib::network::network::{AccessPoint, WifiDevice, WifiStrength};
|
use ReSet_Lib::network::network::{AccessPoint, WifiDevice, WifiStrength};
|
||||||
use ReSet_Lib::signals::{AccessPointAdded, WifiDeviceChanged};
|
use ReSet_Lib::signals::{AccessPointAdded, WifiDeviceChanged};
|
||||||
use ReSet_Lib::signals::{AccessPointChanged, AccessPointRemoved};
|
use ReSet_Lib::signals::{AccessPointChanged, AccessPointRemoved};
|
||||||
|
|
||||||
use crate::components::wifi::wifiBoxImpl;
|
use crate::components::wifi::wifi_box_impl;
|
||||||
use crate::components::wifi::wifiEntry::WifiEntry;
|
use crate::components::wifi::wifi_entry::WifiEntry;
|
||||||
|
|
||||||
use super::savedWifiEntry::SavedWifiEntry;
|
use super::saved_wifi_entry::SavedWifiEntry;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct WifiBox(ObjectSubclass<wifiBoxImpl::WifiBox>)
|
pub struct WifiBox(ObjectSubclass<wifi_box_impl::WifiBox>)
|
||||||
@extends gtk::Box, gtk::Widget,
|
@extends gtk::Box, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||||
}
|
}
|
||||||
|
@ -41,15 +41,15 @@ unsafe impl Sync for WifiBox {}
|
||||||
impl WifiBox {
|
impl WifiBox {
|
||||||
pub fn new(listeners: Arc<Listeners>) -> Arc<Self> {
|
pub fn new(listeners: Arc<Listeners>) -> Arc<Self> {
|
||||||
let obj: Arc<WifiBox> = Arc::new(Object::builder().build());
|
let obj: Arc<WifiBox> = Arc::new(Object::builder().build());
|
||||||
setupCallbacks(listeners, obj)
|
setup_callbacks(listeners, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setupCallbacks(&self) {}
|
pub fn setup_callbacks(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setupCallbacks(listeners: Arc<Listeners>, wifiBox: Arc<WifiBox>) -> Arc<WifiBox> {
|
fn setup_callbacks(listeners: Arc<Listeners>, wifi_box: Arc<WifiBox>) -> Arc<WifiBox> {
|
||||||
let imp = wifiBox.imp();
|
let imp = wifi_box.imp();
|
||||||
let wifibox_ref = wifiBox.clone();
|
let wifibox_ref = wifi_box.clone();
|
||||||
imp.resetSavedNetworks.set_activatable(true);
|
imp.resetSavedNetworks.set_activatable(true);
|
||||||
imp.resetSavedNetworks
|
imp.resetSavedNetworks
|
||||||
.set_action_name(Some("navigation.push"));
|
.set_action_name(Some("navigation.push"));
|
||||||
|
@ -59,44 +59,44 @@ fn setupCallbacks(listeners: Arc<Listeners>, wifiBox: Arc<WifiBox>) -> Arc<WifiB
|
||||||
imp.resetAvailableNetworks.set_activatable(true);
|
imp.resetAvailableNetworks.set_activatable(true);
|
||||||
imp.resetAvailableNetworks
|
imp.resetAvailableNetworks
|
||||||
.set_action_name(Some("navigation.pop"));
|
.set_action_name(Some("navigation.pop"));
|
||||||
setComboRowEllipsis(imp.resetWiFiDevice.get());
|
set_combo_row_ellipsis(imp.resetWiFiDevice.get());
|
||||||
imp.resetWifiSwitch.connect_state_set(
|
imp.resetWifiSwitch.connect_state_set(
|
||||||
clone!(@weak imp => @default-return glib::Propagation::Proceed, move |_, value| {
|
clone!(@weak imp => @default-return glib::Propagation::Proceed, move |_, value| {
|
||||||
set_wifi_enabled(value);
|
set_wifi_enabled(value);
|
||||||
if !value {
|
if !value {
|
||||||
let mut map = imp.wifiEntries.lock().unwrap();
|
let mut map = imp.wifi_entries.lock().unwrap();
|
||||||
for entry in map.iter() {
|
for entry in map.iter() {
|
||||||
imp.resetWifiList.remove(&*(*entry.1));
|
imp.resetWifiList.remove(&*(*entry.1));
|
||||||
}
|
}
|
||||||
map.clear();
|
map.clear();
|
||||||
imp.wifiEntriesPath.lock().unwrap().clear();
|
imp.wifi_entries_path.lock().unwrap().clear();
|
||||||
listeners.network_listener.store(false, Ordering::SeqCst);
|
listeners.network_listener.store(false, Ordering::SeqCst);
|
||||||
} else {
|
} else {
|
||||||
start_event_listener(listeners.clone(), wifibox_ref.clone());
|
start_event_listener(listeners.clone(), wifibox_ref.clone());
|
||||||
show_stored_connections(wifibox_ref.clone());
|
show_stored_connections(wifibox_ref.clone());
|
||||||
scanForWifi(wifibox_ref.clone());
|
scan_for_wifi(wifibox_ref.clone());
|
||||||
}
|
}
|
||||||
glib::Propagation::Proceed
|
glib::Propagation::Proceed
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
wifiBox
|
wifi_box
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scanForWifi(wifiBox: Arc<WifiBox>) {
|
pub fn scan_for_wifi(wifi_box: Arc<WifiBox>) {
|
||||||
let wifibox_ref = wifiBox.clone();
|
let wifibox_ref = wifi_box.clone();
|
||||||
let _wifibox_ref_listener = wifiBox.clone();
|
let _wifibox_ref_listener = wifi_box.clone();
|
||||||
let wifiEntries = wifiBox.imp().wifiEntries.clone();
|
let wifi_entries = wifi_box.imp().wifi_entries.clone();
|
||||||
let wifiEntriesPath = wifiBox.imp().wifiEntriesPath.clone();
|
let wifi_entries_path = wifi_box.imp().wifi_entries_path.clone();
|
||||||
|
|
||||||
gio::spawn_blocking(move || {
|
gio::spawn_blocking(move || {
|
||||||
let accessPoints = get_access_points();
|
let access_points = get_access_points();
|
||||||
let devices = get_wifi_devices();
|
let devices = get_wifi_devices();
|
||||||
{
|
{
|
||||||
let imp = wifibox_ref.imp();
|
let imp = wifibox_ref.imp();
|
||||||
let list = imp.resetModelList.write().unwrap();
|
let list = imp.reset_model_list.write().unwrap();
|
||||||
let mut model_index = imp.resetModelIndex.write().unwrap();
|
let mut model_index = imp.reset_model_index.write().unwrap();
|
||||||
let mut map = imp.resetWifiDevices.write().unwrap();
|
let mut map = imp.reset_wifi_devices.write().unwrap();
|
||||||
imp.resetCurrentWifiDevice
|
imp.reset_current_wifi_device
|
||||||
.replace(devices.last().unwrap().clone());
|
.replace(devices.last().unwrap().clone());
|
||||||
for (index, device) in devices.into_iter().enumerate() {
|
for (index, device) in devices.into_iter().enumerate() {
|
||||||
list.append(&device.name);
|
list.append(&device.name);
|
||||||
|
@ -104,19 +104,19 @@ pub fn scanForWifi(wifiBox: Arc<WifiBox>) {
|
||||||
*model_index += 1;
|
*model_index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let wifiEntries = wifiEntries.clone();
|
let wifi_entries = wifi_entries.clone();
|
||||||
let wifiEntriesPath = wifiEntriesPath.clone();
|
let wifi_entries_path = wifi_entries_path.clone();
|
||||||
dbus_start_network_events();
|
dbus_start_network_events();
|
||||||
glib::spawn_future(async move {
|
glib::spawn_future(async move {
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let mut wifiEntries = wifiEntries.lock().unwrap();
|
let mut wifi_entries = wifi_entries.lock().unwrap();
|
||||||
let mut wifiEntriesPath = wifiEntriesPath.lock().unwrap();
|
let mut wifi_entries_path = wifi_entries_path.lock().unwrap();
|
||||||
let imp = wifibox_ref.imp();
|
let imp = wifibox_ref.imp();
|
||||||
|
|
||||||
let list = imp.resetModelList.read().unwrap();
|
let list = imp.reset_model_list.read().unwrap();
|
||||||
imp.resetWiFiDevice.set_model(Some(&*list));
|
imp.resetWiFiDevice.set_model(Some(&*list));
|
||||||
let map = imp.resetWifiDevices.read().unwrap();
|
let map = imp.reset_wifi_devices.read().unwrap();
|
||||||
let device = imp.resetCurrentWifiDevice.borrow();
|
let device = imp.reset_current_wifi_device.borrow();
|
||||||
if let Some(index) = map.get(&device.name) {
|
if let Some(index) = map.get(&device.name) {
|
||||||
imp.resetWiFiDevice.set_selected(index.1);
|
imp.resetWiFiDevice.set_selected(index.1);
|
||||||
}
|
}
|
||||||
|
@ -130,20 +130,21 @@ pub fn scanForWifi(wifiBox: Arc<WifiBox>) {
|
||||||
let selected = selected.downcast_ref::<StringObject>().unwrap();
|
let selected = selected.downcast_ref::<StringObject>().unwrap();
|
||||||
let selected = selected.string().to_string();
|
let selected = selected.string().to_string();
|
||||||
|
|
||||||
let device = imp.resetWifiDevices.read().unwrap();
|
let device = imp.reset_wifi_devices.read().unwrap();
|
||||||
let device = device.get(&selected);
|
let device = device.get(&selected);
|
||||||
if device.is_none() {
|
if device.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
set_wifi_device(device.unwrap().0.path.clone());
|
set_wifi_device(device.unwrap().0.path.clone());
|
||||||
}));
|
}));
|
||||||
for accessPoint in accessPoints {
|
for access_point in access_points {
|
||||||
let ssid = accessPoint.ssid.clone();
|
let ssid = access_point.ssid.clone();
|
||||||
let path = accessPoint.dbus_path.clone();
|
let path = access_point.dbus_path.clone();
|
||||||
let connected = imp.resetCurrentWifiDevice.borrow().active_access_point == path;
|
let connected =
|
||||||
let entry = WifiEntry::new(connected, accessPoint, imp);
|
imp.reset_current_wifi_device.borrow().active_access_point == path;
|
||||||
wifiEntries.insert(ssid, entry.clone());
|
let entry = WifiEntry::new(connected, access_point, imp);
|
||||||
wifiEntriesPath.insert(path, entry.clone());
|
wifi_entries.insert(ssid, entry.clone());
|
||||||
|
wifi_entries_path.insert(path, entry.clone());
|
||||||
imp.resetWifiList.add(&*entry);
|
imp.resetWifiList.add(&*entry);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -151,19 +152,19 @@ pub fn scanForWifi(wifiBox: Arc<WifiBox>) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show_stored_connections(wifiBox: Arc<WifiBox>) {
|
pub fn show_stored_connections(wifi_box: Arc<WifiBox>) {
|
||||||
let wifibox_ref = wifiBox.clone();
|
let wifibox_ref = wifi_box.clone();
|
||||||
gio::spawn_blocking(move || {
|
gio::spawn_blocking(move || {
|
||||||
let connections = get_stored_connections();
|
let connections = get_stored_connections();
|
||||||
glib::spawn_future(async move {
|
glib::spawn_future(async move {
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let selfImp = wifibox_ref.imp();
|
let self_imp = wifibox_ref.imp();
|
||||||
for connection in connections {
|
for connection in connections {
|
||||||
// TODO include button for settings
|
// TODO include button for settings
|
||||||
let name =
|
let name =
|
||||||
&String::from_utf8(connection.1).unwrap_or_else(|_| String::from(""));
|
&String::from_utf8(connection.1).unwrap_or_else(|_| String::from(""));
|
||||||
let entry = SavedWifiEntry::new(name, connection.0, selfImp);
|
let entry = SavedWifiEntry::new(name, connection.0, self_imp);
|
||||||
selfImp.resetStoredWifiList.add(&entry);
|
self_imp.resetStoredWifiList.add(&entry);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -193,8 +194,8 @@ pub fn get_access_points() -> Vec<AccessPoint> {
|
||||||
if res.is_err() {
|
if res.is_err() {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
let (accessPoints,) = res.unwrap();
|
let (access_points,) = res.unwrap();
|
||||||
accessPoints
|
access_points
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_wifi_device(path: Path<'static>) {
|
pub fn set_wifi_device(path: Path<'static>) {
|
||||||
|
@ -289,18 +290,18 @@ pub fn start_event_listener(listeners: Arc<Listeners>, wifi_box: Arc<WifiBox>) {
|
||||||
glib::spawn_future(async move {
|
glib::spawn_future(async move {
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let imp = wifi_box.imp();
|
let imp = wifi_box.imp();
|
||||||
let mut wifiEntries = imp.wifiEntries.lock().unwrap();
|
let mut wifi_entries = imp.wifi_entries.lock().unwrap();
|
||||||
let mut wifiEntriesPath = imp.wifiEntriesPath.lock().unwrap();
|
let mut wifi_entries_path = imp.wifi_entries_path.lock().unwrap();
|
||||||
let ssid = ir.access_point.ssid.clone();
|
let ssid = ir.access_point.ssid.clone();
|
||||||
let path = ir.access_point.dbus_path.clone();
|
let path = ir.access_point.dbus_path.clone();
|
||||||
if wifiEntries.get(&ssid).is_some() {
|
if wifi_entries.get(&ssid).is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let connected = imp.resetCurrentWifiDevice.borrow().active_access_point
|
let connected = imp.reset_current_wifi_device.borrow().active_access_point
|
||||||
== ir.access_point.dbus_path;
|
== ir.access_point.dbus_path;
|
||||||
let entry = WifiEntry::new(connected, ir.access_point, imp);
|
let entry = WifiEntry::new(connected, ir.access_point, imp);
|
||||||
wifiEntries.insert(ssid, entry.clone());
|
wifi_entries.insert(ssid, entry.clone());
|
||||||
wifiEntriesPath.insert(path, entry.clone());
|
wifi_entries_path.insert(path, entry.clone());
|
||||||
imp.resetWifiList.add(&*entry);
|
imp.resetWifiList.add(&*entry);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -316,15 +317,15 @@ pub fn start_event_listener(listeners: Arc<Listeners>, wifi_box: Arc<WifiBox>) {
|
||||||
glib::spawn_future(async move {
|
glib::spawn_future(async move {
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let imp = wifi_box.imp();
|
let imp = wifi_box.imp();
|
||||||
let mut wifiEntries = imp.wifiEntries.lock().unwrap();
|
let mut wifi_entries = imp.wifi_entries.lock().unwrap();
|
||||||
let mut wifiEntriesPath = imp.wifiEntriesPath.lock().unwrap();
|
let mut wifi_entries_path = imp.wifi_entries_path.lock().unwrap();
|
||||||
let entry = wifiEntriesPath.remove(&ir.access_point);
|
let entry = wifi_entries_path.remove(&ir.access_point);
|
||||||
if entry.is_none() {
|
if entry.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let entry = entry.unwrap();
|
let entry = entry.unwrap();
|
||||||
let ssid = entry.imp().accessPoint.borrow().ssid.clone();
|
let ssid = entry.imp().access_point.borrow().ssid.clone();
|
||||||
wifiEntries.remove(&ssid);
|
wifi_entries.remove(&ssid);
|
||||||
imp.resetWifiList.remove(&*entry);
|
imp.resetWifiList.remove(&*entry);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -341,22 +342,22 @@ pub fn start_event_listener(listeners: Arc<Listeners>, wifi_box: Arc<WifiBox>) {
|
||||||
glib::spawn_future(async move {
|
glib::spawn_future(async move {
|
||||||
glib::idle_add_local_once(move || {
|
glib::idle_add_local_once(move || {
|
||||||
let imp = wifi_box.imp();
|
let imp = wifi_box.imp();
|
||||||
let wifiEntries = imp.wifiEntries.lock().unwrap();
|
let wifi_entries = imp.wifi_entries.lock().unwrap();
|
||||||
let entry = wifiEntries.get(&ir.access_point.ssid);
|
let entry = wifi_entries.get(&ir.access_point.ssid);
|
||||||
if entry.is_none() {
|
if entry.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let entry = entry.unwrap();
|
let entry = entry.unwrap();
|
||||||
let entryImp = entry.imp();
|
let entry_imp = entry.imp();
|
||||||
let strength = WifiStrength::from_u8(ir.access_point.strength);
|
let strength = WifiStrength::from_u8(ir.access_point.strength);
|
||||||
let ssid = ir.access_point.ssid.clone();
|
let ssid = ir.access_point.ssid.clone();
|
||||||
let name_opt = String::from_utf8(ssid).unwrap_or_else(|_| String::from(""));
|
let name_opt = String::from_utf8(ssid).unwrap_or_else(|_| String::from(""));
|
||||||
let name = name_opt.as_str();
|
let name = name_opt.as_str();
|
||||||
entryImp.wifiStrength.set(strength);
|
entry_imp.wifi_strength.set(strength);
|
||||||
entryImp.resetWifiLabel.get().set_text(name);
|
entry_imp.resetWifiLabel.get().set_text(name);
|
||||||
entryImp.resetWifiEncrypted.set_visible(false);
|
entry_imp.resetWifiEncrypted.set_visible(false);
|
||||||
// TODO handle encryption thing
|
// TODO handle encryption thing
|
||||||
entryImp
|
entry_imp
|
||||||
.resetWifiStrength
|
.resetWifiStrength
|
||||||
.get()
|
.get()
|
||||||
.set_from_icon_name(match strength {
|
.set_from_icon_name(match strength {
|
||||||
|
@ -368,18 +369,18 @@ pub fn start_event_listener(listeners: Arc<Listeners>, wifi_box: Arc<WifiBox>) {
|
||||||
WifiStrength::None => Some("network-wireless-signal-none-symbolic"),
|
WifiStrength::None => Some("network-wireless-signal-none-symbolic"),
|
||||||
});
|
});
|
||||||
if !ir.access_point.stored {
|
if !ir.access_point.stored {
|
||||||
entryImp.resetWifiEditButton.set_sensitive(false);
|
entry_imp.resetWifiEditButton.set_sensitive(false);
|
||||||
}
|
}
|
||||||
if ir.access_point.dbus_path
|
if ir.access_point.dbus_path
|
||||||
== imp.resetCurrentWifiDevice.borrow().active_access_point
|
== imp.reset_current_wifi_device.borrow().active_access_point
|
||||||
{
|
{
|
||||||
entryImp.resetWifiConnected.set_text("Connected");
|
entry_imp.resetWifiConnected.set_text("Connected");
|
||||||
} else {
|
} else {
|
||||||
entryImp.resetWifiConnected.set_text("");
|
entry_imp.resetWifiConnected.set_text("");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let mut wifiName = entryImp.wifiName.borrow_mut();
|
let mut wifi_name = entry_imp.wifi_name.borrow_mut();
|
||||||
*wifiName = String::from(name);
|
*wifi_name = String::from(name);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -395,17 +396,17 @@ pub fn start_event_listener(listeners: Arc<Listeners>, wifi_box: Arc<WifiBox>) {
|
||||||
glib::spawn_future(async move {
|
glib::spawn_future(async move {
|
||||||
glib::idle_add_once(move || {
|
glib::idle_add_once(move || {
|
||||||
let imp = wifi_box.imp();
|
let imp = wifi_box.imp();
|
||||||
let mut current_device = imp.resetCurrentWifiDevice.borrow_mut();
|
let mut current_device = imp.reset_current_wifi_device.borrow_mut();
|
||||||
if current_device.path == ir.wifi_device.path {
|
if current_device.path == ir.wifi_device.path {
|
||||||
current_device.active_access_point = ir.wifi_device.active_access_point;
|
current_device.active_access_point = ir.wifi_device.active_access_point;
|
||||||
} else {
|
} else {
|
||||||
*current_device = ir.wifi_device;
|
*current_device = ir.wifi_device;
|
||||||
}
|
}
|
||||||
let mut wifiEntries = imp.wifiEntries.lock().unwrap();
|
let mut wifi_entries = imp.wifi_entries.lock().unwrap();
|
||||||
for entry in wifiEntries.iter_mut() {
|
for entry in wifi_entries.iter_mut() {
|
||||||
let imp = entry.1.imp();
|
let imp = entry.1.imp();
|
||||||
let mut connected = imp.connected.borrow_mut();
|
let mut connected = imp.connected.borrow_mut();
|
||||||
*connected = imp.accessPoint.borrow().dbus_path == current_device.path;
|
*connected = imp.access_point.borrow().dbus_path == current_device.path;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::components::wifi::wifiBox;
|
use crate::components::wifi::wifi_box;
|
||||||
use adw::{ActionRow, ComboRow, NavigationView, PreferencesGroup};
|
use adw::{ActionRow, ComboRow, NavigationView, PreferencesGroup};
|
||||||
use dbus::Path;
|
use dbus::Path;
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
|
@ -9,8 +9,8 @@ use std::collections::HashMap;
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use ReSet_Lib::network::network::WifiDevice;
|
use ReSet_Lib::network::network::WifiDevice;
|
||||||
|
|
||||||
use crate::components::base::listEntry::ListEntry;
|
use crate::components::base::list_entry::ListEntry;
|
||||||
use crate::components::wifi::wifiEntry::WifiEntry;
|
use crate::components::wifi::wifi_entry::WifiEntry;
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[derive(Default, CompositeTemplate)]
|
#[derive(Default, CompositeTemplate)]
|
||||||
|
@ -32,13 +32,13 @@ pub struct WifiBox {
|
||||||
pub resetStoredWifiList: TemplateChild<PreferencesGroup>,
|
pub resetStoredWifiList: TemplateChild<PreferencesGroup>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub resetAvailableNetworks: TemplateChild<ActionRow>,
|
pub resetAvailableNetworks: TemplateChild<ActionRow>,
|
||||||
pub wifiEntries: Arc<Mutex<HashMap<Vec<u8>, Arc<WifiEntry>>>>,
|
pub wifi_entries: Arc<Mutex<HashMap<Vec<u8>, Arc<WifiEntry>>>>,
|
||||||
pub wifiEntriesPath: Arc<Mutex<HashMap<Path<'static>, Arc<WifiEntry>>>>,
|
pub wifi_entries_path: Arc<Mutex<HashMap<Path<'static>, Arc<WifiEntry>>>>,
|
||||||
pub savedWifiEntries: Arc<Mutex<Vec<ListEntry>>>,
|
pub saved_wifi_entries: Arc<Mutex<Vec<ListEntry>>>,
|
||||||
pub resetWifiDevices: Arc<RwLock<HashMap<String, (WifiDevice, u32)>>>,
|
pub reset_wifi_devices: Arc<RwLock<HashMap<String, (WifiDevice, u32)>>>,
|
||||||
pub resetCurrentWifiDevice: Arc<RefCell<WifiDevice>>,
|
pub reset_current_wifi_device: Arc<RefCell<WifiDevice>>,
|
||||||
pub resetModelList: Arc<RwLock<StringList>>,
|
pub reset_model_list: Arc<RwLock<StringList>>,
|
||||||
pub resetModelIndex: Arc<RwLock<u32>>,
|
pub reset_model_index: Arc<RwLock<u32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for WifiBox {}
|
unsafe impl Send for WifiBox {}
|
||||||
|
@ -48,7 +48,7 @@ unsafe impl Sync for WifiBox {}
|
||||||
impl ObjectSubclass for WifiBox {
|
impl ObjectSubclass for WifiBox {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetWifi";
|
const NAME: &'static str = "resetWifi";
|
||||||
type Type = wifiBox::WifiBox;
|
type Type = wifi_box::WifiBox;
|
||||||
type ParentType = gtk::Box;
|
type ParentType = gtk::Box;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
||||||
|
@ -67,7 +67,7 @@ impl ObjectImpl for WifiBox {
|
||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
|
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
obj.setupCallbacks();
|
obj.setup_callbacks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::components::wifi::utils::getConnectionSettings;
|
use crate::components::wifi::utils::get_connection_settings;
|
||||||
use adw::glib;
|
use adw::glib;
|
||||||
use adw::glib::{Object, PropertySet};
|
use adw::glib::{Object, PropertySet};
|
||||||
use adw::prelude::{ActionRowExt, ButtonExt, EditableExt, PopoverExt};
|
use adw::prelude::{ActionRowExt, ButtonExt, EditableExt, PopoverExt};
|
||||||
|
@ -13,12 +13,12 @@ use gtk::gio;
|
||||||
use gtk::prelude::{ListBoxRowExt, WidgetExt};
|
use gtk::prelude::{ListBoxRowExt, WidgetExt};
|
||||||
use ReSet_Lib::network::network::{AccessPoint, WifiStrength};
|
use ReSet_Lib::network::network::{AccessPoint, WifiStrength};
|
||||||
|
|
||||||
use crate::components::wifi::wifiBoxImpl::WifiBox;
|
use crate::components::wifi::wifi_box_impl::WifiBox;
|
||||||
use crate::components::wifi::wifiEntryImpl;
|
use crate::components::wifi::wifi_entry_impl;
|
||||||
use crate::components::wifi::wifiOptions::WifiOptions;
|
use crate::components::wifi::wifi_options::WifiOptions;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct WifiEntry(ObjectSubclass<wifiEntryImpl::WifiEntry>)
|
pub struct WifiEntry(ObjectSubclass<wifi_entry_impl::WifiEntry>)
|
||||||
@extends adw::ActionRow, gtk::Widget,
|
@extends adw::ActionRow, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::Actionable, gtk::ConstraintTarget, gtk::ListBoxRow;
|
@implements gtk::Accessible, gtk::Buildable, gtk::Actionable, gtk::ConstraintTarget, gtk::ListBoxRow;
|
||||||
}
|
}
|
||||||
|
@ -27,21 +27,21 @@ unsafe impl Send for WifiEntry {}
|
||||||
unsafe impl Sync for WifiEntry {}
|
unsafe impl Sync for WifiEntry {}
|
||||||
|
|
||||||
impl WifiEntry {
|
impl WifiEntry {
|
||||||
pub fn new(connected: bool, access_point: AccessPoint, wifiBox: &WifiBox) -> Arc<Self> {
|
pub fn new(connected: bool, access_point: AccessPoint, wifi_box: &WifiBox) -> Arc<Self> {
|
||||||
let entry: Arc<WifiEntry> = Arc::new(Object::builder().build());
|
let entry: Arc<WifiEntry> = Arc::new(Object::builder().build());
|
||||||
let stored_entry = entry.clone();
|
let stored_entry = entry.clone();
|
||||||
let new_entry = entry.clone();
|
let new_entry = entry.clone();
|
||||||
let entryImp = entry.imp();
|
let entry_imp = entry.imp();
|
||||||
let strength = WifiStrength::from_u8(access_point.strength);
|
let strength = WifiStrength::from_u8(access_point.strength);
|
||||||
let ssid = access_point.ssid.clone();
|
let ssid = access_point.ssid.clone();
|
||||||
let name_opt = String::from_utf8(ssid).unwrap_or_else(|_| String::from(""));
|
let name_opt = String::from_utf8(ssid).unwrap_or_else(|_| String::from(""));
|
||||||
let name = name_opt.as_str();
|
let name = name_opt.as_str();
|
||||||
entryImp.wifiStrength.set(strength);
|
entry_imp.wifi_strength.set(strength);
|
||||||
entryImp.resetWifiLabel.get().set_text(name);
|
entry_imp.resetWifiLabel.get().set_text(name);
|
||||||
entryImp.resetWifiEncrypted.set_visible(false);
|
entry_imp.resetWifiEncrypted.set_visible(false);
|
||||||
entryImp.connected.set(connected);
|
entry_imp.connected.set(connected);
|
||||||
// TODO handle encryption thing
|
// TODO handle encryption thing
|
||||||
entryImp
|
entry_imp
|
||||||
.resetWifiStrength
|
.resetWifiStrength
|
||||||
.get()
|
.get()
|
||||||
.set_from_icon_name(match strength {
|
.set_from_icon_name(match strength {
|
||||||
|
@ -51,22 +51,21 @@ impl WifiEntry {
|
||||||
WifiStrength::None => Some("network-wireless-signal-none-symbolic"),
|
WifiStrength::None => Some("network-wireless-signal-none-symbolic"),
|
||||||
});
|
});
|
||||||
if !access_point.stored {
|
if !access_point.stored {
|
||||||
entryImp.resetWifiEditButton.set_sensitive(false);
|
entry_imp.resetWifiEditButton.set_sensitive(false);
|
||||||
}
|
}
|
||||||
if connected {
|
if connected {
|
||||||
entryImp
|
entry_imp.resetWifiConnected.set_text("Connected");
|
||||||
.resetWifiConnected.set_text("Connected");
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let mut wifiName = entryImp.wifiName.borrow_mut();
|
let mut wifi_name = entry_imp.wifi_name.borrow_mut();
|
||||||
*wifiName = String::from(name);
|
*wifi_name = String::from(name);
|
||||||
}
|
}
|
||||||
entryImp.accessPoint.set(access_point);
|
entry_imp.access_point.set(access_point);
|
||||||
|
|
||||||
entry.set_activatable(true);
|
entry.set_activatable(true);
|
||||||
entry.connect_activated(clone!(@weak entryImp => move |_| {
|
entry.connect_activated(clone!(@weak entry_imp => move |_| {
|
||||||
let access_point = entryImp.accessPoint.borrow();
|
let access_point = entry_imp.access_point.borrow();
|
||||||
if *entryImp.connected.borrow() {
|
if *entry_imp.connected.borrow() {
|
||||||
click_disconnect(stored_entry.clone());
|
click_disconnect(stored_entry.clone());
|
||||||
} else if access_point.stored {
|
} else if access_point.stored {
|
||||||
click_stored_network(stored_entry.clone());
|
click_stored_network(stored_entry.clone());
|
||||||
|
@ -74,15 +73,15 @@ impl WifiEntry {
|
||||||
click_new_network(new_entry.clone());
|
click_new_network(new_entry.clone());
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
entry.setupCallbacks(wifiBox);
|
entry.setup_callbacks(wifi_box);
|
||||||
entry
|
entry
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setupCallbacks(&self, wifiBox: &WifiBox) {
|
pub fn setup_callbacks(&self, wifi_box: &WifiBox) {
|
||||||
let selfImp = self.imp();
|
let self_imp = self.imp();
|
||||||
selfImp.resetWifiEditButton.connect_clicked(clone!(@ weak selfImp, @ weak wifiBox => move |_| {
|
self_imp.resetWifiEditButton.connect_clicked(clone!(@ weak self_imp, @ weak wifi_box => move |_| {
|
||||||
let _option = getConnectionSettings(selfImp.accessPoint.borrow().associated_connection.clone());
|
let _option = get_connection_settings(self_imp.access_point.borrow().associated_connection.clone());
|
||||||
wifiBox.resetWifiNavigation.push(&*WifiOptions::new(_option, selfImp.accessPoint.borrow().dbus_path.clone()));
|
wifi_box.resetWifiNavigation.push(&*WifiOptions::new(_option, self_imp.access_point.borrow().dbus_path.clone()));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,8 +118,8 @@ pub fn click_disconnect(entry: Arc<WifiEntry>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn click_stored_network(entry: Arc<WifiEntry>) {
|
pub fn click_stored_network(entry: Arc<WifiEntry>) {
|
||||||
let entryImp = entry.imp();
|
let entry_imp = entry.imp();
|
||||||
let access_point = entryImp.accessPoint.borrow().clone();
|
let access_point = entry_imp.access_point.borrow().clone();
|
||||||
let entry_ref = entry.clone();
|
let entry_ref = entry.clone();
|
||||||
entry.set_activatable(false);
|
entry.set_activatable(false);
|
||||||
gio::spawn_blocking(move || {
|
gio::spawn_blocking(move || {
|
||||||
|
@ -212,18 +211,18 @@ pub fn click_new_network(entry: Arc<WifiEntry>) {
|
||||||
// TODO crate spinner animation and block UI
|
// TODO crate spinner animation and block UI
|
||||||
};
|
};
|
||||||
|
|
||||||
let entryImp = entry.imp();
|
let entry_imp = entry.imp();
|
||||||
let popupImp = entryImp.resetWifiPopup.imp();
|
let popup_imp = entry_imp.resetWifiPopup.imp();
|
||||||
popupImp
|
popup_imp
|
||||||
.resetPopupEntry
|
.resetPopupEntry
|
||||||
.connect_activate(clone!(@weak entry as origEntry, @weak entryImp => move |entry| {
|
.connect_activate(clone!(@weak entry as orig_entry, @weak entry_imp => move |entry| {
|
||||||
connect_new_network(origEntry, entryImp.accessPoint.clone().take(), entry.text().to_string());
|
connect_new_network(orig_entry, entry_imp.access_point.clone().take(), entry.text().to_string());
|
||||||
}));
|
}));
|
||||||
popupImp.resetPopupButton.connect_clicked(
|
popup_imp.resetPopupButton.connect_clicked(
|
||||||
clone!(@weak entry as origEntry,@weak entryImp, @weak popupImp => move |_| {
|
clone!(@weak entry as orig_entry,@weak entry_imp, @weak popup_imp => move |_| {
|
||||||
let entry = entryImp.resetWifiPopup.imp().resetPopupEntry.text().to_string();
|
let entry = entry_imp.resetWifiPopup.imp().resetPopupEntry.text().to_string();
|
||||||
connect_new_network(origEntry, entryImp.accessPoint.clone().take(), entry);
|
connect_new_network(orig_entry, entry_imp.access_point.clone().take(), entry);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
entryImp.resetWifiPopup.popup();
|
entry_imp.resetWifiPopup.popup();
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::components::base::popup::Popup;
|
use crate::components::base::popup::Popup;
|
||||||
use crate::components::wifi::wifiEntry;
|
use crate::components::wifi::wifi_entry;
|
||||||
use adw::subclass::preferences_row::PreferencesRowImpl;
|
use adw::subclass::preferences_row::PreferencesRowImpl;
|
||||||
use adw::subclass::prelude::ActionRowImpl;
|
use adw::subclass::prelude::ActionRowImpl;
|
||||||
use adw::ActionRow;
|
use adw::ActionRow;
|
||||||
|
@ -24,9 +24,9 @@ pub struct WifiEntry {
|
||||||
pub resetWifiConnected: TemplateChild<Label>,
|
pub resetWifiConnected: TemplateChild<Label>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub resetWifiPopup: TemplateChild<Popup>,
|
pub resetWifiPopup: TemplateChild<Popup>,
|
||||||
pub wifiName: RefCell<String>,
|
pub wifi_name: RefCell<String>,
|
||||||
pub wifiStrength: RefCell<WifiStrength>,
|
pub wifi_strength: RefCell<WifiStrength>,
|
||||||
pub accessPoint: RefCell<AccessPoint>,
|
pub access_point: RefCell<AccessPoint>,
|
||||||
pub connected: RefCell<bool>,
|
pub connected: RefCell<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ unsafe impl Sync for WifiEntry {}
|
||||||
impl ObjectSubclass for WifiEntry {
|
impl ObjectSubclass for WifiEntry {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetWifiEntry";
|
const NAME: &'static str = "resetWifiEntry";
|
||||||
type Type = wifiEntry::WifiEntry;
|
type Type = wifi_entry::WifiEntry;
|
||||||
type ParentType = ActionRow;
|
type ParentType = ActionRow;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
390
src/components/wifi/wifi_options.rs
Normal file
390
src/components/wifi/wifi_options.rs
Normal file
|
@ -0,0 +1,390 @@
|
||||||
|
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||||
|
use std::str::FromStr;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use adw::glib::Object;
|
||||||
|
use adw::prelude::{ActionRowExt, ComboRowExt, PreferencesGroupExt};
|
||||||
|
use adw::subclass::prelude::ObjectSubclassIsExt;
|
||||||
|
use adw::{gio, glib};
|
||||||
|
use dbus::arg::PropMap;
|
||||||
|
use dbus::{Error, Path};
|
||||||
|
use glib::{clone, PropertySet};
|
||||||
|
use gtk::prelude::{ButtonExt, EditableExt, WidgetExt};
|
||||||
|
use IpProtocol::{IPv4, IPv6};
|
||||||
|
use ReSet_Lib::network::connection::{Connection, DNSMethod4, DNSMethod6, Enum, TypeSettings};
|
||||||
|
|
||||||
|
use crate::components::wifi::utils::IpProtocol;
|
||||||
|
use crate::components::wifi::wifi_address_entry::WifiAddressEntry;
|
||||||
|
use crate::components::wifi::wifi_options_impl;
|
||||||
|
use crate::components::wifi::wifi_route_entry::WifiRouteEntry;
|
||||||
|
|
||||||
|
glib::wrapper! {
|
||||||
|
pub struct WifiOptions(ObjectSubclass<wifi_options_impl::WifiOptions>)
|
||||||
|
@extends adw::NavigationPage, gtk::Widget,
|
||||||
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for WifiOptions {}
|
||||||
|
unsafe impl Sync for WifiOptions {}
|
||||||
|
|
||||||
|
impl WifiOptions {
|
||||||
|
pub fn new(connection: Connection, access_point: Path<'static>) -> Arc<Self> {
|
||||||
|
let wifi_option: Arc<WifiOptions> = Arc::new(Object::builder().build());
|
||||||
|
wifi_option.imp().connection.set(connection);
|
||||||
|
wifi_option.initialize_ui();
|
||||||
|
setup_callbacks(&wifi_option, access_point);
|
||||||
|
wifi_option
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn initialize_ui(&self) {
|
||||||
|
let self_imp = self.imp();
|
||||||
|
let ip4_address_length;
|
||||||
|
let ip4_route_length;
|
||||||
|
let ip6_address_length;
|
||||||
|
let ip6_route_length;
|
||||||
|
{
|
||||||
|
let conn = self_imp.connection.borrow();
|
||||||
|
ip4_address_length = conn.ipv4.address_data.len();
|
||||||
|
ip4_route_length = conn.ipv4.route_data.len();
|
||||||
|
ip6_address_length = conn.ipv4.address_data.len();
|
||||||
|
ip6_route_length = conn.ipv4.route_data.len();
|
||||||
|
|
||||||
|
// General
|
||||||
|
self_imp
|
||||||
|
.resetWifiAutoConnect
|
||||||
|
.set_active(conn.settings.autoconnect);
|
||||||
|
self_imp
|
||||||
|
.resetWifiMetered
|
||||||
|
.set_active(conn.settings.metered != -1);
|
||||||
|
match &conn.device {
|
||||||
|
TypeSettings::WIFI(wifi) => {
|
||||||
|
self_imp.resetWifiLinkSpeed.set_visible(false);
|
||||||
|
self_imp.resetWifiIP4Addr.set_visible(false);
|
||||||
|
self_imp.resetWifiIP6Addr.set_visible(false);
|
||||||
|
self_imp.resetWifiDNS.set_visible(false);
|
||||||
|
self_imp.resetWifiGateway.set_visible(false);
|
||||||
|
self_imp.resetWifiLastUsed.set_visible(true);
|
||||||
|
self_imp.resetWifiMac.set_subtitle(&wifi.cloned_mac_address);
|
||||||
|
self_imp
|
||||||
|
.resetWifiName
|
||||||
|
.set_subtitle(&String::from_utf8(wifi.ssid.clone()).unwrap_or_default());
|
||||||
|
}
|
||||||
|
TypeSettings::ETHERNET(ethernet) => {
|
||||||
|
self_imp.resetWifiLinkSpeed.set_visible(true);
|
||||||
|
self_imp.resetWifiIP4Addr.set_visible(true);
|
||||||
|
self_imp.resetWifiIP6Addr.set_visible(true);
|
||||||
|
self_imp.resetWifiDNS.set_visible(true);
|
||||||
|
self_imp.resetWifiGateway.set_visible(true);
|
||||||
|
self_imp.resetWifiLastUsed.set_visible(false);
|
||||||
|
self_imp
|
||||||
|
.resetWifiMac
|
||||||
|
.set_subtitle(ðernet.cloned_mac_address);
|
||||||
|
self_imp
|
||||||
|
.resetWifiLinkSpeed
|
||||||
|
.set_subtitle(ðernet.speed.to_string());
|
||||||
|
}
|
||||||
|
TypeSettings::VPN(_vpn) => {}
|
||||||
|
TypeSettings::None => {}
|
||||||
|
};
|
||||||
|
// IPv4
|
||||||
|
self_imp
|
||||||
|
.resetIP4Method
|
||||||
|
.set_selected(conn.ipv4.dns_method.to_i32() as u32);
|
||||||
|
self.set_ip4_visibility(conn.ipv4.dns_method.to_i32() as u32);
|
||||||
|
|
||||||
|
let ipv4_dns: Vec<String> = conn
|
||||||
|
.ipv4
|
||||||
|
.dns
|
||||||
|
.iter()
|
||||||
|
.map(|addr| {
|
||||||
|
addr.iter()
|
||||||
|
.map(|octet| octet.to_string())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(".")
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
self_imp.resetIP4DNS.set_text(&ipv4_dns.join(", "));
|
||||||
|
self_imp.resetIP4Gateway.set_text(&conn.ipv4.gateway);
|
||||||
|
// IPv6
|
||||||
|
self_imp
|
||||||
|
.resetIP6Method
|
||||||
|
.set_selected(conn.ipv6.dns_method.to_i32() as u32);
|
||||||
|
self.set_ip6_visibility(conn.ipv6.dns_method.to_i32() as u32);
|
||||||
|
|
||||||
|
let ipv6_dns: Vec<String> = conn
|
||||||
|
.ipv6
|
||||||
|
.dns
|
||||||
|
.iter()
|
||||||
|
.map(|addr| {
|
||||||
|
addr.iter()
|
||||||
|
.map(|octet| octet.to_string())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(":")
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
self_imp.resetIP6DNS.set_text(&ipv6_dns.join(", "));
|
||||||
|
self_imp.resetIP6Gateway.set_text(&conn.ipv6.gateway);
|
||||||
|
|
||||||
|
// Security
|
||||||
|
if let TypeSettings::WIFI(wifi) = &conn.device {
|
||||||
|
match wifi.security_settings.key_management.as_str() {
|
||||||
|
"none" => {
|
||||||
|
self_imp.resetWifiSecurityDropdown.set_selected(0);
|
||||||
|
self_imp.resetWifiPassword.set_visible(false);
|
||||||
|
self_imp.resetWifiPassword.set_text("");
|
||||||
|
}
|
||||||
|
"wpa-psk" => {
|
||||||
|
self_imp.resetWifiSecurityDropdown.set_selected(1);
|
||||||
|
self_imp.resetWifiPassword.set_visible(true);
|
||||||
|
self_imp
|
||||||
|
.resetWifiPassword
|
||||||
|
.set_text(&wifi.security_settings.psk);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// IPv4
|
||||||
|
for i in 0..ip4_address_length {
|
||||||
|
let address = &WifiAddressEntry::new(Some(i), self_imp.connection.clone(), IPv4);
|
||||||
|
self_imp.resetIP4AddressGroup.add(address);
|
||||||
|
}
|
||||||
|
let address = &WifiAddressEntry::new(None, self_imp.connection.clone(), IPv4);
|
||||||
|
self_imp.resetIP4AddressGroup.add(address);
|
||||||
|
|
||||||
|
for i in 0..ip4_route_length {
|
||||||
|
let route = &WifiRouteEntry::new(Some(i), self_imp.connection.clone(), IPv4);
|
||||||
|
self_imp.resetIP4RoutesGroup.add(route)
|
||||||
|
}
|
||||||
|
let route = &WifiRouteEntry::new(None, self_imp.connection.clone(), IPv4);
|
||||||
|
self_imp.resetIP4RoutesGroup.add(route);
|
||||||
|
|
||||||
|
// IPv6
|
||||||
|
for i in 0..ip6_address_length {
|
||||||
|
let address = &WifiAddressEntry::new(Some(i), self_imp.connection.clone(), IPv6);
|
||||||
|
self_imp.resetIP6AddressGroup.add(address);
|
||||||
|
}
|
||||||
|
let address = &WifiAddressEntry::new(None, self_imp.connection.clone(), IPv6);
|
||||||
|
self_imp.resetIP6AddressGroup.add(address);
|
||||||
|
|
||||||
|
for i in 0..ip6_route_length {
|
||||||
|
let route = &WifiRouteEntry::new(Some(i), self_imp.connection.clone(), IPv6);
|
||||||
|
self_imp.resetIP6RoutesGroup.add(route);
|
||||||
|
}
|
||||||
|
let route = &WifiRouteEntry::new(None, self_imp.connection.clone(), IPv6);
|
||||||
|
self_imp.resetIP6RoutesGroup.add(route);
|
||||||
|
// Security
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_ip4_visibility(&self, method: u32) {
|
||||||
|
let self_imp = self.imp();
|
||||||
|
match method {
|
||||||
|
0 => {
|
||||||
|
// auto
|
||||||
|
self_imp.resetIP4AddressGroup.set_visible(false);
|
||||||
|
self_imp.resetIP4RoutesGroup.set_visible(true);
|
||||||
|
self_imp.resetIP4Gateway.set_visible(false);
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
// manual
|
||||||
|
self_imp.resetIP4AddressGroup.set_visible(true);
|
||||||
|
self_imp.resetIP4RoutesGroup.set_visible(true);
|
||||||
|
self_imp.resetIP4Gateway.set_visible(true);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
self_imp.resetIP4AddressGroup.set_visible(false);
|
||||||
|
self_imp.resetIP4RoutesGroup.set_visible(false);
|
||||||
|
self_imp.resetIP4Gateway.set_visible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_ip6_visibility(&self, method: u32) {
|
||||||
|
let self_imp = self.imp();
|
||||||
|
match method {
|
||||||
|
0 | 1 => {
|
||||||
|
// auto, dhcp
|
||||||
|
self_imp.resetIP6AddressGroup.set_visible(false);
|
||||||
|
self_imp.resetIP6RoutesGroup.set_visible(true);
|
||||||
|
self_imp.resetIP6Gateway.set_visible(false);
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
// manual
|
||||||
|
self_imp.resetIP6AddressGroup.set_visible(true);
|
||||||
|
self_imp.resetIP6RoutesGroup.set_visible(true);
|
||||||
|
self_imp.resetIP6Gateway.set_visible(true);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
self_imp.resetIP6AddressGroup.set_visible(false);
|
||||||
|
self_imp.resetIP6RoutesGroup.set_visible(false);
|
||||||
|
self_imp.resetIP6Gateway.set_visible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_callbacks(wifi_options: &Arc<WifiOptions>, path: Path<'static>) {
|
||||||
|
let imp = wifi_options.imp();
|
||||||
|
|
||||||
|
// General
|
||||||
|
imp.resetWifiAutoConnect
|
||||||
|
.connect_active_notify(clone!(@weak imp => move |x| {
|
||||||
|
imp.connection.borrow_mut().settings.autoconnect = x.is_active();
|
||||||
|
}));
|
||||||
|
imp.resetWifiMetered
|
||||||
|
.connect_active_notify(clone!(@weak imp => move |x| {
|
||||||
|
imp.connection.borrow_mut().settings.metered = if x.is_active() { 1 } else { 2 };
|
||||||
|
}));
|
||||||
|
imp.wifiOptionsApplyButton
|
||||||
|
.connect_clicked(clone!(@weak imp => move |_| {
|
||||||
|
let prop = imp.connection.borrow().convert_to_propmap();
|
||||||
|
set_connection_settings(path.clone(), prop);
|
||||||
|
}));
|
||||||
|
// IPv4
|
||||||
|
let wifi_options_ip4 = wifi_options.clone();
|
||||||
|
imp.resetIP4Method
|
||||||
|
.connect_selected_notify(clone!(@weak imp => move |dropdown| {
|
||||||
|
let selected = dropdown.selected();
|
||||||
|
let mut conn = imp.connection.borrow_mut();
|
||||||
|
conn.ipv4.dns_method = DNSMethod4::from_i32(selected as i32);
|
||||||
|
wifi_options_ip4.set_ip4_visibility(selected);
|
||||||
|
}));
|
||||||
|
|
||||||
|
imp.resetIP4DNS
|
||||||
|
.connect_changed(clone!(@weak imp => move |entry| {
|
||||||
|
let dns_input = entry.text();
|
||||||
|
let mut conn = imp.connection.borrow_mut();
|
||||||
|
conn.ipv4.dns.clear();
|
||||||
|
if dns_input.is_empty() {
|
||||||
|
imp.resetIP4DNS.remove_css_class("error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for dns_entry in dns_input.as_str().split(',').map(|s| s.trim()) {
|
||||||
|
if let Ok(addr) = Ipv4Addr::from_str(dns_entry) {
|
||||||
|
imp.resetIP4DNS.remove_css_class("error");
|
||||||
|
conn.ipv4.dns.push(addr.octets().to_vec());
|
||||||
|
} else {
|
||||||
|
imp.resetIP4DNS.add_css_class("error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
imp.resetIP4AddressAddButton
|
||||||
|
.connect_clicked(clone!(@weak imp => move |_| {
|
||||||
|
let address = &WifiAddressEntry::new(None, imp.connection.clone(), IpProtocol::IPv4);
|
||||||
|
imp.resetIP4AddressGroup.add(address);
|
||||||
|
}));
|
||||||
|
|
||||||
|
imp.resetIP4Gateway
|
||||||
|
.connect_changed(clone!(@weak imp => move |entry| {
|
||||||
|
let gateway_input = entry.text();
|
||||||
|
let mut conn = imp.connection.borrow_mut();
|
||||||
|
conn.ipv4.gateway.clear();
|
||||||
|
if gateway_input.is_empty() {
|
||||||
|
imp.resetIP4Gateway.remove_css_class("error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if Ipv4Addr::from_str(gateway_input.as_str()).is_ok() {
|
||||||
|
imp.resetIP4Gateway.remove_css_class("error");
|
||||||
|
conn.ipv4.gateway = gateway_input.to_string();
|
||||||
|
} else {
|
||||||
|
imp.resetIP4Gateway.add_css_class("error");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
// IPv6
|
||||||
|
let wifi_options_ip6 = wifi_options.clone();
|
||||||
|
imp.resetIP6Method
|
||||||
|
.connect_selected_notify(clone!(@weak imp => move |dropdown| {
|
||||||
|
let selected = dropdown.selected();
|
||||||
|
let mut conn = imp.connection.borrow_mut();
|
||||||
|
conn.ipv6.dns_method = DNSMethod6::from_i32(selected as i32);
|
||||||
|
wifi_options_ip6.set_ip6_visibility(selected);
|
||||||
|
}));
|
||||||
|
|
||||||
|
imp.resetIP6DNS
|
||||||
|
.connect_changed(clone!(@weak imp => move |entry| {
|
||||||
|
let dns_input = entry.text();
|
||||||
|
let mut conn = imp.connection.borrow_mut();
|
||||||
|
conn.ipv6.dns.clear();
|
||||||
|
if dns_input.is_empty() {
|
||||||
|
imp.resetIP6DNS.remove_css_class("error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for dns_entry in dns_input.as_str().split(',').map(|s| s.trim()) {
|
||||||
|
if let Ok(addr) = Ipv6Addr::from_str(dns_entry) {
|
||||||
|
imp.resetIP6DNS.remove_css_class("error");
|
||||||
|
conn.ipv6.dns.push(addr.octets().to_vec());
|
||||||
|
} else {
|
||||||
|
imp.resetIP6DNS.add_css_class("error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
imp.resetIP6AddressAddButton
|
||||||
|
.connect_clicked(clone!(@weak imp => move |_| {
|
||||||
|
let address = &WifiAddressEntry::new(None, imp.connection.clone(), IpProtocol::IPv4);
|
||||||
|
imp.resetIP6AddressGroup.add(address);
|
||||||
|
}));
|
||||||
|
|
||||||
|
imp.resetIP6Gateway
|
||||||
|
.connect_changed(clone!(@weak imp => move |entry| {
|
||||||
|
let gateway_input = entry.text();
|
||||||
|
let mut conn = imp.connection.borrow_mut();
|
||||||
|
conn.ipv6.gateway.clear();
|
||||||
|
if gateway_input.is_empty() {
|
||||||
|
imp.resetIP6Gateway.remove_css_class("error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if Ipv6Addr::from_str(gateway_input.as_str()).is_ok() {
|
||||||
|
imp.resetIP6Gateway.remove_css_class("error");
|
||||||
|
conn.ipv6.gateway = gateway_input.to_string();
|
||||||
|
} else {
|
||||||
|
imp.resetIP6Gateway.add_css_class("error");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Security
|
||||||
|
imp.resetWifiSecurityDropdown
|
||||||
|
.connect_selected_notify(clone!(@weak imp => move |dropdown| {
|
||||||
|
let selected = dropdown.selected();
|
||||||
|
let mut conn = imp.connection.borrow_mut();
|
||||||
|
|
||||||
|
match (selected, &mut conn.device) {
|
||||||
|
(0 , TypeSettings::WIFI(wifi)) => { // None
|
||||||
|
imp.resetWifiPassword.set_visible(false);
|
||||||
|
wifi.security_settings.key_management = String::from("none");
|
||||||
|
wifi.security_settings.authentication_algorithm = String::from("open");
|
||||||
|
},
|
||||||
|
(1 , TypeSettings::WIFI(wifi)) => { // WPA/WPA2 Personal
|
||||||
|
imp.resetWifiPassword.set_visible(true);
|
||||||
|
wifi.security_settings.key_management = String::from("wpa-psk");
|
||||||
|
wifi.security_settings.authentication_algorithm = String::from("");
|
||||||
|
},
|
||||||
|
(_, _) => {}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
imp.resetWifiPassword
|
||||||
|
.connect_changed(clone!(@weak imp => move |entry| {
|
||||||
|
let password_input = entry.text();
|
||||||
|
let mut conn = imp.connection.borrow_mut();
|
||||||
|
if let TypeSettings::WIFI(wifi) = &mut conn.device {
|
||||||
|
wifi.security_settings.psk = password_input.to_string();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_connection_settings(path: Path<'static>, prop: PropMap) {
|
||||||
|
gio::spawn_blocking(move || {
|
||||||
|
let conn = dbus::blocking::Connection::new_session().unwrap();
|
||||||
|
let proxy = conn.with_proxy(
|
||||||
|
"org.Xetibo.ReSetDaemon",
|
||||||
|
"/org/Xetibo/ReSetDaemon",
|
||||||
|
Duration::from_millis(1000),
|
||||||
|
);
|
||||||
|
let _: Result<(bool,), Error> = proxy.method_call(
|
||||||
|
"org.Xetibo.ReSetWireless",
|
||||||
|
"SetConnectionSettings",
|
||||||
|
(path, prop),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
|
@ -1,12 +1,13 @@
|
||||||
use crate::components::wifi::wifiOptions;
|
use crate::components::wifi::wifi_options;
|
||||||
use adw::subclass::prelude::NavigationPageImpl;
|
use adw::subclass::prelude::NavigationPageImpl;
|
||||||
use adw::{ActionRow, ComboRow, EntryRow, NavigationPage, PasswordEntryRow, PreferencesGroup, SwitchRow};
|
use adw::{
|
||||||
|
ActionRow, ComboRow, EntryRow, NavigationPage, PasswordEntryRow, PreferencesGroup, SwitchRow,
|
||||||
|
};
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, Button, CompositeTemplate};
|
use gtk::{glib, Button, CompositeTemplate};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use ReSet_Lib::network::connection::Connection;
|
use ReSet_Lib::network::connection::Connection;
|
||||||
use ReSet_Lib::network::network::AccessPoint;
|
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[derive(Default, CompositeTemplate)]
|
#[derive(Default, CompositeTemplate)]
|
||||||
|
@ -78,7 +79,7 @@ pub struct WifiOptions {
|
||||||
impl ObjectSubclass for WifiOptions {
|
impl ObjectSubclass for WifiOptions {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetWifiOptions";
|
const NAME: &'static str = "resetWifiOptions";
|
||||||
type Type = wifiOptions::WifiOptions;
|
type Type = wifi_options::WifiOptions;
|
||||||
type ParentType = NavigationPage;
|
type ParentType = NavigationPage;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
242
src/components/wifi/wifi_route_entry.rs
Normal file
242
src/components/wifi/wifi_route_entry.rs
Normal file
|
@ -0,0 +1,242 @@
|
||||||
|
use crate::components::wifi::utils::IpProtocol;
|
||||||
|
use adw::glib;
|
||||||
|
use adw::glib::Object;
|
||||||
|
use adw::prelude::{ExpanderRowExt, PreferencesRowExt};
|
||||||
|
use glib::clone;
|
||||||
|
use glib::subclass::prelude::ObjectSubclassIsExt;
|
||||||
|
use gtk::prelude::{EditableExt, WidgetExt};
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use ReSet_Lib::network::connection::{Address, Connection};
|
||||||
|
|
||||||
|
use crate::components::wifi::wifi_route_entry_impl;
|
||||||
|
use crate::components::wifi::wifi_route_entry_impl::WifiRouteEntryImpl;
|
||||||
|
|
||||||
|
glib::wrapper! {
|
||||||
|
pub struct WifiRouteEntry(ObjectSubclass<wifi_route_entry_impl::WifiRouteEntryImpl>)
|
||||||
|
@extends gtk::Box, gtk::Widget,
|
||||||
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WifiRouteEntry {
|
||||||
|
pub fn new(
|
||||||
|
address: Option<usize>,
|
||||||
|
conn: Rc<RefCell<Connection>>,
|
||||||
|
protocol: IpProtocol,
|
||||||
|
) -> Self {
|
||||||
|
let entry: WifiRouteEntry = Object::builder().build();
|
||||||
|
let entry_imp = entry.imp();
|
||||||
|
|
||||||
|
if let Some(address) = address {
|
||||||
|
let conn = conn.borrow();
|
||||||
|
let address = unsafe { conn.ipv4.route_data.get_unchecked(address) };
|
||||||
|
|
||||||
|
entry_imp.resetRouteAddress.set_text(&address.address);
|
||||||
|
entry_imp
|
||||||
|
.resetRoutePrefix
|
||||||
|
.set_text(&address.prefix_length.to_string());
|
||||||
|
if let Some(gateway) = &address.gateway {
|
||||||
|
entry_imp.resetRouteGateway.set_text(gateway);
|
||||||
|
}
|
||||||
|
if let Some(metric) = address.metric {
|
||||||
|
entry_imp.resetRouteMetric.set_text(&metric.to_string());
|
||||||
|
}
|
||||||
|
entry_imp
|
||||||
|
.resetRouteRow
|
||||||
|
.set_title(&format!("{}/{}", &*address.address, address.prefix_length));
|
||||||
|
}
|
||||||
|
entry_imp.protocol.set(protocol);
|
||||||
|
entry.setup_callbacks(conn);
|
||||||
|
entry
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_callbacks(&self, connection: Rc<RefCell<Connection>>) {
|
||||||
|
let self_imp = self.imp();
|
||||||
|
|
||||||
|
let conn = connection.clone();
|
||||||
|
self_imp.resetRouteAddress.connect_changed(clone!(@weak self_imp => move |entry| {
|
||||||
|
let address_input = entry.text();
|
||||||
|
let mut conn = conn.borrow_mut();
|
||||||
|
|
||||||
|
if address_input.is_empty() {
|
||||||
|
self_imp.resetRouteAddress.remove_css_class("error");
|
||||||
|
self_imp.resetRouteRow.set_title("Add new address");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let result = match self_imp.protocol.get() {
|
||||||
|
IpProtocol::IPv4 => Ipv4Addr::from_str(address_input.as_str()).map(IpAddr::V4),
|
||||||
|
IpProtocol::IPv6 => Ipv6Addr::from_str(address_input.as_str()).map(IpAddr::V6),
|
||||||
|
};
|
||||||
|
match result {
|
||||||
|
Ok(ip_addr) => {
|
||||||
|
self_imp.resetRouteAddress.remove_css_class("error");
|
||||||
|
let address_data = match self_imp.protocol.get() {
|
||||||
|
IpProtocol::IPv4 => &mut conn.ipv4.route_data,
|
||||||
|
IpProtocol::IPv6 => &mut conn.ipv6.route_data,
|
||||||
|
};
|
||||||
|
address_data.push(Address::new(ip_addr.to_string(), self_imp.prefix.get().1 as u32,self_imp.gateway.borrow().clone() ,self_imp.metric.get()));
|
||||||
|
*self_imp.address.borrow_mut() = (true, ip_addr.to_string());
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
self_imp.resetRouteAddress.add_css_class("error");
|
||||||
|
*self_imp.address.borrow_mut() = (false, String::default());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_row_title(&self_imp);
|
||||||
|
}));
|
||||||
|
|
||||||
|
let conn = connection.clone();
|
||||||
|
self_imp.resetRoutePrefix.connect_changed(clone!(@weak self_imp => move |entry| {
|
||||||
|
let prefix_input = entry.text();
|
||||||
|
let prefix = prefix_input.parse::<u8>();
|
||||||
|
let mut conn = conn.borrow_mut();
|
||||||
|
|
||||||
|
let handle_error = || {
|
||||||
|
if self_imp.resetRoutePrefix.text().is_empty() {
|
||||||
|
self_imp.resetRoutePrefix.remove_css_class("error");
|
||||||
|
} else {
|
||||||
|
self_imp.resetRoutePrefix.add_css_class("error");
|
||||||
|
}
|
||||||
|
self_imp.prefix.set((false, 0));
|
||||||
|
set_row_title(&self_imp);
|
||||||
|
};
|
||||||
|
|
||||||
|
if prefix_input.is_empty() || prefix.is_err() {
|
||||||
|
handle_error();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let prefix = prefix.unwrap();
|
||||||
|
match self_imp.protocol.get() {
|
||||||
|
IpProtocol::IPv4 if prefix <= 32 => {
|
||||||
|
self_imp.prefix.set((true, prefix as u32));
|
||||||
|
self_imp.resetRoutePrefix.remove_css_class("error");
|
||||||
|
if let Ok(address2) = Ipv4Addr::from_str(self_imp.resetRouteAddress.text().as_str()) {
|
||||||
|
if let Some(addr) = conn.ipv4.route_data.iter_mut()
|
||||||
|
.find(|conn_addr| *conn_addr.address == address2.to_string()) {
|
||||||
|
addr.prefix_length = prefix as u32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IpProtocol::IPv6 if prefix <= 128 => {
|
||||||
|
self_imp.prefix.set((true, prefix as u32));
|
||||||
|
self_imp.resetRoutePrefix.remove_css_class("error");
|
||||||
|
if let Ok(address2) = Ipv6Addr::from_str(self_imp.resetRouteAddress.text().as_str()) {
|
||||||
|
if let Some(addr) = conn.ipv6.route_data.iter_mut()
|
||||||
|
.find(|conn_addr| *conn_addr.address == address2.to_string()) {
|
||||||
|
addr.prefix_length = prefix as u32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => handle_error()
|
||||||
|
}
|
||||||
|
set_row_title(&self_imp);
|
||||||
|
}));
|
||||||
|
|
||||||
|
let conn = connection.clone();
|
||||||
|
self_imp
|
||||||
|
.resetRouteGateway
|
||||||
|
.connect_changed(clone!(@weak self_imp => move |entry| {
|
||||||
|
let gateway_input = entry.text();
|
||||||
|
let mut conn = conn.borrow_mut();
|
||||||
|
|
||||||
|
if gateway_input.is_empty() {
|
||||||
|
self_imp.resetRouteGateway.remove_css_class("error");
|
||||||
|
*self_imp.gateway.borrow_mut() = None;
|
||||||
|
set_row_subtitle(&self_imp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let result = match self_imp.protocol.get() {
|
||||||
|
IpProtocol::IPv4 => Ipv4Addr::from_str(gateway_input.as_str()).map(IpAddr::V4),
|
||||||
|
IpProtocol::IPv6 => Ipv6Addr::from_str(gateway_input.as_str()).map(IpAddr::V6),
|
||||||
|
};
|
||||||
|
match result {
|
||||||
|
Ok(ip_addr) => {
|
||||||
|
self_imp.resetRouteGateway.remove_css_class("error");
|
||||||
|
let address_data = match self_imp.protocol.get() {
|
||||||
|
IpProtocol::IPv4 => &mut conn.ipv4.route_data,
|
||||||
|
IpProtocol::IPv6 => &mut conn.ipv6.route_data,
|
||||||
|
};
|
||||||
|
if let Some(address) = address_data.iter_mut()
|
||||||
|
.find(|conn_addr| *conn_addr.address == self_imp.resetRouteAddress.text()) {
|
||||||
|
address.gateway = Some(ip_addr.to_string());
|
||||||
|
}
|
||||||
|
*self_imp.gateway.borrow_mut() = Some(ip_addr.to_string());
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
self_imp.resetRouteGateway.add_css_class("error");
|
||||||
|
*self_imp.gateway.borrow_mut() = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_row_subtitle(&self_imp);
|
||||||
|
}));
|
||||||
|
|
||||||
|
let conn = connection.clone();
|
||||||
|
self_imp
|
||||||
|
.resetRouteMetric
|
||||||
|
.connect_changed(clone!(@weak self_imp => move |entry| {
|
||||||
|
let metric_input = entry.text();
|
||||||
|
let mut conn = conn.borrow_mut();
|
||||||
|
|
||||||
|
if metric_input.is_empty() {
|
||||||
|
self_imp.resetRouteMetric.remove_css_class("error");
|
||||||
|
self_imp.metric.set(None);
|
||||||
|
set_row_subtitle(&self_imp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let result = metric_input.parse::<u32>();
|
||||||
|
match result {
|
||||||
|
Ok(metric) => {
|
||||||
|
self_imp.resetRouteMetric.remove_css_class("error");
|
||||||
|
let address_data = match self_imp.protocol.get() {
|
||||||
|
IpProtocol::IPv4 => &mut conn.ipv4.route_data,
|
||||||
|
IpProtocol::IPv6 => &mut conn.ipv6.route_data,
|
||||||
|
};
|
||||||
|
if let Some(address) = address_data.iter_mut()
|
||||||
|
.find(|conn_addr| *conn_addr.address == self_imp.resetRouteAddress.text()) {
|
||||||
|
address.metric = Some(metric);
|
||||||
|
}
|
||||||
|
self_imp.metric.set(Some(metric));
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
self_imp.resetRouteMetric.add_css_class("error");
|
||||||
|
self_imp.metric.set(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_row_subtitle(&self_imp);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_row_title(self_imp: &WifiRouteEntryImpl) {
|
||||||
|
if self_imp.resetRouteAddress.text().is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let address = self_imp.address.borrow();
|
||||||
|
let prefix = self_imp.prefix.get();
|
||||||
|
let title = match (address.0, prefix.0) {
|
||||||
|
(true, true) => {
|
||||||
|
format!("{}/{}", address.1, prefix.1)
|
||||||
|
}
|
||||||
|
(true, false) => "Prefix wrong".to_string(),
|
||||||
|
(false, true) => "Address wrong".to_string(),
|
||||||
|
(false, false) => "Address and Prefix wrong".to_string(),
|
||||||
|
};
|
||||||
|
self_imp.resetRouteRow.set_title(&title);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_row_subtitle(self_imp: &WifiRouteEntryImpl) {
|
||||||
|
let gateway = self_imp.gateway.borrow().clone();
|
||||||
|
let metric = self_imp.metric.get();
|
||||||
|
let title = match (gateway, metric) {
|
||||||
|
(Some(gateway), Some(metric)) => {
|
||||||
|
format!("{}, {}", gateway, metric)
|
||||||
|
}
|
||||||
|
(Some(gateway), None) => gateway,
|
||||||
|
(None, Some(metric)) => metric.to_string(),
|
||||||
|
(None, None) => String::default(),
|
||||||
|
};
|
||||||
|
self_imp.resetRouteRow.set_subtitle(&title);
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::components::wifi::utils::IpProtocol;
|
use crate::components::wifi::utils::IpProtocol;
|
||||||
use crate::components::wifi::wifiRouteEntry;
|
use crate::components::wifi::wifi_route_entry;
|
||||||
use adw::{EntryRow, ExpanderRow};
|
use adw::{EntryRow, ExpanderRow};
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, Button, CompositeTemplate};
|
use gtk::{glib, Button, CompositeTemplate};
|
||||||
|
@ -32,7 +32,7 @@ pub struct WifiRouteEntryImpl {
|
||||||
impl ObjectSubclass for WifiRouteEntryImpl {
|
impl ObjectSubclass for WifiRouteEntryImpl {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetWifiRouteEntry";
|
const NAME: &'static str = "resetWifiRouteEntry";
|
||||||
type Type = wifiRouteEntry::WifiRouteEntry;
|
type Type = wifi_route_entry::WifiRouteEntry;
|
||||||
type ParentType = gtk::Box;
|
type ParentType = gtk::Box;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
|
@ -2,123 +2,123 @@ use gtk::prelude::FrameExt;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::components::base::settingBox::SettingBox;
|
use crate::components::base::setting_box::SettingBox;
|
||||||
use crate::components::base::utils::{start_audio_listener, Listeners};
|
use crate::components::base::utils::{start_audio_listener, Listeners};
|
||||||
use crate::components::bluetooth::bluetoothBox::{
|
use crate::components::bluetooth::bluetooth_box::{
|
||||||
populate_conntected_bluetooth_devices, start_bluetooth_listener, BluetoothBox,
|
populate_conntected_bluetooth_devices, start_bluetooth_listener, BluetoothBox,
|
||||||
};
|
};
|
||||||
use crate::components::input::sourceBox::{populate_sources, SourceBox};
|
use crate::components::input::source_box::{populate_sources, SourceBox};
|
||||||
use crate::components::output::sinkBox::{populate_sinks, SinkBox};
|
use crate::components::output::sink_box::{populate_sinks, SinkBox};
|
||||||
use crate::components::wifi::wifiBox::{
|
use crate::components::wifi::wifi_box::{
|
||||||
scanForWifi, show_stored_connections, start_event_listener, WifiBox,
|
scan_for_wifi, show_stored_connections, start_event_listener, WifiBox,
|
||||||
};
|
};
|
||||||
use gtk::prelude::WidgetExt;
|
use gtk::prelude::WidgetExt;
|
||||||
use gtk::{FlowBox, Frame};
|
use gtk::{FlowBox, Frame};
|
||||||
|
|
||||||
pub const HANDLE_CONNECTIVITY_CLICK: fn(Arc<Listeners>, FlowBox) =
|
pub const HANDLE_CONNECTIVITY_CLICK: fn(Arc<Listeners>, FlowBox) =
|
||||||
|listeners: Arc<Listeners>, resetMain: FlowBox| {
|
|listeners: Arc<Listeners>, reset_main: FlowBox| {
|
||||||
listeners.stop_audio_listener();
|
listeners.stop_audio_listener();
|
||||||
let wifiBox = WifiBox::new(listeners.clone());
|
let wifi_box = WifiBox::new(listeners.clone());
|
||||||
start_event_listener(listeners.clone(), wifiBox.clone());
|
start_event_listener(listeners.clone(), wifi_box.clone());
|
||||||
show_stored_connections(wifiBox.clone());
|
show_stored_connections(wifi_box.clone());
|
||||||
scanForWifi(wifiBox.clone());
|
scan_for_wifi(wifi_box.clone());
|
||||||
let wifiFrame = wrapInFrame(SettingBox::new(&*wifiBox));
|
let wifi_frame = wrap_in_frame(SettingBox::new(&*wifi_box));
|
||||||
let bluetooth_box = BluetoothBox::new(listeners.clone());
|
let bluetooth_box = BluetoothBox::new(listeners.clone());
|
||||||
populate_conntected_bluetooth_devices(bluetooth_box.clone());
|
populate_conntected_bluetooth_devices(bluetooth_box.clone());
|
||||||
start_bluetooth_listener(listeners.clone(), bluetooth_box.clone());
|
start_bluetooth_listener(listeners.clone(), bluetooth_box.clone());
|
||||||
let bluetoothFrame = wrapInFrame(SettingBox::new(&*bluetooth_box));
|
let bluetooth_frame = wrap_in_frame(SettingBox::new(&*bluetooth_box));
|
||||||
resetMain.remove_all();
|
reset_main.remove_all();
|
||||||
resetMain.insert(&wifiFrame, -1);
|
reset_main.insert(&wifi_frame, -1);
|
||||||
resetMain.insert(&bluetoothFrame, -1);
|
reset_main.insert(&bluetooth_frame, -1);
|
||||||
resetMain.set_max_children_per_line(2);
|
reset_main.set_max_children_per_line(2);
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HANDLE_WIFI_CLICK: fn(Arc<Listeners>, FlowBox) =
|
pub const HANDLE_WIFI_CLICK: fn(Arc<Listeners>, FlowBox) =
|
||||||
|listeners: Arc<Listeners>, resetMain: FlowBox| {
|
|listeners: Arc<Listeners>, reset_main: FlowBox| {
|
||||||
listeners.stop_audio_listener();
|
listeners.stop_audio_listener();
|
||||||
listeners.stop_bluetooth_listener();
|
listeners.stop_bluetooth_listener();
|
||||||
let wifiBox = WifiBox::new(listeners.clone());
|
let wifi_box = WifiBox::new(listeners.clone());
|
||||||
start_event_listener(listeners.clone(), wifiBox.clone());
|
start_event_listener(listeners.clone(), wifi_box.clone());
|
||||||
show_stored_connections(wifiBox.clone());
|
show_stored_connections(wifi_box.clone());
|
||||||
scanForWifi(wifiBox.clone());
|
scan_for_wifi(wifi_box.clone());
|
||||||
let wifiFrame = wrapInFrame(SettingBox::new(&*wifiBox));
|
let wifi_frame = wrap_in_frame(SettingBox::new(&*wifi_box));
|
||||||
resetMain.remove_all();
|
reset_main.remove_all();
|
||||||
resetMain.insert(&wifiFrame, -1);
|
reset_main.insert(&wifi_frame, -1);
|
||||||
resetMain.set_max_children_per_line(1);
|
reset_main.set_max_children_per_line(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HANDLE_BLUETOOTH_CLICK: fn(Arc<Listeners>, FlowBox) =
|
pub const HANDLE_BLUETOOTH_CLICK: fn(Arc<Listeners>, FlowBox) =
|
||||||
|listeners: Arc<Listeners>, resetMain: FlowBox| {
|
|listeners: Arc<Listeners>, reset_main: FlowBox| {
|
||||||
listeners.stop_network_listener();
|
listeners.stop_network_listener();
|
||||||
listeners.stop_audio_listener();
|
listeners.stop_audio_listener();
|
||||||
let bluetooth_box = BluetoothBox::new(listeners.clone());
|
let bluetooth_box = BluetoothBox::new(listeners.clone());
|
||||||
start_bluetooth_listener(listeners.clone(), bluetooth_box.clone());
|
start_bluetooth_listener(listeners.clone(), bluetooth_box.clone());
|
||||||
populate_conntected_bluetooth_devices(bluetooth_box.clone());
|
populate_conntected_bluetooth_devices(bluetooth_box.clone());
|
||||||
let bluetoothFrame = wrapInFrame(SettingBox::new(&*bluetooth_box));
|
let bluetooth_frame = wrap_in_frame(SettingBox::new(&*bluetooth_box));
|
||||||
resetMain.remove_all();
|
reset_main.remove_all();
|
||||||
resetMain.insert(&bluetoothFrame, -1);
|
reset_main.insert(&bluetooth_frame, -1);
|
||||||
resetMain.set_max_children_per_line(1);
|
reset_main.set_max_children_per_line(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HANDLE_AUDIO_CLICK: fn(Arc<Listeners>, FlowBox) =
|
pub const HANDLE_AUDIO_CLICK: fn(Arc<Listeners>, FlowBox) =
|
||||||
|listeners: Arc<Listeners>, resetMain: FlowBox| {
|
|listeners: Arc<Listeners>, reset_main: FlowBox| {
|
||||||
listeners.stop_network_listener();
|
listeners.stop_network_listener();
|
||||||
listeners.stop_bluetooth_listener();
|
listeners.stop_bluetooth_listener();
|
||||||
let audioOutput = Arc::new(SinkBox::new());
|
let audio_output = Arc::new(SinkBox::new());
|
||||||
let audioInput = Arc::new(SourceBox::new());
|
let audio_input = Arc::new(SourceBox::new());
|
||||||
start_audio_listener(
|
start_audio_listener(
|
||||||
listeners.clone(),
|
listeners.clone(),
|
||||||
Some(audioOutput.clone()),
|
Some(audio_output.clone()),
|
||||||
Some(audioInput.clone()),
|
Some(audio_input.clone()),
|
||||||
);
|
);
|
||||||
populate_sinks(audioOutput.clone());
|
populate_sinks(audio_output.clone());
|
||||||
let audioFrame = wrapInFrame(SettingBox::new(&*audioOutput));
|
let audio_frame = wrap_in_frame(SettingBox::new(&*audio_output));
|
||||||
populate_sources(audioInput.clone());
|
populate_sources(audio_input.clone());
|
||||||
let sourceFrame = wrapInFrame(SettingBox::new(&*audioInput));
|
let source_frame = wrap_in_frame(SettingBox::new(&*audio_input));
|
||||||
resetMain.remove_all();
|
reset_main.remove_all();
|
||||||
resetMain.insert(&audioFrame, -1);
|
reset_main.insert(&audio_frame, -1);
|
||||||
resetMain.insert(&sourceFrame, -1);
|
reset_main.insert(&source_frame, -1);
|
||||||
resetMain.set_max_children_per_line(2);
|
reset_main.set_max_children_per_line(2);
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HANDLE_VOLUME_CLICK: fn(Arc<Listeners>, FlowBox) =
|
pub const HANDLE_VOLUME_CLICK: fn(Arc<Listeners>, FlowBox) =
|
||||||
|listeners: Arc<Listeners>, resetMain: FlowBox| {
|
|listeners: Arc<Listeners>, reset_main: FlowBox| {
|
||||||
listeners.stop_network_listener();
|
listeners.stop_network_listener();
|
||||||
listeners.stop_bluetooth_listener();
|
listeners.stop_bluetooth_listener();
|
||||||
let audioOutput = Arc::new(SinkBox::new());
|
let audio_output = Arc::new(SinkBox::new());
|
||||||
start_audio_listener(listeners.clone(), Some(audioOutput.clone()), None);
|
start_audio_listener(listeners.clone(), Some(audio_output.clone()), None);
|
||||||
while !listeners.pulse_listener.load(Ordering::SeqCst) {
|
while !listeners.pulse_listener.load(Ordering::SeqCst) {
|
||||||
std::hint::spin_loop()
|
std::hint::spin_loop()
|
||||||
}
|
}
|
||||||
populate_sinks(audioOutput.clone());
|
populate_sinks(audio_output.clone());
|
||||||
let audioFrame = wrapInFrame(SettingBox::new(&*audioOutput));
|
let audio_frame = wrap_in_frame(SettingBox::new(&*audio_output));
|
||||||
resetMain.remove_all();
|
reset_main.remove_all();
|
||||||
resetMain.insert(&audioFrame, -1);
|
reset_main.insert(&audio_frame, -1);
|
||||||
resetMain.set_max_children_per_line(1);
|
reset_main.set_max_children_per_line(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HANDLE_MICROPHONE_CLICK: fn(Arc<Listeners>, FlowBox) =
|
pub const HANDLE_MICROPHONE_CLICK: fn(Arc<Listeners>, FlowBox) =
|
||||||
|listeners: Arc<Listeners>, resetMain: FlowBox| {
|
|listeners: Arc<Listeners>, reset_main: FlowBox| {
|
||||||
listeners.stop_network_listener();
|
listeners.stop_network_listener();
|
||||||
listeners.stop_bluetooth_listener();
|
listeners.stop_bluetooth_listener();
|
||||||
let audioInput = Arc::new(SourceBox::new());
|
let audio_input = Arc::new(SourceBox::new());
|
||||||
start_audio_listener(listeners.clone(), None, Some(audioInput.clone()));
|
start_audio_listener(listeners.clone(), None, Some(audio_input.clone()));
|
||||||
populate_sources(audioInput.clone());
|
populate_sources(audio_input.clone());
|
||||||
let sourceFrame = wrapInFrame(SettingBox::new(&*audioInput));
|
let source_frame = wrap_in_frame(SettingBox::new(&*audio_input));
|
||||||
resetMain.remove_all();
|
reset_main.remove_all();
|
||||||
resetMain.insert(&sourceFrame, -1);
|
reset_main.insert(&source_frame, -1);
|
||||||
resetMain.set_max_children_per_line(1);
|
reset_main.set_max_children_per_line(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HANDLE_HOME: fn(Arc<Listeners>, FlowBox) =
|
pub const HANDLE_HOME: fn(Arc<Listeners>, FlowBox) =
|
||||||
|listeners: Arc<Listeners>, resetMain: FlowBox| {
|
|listeners: Arc<Listeners>, reset_main: FlowBox| {
|
||||||
listeners.stop_network_listener();
|
listeners.stop_network_listener();
|
||||||
listeners.stop_audio_listener();
|
listeners.stop_audio_listener();
|
||||||
listeners.stop_bluetooth_listener();
|
listeners.stop_bluetooth_listener();
|
||||||
resetMain.remove_all();
|
reset_main.remove_all();
|
||||||
};
|
};
|
||||||
|
|
||||||
fn wrapInFrame(widget: SettingBox) -> Frame {
|
fn wrap_in_frame(widget: SettingBox) -> Frame {
|
||||||
let frame = Frame::new(None);
|
let frame = Frame::new(None);
|
||||||
frame.set_child(Some(&widget));
|
frame.set_child(Some(&widget));
|
||||||
frame.add_css_class("resetSettingFrame");
|
frame.add_css_class("resetSettingFrame");
|
|
@ -1,6 +1,5 @@
|
||||||
#![allow(non_snake_case)]
|
pub mod handle_sidebar_click;
|
||||||
pub mod handleSidebarClick;
|
pub mod reset_window;
|
||||||
pub mod resetWindow;
|
pub mod reset_window_impl;
|
||||||
pub mod resetWindowImpl;
|
pub mod sidebar_entry;
|
||||||
pub mod sidebarEntry;
|
pub mod sidebar_entry_impl;
|
||||||
pub mod sidebarEntryImpl;
|
|
||||||
|
|
|
@ -5,13 +5,13 @@ use glib::Object;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{gio, glib, Application, ListBoxRow, Orientation};
|
use gtk::{gio, glib, Application, ListBoxRow, Orientation};
|
||||||
|
|
||||||
use crate::components::window::handleSidebarClick::*;
|
use crate::components::window::handle_sidebar_click::*;
|
||||||
use crate::components::window::resetWindowImpl;
|
use crate::components::window::reset_window_impl;
|
||||||
use crate::components::window::sidebarEntry::SidebarEntry;
|
use crate::components::window::sidebar_entry::SidebarEntry;
|
||||||
use crate::components::window::sidebarEntryImpl::Categories;
|
use crate::components::window::sidebar_entry_impl::Categories;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct ReSetWindow(ObjectSubclass<resetWindowImpl::ReSetWindow>)
|
pub struct ReSetWindow(ObjectSubclass<reset_window_impl::ReSetWindow>)
|
||||||
@extends gtk::ApplicationWindow, gtk::Window, gtk::Widget,
|
@extends gtk::ApplicationWindow, gtk::Window, gtk::Widget,
|
||||||
@implements gio::ActionGroup, gio::ActionMap, gtk::Accessible, gtk::Buildable,
|
@implements gio::ActionGroup, gio::ActionMap, gtk::Accessible, gtk::Buildable,
|
||||||
gtk::ConstraintTarget, gtk::Native, gtk::Root, gtk::ShortcutManager;
|
gtk::ConstraintTarget, gtk::Native, gtk::Root, gtk::ShortcutManager;
|
||||||
|
@ -21,36 +21,35 @@ unsafe impl Send for ReSetWindow {}
|
||||||
|
|
||||||
unsafe impl Sync for ReSetWindow {}
|
unsafe impl Sync for ReSetWindow {}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
impl ReSetWindow {
|
impl ReSetWindow {
|
||||||
pub fn new(app: &Application) -> Self {
|
pub fn new(app: &Application) -> Self {
|
||||||
Object::builder().property("application", app).build()
|
Object::builder().property("application", app).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setupCallback(&self) {
|
pub fn setup_callback(&self) {
|
||||||
let selfImp = self.imp();
|
let self_imp = self.imp();
|
||||||
|
|
||||||
selfImp
|
self_imp.resetSearchEntry.connect_search_changed(
|
||||||
.resetSearchEntry
|
clone!(@ weak self as window => move |_| {
|
||||||
.connect_search_changed(clone!(@ weak self as window => move |_| {
|
window.filter_list();
|
||||||
window.filterList();
|
|
||||||
}));
|
|
||||||
|
|
||||||
selfImp
|
|
||||||
.resetSideBarToggle
|
|
||||||
.connect_clicked(clone!(@ weak self as window => move |_| {
|
|
||||||
window.toggleSidebar();
|
|
||||||
}));
|
|
||||||
|
|
||||||
selfImp.resetSidebarList.connect_row_activated(
|
|
||||||
clone!(@ weak selfImp as flowbox => move |_, y| {
|
|
||||||
let result = y.downcast_ref::<SidebarEntry>().unwrap();
|
|
||||||
let clickEvent = result.imp().onClickEvent.borrow().onClickEvent;
|
|
||||||
(clickEvent)(flowbox.listeners.clone(), flowbox.resetMain.get());
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
selfImp
|
self_imp
|
||||||
|
.resetSideBarToggle
|
||||||
|
.connect_clicked(clone!(@ weak self as window => move |_| {
|
||||||
|
window.toggle_sidebar();
|
||||||
|
}));
|
||||||
|
|
||||||
|
self_imp.resetSidebarList.connect_row_activated(
|
||||||
|
clone!(@ weak self_imp as flowbox => move |_, y| {
|
||||||
|
let result = y.downcast_ref::<SidebarEntry>().unwrap();
|
||||||
|
let click_event = result.imp().on_click_event.borrow().on_click_event;
|
||||||
|
(click_event)(flowbox.listeners.clone(), flowbox.resetMain.get());
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
self_imp
|
||||||
.resetClose
|
.resetClose
|
||||||
.connect_clicked(clone!(@ weak self as window => move |_| {
|
.connect_clicked(clone!(@ weak self as window => move |_| {
|
||||||
window.close();
|
window.close();
|
||||||
|
@ -62,62 +61,62 @@ impl ReSetWindow {
|
||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handleDynamicSidebar(&self) {
|
pub fn handle_dynamic_sidebar(&self) {
|
||||||
let selfImp = self.imp();
|
let self_imp = self.imp();
|
||||||
selfImp
|
self_imp
|
||||||
.resetSidebarBreakpoint
|
.resetSidebarBreakpoint
|
||||||
.set_condition(BreakpointCondition::parse("max-width: 700sp").as_ref().ok());
|
.set_condition(BreakpointCondition::parse("max-width: 700sp").as_ref().ok());
|
||||||
selfImp.resetSidebarBreakpoint.add_setter(
|
self_imp.resetSidebarBreakpoint.add_setter(
|
||||||
&Object::from(selfImp.resetOverlaySplitView.get()),
|
&Object::from(self_imp.resetOverlaySplitView.get()),
|
||||||
"collapsed",
|
"collapsed",
|
||||||
&true.to_value(),
|
&true.to_value(),
|
||||||
);
|
);
|
||||||
selfImp.resetSidebarBreakpoint.add_setter(
|
self_imp.resetSidebarBreakpoint.add_setter(
|
||||||
&Object::from(selfImp.resetSideBarToggle.get()),
|
&Object::from(self_imp.resetSideBarToggle.get()),
|
||||||
"visible",
|
"visible",
|
||||||
&true.to_value(),
|
&true.to_value(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn filterList(&self) {
|
pub fn filter_list(&self) {
|
||||||
let text = self.imp().resetSearchEntry.text().to_string();
|
let text = self.imp().resetSearchEntry.text().to_string();
|
||||||
for (mainEntry, subEntries) in self.imp().sidebarEntries.borrow().iter() {
|
for (main_entry, sub_entriess) in self.imp().sidebar_entries.borrow().iter() {
|
||||||
if text.is_empty() {
|
if text.is_empty() {
|
||||||
mainEntry.set_visible(true);
|
main_entry.set_visible(true);
|
||||||
for subEntry in subEntries {
|
for sub_entry in sub_entriess {
|
||||||
subEntry.set_visible(true);
|
sub_entry.set_visible(true);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if mainEntry
|
if main_entry
|
||||||
.imp()
|
.imp()
|
||||||
.name
|
.name
|
||||||
.borrow()
|
.borrow()
|
||||||
.to_lowercase()
|
.to_lowercase()
|
||||||
.contains(&text.to_lowercase())
|
.contains(&text.to_lowercase())
|
||||||
{
|
{
|
||||||
mainEntry.set_visible(true);
|
main_entry.set_visible(true);
|
||||||
} else {
|
} else {
|
||||||
mainEntry.set_visible(false);
|
main_entry.set_visible(false);
|
||||||
}
|
}
|
||||||
for subEntry in subEntries {
|
for sub_entry in sub_entriess {
|
||||||
if subEntry
|
if sub_entry
|
||||||
.imp()
|
.imp()
|
||||||
.name
|
.name
|
||||||
.borrow()
|
.borrow()
|
||||||
.to_lowercase()
|
.to_lowercase()
|
||||||
.contains(&text.to_lowercase())
|
.contains(&text.to_lowercase())
|
||||||
{
|
{
|
||||||
subEntry.set_visible(true);
|
sub_entry.set_visible(true);
|
||||||
mainEntry.set_visible(true);
|
main_entry.set_visible(true);
|
||||||
} else {
|
} else {
|
||||||
subEntry.set_visible(false);
|
sub_entry.set_visible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggleSidebar(&self) {
|
pub fn toggle_sidebar(&self) {
|
||||||
if self.imp().resetOverlaySplitView.shows_sidebar() {
|
if self.imp().resetOverlaySplitView.shows_sidebar() {
|
||||||
self.imp().resetOverlaySplitView.set_show_sidebar(false);
|
self.imp().resetOverlaySplitView.set_show_sidebar(false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -125,11 +124,11 @@ impl ReSetWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setupSidebarEntries(&self) {
|
pub fn setup_sidebar_entries(&self) {
|
||||||
let selfImp = self.imp();
|
let self_imp = self.imp();
|
||||||
let mut sidebarEntries = selfImp.sidebarEntries.borrow_mut();
|
let mut sidebar_entries = self_imp.sidebar_entries.borrow_mut();
|
||||||
|
|
||||||
let connectivityList = vec![
|
let connectivity_list = vec![
|
||||||
SidebarEntry::new(
|
SidebarEntry::new(
|
||||||
"WiFi",
|
"WiFi",
|
||||||
"network-wireless-symbolic",
|
"network-wireless-symbolic",
|
||||||
|
@ -153,7 +152,7 @@ impl ReSetWindow {
|
||||||
// ),
|
// ),
|
||||||
];
|
];
|
||||||
|
|
||||||
sidebarEntries.push((
|
sidebar_entries.push((
|
||||||
SidebarEntry::new(
|
SidebarEntry::new(
|
||||||
"Connectivity",
|
"Connectivity",
|
||||||
"network-wired-symbolic",
|
"network-wired-symbolic",
|
||||||
|
@ -161,10 +160,10 @@ impl ReSetWindow {
|
||||||
false,
|
false,
|
||||||
HANDLE_CONNECTIVITY_CLICK,
|
HANDLE_CONNECTIVITY_CLICK,
|
||||||
),
|
),
|
||||||
connectivityList,
|
connectivity_list,
|
||||||
));
|
));
|
||||||
|
|
||||||
let audioList = vec![
|
let audio_list = vec![
|
||||||
SidebarEntry::new(
|
SidebarEntry::new(
|
||||||
"Output",
|
"Output",
|
||||||
"audio-volume-high-symbolic",
|
"audio-volume-high-symbolic",
|
||||||
|
@ -181,7 +180,7 @@ impl ReSetWindow {
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
sidebarEntries.push((
|
sidebar_entries.push((
|
||||||
SidebarEntry::new(
|
SidebarEntry::new(
|
||||||
"Audio",
|
"Audio",
|
||||||
"audio-headset-symbolic",
|
"audio-headset-symbolic",
|
||||||
|
@ -189,7 +188,7 @@ impl ReSetWindow {
|
||||||
false,
|
false,
|
||||||
HANDLE_AUDIO_CLICK,
|
HANDLE_AUDIO_CLICK,
|
||||||
),
|
),
|
||||||
audioList,
|
audio_list,
|
||||||
));
|
));
|
||||||
|
|
||||||
// let peripheralsList = vec![
|
// let peripheralsList = vec![
|
||||||
|
@ -227,28 +226,28 @@ impl ReSetWindow {
|
||||||
// peripheralsList,
|
// peripheralsList,
|
||||||
// ));
|
// ));
|
||||||
|
|
||||||
selfImp
|
self_imp
|
||||||
.resetSidebarList
|
.resetSidebarList
|
||||||
.connect_row_activated(clone!(@ weak selfImp => move |_, _| {
|
.connect_row_activated(clone!(@ weak self_imp => move |_, _| {
|
||||||
selfImp.resetSearchEntry.set_text("");
|
self_imp.resetSearchEntry.set_text("");
|
||||||
}));
|
}));
|
||||||
|
|
||||||
for (mainEntry, subEntries) in sidebarEntries.iter() {
|
for (main_entry, sub_entries) in sidebar_entries.iter() {
|
||||||
selfImp.resetSidebarList.append(mainEntry);
|
self_imp.resetSidebarList.append(main_entry);
|
||||||
for subEntry in subEntries {
|
for sub_entry in sub_entries {
|
||||||
selfImp.resetSidebarList.append(subEntry);
|
self_imp.resetSidebarList.append(sub_entry);
|
||||||
}
|
}
|
||||||
let separator = ListBoxRow::new();
|
let separator = ListBoxRow::new();
|
||||||
separator.set_child(Some(>k::Separator::new(Orientation::Horizontal)));
|
separator.set_child(Some(>k::Separator::new(Orientation::Horizontal)));
|
||||||
separator.set_selectable(false);
|
separator.set_selectable(false);
|
||||||
separator.set_activatable(false);
|
separator.set_activatable(false);
|
||||||
selfImp.resetSidebarList.append(&separator);
|
self_imp.resetSidebarList.append(&separator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setupPopoverButtons(&self) {
|
pub fn setup_popover_buttons(&self) {
|
||||||
let selfImp = self.imp();
|
let self_imp = self.imp();
|
||||||
selfImp
|
self_imp
|
||||||
.resetAboutButton
|
.resetAboutButton
|
||||||
.connect_clicked(clone!(@ weak self as window => move |_| {
|
.connect_clicked(clone!(@ weak self as window => move |_| {
|
||||||
let dialog = adw::AboutWindow::builder()
|
let dialog = adw::AboutWindow::builder()
|
||||||
|
@ -269,14 +268,14 @@ impl ReSetWindow {
|
||||||
window.imp().resetPopoverMenu.popdown();
|
window.imp().resetPopoverMenu.popdown();
|
||||||
dialog.present();
|
dialog.present();
|
||||||
}));
|
}));
|
||||||
selfImp
|
self_imp
|
||||||
.resetPreferenceButton
|
.resetPreferenceButton
|
||||||
.connect_clicked(clone!(@weak self as window => move |_| {
|
.connect_clicked(clone!(@weak self as window => move |_| {
|
||||||
let preferences = adw::PreferencesWindow::builder().build();
|
let preferences = adw::PreferencesWindow::builder().build();
|
||||||
window.imp().resetPopoverMenu.popdown();
|
window.imp().resetPopoverMenu.popdown();
|
||||||
preferences.present();
|
preferences.present();
|
||||||
}));
|
}));
|
||||||
selfImp
|
self_imp
|
||||||
.resetShortcutsButton
|
.resetShortcutsButton
|
||||||
.connect_clicked(clone!(@weak self as window => move |_| {
|
.connect_clicked(clone!(@weak self as window => move |_| {
|
||||||
let shortcuts = gtk::ShortcutsWindow::builder().build();
|
let shortcuts = gtk::ShortcutsWindow::builder().build();
|
|
@ -9,9 +9,9 @@ use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, Button, CompositeTemplate, FlowBox, ListBox, PopoverMenu, SearchEntry};
|
use gtk::{glib, Button, CompositeTemplate, FlowBox, ListBox, PopoverMenu, SearchEntry};
|
||||||
|
|
||||||
use crate::components::base::utils::Listeners;
|
use crate::components::base::utils::Listeners;
|
||||||
use crate::components::wifi::wifiBox::WifiBox;
|
use crate::components::wifi::wifi_box::WifiBox;
|
||||||
use crate::components::window::resetWindow;
|
use crate::components::window::reset_window;
|
||||||
use crate::components::window::sidebarEntry::SidebarEntry;
|
use crate::components::window::sidebar_entry::SidebarEntry;
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[derive(CompositeTemplate, Default)]
|
#[derive(CompositeTemplate, Default)]
|
||||||
|
@ -39,7 +39,7 @@ pub struct ReSetWindow {
|
||||||
pub resetPreferenceButton: TemplateChild<Button>,
|
pub resetPreferenceButton: TemplateChild<Button>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub resetShortcutsButton: TemplateChild<Button>,
|
pub resetShortcutsButton: TemplateChild<Button>,
|
||||||
pub sidebarEntries: RefCell<Vec<(SidebarEntry, Vec<SidebarEntry>)>>,
|
pub sidebar_entries: RefCell<Vec<(SidebarEntry, Vec<SidebarEntry>)>>,
|
||||||
pub listeners: Arc<Listeners>,
|
pub listeners: Arc<Listeners>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ unsafe impl Sync for ReSetWindow {}
|
||||||
impl ObjectSubclass for ReSetWindow {
|
impl ObjectSubclass for ReSetWindow {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetUI";
|
const NAME: &'static str = "resetUI";
|
||||||
type Type = resetWindow::ReSetWindow;
|
type Type = reset_window::ReSetWindow;
|
||||||
type ParentType = adw::ApplicationWindow;
|
type ParentType = adw::ApplicationWindow;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
||||||
|
@ -68,10 +68,10 @@ impl ObjectImpl for ReSetWindow {
|
||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
|
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
obj.setupCallback();
|
obj.setup_callback();
|
||||||
obj.setupPopoverButtons();
|
obj.setup_popover_buttons();
|
||||||
obj.handleDynamicSidebar();
|
obj.handle_dynamic_sidebar();
|
||||||
obj.setupSidebarEntries();
|
obj.setup_sidebar_entries();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use crate::components::base::utils::Listeners;
|
|
||||||
use crate::components::window::sidebarEntryImpl;
|
|
||||||
use crate::components::window::sidebarEntryImpl::{Categories, SidebarAction};
|
|
||||||
use adw::subclass::prelude::ObjectSubclassIsExt;
|
|
||||||
use glib::Object;
|
|
||||||
use gtk::prelude::*;
|
|
||||||
use gtk::{glib, FlowBox};
|
|
||||||
|
|
||||||
glib::wrapper! {
|
|
||||||
pub struct SidebarEntry(ObjectSubclass<sidebarEntryImpl::SidebarEntry>)
|
|
||||||
@extends gtk::ListBoxRow, gtk::Widget,
|
|
||||||
@implements gtk::Accessible, gtk::Actionable, gtk::Buildable, gtk::ConstraintTarget;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SidebarEntry {
|
|
||||||
pub fn new(
|
|
||||||
entryName: &str,
|
|
||||||
iconName: &str,
|
|
||||||
category: Categories,
|
|
||||||
isSubcategory: bool,
|
|
||||||
clickEvent: fn(Arc<Listeners>, FlowBox),
|
|
||||||
) -> Self {
|
|
||||||
let entry: SidebarEntry = Object::builder().build();
|
|
||||||
let entryImp = entry.imp();
|
|
||||||
entryImp.resetSidebarLabel.get().set_text(entryName);
|
|
||||||
entryImp
|
|
||||||
.resetSidebarImage
|
|
||||||
.set_from_icon_name(Some(iconName));
|
|
||||||
entryImp.category.set(category);
|
|
||||||
entryImp.isSubcategory.set(isSubcategory);
|
|
||||||
{
|
|
||||||
let mut name = entryImp.name.borrow_mut();
|
|
||||||
*name = String::from(entryName);
|
|
||||||
let mut action = entryImp.onClickEvent.borrow_mut();
|
|
||||||
*action = SidebarAction {
|
|
||||||
onClickEvent: clickEvent,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Self::setMargin(&entry);
|
|
||||||
entry
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setMargin(entry: &SidebarEntry) {
|
|
||||||
if entry.imp().isSubcategory.get() {
|
|
||||||
let option = entry.child().unwrap();
|
|
||||||
option.set_margin_start(30);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
51
src/components/window/sidebar_entry.rs
Normal file
51
src/components/window/sidebar_entry.rs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::components::base::utils::Listeners;
|
||||||
|
use crate::components::window::sidebar_entry_impl;
|
||||||
|
use crate::components::window::sidebar_entry_impl::{Categories, SidebarAction};
|
||||||
|
use adw::subclass::prelude::ObjectSubclassIsExt;
|
||||||
|
use glib::Object;
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use gtk::{glib, FlowBox};
|
||||||
|
|
||||||
|
glib::wrapper! {
|
||||||
|
pub struct SidebarEntry(ObjectSubclass<sidebar_entry_impl::SidebarEntry>)
|
||||||
|
@extends gtk::ListBoxRow, gtk::Widget,
|
||||||
|
@implements gtk::Accessible, gtk::Actionable, gtk::Buildable, gtk::ConstraintTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SidebarEntry {
|
||||||
|
pub fn new(
|
||||||
|
entry_name: &str,
|
||||||
|
icon_name: &str,
|
||||||
|
category: Categories,
|
||||||
|
is_subcategory: bool,
|
||||||
|
click_event: fn(Arc<Listeners>, FlowBox),
|
||||||
|
) -> Self {
|
||||||
|
let entry: SidebarEntry = Object::builder().build();
|
||||||
|
let entry_imp = entry.imp();
|
||||||
|
entry_imp.resetSidebarLabel.get().set_text(entry_name);
|
||||||
|
entry_imp
|
||||||
|
.resetSidebarImage
|
||||||
|
.set_from_icon_name(Some(icon_name));
|
||||||
|
entry_imp.category.set(category);
|
||||||
|
entry_imp.is_subcategory.set(is_subcategory);
|
||||||
|
{
|
||||||
|
let mut name = entry_imp.name.borrow_mut();
|
||||||
|
*name = String::from(entry_name);
|
||||||
|
let mut action = entry_imp.on_click_event.borrow_mut();
|
||||||
|
*action = SidebarAction {
|
||||||
|
on_click_event: click_event,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Self::set_margin(&entry);
|
||||||
|
entry
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_margin(entry: &SidebarEntry) {
|
||||||
|
if entry.imp().is_subcategory.get() {
|
||||||
|
let option = entry.child().unwrap();
|
||||||
|
option.set_margin_start(30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,8 +6,8 @@ use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, CompositeTemplate, FlowBox, Image, Label, ListBoxRow};
|
use gtk::{glib, CompositeTemplate, FlowBox, Image, Label, ListBoxRow};
|
||||||
|
|
||||||
use crate::components::base::utils::Listeners;
|
use crate::components::base::utils::Listeners;
|
||||||
use crate::components::window::handleSidebarClick::HANDLE_HOME;
|
use crate::components::window::handle_sidebar_click::HANDLE_HOME;
|
||||||
use crate::components::window::sidebarEntry;
|
use crate::components::window::sidebar_entry;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub enum Categories {
|
pub enum Categories {
|
||||||
|
@ -27,20 +27,19 @@ pub struct SidebarEntry {
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub resetSidebarImage: TemplateChild<Image>,
|
pub resetSidebarImage: TemplateChild<Image>,
|
||||||
pub category: Cell<Categories>,
|
pub category: Cell<Categories>,
|
||||||
pub isSubcategory: Cell<bool>,
|
pub is_subcategory: Cell<bool>,
|
||||||
pub onClickEvent: RefCell<SidebarAction>,
|
pub on_click_event: RefCell<SidebarAction>,
|
||||||
pub name: RefCell<String>,
|
pub name: RefCell<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
pub struct SidebarAction {
|
pub struct SidebarAction {
|
||||||
pub onClickEvent: fn(Arc<Listeners>, FlowBox),
|
pub on_click_event: fn(Arc<Listeners>, FlowBox),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SidebarAction {
|
impl Default for SidebarAction {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
onClickEvent: HANDLE_HOME,
|
on_click_event: HANDLE_HOME,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +48,7 @@ impl Default for SidebarAction {
|
||||||
impl ObjectSubclass for SidebarEntry {
|
impl ObjectSubclass for SidebarEntry {
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
const NAME: &'static str = "resetSidebarEntry";
|
const NAME: &'static str = "resetSidebarEntry";
|
||||||
type Type = sidebarEntry::SidebarEntry;
|
type Type = sidebar_entry::SidebarEntry;
|
||||||
type ParentType = ListBoxRow;
|
type ParentType = ListBoxRow;
|
||||||
|
|
||||||
fn class_init(klass: &mut Self::Class) {
|
fn class_init(klass: &mut Self::Class) {
|
13
src/main.rs
13
src/main.rs
|
@ -1,9 +1,7 @@
|
||||||
#![allow(non_snake_case)]
|
|
||||||
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use components::window::resetWindow::ReSetWindow;
|
use components::window::reset_window::ReSetWindow;
|
||||||
use dbus::blocking::Connection;
|
use dbus::blocking::Connection;
|
||||||
use dbus::Error;
|
use dbus::Error;
|
||||||
use gtk::gdk::Display;
|
use gtk::gdk::Display;
|
||||||
|
@ -27,15 +25,15 @@ async fn main() {
|
||||||
|
|
||||||
app.connect_startup(move |_| {
|
app.connect_startup(move |_| {
|
||||||
adw::init().unwrap();
|
adw::init().unwrap();
|
||||||
loadCss();
|
load_css();
|
||||||
});
|
});
|
||||||
|
|
||||||
app.connect_activate(buildUI);
|
app.connect_activate(build_ui);
|
||||||
app.connect_shutdown(shutdown);
|
app.connect_shutdown(shutdown);
|
||||||
app.run();
|
app.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn loadCss() {
|
fn load_css() {
|
||||||
let provider = CssProvider::new();
|
let provider = CssProvider::new();
|
||||||
provider.load_from_resource("/org/Xetibo/ReSet/style/style.css");
|
provider.load_from_resource("/org/Xetibo/ReSet/style/style.css");
|
||||||
|
|
||||||
|
@ -46,8 +44,7 @@ fn loadCss() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
fn build_ui(app: &Application) {
|
||||||
fn buildUI(app: &Application) {
|
|
||||||
let window = ReSetWindow::new(app);
|
let window = ReSetWindow::new(app);
|
||||||
window.present();
|
window.present();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue