app categories
This commit is contained in:
@@ -70,7 +70,7 @@ struct AppList {
|
|||||||
//data: Vec<ParserData>,
|
//data: Vec<ParserData>,
|
||||||
entries_to_mount: VecDeque<DesktopEntry>,
|
entries_to_mount: VecDeque<DesktopEntry>,
|
||||||
list_parent: WidgetPair,
|
list_parent: WidgetPair,
|
||||||
prev_first_letter: char,
|
prev_category_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
// called after the user clicks any desktop entry
|
// called after the user clicks any desktop entry
|
||||||
@@ -140,12 +140,17 @@ impl<T> TabApps<T> {
|
|||||||
.find_entries()
|
.find_entries()
|
||||||
.into_values()
|
.into_values()
|
||||||
.collect();
|
.collect();
|
||||||
entries_sorted.sort_by(|a, b| a.app_name.cmp(&b.app_name));
|
|
||||||
|
entries_sorted.sort_by(|a, b| {
|
||||||
|
let cat_name_a = get_category_name(a);
|
||||||
|
let cat_name_b = get_category_name(b);
|
||||||
|
cat_name_a.cmp(cat_name_b)
|
||||||
|
});
|
||||||
|
|
||||||
let app_list = AppList {
|
let app_list = AppList {
|
||||||
entries_to_mount: entries_sorted.drain(..).collect(),
|
entries_to_mount: entries_sorted.drain(..).collect(),
|
||||||
list_parent: app_list_parent,
|
list_parent: app_list_parent,
|
||||||
prev_first_letter: ' ',
|
prev_category_name: String::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -158,6 +163,115 @@ impl<T> TabApps<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Scores {
|
||||||
|
Empty,
|
||||||
|
Unknown,
|
||||||
|
XFooBar, // X-something
|
||||||
|
Xfce,
|
||||||
|
Gnome,
|
||||||
|
Kde,
|
||||||
|
Gtk,
|
||||||
|
Qt,
|
||||||
|
Settings,
|
||||||
|
Application,
|
||||||
|
System,
|
||||||
|
Utility,
|
||||||
|
FileTools,
|
||||||
|
Filesystem,
|
||||||
|
FileManager,
|
||||||
|
Graphics,
|
||||||
|
Office,
|
||||||
|
Game,
|
||||||
|
VR, // best score (of course!)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_category_name_score(name: &str) -> u8 {
|
||||||
|
if name.starts_with("X-") {
|
||||||
|
return Scores::XFooBar as u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
match name {
|
||||||
|
"" => {
|
||||||
|
return Scores::Empty as u8;
|
||||||
|
}
|
||||||
|
"VR" => {
|
||||||
|
return Scores::VR as u8;
|
||||||
|
}
|
||||||
|
"Game" => {
|
||||||
|
return Scores::Game as u8;
|
||||||
|
}
|
||||||
|
"FileManager" => {
|
||||||
|
return Scores::FileManager as u8;
|
||||||
|
}
|
||||||
|
"Utility" => {
|
||||||
|
return Scores::Utility as u8;
|
||||||
|
}
|
||||||
|
"FileTools" => {
|
||||||
|
return Scores::FileTools as u8;
|
||||||
|
}
|
||||||
|
"Filesystem" => {
|
||||||
|
return Scores::Filesystem as u8;
|
||||||
|
}
|
||||||
|
"System" => {
|
||||||
|
return Scores::System as u8;
|
||||||
|
}
|
||||||
|
"Office" => {
|
||||||
|
return Scores::Office as u8;
|
||||||
|
}
|
||||||
|
"Settings" => {
|
||||||
|
return Scores::Settings as u8;
|
||||||
|
}
|
||||||
|
"Application" => {
|
||||||
|
return Scores::Application as u8;
|
||||||
|
}
|
||||||
|
"GTK" => {
|
||||||
|
return Scores::Gtk as u8;
|
||||||
|
}
|
||||||
|
"Qt" => {
|
||||||
|
return Scores::Qt as u8;
|
||||||
|
}
|
||||||
|
"XFCE" => {
|
||||||
|
return Scores::Xfce as u8;
|
||||||
|
}
|
||||||
|
"GNOME" => {
|
||||||
|
return Scores::Gnome as u8;
|
||||||
|
}
|
||||||
|
"KDE" => {
|
||||||
|
return Scores::Kde as u8;
|
||||||
|
}
|
||||||
|
"Graphics" => {
|
||||||
|
return Scores::Graphics as u8;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Scores::Unknown as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_best_category_name(categories: &[Rc<str>]) -> Option<&Rc<str>> {
|
||||||
|
let mut best_score: u8 = 0;
|
||||||
|
let mut best_category: Option<&Rc<str>> = None;
|
||||||
|
|
||||||
|
for cat in categories {
|
||||||
|
let score = get_category_name_score(cat);
|
||||||
|
if score > best_score {
|
||||||
|
best_category = Some(cat);
|
||||||
|
best_score = score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
best_category
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_category_name(entry: &DesktopEntry) -> &str {
|
||||||
|
//log::info!("{:?}", entry.categories);
|
||||||
|
|
||||||
|
match get_best_category_name(&entry.categories) {
|
||||||
|
Some(cat) => cat,
|
||||||
|
None => "Other",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AppList {
|
impl AppList {
|
||||||
fn mount_entry<T>(
|
fn mount_entry<T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -166,12 +280,11 @@ impl AppList {
|
|||||||
doc_params: &ParseDocumentParams,
|
doc_params: &ParseDocumentParams,
|
||||||
entry: &DesktopEntry,
|
entry: &DesktopEntry,
|
||||||
) -> anyhow::Result<Rc<ComponentButton>> {
|
) -> anyhow::Result<Rc<ComponentButton>> {
|
||||||
if let Some(ch) = entry.app_name.chars().next()
|
let category_name = get_category_name(entry);
|
||||||
&& self.prev_first_letter != ch
|
if category_name != self.prev_category_name {
|
||||||
{
|
self.prev_category_name = String::from(category_name);
|
||||||
self.prev_first_letter = ch;
|
|
||||||
let mut params = HashMap::<Rc<str>, Rc<str>>::new();
|
let mut params = HashMap::<Rc<str>, Rc<str>>::new();
|
||||||
params.insert("text".into(), format!("{}", ch).into());
|
params.insert("text".into(), category_name.into());
|
||||||
|
|
||||||
parser_state.parse_template(
|
parser_state.parse_template(
|
||||||
doc_params,
|
doc_params,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ struct DesktopEntryOwned {
|
|||||||
exec_args: String,
|
exec_args: String,
|
||||||
app_name: String,
|
app_name: String,
|
||||||
icon_path: Option<String>,
|
icon_path: Option<String>,
|
||||||
|
categories: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
@@ -28,6 +29,7 @@ pub struct DesktopEntry {
|
|||||||
pub exec_args: Rc<str>,
|
pub exec_args: Rc<str>,
|
||||||
pub app_name: Rc<str>,
|
pub app_name: Rc<str>,
|
||||||
pub icon_path: Option<Rc<str>>,
|
pub icon_path: Option<Rc<str>>,
|
||||||
|
pub categories: Vec<Rc<str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DesktopEntryOwned> for DesktopEntry {
|
impl From<DesktopEntryOwned> for DesktopEntry {
|
||||||
@@ -37,6 +39,7 @@ impl From<DesktopEntryOwned> for DesktopEntry {
|
|||||||
exec_args: value.exec_args.into(),
|
exec_args: value.exec_args.into(),
|
||||||
app_name: value.app_name.into(),
|
app_name: value.app_name.into(),
|
||||||
icon_path: value.icon_path.map(|x| x.into()),
|
icon_path: value.icon_path.map(|x| x.into()),
|
||||||
|
categories: value.categories.into_iter().map(|x| x.into()).collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -220,14 +223,17 @@ impl DesktopFinder {
|
|||||||
|
|
||||||
let icon_path = section
|
let icon_path = section
|
||||||
.get("Icon")
|
.get("Icon")
|
||||||
.and_then(|icon_name| Self::find_icon(¶ms, &icon_name))
|
.and_then(|icon_name| Self::find_icon(¶ms, icon_name))
|
||||||
.or_else(|| Self::create_icon(&file_name).ok());
|
.or_else(|| Self::create_icon(&file_name).ok());
|
||||||
|
|
||||||
|
let mut vec_categories = Vec::<String>::new();
|
||||||
|
|
||||||
if let Some(categories) = section.get("Categories") {
|
if let Some(categories) = section.get("Categories") {
|
||||||
for cat in categories.split(";") {
|
for cat in categories.split(";") {
|
||||||
if CATEGORY_TYPE_BLOCKLIST.contains(&cat) {
|
if CATEGORY_TYPE_BLOCKLIST.contains(&cat) {
|
||||||
continue 'entries;
|
continue 'entries;
|
||||||
}
|
}
|
||||||
|
vec_categories.push(String::from(cat));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,6 +246,7 @@ impl DesktopFinder {
|
|||||||
exec_path: String::from(exec_path),
|
exec_path: String::from(exec_path),
|
||||||
exec_args: exec_args.join(" "),
|
exec_args: exec_args.join(" "),
|
||||||
icon_path,
|
icon_path,
|
||||||
|
categories: vec_categories,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user