diff options
| author | lukeflo | 2024-09-27 14:49:37 +0200 |
|---|---|---|
| committer | lukeflo | 2024-09-27 14:49:37 +0200 |
| commit | 3e86e1d11fa06dedde78621c3e0503a7492ad05e (patch) | |
| tree | 9a1317a48825251f9f6d5000b2b2196faa06d0d7 /src | |
| parent | 576e7a39312f26ff3df24cf2eb279e6fdabbe903 (diff) | |
| download | bibiman-3e86e1d11fa06dedde78621c3e0503a7492ad05e.tar.gz bibiman-3e86e1d11fa06dedde78621c3e0503a7492ad05e.zip | |
copy citekey action, info box init
Diffstat (limited to 'src')
| -rw-r--r-- | src/backend/bib.rs | 29 | ||||
| -rw-r--r-- | src/frontend/app.rs | 94 | ||||
| -rw-r--r-- | src/frontend/handler.rs | 9 | ||||
| -rw-r--r-- | src/frontend/ui.rs | 70 | ||||
| -rw-r--r-- | src/main.rs | 8 |
5 files changed, 138 insertions, 72 deletions
diff --git a/src/backend/bib.rs b/src/backend/bib.rs index c520395..cbaa00e 100644 --- a/src/backend/bib.rs +++ b/src/backend/bib.rs @@ -23,6 +23,7 @@ use biblatex::{ChunksExt, Type}; // Set necessary fields // TODO: can surely be made more efficient/simpler +#[derive(Debug)] pub struct BibiMain { pub bibfile: PathBuf, // path to bibfile pub bibfilestring: String, // content of bibfile as string @@ -105,7 +106,7 @@ impl BibiEntry { ] } - fn get_authors(citekey: &str, biblio: &Bibliography) -> String { + pub fn get_authors(citekey: &str, biblio: &Bibliography) -> String { let authors = { if biblio.get(&citekey).unwrap().author().is_ok() { let authors = biblio.get(&citekey).unwrap().author().unwrap(); @@ -141,7 +142,7 @@ impl BibiEntry { authors } - fn get_title(citekey: &str, biblio: &Bibliography) -> String { + pub fn get_title(citekey: &str, biblio: &Bibliography) -> String { let title = { if biblio.get(&citekey).unwrap().title().is_ok() { let title = biblio @@ -159,7 +160,7 @@ impl BibiEntry { title } - fn get_year(citekey: &str, biblio: &Bibliography) -> String { + pub fn get_year(citekey: &str, biblio: &Bibliography) -> String { let year = biblio.get(&citekey).unwrap(); let year = { if year.date().is_ok() { @@ -174,12 +175,12 @@ impl BibiEntry { year } - fn get_pubtype(citekey: &str, biblio: &Bibliography) -> String { + pub fn get_pubtype(citekey: &str, biblio: &Bibliography) -> String { let pubtype = biblio.get(&citekey).unwrap().entry_type.to_string(); pubtype } - fn get_keywords(citekey: &str, biblio: &Bibliography) -> String { + pub fn get_keywords(citekey: &str, biblio: &Bibliography) -> String { let keywords = biblio .get(&citekey) .unwrap() @@ -188,4 +189,22 @@ impl BibiEntry { .format_verbatim(); keywords } + + pub fn get_abstract(citekey: &str, biblio: &Bibliography) -> String { + let text = { + if biblio.get(&citekey).unwrap().abstract_().is_ok() { + let abstract_text = biblio + .get(&citekey) + .unwrap() + .abstract_() + .unwrap() + .format_verbatim(); + abstract_text + } else { + let abstract_text = format!("No abstract"); + abstract_text + } + }; + text + } } diff --git a/src/frontend/app.rs b/src/frontend/app.rs index d61d094..7a211e8 100644 --- a/src/frontend/app.rs +++ b/src/frontend/app.rs @@ -18,6 +18,7 @@ use crate::backend::bib::*; use std::error; +use arboard::Clipboard; use itertools::Itertools; use ratatui::widgets::{ListState, TableState}; @@ -37,10 +38,16 @@ pub enum CurrentArea { pub struct App { // Is the application running? pub running: bool, + // main bibliography + pub main_biblio: BibiMain, + // bibliographic data + pub biblio_data: BibiData, // list pub tag_list: TagList, // TODO: table items pub entry_table: EntryTable, + // scroll state info buffer + pub scroll_info: u16, // area pub current_area: CurrentArea, } @@ -185,39 +192,35 @@ impl EntryTableItem { } } -// impl Default for App { -// fn default(bib_main: &BibiMain, bib_data: &BibiData) -> Self { -// // TEST: read file -// let keyword_list = BibiMain::new().citekeys; -// let entry_vec = BibiData::new().entry_list.bibentries; -// Self { -// running: true, -// tag_list: TagList::from_iter(keyword_list), -// entry_table: EntryTable::from_iter(entry_vec), -// current_area: CurrentArea::EntryArea, -// } -// } -// } +impl Default for App { + fn default() -> Self { + let running = true; + let main_biblio = BibiMain::new(); + let biblio_data = BibiData::new(&main_biblio.bibliography, &main_biblio.citekeys); + let tag_list = TagList::from_iter(main_biblio.citekeys.clone()); + let entry_table = EntryTable::from_iter(biblio_data.entry_list.bibentries.clone()); + let current_area = CurrentArea::EntryArea; + Self { + running, + main_biblio, + biblio_data, + tag_list, + entry_table, + scroll_info: 0, + current_area, + } + } +} impl App { // Constructs a new instance of [`App`]. - pub fn new(bib_main: &BibiMain, bib_data: &BibiData) -> Self { - Self { - running: true, - tag_list: TagList::from_iter(bib_main.citekeys.clone()), - entry_table: EntryTable::from_iter(bib_data.entry_list.bibentries.clone()), - current_area: CurrentArea::EntryArea, - } + pub fn new() -> Self { + Self::default() } // Handles the tick event of the terminal. pub fn tick(&self) {} - // TODO: Create process to do something with selected entry - // The logic getting e.g. the citekey of the selected entry is: - // let idx = self.entry_table.entry_table_state.selected().unwrap(); - // println!("{:#?}", self.entry_table.entry_table_items[*idx].citekey); - // Set running to false to quit the application. pub fn quit(&mut self) { self.running = false; @@ -231,6 +234,18 @@ impl App { } } + pub fn scroll_info_down(&mut self) { + self.scroll_info = (self.scroll_info + 1) % 10; + } + + pub fn scroll_info_up(&mut self) { + if self.scroll_info == 0 { + {} + } else { + self.scroll_info = (self.scroll_info - 1) % 10; + } + } + pub fn select_none(&mut self) { match self.current_area { CurrentArea::EntryArea => self.entry_table.entry_table_state.select(None), @@ -270,22 +285,17 @@ impl App { // self.tag_list.tag_list_state.select_last(); } - // pub fn select_none(&mut self) { - // self.entry_table.entry_table_state.select(None); - // } - - // pub fn select_next(&mut self) { - // self.entry_table.entry_table_state.select_next(); - // } - // pub fn select_previous(&mut self) { - // self.entry_table.entry_table_state.select_previous(); - // } - - // pub fn select_first(&mut self) { - // self.entry_table.entry_table_state.select_first(); - // } + // Get the citekey of the selected entry + pub fn get_selected_citekey(&self) -> &str { + let idx = self.entry_table.entry_table_state.selected().unwrap(); + let citekey = &self.entry_table.entry_table_items[idx].citekey; + citekey + } - // pub fn select_last(&mut self) { - // self.entry_table.entry_table_state.select_last(); - // } + // Yank the passed string to system clipboard + pub fn yank_text(selection: &str) { + let mut clipboard = Clipboard::new().unwrap(); + let yanked_text = selection.to_string(); + clipboard.set_text(yanked_text).unwrap(); + } } diff --git a/src/frontend/handler.rs b/src/frontend/handler.rs index cdf47e2..a9b79a0 100644 --- a/src/frontend/handler.rs +++ b/src/frontend/handler.rs @@ -34,6 +34,12 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> { app.quit(); } } + KeyCode::PageDown => { + app.scroll_info_down(); + } + KeyCode::PageUp => { + app.scroll_info_up(); + } _ => {} } // Keycodes for specific areas @@ -77,6 +83,9 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> { KeyCode::Char('G') | KeyCode::End => { app.select_last(); } + KeyCode::Char('y') => { + App::yank_text(&app.get_selected_citekey()); + } KeyCode::Tab | KeyCode::BackTab => { app.toggle_area(); } diff --git a/src/frontend/ui.rs b/src/frontend/ui.rs index 5d17051..8d5dcd8 100644 --- a/src/frontend/ui.rs +++ b/src/frontend/ui.rs @@ -15,6 +15,7 @@ // along with this program. If not, see <https://www.gnu.org/licenses/>. ///// +use biblatex::ChunksExt; use ratatui::{ buffer::Buffer, layout::{Constraint, Layout, Rect}, @@ -23,14 +24,17 @@ use ratatui::{ Color, Modifier, Style, Stylize, }, symbols, - text::{Line, Text}, + text::{Line, Span, Text}, widgets::{ Block, Cell, HighlightSpacing, List, ListItem, Padding, Paragraph, Row, StatefulWidget, Table, TableState, Widget, Wrap, }, }; -use crate::frontend::app::{App, TagListItem}; +use crate::{ + backend::bib::BibiEntry, + frontend::app::{App, TagListItem}, +}; use super::app::EntryTableItem; @@ -171,24 +175,54 @@ impl App { ); } - pub fn render_selected_item(&self, area: Rect, buf: &mut Buffer) { + pub fn render_selected_item(&mut self, area: Rect, buf: &mut Buffer) { // We get the info depending on the item's state. - // INFO: Only a placeholder at the moment: - let info = "Infor for selected item".to_string(); // TODO: Implement logic showin informations for selected entry: - // let info = if let Some(i) = self.tag_list.state.selected() { - // "Infor for selected item".to_string() - // // match self.todo_list.items[i].status { - // // Status::Completed => format!("✓ DONE: {}", self.todo_list.items[i].info), - // // Status::Todo => format!("☐ TODO: {}", self.todo_list.items[i].info), - // // } - // } else { - // "Nothing selected...".to_string() - // }; + let style_value = Style::new().bold(); + let mut lines = vec![]; + lines.push(Line::from(vec![ + Span::styled("Authors: ", style_value), + Span::styled( + String::from(BibiEntry::get_authors( + &self.get_selected_citekey(), + &self.main_biblio.bibliography, + )), + Style::new().green(), + ), + ])); + lines.push(Line::from(vec![ + Span::styled("Title: ", style_value), + Span::styled( + String::from(BibiEntry::get_title( + &self.get_selected_citekey(), + &self.main_biblio.bibliography, + )), + Style::new().magenta(), + ), + ])); + lines.push(Line::from(vec![ + Span::styled("Year: ", style_value), + Span::styled( + String::from(BibiEntry::get_year( + &self.get_selected_citekey(), + &self.main_biblio.bibliography, + )), + Style::new().light_magenta(), + ), + ])); + lines.push(Line::from("")); + lines.push(Line::from(vec![Span::styled( + String::from(BibiEntry::get_abstract( + &self.get_selected_citekey(), + &self.main_biblio.bibliography, + )), + Style::default(), + )])); + let info = Text::from(lines); // We show the list item's info under the list in this paragraph let block = Block::bordered() - .title(Line::raw(" Item Info ").centered()) + .title(Line::raw(" Entry Information ").centered()) // .borders(Borders::TOP) .border_set(symbols::border::ROUNDED) .border_style(BOX_BORDER_STYLE_MAIN) @@ -198,8 +232,9 @@ impl App { // We can now render the item info Paragraph::new(info) .block(block) - .fg(TEXT_FG_COLOR) + // .fg(TEXT_FG_COLOR) .wrap(Wrap { trim: false }) + .scroll((self.scroll_info, 0)) .render(area, buf); } @@ -208,8 +243,7 @@ impl App { .title(Line::raw(" Tag List ").centered()) .border_set(symbols::border::ROUNDED) .border_style(BOX_BORDER_STYLE_MAIN) - .bg(Color::Black) - .padding(Padding::horizontal(1)); + .bg(Color::Black); // Iterate through all elements in the `items` and stylize them. let items: Vec<ListItem> = self diff --git a/src/main.rs b/src/main.rs index a07b75a..6ffff25 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,14 +50,8 @@ async fn main() -> AppResult<()> { std::process::exit(0); } - // TODO: Implement logic for CLI arguments/options which need to be handled - // before the TUI is started - - let mut bib_main = BibiMain::new(); - let mut bib_data = BibiData::new(&bib_main.bibliography, &bib_main.citekeys); - // Create an application. - let mut app = App::new(&mut bib_main, &mut bib_data); + let mut app = App::new(); // Initialize the terminal user interface. let backend = CrosstermBackend::new(io::stdout()); |
