Skip to content

Commit

Permalink
Enable resourceurls
Browse files Browse the repository at this point in the history
  • Loading branch information
alexr00 committed Jan 14, 2022
1 parent 047901a commit da9e9fc
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 5 deletions.
32 changes: 30 additions & 2 deletions src/vs/workbench/browser/dnd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { parse, stringify } from 'vs/base/common/marshalling';
import { ILabelService } from 'vs/platform/label/common/label';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { withNullAsUndefined } from 'vs/base/common/types';
import { ITreeDataTransfer } from 'vs/workbench/common/views';

//#region Editor / Resources DND

Expand All @@ -46,6 +47,11 @@ export class DraggedEditorGroupIdentifier {
constructor(readonly identifier: GroupIdentifier) { }
}

export class DraggedExtensionTreeItemsIdentifier {

constructor(readonly identifier: string) { }
}

export const CodeDataTransfers = {
EDITORS: 'CodeEditors',
FILES: 'CodeFiles'
Expand Down Expand Up @@ -130,6 +136,28 @@ export function extractEditorsDropData(e: DragEvent): Array<IDraggedResourceEdit
return editors;
}

export async function extractTreeDropData(dataTransfer: ITreeDataTransfer): Promise<Array<IDraggedResourceEditorInput>> {
const editors: IDraggedResourceEditorInput[] = [];
// Data Transfer: Resources
const resourcesKey = DataTransfers.RESOURCES.toLowerCase();
if (dataTransfer.has(resourcesKey)) {
try {
const rawResourcesData = await dataTransfer.get(resourcesKey)?.asString();
if (rawResourcesData) {
const rawResourceList = JSON.parse(rawResourcesData);
for (const resourceRaw of rawResourceList) {
if (resourceRaw.indexOf(':') > 0) { // mitigate https://github.com/microsoft/vscode/issues/124946
editors.push({ resource: URI.parse(resourceRaw) });
}
}
}
} catch (error) {
// Invalid transfer
}
}
return editors;
}

