});
let _ = self.tx.send(cmd);
}
+
+ /// Creates a collection/notebook in the specified parent
+ pub fn add_notebook<F>(&self, parent: &collection::Model, name: String, callback: F)
+ where F: FnOnce(Result<collection::Model, DbErr>) + Send + 'static {
+ let backend = self.backend.clone();
+ let parent_path = format!("{}/{}", parent.parent, parent.name);
+
+ let cmd = Box::pin(async move {
+ let profile_id = backend.current_profile.id;
+
+ let insert_notebook = collection::ActiveModel {
+ profile_id: Set(profile_id),
+ name: Set(name.to_string()),
+ parent: Set(parent_path),
+ icon: Set("".to_string()),
+ kind: Set(CollectionType::Notebook),
+
+ ..Default::default()
+ };
+
+ let result = insert_notebook.insert(&backend.db).await;
+ callback(result);
+ });
+ let _ = self.tx.send(cmd);
+ }
}
* POSSIBILITY OF SUCH DAMAGE.
*/
-use ui_rs::{UiModel, UiActions};
+use ui_rs::{UiModel, ui_actions};
use ui_rs::ui::*;
use entity::collection::{Model as Collection};
+use crate::backend::{BackendHandle};
-#[derive(UiModel, UiActions, Default)]
+#[derive(UiModel)]
struct NewNotebookDialog {
+ backend: BackendHandle,
+
+ #[bind]
name: UiString,
+
+ #[bind]
+ message: UiString,
+
+ #[bind]
groups: UiList<Collection>
}
-pub fn new_notebook_dialog<T>(parent: &UiObject<T>) {
- let data = NewNotebookDialog::default();
+#[ui_actions]
+impl NewNotebookDialog {
+ /// Creates a new notebook in the selected parent (group)
+ fn add_notebook(&mut self, obj: &UiObject<NewNotebookDialog>) {
+ if self.name.get().len() == 0 {
+ self.message.set("Name required");
+ return;
+ }
+
+ let i = self.groups.selected_index();
+ let collections = self.groups.data();
+ let parent = usize::try_from(i).ok().and_then(|idx| collections.get(idx));
+ if let Some(parent) = parent {
+ let proxy = obj.obj_proxy();
+
+ self.backend.add_notebook(parent, self.name.get(), |result|{
+ proxy.call_mainthread(|obj, nnd|{
+ match result {
+ Ok(_collection) => {
+ // we actually don't need the new collection object, we force
+ // a global reload
+ nnd.backend.reload_collections();
+ obj.close();
+ }
+ Err(err) => {
+ let msg = format!("add_notebook failed: {}", err);
+ nnd.message.set(msg.as_str());
+ }
+ }
+ });
+ });
+ } else {
+ self.message.set("No parent selected");
+ }
+ }
+}
+
+pub fn new_notebook_dialog<T>(parent: &UiObject<T>, groups: &Vec<Collection>, backend: BackendHandle) {
+ let data = NewNotebookDialog {
+ backend: backend,
+ name: Default::default(),
+ message: Default::default(),
+ groups: Default::default(),
+ };
parent.dialogwindow_builder()
.title("Add Notebook")
.lbutton1("Add")
.rbutton4("Cancel")
.default_button(1)
- .onclick(|e|{
- e.obj.close();
+ .onclick(|e: &mut Event<NewNotebookDialog>|{
+ if e.intval == 1 {
+ // button1 pressed
+ e.data.add_notebook(e.obj)
+ } else {
+ // button2 (Cancel) pressed
+ e.obj.close();
+ }
})
.create(data, |obj, data|
{
+ // init data
+ data.groups.data().extend(groups.clone());
+
+ // create dialog UI
obj.grid(|a| {
a.margin(10);
a.columnspacing(10);
}, |obj| {
obj.grid_row(|obj| {
obj.rlabel_builder().label("Group").create();
- obj.dropdown_builder::<Collection>().value(&data.groups).create();
+ obj.dropdown_builder::<Collection>().value(&data.groups).getvalue(|e, _col, _row| ListValue::String(e.name.clone()) ).create();
});
obj.grid_row(|obj| {
obj.rlabel_builder().label("Name").create();
obj.textfield_builder().value(&data.name).create();
});
+ obj.grid_row(|obj| {
+ obj.llabel_builder().value(&data.message).colspan(2).create();
+ });
});
}).show();
}
\ No newline at end of file
#[derive(UiModel)]
pub struct MainWindow {
+ pub obj: UiObjRef<MainWindow>,
+
pub backend: BackendHandle,
+ groups: Vec<Collection>,
+
#[bind]
notebooks: UiSourceList<Collection>
}
impl MainWindow {
pub fn new(app: &App) -> MainWindow {
MainWindow {
+ obj: UiObjRef::default(),
backend: app.backend.clone(),
+ groups: Vec::new(),
notebooks: UiSourceList::default()
}
}
#[action]
pub fn new_notebook(&mut self, event: &ActionEvent) {
- new_notebook_dialog(event.obj);
+ new_notebook_dialog(event.obj, &self.groups, self.backend.clone());
}
#[action]
pub fn message(&mut self, _event: &ActionEvent) {
while let Ok(msg) = self.backend.brx.try_recv() {
match msg {
- BroadcastMessage::NotebookStructureUpdate(nodes) => fill_sourcelist_from_nodes(&mut self.notebooks, &nodes),
+ BroadcastMessage::NotebookStructureUpdate(nodes) => self.update_notebook_structure(&nodes),
+ }
+ }
+ }
+
+ fn update_notebook_structure(&mut self, nodes: &Vec<Node>) {
+ self.notebooks.clear();
+ self.groups.clear();
+
+ for elm in nodes.iter() {
+ self.groups.push(elm.collection.clone());
+
+ let mut notebook = SubList::new();
+ notebook.set_header(elm.collection.name.as_str());
+
+ let sublist_data = notebook.list().data();
+ for child in elm.children.iter() {
+ sublist_data.push(child.collection.clone());
}
+
+ self.notebooks.push(notebook);
}
+ self.notebooks.update();
}
}
let window = ctx.splitview_window("note", true, windowdata, |obj, data| {
init_window_data(data, app);
+ data.obj = obj.obj_ref();
obj.sidebar_builder().create(|obj|{
obj.sourcelist(|b|{
}
fn init_window_data(window: &mut MainWindow, data: &App) {
- fill_sourcelist_from_nodes(&mut window.notebooks, &data.notebooks);
+ window.update_notebook_structure(&data.notebooks);
}
-fn fill_sourcelist_from_nodes(list: &mut UiSourceList<Collection>, nodes: &Vec<Node>) {
- list.clear();
-
- for elm in nodes.iter() {
- let mut notebook = SubList::new();
- notebook.set_header(elm.collection.name.as_str());
-
- let sublist_data = notebook.list().data();
- for child in elm.children.iter() {
- sublist_data.push(child.collection.clone());
- }
-
- list.push(notebook);
- }
- list.update();
-}
self
}
- pub fn value(&mut self, value: &toolkit::UiString) {
+ pub fn value(&mut self, value: &toolkit::UiString) -> &mut Self{
unsafe {
ui_label_args_set_value(self.args, value.ptr);
}
+ self
}
pub fn varname(&mut self, varname: &str) -> &mut Self {
UiObjProxy::from_ptr(self.ptr)
}
- pub fn window_data<F>(&mut self, f: F)
+ pub unsafe fn window_data<F>(&self, f: F)
where F: FnOnce(&mut T) {
unsafe {
let wdata_ptr: *mut T = ui_object_get_windowdata(self.ptr).cast();
}
pub fn call_mainthread<F>(self, f: F)
- where F: FnOnce(&mut T) + Send + 'static {
+ where F: FnOnce(&UiObject<T>, &mut T) + Send + 'static {
call_mainthread(|| {
- let mut obj: UiObject<T> = UiObject::from_ptr(self.ptr);
- obj.window_data(|wdata| {
- f(wdata);
- });
+ let obj: UiObject<T> = UiObject::from_ptr(self.ptr);
+ unsafe {
+ obj.window_data(|wdata| {
+ f(&obj, wdata);
+ });
+ }
drop(self);
});
}