Skip to main content

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