export interface IFileDropData {
name: string;
data: VSBuffer;
Expand Down Expand Up @@ -195,8 +223,8 @@ export class ResourcesDropHandler {
) {
}

async handleDrop(event: DragEvent, resolveTargetGroup: () => IEditorGroup | undefined, afterDrop: (targetGroup: IEditorGroup | undefined) => void, targetIndex?: number): Promise<void> {
const editors = extractEditorsDropData(event);
async handleDrop(event: DragEvent | ITreeDataTransfer, resolveTargetGroup: () => IEditorGroup | undefined, afterDrop: (targetGroup: IEditorGroup | undefined) => void, targetIndex?: number): Promise<void> {
const editors = event instanceof DragEvent ? extractEditorsDropData(event) : await extractTreeDropData(event);
if (!editors.length) {
return;
}
Expand Down
26 changes: 24 additions & 2 deletions src/vs/workbench/browser/parts/editor/editorDropTarget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import 'vs/css!./media/editordroptarget';
import { LocalSelectionTransfer, DraggedEditorIdentifier, ResourcesDropHandler, DraggedEditorGroupIdentifier, DragAndDropObserver, containsDragType, CodeDataTransfers, extractFilesDropData } from 'vs/workbench/browser/dnd';
import { LocalSelectionTransfer, DraggedEditorIdentifier, ResourcesDropHandler, DraggedEditorGroupIdentifier, DragAndDropObserver, containsDragType, CodeDataTransfers, extractFilesDropData, DraggedExtensionTreeItemsIdentifier } from 'vs/workbench/browser/dnd';
import { addDisposableListener, EventType, EventHelper, isAncestor } from 'vs/base/browser/dom';
import { IEditorGroupsAccessor, IEditorGroupView, fillActiveEditorViewState } from 'vs/workbench/browser/parts/editor/editor';
import { EDITOR_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme';
Expand All @@ -21,6 +21,8 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
import { assertIsDefined, assertAllDefined } from 'vs/base/common/types';
import { Schemas } from 'vs/base/common/network';
import { URI } from 'vs/base/common/uri';
import { ITreeViewsDragAndDropService } from 'vs/workbench/services/views/common/treeViewsDragAndDropService';
import { ITreeDataTransfer } from 'vs/workbench/common/views';

interface IDropOperation {
splitDirection?: GroupDirection;
Expand All @@ -40,14 +42,16 @@ class DropOverlay extends Themable {

private readonly editorTransfer = LocalSelectionTransfer.getInstance<DraggedEditorIdentifier>();
private readonly groupTransfer = LocalSelectionTransfer.getInstance<DraggedEditorGroupIdentifier>();
private readonly treeItemsTransfer = LocalSelectionTransfer.getInstance<DraggedExtensionTreeItemsIdentifier>();

constructor(
private accessor: IEditorGroupsAccessor,
private groupView: IEditorGroupView,
@IThemeService themeService: IThemeService,
@IInstantiationService private instantiationService: IInstantiationService,
@IEditorService private readonly editorService: IEditorService,
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
@ITreeViewsDragAndDropService private readonly treeViewsDragAndDropService: ITreeViewsDragAndDropService<ITreeDataTransfer>
) {
super(themeService);

Expand Down Expand Up @@ -292,6 +296,24 @@ class DropOverlay extends Themable {
}
}

// Check for tree items
else if (this.treeItemsTransfer.hasData(DraggedExtensionTreeItemsIdentifier.prototype)) {
const data = this.treeItemsTransfer.getData(DraggedExtensionTreeItemsIdentifier.prototype);
if (Array.isArray(data)) {
const treeData = Promise.all(
data.map(id => this.treeViewsDragAndDropService.removeDragOperationTransfer(id.identifier)));
treeData.then(dataTransferItems => {
const dropHandler = this.instantiationService.createInstance(ResourcesDropHandler, { allowWorkspaceOpen: true /* open workspace instead of file if dropped */ });
dataTransferItems.forEach(dataTransferItem => {
if (dataTransferItem) {
dropHandler.handleDrop(dataTransferItem, () => ensureTargetGroup(), targetGroup => targetGroup?.focus());
}
});
});
}
this.treeItemsTransfer.clearData(DraggedExtensionTreeItemsIdentifier.prototype);
}

// Web: check for file transfer
else if (isWeb && containsDragType(event, DataTransfers.FILES)) {
let targetGroup: IEditorGroupView | undefined = undefined;
Expand Down
5 changes: 4 additions & 1 deletion src/vs/workbench/browser/parts/views/treeView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cance
import { Command } from 'vs/editor/common/languages';
import { isCancellationError } from 'vs/base/common/errors';
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
import { CodeDataTransfers, fillEditorsDragData } from 'vs/workbench/browser/dnd';
import { CodeDataTransfers, DraggedExtensionTreeItemsIdentifier, fillEditorsDragData, LocalSelectionTransfer } from 'vs/workbench/browser/dnd';
import { Schemas } from 'vs/base/common/network';
import { ITreeViewsDragAndDropService } from 'vs/workbench/services/views/common/treeViewsDragAndDropService';
import { generateUuid } from 'vs/base/common/uuid';
Expand Down Expand Up @@ -1241,6 +1241,8 @@ const TREE_DRAG_UUID_MIME = 'tree-dnd';

export class CustomTreeViewDragAndDrop implements ITreeDragAndDrop<ITreeItem> {
private readonly treeMimeType: string;
private readonly treeItemsTransfer = LocalSelectionTransfer.getInstance<DraggedExtensionTreeItemsIdentifier>();

constructor(
private readonly treeId: string,
@ILabelService private readonly labelService: ILabelService,
Expand All @@ -1262,6 +1264,7 @@ export class CustomTreeViewDragAndDrop implements ITreeDragAndDrop<ITreeItem> {
const uuid = generateUuid();
this.treeViewsDragAndDropService.addDragOperationTransfer(uuid, this.dndController.handleDrag(itemHandles, uuid));
originalEvent.dataTransfer.setData(TREE_DRAG_UUID_MIME, uuid);
this.treeItemsTransfer.setData([new DraggedExtensionTreeItemsIdentifier(uuid)], DraggedExtensionTreeItemsIdentifier.prototype);
}

private addResourceInfoToTransfer(originalEvent: DragEvent, resources: URI[]) {
Expand Down
3 changes: 3 additions & 0 deletions src/vscode-dts/vscode.proposed.treeViewDragAndDrop.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ declare module 'vscode' {
* When the items are dropped on **another tree item** in **the same tree**, your `TreeDataTransferItem` objects
* will be preserved. See the documentation for `TreeDataTransferItem` for how best to take advantage of this.
*
* To add a data transfer item that can be dragged into the editor, use the application specific mime type "resourceurls".
* The data for "resourceurls" should be an array of `toString()`ed Uris.
*
* The returned `TreeDataTransfer` will be merged with the original`TreeDataTransfer` for the operation.
*
* @param source The source items for the drag and drop operation.
Expand Down

0 comments on commit da9e9fc

Please sign in to comment.