1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
use super::*;
mod imp {
use super::*;
#[derive(Properties, Default, Debug)]
#[properties(wrapper_type = super::PpsFileMonitor)]
pub struct PpsFileMonitor {
#[property(construct_only, get)]
pub(super) uri: RefCell<String>,
pub(super) monitor: std::cell::OnceCell<gio::FileMonitor>,
pub(super) timeout_id: RefCell<Option<glib::SourceId>>,
}
#[glib::object_subclass]
impl ObjectSubclass for PpsFileMonitor {
const NAME: &'static str = "PpsFileMonitor";
type Type = super::PpsFileMonitor;
type ParentType = glib::Object;
}
#[glib::derived_properties]
impl ObjectImpl for PpsFileMonitor {
fn signals() -> &'static [Signal] {
static SIGNALS: OnceLock<Vec<Signal>> = OnceLock::new();
SIGNALS.get_or_init(|| vec![Signal::builder("changed").run_last().action().build()])
}
fn constructed(&self) {
let file = gio::File::for_uri(self.uri.borrow().as_ref());
match file.monitor_file(gio::FileMonitorFlags::NONE, gio::Cancellable::NONE) {
Ok(monitor) => {
monitor.connect_changed(glib::clone!(
#[weak(rename_to = obj)]
self,
move |_, _, _, event| {
match event {
gio::FileMonitorEvent::ChangesDoneHint => {
obj.timeout_stop();
obj.obj().emit_by_name::<()>("changed", &[]);
}
gio::FileMonitorEvent::Changed => obj.timeout_start(),
_ => (),
}
}
));
self.monitor.set(monitor).unwrap();
}
Err(e) => {
glib::g_warning!("", "{}", e.message());
}
}
}
fn dispose(&self) {
self.timeout_stop();
}
}
impl PpsFileMonitor {
fn timeout_start(&self) {
self.timeout_stop();
let id = glib::timeout_add_seconds_local_once(
5,
glib::clone!(
#[weak(rename_to = obj)]
self,
move || {
obj.timeout_id.take();
obj.obj().emit_by_name::<()>("changed", &[]);
}
),
);
self.timeout_id.replace(Some(id));
}
fn timeout_stop(&self) {
if let Some(id) = self.timeout_id.take() {
id.remove();
}
}
}
}
glib::wrapper! {
pub struct PpsFileMonitor(ObjectSubclass<imp::PpsFileMonitor>);
}
impl PpsFileMonitor {
pub fn new(uri: &str) -> Self {
glib::Object::builder().property("uri", uri).build()
}
}
|