mirror of
https://gitlab.freedesktop.org/dabrain34/GstPipelineStudio.git
synced 2024-11-21 16:41:03 +00:00
app: enhance element uri handler
Open the given dialog according to the type of property or uri handler supported
This commit is contained in:
parent
7bb0d73e40
commit
8905ff6592
4 changed files with 179 additions and 40 deletions
127
src/app.rs
127
src/app.rs
|
@ -448,20 +448,24 @@ impl GPSApp {
|
|||
let app_weak = self.downgrade();
|
||||
self.connect_app_menu_action("open", move |_, _| {
|
||||
let app = upgrade_weak!(app_weak);
|
||||
GPSUI::dialog::get_file_from_dialog(&app, false, move |app, filename| {
|
||||
app.load_graph(&filename, false)
|
||||
.unwrap_or_else(|_| GPS_ERROR!("Unable to open file {}", filename));
|
||||
});
|
||||
GPSUI::dialog::get_file_from_dialog(
|
||||
&app,
|
||||
GPSUI::dialog::FileDialogType::Open,
|
||||
move |app, filename| {
|
||||
app.load_graph(&filename, false)
|
||||
.unwrap_or_else(|_| GPS_ERROR!("Unable to open file {}", filename));
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
let app_weak = self.downgrade();
|
||||
self.connect_app_menu_action("open_pipeline", move |_, _| {
|
||||
let app = upgrade_weak!(app_weak);
|
||||
GPSUI::dialog::create_input_dialog(
|
||||
&app,
|
||||
"Enter pipeline description with gst-launch format",
|
||||
"description",
|
||||
&Settings::recent_pipeline_description(),
|
||||
&app,
|
||||
move |app, pipeline_desc| {
|
||||
app.load_pipeline(&pipeline_desc).unwrap_or_else(|_| {
|
||||
GPS_ERROR!("Unable to open pipeline description {}", pipeline_desc)
|
||||
|
@ -475,12 +479,16 @@ impl GPSApp {
|
|||
let app = upgrade_weak!(app_weak);
|
||||
let gt = graphbook::current_graphtab(&app);
|
||||
if gt.undefined() {
|
||||
GPSUI::dialog::get_file_from_dialog(&app, true, move |app, filename| {
|
||||
GPS_DEBUG!("Save file {}", filename);
|
||||
app.save_graph(&filename)
|
||||
.unwrap_or_else(|_| GPS_ERROR!("Unable to save file to {}", filename));
|
||||
graphbook::current_graphtab_set_filename(&app, filename.as_str());
|
||||
});
|
||||
GPSUI::dialog::get_file_from_dialog(
|
||||
&app,
|
||||
GPSUI::dialog::FileDialogType::Save,
|
||||
move |app, filename| {
|
||||
GPS_DEBUG!("Save file {}", filename);
|
||||
app.save_graph(&filename)
|
||||
.unwrap_or_else(|_| GPS_ERROR!("Unable to save file to {}", filename));
|
||||
graphbook::current_graphtab_set_filename(&app, filename.as_str());
|
||||
},
|
||||
);
|
||||
} else if gt.modified() {
|
||||
let filename = gt.filename();
|
||||
app.save_graph(&filename)
|
||||
|
@ -492,12 +500,16 @@ impl GPSApp {
|
|||
let app_weak = self.downgrade();
|
||||
self.connect_app_menu_action("save_as", move |_, _| {
|
||||
let app = upgrade_weak!(app_weak);
|
||||
GPSUI::dialog::get_file_from_dialog(&app, true, move |app, filename| {
|
||||
GPS_DEBUG!("Save file {}", filename);
|
||||
app.save_graph(&filename)
|
||||
.unwrap_or_else(|_| GPS_ERROR!("Unable to save file to {}", filename));
|
||||
graphbook::current_graphtab_set_filename(&app, filename.as_str());
|
||||
});
|
||||
GPSUI::dialog::get_file_from_dialog(
|
||||
&app,
|
||||
GPSUI::dialog::FileDialogType::Save,
|
||||
move |app, filename| {
|
||||
GPS_DEBUG!("Save file {}", filename);
|
||||
app.save_graph(&filename)
|
||||
.unwrap_or_else(|_| GPS_ERROR!("Unable to save file to {}", filename));
|
||||
graphbook::current_graphtab_set_filename(&app, filename.as_str());
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
let app_weak = self.downgrade();
|
||||
|
@ -589,15 +601,78 @@ impl GPSApp {
|
|||
.graphview()
|
||||
.create_node(element_name, GPS::ElementInfo::element_type(element_name));
|
||||
let node_id = node.id();
|
||||
if GPS::ElementInfo::element_is_uri_src_handler(element_name) {
|
||||
GPSUI::dialog::get_file_from_dialog(self, false, move |app, filename| {
|
||||
GPS_DEBUG!("Open file {}", filename);
|
||||
let mut properties: HashMap<String, String> = HashMap::new();
|
||||
properties.insert(String::from("location"), filename);
|
||||
if let Some(node) = graphbook::current_graphtab(&app).graphview().node(node_id) {
|
||||
node.update_properties(&properties);
|
||||
}
|
||||
});
|
||||
if let Some((prop_name, file_chooser)) =
|
||||
GPS::ElementInfo::element_is_uri_src_handler(element_name)
|
||||
{
|
||||
if file_chooser {
|
||||
GPSUI::dialog::get_file_from_dialog(
|
||||
self,
|
||||
GPSUI::dialog::FileDialogType::OpenAll,
|
||||
move |app, filename| {
|
||||
GPS_DEBUG!("Open file {}", filename);
|
||||
let mut properties: HashMap<String, String> = HashMap::new();
|
||||
properties.insert(prop_name.clone(), filename);
|
||||
if let Some(node) =
|
||||
graphbook::current_graphtab(&app).graphview().node(node_id)
|
||||
{
|
||||
node.update_properties(&properties);
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
GPSUI::dialog::create_input_dialog(
|
||||
self,
|
||||
"Enter uri",
|
||||
"uri",
|
||||
"",
|
||||
move |app, uri| {
|
||||
GPS_DEBUG!("Open uri {}", uri);
|
||||
let mut properties: HashMap<String, String> = HashMap::new();
|
||||
properties.insert(String::from("uri"), uri);
|
||||
if let Some(node) =
|
||||
graphbook::current_graphtab(&app).graphview().node(node_id)
|
||||
{
|
||||
node.update_properties(&properties);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
} else if let Some((prop_name, file_chooser)) =
|
||||
GPS::ElementInfo::element_is_uri_sink_handler(element_name)
|
||||
{
|
||||
if file_chooser {
|
||||
GPSUI::dialog::get_file_from_dialog(
|
||||
self,
|
||||
GPSUI::dialog::FileDialogType::SaveAll,
|
||||
move |app, filename| {
|
||||
GPS_DEBUG!("Save file {}", filename);
|
||||
let mut properties: HashMap<String, String> = HashMap::new();
|
||||
properties.insert(prop_name.clone(), filename);
|
||||
if let Some(node) =
|
||||
graphbook::current_graphtab(&app).graphview().node(node_id)
|
||||
{
|
||||
node.update_properties(&properties);
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
GPSUI::dialog::create_input_dialog(
|
||||
self,
|
||||
"Enter uri",
|
||||
"uri",
|
||||
"",
|
||||
move |app, uri| {
|
||||
GPS_DEBUG!("Save uri {}", uri);
|
||||
let mut properties: HashMap<String, String> = HashMap::new();
|
||||
properties.insert(String::from("uri"), uri);
|
||||
if let Some(node) =
|
||||
graphbook::current_graphtab(&app).graphview().node(node_id)
|
||||
{
|
||||
node.update_properties(&properties);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
graphbook::current_graphtab(self).graphview().add_node(node);
|
||||
for input in inputs {
|
||||
|
|
|
@ -237,9 +237,17 @@ impl ElementInfo {
|
|||
ElementInfo::element_properties(&element)
|
||||
}
|
||||
|
||||
pub fn element_is_uri_src_handler(element_name: &str) -> bool {
|
||||
let feature = ElementInfo::element_feature(element_name).expect("Unable to get feature");
|
||||
pub fn element_has_property(element: &gst::Element, property_name: &str) -> bool {
|
||||
let properties = ElementInfo::element_properties(element)
|
||||
.unwrap_or_else(|_| panic!("Couldn't get properties for {}", element.name()));
|
||||
|
||||
properties.keys().any(|name| name == property_name)
|
||||
}
|
||||
|
||||
pub fn element_is_uri_src_handler(element_name: &str) -> Option<(String, bool)> {
|
||||
let feature: gst::PluginFeature =
|
||||
ElementInfo::element_feature(element_name).expect("Unable to get feature");
|
||||
let mut file_chooser = false;
|
||||
let factory = feature
|
||||
.downcast::<gst::ElementFactory>()
|
||||
.expect("Unable to get the factory from the feature");
|
||||
|
@ -247,10 +255,52 @@ impl ElementInfo {
|
|||
.create()
|
||||
.build()
|
||||
.expect("Unable to create an element from the feature");
|
||||
match element.dynamic_cast::<gst::URIHandler>() {
|
||||
Ok(uri_handler) => uri_handler.uri_type() == gst::URIType::Src,
|
||||
Err(_e) => false,
|
||||
if let Ok(uri_handler) = element.clone().dynamic_cast::<gst::URIHandler>() {
|
||||
let search_strings = ["file", "pushfile"];
|
||||
file_chooser = search_strings
|
||||
.iter()
|
||||
.any(|s| uri_handler.protocols().contains(&glib::GString::from(*s)));
|
||||
}
|
||||
|
||||
if element.is::<gst::Bin>() || ElementInfo::element_type(element_name) == NodeType::Source {
|
||||
if ElementInfo::element_has_property(&element, "uri") {
|
||||
return Some((String::from("uri"), file_chooser));
|
||||
}
|
||||
if ElementInfo::element_has_property(&element, "location") {
|
||||
return Some((String::from("location"), file_chooser));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn element_is_uri_sink_handler(element_name: &str) -> Option<(String, bool)> {
|
||||
let feature = ElementInfo::element_feature(element_name).expect("Unable to get feature");
|
||||
let mut file_chooser = false;
|
||||
let factory = feature
|
||||
.downcast::<gst::ElementFactory>()
|
||||
.expect("Unable to get the factory from the feature");
|
||||
let element = factory
|
||||
.create()
|
||||
.build()
|
||||
.expect("Unable to create an element from the feature");
|
||||
|
||||
if let Ok(uri_handler) = element.clone().dynamic_cast::<gst::URIHandler>() {
|
||||
file_chooser = uri_handler
|
||||
.protocols()
|
||||
.contains(&glib::GString::from("file"))
|
||||
}
|
||||
|
||||
if ElementInfo::element_type(element_name) == NodeType::Sink {
|
||||
if ElementInfo::element_has_property(&element, "uri") {
|
||||
return Some((String::from("uri"), file_chooser));
|
||||
}
|
||||
if ElementInfo::element_has_property(&element, "location") {
|
||||
return Some((String::from("location"), file_chooser));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn element_supports_new_pad_request(
|
||||
|
|
|
@ -534,10 +534,10 @@ pub fn create_graphtab(app: &GPSApp, id: u32, name: Option<&str>) {
|
|||
GPS_TRACE!("link double clicked id={}", link_id);
|
||||
let link = current_graphtab(&app).graphview().link(link_id).unwrap();
|
||||
GPSUI::dialog::create_input_dialog(
|
||||
&app,
|
||||
"Enter caps filter description",
|
||||
"description",
|
||||
&link.name(),
|
||||
&app,
|
||||
move |app, link_desc| {
|
||||
current_graphtab(&app)
|
||||
.graphview()
|
||||
|
|
|
@ -12,6 +12,14 @@ use gtk::glib;
|
|||
use gtk::prelude::*;
|
||||
use gtk::{ApplicationWindow, FileChooserAction, FileChooserDialog, FileFilter, ResponseType};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum FileDialogType {
|
||||
Save,
|
||||
Open,
|
||||
OpenAll,
|
||||
SaveAll,
|
||||
}
|
||||
|
||||
pub fn create_dialog<F: Fn(GPSApp, gtk::Dialog) + 'static>(
|
||||
name: &str,
|
||||
app: &GPSApp,
|
||||
|
@ -50,10 +58,10 @@ pub fn create_dialog<F: Fn(GPSApp, gtk::Dialog) + 'static>(
|
|||
}
|
||||
|
||||
pub fn create_input_dialog<F: Fn(GPSApp, String) + 'static>(
|
||||
app: &GPSApp,
|
||||
dialog_name: &str,
|
||||
input_name: &str,
|
||||
default_value: &str,
|
||||
app: &GPSApp,
|
||||
f: F,
|
||||
) {
|
||||
let dialog = gtk::Dialog::with_buttons(
|
||||
|
@ -104,12 +112,16 @@ pub fn create_input_dialog<F: Fn(GPSApp, String) + 'static>(
|
|||
dialog.show();
|
||||
}
|
||||
|
||||
pub fn get_file_from_dialog<F: Fn(GPSApp, String) + 'static>(app: &GPSApp, save: bool, f: F) {
|
||||
pub fn get_file_from_dialog<F: Fn(GPSApp, String) + 'static>(
|
||||
app: &GPSApp,
|
||||
dlg_type: FileDialogType,
|
||||
f: F,
|
||||
) {
|
||||
let mut message = "Open file";
|
||||
let mut ok_button = "Open";
|
||||
let cancel_button = "Cancel";
|
||||
let mut action = FileChooserAction::Open;
|
||||
if save {
|
||||
if dlg_type == FileDialogType::Save || dlg_type == FileDialogType::SaveAll {
|
||||
message = "Save file";
|
||||
ok_button = "Save";
|
||||
action = FileChooserAction::Save;
|
||||
|
@ -127,13 +139,15 @@ pub fn get_file_from_dialog<F: Fn(GPSApp, String) + 'static>(app: &GPSApp, save:
|
|||
(cancel_button, ResponseType::Cancel),
|
||||
],
|
||||
);
|
||||
if save {
|
||||
if dlg_type == FileDialogType::Save {
|
||||
file_chooser.set_current_name("untitled.gps");
|
||||
}
|
||||
let filter = FileFilter::new();
|
||||
filter.add_pattern("*.gps");
|
||||
filter.set_name(Some("GPS Files (*.gps)"));
|
||||
file_chooser.add_filter(&filter);
|
||||
if dlg_type == FileDialogType::Open {
|
||||
let filter = FileFilter::new();
|
||||
filter.add_pattern("*.gps");
|
||||
filter.set_name(Some("GPS Files (*.gps)"));
|
||||
file_chooser.add_filter(&filter);
|
||||
}
|
||||
|
||||
let app_weak = app.downgrade();
|
||||
file_chooser.connect_response(move |d: &FileChooserDialog, response: ResponseType| {
|
||||
|
|
Loading…
Reference in a new issue