feat: finish highlevel
This commit is contained in:
@@ -51,6 +51,8 @@ pub enum ParseProgramError {
|
|||||||
pub enum ProgramError {
|
pub enum ProgramError {
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Lowlevel(#[from] lowlevel::Error),
|
Lowlevel(#[from] lowlevel::Error),
|
||||||
|
#[error("given index is invalid")]
|
||||||
|
BadIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
@@ -236,8 +238,11 @@ pub struct Program {
|
|||||||
icon: Option<Rc<ProgramIcon>>,
|
icon: Option<Rc<ProgramIcon>>,
|
||||||
behavior: Option<Rc<ProgramBehavior>>,
|
behavior: Option<Rc<ProgramBehavior>>,
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
strs: Vec<Rc<ProgramStr>>,
|
strs: Vec<Rc<ProgramStr>>,
|
||||||
|
#[allow(dead_code)]
|
||||||
icons: Vec<Rc<ProgramIcon>>,
|
icons: Vec<Rc<ProgramIcon>>,
|
||||||
|
#[allow(dead_code)]
|
||||||
behaviors: Vec<Rc<ProgramBehavior>>,
|
behaviors: Vec<Rc<ProgramBehavior>>,
|
||||||
|
|
||||||
ext_keys: Vec<ProgramProgIdExtKey>,
|
ext_keys: Vec<ProgramProgIdExtKey>,
|
||||||
@@ -463,8 +468,8 @@ impl Program {
|
|||||||
|
|
||||||
// Create ProgId subkeys one by one
|
// Create ProgId subkeys one by one
|
||||||
debug_println!("Adding ProgId subkey...");
|
debug_println!("Adding ProgId subkey...");
|
||||||
for program_progid_key in &mut self.ext_keys {
|
for program_key in &mut self.ext_keys {
|
||||||
let progid_key = &mut program_progid_key.progid_key;
|
let progid_key = &mut program_key.progid_key;
|
||||||
debug_println!(
|
debug_println!(
|
||||||
"Adding ProgId \"{0}\" subkey...",
|
"Adding ProgId \"{0}\" subkey...",
|
||||||
progid_key.inner().to_string()
|
progid_key.inner().to_string()
|
||||||
@@ -473,14 +478,14 @@ impl Program {
|
|||||||
// Create ProgId subkey
|
// Create ProgId subkey
|
||||||
progid_key.ensure(scope)?;
|
progid_key.ensure(scope)?;
|
||||||
// Write ProgId values
|
// 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_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_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.
|
// 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())?;
|
ext_key.add_into_open_with_progids(scope, progid_key.inner())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,8 +510,8 @@ impl Program {
|
|||||||
|
|
||||||
// Delete ProgId subkeys one by one.
|
// Delete ProgId subkeys one by one.
|
||||||
debug_println!("Adding ProgId subkey...");
|
debug_println!("Adding ProgId subkey...");
|
||||||
for program_progid_key in &mut self.ext_keys {
|
for program_key in &mut self.ext_keys {
|
||||||
let progid_key = &mut program_progid_key.progid_key;
|
let progid_key = &mut program_key.progid_key;
|
||||||
debug_println!(
|
debug_println!(
|
||||||
"Deleting ProgId \"{0}\" subkey...",
|
"Deleting ProgId \"{0}\" subkey...",
|
||||||
progid_key.inner().to_string()
|
progid_key.inner().to_string()
|
||||||
@@ -518,7 +523,7 @@ impl Program {
|
|||||||
// So we simply remove it from "open with" list.
|
// So we simply remove it from "open with" list.
|
||||||
|
|
||||||
// Remove this ProgId from file extension "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())?;
|
ext_key.remove_from_open_with_progids(scope, progid_key.inner())?;
|
||||||
|
|
||||||
// Delete ProgId subkey
|
// Delete ProgId subkey
|
||||||
@@ -551,8 +556,8 @@ impl Program {
|
|||||||
|
|
||||||
// Check ProgId subkey.
|
// Check ProgId subkey.
|
||||||
debug_println!("Checking ProgId subkey...");
|
debug_println!("Checking ProgId subkey...");
|
||||||
for program_progid_key in &self.ext_keys {
|
for program_key in &self.ext_keys {
|
||||||
let progid_key = &program_progid_key.progid_key;
|
let progid_key = &program_key.progid_key;
|
||||||
debug_println!(
|
debug_println!(
|
||||||
"Checking ProgId \"{0}\" subkey...",
|
"Checking ProgId \"{0}\" subkey...",
|
||||||
progid_key.inner().to_string()
|
progid_key.inner().to_string()
|
||||||
@@ -567,16 +572,115 @@ impl Program {
|
|||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn link_ext(&self, scope: Scope, index: usize) -> Result<(), ProgramError> {
|
pub fn link_ext(&mut self, scope: Scope, index: usize) -> Result<(), ProgramError> {
|
||||||
todo!()
|
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> {
|
pub fn unlink_ext(&mut self, scope: Scope, index: usize) -> Result<(), ProgramError> {
|
||||||
todo!()
|
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> {
|
pub fn ext_status(
|
||||||
todo!()
|
&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