app categories

This commit is contained in:
Aleksander
2026-01-06 20:17:34 +01:00
parent 3addd6eaa0
commit 33ad05ee39
2 changed files with 129 additions and 9 deletions

View File

@@ -70,7 +70,7 @@ struct AppList {
//data: Vec<ParserData>,
entries_to_mount: VecDeque<DesktopEntry>,
list_parent: WidgetPair,
prev_first_letter: char,
prev_category_name: String,
}
// called after the user clicks any desktop entry
@@ -140,12 +140,17 @@ impl<T> TabApps<T> {
.find_entries()
.into_values()
.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 {
entries_to_mount: entries_sorted.drain(..).collect(),
list_parent: app_list_parent,
prev_first_letter: ' ',
prev_category_name: String::new(),
};
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 {
fn mount_entry<T>(
&mut self,
@@ -166,12 +280,11 @@ impl AppList {
doc_params: &ParseDocumentParams,
entry: &DesktopEntry,
) -> anyhow::Result<Rc<ComponentButton>> {
if let Some(ch) = entry.app_name.chars().next()
&& self.prev_first_letter != ch
{
self.prev_first_letter = ch;
let category_name = get_category_name(entry);
if category_name != self.prev_category_name {
self.prev_category_name = String::from(category_name);
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(
doc_params,

View File

@@ -20,6 +20,7 @@ struct DesktopEntryOwned {
exec_args: String,
app_name: String,
icon_path: Option<String>,
categories: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -28,6 +29,7 @@ pub struct DesktopEntry {
pub exec_args: Rc<str>,
pub app_name: Rc<str>,
pub icon_path: Option<Rc<str>>,
pub categories: Vec<Rc<str>>,
}
impl From<DesktopEntryOwned> for DesktopEntry {
@@ -37,6 +39,7 @@ impl From<DesktopEntryOwned> for DesktopEntry {
exec_args: value.exec_args.into(),
app_name: value.app_name.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
.get("Icon")
.and_then(|icon_name| Self::find_icon(&params, &icon_name))
.and_then(|icon_name| Self::find_icon(&params, icon_name))
.or_else(|| Self::create_icon(&file_name).ok());
let mut vec_categories = Vec::<String>::new();
if let Some(categories) = section.get("Categories") {
for cat in categories.split(";") {
if CATEGORY_TYPE_BLOCKLIST.contains(&cat) {
continue 'entries;
}
vec_categories.push(String::from(cat));
}
}
@@ -240,6 +246,7 @@ impl DesktopFinder {
exec_path: String::from(exec_path),
exec_args: exec_args.join(" "),
icon_path,
categories: vec_categories,
},
);
}