Skip to content

Commit

Permalink
modified to handle removed items
Browse files Browse the repository at this point in the history
  • Loading branch information
dovakin0007 committed Aug 2, 2024
1 parent 5311760 commit e481199
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 190 deletions.
60 changes: 26 additions & 34 deletions examples/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,45 +76,37 @@ extern "system" fn wndproc(window: HWND, message: u32, wparam: WPARAM, lparam: L
unsafe fn create_jump_list() {
let mut jump_list = JumpList::new();

// Creating a custom category
let mut custom_category = JumpListCategoryCustom::new(JumpListCategoryType::Custom, Some(String::from("Custom Category")));
let args = vec![String::from("arg1"), String::from("arg2")];
let mut link1 = JumpListItemLink::new(
Some(args.clone()),
String::from("Custom Ite 1"),
Some(String::from("C:\\Path\\To\\Executable.exe")),
Some(String::from("C:\\Path\\To\\Icon.ico")),
// Creating a custom category for VS Code
let mut custom_category = JumpListCategoryCustom::new(JumpListCategoryType::Custom, Some(String::from("VS Code Tasks")));

// Directory to open in VS Code
let directory_to_open = String::from("C:\\Users\\dovak\\OneDrive\\Documents\\lua");

// Arguments to pass to VS Code (open the directory)
let args = vec![directory_to_open.clone()];

// Creating a JumpList item for VS Code
let mut vs_code_link = JumpListItemLink::new(
Some(args),
String::from("Open in VS Code"),
Some(String::from("C:\\Users\\dovak\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe")), // Path to the VS Code executable
Some(String::from("C:\\Path\\To\\VSCodeIcon.ico")), // Optional: Path to the VS Code icon
0,
);
link1.set_working_dir(String::from("C:\\"));

// Set the working directory (can be the directory you're opening or any other)
vs_code_link.set_working_dir(directory_to_open.clone());

// Add the item to the custom category
custom_category.jump_list_category.set_visible(true);
custom_category.jump_list_category.items.push(Box::new(link1));
custom_category.jump_list_category.items.push(Box::new(vs_code_link));

// Add the custom category to the JumpList
jump_list.add_category(custom_category);

// Creating a recent category
let mut recent_category = JumpListCategoryCustom::new(JumpListCategoryType::Recent, None);
recent_category.jump_list_category.set_visible(true);
jump_list.add_category(recent_category);

// Creating a frequent category
let mut frequent_category = JumpListCategoryCustom::new(JumpListCategoryType::Frequent, None);
frequent_category.jump_list_category.set_visible(true);
jump_list.add_category(frequent_category);

// Creating a task category
let mut task_category = JumpListCategoryCustom::new(JumpListCategoryType::Task, Some(String::from("Tasks")));
let mut link2 = JumpListItemLink::new(
Some(args.clone()),
String::from("Task Item"),
Some(String::from("C:\\Path\\To\\Executable2.exe")),
None,
0,
);
link2.set_working_dir(String::from("D:\\"));
task_category.jump_list_category.set_visible(true);
task_category.jump_list_category.items.push(Box::new(link2));
jump_list.add_category(task_category);
// Optionally, add other categories like recent, frequent, or tasks
// ...

// Update the JumpList to apply changes
jump_list.update();
}

137 changes: 0 additions & 137 deletions examples/example_args.rs

This file was deleted.

86 changes: 67 additions & 19 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#![allow(warnings)]
use std::error::Error;
use windows::core::{GUID, Interface, PROPVARIANT, PWSTR};
use windows::Win32::System::Com::{CLSCTX_INPROC_SERVER, CoCreateInstance};
use windows::Win32::UI::Shell::{EnumerableObjectCollection, Common::IObjectCollection, IShellLinkW, ShellLink, ICustomDestinationList, DestinationList, KDC_RECENT, KDC_FREQUENT, IApplicationDestinations, SHAddToRecentDocs, SHARD_SHELLITEM};
use windows::Win32::UI::Shell::{EnumerableObjectCollection, Common::IObjectCollection, IShellLinkW, ShellLink, ICustomDestinationList, DestinationList, KDC_RECENT, KDC_FREQUENT, IApplicationDestinations, SHAddToRecentDocs, SHARD_SHELLITEM, IShellItem, SHCreateItemInKnownFolder, FOLDERID_Documents, KF_FLAG_DEFAULT};
use windows::Win32::UI::Shell::PropertiesSystem::{IPropertyStore, PROPERTYKEY};
use windows::Win32::Storage::EnhancedStorage::PKEY_Title;
use windows::Win32::UI::Shell::Common::IObjectArray;
Expand Down Expand Up @@ -156,10 +157,22 @@ impl JumpListCategory {
}
}

// unsafe fn check_removed_item(remove_shell_item: IObjectArray) -> bool {
// let no_error = &remove_shell_item.GetCount().is_ok();
// if *no_error {
// let item_count = &remove_shell_item.GetCount().unwrap();
// for index in item_count {
// match remove_shell_item.GetAt::<IShellItem>(*index){
// Ok(shell_item) => {
// shell_item.Compare()
// }
// }
// }
// }
// }
pub unsafe fn get_category(&mut self) -> Result<IObjectCollection, Box<dyn Error>> {
let obj_collection: *const GUID = &EnumerableObjectCollection;
let collection: IObjectCollection = CoCreateInstance(obj_collection, None, CLSCTX_INPROC_SERVER)?;

let mut items_to_remove = vec![];

for (index, item) in self.items.iter().enumerate() {
Expand Down Expand Up @@ -259,18 +272,31 @@ impl JumpList {
pub fn get_tasks(&mut self) -> &JumpListCategory {
&self.task
}

pub unsafe fn update(&mut self, shell_link: Option<IShellLinkW>) {
self.jumplist.BeginList::<IObjectArray>(&mut 10).unwrap();
let is_command_empty = self.task.items.is_empty();
if self.task.visible && !is_command_empty {
if let Ok(value) = self.task.get_category() {
if let Err(err) = self.jumplist.AddUserTasks(&value) {
eprintln!("Error adding user tasks: {:?}", err);
pub unsafe fn update(&mut self) {
let object_array = match self.jumplist.BeginList::<IObjectArray>(&mut 10) {
Ok(obj) => Some(obj),
_ => None
};
let rem_obj = match self.jumplist.GetRemovedDestinations::<IObjectArray>() {
Ok(removed_obj) => Some(removed_obj),
_ => None
};
let rem_obj_count= &rem_obj.as_ref().unwrap().GetCount().unwrap();
let object_array_count = &object_array.as_ref().unwrap().GetCount().unwrap();
let mut is_present_in_removed = false;
for i in 0..*rem_obj_count{
for j in 0..*object_array_count{
let obj = object_array.as_ref().unwrap();
let rem = object_array.as_ref().unwrap();
if obj.GetAt::<IShellLinkW>(i).unwrap() == rem.GetAt::<IShellLinkW>(j).unwrap() {
is_present_in_removed = true;
}
}
}


if is_present_in_removed==false {

let mut categories_to_remove = vec![];

for (index, category) in self.custom.iter_mut().enumerate() {
Expand All @@ -279,7 +305,20 @@ impl JumpList {
if category.jump_list_category.visible && !category.jump_list_category.items.is_empty() {
if let Some(title) = &category.title {
let title_wstr = to_w_str(title.clone());
if let Ok(value) = category.jump_list_category.get_category() {
if let Ok(mut value) = category.jump_list_category.get_category() {
let mut items_to_remove = vec![];
for (item_index, item) in category.jump_list_category.items.iter().enumerate() {
if let Err(err) = item.get_link() {
eprintln!("Error creating link for item: {:?}", err);
items_to_remove.push(item_index);
}
}

// Remove items that failed to create links
for index in items_to_remove.iter().rev() {
category.jump_list_category.items.remove(*index);
}

if let Err(err) = self.jumplist.AppendCategory(PWSTR(title_wstr.as_ptr() as *mut u16), &value) {
eprintln!("Error appending custom category: {:?}", err);
categories_to_remove.push(index);
Expand All @@ -290,7 +329,6 @@ impl JumpList {
}
JumpListCategoryType::Recent => {
if category.jump_list_category.visible && !category.jump_list_category.items.is_empty() {
///TODO Add a way to create and add KnowJumplist and update it
if let Err(err) = self.jumplist.AppendKnownCategory(KDC_RECENT) {
eprintln!("Error appending recent category: {:?}", err);
categories_to_remove.push(index);
Expand All @@ -299,20 +337,28 @@ impl JumpList {
}
JumpListCategoryType::Frequent => {
if category.jump_list_category.visible && !category.jump_list_category.items.is_empty() {
///TODO Add a way to create and add KnowJumplist and update it
if let Err(err) = self.jumplist.AppendKnownCategory(KDC_FREQUENT) {
eprintln!("Error appending frequent category: {:?}", err);
categories_to_remove.push(index);
}else{

// SHAddToRecentDocs(SHARD_SHELLITEM.0 as u32, Some(shell_link.clone().unwrap().into_raw()));
}

}
}
JumpListCategoryType::Task => {
if category.jump_list_category.visible && !category.jump_list_category.items.is_empty() {
if let Ok(value) = category.jump_list_category.get_category() {
if let Ok(mut value) = category.jump_list_category.get_category() {
let mut items_to_remove = vec![];
for (item_index, item) in category.jump_list_category.items.iter().enumerate() {
if let Err(err) = item.get_link() {
eprintln!("Error creating link for item: {:?}", err);
items_to_remove.push(item_index);
}
}

// Remove items that failed to create links
for index in items_to_remove.iter().rev() {
category.jump_list_category.items.remove(*index);
}

if let Err(err) = self.jumplist.AddUserTasks(&value) {
eprintln!("Error adding user tasks: {:?}", err);
categories_to_remove.push(index);
Expand All @@ -325,15 +371,16 @@ impl JumpList {

// Remove categories that failed to append
for index in categories_to_remove.iter().rev() {

self.custom.remove(*index);
}

if let Err(err) = self.jumplist.CommitList() {
eprintln!("Error committing jump list: {:?}", err);
}
}
}


pub unsafe fn delete_list(&self) {
if let Err(err) = self.jumplist.DeleteList(None) {
eprintln!("Error deleting jump list: {:?}", err);
Expand All @@ -345,3 +392,4 @@ impl JumpList {
}
}


0 comments on commit e481199

Please sign in to comment.