1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
// bibiman - a TUI for managing BibLaTeX databases
// Copyright (C) 2024 lukeflo
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/////
use super::app::{App, FormerArea};
use super::entries::EntryTable;
use crate::backend::search::BibiSearch;
use ratatui::widgets::ListState;
#[derive(Debug)]
pub struct TagList {
pub tag_list_items: Vec<TagListItem>,
pub tag_list_state: ListState,
}
// Structure of the list items.
#[derive(Debug)]
pub struct TagListItem {
pub keyword: String,
}
// Function to process inputed characters and convert them (to string, or more complex function)
impl TagListItem {
pub fn new(info: &str) -> Self {
Self {
keyword: info.to_string(),
}
}
}
impl FromIterator<String> for TagList {
fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> Self {
let tag_list_items = iter
.into_iter()
.map(|info| TagListItem::new(&info))
.collect();
let tag_list_state = ListState::default(); // for preselection: .with_selected(Some(0));
Self {
tag_list_items,
tag_list_state,
}
}
}
impl App {
// Tag List commands
// Movement
pub fn select_next_tag(&mut self) {
self.tag_list.tag_list_state.select_next();
}
pub fn select_previous_tag(&mut self) {
self.tag_list.tag_list_state.select_previous();
}
pub fn select_first_tag(&mut self) {
self.tag_list.tag_list_state.select_first();
}
pub fn select_last_tag(&mut self) {
self.tag_list.tag_list_state.select_last();
}
pub fn get_selected_tag(&self) -> &str {
let idx = self.tag_list.tag_list_state.selected().unwrap();
let keyword = &self.tag_list.tag_list_items[idx].keyword;
keyword
}
pub fn search_tags(&mut self) {
let orig_list = &self.main_biblio.keyword_list;
let filtered_list =
BibiSearch::search_tag_list(&self.search_struct.search_string, orig_list.clone());
self.tag_list = TagList::from_iter(filtered_list)
}
pub fn filter_tags_by_entries(&mut self) {
if !self.search_struct.filtered_entry_list.is_empty() {
self.search_struct.filtered_tag_list.clear();
let orig_list = self.search_struct.filtered_entry_list.clone();
let mut filtered_keywords: Vec<String> = Vec::new();
for e in orig_list {
if !e[4].is_empty() {
let mut key_vec: Vec<String> = e[4]
.split(',')
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.collect();
filtered_keywords.append(&mut key_vec);
}
}
filtered_keywords.sort_by(|a, b| a.to_lowercase().cmp(&b.to_lowercase()));
filtered_keywords.dedup();
self.search_struct.filtered_tag_list = filtered_keywords.clone();
self.tag_list = TagList::from_iter(filtered_keywords);
}
}
// Filter the entry list by tags when hitting enter
// If already inside a filtered tag or entry list, apply the filtering
// to the already filtered list only
pub fn filter_for_tags(&mut self) {
let orig_list = {
if self.search_struct.inner_search {
let orig_list = &self.search_struct.filtered_entry_list;
orig_list
} else {
let orig_list = &self.biblio_data.entry_list.bibentries;
orig_list
}
};
let keyword = self.get_selected_tag();
let filtered_list = BibiSearch::filter_entries_by_tag(&keyword, &orig_list);
self.search_struct.filtered_entry_list = filtered_list;
self.entry_table = EntryTable::from_iter(self.search_struct.filtered_entry_list.clone());
self.filter_tags_by_entries();
self.toggle_area();
self.former_area = Some(FormerArea::TagArea);
}
}
|