pull/174286/head^2
parent
e3bea63a7a
commit
85925efe02
|
@ -14,7 +14,7 @@ import { COPY_PATH_COMMAND_ID, REVEAL_IN_EXPLORER_COMMAND_ID, OPEN_TO_SIDE_COMMA
|
|||
import { CommandsRegistry, ICommandHandler } from '../../../../platform/commands/common/commands.js';
|
||||
import { ContextKeyExpr, ContextKeyExpression } from '../../../../platform/contextkey/common/contextkey.js';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';
|
||||
import { FilesExplorerFocusCondition, ExplorerRootContext, ExplorerFolderContext, ExplorerResourceNotReadonlyContext, ExplorerResourceCut, ExplorerResourceMoveableToTrash, ExplorerResourceAvailableEditorIdsContext, FoldersViewVisibleContext } from '../common/files.js';
|
||||
import { FilesExplorerFocusCondition, ExplorerRootContext, ExplorerFolderContext, ExplorerResourceWritableContext, ExplorerResourceCut, ExplorerResourceMoveableToTrash, ExplorerResourceAvailableEditorIdsContext, FoldersViewVisibleContext } from '../common/files.js';
|
||||
import { ADD_ROOT_FOLDER_COMMAND_ID, ADD_ROOT_FOLDER_LABEL } from '../../../browser/actions/workspaceCommands.js';
|
||||
import { CLOSE_SAVED_EDITORS_COMMAND_ID, CLOSE_EDITORS_IN_GROUP_COMMAND_ID, CLOSE_EDITOR_COMMAND_ID, CLOSE_OTHER_EDITORS_IN_GROUP_COMMAND_ID, REOPEN_WITH_COMMAND_ID } from '../../../browser/parts/editor/editorCommands.js';
|
||||
import { AutoSaveAfterShortDelayContext } from '../../../services/filesConfiguration/common/filesConfigurationService.js';
|
||||
|
@ -52,7 +52,7 @@ const RENAME_ID = 'renameFile';
|
|||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: RENAME_ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus,
|
||||
when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerRootContext.toNegated(), ExplorerResourceNotReadonlyContext),
|
||||
when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerRootContext.toNegated(), ExplorerResourceWritableContext),
|
||||
primary: KeyCode.F2,
|
||||
mac: {
|
||||
primary: KeyCode.Enter
|
||||
|
@ -64,7 +64,7 @@ const MOVE_FILE_TO_TRASH_ID = 'moveFileToTrash';
|
|||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: MOVE_FILE_TO_TRASH_ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus,
|
||||
when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerResourceNotReadonlyContext, ExplorerResourceMoveableToTrash),
|
||||
when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerResourceMoveableToTrash),
|
||||
primary: KeyCode.Delete,
|
||||
mac: {
|
||||
primary: KeyMod.CtrlCmd | KeyCode.Backspace,
|
||||
|
@ -77,7 +77,7 @@ const DELETE_FILE_ID = 'deleteFile';
|
|||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: DELETE_FILE_ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus,
|
||||
when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerResourceNotReadonlyContext),
|
||||
when: FilesExplorerFocusCondition,
|
||||
primary: KeyMod.Shift | KeyCode.Delete,
|
||||
mac: {
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Backspace
|
||||
|
@ -88,7 +88,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: DELETE_FILE_ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus,
|
||||
when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerResourceNotReadonlyContext, ExplorerResourceMoveableToTrash.toNegated()),
|
||||
when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerResourceMoveableToTrash.toNegated()),
|
||||
primary: KeyCode.Delete,
|
||||
mac: {
|
||||
primary: KeyMod.CtrlCmd | KeyCode.Backspace
|
||||
|
@ -100,7 +100,7 @@ const CUT_FILE_ID = 'filesExplorer.cut';
|
|||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: CUT_FILE_ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus,
|
||||
when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerRootContext.toNegated(), ExplorerResourceNotReadonlyContext),
|
||||
when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerRootContext.toNegated(), ExplorerResourceWritableContext),
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KeyX,
|
||||
handler: cutFileHandler,
|
||||
});
|
||||
|
@ -121,7 +121,7 @@ CommandsRegistry.registerCommand(PASTE_FILE_ID, pasteFileHandler);
|
|||
KeybindingsRegistry.registerKeybindingRule({
|
||||
id: `^${PASTE_FILE_ID}`, // the `^` enables pasting files into the explorer by preventing default bubble up
|
||||
weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus,
|
||||
when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerResourceNotReadonlyContext),
|
||||
when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerResourceWritableContext),
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KeyV,
|
||||
});
|
||||
|
||||
|
@ -479,7 +479,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
|
|||
command: {
|
||||
id: NEW_FILE_COMMAND_ID,
|
||||
title: NEW_FILE_LABEL,
|
||||
precondition: ExplorerResourceNotReadonlyContext
|
||||
precondition: ExplorerResourceWritableContext
|
||||
},
|
||||
when: ExplorerFolderContext
|
||||
});
|
||||
|
@ -490,7 +490,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
|
|||
command: {
|
||||
id: NEW_FOLDER_COMMAND_ID,
|
||||
title: NEW_FOLDER_LABEL,
|
||||
precondition: ExplorerResourceNotReadonlyContext
|
||||
precondition: ExplorerResourceWritableContext
|
||||
},
|
||||
when: ExplorerFolderContext
|
||||
});
|
||||
|
@ -540,7 +540,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
|
|||
id: CUT_FILE_ID,
|
||||
title: nls.localize('cut', "Cut"),
|
||||
},
|
||||
when: ContextKeyExpr.and(ExplorerRootContext.toNegated(), ExplorerResourceNotReadonlyContext)
|
||||
when: ContextKeyExpr.and(ExplorerRootContext.toNegated(), ExplorerResourceWritableContext)
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
|
||||
|
@ -559,7 +559,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
|
|||
command: {
|
||||
id: PASTE_FILE_ID,
|
||||
title: PASTE_FILE_LABEL,
|
||||
precondition: ContextKeyExpr.and(ExplorerResourceNotReadonlyContext, FileCopiedContext)
|
||||
precondition: ContextKeyExpr.and(ExplorerResourceWritableContext, FileCopiedContext)
|
||||
},
|
||||
when: ExplorerFolderContext
|
||||
});
|
||||
|
@ -593,8 +593,8 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, ({
|
|||
IsWebContext,
|
||||
// only on folders
|
||||
ExplorerFolderContext,
|
||||
// only on editable folders
|
||||
ExplorerResourceNotReadonlyContext
|
||||
// only on writable folders
|
||||
ExplorerResourceWritableContext
|
||||
)
|
||||
}));
|
||||
|
||||
|
@ -638,7 +638,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
|
|||
command: {
|
||||
id: RENAME_ID,
|
||||
title: TRIGGER_RENAME_LABEL,
|
||||
precondition: ExplorerResourceNotReadonlyContext,
|
||||
precondition: ExplorerResourceWritableContext,
|
||||
},
|
||||
when: ExplorerRootContext.toNegated()
|
||||
});
|
||||
|
@ -648,13 +648,11 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
|
|||
order: 20,
|
||||
command: {
|
||||
id: MOVE_FILE_TO_TRASH_ID,
|
||||
title: MOVE_FILE_TO_TRASH_LABEL,
|
||||
precondition: ContextKeyExpr.and(ExplorerResourceNotReadonlyContext),
|
||||
title: MOVE_FILE_TO_TRASH_LABEL
|
||||
},
|
||||
alt: {
|
||||
id: DELETE_FILE_ID,
|
||||
title: nls.localize('deleteFile', "Delete Permanently"),
|
||||
precondition: ContextKeyExpr.and(ExplorerResourceNotReadonlyContext),
|
||||
title: nls.localize('deleteFile', "Delete Permanently")
|
||||
},
|
||||
when: ContextKeyExpr.and(ExplorerRootContext.toNegated(), ExplorerResourceMoveableToTrash)
|
||||
});
|
||||
|
@ -664,8 +662,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
|
|||
order: 20,
|
||||
command: {
|
||||
id: DELETE_FILE_ID,
|
||||
title: nls.localize('deleteFile', "Delete Permanently"),
|
||||
precondition: ExplorerResourceNotReadonlyContext,
|
||||
title: nls.localize('deleteFile', "Delete Permanently")
|
||||
},
|
||||
when: ContextKeyExpr.and(ExplorerRootContext.toNegated(), ExplorerResourceMoveableToTrash.toNegated())
|
||||
});
|
||||
|
|
|
@ -93,7 +93,7 @@ async function refreshIfSeparator(value: string, explorerService: IExplorerServi
|
|||
}
|
||||
}
|
||||
|
||||
async function deleteFiles(explorerService: IExplorerService, workingCopyFileService: IWorkingCopyFileService, dialogService: IDialogService, configurationService: IConfigurationService, elements: ExplorerItem[], useTrash: boolean, skipConfirm = false, ignoreIfNotExists = false): Promise<void> {
|
||||
async function deleteFiles(explorerService: IExplorerService, workingCopyFileService: IWorkingCopyFileService, dialogService: IDialogService, configurationService: IConfigurationService, filesConfigurationService: IFilesConfigurationService, elements: ExplorerItem[], useTrash: boolean, skipConfirm = false, ignoreIfNotExists = false): Promise<void> {
|
||||
let primaryButton: string;
|
||||
if (useTrash) {
|
||||
primaryButton = isWindows ? nls.localize('deleteButtonLabelRecycleBin', "&&Move to Recycle Bin") : nls.localize({ key: 'deleteButtonLabelTrash', comment: ['&& denotes a mnemonic'] }, "&&Move to Trash");
|
||||
|
@ -109,7 +109,7 @@ async function deleteFiles(explorerService: IExplorerService, workingCopyFileSer
|
|||
dirtyWorkingCopies.add(dirtyWorkingCopy);
|
||||
}
|
||||
}
|
||||
let confirmed = true;
|
||||
|
||||
if (dirtyWorkingCopies.size) {
|
||||
let message: string;
|
||||
if (distinctElements.length > 1) {
|
||||
|
@ -132,18 +132,40 @@ async function deleteFiles(explorerService: IExplorerService, workingCopyFileSer
|
|||
});
|
||||
|
||||
if (!response.confirmed) {
|
||||
confirmed = false;
|
||||
return;
|
||||
} else {
|
||||
skipConfirm = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if file is dirty in editor and save it to avoid data loss
|
||||
if (!confirmed) {
|
||||
return;
|
||||
// Handle readonly
|
||||
if (!skipConfirm) {
|
||||
const readonlyResources = distinctElements.filter(e => filesConfigurationService.isReadonly(e.resource));
|
||||
if (readonlyResources.length) {
|
||||
let message: string;
|
||||
if (readonlyResources.length > 1) {
|
||||
message = nls.localize('readonlyMessageFilesDelete', "You are deleting files that are configured to be read-only. Do you want to continue?");
|
||||
} else if (readonlyResources[0].isDirectory) {
|
||||
message = nls.localize('readonlyMessageFolderOneDelete', "You are deleting a folder {0} that is configured to be read-only. Do you want to continue?", distinctElements[0].name);
|
||||
} else {
|
||||
message = nls.localize('readonlyMessageFolderDelete', "You are deleting a file {0} that is configured to be read-only. Do you want to continue?", distinctElements[0].name);
|
||||
}
|
||||
|
||||
const response = await dialogService.confirm({
|
||||
type: 'warning',
|
||||
message,
|
||||
detail: nls.localize('continueDetail', "The read-only protection will be overridden if you continue."),
|
||||
primaryButton: nls.localize('continueButtonLabel', "Continue")
|
||||
});
|
||||
|
||||
if (!response.confirmed) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let confirmation: IConfirmationResult;
|
||||
|
||||
// We do not support undo of folders, so in that case the delete action is irreversible
|
||||
const deleteDetail = distinctElements.some(e => e.isDirectory) ? nls.localize('irreversible', "This action is irreversible!") :
|
||||
distinctElements.length > 1 ? nls.localize('restorePlural', "You can restore these files using the Undo command.") : nls.localize('restore', "You can restore this file using the Undo command.");
|
||||
|
@ -234,7 +256,7 @@ async function deleteFiles(explorerService: IExplorerService, workingCopyFileSer
|
|||
skipConfirm = true;
|
||||
ignoreIfNotExists = true;
|
||||
|
||||
return deleteFiles(explorerService, workingCopyFileService, dialogService, configurationService, elements, useTrash, skipConfirm, ignoreIfNotExists);
|
||||
return deleteFiles(explorerService, workingCopyFileService, dialogService, configurationService, filesConfigurationService, elements, useTrash, skipConfirm, ignoreIfNotExists);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1020,7 +1042,7 @@ export const moveFileToTrashHandler = async (accessor: ServicesAccessor) => {
|
|||
const explorerService = accessor.get(IExplorerService);
|
||||
const stats = explorerService.getContext(true).filter(s => !s.isRoot);
|
||||
if (stats.length) {
|
||||
await deleteFiles(accessor.get(IExplorerService), accessor.get(IWorkingCopyFileService), accessor.get(IDialogService), accessor.get(IConfigurationService), stats, true);
|
||||
await deleteFiles(accessor.get(IExplorerService), accessor.get(IWorkingCopyFileService), accessor.get(IDialogService), accessor.get(IConfigurationService), accessor.get(IFilesConfigurationService), stats, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1029,7 +1051,7 @@ export const deleteFileHandler = async (accessor: ServicesAccessor) => {
|
|||
const stats = explorerService.getContext(true).filter(s => !s.isRoot);
|
||||
|
||||
if (stats.length) {
|
||||
await deleteFiles(accessor.get(IExplorerService), accessor.get(IWorkingCopyFileService), accessor.get(IDialogService), accessor.get(IConfigurationService), stats, false);
|
||||
await deleteFiles(accessor.get(IExplorerService), accessor.get(IWorkingCopyFileService), accessor.get(IDialogService), accessor.get(IConfigurationService), accessor.get(IFilesConfigurationService), stats, false);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import { URI } from '../../../../../base/common/uri.js';
|
|||
import * as perf from '../../../../../base/common/performance.js';
|
||||
import { WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification } from '../../../../../base/common/actions.js';
|
||||
import { memoize } from '../../../../../base/common/decorators.js';
|
||||
import { IFilesConfiguration, ExplorerFolderContext, FilesExplorerFocusedContext, ExplorerFocusedContext, ExplorerRootContext, ExplorerResourceReadonlyContext, ExplorerResourceCut, ExplorerResourceMoveableToTrash, ExplorerCompressedFocusContext, ExplorerCompressedFirstFocusContext, ExplorerCompressedLastFocusContext, ExplorerResourceAvailableEditorIdsContext, VIEW_ID, ExplorerResourceNotReadonlyContext, ViewHasSomeCollapsibleRootItemContext, FoldersViewVisibleContext, ExplorerResourceParentReadOnlyContext, ExplorerFindProviderActive } from '../../common/files.js';
|
||||
import { IFilesConfiguration, ExplorerFolderContext, FilesExplorerFocusedContext, ExplorerFocusedContext, ExplorerRootContext, ExplorerResourceReadonlyContext, ExplorerResourceCut, ExplorerResourceMoveableToTrash, ExplorerCompressedFocusContext, ExplorerCompressedFirstFocusContext, ExplorerCompressedLastFocusContext, ExplorerResourceAvailableEditorIdsContext, VIEW_ID, ExplorerResourceWritableContext, ViewHasSomeCollapsibleRootItemContext, FoldersViewVisibleContext, ExplorerResourceParentReadOnlyContext, ExplorerFindProviderActive } from '../../common/files.js';
|
||||
import { FileCopiedContext, NEW_FILE_COMMAND_ID, NEW_FOLDER_COMMAND_ID } from '../fileActions.js';
|
||||
import * as DOM from '../../../../../base/browser/dom.js';
|
||||
import { IWorkbenchLayoutService } from '../../../../services/layout/browser/layoutService.js';
|
||||
|
@ -988,7 +988,7 @@ export function createFileIconThemableTreeContainerScope(container: HTMLElement,
|
|||
|
||||
const CanCreateContext = ContextKeyExpr.or(
|
||||
// Folder: can create unless readonly
|
||||
ContextKeyExpr.and(ExplorerFolderContext, ExplorerResourceNotReadonlyContext),
|
||||
ContextKeyExpr.and(ExplorerFolderContext, ExplorerResourceWritableContext),
|
||||
// File: can create unless parent is readonly
|
||||
ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ExplorerResourceParentReadOnlyContext.toNegated())
|
||||
);
|
||||
|
|
|
@ -40,7 +40,7 @@ export const ExplorerViewletVisibleContext = new RawContextKey<boolean>('explore
|
|||
export const FoldersViewVisibleContext = new RawContextKey<boolean>('foldersViewVisible', true, { type: 'boolean', description: localize('foldersViewVisible', "True when the FOLDERS view (the file tree within the explorer view container) is visible.") });
|
||||
export const ExplorerFolderContext = new RawContextKey<boolean>('explorerResourceIsFolder', false, { type: 'boolean', description: localize('explorerResourceIsFolder', "True when the focused item in the EXPLORER is a folder.") });
|
||||
export const ExplorerResourceReadonlyContext = new RawContextKey<boolean>('explorerResourceReadonly', false, { type: 'boolean', description: localize('explorerResourceReadonly', "True when the focused item in the EXPLORER is read-only.") });
|
||||
export const ExplorerResourceNotReadonlyContext = ExplorerResourceReadonlyContext.toNegated();
|
||||
export const ExplorerResourceWritableContext = ExplorerResourceReadonlyContext.toNegated();
|
||||
export const ExplorerResourceParentReadOnlyContext = new RawContextKey<boolean>('explorerResourceParentReadonly', false, { type: 'boolean', description: localize('explorerResourceParentReadonly', "True when the focused item in the EXPLORER's parent is read-only.") });
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue