xfconf 0.1.0

Provides access to xfconf, Xfce's desktop configuration system
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files.gtk (https://github.com/gtk-rs/gir-files)
// from gir-files.xfce
// DO NOT EDIT

use crate::ffi;
use glib::{
    object::ObjectType as _,
    prelude::*,
    signal::{SignalHandlerId, connect_raw},
    translate::*,
};
use std::boxed::Box as Box_;

glib::wrapper! {
    /// An opaque structure that holds state about a channel.
    ///
    /// ## Properties
    ///
    ///
    /// #### `channel-name`
    ///  The string identifier used for this channel.
    ///
    /// Readable | Writeable | Construct Only
    ///
    ///
    /// #### `is-singleton`
    ///  Identifies the instance of the class as a singleton instance
    /// or not. This is mainly used internally by [`Channel`][crate::Channel]
    /// but may be useful for API users.
    ///
    /// Readable | Writeable | Construct Only
    ///
    ///
    /// #### `property-base`
    ///  The string identifier used for the property base inside a channel.
    /// This can be used to restrict a channel to a subset of properties.
    ///
    /// Readable | Writeable | Construct Only
    ///
    /// ## Signals
    ///
    ///
    /// #### `property-changed`
    ///  Emitted whenever a property on `channel` has changed. If
    /// the change was caused by the removal of `property`, `value`
    /// will be unset; you should test this with
    /// `<informalexample>``<programlisting>`
    /// G_VALUE_TYPE(value) == G_TYPE_INVALID
    /// `</programlisting>``</informalexample>`
    ///
    /// Detailed
    ///
    /// # Implements
    ///
    /// [`trait@glib::ObjectExt`]
    #[doc(alias = "XfconfChannel")]
    pub struct Channel(Object<ffi::XfconfChannel>);

    match fn {
        type_ => || ffi::xfconf_channel_get_type(),
    }
}

impl Channel {
    /// Either creates a new channel, or fetches a singleton object for
    /// `channel_name`. This function always returns a valid object; no
    /// checking is done to see if the channel exists or has a valid name.
    ///
    /// The reference count of the returned channel is owned by libxfconf.
    /// ## `channel_name`
    /// A channel name.
    ///
    /// # Returns
    ///
    /// An [`Channel`][crate::Channel] singleton.
    #[doc(alias = "xfconf_channel_get")]
    pub fn get(channel_name: &str) -> Channel {
        unsafe { from_glib_none(ffi::xfconf_channel_get(channel_name.to_glib_none().0)) }
    }

    /// Creates a new channel using `name` as the channel's identifier.
    /// This function always returns a valid object; no checking is done
    /// to see if the channel exists or has a valid name.
    ///
    /// Note: use of this function is not recommended, in favor of
    /// [`get()`][Self::get()], which returns a singleton object and
    /// saves a little memory. However, [`new()`][Self::new()] can be
    /// useful in some cases where you want to tie an [`Channel`][crate::Channel]'s
    /// lifetime (and thus the lifetime of connected signals and bound
    /// [`glib::Object`][crate::glib::Object] properties) to the lifetime of another object.
    ///
    /// Also note that each channel has its own cache, so if you create
    /// 2 new channels with the same name, it will double the dbus traffic,
    /// so in this cases it is highly recommended to use [`get()`][Self::get()].
    /// ## `channel_name`
    /// A channel name.
    ///
    /// # Returns
    ///
    /// A new [`Channel`][crate::Channel]. Release with `g_object_unref()`
    ///  when no longer needed.
    #[doc(alias = "xfconf_channel_new")]
    pub fn new(channel_name: &str) -> Channel {
        unsafe { from_glib_full(ffi::xfconf_channel_new(channel_name.to_glib_none().0)) }
    }

    /// Creates a new channel using `name` as the channel's identifier,
    /// restricting the accessible properties to be rooted at
    /// `property_base`. This function always returns a valid object;
    /// no checking is done to see if the channel exists or has a valid
    /// name.
    /// ## `channel_name`
    /// A channel name.
    /// ## `property_base`
    /// A property root name.
    ///
    /// # Returns
    ///
    /// A new [`Channel`][crate::Channel]. Release with `g_object_unref()`
    ///  when no longer needed.
    #[doc(alias = "xfconf_channel_new_with_property_base")]
    #[doc(alias = "new_with_property_base")]
    pub fn with_property_base(channel_name: &str, property_base: &str) -> Channel {
        unsafe {
            from_glib_full(ffi::xfconf_channel_new_with_property_base(
                channel_name.to_glib_none().0,
                property_base.to_glib_none().0,
            ))
        }
    }

    /// Checks to see if `property` exists on `self`.
    /// ## `property`
    /// A property name.
    ///
    /// # Returns
    ///
    /// [`true`] if `property` exists, [`false`] otherwise.
    #[doc(alias = "xfconf_channel_has_property")]
    pub fn has_property(&self, property: &str) -> bool {
        unsafe {
            from_glib(ffi::xfconf_channel_has_property(
                self.to_glib_none().0,
                property.to_glib_none().0,
            ))
        }
    }

    /// Queries whether or not `property` on `self` is locked by system
    /// policy. If the property is locked, calls to
    /// [`set_property()`][Self::set_property()] (or any of the "set" family of functions)
    /// or [`reset_property()`][Self::reset_property()] will fail.
    /// ## `property`
    /// A property name.
    ///
    /// # Returns
    ///
    /// [`true`] if the property is locked, [`false`] otherwise.
    #[doc(alias = "xfconf_channel_is_property_locked")]
    pub fn is_property_locked(&self, property: &str) -> bool {
        unsafe {
            from_glib(ffi::xfconf_channel_is_property_locked(
                self.to_glib_none().0,
                property.to_glib_none().0,
            ))
        }
    }

    /// Resets properties starting at (and including) `property_base`.
    /// If `recursive` is [`true`], will also reset all properties that are
    /// under `property_base` in the property hierarchy.
    ///
    /// A bit of an explanation as to what this function actually does:
    /// Since Xfconf backends are expected to support setting defaults
    /// via what you might call "optional schema," you can't really
    /// "remove" properties. Since the client library can't know if a
    /// channel provides default values (or even if the backend supports
    /// it!), at best it can only reset properties to their default values.
    ///
    /// The `property_base` parameter can be [`None`] or the empty string (""),
    /// in which case the channel root ("/") will be assumed. Of course,
    /// [`true`] must be passed for `recursive` in this case.
    /// ## `property_base`
    /// A property tree root or property name.
    /// ## `recursive`
    /// Whether to reset properties recursively.
    #[doc(alias = "xfconf_channel_reset_property")]
    pub fn reset_property(&self, property_base: &str, recursive: bool) {
        unsafe {
            ffi::xfconf_channel_reset_property(
                self.to_glib_none().0,
                property_base.to_glib_none().0,
                recursive.into_glib(),
            );
        }
    }

    /// The string identifier used for this channel.
    #[doc(alias = "channel-name")]
    pub fn channel_name(&self) -> Option<glib::GString> {
        ObjectExt::property(self, "channel-name")
    }

    /// Identifies the instance of the class as a singleton instance
    /// or not. This is mainly used internally by [`Channel`][crate::Channel]
    /// but may be useful for API users.
    #[doc(alias = "is-singleton")]
    pub fn is_singleton(&self) -> bool {
        ObjectExt::property(self, "is-singleton")
    }

    /// The string identifier used for the property base inside a channel.
    /// This can be used to restrict a channel to a subset of properties.
    #[doc(alias = "property-base")]
    pub fn property_base(&self) -> Option<glib::GString> {
        ObjectExt::property(self, "property-base")
    }

    /// Emitted whenever a property on `channel` has changed. If
    /// the change was caused by the removal of `property`, `value`
    /// will be unset; you should test this with
    /// `<informalexample>``<programlisting>`
    /// G_VALUE_TYPE(value) == G_TYPE_INVALID
    /// `</programlisting>``</informalexample>`
    /// ## `property`
    /// The property that changed.
    /// ## `value`
    /// The new value.
    #[doc(alias = "property-changed")]
    pub fn connect_property_changed<F: Fn(&Self, &str, &glib::Value) + 'static>(
        &self,
        detail: Option<&str>,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn property_changed_trampoline<
            F: Fn(&Channel, &str, &glib::Value) + 'static,
        >(
            this: *mut ffi::XfconfChannel,
            property: *mut std::ffi::c_char,
            value: *mut glib::gobject_ffi::GValue,
            f: glib::ffi::gpointer,
        ) {
            unsafe {
                let f: &F = &*(f as *const F);
                f(
                    &from_glib_borrow(this),
                    &glib::GString::from_glib_borrow(property),
                    &from_glib_borrow(value),
                )
            }
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            let detailed_signal_name = detail.map(|name| format!("property-changed::{name}\0"));
            let signal_name = detailed_signal_name
                .as_ref()
                .map_or(c"property-changed", |n| {
                    std::ffi::CStr::from_bytes_with_nul_unchecked(n.as_bytes())
                });
            connect_raw(
                self.as_ptr() as *mut _,
                signal_name.as_ptr(),
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    property_changed_trampoline::<F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }
}