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
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT

use glib::object::IsA;
use glib::translate::*;
use std::ptr;

glib::wrapper! {
    /// This interface offers methods to query and manipulate parameter preset sets.
    /// A preset is a bunch of property settings, together with meta data and a name.
    /// The name of a preset serves as key for subsequent method calls to manipulate
    /// single presets.
    /// All instances of one type will share the list of presets. The list is created
    /// on demand, if presets are not used, the list is not created.
    ///
    /// The interface comes with a default implementation that serves most plugins.
    /// Wrapper plugins will override most methods to implement support for the
    /// native preset format of those wrapped plugins.
    /// One method that is useful to be overridden is [`Self::get_property_names()`].
    /// With that one can control which properties are saved and in which order.
    /// When implementing support for read-only presets, one should set the vmethods
    /// for [`Self::save_preset()`] and [`Self::delete_preset()`] to [`None`].
    /// Applications can use [`Self::is_editable()`] to check for that.
    ///
    /// The default implementation supports presets located in a system directory,
    /// application specific directory and in the users home directory. When getting
    /// a list of presets individual presets are read and overlaid in 1) system,
    /// 2) application and 3) user order. Whenever an earlier entry is newer, the
    /// later entries will be updated. Since 1.8 you can also provide extra paths
    /// where to find presets through the GST_PRESET_PATH environment variable.
    /// Presets found in those paths will be considered as "app presets".
    ///
    /// # Implements
    ///
    /// [`trait@crate::prelude::PresetExt`]
    pub struct Preset(Interface<ffi::GstPreset, ffi::GstPresetInterface>);

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

impl Preset {
    /// Gets the directory for application specific presets if set by the
    /// application.
    ///
    /// # Returns
    ///
    /// the directory or [`None`], don't free or modify
    /// the string
    #[doc(alias = "gst_preset_get_app_dir")]
    #[doc(alias = "get_app_dir")]
    pub fn app_dir() -> Option<std::path::PathBuf> {
        assert_initialized_main_thread!();
        unsafe { from_glib_none(ffi::gst_preset_get_app_dir()) }
    }

    /// Sets an extra directory as an absolute path that should be considered when
    /// looking for presets. Any presets in the application dir will shadow the
    /// system presets.
    /// ## `app_dir`
    /// the application specific preset dir
    ///
    /// # Returns
    ///
    /// [`true`] for success, [`false`] if the dir already has been set
    #[doc(alias = "gst_preset_set_app_dir")]
    pub fn set_app_dir<P: AsRef<std::path::Path>>(
        app_dir: P,
    ) -> Result<(), glib::error::BoolError> {
        assert_initialized_main_thread!();
        unsafe {
            glib::result_from_gboolean!(
                ffi::gst_preset_set_app_dir(app_dir.as_ref().to_glib_none().0),
                "Failed to set app preset directory"
            )
        }
    }
}

unsafe impl Send for Preset {}
unsafe impl Sync for Preset {}

pub const NONE_PRESET: Option<&Preset> = None;

/// Trait containing all `Preset` methods.
///
/// # Implementors
///
/// [`struct@crate::Preset`]
pub trait PresetExt: 'static {
    /// Delete the given preset.
    /// ## `name`
    /// preset name to remove
    ///
    /// # Returns
    ///
    /// [`true`] for success, [`false`] if e.g. there is no preset with that `name`
    #[doc(alias = "gst_preset_delete_preset")]
    fn delete_preset(&self, name: &str) -> Result<(), glib::error::BoolError>;

    /// Gets the `value` for an existing meta data `tag`. Meta data `tag` names can be
    /// something like e.g. "comment". Returned values need to be released when done.
    /// ## `name`
    /// preset name
    /// ## `tag`
    /// meta data item name
    /// ## `value`
    /// value
    ///
    /// # Returns
    ///
    /// [`true`] for success, [`false`] if e.g. there is no preset with that `name`
    /// or no value for the given `tag`
    #[doc(alias = "gst_preset_get_meta")]
    #[doc(alias = "get_meta")]
    fn meta(&self, name: &str, tag: &str) -> Option<glib::GString>;

    /// Get a copy of preset names as a [`None`] terminated string array.
    ///
    /// # Returns
    ///
    ///
    ///  list with names, use `g_strfreev()` after usage.
    #[doc(alias = "gst_preset_get_preset_names")]
    #[doc(alias = "get_preset_names")]
    fn preset_names(&self) -> Vec<glib::GString>;

    /// Get a the names of the GObject properties that can be used for presets.
    ///
    /// # Returns
    ///
    /// an
    ///  array of property names which should be freed with `g_strfreev()` after use.
    #[doc(alias = "gst_preset_get_property_names")]
    #[doc(alias = "get_property_names")]
    fn property_names(&self) -> Vec<glib::GString>;

    /// Check if one can add new presets, change existing ones and remove presets.
    ///
    /// # Returns
    ///
    /// [`true`] if presets are editable or [`false`] if they are static
    #[doc(alias = "gst_preset_is_editable")]
    fn is_editable(&self) -> bool;

    /// Load the given preset.
    /// ## `name`
    /// preset name to load
    ///
    /// # Returns
    ///
    /// [`true`] for success, [`false`] if e.g. there is no preset with that `name`
    #[doc(alias = "gst_preset_load_preset")]
    fn load_preset(&self, name: &str) -> Result<(), glib::error::BoolError>;

    /// Renames a preset. If there is already a preset by the `new_name` it will be
    /// overwritten.
    /// ## `old_name`
    /// current preset name
    /// ## `new_name`
    /// new preset name
    ///
    /// # Returns
    ///
    /// [`true`] for success, [`false`] if e.g. there is no preset with `old_name`
    #[doc(alias = "gst_preset_rename_preset")]
    fn rename_preset(&self, old_name: &str, new_name: &str) -> Result<(), glib::error::BoolError>;

    /// Save the current object settings as a preset under the given name. If there
    /// is already a preset by this `name` it will be overwritten.
    /// ## `name`
    /// preset name to save
    ///
    /// # Returns
    ///
    /// [`true`] for success, [`false`]
    #[doc(alias = "gst_preset_save_preset")]
    fn save_preset(&self, name: &str) -> Result<(), glib::error::BoolError>;

    /// Sets a new `value` for an existing meta data item or adds a new item. Meta
    /// data `tag` names can be something like e.g. "comment". Supplying [`None`] for the
    /// `value` will unset an existing value.
    /// ## `name`
    /// preset name
    /// ## `tag`
    /// meta data item name
    /// ## `value`
    /// new value
    ///
    /// # Returns
    ///
    /// [`true`] for success, [`false`] if e.g. there is no preset with that `name`
    #[doc(alias = "gst_preset_set_meta")]
    fn set_meta(
        &self,
        name: &str,
        tag: &str,
        value: Option<&str>,
    ) -> Result<(), glib::error::BoolError>;
}

