shell32: Call the trashing code from SHFileOperationW.
diff --git a/dlls/shell32/shell32_En.rc b/dlls/shell32/shell32_En.rc
index a068538..03b31f6 100644
--- a/dlls/shell32/shell32_En.rc
+++ b/dlls/shell32/shell32_En.rc
@@ -168,6 +168,7 @@
IDS_TRASHITEM_TEXT "Are you sure that you want to send '%1' to the Trash?"
IDS_TRASHFOLDER_TEXT "Are you sure that you want to send '%1' and all it's content to the Trash?"
IDS_TRASHMULTIPLE_TEXT "Are you sure that you want to send these %1 items to the Trash?"
+ IDS_CANTTRASH_TEXT "The item '%1' can't be sent to Trash. Do you want to delete it instead?"
IDS_OVERWRITEFILE_TEXT "OverWrite File %1?"
IDS_OVERWRITEFILE_CAPTION "Confirm File OverWrite"
diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h
index ab52096..5bc8e64 100644
--- a/dlls/shell32/shell32_main.h
+++ b/dlls/shell32/shell32_main.h
@@ -151,6 +151,7 @@
#define ASK_TRASH_FILE 7
#define ASK_TRASH_FOLDER 8
#define ASK_TRASH_MULTIPLE_ITEM 9
+#define ASK_CANT_TRASH_ITEM 10
BOOL SHELL_DeleteDirectoryW(HWND hwnd, LPCWSTR pwszDir, BOOL bShowUI);
BOOL SHELL_ConfirmDialogW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir);
diff --git a/dlls/shell32/shfldr_fs.c b/dlls/shell32/shfldr_fs.c
index 4e1c878..dca38c2 100644
--- a/dlls/shell32/shfldr_fs.c
+++ b/dlls/shell32/shfldr_fs.c
@@ -1214,7 +1214,7 @@
op.hwnd = GetActiveWindow();
op.wFunc = FO_DELETE;
op.pFrom = wszPathsList;
- op.fFlags = 0;
+ op.fFlags = FOF_ALLOWUNDO;
if (SHFileOperationW(&op))
{
WARN("SHFileOperation failed\n");
diff --git a/dlls/shell32/shfldr_unixfs.c b/dlls/shell32/shfldr_unixfs.c
index 7d458b7..e679f6b 100644
--- a/dlls/shell32/shfldr_unixfs.c
+++ b/dlls/shell32/shfldr_unixfs.c
@@ -1810,6 +1810,7 @@
op.hwnd = GetActiveWindow();
op.wFunc = FO_DELETE;
op.pFrom = wszPathsList;
+ op.fFlags = FOF_ALLOWUNDO;
if (!SHFileOperationW(&op))
{
WARN("SHFileOperationW failed\n");
diff --git a/dlls/shell32/shlfileop.c b/dlls/shell32/shlfileop.c
index d744689..dda59de 100644
--- a/dlls/shell32/shlfileop.c
+++ b/dlls/shell32/shlfileop.c
@@ -42,6 +42,7 @@
#include "undocshell.h"
#include "wine/unicode.h"
#include "wine/debug.h"
+#include "xdg.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
@@ -106,6 +107,11 @@
ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
ids->text_resource_id = IDS_TRASHMULTIPLE_TEXT;
return TRUE;
+ case ASK_CANT_TRASH_ITEM:
+ ids->icon_resource_id = IDI_SHELL_CONFIRM_DELETE;
+ ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
+ ids->text_resource_id = IDS_CANTTRASH_TEXT;
+ return TRUE;
case ASK_DELETE_SELECTED:
ids->icon_resource_id = IDI_SHELL_CONFIRM_DELETE;
ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
@@ -1104,12 +1110,17 @@
FILE_ENTRY *fileEntry;
DWORD i;
BOOL bPathExists;
+ BOOL bTrash;
if (!flFrom->dwNumFiles)
return ERROR_SUCCESS;
- if (!(lpFileOp->fFlags & FOF_NOCONFIRMATION) || (lpFileOp->fFlags & FOF_WANTNUKEWARNING))
- if (!confirm_delete_list(lpFileOp->hwnd, lpFileOp->fFlags, FALSE, flFrom))
+ /* Windows also checks only the first item */
+ bTrash = (lpFileOp->fFlags & FOF_ALLOWUNDO)
+ && TRASH_CanTrashFile(flFrom->feFiles[0].szFullPath);
+
+ if (!(lpFileOp->fFlags & FOF_NOCONFIRMATION) || (!bTrash && lpFileOp->fFlags & FOF_WANTNUKEWARNING))
+ if (!confirm_delete_list(lpFileOp->hwnd, lpFileOp->fFlags, bTrash, flFrom))
{
lpFileOp->fAnyOperationsAborted = TRUE;
return 0;
@@ -1120,10 +1131,33 @@
bPathExists = TRUE;
fileEntry = &flFrom->feFiles[i];
+ if (!IsAttribFile(fileEntry->attributes) &&
+ (lpFileOp->fFlags & FOF_FILESONLY && fileEntry->bFromWildcard))
+ continue;
+
+ if (bTrash)
+ {
+ BOOL bDelete;
+ if (TRASH_TrashFile(fileEntry->szFullPath))
+ continue;
+
+ /* Note: Windows silently deletes the file in such a situation, we show a dialog */
+ if (!(lpFileOp->fFlags & FOF_NOCONFIRMATION) || (lpFileOp->fFlags & FOF_WANTNUKEWARNING))
+ bDelete = SHELL_ConfirmDialogW(lpFileOp->hwnd, ASK_CANT_TRASH_ITEM, fileEntry->szFullPath);
+ else
+ bDelete = TRUE;
+
+ if (!bDelete)
+ {
+ lpFileOp->fAnyOperationsAborted = TRUE;
+ break;
+ }
+ }
+
/* delete the file or directory */
if (IsAttribFile(fileEntry->attributes))
bPathExists = DeleteFileW(fileEntry->szFullPath);
- else if (!(lpFileOp->fFlags & FOF_FILESONLY && fileEntry->bFromWildcard))
+ else
bPathExists = SHELL_DeleteDirectoryW(lpFileOp->hwnd, fileEntry->szFullPath, FALSE);
if (!bPathExists)
@@ -1252,7 +1286,7 @@
/* alert the user if an unsupported flag is used */
static void check_flags(FILEOP_FLAGS fFlags)
{
- WORD wUnsupportedFlags = FOF_ALLOWUNDO | FOF_NO_CONNECTED_ELEMENTS |
+ WORD wUnsupportedFlags = FOF_NO_CONNECTED_ELEMENTS |
FOF_NOCOPYSECURITYATTRIBS | FOF_NORECURSEREPARSE |
FOF_RENAMEONCOLLISION | FOF_WANTMAPPINGHANDLE;
diff --git a/dlls/shell32/shresdef.h b/dlls/shell32/shresdef.h
index 2f85532..3f0e1d7 100644
--- a/dlls/shell32/shresdef.h
+++ b/dlls/shell32/shresdef.h
@@ -89,6 +89,7 @@
#define IDS_TRASHFOLDER_TEXT 137
#define IDS_TRASHITEM_TEXT 138
#define IDS_TRASHMULTIPLE_TEXT 139
+#define IDS_CANTTRASH_TEXT 140
/* browse for folder dialog box */
#define IDD_STATUS 0x3743