//! ElyTable's one open dialog. use ely_gpui_component::{ forms::TextInput, tables::{FilterRule, SortKey}, }; use ely_lok::sheet::{Entry, Format, References, Selection, Validation}; use gpui::{AnyElement, App, Context, Entity, IntoElement, SharedString, Window}; use crate::book::Book; use crate::{analysis, data, rules}; /// Changes the open dialog's state. pub(crate) fn edit( this: &Entity, cx: &mut App, change: impl FnOnce(&mut Dialog, &mut Book, &mut Context), ) { this.update(cx, |book, cx| { if let Some(mut dialog) = book.dialog.take() { change(&mut dialog, book, cx); book.dialog = Some(dialog); } cx.notify(); }); } /// What the open dialog asks, for which workbook. pub enum Dialog { Rename { tab: u64, /// The state the sheet number was read in. at: ely_lok::Doc, index: usize, field: Entity, }, Show { tab: u64, hidden: Vec, chosen: String, }, Delete { tab: u64, /// The state the sheet number was read in. at: ely_lok::Doc, index: usize, name: String, references: References, }, Size { tab: u64, column: bool, field: Entity, }, Merge { tab: u64, }, Define { tab: u64, name: Entity, range: Entity, scope: String, }, Names { tab: u64, names: Vec, chosen: usize, range: Entity, }, Sort { tab: u64, picked: Selection, keys: Vec, header: bool, }, Filter { tab: u64, picked: Selection, rules: Vec, any: bool, }, Dedupe { tab: u64, picked: Selection, header: bool, state: crate::data::ReadState, }, Columns { tab: u64, separators: Vec, other: Entity, }, /// A column button's filter menu. Column { tab: u64, column: u32, entries: Vec, picked: Vec, }, Validation { tab: u64, rule: Box, fields: Box, }, Conditional { tab: u64, kind: &'static str, operator: &'static str, style: &'static str, preset: usize, value1: Entity, value2: Entity, }, Formats { tab: u64, formats: Vec, chosen: usize, }, Pivot { tab: u64, source: String, fields: Vec, layout: ely_lok::sheet::Layout, /// Changes the pivot table at the cursor. editing: bool, }, Chart { tab: u64, /// The selected chart; none inserts one. chart: Option>, look: Box, fields: Box, }, /// A text file before it opens. Import(Box), Export { tab: u64, format: crate::output::Format, }, Page { tab: u64, layout: Box, landscape: bool, scale: ely_lok::sheet::Scale, fields: Box, }, Protect { tab: u64, protecting: Box, }, } impl Book { /// The define dialog's sheets: its own workbook's. pub(crate) fn define_scopes(&self) -> Option> { let Some(Dialog::Define { tab, .. }) = &self.dialog else { return None; }; self.sheet_in(*tab).map(|(_, _, names)| names) } /// ElyTable's open dialog, if any. pub fn dialog_element(&mut self, cx: &mut Context) -> Option { let this = cx.entity(); let dismiss = { let this = this.clone(); move |_: &mut Window, cx: &mut App| { this.update(cx, |book, cx| { book.dialog = None; cx.notify(); }) } }; let element = match self.dialog.as_ref()? { Dialog::Rename { tab, index, field, .. } => { let names = self.sheet_in(*tab)?.2; crate::sheets::dialogs::rename(this, (*index, field, names), dismiss, cx) .into_any_element() } Dialog::Show { tab, hidden, chosen, } => crate::sheets::dialogs::show(this, (*tab, hidden, chosen), dismiss, cx) .into_any_element(), Dialog::Delete { name, references, .. } => crate::sheets::dialogs::delete(this, (name, references), dismiss, cx) .into_any_element(), Dialog::Size { column, field, .. } => { crate::cells::size_dialog(this, (*column, field), dismiss, cx).into_any_element() } Dialog::Merge { tab } => { crate::cells::merge_dialog(this, *tab, dismiss, cx).into_any_element() } Dialog::Define { name, range, scope, .. } => crate::formulas::define_dialog( this, (name, range, scope, self.define_scopes()?), dismiss, cx, ) .into_any_element(), Dialog::Names { names, chosen, range, .. } => crate::formulas::names_dialog(this, (names, *chosen, range), dismiss, cx) .into_any_element(), Dialog::Sort { picked, keys, header, .. } => data::sort_dialog(this, (picked, keys, *header), dismiss, cx).into_any_element(), Dialog::Filter { picked, rules, any, .. } => data::filter_dialog(this, (picked, rules, *any), dismiss, cx).into_any_element(), Dialog::Dedupe { picked, header, .. } => { data::dedupe_dialog(this, (picked, *header), dismiss, cx).into_any_element() } Dialog::Columns { separators, other, .. } => data::columns_dialog(this, (separators, other), dismiss, cx).into_any_element(), Dialog::Column { column, entries, picked, .. } => data::column_dialog(this, (*column, entries, picked), dismiss, cx) .into_any_element(), Dialog::Validation { rule, fields, .. } => { rules::validation_dialog(this, (rule, fields), dismiss, cx).into_any_element() } Dialog::Conditional { kind, operator, style, preset, value1, value2, .. } => { let shown = rules::Shown { kind, operator, style, preset: *preset, value1, value2, }; rules::conditional_dialog(this, shown, dismiss, cx).into_any_element() } Dialog::Formats { formats, chosen, .. } => rules::formats_dialog(this, (formats, *chosen), dismiss, cx).into_any_element(), Dialog::Pivot { source, fields, layout, editing, .. } => analysis::pivot_dialog(this, (source, fields, layout, *editing), dismiss, cx) .into_any_element(), Dialog::Chart { chart, look, fields, .. } => analysis::chart_dialog(this, (chart.as_deref(), look, fields), dismiss, cx) .into_any_element(), Dialog::Import(pending) => { crate::text::import_dialog(this, pending, dismiss, cx).into_any_element() } Dialog::Export { tab, format } => { let sheet = self.sheet_in(*tab)?.1; crate::output::export_dialog(this, (*format, &sheet), dismiss, cx) .into_any_element() } Dialog::Page { layout, landscape, scale, fields, .. } => crate::page::page_dialog(this, (layout, *landscape, *scale, fields), dismiss, cx) .into_any_element(), Dialog::Protect { protecting, .. } => { crate::protect::protect_dialog(this, protecting, dismiss, cx).into_any_element() } }; Some(element) } }