gstreamer_editing_services/auto/
project.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
4// DO NOT EDIT
5
6#[cfg(feature = "v1_18")]
7#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
8use crate::Formatter;
9use crate::{ffi, Asset, MetaContainer, Timeline};
10use glib::{
11    object::ObjectType as _,
12    prelude::*,
13    signal::{connect_raw, SignalHandlerId},
14    translate::*,
15};
16use std::boxed::Box as Box_;
17
18glib::wrapper! {
19    /// The [`Project`][crate::Project] is used to control a set of [`Asset`][crate::Asset] and is a
20    /// [`Asset`][crate::Asset] with `GES_TYPE_TIMELINE` as `extractable_type` itself. That
21    /// means that you can extract [`Timeline`][crate::Timeline] from a project as followed:
22    ///
23    /// **⚠️ The following code is in c ⚠️**
24    ///
25    /// ```c
26    /// GESProject *project;
27    /// GESTimeline *timeline;
28    ///
29    /// project = ges_project_new ("file:///path/to/a/valid/project/uri");
30    ///
31    /// // Here you can connect to the various signal to get more infos about
32    /// // what is happening and recover from errors if possible
33    /// ...
34    ///
35    /// timeline = ges_asset_extract (GES_ASSET (project));
36    /// ```
37    ///
38    /// The [`Project`][crate::Project] class offers a higher level API to handle [`Asset`][crate::Asset]-s.
39    /// It lets you request new asset, and it informs you about new assets through
40    /// a set of signals. Also it handles problem such as missing files/missing
41    /// [`gst::Element`][crate::gst::Element] and lets you try to recover from those.
42    ///
43    /// ## Subprojects
44    ///
45    /// In order to add a subproject, the only thing to do is to add the subproject
46    /// to the main project:
47    ///
48    /// **⚠️ The following code is in  c ⚠️**
49    ///
50    /// ``` c
51    /// ges_project_add_asset (project, GES_ASSET (subproject));
52    /// ```
53    /// then the subproject will be serialized in the project files. To use
54    /// the subproject in a timeline, you should use a [`UriClip`][crate::UriClip] with the
55    /// same subproject URI.
56    ///
57    /// When loading a project with subproject, subprojects URIs will be temporary
58    /// writable local files. If you want to edit the subproject timeline,
59    /// you should retrieve the subproject from the parent project asset list and
60    /// extract the timeline with [`AssetExt::extract()`][crate::prelude::AssetExt::extract()] and save it at
61    /// the same temporary location.
62    ///
63    /// ## Properties
64    ///
65    ///
66    /// #### `uri`
67    ///  Readable | Writeable | Construct Only
68    /// <details><summary><h4>Asset</h4></summary>
69    ///
70    ///
71    /// #### `extractable-type`
72    ///  The [`Extractable`][crate::Extractable] object type that can be extracted from the asset.
73    ///
74    /// Readable | Writeable | Construct Only
75    ///
76    ///
77    /// #### `id`
78    ///  The ID of the asset. This should be unique amongst all assets with
79    /// the same [`extractable-type`][struct@crate::Asset#extractable-type]. Depending on the associated
80    /// [`Extractable`][crate::Extractable] implementation, this id may convey some information
81    /// about the [`glib::Object`][crate::glib::Object] that should be extracted. Note that, as such, the
82    /// ID will have an expected format, and you can not choose this value
83    /// arbitrarily. By default, this will be set to the type name of the
84    /// [`extractable-type`][struct@crate::Asset#extractable-type], but you should check the documentation
85    /// of the extractable type to see whether they differ from the
86    /// default behaviour.
87    ///
88    /// Readable | Writeable | Construct Only
89    ///
90    ///
91    /// #### `proxy`
92    ///  The default proxy for this asset, or [`None`] if it has no proxy. A
93    /// proxy will act as a substitute for the original asset when the
94    /// original is requested (see [`Asset::request()`][crate::Asset::request()]).
95    ///
96    /// Setting this property will not usually remove the existing proxy, but
97    /// will replace it as the default (see [`AssetExt::set_proxy()`][crate::prelude::AssetExt::set_proxy()]).
98    ///
99    /// Readable | Writeable
100    ///
101    ///
102    /// #### `proxy-target`
103    ///  The asset that this asset is a proxy for, or [`None`] if it is not a
104    /// proxy for another asset.
105    ///
106    /// Note that even if this asset is acting as a proxy for another asset,
107    /// but this asset is not the default [`proxy`][struct@crate::Asset#proxy], then `proxy`-target
108    /// will *still* point to this other asset. So you should check the
109    /// [`proxy`][struct@crate::Asset#proxy] property of `target`-proxy before assuming it is the
110    /// current default proxy for the target.
111    ///
112    /// Note that the [`notify`][struct@crate::glib::Object#notify] for this property is emitted after
113    /// the [`proxy`][struct@crate::Asset#proxy] [`notify`][struct@crate::glib::Object#notify] for the corresponding (if any)
114    /// asset it is now the proxy of/no longer the proxy of.
115    ///
116    /// Readable
117    /// </details>
118    ///
119    /// ## Signals
120    ///
121    ///
122    /// #### `asset-added`
123    ///
124    ///
125    ///
126    /// #### `asset-loading`
127    ///
128    ///
129    ///
130    /// #### `asset-removed`
131    ///
132    ///
133    ///
134    /// #### `error-loading`
135    ///
136    ///
137    ///
138    /// #### `error-loading-asset`
139    ///  Informs you that a [`Asset`][crate::Asset] could not be created. In case of
140    /// missing GStreamer plugins, the error will be set to `GST_CORE_ERROR`
141    /// [`gst::CoreError::MissingPlugin`][crate::gst::CoreError::MissingPlugin]
142    ///
143    ///
144    ///
145    ///
146    /// #### `loaded`
147    ///
148    ///
149    ///
150    /// #### `loading`
151    ///
152    ///
153    ///
154    /// #### `missing-uri`
155    ///  **⚠️ The following code is in c ⚠️**
156    ///
157    /// ```c
158    /// static gchar
159    /// source_moved_cb (GESProject *project, GError *error, GESAsset *asset_with_error)
160    /// {
161    ///   return g_strdup ("file:///the/new/uri.ogg");
162    /// }
163    ///
164    /// static int
165    /// main (int argc, gchar ** argv)
166    /// {
167    ///   GESTimeline *timeline;
168    ///   GESProject *project = ges_project_new ("file:///some/uri.xges");
169    ///
170    ///   g_signal_connect (project, "missing-uri", source_moved_cb, NULL);
171    ///   timeline = ges_asset_extract (GES_ASSET (project));
172    /// }
173    /// ```
174    ///
175    ///
176    /// <details><summary><h4>MetaContainer</h4></summary>
177    ///
178    ///
179    /// #### `notify-meta`
180    ///  This is emitted for a meta container whenever the metadata under one
181    /// of its fields changes, is set for the first time, or is removed. In
182    /// the latter case, `value` will be [`None`].
183    ///
184    /// Detailed
185    /// </details>
186    ///
187    /// # Implements
188    ///
189    /// [`ProjectExt`][trait@crate::prelude::ProjectExt], [`AssetExt`][trait@crate::prelude::AssetExt], [`trait@glib::ObjectExt`], [`MetaContainerExt`][trait@crate::prelude::MetaContainerExt]
190    #[doc(alias = "GESProject")]
191    pub struct Project(Object<ffi::GESProject, ffi::GESProjectClass>) @extends Asset, @implements MetaContainer;
192
193    match fn {
194        type_ => || ffi::ges_project_get_type(),
195    }
196}
197
198impl Project {
199    pub const NONE: Option<&'static Project> = None;
200
201    /// Creates a new [`Project`][crate::Project] and sets its uri to `uri` if provided. Note that
202    /// if `uri` is not valid or [`None`], the uri of the project will then be set
203    /// the first time you save the project. If you then save the project to
204    /// other locations, it will never be updated again and the first valid URI is
205    /// the URI it will keep refering to.
206    /// ## `uri`
207    /// The uri to be set after creating the project.
208    ///
209    /// # Returns
210    ///
211    /// A newly created [`Project`][crate::Project]
212    ///
213    /// MT safe.
214    #[doc(alias = "ges_project_new")]
215    pub fn new(uri: Option<&str>) -> Project {
216        assert_initialized_main_thread!();
217        unsafe { from_glib_full(ffi::ges_project_new(uri.to_glib_none().0)) }
218    }
219}
220
221/// Trait containing all [`struct@Project`] methods.
222///
223/// # Implementors
224///
225/// [`Project`][struct@crate::Project]
226pub trait ProjectExt: IsA<Project> + 'static {
227    /// Adds a [`Asset`][crate::Asset] to `self`, the project will keep a reference on
228    /// `asset`.
229    /// ## `asset`
230    /// A [`Asset`][crate::Asset] to add to `self`
231    ///
232    /// # Returns
233    ///
234    /// [`true`] if the asset could be added [`false`] it was already
235    /// in the project.
236    ///
237    /// MT safe.
238    #[doc(alias = "ges_project_add_asset")]
239    fn add_asset(&self, asset: &impl IsA<Asset>) -> bool {
240        unsafe {
241            from_glib(ffi::ges_project_add_asset(
242                self.as_ref().to_glib_none().0,
243                asset.as_ref().to_glib_none().0,
244            ))
245        }
246    }
247
248    /// Adds `profile` to the project. It lets you save in what format
249    /// the project will be rendered and keep a reference to those formats.
250    /// Also, those formats will be saved to the project file when possible.
251    /// ## `profile`
252    /// A [`gst_pbutils::EncodingProfile`][crate::gst_pbutils::EncodingProfile] to add to the project. If a profile with
253    /// the same name already exists, it will be replaced.
254    ///
255    /// # Returns
256    ///
257    /// [`true`] if `profile` could be added, [`false`] otherwise
258    ///
259    /// MT safe.
260    #[doc(alias = "ges_project_add_encoding_profile")]
261    fn add_encoding_profile(
262        &self,
263        profile: &impl IsA<gst_pbutils::EncodingProfile>,
264    ) -> Result<(), glib::error::BoolError> {
265        unsafe {
266            glib::result_from_gboolean!(
267                ffi::ges_project_add_encoding_profile(
268                    self.as_ref().to_glib_none().0,
269                    profile.as_ref().to_glib_none().0
270                ),
271                "Failed to add profile"
272            )
273        }
274    }
275
276    /// Adds a formatter to be used to load `self`
277    /// ## `formatter`
278    /// A formatter used by `self`
279    #[cfg(feature = "v1_18")]
280    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
281    #[doc(alias = "ges_project_add_formatter")]
282    fn add_formatter(&self, formatter: &impl IsA<Formatter>) {
283        unsafe {
284            ffi::ges_project_add_formatter(
285                self.as_ref().to_glib_none().0,
286                formatter.as_ref().to_glib_none().0,
287            );
288        }
289    }
290
291    /// Create and add a [`Asset`][crate::Asset] to `self`. You should connect to the
292    /// "asset-added" signal to get the asset when it finally gets added to
293    /// `self`
294    /// ## `id`
295    /// The id of the asset to create and add to `self`
296    /// ## `extractable_type`
297    /// The `GType` of the asset to create
298    ///
299    /// # Returns
300    ///
301    /// [`true`] if the asset was added and started loading, [`false`] it was
302    /// already in the project.
303    ///
304    /// MT safe.
305    #[doc(alias = "ges_project_create_asset")]
306    fn create_asset(&self, id: Option<&str>, extractable_type: glib::types::Type) -> bool {
307        unsafe {
308            from_glib(ffi::ges_project_create_asset(
309                self.as_ref().to_glib_none().0,
310                id.to_glib_none().0,
311                extractable_type.into_glib(),
312            ))
313        }
314    }
315
316    /// Create and add a [`Asset`][crate::Asset] to `self`. You should connect to the
317    /// "asset-added" signal to get the asset when it finally gets added to
318    /// `self`
319    /// ## `id`
320    /// The id of the asset to create and add to `self`
321    /// ## `extractable_type`
322    /// The `GType` of the asset to create
323    ///
324    /// # Returns
325    ///
326    /// The newly created [`Asset`][crate::Asset] or [`None`].
327    ///
328    /// MT safe.
329    #[doc(alias = "ges_project_create_asset_sync")]
330    fn create_asset_sync(
331        &self,
332        id: Option<&str>,
333        extractable_type: glib::types::Type,
334    ) -> Result<Option<Asset>, glib::Error> {
335        unsafe {
336            let mut error = std::ptr::null_mut();
337            let ret = ffi::ges_project_create_asset_sync(
338                self.as_ref().to_glib_none().0,
339                id.to_glib_none().0,
340                extractable_type.into_glib(),
341                &mut error,
342            );
343            if error.is_null() {
344                Ok(from_glib_full(ret))
345            } else {
346                Err(from_glib_full(error))
347            }
348        }
349    }
350
351    /// ## `id`
352    /// The id of the asset to retrieve
353    /// ## `extractable_type`
354    /// The extractable_type of the asset
355    /// to retrieve from `object`
356    ///
357    /// # Returns
358    ///
359    /// The [`Asset`][crate::Asset] with
360    /// `id` or [`None`] if no asset with `id` as an ID
361    ///
362    /// MT safe.
363    #[doc(alias = "ges_project_get_asset")]
364    #[doc(alias = "get_asset")]
365    fn asset(&self, id: &str, extractable_type: glib::types::Type) -> Option<Asset> {
366        unsafe {
367            from_glib_full(ffi::ges_project_get_asset(
368                self.as_ref().to_glib_none().0,
369                id.to_glib_none().0,
370                extractable_type.into_glib(),
371            ))
372        }
373    }
374
375    /// Get the assets that are being loaded
376    ///
377    /// # Returns
378    ///
379    /// A set of loading asset
380    /// that will be added to `self`. Note that those Asset are *not* loaded yet,
381    /// and thus can not be used.
382    ///
383    /// MT safe.
384    #[doc(alias = "ges_project_get_loading_assets")]
385    #[doc(alias = "get_loading_assets")]
386    fn loading_assets(&self) -> Vec<Asset> {
387        unsafe {
388            FromGlibPtrContainer::from_glib_full(ffi::ges_project_get_loading_assets(
389                self.as_ref().to_glib_none().0,
390            ))
391        }
392    }
393
394    /// Retrieve the uri that is currently set on `self`
395    ///
396    /// # Returns
397    ///
398    /// a newly allocated string representing uri.
399    ///
400    /// MT safe.
401    #[doc(alias = "ges_project_get_uri")]
402    #[doc(alias = "get_uri")]
403    fn uri(&self) -> Option<glib::GString> {
404        unsafe { from_glib_full(ffi::ges_project_get_uri(self.as_ref().to_glib_none().0)) }
405    }
406
407    /// List all `asset` contained in `self` filtering per extractable_type
408    /// as defined by `filter`. It copies the asset and thus will not be updated
409    /// in time.
410    /// ## `filter`
411    /// Type of assets to list, `GES_TYPE_EXTRACTABLE` will list
412    /// all assets
413    ///
414    /// # Returns
415    ///
416    /// The list of
417    /// [`Asset`][crate::Asset] the object contains
418    ///
419    /// MT safe.
420    #[doc(alias = "ges_project_list_assets")]
421    fn list_assets(&self, filter: glib::types::Type) -> Vec<Asset> {
422        unsafe {
423            FromGlibPtrContainer::from_glib_full(ffi::ges_project_list_assets(
424                self.as_ref().to_glib_none().0,
425                filter.into_glib(),
426            ))
427        }
428    }
429
430    /// Lists the encoding profile that have been set to `self`. The first one
431    /// is the latest added.
432    ///
433    /// # Returns
434    ///
435    /// The
436    /// list of [`gst_pbutils::EncodingProfile`][crate::gst_pbutils::EncodingProfile] used in `self`
437    #[doc(alias = "ges_project_list_encoding_profiles")]
438    fn list_encoding_profiles(&self) -> Vec<gst_pbutils::EncodingProfile> {
439        unsafe {
440            FromGlibPtrContainer::from_glib_none(ffi::ges_project_list_encoding_profiles(
441                self.as_ref().to_glib_none().0,
442            ))
443        }
444    }
445
446    /// Loads `self` into `timeline`
447    /// ## `timeline`
448    /// A blank timeline to load `self` into
449    ///
450    /// # Returns
451    ///
452    /// [`true`] if the project could be loaded [`false`] otherwise.
453    ///
454    /// MT safe.
455    #[doc(alias = "ges_project_load")]
456    fn load(&self, timeline: &impl IsA<Timeline>) -> Result<(), glib::Error> {
457        unsafe {
458            let mut error = std::ptr::null_mut();
459            let is_ok = ffi::ges_project_load(
460                self.as_ref().to_glib_none().0,
461                timeline.as_ref().to_glib_none().0,
462                &mut error,
463            );
464            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
465            if error.is_null() {
466                Ok(())
467            } else {
468                Err(from_glib_full(error))
469            }
470        }
471    }
472
473    /// Remove `asset` from `self`.
474    /// ## `asset`
475    /// A [`Asset`][crate::Asset] to remove from `self`
476    ///
477    /// # Returns
478    ///
479    /// [`true`] if the asset could be removed [`false`] otherwise
480    ///
481    /// MT safe.
482    #[doc(alias = "ges_project_remove_asset")]
483    fn remove_asset(&self, asset: &impl IsA<Asset>) -> Result<(), glib::error::BoolError> {
484        unsafe {
485            glib::result_from_gboolean!(
486                ffi::ges_project_remove_asset(
487                    self.as_ref().to_glib_none().0,
488                    asset.as_ref().to_glib_none().0
489                ),
490                "Failed to remove asset"
491            )
492        }
493    }
494
495    /// Save the timeline of `self` to `uri`. You should make sure that `timeline`
496    /// is one of the timelines that have been extracted from `self`
497    /// (using ges_asset_extract (`self`);)
498    /// ## `timeline`
499    /// The [`Timeline`][crate::Timeline] to save, it must have been extracted from `self`
500    /// ## `uri`
501    /// The uri where to save `self` and `timeline`
502    /// ## `formatter_asset`
503    /// The formatter asset to
504    /// use or [`None`]. If [`None`], will try to save in the same format as the one
505    /// from which the timeline as been loaded or default to the best formatter
506    /// as defined in `ges_find_formatter_for_uri`
507    /// ## `overwrite`
508    /// [`true`] to overwrite file if it exists
509    ///
510    /// # Returns
511    ///
512    /// [`true`] if the project could be save, [`false`] otherwise
513    ///
514    /// MT safe.
515    #[doc(alias = "ges_project_save")]
516    fn save(
517        &self,
518        timeline: &impl IsA<Timeline>,
519        uri: &str,
520        formatter_asset: Option<impl IsA<Asset>>,
521        overwrite: bool,
522    ) -> Result<(), glib::Error> {
523        unsafe {
524            let mut error = std::ptr::null_mut();
525            let is_ok = ffi::ges_project_save(
526                self.as_ref().to_glib_none().0,
527                timeline.as_ref().to_glib_none().0,
528                uri.to_glib_none().0,
529                formatter_asset.map(|p| p.upcast()).into_glib_ptr(),
530                overwrite.into_glib(),
531                &mut error,
532            );
533            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
534            if error.is_null() {
535                Ok(())
536            } else {
537                Err(from_glib_full(error))
538            }
539        }
540    }
541
542    /// ## `asset`
543    /// The [`Asset`][crate::Asset] that has been added to `project`
544    #[doc(alias = "asset-added")]
545    fn connect_asset_added<F: Fn(&Self, &Asset) + 'static>(&self, f: F) -> SignalHandlerId {
546        unsafe extern "C" fn asset_added_trampoline<
547            P: IsA<Project>,
548            F: Fn(&P, &Asset) + 'static,
549        >(
550            this: *mut ffi::GESProject,
551            asset: *mut ffi::GESAsset,
552            f: glib::ffi::gpointer,
553        ) {
554            let f: &F = &*(f as *const F);
555            f(
556                Project::from_glib_borrow(this).unsafe_cast_ref(),
557                &from_glib_borrow(asset),
558            )
559        }
560        unsafe {
561            let f: Box_<F> = Box_::new(f);
562            connect_raw(
563                self.as_ptr() as *mut _,
564                c"asset-added".as_ptr() as *const _,
565                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
566                    asset_added_trampoline::<Self, F> as *const (),
567                )),
568                Box_::into_raw(f),
569            )
570        }
571    }
572
573    /// ## `asset`
574    /// The [`Asset`][crate::Asset] that started loading
575    #[doc(alias = "asset-loading")]
576    fn connect_asset_loading<F: Fn(&Self, &Asset) + 'static>(&self, f: F) -> SignalHandlerId {
577        unsafe extern "C" fn asset_loading_trampoline<
578            P: IsA<Project>,
579            F: Fn(&P, &Asset) + 'static,
580        >(
581            this: *mut ffi::GESProject,
582            asset: *mut ffi::GESAsset,
583            f: glib::ffi::gpointer,
584        ) {
585            let f: &F = &*(f as *const F);
586            f(
587                Project::from_glib_borrow(this).unsafe_cast_ref(),
588                &from_glib_borrow(asset),
589            )
590        }
591        unsafe {
592            let f: Box_<F> = Box_::new(f);
593            connect_raw(
594                self.as_ptr() as *mut _,
595                c"asset-loading".as_ptr() as *const _,
596                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
597                    asset_loading_trampoline::<Self, F> as *const (),
598                )),
599                Box_::into_raw(f),
600            )
601        }
602    }
603
604    /// ## `asset`
605    /// The [`Asset`][crate::Asset] that has been removed from `project`
606    #[doc(alias = "asset-removed")]
607    fn connect_asset_removed<F: Fn(&Self, &Asset) + 'static>(&self, f: F) -> SignalHandlerId {
608        unsafe extern "C" fn asset_removed_trampoline<
609            P: IsA<Project>,
610            F: Fn(&P, &Asset) + 'static,
611        >(
612            this: *mut ffi::GESProject,
613            asset: *mut ffi::GESAsset,
614            f: glib::ffi::gpointer,
615        ) {
616            let f: &F = &*(f as *const F);
617            f(
618                Project::from_glib_borrow(this).unsafe_cast_ref(),
619                &from_glib_borrow(asset),
620            )
621        }
622        unsafe {
623            let f: Box_<F> = Box_::new(f);
624            connect_raw(
625                self.as_ptr() as *mut _,
626                c"asset-removed".as_ptr() as *const _,
627                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
628                    asset_removed_trampoline::<Self, F> as *const (),
629                )),
630                Box_::into_raw(f),
631            )
632        }
633    }
634
635    /// ## `timeline`
636    /// The timeline that failed loading
637    /// ## `error`
638    /// The [`glib::Error`][crate::glib::Error] defining the error that occured
639    #[cfg(feature = "v1_18")]
640    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
641    #[doc(alias = "error-loading")]
642    fn connect_error_loading<F: Fn(&Self, &Timeline, &glib::Error) + 'static>(
643        &self,
644        f: F,
645    ) -> SignalHandlerId {
646        unsafe extern "C" fn error_loading_trampoline<
647            P: IsA<Project>,
648            F: Fn(&P, &Timeline, &glib::Error) + 'static,
649        >(
650            this: *mut ffi::GESProject,
651            timeline: *mut ffi::GESTimeline,
652            error: *mut glib::ffi::GError,
653            f: glib::ffi::gpointer,
654        ) {
655            let f: &F = &*(f as *const F);
656            f(
657                Project::from_glib_borrow(this).unsafe_cast_ref(),
658                &from_glib_borrow(timeline),
659                &from_glib_borrow(error),
660            )
661        }
662        unsafe {
663            let f: Box_<F> = Box_::new(f);
664            connect_raw(
665                self.as_ptr() as *mut _,
666                c"error-loading".as_ptr() as *const _,
667                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
668                    error_loading_trampoline::<Self, F> as *const (),
669                )),
670                Box_::into_raw(f),
671            )
672        }
673    }
674
675    /// Informs you that a [`Asset`][crate::Asset] could not be created. In case of
676    /// missing GStreamer plugins, the error will be set to `GST_CORE_ERROR`
677    /// [`gst::CoreError::MissingPlugin`][crate::gst::CoreError::MissingPlugin]
678    /// ## `error`
679    /// The [`glib::Error`][crate::glib::Error] defining the error that occured, might be [`None`]
680    /// ## `id`
681    /// The `id` of the asset that failed loading
682    /// ## `extractable_type`
683    /// The `extractable_type` of the asset that
684    /// failed loading
685    #[doc(alias = "error-loading-asset")]
686    fn connect_error_loading_asset<
687        F: Fn(&Self, &glib::Error, &str, glib::types::Type) + 'static,
688    >(
689        &self,
690        f: F,
691    ) -> SignalHandlerId {
692        unsafe extern "C" fn error_loading_asset_trampoline<
693            P: IsA<Project>,
694            F: Fn(&P, &glib::Error, &str, glib::types::Type) + 'static,
695        >(
696            this: *mut ffi::GESProject,
697            error: *mut glib::ffi::GError,
698            id: *mut std::ffi::c_char,
699            extractable_type: glib::ffi::GType,
700            f: glib::ffi::gpointer,
701        ) {
702            let f: &F = &*(f as *const F);
703            f(
704                Project::from_glib_borrow(this).unsafe_cast_ref(),
705                &from_glib_borrow(error),
706                &glib::GString::from_glib_borrow(id),
707                from_glib(extractable_type),
708            )
709        }
710        unsafe {
711            let f: Box_<F> = Box_::new(f);
712            connect_raw(
713                self.as_ptr() as *mut _,
714                c"error-loading-asset".as_ptr() as *const _,
715                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
716                    error_loading_asset_trampoline::<Self, F> as *const (),
717                )),
718                Box_::into_raw(f),
719            )
720        }
721    }
722
723    /// ## `timeline`
724    /// The [`Timeline`][crate::Timeline] that completed loading
725    #[doc(alias = "loaded")]
726    fn connect_loaded<F: Fn(&Self, &Timeline) + 'static>(&self, f: F) -> SignalHandlerId {
727        unsafe extern "C" fn loaded_trampoline<P: IsA<Project>, F: Fn(&P, &Timeline) + 'static>(
728            this: *mut ffi::GESProject,
729            timeline: *mut ffi::GESTimeline,
730            f: glib::ffi::gpointer,
731        ) {
732            let f: &F = &*(f as *const F);
733            f(
734                Project::from_glib_borrow(this).unsafe_cast_ref(),
735                &from_glib_borrow(timeline),
736            )
737        }
738        unsafe {
739            let f: Box_<F> = Box_::new(f);
740            connect_raw(
741                self.as_ptr() as *mut _,
742                c"loaded".as_ptr() as *const _,
743                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
744                    loaded_trampoline::<Self, F> as *const (),
745                )),
746                Box_::into_raw(f),
747            )
748        }
749    }
750
751    /// ## `timeline`
752    /// The [`Timeline`][crate::Timeline] that started loading
753    #[cfg(feature = "v1_18")]
754    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
755    #[doc(alias = "loading")]
756    fn connect_loading<F: Fn(&Self, &Timeline) + 'static>(&self, f: F) -> SignalHandlerId {
757        unsafe extern "C" fn loading_trampoline<P: IsA<Project>, F: Fn(&P, &Timeline) + 'static>(
758            this: *mut ffi::GESProject,
759            timeline: *mut ffi::GESTimeline,
760            f: glib::ffi::gpointer,
761        ) {
762            let f: &F = &*(f as *const F);
763            f(
764                Project::from_glib_borrow(this).unsafe_cast_ref(),
765                &from_glib_borrow(timeline),
766            )
767        }
768        unsafe {
769            let f: Box_<F> = Box_::new(f);
770            connect_raw(
771                self.as_ptr() as *mut _,
772                c"loading".as_ptr() as *const _,
773                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
774                    loading_trampoline::<Self, F> as *const (),
775                )),
776                Box_::into_raw(f),
777            )
778        }
779    }
780
781    /// **⚠️ The following code is in c ⚠️**
782    ///
783    /// ```c
784    /// static gchar
785    /// source_moved_cb (GESProject *project, GError *error, GESAsset *asset_with_error)
786    /// {
787    ///   return g_strdup ("file:///the/new/uri.ogg");
788    /// }
789    ///
790    /// static int
791    /// main (int argc, gchar ** argv)
792    /// {
793    ///   GESTimeline *timeline;
794    ///   GESProject *project = ges_project_new ("file:///some/uri.xges");
795    ///
796    ///   g_signal_connect (project, "missing-uri", source_moved_cb, NULL);
797    ///   timeline = ges_asset_extract (GES_ASSET (project));
798    /// }
799    /// ```
800    /// ## `error`
801    /// The error that happened
802    /// ## `wrong_asset`
803    /// The asset with the wrong ID, you should us it and its content
804    /// only to find out what the new location is.
805    ///
806    /// # Returns
807    ///
808    /// The new URI of `wrong_asset`
809    #[doc(alias = "missing-uri")]
810    fn connect_missing_uri<
811        F: Fn(&Self, &glib::Error, &Asset) -> Option<glib::GString> + 'static,
812    >(
813        &self,
814        f: F,
815    ) -> SignalHandlerId {
816        unsafe extern "C" fn missing_uri_trampoline<
817            P: IsA<Project>,
818            F: Fn(&P, &glib::Error, &Asset) -> Option<glib::GString> + 'static,
819        >(
820            this: *mut ffi::GESProject,
821            error: *mut glib::ffi::GError,
822            wrong_asset: *mut ffi::GESAsset,
823            f: glib::ffi::gpointer,
824        ) -> *mut std::ffi::c_char {
825            let f: &F = &*(f as *const F);
826            f(
827                Project::from_glib_borrow(this).unsafe_cast_ref(),
828                &from_glib_borrow(error),
829                &from_glib_borrow(wrong_asset),
830            )
831            .to_glib_full()
832        }
833        unsafe {
834            let f: Box_<F> = Box_::new(f);
835            connect_raw(
836                self.as_ptr() as *mut _,
837                c"missing-uri".as_ptr() as *const _,
838                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
839                    missing_uri_trampoline::<Self, F> as *const (),
840                )),
841                Box_::into_raw(f),
842            )
843        }
844    }
845}
846
847impl<O: IsA<Project>> ProjectExt for O {}