impl<O: IsA<Preset>> PresetExt for O {
    fn delete_preset(&self, name: &str) -> Result<(), glib::error::BoolError> {
        unsafe {
            glib::result_from_gboolean!(
                ffi::gst_preset_delete_preset(
                    self.as_ref().to_glib_none().0,
                    name.to_glib_none().0
                ),
                "Failed to delete preset"
            )
        }
    }

    fn meta(&self, name: &str, tag: &str) -> Option<glib::GString> {
        unsafe {
            let mut value = ptr::null_mut();
            let ret = from_glib(ffi::gst_preset_get_meta(
                self.as_ref().to_glib_none().0,
                name.to_glib_none().0,
                tag.to_glib_none().0,
                &mut value,
            ));
            if ret {
                Some(from_glib_full(value))
            } else {
                None
            }
        }
    }

    fn preset_names(&self) -> Vec<glib::GString> {
        unsafe {
            FromGlibPtrContainer::from_glib_full(ffi::gst_preset_get_preset_names(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    fn property_names(&self) -> Vec<glib::GString> {
        unsafe {
            FromGlibPtrContainer::from_glib_full(ffi::gst_preset_get_property_names(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    fn is_editable(&self) -> bool {
        unsafe { from_glib(ffi::gst_preset_is_editable(self.as_ref().to_glib_none().0)) }
    }

    fn load_preset(&self, name: &str) -> Result<(), glib::error::BoolError> {
        unsafe {
            glib::result_from_gboolean!(
                ffi::gst_preset_load_preset(self.as_ref().to_glib_none().0, name.to_glib_none().0),
                "Failed to load preset"
            )
        }
    }

    fn rename_preset(&self, old_name: &str, new_name: &str) -> Result<(), glib::error::BoolError> {
        unsafe {
            glib::result_from_gboolean!(
                ffi::gst_preset_rename_preset(
                    self.as_ref().to_glib_none().0,
                    old_name.to_glib_none().0,
                    new_name.to_glib_none().0
                ),
                "Failed to rename preset"
            )
        }
    }

    fn save_preset(&self, name: &str) -> Result<(), glib::error::BoolError> {
        unsafe {
            glib::result_from_gboolean!(
                ffi::gst_preset_save_preset(self.as_ref().to_glib_none().0, name.to_glib_none().0),
                "Failed to save preset"
            )
        }
    }

    fn set_meta(
        &self,
        name: &str,
        tag: &str,
        value: Option<&str>,
    ) -> Result<(), glib::error::BoolError> {
        unsafe {
            glib::result_from_gboolean!(
                ffi::gst_preset_set_meta(
                    self.as_ref().to_glib_none().0,
                    name.to_glib_none().0,
                    tag.to_glib_none().0,
                    value.to_glib_none().0
                ),
                "Failed to set preset meta"
            )
        }
    }
}