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
6#[cfg(feature = "v1_18")]
7#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
8use crate::Formatter;
9use crate::{Asset, MetaContainer, Timeline, ffi};
10use glib::{
11    object::ObjectType as _,
12    prelude::*,
13    signal::{SignalHandlerId, connect_raw},
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_with_type()`][crate::Asset::request_with_type()]).
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            unsafe {
555                let f: &F = &*(f as *const F);
556                f(
557                    Project::from_glib_borrow(this).unsafe_cast_ref(),
558                    &from_glib_borrow(asset),
559                )
560            }
561        }
562        unsafe {
563            let f: Box_<F> = Box_::new(f);
564            connect_raw(
565                self.as_ptr() as *mut _,
566                c"asset-added".as_ptr(),
567                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
568                    asset_added_trampoline::<Self, F> as *const (),
569                )),
570                Box_::into_raw(f),
571            )
572        }
573    }
574
575    /// ## `asset`
576    /// The [`Asset`][crate::Asset] that started loading
577    #[doc(alias = "asset-loading")]
578    fn connect_asset_loading<F: Fn(&Self, &Asset) + 'static>(&self, f: F) -> SignalHandlerId {
579        unsafe extern "C" fn asset_loading_trampoline<
580            P: IsA<Project>,
581            F: Fn(&P, &Asset) + 'static,
582        >(
583            this: *mut ffi::GESProject,
584            asset: *mut ffi::GESAsset,
585            f: glib::ffi::gpointer,
586        ) {
587            unsafe {
588                let f: &F = &*(f as *const F);
589                f(
590                    Project::from_glib_borrow(this).unsafe_cast_ref(),
591                    &from_glib_borrow(asset),
592                )
593            }
594        }
595        unsafe {
596            let f: Box_<F> = Box_::new(f);
597            connect_raw(
598                self.as_ptr() as *mut _,
599                c"asset-loading".as_ptr(),
600                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
601                    asset_loading_trampoline::<Self, F> as *const (),
602                )),
603                Box_::into_raw(f),
604            )
605        }
606    }
607
608    /// ## `asset`
609    /// The [`Asset`][crate::Asset] that has been removed from `project`
610    #[doc(alias = "asset-removed")]
611    fn connect_asset_removed<F: Fn(&Self, &Asset) + 'static>(&self, f: F) -> SignalHandlerId {
612        unsafe extern "C" fn asset_removed_trampoline<
613            P: IsA<Project>,
614            F: Fn(&P, &Asset) + 'static,
615        >(
616            this: *mut ffi::GESProject,
617            asset: *mut ffi::GESAsset,
618            f: glib::ffi::gpointer,
619        ) {
620            unsafe {
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        }
628        unsafe {
629            let f: Box_<F> = Box_::new(f);
630            connect_raw(
631                self.as_ptr() as *mut _,
632                c"asset-removed".as_ptr(),
633                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
634                    asset_removed_trampoline::<Self, F> as *const (),
635                )),
636                Box_::into_raw(f),
637            )
638        }
639    }
640
641    /// ## `timeline`
642    /// The timeline that failed loading
643    /// ## `error`
644    /// The [`glib::Error`][crate::glib::Error] defining the error that occured
645    #[cfg(feature = "v1_18")]
646    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
647    #[doc(alias = "error-loading")]
648    fn connect_error_loading<F: Fn(&Self, &Timeline, &glib::Error) + 'static>(
649        &self,
650        f: F,
651    ) -> SignalHandlerId {
652        unsafe extern "C" fn error_loading_trampoline<
653            P: IsA<Project>,
654            F: Fn(&P, &Timeline, &glib::Error) + 'static,
655        >(
656            this: *mut ffi::GESProject,
657            timeline: *mut ffi::GESTimeline,
658            error: *mut glib::ffi::GError,
659            f: glib::ffi::gpointer,
660        ) {
661            unsafe {
662                let f: &F = &*(f as *const F);
663                f(
664                    Project::from_glib_borrow(this).unsafe_cast_ref(),
665                    &from_glib_borrow(timeline),
666                    &from_glib_borrow(error),
667                )
668            }
669        }
670        unsafe {
671            let f: Box_<F> = Box_::new(f);
672            connect_raw(
673                self.as_ptr() as *mut _,
674                c"error-loading".as_ptr(),
675                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
676                    error_loading_trampoline::<Self, F> as *const (),
677                )),
678                Box_::into_raw(f),
679            )
680        }
681    }
682
683    /// Informs you that a [`Asset`][crate::Asset] could not be created. In case of
684    /// missing GStreamer plugins, the error will be set to `GST_CORE_ERROR`
685    /// [`gst::CoreError::MissingPlugin`][crate::gst::CoreError::MissingPlugin]
686    /// ## `error`
687    /// The [`glib::Error`][crate::glib::Error] defining the error that occured, might be [`None`]
688    /// ## `id`
689    /// The `id` of the asset that failed loading
690    /// ## `extractable_type`
691    /// The `extractable_type` of the asset that
692    /// failed loading
693    #[doc(alias = "error-loading-asset")]
694    fn connect_error_loading_asset<
695        F: Fn(&Self, &glib::Error, &str, glib::types::Type) + 'static,
696    >(
697        &self,
698        f: F,
699    ) -> SignalHandlerId {
700        unsafe extern "C" fn error_loading_asset_trampoline<
701            P: IsA<Project>,
702            F: Fn(&P, &glib::Error, &str, glib::types::Type) + 'static,
703        >(
704            this: *mut ffi::GESProject,
705            error: *mut glib::ffi::GError,
706            id: *mut std::ffi::c_char,
707            extractable_type: glib::ffi::GType,
708            f: glib::ffi::gpointer,
709        ) {
710            unsafe {
711                let f: &F = &*(f as *const F);
712                f(
713                    Project::from_glib_borrow(this).unsafe_cast_ref(),
714                    &from_glib_borrow(error),
715                    &glib::GString::from_glib_borrow(id),
716                    from_glib(extractable_type),
717                )
718            }
719        }
720        unsafe {
721            let f: Box_<F> = Box_::new(f);
722            connect_raw(
723                self.as_ptr() as *mut _,
724                c"error-loading-asset".as_ptr(),
725                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
726                    error_loading_asset_trampoline::<Self, F> as *const (),
727                )),
728                Box_::into_raw(f),
729            )
730        }
731    }
732
733    /// ## `timeline`
734    /// The [`Timeline`][crate::Timeline] that completed loading
735    #[doc(alias = "loaded")]
736    fn connect_loaded<F: Fn(&Self, &Timeline) + 'static>(&self, f: F) -> SignalHandlerId {
737        unsafe extern "C" fn loaded_trampoline<P: IsA<Project>, F: Fn(&P, &Timeline) + 'static>(
738            this: *mut ffi::GESProject,
739            timeline: *mut ffi::GESTimeline,
740            f: glib::ffi::gpointer,
741        ) {
742            unsafe {
743                let f: &F = &*(f as *const F);
744                f(
745                    Project::from_glib_borrow(this).unsafe_cast_ref(),
746                    &from_glib_borrow(timeline),
747                )
748            }
749        }
750        unsafe {
751            let f: Box_<F> = Box_::new(f);
752            connect_raw(
753                self.as_ptr() as *mut _,
754                c"loaded".as_ptr(),
755                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
756                    loaded_trampoline::<Self, F> as *const (),
757                )),
758                Box_::into_raw(f),
759            )
760        }
761    }
762
763    /// ## `timeline`
764    /// The [`Timeline`][crate::Timeline] that started loading
765    #[cfg(feature = "v1_18")]
766    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
767    #[doc(alias = "loading")]
768    fn connect_loading<F: Fn(&Self, &Timeline) + 'static>(&self, f: F) -> SignalHandlerId {
769        unsafe extern "C" fn loading_trampoline<P: IsA<Project>, F: Fn(&P, &Timeline) + 'static>(
770            this: *mut ffi::GESProject,
771            timeline: *mut ffi::GESTimeline,
772            f: glib::ffi::gpointer,
773        ) {
774            unsafe {
775                let f: &F = &*(f as *const F);
776                f(
777                    Project::from_glib_borrow(this).unsafe_cast_ref(),
778                    &from_glib_borrow(timeline),
779                )
780            }
781        }
782        unsafe {
783            let f: Box_<F> = Box_::new(f);
784            connect_raw(
785                self.as_ptr() as *mut _,
786                c"loading".as_ptr(),
787                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
788                    loading_trampoline::<Self, F> as *const (),
789                )),
790                Box_::into_raw(f),
791            )
792        }
793    }
794
795    /// **⚠️ The following code is in c ⚠️**
796    ///
797    /// ```c
798    /// static gchar
799    /// source_moved_cb (GESProject *project, GError *error, GESAsset *asset_with_error)
800    /// {
801    ///   return g_strdup ("file:///the/new/uri.ogg");
802    /// }
803    ///
804    /// static int
805    /// main (int argc, gchar ** argv)
806    /// {
807    ///   GESTimeline *timeline;
808    ///   GESProject *project = ges_project_new ("file:///some/uri.xges");
809    ///
810    ///   g_signal_connect (project, "missing-uri", source_moved_cb, NULL);
811    ///   timeline = ges_asset_extract (GES_ASSET (project));
812    /// }
813    /// ```
814    /// ## `error`
815    /// The error that happened
816    /// ## `wrong_asset`
817    /// The asset with the wrong ID, you should us it and its content
818    /// only to find out what the new location is.
819    ///
820    /// # Returns
821    ///
822    /// The new URI of `wrong_asset`
823    #[doc(alias = "missing-uri")]
824    fn connect_missing_uri<
825        F: Fn(&Self, &glib::Error, &Asset) -> Option<glib::GString> + 'static,
826    >(
827        &self,
828        f: F,
829    ) -> SignalHandlerId {
830        unsafe extern "C" fn missing_uri_trampoline<
831            P: IsA<Project>,
832            F: Fn(&P, &glib::Error, &Asset) -> Option<glib::GString> + 'static,
833        >(
834            this: *mut ffi::GESProject,
835            error: *mut glib::ffi::GError,
836            wrong_asset: *mut ffi::GESAsset,
837            f: glib::ffi::gpointer,
838        ) -> *mut std::ffi::c_char {
839            unsafe {
840                let f: &F = &*(f as *const F);
841                f(
842                    Project::from_glib_borrow(this).unsafe_cast_ref(),
843                    &from_glib_borrow(error),
844                    &from_glib_borrow(wrong_asset),
845                )
846                .to_glib_full()
847            }
848        }
849        unsafe {
850            let f: Box_<F> = Box_::new(f);
851            connect_raw(
852                self.as_ptr() as *mut _,
853                c"missing-uri".as_ptr(),
854                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
855                    missing_uri_trampoline::<Self, F> as *const (),
856                )),
857                Box_::into_raw(f),
858            )
859        }
860    }
861}
862
863impl<O: IsA<Project>> ProjectExt for O {}