Handle icon paths to specific image files
This commit is contained in:
parent
3dbfda2c40
commit
dc6ddc4e85
@ -74,6 +74,10 @@ impl DesktopFile {
|
||||
self.get_key_val("Icon")
|
||||
}
|
||||
|
||||
pub fn update_icon(&mut self, value: &str) {
|
||||
self.update_key_val("Icon", value);
|
||||
}
|
||||
|
||||
fn show_in_gnome(&self) -> bool {
|
||||
if self.key_exists("NotShowIn") && self.key_value_contains("NotShowIn", "GNOME") {
|
||||
return false;
|
||||
@ -118,6 +122,14 @@ impl DesktopFile {
|
||||
None
|
||||
}
|
||||
|
||||
fn update_key_val(&mut self, key: &str, value: &str) {
|
||||
if let Some(&idx) = self.main_map.get(key) {
|
||||
if idx < self.lines.len() {
|
||||
self.lines[idx] = Line::KeyValue(key.to_string(), value.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(filename: &str) -> DesktopFile {
|
||||
DesktopFile {
|
||||
filename: filename.to_string(),
|
||||
|
@ -6,6 +6,7 @@ use std::time::SystemTime;
|
||||
use libcitadel::{Realm, Realms, Result, util};
|
||||
use crate::sync::parser::DesktopFileParser;
|
||||
use std::fs::DirEntry;
|
||||
use crate::sync::desktop_file::DesktopFile;
|
||||
use crate::sync::icons::IconSync;
|
||||
|
||||
/// Synchronize dot-desktop files from active realm to a target directory in Citadel.
|
||||
@ -161,15 +162,31 @@ impl DesktopFileSync {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn sync_item_icon(&self, file: &mut DesktopFile) {
|
||||
let icon_val = match file.icon() {
|
||||
Some(icon) => icon.to_string(),
|
||||
None => return,
|
||||
};
|
||||
if let Some(ref icons) = self.icons {
|
||||
if let Err(err) = icons.sync_icon(file, &icon_val) {
|
||||
warn!("Failed to sync desktop file icon '{}': {}", icon_val, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn sync_item(&self, item: &DesktopItem) -> Result<()> {
|
||||
let dfp = DesktopFileParser::parse_from_path(&item.path, "/usr/libexec/citadel-run ")?;
|
||||
let mut dfp = DesktopFileParser::parse_from_path(&item.path, "/usr/libexec/citadel-run ")?;
|
||||
if dfp.is_showable() {
|
||||
self.sync_item_icon(&mut dfp);
|
||||
dfp.write_to_dir(Self::CITADEL_APPLICATIONS, Some(&self.realm))?;
|
||||
/*
|
||||
if let Some(icon_name)= dfp.icon() {
|
||||
if let Some(ref icons) = self.icons {
|
||||
icons.sync_icon(icon_name)?;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
} else {
|
||||
debug!("Ignoring desktop file {} as not showable", dfp.filename());
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ impl IconCache {
|
||||
|
||||
let hash = Self::icon_name_hash(icon_name) % nbuckets;
|
||||
let mut chain_offset = self.read_offset(hash_offset + 4 + (4 * hash as usize))?;
|
||||
while chain_offset != u32::max_value() as usize {
|
||||
while chain_offset != u32::MAX as usize {
|
||||
let name_offset = self.read_offset(chain_offset + 4)?;
|
||||
chain_offset = self.read_offset(chain_offset)?;
|
||||
let name = self.read_string(name_offset)?;
|
||||
|
@ -4,6 +4,7 @@ use std::path::{Path, PathBuf};
|
||||
|
||||
use libcitadel::{Result, util, Realm};
|
||||
use std::cell::{RefCell, Cell};
|
||||
use crate::sync::desktop_file::DesktopFile;
|
||||
|
||||
pub struct IconSync {
|
||||
realm_base: PathBuf,
|
||||
@ -26,7 +27,40 @@ impl IconSync {
|
||||
Ok(IconSync { realm_base, cache, known, known_changed })
|
||||
}
|
||||
|
||||
pub fn sync_icon(&self, icon_name: &str) -> Result<()> {
|
||||
fn sync_icon_filepath(&self, file: &mut DesktopFile, path: &Path) -> Result<()> {
|
||||
let icon_path = path.canonicalize()
|
||||
.map_err(context!("Failed to canonicalize icon path {}", path.display()))?;
|
||||
|
||||
let icon_path = icon_path.strip_prefix("/")
|
||||
.map_err(context!("Failed to strip initial / from {}", icon_path.display()))?;
|
||||
|
||||
let realm_path = self.realm_base.join(icon_path);
|
||||
|
||||
if !realm_path.is_file() {
|
||||
bail!("Failed to find icon file {}", realm_path.display());
|
||||
}
|
||||
|
||||
let dir = Path::new(Self::CITADEL_ICONS).join("filepaths-icons");
|
||||
let target = dir.join(realm_path.file_name()
|
||||
.expect("Icon has no filename?"));
|
||||
|
||||
util::create_dir(&dir)?;
|
||||
util::copy_file(&realm_path, &target)?;
|
||||
util::chmod(&target, 0o644)?;
|
||||
|
||||
let target_str = target.display().to_string();
|
||||
file.update_icon(&target_str);
|
||||
|
||||
info!("Copied icon from {} to {}", icon_path.display(), target_str);
|
||||
|
||||
Ok(())
|
||||
|
||||
}
|
||||
pub fn sync_icon(&self, file: &mut DesktopFile, icon_name: &str) -> Result<()> {
|
||||
if icon_name.starts_with("/") {
|
||||
return self.sync_icon_filepath(file, Path::new(icon_name));
|
||||
}
|
||||
|
||||
if self.is_known(icon_name) {
|
||||
return Ok(())
|
||||
}
|
||||
@ -116,7 +150,8 @@ impl IconSync {
|
||||
let target = Path::new(Self::CITADEL_ICONS).join("hicolor").join(stripped);
|
||||
let parent = target.parent().unwrap();
|
||||
util::create_dir(parent)?;
|
||||
util::copy_file(icon_path, target)?;
|
||||
util::copy_file(icon_path, &target)?;
|
||||
util::chmod(&target, 0o644)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user