editors dnd - towards allowing any untyped editor input

This commit is contained in:
Benjamin Pasero 2021-05-27 10:13:37 +02:00
parent 433c801dcc
commit 367a0b809a
No known key found for this signature in database
GPG key ID: E6380CC4C8219E65
6 changed files with 22 additions and 20 deletions

View file

@ -11,7 +11,7 @@ import { IWindowOpenable } from 'vs/platform/windows/common/windows';
import { URI } from 'vs/base/common/uri';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { FileAccess, Schemas } from 'vs/base/common/network';
import { ITextResourceEditorInput } from 'vs/platform/editor/common/editor';
import { IBaseTextResourceEditorInput } from 'vs/platform/editor/common/editor';
import { DataTransfers, IDragAndDropData } from 'vs/base/browser/dnd';
import { DragMouseEvent } from 'vs/base/browser/mouseEvent';
import { normalizeDriveLetter } from 'vs/base/common/labels';
@ -48,12 +48,13 @@ export const CodeDataTransfers = {
FILES: 'CodeFiles'
};
interface IDraggedTextResourceEditorInput extends ITextResourceEditorInput {
interface IDraggedResourceEditorInput extends IBaseTextResourceEditorInput {
resource?: URI;
isExternal?: boolean;
}
export function extractEditorsDropData(e: DragEvent, externalOnly?: boolean): Array<IDraggedTextResourceEditorInput> {
const editors: Array<IDraggedTextResourceEditorInput> = [];
export function extractEditorsDropData(e: DragEvent, externalOnly?: boolean): Array<IDraggedResourceEditorInput> {
const editors: Array<IDraggedResourceEditorInput> = [];
if (e.dataTransfer && e.dataTransfer.types.length > 0) {
// Check for window-to-window DND
@ -150,7 +151,7 @@ export class ResourcesDropHandler {
await this.hostService.focus();
// Check for workspace file being dropped if we are allowed to do so
const externalLocalFiles = editors.filter(editor => editor.isExternal && editor.resource.scheme === Schemas.file).map(file => file.resource);
const externalLocalFiles = coalesce(editors.filter(editor => editor.isExternal && editor.resource?.scheme === Schemas.file).map(editor => editor.resource));
if (this.options.allowWorkspaceOpen) {
if (externalLocalFiles.length > 0) {
const isWorkspaceOpening = await this.handleWorkspaceFileDrop(externalLocalFiles);
@ -280,12 +281,12 @@ export function fillEditorsDragData(accessor: ServicesAccessor, resourcesOrEdito
const textFileService = accessor.get(ITextFileService);
const editorService = accessor.get(IEditorService);
const draggedEditors: IDraggedTextResourceEditorInput[] = [];
const draggedEditors: IDraggedResourceEditorInput[] = [];
for (const resourceOrEditor of resourcesOrEditors) {
// Extract resource editor from provided object or URI
let editor: ITextResourceEditorInput | undefined = undefined;
let editor: IDraggedResourceEditorInput | undefined = undefined;
if (isEditorIdentifier(resourceOrEditor)) {
editor = resourceOrEditor.editor.asResourceEditorInput(resourceOrEditor.groupId);
} else if (URI.isUri(resourceOrEditor)) {
@ -304,7 +305,7 @@ export function fillEditorsDragData(accessor: ServicesAccessor, resourcesOrEdito
// provide everything from the `asResourceEditorInput` method.
{
const resource = editor.resource;
const textModel = resource.scheme === Schemas.untitled ? textFileService.untitled.get(resource) : textFileService.files.get(resource);
const textModel = resource ? resource.scheme === Schemas.untitled ? textFileService.untitled.get(resource) : textFileService.files.get(resource) : undefined;
if (textModel) {
// mode

View file

@ -541,7 +541,7 @@ export interface IEditorInput extends IDisposable {
*
* May return `undefined` if a untyped representatin is not supported.
*/
asResourceEditorInput(groupId: GroupIdentifier): IResourceEditorInput | undefined;
asResourceEditorInput(groupId: GroupIdentifier): IBaseResourceEditorInput | undefined;
/**
* Returns if the other object matches this input.

View file

@ -6,7 +6,7 @@
import { Emitter } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { Disposable } from 'vs/base/common/lifecycle';
import { IEditorModel, IResourceEditorInput } from 'vs/platform/editor/common/editor';
import { IBaseResourceEditorInput, IEditorModel } from 'vs/platform/editor/common/editor';
import { firstOrDefault } from 'vs/base/common/arrays';
import { IEditorInput, EditorInputCapabilities, Verbosity, GroupIdentifier, ISaveOptions, IRevertOptions, IMoveResult, IEditorDescriptor, IEditorPane } from 'vs/workbench/common/editor';
@ -118,7 +118,7 @@ export abstract class EditorInput extends Disposable implements IEditorInput {
return firstOrDefault(editors);
}
asResourceEditorInput(groupId: GroupIdentifier): IResourceEditorInput | undefined {
asResourceEditorInput(groupId: GroupIdentifier): IBaseResourceEditorInput | undefined {
return undefined;
}

View file

@ -375,9 +375,10 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements
};
}
override asResourceEditorInput(group: GroupIdentifier): ITextResourceEditorInput | undefined {
override asResourceEditorInput(group: GroupIdentifier): ITextResourceEditorInput {
return {
resource: this.preferredResource,
forceFile: true,
encoding: this.getEncoding(),
mode: this.getMode(),
options: {

View file

@ -418,8 +418,8 @@ export class NativeFileImport {
private async doImport(target: ExplorerItem, source: DragEvent, token: CancellationToken): Promise<void> {
// Check for dropped external files to be folders
const editors = extractEditorsDropData(source, true);
const resolvedFiles = await this.fileService.resolveAll(editors.map(editor => ({ resource: editor.resource })));
const files = coalesce(extractEditorsDropData(source, true).filter(editor => URI.isUri(editor.resource) && this.fileService.canHandleResource(editor.resource)).map(editor => editor.resource));
const resolvedFiles = await this.fileService.resolveAll(files.map(file => ({ resource: file })));
if (token.isCancellationRequested) {
return;
@ -462,13 +462,13 @@ export class NativeFileImport {
// Copy resources
if (choice === buttons.length - 2) {
return this.importResources(target, editors.map(editor => editor.resource), token);
return this.importResources(target, files, token);
}
}
// Handle dropped files (only support FileStat as target)
else if (target instanceof ExplorerItem) {
return this.importResources(target, editors.map(editor => editor.resource), token);
return this.importResources(target, files, token);
}
}

View file

@ -3,8 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ITextResourceEditorInput } from 'vs/platform/editor/common/editor';
import { GroupIdentifier, Verbosity } from 'vs/workbench/common/editor';
import { GroupIdentifier, IUntitledTextResourceEditorInput, Verbosity } from 'vs/workbench/common/editor';
import { AbstractTextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput';
import { IUntitledTextEditorModel } from 'vs/workbench/services/untitled/common/untitledTextEditorModel';
import { EncodingMode, IEncodingSupport, IModeSupport, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
@ -116,9 +115,10 @@ export class UntitledTextEditorInput extends AbstractTextResourceEditorInput imp
return this.model;
}
override asResourceEditorInput(group: GroupIdentifier): ITextResourceEditorInput | undefined {
override asResourceEditorInput(group: GroupIdentifier): IUntitledTextResourceEditorInput {
return {
resource: this.model.resource,
resource: this.model.hasAssociatedFilePath ? this.model.resource : undefined,
forceUntitled: true,
encoding: this.getEncoding(),
mode: this.getMode(),
options: {