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")
|
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 {
|
fn show_in_gnome(&self) -> bool {
|
||||||
if self.key_exists("NotShowIn") && self.key_value_contains("NotShowIn", "GNOME") {
|
if self.key_exists("NotShowIn") && self.key_value_contains("NotShowIn", "GNOME") {
|
||||||
return false;
|
return false;
|
||||||
@ -118,6 +122,14 @@ impl DesktopFile {
|
|||||||
None
|
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 {
|
pub fn new(filename: &str) -> DesktopFile {
|
||||||
DesktopFile {
|
DesktopFile {
|
||||||
filename: filename.to_string(),
|
filename: filename.to_string(),
|
||||||
|
@ -6,6 +6,7 @@ use std::time::SystemTime;
|
|||||||
use libcitadel::{Realm, Realms, Result, util};
|
use libcitadel::{Realm, Realms, Result, util};
|
||||||
use crate::sync::parser::DesktopFileParser;
|
use crate::sync::parser::DesktopFileParser;
|
||||||
use std::fs::DirEntry;
|
use std::fs::DirEntry;
|
||||||
|
use crate::sync::desktop_file::DesktopFile;
|
||||||
use crate::sync::icons::IconSync;
|
use crate::sync::icons::IconSync;
|
||||||
|
|
||||||
/// Synchronize dot-desktop files from active realm to a target directory in Citadel.
|
/// Synchronize dot-desktop files from active realm to a target directory in Citadel.
|
||||||
@ -161,15 +162,31 @@ impl DesktopFileSync {
|
|||||||
Ok(())
|
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<()> {
|
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() {
|
if dfp.is_showable() {
|
||||||
|
self.sync_item_icon(&mut dfp);
|
||||||
dfp.write_to_dir(Self::CITADEL_APPLICATIONS, Some(&self.realm))?;
|
dfp.write_to_dir(Self::CITADEL_APPLICATIONS, Some(&self.realm))?;
|
||||||
|
/*
|
||||||
if let Some(icon_name)= dfp.icon() {
|
if let Some(icon_name)= dfp.icon() {
|
||||||
if let Some(ref icons) = self.icons {
|
if let Some(ref icons) = self.icons {
|
||||||
icons.sync_icon(icon_name)?;
|
icons.sync_icon(icon_name)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
} else {
|
} else {
|
||||||
debug!("Ignoring desktop file {} as not showable", dfp.filename());
|
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 hash = Self::icon_name_hash(icon_name) % nbuckets;
|
||||||
let mut chain_offset = self.read_offset(hash_offset + 4 + (4 * hash as usize))?;
|
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)?;
|
let name_offset = self.read_offset(chain_offset + 4)?;
|
||||||
chain_offset = self.read_offset(chain_offset)?;
|
chain_offset = self.read_offset(chain_offset)?;
|
||||||
let name = self.read_string(name_offset)?;
|
let name = self.read_string(name_offset)?;
|
||||||
|
@ -4,6 +4,7 @@ use std::path::{Path, PathBuf};
|
|||||||
|
|
||||||
use libcitadel::{Result, util, Realm};
|
use libcitadel::{Result, util, Realm};
|
||||||
use std::cell::{RefCell, Cell};
|
use std::cell::{RefCell, Cell};
|
||||||
|
use crate::sync::desktop_file::DesktopFile;
|
||||||
|
|
||||||
pub struct IconSync {
|
pub struct IconSync {
|
||||||
realm_base: PathBuf,
|
realm_base: PathBuf,
|
||||||
@ -26,7 +27,40 @@ impl IconSync {
|
|||||||
Ok(IconSync { realm_base, cache, known, known_changed })
|
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) {
|
if self.is_known(icon_name) {
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
@ -116,7 +150,8 @@ impl IconSync {
|
|||||||
let target = Path::new(Self::CITADEL_ICONS).join("hicolor").join(stripped);
|
let target = Path::new(Self::CITADEL_ICONS).join("hicolor").join(stripped);
|
||||||
let parent = target.parent().unwrap();
|
let parent = target.parent().unwrap();
|
||||||
util::create_dir(parent)?;
|
util::create_dir(parent)?;
|
||||||
util::copy_file(icon_path, target)?;
|
util::copy_file(icon_path, &target)?;
|
||||||
|
util::chmod(&target, 0o644)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user