feat: finish highlevel
This commit is contained in:
@@ -51,6 +51,8 @@ pub enum ParseProgramError {
|
||||
pub enum ProgramError {
|
||||
#[error("{0}")]
|
||||
Lowlevel(#[from] lowlevel::Error),
|
||||
#[error("given index is invalid")]
|
||||
BadIndex,
|
||||
}
|
||||
|
||||
// endregion
|
||||
@@ -236,8 +238,11 @@ pub struct Program {
|
||||
icon: Option<Rc<ProgramIcon>>,
|
||||
behavior: Option<Rc<ProgramBehavior>>,
|
||||
|
||||
#[allow(dead_code)]
|
||||
strs: Vec<Rc<ProgramStr>>,
|
||||
#[allow(dead_code)]
|
||||
icons: Vec<Rc<ProgramIcon>>,
|
||||
#[allow(dead_code)]
|
||||
behaviors: Vec<Rc<ProgramBehavior>>,
|
||||
|
||||
ext_keys: Vec<ProgramProgIdExtKey>,
|
||||
@@ -463,8 +468,8 @@ impl Program {
|
||||
|
||||
// Create ProgId subkeys one by one
|
||||
debug_println!("Adding ProgId subkey...");
|
||||
for program_progid_key in &mut self.ext_keys {
|
||||
let progid_key = &mut program_progid_key.progid_key;
|
||||
for program_key in &mut self.ext_keys {
|
||||
let progid_key = &mut program_key.progid_key;
|
||||
debug_println!(
|
||||
"Adding ProgId \"{0}\" subkey...",
|
||||
progid_key.inner().to_string()
|
||||
@@ -473,14 +478,14 @@ impl Program {
|
||||
// Create ProgId subkey
|
||||
progid_key.ensure(scope)?;
|
||||
// Write ProgId values
|
||||
let name = Some(&program_progid_key.name.inner);
|
||||
let name = Some(&program_key.name.inner);
|
||||
progid_key.set_default(scope, name)?;
|
||||
progid_key.set_shell_verb(scope, &program_progid_key.behavior.inner)?;
|
||||
progid_key.set_shell_verb(scope, &program_key.behavior.inner)?;
|
||||
progid_key.set_friendly_type_name(scope, name)?;
|
||||
progid_key.set_default_icon(scope, Some(&program_progid_key.icon.inner))?;
|
||||
progid_key.set_default_icon(scope, Some(&program_key.icon.inner))?;
|
||||
|
||||
// Add this progid to file extension "open with" list.
|
||||
let ext_key = &mut program_progid_key.ext_key;
|
||||
let ext_key = &mut program_key.ext_key;
|
||||
ext_key.add_into_open_with_progids(scope, progid_key.inner())?;
|
||||
}
|
||||
|
||||
@@ -505,8 +510,8 @@ impl Program {
|
||||
|
||||
// Delete ProgId subkeys one by one.
|
||||
debug_println!("Adding ProgId subkey...");
|
||||
for program_progid_key in &mut self.ext_keys {
|
||||
let progid_key = &mut program_progid_key.progid_key;
|
||||
for program_key in &mut self.ext_keys {
|
||||
let progid_key = &mut program_key.progid_key;
|
||||
debug_println!(
|
||||
"Deleting ProgId \"{0}\" subkey...",
|
||||
progid_key.inner().to_string()
|
||||
@@ -518,7 +523,7 @@ impl Program {
|
||||
// So we simply remove it from "open with" list.
|
||||
|
||||
// Remove this ProgId from file extension "open with" list.
|
||||
let ext_key = &mut program_progid_key.ext_key;
|
||||
let ext_key = &mut program_key.ext_key;
|
||||
ext_key.remove_from_open_with_progids(scope, progid_key.inner())?;
|
||||
|
||||
// Delete ProgId subkey
|
||||
@@ -551,8 +556,8 @@ impl Program {
|
||||
|
||||
// Check ProgId subkey.
|
||||
debug_println!("Checking ProgId subkey...");
|
||||
for program_progid_key in &self.ext_keys {
|
||||
let progid_key = &program_progid_key.progid_key;
|
||||
for program_key in &self.ext_keys {
|
||||
let progid_key = &program_key.progid_key;
|
||||
debug_println!(
|
||||
"Checking ProgId \"{0}\" subkey...",
|
||||
progid_key.inner().to_string()
|
||||
@@ -567,16 +572,115 @@ impl Program {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub fn link_ext(&self, scope: Scope, index: usize) -> Result<(), ProgramError> {
|
||||
todo!()
|
||||
pub fn link_ext(&mut self, scope: Scope, index: usize) -> Result<(), ProgramError> {
|
||||
match self.ext_keys.get_mut(index) {
|
||||
Some(program_key) => {
|
||||
let ext_key = &mut program_key.ext_key;
|
||||
let progid_key = &program_key.progid_key;
|
||||
|
||||
// Before setting it, we must make sure this extension is existing
|
||||
ext_key.ensure(scope)?;
|
||||
ext_key.set_default(scope, Some(progid_key.inner()))?;
|
||||
Ok(())
|
||||
}
|
||||
None => Err(ProgramError::BadIndex),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unlink_ext(&self, scope: Scope, index: usize) -> Result<(), ProgramError> {
|
||||
todo!()
|
||||
pub fn unlink_ext(&mut self, scope: Scope, index: usize) -> Result<(), ProgramError> {
|
||||
match self.ext_keys.get_mut(index) {
|
||||
Some(program_key) => {
|
||||
let ext_key = &mut program_key.ext_key;
|
||||
|
||||
// Before setting it, we must make sure this extension is existing
|
||||
ext_key.ensure(scope)?;
|
||||
ext_key.set_default(scope, None)?;
|
||||
Ok(())
|
||||
}
|
||||
None => Err(ProgramError::BadIndex),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ext_status(&self, view: View, index: usize) -> Result<(), ProgramError> {
|
||||
todo!()
|
||||
pub fn ext_status(
|
||||
&self,
|
||||
view: View,
|
||||
index: usize,
|
||||
) -> Result<Option<ProgramExtStatus>, ProgramError> {
|
||||
match self.ext_keys.get(index) {
|
||||
Some(program_key) => {
|
||||
let ext_key = &program_key.ext_key;
|
||||
|
||||
// If there is no such extension key, return None about this extension.
|
||||
if !ext_key.is_exist(view)? {
|
||||
return Ok(None);
|
||||
}
|
||||
// Let we fetch its associated default ProgId.
|
||||
// If there is no such key, return None instead.
|
||||
let progid = match ext_key.get_default(view)? {
|
||||
Some(progid) => progid,
|
||||
None => return Ok(None),
|
||||
};
|
||||
// Now we build ProgId key from gotten association
|
||||
let progid_key = lowlevel::ProgIdKey::new(progid);
|
||||
// If this associated ProgId key is not presented,
|
||||
// we return None instead.
|
||||
if !progid_key.is_exist(view)? {
|
||||
return Ok(None);
|
||||
}
|
||||
// Now try fetch its diaplay name in modern way first.
|
||||
// If there is no modern way, use legacy way instead.
|
||||
// If there is still no display name, use ProgId self instead as display name.
|
||||
let name = match progid_key.get_friendly_type_name(view)? {
|
||||
Some(name) => name.extract()?,
|
||||
None => match progid_key.get_default(view)? {
|
||||
Some(name) => name.extract()?,
|
||||
None => progid_key.inner().to_string(),
|
||||
},
|
||||
};
|
||||
// Now try to fetch icon.
|
||||
let icon = progid_key
|
||||
.get_default_icon(view)?
|
||||
.map(|ico| ico.extract(concept::IconSizeKind::Small))
|
||||
.transpose()?;
|
||||
|
||||
// Okey, return it.
|
||||
Ok(Some(ProgramExtStatus::new(name, icon)))
|
||||
}
|
||||
None => Err(ProgramError::BadIndex),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region: Program Exposed Structs
|
||||
|
||||
/// Exposed struct representing the default associated program of specific file extension.
|
||||
///
|
||||
/// The data including the diaplay name and icon.
|
||||
pub struct ProgramExtStatus {
|
||||
name: String,
|
||||
icon: Option<concept::IconRc>,
|
||||
}
|
||||
|
||||
impl ProgramExtStatus {
|
||||
fn new(name: String, icon: Option<concept::IconRc>) -> Self {
|
||||
Self { name, icon }
|
||||
}
|
||||
|
||||
/// Get the display name of this program.
|
||||
///
|
||||
/// The program provided display name will be used firstly.
|
||||
/// If this program has no display name, the stringified ProgId will be used instead.
|
||||
pub fn get_name(&self) -> &str {
|
||||
self.name.as_str()
|
||||
}
|
||||
|
||||
/// Get the icon of this program.
|
||||
///
|
||||
/// Due to the icon is optional, if there is no icon, return None.
|
||||
pub fn get_icon(&self) -> Option<&concept::IconRc> {
|
||||
self.icon.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user