shell32: Implement restoring items from the recycle bin.

This commit is contained in:
Jay Yang 2011-07-08 10:47:08 -04:00 committed by Alexandre Julliard
parent 4dd99dcc55
commit 80c62ca203
3 changed files with 83 additions and 0 deletions

View File

@ -186,6 +186,52 @@ static void DoErase(RecycleBinMenu *This)
ISFHelper_DeleteItems(helper,This->cidl,(LPCITEMIDLIST*)This->apidl);
}
static void DoRestore(RecycleBinMenu *This)
{
/*TODO add prompts*/
UINT i;
for(i=0;i<This->cidl;i++)
{
WIN32_FIND_DATAW data;
TRASH_UnpackItemID(&((This->apidl[i])->mkid),&data);
if(PathFileExistsW(data.cFileName))
{
PIDLIST_ABSOLUTE dest_pidl = ILCreateFromPathW(data.cFileName);
WCHAR message[100];
WCHAR caption[50];
if(_ILIsFolder(ILFindLastID(dest_pidl)))
LoadStringW(shell32_hInstance,IDS_RECYCLEBIN_OVERWRITEFOLDER,
message,sizeof(message)/sizeof(WCHAR));
else
LoadStringW(shell32_hInstance,IDS_RECYCLEBIN_OVERWRITEFILE,
message,sizeof(message)/sizeof(WCHAR));
LoadStringW(shell32_hInstance,IDS_RECYCLEBIN_OVERWRITE_CAPTION,
caption,sizeof(caption)/sizeof(WCHAR));
if(ShellMessageBoxW(shell32_hInstance,GetActiveWindow(),message,
caption,MB_YESNO|MB_ICONEXCLAMATION,
data.cFileName)!=IDYES)
continue;
}
if(SUCCEEDED(TRASH_RestoreItem(This->apidl[i])))
{
IPersistFolder2 *persist;
LPITEMIDLIST root_pidl;
PIDLIST_ABSOLUTE dest_pidl = ILCreateFromPathW(data.cFileName);
BOOL is_folder = _ILIsFolder(ILFindLastID(dest_pidl));
IShellFolder2_QueryInterface(This->folder,&IID_IPersistFolder2,
(void**)&persist);
IPersistFolder2_GetCurFolder(persist,&root_pidl);
SHChangeNotify(is_folder ? SHCNE_RMDIR : SHCNE_DELETE,
SHCNF_IDLIST,ILCombine(root_pidl,This->apidl[i]),0);
SHChangeNotify(is_folder ? SHCNE_MKDIR : SHCNE_CREATE,
SHCNF_IDLIST,dest_pidl,0);
ILFree(dest_pidl);
ILFree(root_pidl);
}
}
}
static HRESULT WINAPI RecycleBinMenu_InvokeCommand(IContextMenu2 *iface,
LPCMINVOKECOMMANDINFO pici)
@ -199,6 +245,9 @@ static HRESULT WINAPI RecycleBinMenu_InvokeCommand(IContextMenu2 *iface,
case IDM_RECYCLEBIN_ERASE:
DoErase(This);
break;
case IDM_RECYCLEBIN_RESTORE:
DoRestore(This);
break;
default:
return E_NOTIMPL;
}

View File

@ -544,6 +544,39 @@ failed:
return err;
}
HRESULT TRASH_RestoreItem(LPCITEMIDLIST pidl){
int suffix_length = strlen(trashinfo_suffix);
LPCSHITEMID id = &(pidl->mkid);
const char *bucket_name = (const char*)(id->abID+1+sizeof(WIN32_FIND_DATAW));
const char *filename = (const char*)(id->abID+1+sizeof(WIN32_FIND_DATAW)+strlen(bucket_name)+1);
char *restore_path;
WIN32_FIND_DATAW data;
char *file_path;
TRACE("(%p)",pidl);
if(strcmp(filename+strlen(filename)-suffix_length,trashinfo_suffix))
{
ERR("pidl at %p is not a valid recycle bin entry",pidl);
return E_INVALIDARG;
}
TRASH_UnpackItemID(id,&data);
restore_path = wine_get_unix_file_name(data.cFileName);
file_path = SHAlloc(max(strlen(home_trash->files_dir),strlen(home_trash->info_dir))+strlen(filename)+1);
sprintf(file_path,"%s%s",home_trash->files_dir,filename);
file_path[strlen(home_trash->files_dir)+strlen(filename)-suffix_length] = '\0';
if(!rename(file_path,restore_path))
{
sprintf(file_path,"%s%s",home_trash->info_dir,filename);
if(unlink(file_path))
WARN("failed to delete the trashinfo file %s",filename);
}
else
WARN("could not erase %s from the trash (errno=%i)\n",filename,errno);
SHFree(file_path);
HeapFree(GetProcessHeap(), 0, restore_path);
return S_OK;
}
HRESULT TRASH_EraseItem(LPCITEMIDLIST pidl)
{
int suffix_length = strlen(trashinfo_suffix);

View File

@ -41,6 +41,7 @@ BOOL TRASH_CanTrashFile(LPCWSTR wszPath) DECLSPEC_HIDDEN;
BOOL TRASH_TrashFile(LPCWSTR wszPath) DECLSPEC_HIDDEN;
HRESULT TRASH_UnpackItemID(LPCSHITEMID id, WIN32_FIND_DATAW *data) DECLSPEC_HIDDEN;
HRESULT TRASH_EnumItems(LPITEMIDLIST **pidls, int *count) DECLSPEC_HIDDEN;
HRESULT TRASH_RestoreItem(LPCITEMIDLIST pidl) DECLSPEC_HIDDEN;
HRESULT TRASH_EraseItem(LPCITEMIDLIST pidl) DECLSPEC_HIDDEN;
HRESULT XDG_UserDirLookup(const char * const *xdg_dirs, const unsigned int num_dirs, char *** out_ptr) DECLSPEC_HIDDEN;