提交 b4971f37 编写于 作者: I isidor

explorer: polish cut action

上级 ff822422
......@@ -45,11 +45,14 @@ export interface IExplorerService {
readonly onDidChangeItem: Event<ExplorerItem | undefined>;
readonly onDidChangeEditable: Event<ExplorerItem>;
readonly onDidSelectItem: Event<{ item?: ExplorerItem, reveal?: boolean }>;
readonly onDidCopyItems: Event<{ items: ExplorerItem[], cut: boolean, previouslyCutItems: ExplorerItem[] }>;
setEditable(stat: ExplorerItem, data: IEditableData): void;
getEditableData(stat: ExplorerItem): IEditableData | undefined;
findClosest(resource: URI): ExplorerItem | null;
refresh(): void;
setToCopy(stats: ExplorerItem[], cut: boolean): void;
isCut(stat: ExplorerItem): boolean;
/**
* Selects and reveal the file element provided by the given resource if its found in the explorer. Will try to
......
......@@ -16,6 +16,7 @@ import { ResourceGlobMatcher } from 'vs/workbench/electron-browser/resources';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
import { IExpression } from 'vs/base/common/glob';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
function getFileEventsExcludes(configurationService: IConfigurationService, root?: URI): IExpression {
const scope = root ? { resource: root } : undefined;
......@@ -33,15 +34,18 @@ export class ExplorerService implements IExplorerService {
private _onDidChangeItem = new Emitter<ExplorerItem | undefined>();
private _onDidChangeEditable = new Emitter<ExplorerItem>();
private _onDidSelectItem = new Emitter<{ item?: ExplorerItem, reveal?: boolean }>();
private _onDidCopyItems = new Emitter<{ items: ExplorerItem[], cut: boolean, previouslyCutItems: ExplorerItem[] }>();
private disposables: IDisposable[] = [];
private editableStats = new Map<ExplorerItem, IEditableData>();
private _sortOrder: SortOrder;
private cutItems: ExplorerItem[];
constructor(
@IFileService private fileService: IFileService,
@IInstantiationService private instantiationService: IInstantiationService,
@IConfigurationService private configurationService: IConfigurationService,
@IWorkspaceContextService private contextService: IWorkspaceContextService
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IClipboardService private clipboardService: IClipboardService
) { }
get roots(): ExplorerItem[] {
......@@ -64,6 +68,10 @@ export class ExplorerService implements IExplorerService {
return this._onDidSelectItem.event;
}
get onDidCopyItems(): Event<{ items: ExplorerItem[], cut: boolean, previouslyCutItems: ExplorerItem[] }> {
return this._onDidCopyItems.event;
}
get sortOrder(): SortOrder {
return this._sortOrder;
}
......@@ -103,6 +111,18 @@ export class ExplorerService implements IExplorerService {
this._onDidChangeEditable.fire(stat);
}
setToCopy(items: ExplorerItem[], cut: boolean): void {
const previouslyCutItems = this.cutItems;
this.cutItems = cut ? items : undefined;
this.clipboardService.writeResources(items.map(s => s.resource));
this._onDidCopyItems.fire({ items, cut, previouslyCutItems });
}
isCut(item: ExplorerItem): boolean {
return this.cutItems && this.cutItems.indexOf(item) >= 0;
}
getEditableData(stat: ExplorerItem): IEditableData | undefined {
return this.editableStats.get(stat);
}
......
......@@ -475,6 +475,10 @@ class PasteFileAction extends BaseErrorReportingAction {
// Copy File
const promise = pasteShouldMove ? this.fileService.moveFile(fileToPaste, targetFile) : this.fileService.copyFile(fileToPaste, targetFile);
return promise.then(stat => {
if (pasteShouldMove) {
// Cut is done. Make sure to clear cut state.
this.explorerService.setToCopy([], false);
}
if (!stat.isDirectory) {
return this.editorService.openEditor({ resource: stat.resource, options: { pinned: true, preserveFocus: true } });
}
......@@ -1102,22 +1106,20 @@ export const deleteFileHandler = (accessor: ServicesAccessor) => {
};
export const copyFileHandler = (accessor: ServicesAccessor) => {
const clipboardService = accessor.get(IClipboardService);
const listService = accessor.get(IListService);
const explorerContext = getContext(listService.lastFocusedList);
const explorerService = accessor.get(IExplorerService);
const stats = explorerContext.selection.length > 1 ? explorerContext.selection : [explorerContext.stat];
explorerService.setToCopy(stats, false);
clipboardService.writeResources(stats.map(e => e.resource));
pasteShouldMove = false;
};
export const cutFileHandler = (accessor: ServicesAccessor) => {
const listService = accessor.get(IListService);
const explorerContext = getContext(listService.lastFocusedList);
const clipboardService = accessor.get(IClipboardService);
const explorerService = accessor.get(IExplorerService);
const stats = explorerContext.selection.length > 1 ? explorerContext.selection : [explorerContext.stat];
clipboardService.writeResources(stats.map(s => s.resource));
explorerService.setToCopy(stats, true);
pasteShouldMove = true;
};
......
......@@ -47,6 +47,10 @@
flex: 1;
}
.explorer-viewlet .explorer-item.cut {
opacity: 0.3;
}
.explorer-viewlet .explorer-item.explorer-item-edited .label-name {
flex: 0; /* do not steal space when label is hidden because we are in edit mode */
}
......
......@@ -37,7 +37,6 @@ import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/work
import { ITreeContextMenuEvent } from 'vs/base/browser/ui/tree/tree';
import { IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions';
import { fillInContextMenuActions } from 'vs/platform/actions/browser/menuItemActionItem';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ExplorerItem } from 'vs/workbench/parts/files/common/explorerModel';
import { onUnexpectedError } from 'vs/base/common/errors';
......@@ -83,7 +82,6 @@ export class ExplorerView extends ViewletPanel {
@IThemeService private readonly themeService: IWorkbenchThemeService,
@IListService private readonly listService: IListService,
@IMenuService private readonly menuService: IMenuService,
@IClipboardService private readonly clipboardService: IClipboardService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
@IExplorerService private readonly explorerService: IExplorerService,
@IStorageService private readonly storageService: IStorageService
......@@ -185,6 +183,7 @@ export class ExplorerView extends ViewletPanel {
}
}));
this.disposables.push(this.explorerService.onDidSelectItem(e => this.onSelectItem(e.item, e.reveal)));
this.disposables.push(this.explorerService.onDidCopyItems(e => this.onCopyItems(e.items, e.cut, e.previouslyCutItems)));
// Update configuration
const configuration = this.configurationService.getValue<IFilesConfiguration>();
......@@ -368,9 +367,6 @@ export class ExplorerView extends ViewletPanel {
private onContextMenu(e: ITreeContextMenuEvent<ExplorerItem>): void {
const stat = e.element;
// update dynamic contexts
this.fileCopiedContextKey.set(this.clipboardService.hasResources());
const selection = this.tree.getSelection();
this.contextMenuService.showContextMenu({
getAnchor: () => e.anchor,
......@@ -484,6 +480,16 @@ export class ExplorerView extends ViewletPanel {
});
}
private onCopyItems(stats: ExplorerItem[], cut: boolean, previousCut: ExplorerItem[]): void {
this.fileCopiedContextKey.set(stats.length > 0);
if (previousCut) {
previousCut.forEach(item => this.tree.refresh(item));
}
if (cut) {
stats.forEach(s => this.tree.refresh(s));
}
}
collapseAll(): void {
this.tree.collapseAll();
}
......
......@@ -140,6 +140,9 @@ export class FilesRenderer implements ITreeRenderer<ExplorerItem, FuzzyScore, IF
if (!editableData) {
templateData.label.element.style.display = 'flex';
const extraClasses = ['explorer-item'];
if (this.explorerService.isCut(stat)) {
extraClasses.push('cut');
}
templateData.label.setFile(stat.resource, {
hidePath: true,
fileKind: stat.isRoot ? FileKind.ROOT_FOLDER : stat.isDirectory ? FileKind.FOLDER : FileKind.FILE,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册