mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2025-01-27 22:46:01 -05:00
Add "Copy config" option to "Add camera" dialog
This commit is contained in:
parent
1fde947f36
commit
81ea7d8a87
@ -5,7 +5,7 @@
|
||||
use crate::stream::{self, Opener};
|
||||
use base::strutil::{decode_size, encode_size};
|
||||
use cursive::traits::{Finder, Nameable, Resizable, Scrollable};
|
||||
use cursive::views::{self, ViewRef};
|
||||
use cursive::views::{self, Dialog, ViewRef};
|
||||
use cursive::Cursive;
|
||||
use db::writer;
|
||||
use failure::{bail, format_err, Error, ResultExt};
|
||||
@ -434,32 +434,12 @@ fn edit_stream_url(type_: db::StreamType, content: &str, mut test_button: ViewRe
|
||||
test_button.set_enabled(enable_test);
|
||||
}
|
||||
|
||||
/// Adds or updates a camera.
|
||||
/// (The former if `item` is None; the latter otherwise.)
|
||||
fn edit_camera_dialog(db: &Arc<db::Database>, siv: &mut Cursive, item: &Option<i32>) {
|
||||
let camera_list = views::ListView::new()
|
||||
.child(
|
||||
"id",
|
||||
views::TextView::new(item.map_or_else(|| "<new>".to_string(), |id| id.to_string())),
|
||||
)
|
||||
.child("uuid", views::TextView::new("<new>").with_name("uuid"))
|
||||
.child("short name", views::EditView::new().with_name("short_name"))
|
||||
.child(
|
||||
"onvif_base_url",
|
||||
views::EditView::new().with_name("onvif_base_url"),
|
||||
)
|
||||
.child("username", views::EditView::new().with_name("username"))
|
||||
.child("password", views::EditView::new().with_name("password"))
|
||||
.min_height(6);
|
||||
let mut layout = views::LinearLayout::vertical()
|
||||
.child(camera_list)
|
||||
.child(views::TextView::new("description"))
|
||||
.child(
|
||||
views::TextArea::new()
|
||||
.with_name("description")
|
||||
.min_height(3),
|
||||
);
|
||||
|
||||
fn load_camera_values(
|
||||
db: &Arc<db::Database>,
|
||||
camera_id: i32,
|
||||
dialog: &mut Dialog,
|
||||
overwrite_uuid: bool,
|
||||
) -> (String, i64) {
|
||||
let dirs: Vec<_> = ::std::iter::once(("<none>".into(), None))
|
||||
.chain(
|
||||
db.lock()
|
||||
@ -468,70 +448,15 @@ fn edit_camera_dialog(db: &Arc<db::Database>, siv: &mut Cursive, item: &Option<i
|
||||
.map(|(&id, d)| (d.path.to_owned(), Some(id))),
|
||||
)
|
||||
.collect();
|
||||
for &type_ in &db::ALL_STREAM_TYPES {
|
||||
let list = views::ListView::new()
|
||||
.child(
|
||||
"rtsp url",
|
||||
views::LinearLayout::horizontal()
|
||||
.child(
|
||||
views::EditView::new()
|
||||
.on_edit(move |siv, content, _pos| {
|
||||
let test_button = siv
|
||||
.find_name::<views::Button>(&format!("{}_test", type_))
|
||||
.unwrap();
|
||||
edit_stream_url(type_, content, test_button);
|
||||
})
|
||||
.with_name(format!("{}_url", type_))
|
||||
.full_width(),
|
||||
)
|
||||
.child(views::DummyView)
|
||||
.child(
|
||||
views::Button::new("Test", move |siv| press_test(siv, type_))
|
||||
.disabled()
|
||||
.with_name(format!("{}_test", type_)),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
"sample file dir",
|
||||
views::SelectView::<Option<i32>>::new()
|
||||
.with_all(dirs.iter().map(|(p, id)| (p.display().to_string(), *id)))
|
||||
.popup()
|
||||
.with_name(format!("{}_sample_file_dir", type_)),
|
||||
)
|
||||
.child(
|
||||
"record",
|
||||
views::Checkbox::new().with_name(format!("{}_record", type_)),
|
||||
)
|
||||
.child(
|
||||
"rtsp_transport",
|
||||
views::SelectView::<&str>::new()
|
||||
.with_all([("(default)", ""), ("tcp", "tcp"), ("udp", "udp")])
|
||||
.popup()
|
||||
.with_name(format!("{}_rtsp_transport", type_)),
|
||||
)
|
||||
.child(
|
||||
"flush_if_sec",
|
||||
views::EditView::new().with_name(format!("{}_flush_if_sec", type_)),
|
||||
)
|
||||
.child(
|
||||
"usage/capacity",
|
||||
views::TextView::new("").with_name(format!("{}_usage_cap", type_)),
|
||||
)
|
||||
.min_height(5);
|
||||
layout.add_child(views::DummyView);
|
||||
layout.add_child(views::TextView::new(format!("{} stream", type_)));
|
||||
layout.add_child(list);
|
||||
}
|
||||
|
||||
let mut dialog = views::Dialog::around(layout.scrollable());
|
||||
let dialog = if let Some(camera_id) = *item {
|
||||
let l = db.lock();
|
||||
let camera = l.cameras_by_id().get(&camera_id).expect("missing camera");
|
||||
if overwrite_uuid {
|
||||
dialog
|
||||
.call_on_name("uuid", |v: &mut views::TextView| {
|
||||
v.set_content(camera.uuid.to_string())
|
||||
})
|
||||
.expect("missing TextView");
|
||||
}
|
||||
|
||||
let mut bytes = 0;
|
||||
for (i, sid) in camera.streams.iter().enumerate() {
|
||||
@ -627,6 +552,101 @@ fn edit_camera_dialog(db: &Arc<db::Database>, siv: &mut Cursive, item: &Option<i
|
||||
v.set_content(camera.config.description.clone())
|
||||
})
|
||||
.expect("missing TextArea");
|
||||
(name, bytes)
|
||||
}
|
||||
|
||||
/// Adds or updates a camera.
|
||||
/// (The former if `item` is None; the latter otherwise.)
|
||||
fn edit_camera_dialog(db: &Arc<db::Database>, siv: &mut Cursive, item: &Option<i32>) {
|
||||
let camera_list = views::ListView::new()
|
||||
.child(
|
||||
"id",
|
||||
views::TextView::new(item.map_or_else(|| "<new>".to_string(), |id| id.to_string())),
|
||||
)
|
||||
.child("uuid", views::TextView::new("<new>").with_name("uuid"))
|
||||
.child("short name", views::EditView::new().with_name("short_name"))
|
||||
.child(
|
||||
"onvif_base_url",
|
||||
views::EditView::new().with_name("onvif_base_url"),
|
||||
)
|
||||
.child("username", views::EditView::new().with_name("username"))
|
||||
.child("password", views::EditView::new().with_name("password"))
|
||||
.min_height(6);
|
||||
let mut layout = views::LinearLayout::vertical()
|
||||
.child(camera_list)
|
||||
.child(views::TextView::new("description"))
|
||||
.child(
|
||||
views::TextArea::new()
|
||||
.with_name("description")
|
||||
.min_height(3),
|
||||
);
|
||||
|
||||
let dirs: Vec<_> = ::std::iter::once(("<none>".into(), None))
|
||||
.chain(
|
||||
db.lock()
|
||||
.sample_file_dirs_by_id()
|
||||
.iter()
|
||||
.map(|(&id, d)| (d.path.to_owned(), Some(id))),
|
||||
)
|
||||
.collect();
|
||||
for &type_ in &db::ALL_STREAM_TYPES {
|
||||
let list = views::ListView::new()
|
||||
.child(
|
||||
"rtsp url",
|
||||
views::LinearLayout::horizontal()
|
||||
.child(
|
||||
views::EditView::new()
|
||||
.on_edit(move |siv, content, _pos| {
|
||||
let test_button = siv
|
||||
.find_name::<views::Button>(&format!("{}_test", type_))
|
||||
.unwrap();
|
||||
edit_stream_url(type_, content, test_button);
|
||||
})
|
||||
.with_name(format!("{}_url", type_))
|
||||
.full_width(),
|
||||
)
|
||||
.child(views::DummyView)
|
||||
.child(
|
||||
views::Button::new("Test", move |siv| press_test(siv, type_))
|
||||
.disabled()
|
||||
.with_name(format!("{}_test", type_)),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
"sample file dir",
|
||||
views::SelectView::<Option<i32>>::new()
|
||||
.with_all(dirs.iter().map(|(p, id)| (p.display().to_string(), *id)))
|
||||
.popup()
|
||||
.with_name(format!("{}_sample_file_dir", type_)),
|
||||
)
|
||||
.child(
|
||||
"record",
|
||||
views::Checkbox::new().with_name(format!("{}_record", type_)),
|
||||
)
|
||||
.child(
|
||||
"rtsp_transport",
|
||||
views::SelectView::<&str>::new()
|
||||
.with_all([("(default)", ""), ("tcp", "tcp"), ("udp", "udp")])
|
||||
.popup()
|
||||
.with_name(format!("{}_rtsp_transport", type_)),
|
||||
)
|
||||
.child(
|
||||
"flush_if_sec",
|
||||
views::EditView::new().with_name(format!("{}_flush_if_sec", type_)),
|
||||
)
|
||||
.child(
|
||||
"usage/capacity",
|
||||
views::TextView::new("").with_name(format!("{}_usage_cap", type_)),
|
||||
)
|
||||
.min_height(5);
|
||||
layout.add_child(views::DummyView);
|
||||
layout.add_child(views::TextView::new(format!("{} stream", type_)));
|
||||
layout.add_child(list);
|
||||
}
|
||||
|
||||
let mut dialog = views::Dialog::around(layout.scrollable());
|
||||
let dialog = if let Some(camera_id) = *item {
|
||||
let (name, bytes) = load_camera_values(db, camera_id, &mut dialog, true);
|
||||
dialog
|
||||
.title("Edit camera")
|
||||
.button("Edit", {
|
||||
@ -644,14 +664,47 @@ fn edit_camera_dialog(db: &Arc<db::Database>, siv: &mut Cursive, item: &Option<i
|
||||
|v: &mut views::TextView| v.set_content("<new>"),
|
||||
);
|
||||
}
|
||||
dialog.title("Add camera").button("Add", {
|
||||
dialog
|
||||
.title("Add camera")
|
||||
.button("Add", {
|
||||
let db = db.clone();
|
||||
move |s| press_edit(s, &db, None)
|
||||
})
|
||||
.button("Copy config", {
|
||||
let db = db.clone();
|
||||
move |s| copy_camera_dialog(s, &db)
|
||||
})
|
||||
};
|
||||
siv.add_layer(dialog.dismiss_button("Cancel"));
|
||||
}
|
||||
|
||||
fn copy_camera_dialog(siv: &mut Cursive, db: &Arc<db::Database>) {
|
||||
siv.add_layer(
|
||||
views::Dialog::around(
|
||||
views::SelectView::new()
|
||||
.with_all(
|
||||
db.lock()
|
||||
.cameras_by_id()
|
||||
.iter()
|
||||
.map(|(&id, camera)| (format!("{}: {}", id, camera.short_name), id)),
|
||||
)
|
||||
.on_submit({
|
||||
let db = db.clone();
|
||||
move |siv, &camera_id| {
|
||||
siv.pop_layer();
|
||||
let screen = siv.screen_mut();
|
||||
let dialog = screen.get_mut(views::LayerPosition::FromFront(0)).unwrap();
|
||||
let dialog = dialog.downcast_mut::<Dialog>().unwrap();
|
||||
load_camera_values(&db, camera_id, dialog, false);
|
||||
}
|
||||
})
|
||||
.full_width(),
|
||||
)
|
||||
.dismiss_button("Cancel")
|
||||
.title("Select camera to copy"),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn top_dialog(db: &Arc<db::Database>, siv: &mut Cursive) {
|
||||
siv.add_layer(
|
||||
views::Dialog::around(
|
||||
|
Loading…
x
Reference in New Issue
Block a user