aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlukeflo2025-05-26 17:11:55 +0200
committerlukeflo2025-05-26 17:11:55 +0200
commit5ab55a263a5ae9cc5cbadf52f6000621e2552f85 (patch)
treefa0ed3addcafbf3a1d9479c71d4a3e5cb8a312c9 /src
parentc0dcbcd18a3fba111885fd0eaf8ef18f71cf693a (diff)
downloadbibiman-5ab55a263a5ae9cc5cbadf52f6000621e2552f85.tar.gz
bibiman-5ab55a263a5ae9cc5cbadf52f6000621e2552f85.zip
first steps in rewriting popups
Diffstat (limited to 'src')
-rw-r--r--src/app.rs73
-rw-r--r--src/bibiman.rs155
-rw-r--r--src/tui/popup.rs6
-rw-r--r--src/tui/ui.rs2
4 files changed, 186 insertions, 50 deletions
diff --git a/src/app.rs b/src/app.rs
index e0c149c..23230ba 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -300,18 +300,24 @@ impl App {
.selected()
.unwrap();
let entry = self.bibiman.entry_table.entry_table_items[idx].clone();
- let mut items = vec!["Citekey".to_owned()];
+ let mut items = vec![("Citekey: ".to_string(), entry.citekey.clone())];
if entry.doi_url.is_some() {
- items.push("Weblink".to_owned())
+ items.push(("Weblink: ".into(), entry.doi_url.unwrap().clone()))
}
if entry.filepath.is_some() {
- items.push("Filepath".to_owned())
+ items.push((
+ "Filepath: ".into(),
+ entry.filepath.unwrap()[0].clone().into_string().unwrap(),
+ ))
}
- self.bibiman.popup_area.popup_kind = Some(PopupKind::YankItem);
- self.bibiman.popup_area.popup_selection(items);
- self.bibiman.former_area = Some(FormerArea::EntryArea);
- self.bibiman.current_area = CurrentArea::PopupArea;
- self.bibiman.popup_area.popup_state.select(Some(0));
+
+ // self.bibiman.popup_area.popup_kind = Some(PopupKind::YankItem);
+ // self.bibiman.popup_area.popup_selection(items);
+ // self.bibiman.former_area = Some(FormerArea::EntryArea);
+ // self.bibiman.current_area = CurrentArea::PopupArea;
+ // self.bibiman.popup_area.popup_state.select(Some(0));
+ self.bibiman
+ .open_popup(PopupKind::YankItem, None, None, Some(items));
}
}
CmdAction::EditFile => {
@@ -328,25 +334,40 @@ impl App {
.selected()
.unwrap();
let entry = self.bibiman.entry_table.entry_table_items[idx].clone();
+ let mut items: Vec<(String, String)> = vec![];
if entry.filepath.is_some() || entry.doi_url.is_some() {
- let mut items = vec![];
if entry.doi_url.is_some() {
- items.push("Weblink (DOI/URL)".to_owned())
+ items.push((
+ "Weblink (DOI/URL): ".into(),
+ entry.doi_url.unwrap().clone(),
+ ))
}
if entry.filepath.is_some() {
- items.push("File (PDF/EPUB)".to_owned())
+ items.push((
+ "File (PDF/EPUB): ".into(),
+ entry.filepath.unwrap()[0].clone().into_string().unwrap(),
+ ))
}
- self.bibiman.popup_area.popup_kind = Some(PopupKind::OpenRes);
- self.bibiman.popup_area.popup_selection(items);
- self.bibiman.former_area = Some(FormerArea::EntryArea);
- self.bibiman.current_area = CurrentArea::PopupArea;
- self.bibiman.popup_area.popup_state.select(Some(0))
+ // self.bibiman.popup_area.popup_kind = Some(PopupKind::OpenRes);
+ // self.bibiman.popup_area.popup_selection(items);
+ // self.bibiman.former_area = Some(FormerArea::EntryArea);
+ // self.bibiman.current_area = CurrentArea::PopupArea;
+ // self.bibiman.popup_area.popup_state.select(Some(0))
+
+ self.bibiman
+ .open_popup(PopupKind::OpenRes, None, None, Some(items));
} else {
- self.bibiman.popup_area.popup_message(
- "Selected entry has no connected ressources: ",
- &entry.citekey,
- false,
- )
+ self.bibiman.open_popup(
+ PopupKind::MessageError,
+ Some("Selected entry has no connected ressources: "),
+ Some(&entry.citekey),
+ None,
+ );
+ // self.bibiman.popup_area.popup_message(
+ // "Selected entry has no connected ressources: ",
+ // &entry.citekey,
+ // false,
+ // )
}
}
}
@@ -357,7 +378,7 @@ impl App {
}
}
CmdAction::ShowHelp => {
- self.bibiman.show_help();
+ self.bibiman.open_popup(PopupKind::Help, None, None, None);
}
CmdAction::Exit => {
self.quit();
@@ -430,6 +451,14 @@ pub fn expand_home(path: &PathBuf) -> PathBuf {
}
}
+/// Convert `Vec<(&str, &str)` to `Vec<(String, String)`
+pub fn convert_to_owned_vec(mut items: Vec<(&str, &str)>) -> Vec<(String, String)> {
+ items
+ .iter_mut()
+ .map(|(msg, obj)| (msg.to_string(), obj.to_string()))
+ .collect()
+}
+
#[cfg(test)]
mod test {
use super::*;
diff --git a/src/bibiman.rs b/src/bibiman.rs
index 646a078..9606c19 100644
--- a/src/bibiman.rs
+++ b/src/bibiman.rs
@@ -118,6 +118,7 @@ impl Bibiman {
self.popup_area.popup_kind = Some(PopupKind::Help);
}
+ /// Close all current popups and select former tab of main app
pub fn close_popup(&mut self) {
// Reset all popup fields to default values
self.popup_area = PopupArea::default();
@@ -133,6 +134,80 @@ impl Bibiman {
self.former_area = None;
}
+ /// Open a popup
+ ///
+ /// Necessary arguments are:
+ ///
+ /// - `popup_kind`: a valid value of the `PopupKind` `enum`. This determines the
+ /// further behaviour of the popup.
+ /// - `message`: A message shown in the popup. This is needed for the `PopupKind`
+ /// values `MessageConfirm` and `MessageError`. If not needed, set it to `None`.
+ /// - `object`: An object passed as `&str` which might explain the current popup
+ /// action. Its not needed, but very useful. Can be used with the `PopupKind`
+ /// values `MessageConfirm`, `MessageError` and `YankItem`. If not needed, set it
+ /// to `None`.
+ /// - `items`: A vector of items which are needed if a selectable list is rendered.
+ /// The vector consists of tuples including a pair of `&str`. The second item of
+ /// the tuple is considered kind of an object which can be used e.g. to open
+ /// the given filepath etc. If not needed, set it to `None`.
+ pub fn open_popup(
+ &mut self,
+ popup_kind: PopupKind,
+ message: Option<&str>,
+ object: Option<&str>,
+ items: Option<Vec<(String, String)>>,
+ ) {
+ if let CurrentArea::EntryArea = self.current_area {
+ self.former_area = Some(FormerArea::EntryArea);
+ } else if let CurrentArea::TagArea = self.current_area {
+ self.former_area = Some(FormerArea::TagArea);
+ }
+ self.popup_area.is_popup = true;
+ self.current_area = CurrentArea::PopupArea;
+
+ match popup_kind {
+ PopupKind::Help => {
+ self.popup_area.popup_kind = Some(PopupKind::Help);
+ }
+ PopupKind::MessageConfirm => {
+ self.popup_area.popup_kind = Some(PopupKind::MessageConfirm);
+ if object.is_some() && message.is_some() {
+ self.popup_area.popup_message = message.unwrap().to_owned() + object.unwrap()
+ } else if object.is_none() && message.is_some() {
+ self.popup_area.popup_message = message.unwrap().to_owned()
+ } else {
+ return;
+ }
+ }
+ PopupKind::MessageError => {
+ self.popup_area.popup_kind = Some(PopupKind::MessageError);
+ if object.is_some() && message.is_some() {
+ self.popup_area.popup_message = message.unwrap().to_owned() + object.unwrap()
+ } else if object.is_none() && message.is_some() {
+ self.popup_area.popup_message = message.unwrap().to_owned()
+ } else {
+ return;
+ }
+ }
+ PopupKind::OpenRes => {
+ self.popup_area.popup_kind = Some(PopupKind::OpenRes);
+ self.popup_area.popup_selection(items.unwrap());
+ self.popup_area.popup_state.select(Some(0));
+ }
+ PopupKind::AppendToFile => {
+ self.popup_area.popup_kind = Some(PopupKind::AppendToFile);
+ }
+ PopupKind::AddEntry => {
+ self.popup_area.popup_kind = Some(PopupKind::AddEntry);
+ }
+ PopupKind::YankItem => {
+ self.popup_area.popup_kind = Some(PopupKind::YankItem);
+ self.popup_area.popup_selection(items.unwrap());
+ self.popup_area.popup_state.select(Some(0));
+ }
+ }
+ }
+
pub fn update_lists(&mut self, cfg: &BibiConfig) {
self.main_biblio = BibiSetup::new(&self.main_bibfiles, cfg);
self.tag_list = TagList::new(self.main_biblio.keyword_list.clone());
@@ -442,26 +517,33 @@ impl Bibiman {
self.current_area = CurrentArea::PopupArea;
self.popup_area.popup_state.select(Some(0))
} else {
- self.popup_area
- .popup_message("Can't find DOI: ", &doi_string, false);
+ self.open_popup(
+ PopupKind::MessageError,
+ Some("Can't find DOI: "),
+ Some(&doi_string),
+ None,
+ );
+ // self.popup_area
+ // .popup_message("Can't find DOI: ", &doi_string, false);
}
}
pub fn append_to_file(&mut self) {
- let mut items = vec!["Create new file".to_owned()];
+ let mut items = vec![("Create new file".to_owned(), "".to_string())];
if self.main_bibfiles.len() > 1 {
for f in self.main_bibfiles.clone() {
- items.push(f.to_str().unwrap().to_owned());
+ items.push(("File: ".into(), f.to_str().unwrap().to_owned()));
}
} else {
- items.push(
+ items.push((
+ "File: ".into(),
self.main_bibfiles
.first()
.unwrap()
.to_str()
.unwrap()
.to_owned(),
- );
+ ));
}
self.popup_area.popup_selection(items);
}
@@ -482,7 +564,10 @@ impl Bibiman {
.to_string();
// Check if new file or existing file was choosen
- let mut file = if self.popup_area.popup_list[popup_idx].contains("Create new file") {
+ let mut file = if self.popup_area.popup_list[popup_idx]
+ .0
+ .contains("Create new file")
+ {
let citekey = PathBuf::from(&citekey);
// Get path of current files
let path: PathBuf = if self.main_bibfiles[0].is_file() {
@@ -552,11 +637,11 @@ impl Bibiman {
let popup_idx = self.popup_area.popup_state.selected().unwrap();
// Choose ressource depending an selected popup field
- if self.popup_area.popup_list[popup_idx].contains("Weblink") {
+ if self.popup_area.popup_list[popup_idx].0.contains("Weblink") {
let object = self.entry_table.entry_table_items[entry_idx].doi_url();
let url = app::prepare_weblink(object);
app::open_connected_link(cfg, &url)?;
- } else if self.popup_area.popup_list[popup_idx].contains("File") {
+ } else if self.popup_area.popup_list[popup_idx].0.contains("File") {
// TODO: Selection for multiple files
let object = self.entry_table.entry_table_items[entry_idx].filepath()[0];
app::open_connected_file(cfg, object)?;
@@ -570,6 +655,7 @@ impl Bibiman {
}
pub fn yank_entry_field(&mut self) -> Result<()> {
+ // self.close_popup();
// Index of selected entry
let entry_idx = self.entry_table.entry_table_state.selected().unwrap();
@@ -577,30 +663,45 @@ impl Bibiman {
let popup_idx = self.popup_area.popup_state.selected().unwrap();
match self.popup_area.popup_list[popup_idx]
+ .0
.to_lowercase()
.as_str()
+ .split_whitespace()
+ .next()
{
- "citekey" => {
+ Some("citekey:") => {
let citekey = &self.entry_table.entry_table_items[entry_idx].citekey;
Bibiman::yank_text(citekey);
- self.popup_area.popup_message(
- "Yanked citekey to clipboard: ",
- citekey, // self.bibiman.get_selected_citekey(),
- true,
+ self.open_popup(
+ PopupKind::MessageConfirm,
+ Some("Yanked citekey to clipboard: "),
+ Some(citekey.clone().as_str()),
+ None,
);
+ // self.popup_area.popup_message(
+ // "Yanked citekey to clipboard: ",
+ // citekey, // self.bibiman.get_selected_citekey(),
+ // true,
+ // );
}
- "weblink" => {
+ Some("weblink:") => {
let link = &self.entry_table.entry_table_items[entry_idx].doi_url;
if let Some(l) = link {
Bibiman::yank_text(l);
- self.popup_area.popup_message(
- "Yanked weblink to clipboard: ",
- l, // self.bibiman.get_selected_link(),
- true,
+ self.open_popup(
+ PopupKind::MessageConfirm,
+ Some("Yanked weblink to clipboard: "),
+ Some(l.clone().as_str()),
+ None,
);
+ // self.popup_area.popup_message(
+ // "Yanked weblink to clipboard: ",
+ // l, // self.bibiman.get_selected_link(),
+ // true,
+ // );
}
}
- "filepath" => {
+ Some("filepath:") => {
let path = self.entry_table.entry_table_items[entry_idx]
.filepath
.clone();
@@ -608,11 +709,17 @@ impl Bibiman {
let p = p[0].as_os_str().to_str();
if let Some(p) = p {
Bibiman::yank_text(p);
- self.popup_area.popup_message(
- "Yanked filepath to clipboard: ",
- p, // self.bibiman.get_selected_link(),
- true,
+ self.open_popup(
+ PopupKind::MessageConfirm,
+ Some("Yanked filepath to clipboard: "),
+ Some(p),
+ None,
);
+ // self.popup_area.popup_message(
+ // "Yanked filepath to clipboard: ",
+ // p, // self.bibiman.get_selected_link(),
+ // true,
+ // );
}
}
}
diff --git a/src/tui/popup.rs b/src/tui/popup.rs
index a0a61a4..f3f6d58 100644
--- a/src/tui/popup.rs
+++ b/src/tui/popup.rs
@@ -46,7 +46,7 @@ pub struct PopupArea {
pub popup_kind: Option<PopupKind>,
pub popup_message: String,
pub popup_scroll_pos: u16,
- pub popup_list: Vec<String>,
+ pub popup_list: Vec<(String, String)>,
pub popup_state: ListState,
pub popup_sel_item: String,
// pub add_entry_input: String,
@@ -138,8 +138,8 @@ impl PopupArea {
/// Opens a popup with a selectable list
///
- /// The list items are passed as argument of the kind `Vec<String>`.
- pub fn popup_selection(&mut self, items: Vec<String>) {
+ /// The list items are passed as argument of the kind `Vec<(String, String)>`.
+ pub fn popup_selection(&mut self, items: Vec<(String, String)>) {
self.popup_list = items;
// self.popup_kind = Some(PopupKind::SelectRes);
self.is_popup = true;
diff --git a/src/tui/ui.rs b/src/tui/ui.rs
index 883e4df..9cbd075 100644
--- a/src/tui/ui.rs
+++ b/src/tui/ui.rs
@@ -279,7 +279,7 @@ pub fn render_popup(app: &mut App, cfg: &BibiConfig, frame: &mut Frame) {
.popup_area
.popup_list
.iter()
- .map(|item| ListItem::from(item.to_owned()))
+ .map(|(mes, obj)| ListItem::from(mes.to_owned() + obj))
.collect();
let title = if let Some(PopupKind::OpenRes) = app.bibiman.popup_area.popup_kind {