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
221mod sealed {
222    pub trait Sealed {}
223    impl<T: super::IsA<super::Project>> Sealed for T {}
224}
225
226/// Trait containing all [`struct@Project`] methods.
227///
228/// # Implementors
229///
230/// [`Project`][struct@crate::Project]
231pub trait ProjectExt: IsA<Project> + sealed::Sealed + 'static {
232    /// Adds a [`Asset`][crate::Asset] to `self`, the project will keep a reference on
233    /// `asset`.
234    /// ## `asset`
235    /// A [`Asset`][crate::Asset] to add to `self`
236    ///
237    /// # Returns
238    ///
239    /// [`true`] if the asset could be added [`false`] it was already
240    /// in the project.
241    ///
242    /// MT safe.
243    #[doc(alias = "ges_project_add_asset")]
244    fn add_asset(&self, asset: &impl IsA<Asset>) -> bool {
245        unsafe {
246            from_glib(ffi::ges_project_add_asset(
247                self.as_ref().to_glib_none().0,
248                asset.as_ref().to_glib_none().0,
249            ))
250        }
251    }
252
253    /// Adds `profile` to the project. It lets you save in what format
254    /// the project will be rendered and keep a reference to those formats.
255    /// Also, those formats will be saved to the project file when possible.
256    /// ## `profile`
257    /// A [`gst_pbutils::EncodingProfile`][crate::gst_pbutils::EncodingProfile] to add to the project. If a profile with
258    /// the same name already exists, it will be replaced.
259    ///
260    /// # Returns
261    ///
262    /// [`true`] if `profile` could be added, [`false`] otherwise
263    ///
264    /// MT safe.
265    #[doc(alias = "ges_project_add_encoding_profile")]
266    fn add_encoding_profile(
267        &self,
268        profile: &impl IsA<gst_pbutils::EncodingProfile>,
269    ) -> Result<(), glib::error::BoolError> {
270        unsafe {
271            glib::result_from_gboolean!(
272                ffi::ges_project_add_encoding_profile(
273                    self.as_ref().to_glib_none().0,
274                    profile.as_ref().to_glib_none().0
275                ),
276                "Failed to add profile"
277            )
278        }
279    }
280
281    /// Adds a formatter to be used to load `self`
282    /// ## `formatter`
283    /// A formatter used by `self`
284    #[cfg(feature = "v1_18")]
285    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
286    #[doc(alias = "ges_project_add_formatter")]
287    fn add_formatter(&self, formatter: &impl IsA<Formatter>) {
288        unsafe {
289            ffi::ges_project_add_formatter(
290                self.as_ref().to_glib_none().0,
291                formatter.as_ref().to_glib_none().0,
292            );
293        }
294    }
295
296    /// Create and add a [`Asset`][crate::Asset] to `self`. You should connect to the
297    /// "asset-added" signal to get the asset when it finally gets added to
298    /// `self`
299    /// ## `id`
300    /// The id of the asset to create and add to `self`
301    /// ## `extractable_type`
302    /// The `GType` of the asset to create
303    ///
304    /// # Returns
305    ///
306    /// [`true`] if the asset was added and started loading, [`false`] it was
307    /// already in the project.
308    ///
309    /// MT safe.
310    #[doc(alias = "ges_project_create_asset")]
311    fn create_asset(&self, id: Option<&str>, extractable_type: glib::types::Type) -> bool {
312        unsafe {
313            from_glib(ffi::ges_project_create_asset(
314                self.as_ref().to_glib_none().0,
315                id.to_glib_none().0,
316                extractable_type.into_glib(),
317            ))
318        }
319    }
320
321    /// Create and add a [`Asset`][crate::Asset] to `self`. You should connect to the
322    /// "asset-added" signal to get the asset when it finally gets added to
323    /// `self`
324    /// ## `id`
325    /// The id of the asset to create and add to `self`
326    /// ## `extractable_type`
327    /// The `GType` of the asset to create
328    ///
329    /// # Returns
330    ///
331    /// The newly created [`Asset`][crate::Asset] or [`None`].
332    ///
333    /// MT safe.
334    #[doc(alias = "ges_project_create_asset_sync")]
335    fn create_asset_sync(
336        &self,
337        id: Option<&str>,
338        extractable_type: glib::types::Type,
339    ) -> Result<Option<Asset>, glib::Error> {
340        unsafe {
341            let mut error = std::ptr::null_mut();
342            let ret = ffi::ges_project_create_asset_sync(
343                self.as_ref().to_glib_none().0,
344                id.to_glib_none().0,
345                extractable_type.into_glib(),
346                &mut error,
347            );
348            if error.is_null() {
349                Ok(from_glib_full(ret))
350            } else {
351                Err(from_glib_full(error))
352            }
353        }
354    }
355
356    /// ## `id`
357    /// The id of the asset to retrieve
358    /// ## `extractable_type`
359    /// The extractable_type of the asset
360    /// to retrieve from `object`
361    ///
362    /// # Returns
363    ///
364    /// The [`Asset`][crate::Asset] with
365    /// `id` or [`None`] if no asset with `id` as an ID
366    ///
367    /// MT safe.
368    #[doc(alias = "ges_project_get_asset")]
369    #[doc(alias = "get_asset")]
370    fn asset(&self, id: &str, extractable_type: glib::types::Type) -> Option<Asset> {
371        unsafe {
372            from_glib_full(ffi::ges_project_get_asset(
373                self.as_ref().to_glib_none().0,
374                id.to_glib_none().0,
375                extractable_type.into_glib(),
376            ))
377        }
378    }
379
380    /// Get the assets that are being loaded
381    ///
382    /// # Returns
383    ///
384    /// A set of loading asset
385    /// that will be added to `self`. Note that those Asset are *not* loaded yet,
386    /// and thus can not be used.
387    ///
388    /// MT safe.
389    #[doc(alias = "ges_project_get_loading_assets")]
390    #[doc(alias = "get_loading_assets")]
391    fn loading_assets(&self) -> Vec<Asset> {
392        unsafe {
393            FromGlibPtrContainer::from_glib_full(ffi::ges_project_get_loading_assets(
394                self.as_ref().to_glib_none().0,
395            ))
396        }
397    }
398
399    /// Retrieve the uri that is currently set on `self`
400    ///
401    /// # Returns
402    ///
403    /// a newly allocated string representing uri.
404    ///
405    /// MT safe.
406    #[doc(alias = "ges_project_get_uri")]
407    #[doc(alias = "get_uri")]
408    fn uri(&self) -> Option<glib::GString> {
409        unsafe { from_glib_full(ffi::ges_project_get_uri(self.as_ref().to_glib_none().0)) }
410    }
411
412    /// List all `asset` contained in `self` filtering per extractable_type
413    /// as defined by `filter`. It copies the asset and thus will not be updated
414    /// in time.
415    /// ## `filter`
416    /// Type of assets to list, `GES_TYPE_EXTRACTABLE` will list
417    /// all assets
418    ///
419    /// # Returns
420    ///
421    /// The list of
422    /// [`Asset`][crate::Asset] the object contains
423    ///
424    /// MT safe.
425    #[doc(alias = "ges_project_list_assets")]
426    fn list_assets(&self, filter: glib::types::Type) -> Vec<Asset> {
427        unsafe {
428            FromGlibPtrContainer::from_glib_full(ffi::ges_project_list_assets(
429                self.as_ref().to_glib_none().0,
430                filter.into_glib(),
431            ))
432        }
433    }
434
435    /// Lists the encoding profile that have been set to `self`. The first one
436    /// is the latest added.
437    ///
438    /// # Returns
439    ///
440    /// The
441    /// list of [`gst_pbutils::EncodingProfile`][crate::gst_pbutils::EncodingProfile] used in `self`
442    #[doc(alias = "ges_project_list_encoding_profiles")]
443    fn list_encoding_profiles(&self) -> Vec<gst_pbutils::EncodingProfile> {
444        unsafe {
445            FromGlibPtrContainer::from_glib_none(ffi::ges_project_list_encoding_profiles(
446                self.as_ref().to_glib_none().0,
447            ))
448        }
449    }
450
451    /// Loads `self` into `timeline`
452    /// ## `timeline`
453    /// A blank timeline to load `self` into
454    ///
455    /// # Returns
456    ///
457    /// [`true`] if the project could be loaded [`false`] otherwise.
458    ///
459    /// MT safe.
460    #[doc(alias = "ges_project_load")]
461    fn load(&self, timeline: &impl IsA<Timeline>) -> Result<(), glib::Error> {
462        unsafe {
463            let mut error = std::ptr::null_mut();
464            let is_ok = ffi::ges_project_load(
465                self.as_ref().to_glib_none().0,
466                timeline.as_ref().to_glib_none().0,
467                &mut error,
468            );
469            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
470            if error.is_null() {
471                Ok(())
472            } else {
473                Err(from_glib_full(error))
474            }
475        }
476    }
477
478    /// Remove `asset` from `self`.
479    /// ## `asset`
480    /// A [`Asset`][crate::Asset] to remove from `self`
481    ///
482    /// # Returns
483    ///
484    /// [`true`] if the asset could be removed [`false`] otherwise
485    ///
486    /// MT safe.
487    #[doc(alias = "ges_project_remove_asset")]
488    fn remove_asset(&self, asset: &impl IsA<Asset>) -> Result<(), glib::error::BoolError> {
489        unsafe {
490            glib::result_from_gboolean!(
491                ffi::ges_project_remove_asset(
492                    self.as_ref().to_glib_none().0,
493                    asset.as_ref().to_glib_none().0
494                ),
495                "Failed to remove asset"
496            )
497        }
498    }
499
500    /// Save the timeline of `self` to `uri`. You should make sure that `timeline`
501    /// is one of the timelines that have been extracted from `self`
502    /// (using ges_asset_extract (`self`);)
503    /// ## `timeline`
504    /// The [`Timeline`][crate::Timeline] to save, it must have been extracted from `self`
505    /// ## `uri`
506    /// The uri where to save `self` and `timeline`
507    /// ## `formatter_asset`
508    /// The formatter asset to
509    /// use or [`None`]. If [`None`], will try to save in the same format as the one
510    /// from which the timeline as been loaded or default to the best formatter
511    /// as defined in `ges_find_formatter_for_uri`
512    /// ## `overwrite`
513    /// [`true`] to overwrite file if it exists
514    ///
515    /// # Returns
516    ///
517    /// [`true`] if the project could be save, [`false`] otherwise
518    ///
519    /// MT safe.
520    #[doc(alias = "ges_project_save")]
521    fn save(
522        &self,
523        timeline: &impl IsA<Timeline>,
524        uri: &str,
525        formatter_asset: Option<impl IsA<Asset>>,
526        overwrite: bool,
527    ) -> Result<(), glib::Error> {
528        unsafe {
529            let mut error = std::ptr::null_mut();
530            let is_ok = ffi::ges_project_save(
531                self.as_ref().to_glib_none().0,
532                timeline.as_ref().to_glib_none().0,
533                uri.to_glib_none().0,
534                formatter_asset.map(|p| p.upcast()).into_glib_ptr(),
535                overwrite.into_glib(),
536                &mut error,
537            );
538            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
539            if error.is_null() {
540                Ok(())
541            } else {
542                Err(from_glib_full(error))
543            }
544        }
545    }
546
547    /// ## `asset`
548    /// The [`Asset`][crate::Asset] that has been added to `project`
549    #[doc(alias = "asset-added")]
550    fn connect_asset_added<F: Fn(&Self, &Asset) + 'static>(&self, f: F) -> SignalHandlerId {
551        unsafe extern "C" fn asset_added_trampoline<
552            P: IsA<Project>,
553            F: Fn(&P, &Asset) + 'static,
554        >(
555            this: *mut ffi::GESProject,
556            asset: *mut ffi::GESAsset,
557            f: glib::ffi::gpointer,
558        ) {
559            let f: &F = &*(f as *const F);
560            f(
561                Project::from_glib_borrow(this).unsafe_cast_ref(),
562                &from_glib_borrow(asset),
563            )
564        }
565        unsafe {
566            let f: Box_<F> = Box_::new(f);
567            connect_raw(
568                self.as_ptr() as *mut _,
569                b"asset-added\0".as_ptr() as *const _,
570                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
571                    asset_added_trampoline::<Self, F> as *const (),
572                )),
573                Box_::into_raw(f),
574            )
575        }
576    }
577
578    /// ## `asset`
579    /// The [`Asset`][crate::Asset] that started loading
580    #[doc(alias = "asset-loading")]
581    fn connect_asset_loading<F: Fn(&Self, &Asset) + 'static>(&self, f: F) -> SignalHandlerId {
582        unsafe extern "C" fn asset_loading_trampoline<
583            P: IsA<Project>,
584            F: Fn(&P, &Asset) + 'static,
585        >(
586            this: *mut ffi::GESProject,
587            asset: *mut ffi::GESAsset,
588            f: glib::ffi::gpointer,
589        ) {
590            let f: &F = &*(f as *const F);
591            f(
592                Project::from_glib_borrow(this).unsafe_cast_ref(),
593                &from_glib_borrow(asset),
594            )
595        }
596        unsafe {
597            let f: Box_<F> = Box_::new(f);
598            connect_raw(
599                self.as_ptr() as *mut _,
600                b"asset-loading\0".as_ptr() as *const _,
601                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
602                    asset_loading_trampoline::<Self, F> as *const (),
603                )),
604                Box_::into_raw(f),
605            )
606        }
607    }
608
609    /// ## `asset`
610    /// The [`Asset`][crate::Asset] that has been removed from `project`
611    #[doc(alias = "asset-removed")]
612    fn connect_asset_removed<F: Fn(&Self, &Asset) + 'static>(&self, f: F) -> SignalHandlerId {
613        unsafe extern "C" fn asset_removed_trampoline<
614            P: IsA<Project>,
615            F: Fn(&P, &Asset) + 'static,
616        >(
617            this: *mut ffi::GESProject,
618            asset: *mut ffi::GESAsset,
619            f: glib::ffi::gpointer,
620        ) {
621            let f: &F = &*(f as *const F);
622            f(
623                Project::from_glib_borrow(this).unsafe_cast_ref(),
624                &from_glib_borrow(asset),
625            )
626        }
627        unsafe {
628            let f: Box_<F> = Box_::new(f);
629            connect_raw(
630                self.as_ptr() as *mut _,
631                b"asset-removed\0".as_ptr() as *const _,
632                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
633                    asset_removed_trampoline::<Self, F> as *const (),
634                )),
635                Box_::into_raw(f),
636            )
637        }
638    }
639
640    /// ## `timeline`
641    /// The timeline that failed loading
642    /// ## `error`
643    /// The [`glib::Error`][crate::glib::Error] defining the error that occured
644    #[cfg(feature = "v1_18")]
645    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
646    #[doc(alias = "error-loading")]
647    fn connect_error_loading<F: Fn(&Self, &Timeline, &glib::Error) + 'static>(
648        &self,
649        f: F,
650    ) -> SignalHandlerId {
651        unsafe extern "C" fn error_loading_trampoline<
652            P: IsA<Project>,
653            F: Fn(&P, &Timeline, &glib::Error) + 'static,
654        >(
655            this: *mut ffi::GESProject,
656            timeline: *mut ffi::GESTimeline,
657            error: *mut glib::ffi::GError,
658            f: glib::ffi::gpointer,
659        ) {
660            let f: &F = &*(f as *const F);
661            f(
662                Project::from_glib_borrow(this).unsafe_cast_ref(),
663                &from_glib_borrow(timeline),
664                &from_glib_borrow(error),
665            )
666        }
667        unsafe {
668            let f: Box_<F> = Box_::new(f);
669            connect_raw(
670                self.as_ptr() as *mut _,
671                b"error-loading\0".as_ptr() as *const _,
672                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
673                    error_loading_trampoline::<Self, F> as *const (),
674                )),
675                Box_::into_raw(f),
676            )
677        }
678    }
679
680    /// Informs you that a [`Asset`][crate::Asset] could not be created. In case of
681    /// missing GStreamer plugins, the error will be set to `GST_CORE_ERROR`
682    /// [`gst::CoreError::MissingPlugin`][crate::gst::CoreError::MissingPlugin]
683    /// ## `error`
684    /// The [`glib::Error`][crate::glib::Error] defining the error that occured, might be [`None`]
685    /// ## `id`
686    /// The `id` of the asset that failed loading
687    /// ## `extractable_type`
688    /// The `extractable_type` of the asset that
689    /// failed loading
690    #[doc(alias = "error-loading-asset")]
691    fn connect_error_loading_asset<
692        F: Fn(&Self, &glib::Error, &str, glib::types::Type) + 'static,
693    >(
694        &self,
695        f: F,
696    ) -> SignalHandlerId {
697        unsafe extern "C" fn error_loading_asset_trampoline<
698            P: IsA<Project>,
699            F: Fn(&P, &glib::Error, &str, glib::types::Type) + 'static,
700        >(
701            this: *mut ffi::GESProject,
702            error: *mut glib::ffi::GError,
703            id: *mut std::ffi::c_char,
704            extractable_type: glib::ffi::GType,
705            f: glib::ffi::gpointer,
706        ) {
707            let f: &F = &*(f as *const F);
708            f(
709                Project::from_glib_borrow(this).unsafe_cast_ref(),
710                &from_glib_borrow(error),
711                &glib::GString::from_glib_borrow(id),
712                from_glib(extractable_type),
713            )
714        }
715        unsafe {
716            let f: Box_<F> = Box_::new(f);
717            connect_raw(
718                self.as_ptr() as *mut _,
719                b"error-loading-asset\0".as_ptr() as *const _,
720                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
721                    error_loading_asset_trampoline::<Self, F> as *const (),
722                )),
723                Box_::into_raw(f),
724            )
725        }
726    }
727
728    /// ## `timeline`
729    /// The [`Timeline`][crate::Timeline] that completed loading
730    #[doc(alias = "loaded")]
731    fn connect_loaded<F: Fn(&Self, &Timeline) + 'static>(&self, f: F) -> SignalHandlerId {
732        unsafe extern "C" fn loaded_trampoline<P: IsA<Project>, F: Fn(&P, &Timeline) + 'static>(
733            this: *mut ffi::GESProject,
734            timeline: *mut ffi::GESTimeline,
735            f: glib::ffi::gpointer,
736        ) {
737            let f: &F = &*(f as *const F);
738            f(
739                Project::from_glib_borrow(this).unsafe_cast_ref(),
740                &from_glib_borrow(timeline),
741            )
742        }
743        unsafe {
744            let f: Box_<F> = Box_::new(f);
745            connect_raw(
746                self.as_ptr() as *mut _,
747                b"loaded\0".as_ptr() as *const _,
748                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
749                    loaded_trampoline::<Self, F> as *const (),
750                )),
751                Box_::into_raw(f),
752            )
753        }
754    }
755
756    /// ## `timeline`
757    /// The [`Timeline`][crate::Timeline] that started loading
758    #[cfg(feature = "v1_18")]
759    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
760    #[doc(alias = "loading")]
761    fn connect_loading<F: Fn(&Self, &Timeline) + 'static>(&self, f: F) -> SignalHandlerId {
762        unsafe extern "C" fn loading_trampoline<P: IsA<Project>, F: Fn(&P, &Timeline) + 'static>(
763            this: *mut ffi::GESProject,
764            timeline: *mut ffi::GESTimeline,
765            f: glib::ffi::gpointer,
766        ) {
767            let f: &F = &*(f as *const F);
768            f(
769                Project::from_glib_borrow(this).unsafe_cast_ref(),
770                &from_glib_borrow(timeline),
771            )
772        }
773        unsafe {
774            let f: Box_<F> = Box_::new(f);
775            connect_raw(
776                self.as_ptr() as *mut _,
777                b"loading\0".as_ptr() as *const _,
778                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
779                    loading_trampoline::<Self, F> as *const (),
780                )),
781                Box_::into_raw(f),
782            )
783        }
784    }
785
786    /// **⚠️ The following code is in c ⚠️**
787    ///
788    /// ```c
789    /// static gchar
790    /// source_moved_cb (GESProject *project, GError *error, GESAsset *asset_with_error)
791    /// {
792    ///   return g_strdup ("file:///the/new/uri.ogg");
793    /// }
794    ///
795    /// static int
796    /// main (int argc, gchar ** argv)
797    /// {
798    ///   GESTimeline *timeline;
799    ///   GESProject *project = ges_project_new ("file:///some/uri.xges");
800    ///
801    ///   g_signal_connect (project, "missing-uri", source_moved_cb, NULL);
802    ///   timeline = ges_asset_extract (GES_ASSET (project));
803    /// }
804    /// ```
805    /// ## `error`
806    /// The error that happened
807    /// ## `wrong_asset`
808    /// The asset with the wrong ID, you should us it and its content
809    /// only to find out what the new location is.
810    ///
811    /// # Returns
812    ///
813    /// The new URI of `wrong_asset`
814    #[doc(alias = "missing-uri")]
815    fn connect_missing_uri<
816        F: Fn(&Self, &glib::Error, &Asset) -> Option<glib::GString> + 'static,
817    >(
818        &self,
819        f: F,
820    ) -> SignalHandlerId {
821        unsafe extern "C" fn missing_uri_trampoline<
822            P: IsA<Project>,
823            F: Fn(&P, &glib::Error, &Asset) -> Option<glib::GString> + 'static,
824        >(
825            this: *mut ffi::GESProject,
826            error: *mut glib::ffi::GError,
827            wrong_asset: *mut ffi::GESAsset,
828            f: glib::ffi::gpointer,
829        ) -> *mut std::ffi::c_char {
830            let f: &F = &*(f as *const F);
831            f(
832                Project::from_glib_borrow(this).unsafe_cast_ref(),
833                &from_glib_borrow(error),
834                &from_glib_borrow(wrong_asset),
835            )
836            .to_glib_full()
837        }
838        unsafe {
839            let f: Box_<F> = Box_::new(f);
840            connect_raw(
841                self.as_ptr() as *mut _,
842                b"missing-uri\0".as_ptr() as *const _,
843                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
844                    missing_uri_trampoline::<Self, F> as *const (),
845                )),
846                Box_::into_raw(f),
847            )
848        }
849    }
850}
851
852impl<O: IsA<Project>> ProjectExt for O {}