mirror of
https://gitlab.freedesktop.org/dabrain34/GstPipelineStudio.git
synced 2024-11-22 00:50:59 +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
99
src/app.rs
99
src/app.rs
|
@ -448,20 +448,24 @@ impl GPSApp {
|
||||||
let app_weak = self.downgrade();
|
let app_weak = self.downgrade();
|
||||||
self.connect_app_menu_action("open", move |_, _| {
|
self.connect_app_menu_action("open", move |_, _| {
|
||||||
let app = upgrade_weak!(app_weak);
|
let app = upgrade_weak!(app_weak);
|
||||||
GPSUI::dialog::get_file_from_dialog(&app, false, move |app, filename| {
|
GPSUI::dialog::get_file_from_dialog(
|
||||||
|
&app,
|
||||||
|
GPSUI::dialog::FileDialogType::Open,
|
||||||
|
move |app, filename| {
|
||||||
app.load_graph(&filename, false)
|
app.load_graph(&filename, false)
|
||||||
.unwrap_or_else(|_| GPS_ERROR!("Unable to open file {}", filename));
|
.unwrap_or_else(|_| GPS_ERROR!("Unable to open file {}", filename));
|
||||||
});
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
let app_weak = self.downgrade();
|
let app_weak = self.downgrade();
|
||||||
self.connect_app_menu_action("open_pipeline", move |_, _| {
|
self.connect_app_menu_action("open_pipeline", move |_, _| {
|
||||||
let app = upgrade_weak!(app_weak);
|
let app = upgrade_weak!(app_weak);
|
||||||
GPSUI::dialog::create_input_dialog(
|
GPSUI::dialog::create_input_dialog(
|
||||||
|
&app,
|
||||||
"Enter pipeline description with gst-launch format",
|
"Enter pipeline description with gst-launch format",
|
||||||
"description",
|
"description",
|
||||||
&Settings::recent_pipeline_description(),
|
&Settings::recent_pipeline_description(),
|
||||||
&app,
|
|
||||||
move |app, pipeline_desc| {
|
move |app, pipeline_desc| {
|
||||||
app.load_pipeline(&pipeline_desc).unwrap_or_else(|_| {
|
app.load_pipeline(&pipeline_desc).unwrap_or_else(|_| {
|
||||||
GPS_ERROR!("Unable to open pipeline description {}", pipeline_desc)
|
GPS_ERROR!("Unable to open pipeline description {}", pipeline_desc)
|
||||||
|
@ -475,12 +479,16 @@ impl GPSApp {
|
||||||
let app = upgrade_weak!(app_weak);
|
let app = upgrade_weak!(app_weak);
|
||||||
let gt = graphbook::current_graphtab(&app);
|
let gt = graphbook::current_graphtab(&app);
|
||||||
if gt.undefined() {
|
if gt.undefined() {
|
||||||
GPSUI::dialog::get_file_from_dialog(&app, true, move |app, filename| {
|
GPSUI::dialog::get_file_from_dialog(
|
||||||
|
&app,
|
||||||
|
GPSUI::dialog::FileDialogType::Save,
|
||||||
|
move |app, filename| {
|
||||||
GPS_DEBUG!("Save file {}", filename);
|
GPS_DEBUG!("Save file {}", filename);
|
||||||
app.save_graph(&filename)
|
app.save_graph(&filename)
|
||||||
.unwrap_or_else(|_| GPS_ERROR!("Unable to save file to {}", filename));
|
.unwrap_or_else(|_| GPS_ERROR!("Unable to save file to {}", filename));
|
||||||
graphbook::current_graphtab_set_filename(&app, filename.as_str());
|
graphbook::current_graphtab_set_filename(&app, filename.as_str());
|
||||||
});
|
},
|
||||||
|
);
|
||||||
} else if gt.modified() {
|
} else if gt.modified() {
|
||||||
let filename = gt.filename();
|
let filename = gt.filename();
|
||||||
app.save_graph(&filename)
|
app.save_graph(&filename)
|
||||||
|
@ -492,12 +500,16 @@ impl GPSApp {
|
||||||
let app_weak = self.downgrade();
|
let app_weak = self.downgrade();
|
||||||
self.connect_app_menu_action("save_as", move |_, _| {
|
self.connect_app_menu_action("save_as", move |_, _| {
|
||||||
let app = upgrade_weak!(app_weak);
|
let app = upgrade_weak!(app_weak);
|
||||||
GPSUI::dialog::get_file_from_dialog(&app, true, move |app, filename| {
|
GPSUI::dialog::get_file_from_dialog(
|
||||||
|
&app,
|
||||||
|
GPSUI::dialog::FileDialogType::Save,
|
||||||
|
move |app, filename| {
|
||||||
GPS_DEBUG!("Save file {}", filename);
|
GPS_DEBUG!("Save file {}", filename);
|
||||||
app.save_graph(&filename)
|
app.save_graph(&filename)
|
||||||
.unwrap_or_else(|_| GPS_ERROR!("Unable to save file to {}", filename));
|
.unwrap_or_else(|_| GPS_ERROR!("Unable to save file to {}", filename));
|
||||||
graphbook::current_graphtab_set_filename(&app, filename.as_str());
|
graphbook::current_graphtab_set_filename(&app, filename.as_str());
|
||||||
});
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
let app_weak = self.downgrade();
|
let app_weak = self.downgrade();
|
||||||
|
@ -589,15 +601,78 @@ impl GPSApp {
|
||||||
.graphview()
|
.graphview()
|
||||||
.create_node(element_name, GPS::ElementInfo::element_type(element_name));
|
.create_node(element_name, GPS::ElementInfo::element_type(element_name));
|
||||||
let node_id = node.id();
|
let node_id = node.id();
|
||||||
if GPS::ElementInfo::element_is_uri_src_handler(element_name) {
|
if let Some((prop_name, file_chooser)) =
|
||||||
GPSUI::dialog::get_file_from_dialog(self, false, move |app, filename| {
|
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);
|
GPS_DEBUG!("Open file {}", filename);
|
||||||
let mut properties: HashMap<String, String> = HashMap::new();
|
let mut properties: HashMap<String, String> = HashMap::new();
|
||||||
properties.insert(String::from("location"), filename);
|
properties.insert(prop_name.clone(), filename);
|
||||||
if let Some(node) = graphbook::current_graphtab(&app).graphview().node(node_id) {
|
if let Some(node) =
|
||||||
|
graphbook::current_graphtab(&app).graphview().node(node_id)
|
||||||
|
{
|
||||||
node.update_properties(&properties);
|
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);
|
graphbook::current_graphtab(self).graphview().add_node(node);
|
||||||
for input in inputs {
|
for input in inputs {
|
||||||
|
|
|
@ -237,9 +237,17 @@ impl ElementInfo {
|
||||||
ElementInfo::element_properties(&element)
|
ElementInfo::element_properties(&element)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn element_is_uri_src_handler(element_name: &str) -> bool {
|
pub fn element_has_property(element: &gst::Element, property_name: &str) -> bool {
|
||||||
let feature = ElementInfo::element_feature(element_name).expect("Unable to get feature");
|
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
|
let factory = feature
|
||||||
.downcast::<gst::ElementFactory>()
|
.downcast::<gst::ElementFactory>()
|
||||||
.expect("Unable to get the factory from the feature");
|
.expect("Unable to get the factory from the feature");
|
||||||
|
@ -247,10 +255,52 @@ impl ElementInfo {
|
||||||
.create()
|
.create()
|
||||||
.build()
|
.build()
|
||||||
.expect("Unable to create an element from the feature");
|
.expect("Unable to create an element from the feature");
|
||||||
match element.dynamic_cast::<gst::URIHandler>() {
|
if let Ok(uri_handler) = element.clone().dynamic_cast::<gst::URIHandler>() {
|
||||||
Ok(uri_handler) => uri_handler.uri_type() == gst::URIType::Src,
|
let search_strings = ["file", "pushfile"];
|
||||||
Err(_e) => false,
|
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(
|
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);
|
GPS_TRACE!("link double clicked id={}", link_id);
|
||||||
let link = current_graphtab(&app).graphview().link(link_id).unwrap();
|
let link = current_graphtab(&app).graphview().link(link_id).unwrap();
|
||||||
GPSUI::dialog::create_input_dialog(
|
GPSUI::dialog::create_input_dialog(
|
||||||
|
&app,
|
||||||
"Enter caps filter description",
|
"Enter caps filter description",
|
||||||
"description",
|
"description",
|
||||||
&link.name(),
|
&link.name(),
|
||||||
&app,
|
|
||||||
move |app, link_desc| {
|
move |app, link_desc| {
|
||||||
current_graphtab(&app)
|
current_graphtab(&app)
|
||||||
.graphview()
|
.graphview()
|
||||||
|
|
|
@ -12,6 +12,14 @@ use gtk::glib;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{ApplicationWindow, FileChooserAction, FileChooserDialog, FileFilter, ResponseType};
|
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>(
|
pub fn create_dialog<F: Fn(GPSApp, gtk::Dialog) + 'static>(
|
||||||
name: &str,
|
name: &str,
|
||||||
app: &GPSApp,
|
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>(
|
pub fn create_input_dialog<F: Fn(GPSApp, String) + 'static>(
|
||||||
|
app: &GPSApp,
|
||||||
dialog_name: &str,
|
dialog_name: &str,
|
||||||
input_name: &str,
|
input_name: &str,
|
||||||
default_value: &str,
|
default_value: &str,
|
||||||
app: &GPSApp,
|
|
||||||
f: F,
|
f: F,
|
||||||
) {
|
) {
|
||||||
let dialog = gtk::Dialog::with_buttons(
|
let dialog = gtk::Dialog::with_buttons(
|
||||||
|
@ -104,12 +112,16 @@ pub fn create_input_dialog<F: Fn(GPSApp, String) + 'static>(
|
||||||
dialog.show();
|
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 message = "Open file";
|
||||||
let mut ok_button = "Open";
|
let mut ok_button = "Open";
|
||||||
let cancel_button = "Cancel";
|
let cancel_button = "Cancel";
|
||||||
let mut action = FileChooserAction::Open;
|
let mut action = FileChooserAction::Open;
|
||||||
if save {
|
if dlg_type == FileDialogType::Save || dlg_type == FileDialogType::SaveAll {
|
||||||
message = "Save file";
|
message = "Save file";
|
||||||
ok_button = "Save";
|
ok_button = "Save";
|
||||||
action = FileChooserAction::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),
|
(cancel_button, ResponseType::Cancel),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
if save {
|
if dlg_type == FileDialogType::Save {
|
||||||
file_chooser.set_current_name("untitled.gps");
|
file_chooser.set_current_name("untitled.gps");
|
||||||
}
|
}
|
||||||
|
if dlg_type == FileDialogType::Open {
|
||||||
let filter = FileFilter::new();
|
let filter = FileFilter::new();
|
||||||
filter.add_pattern("*.gps");
|
filter.add_pattern("*.gps");
|
||||||
filter.set_name(Some("GPS Files (*.gps)"));
|
filter.set_name(Some("GPS Files (*.gps)"));
|
||||||
file_chooser.add_filter(&filter);
|
file_chooser.add_filter(&filter);
|
||||||
|
}
|
||||||
|
|
||||||
let app_weak = app.downgrade();
|
let app_weak = app.downgrade();
|
||||||
file_chooser.connect_response(move |d: &FileChooserDialog, response: ResponseType| {
|
file_chooser.connect_response(move |d: &FileChooserDialog, response: ResponseType| {
|
||||||
|
|
Loading…
Reference in a new issue