Skip to content

Commit da9e9fc

Browse files
committed
Enable resourceurls
1 parent 047901a commit da9e9fc

File tree

4 files changed

+61
-5
lines changed

4 files changed

+61
-5
lines changed

src/vs/workbench/browser/dnd.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { parse, stringify } from 'vs/base/common/marshalling';
3333
import { ILabelService } from 'vs/platform/label/common/label';
3434
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
3535
import { withNullAsUndefined } from 'vs/base/common/types';
36+
import { ITreeDataTransfer } from 'vs/workbench/common/views';
3637

3738
//#region Editor / Resources DND
3839

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

50+
export class DraggedExtensionTreeItemsIdentifier {
51+
52+
constructor(readonly identifier: string) { }
53+
}
54+
4955
export const CodeDataTransfers = {
5056
EDITORS: 'CodeEditors',
5157
FILES: 'CodeFiles'
@@ -130,6 +136,28 @@ export function extractEditorsDropData(e: DragEvent): Array<IDraggedResourceEdit
130136
return editors;
131137
}
132138

139+
export async function extractTreeDropData(dataTransfer: ITreeDataTransfer): Promise<Array<IDraggedResourceEditorInput>> {
140+
const editors: IDraggedResourceEditorInput[] = [];
141+
// Data Transfer: Resources
142+
const resourcesKey = DataTransfers.RESOURCES.toLowerCase();
143+
if (dataTransfer.has(resourcesKey)) {
144+
try {
145+
const rawResourcesData = await dataTransfer.get(resourcesKey)?.asString();
146+
if (rawResourcesData) {
147+
const rawResourceList = JSON.parse(rawResourcesData);
148+
for (const resourceRaw of rawResourceList) {
149+
if (resourceRaw.indexOf(':') > 0) { // mitigate https://github.com/microsoft/vscode/issues/124946
150+
editors.push({ resource: URI.parse(resourceRaw) });
151+
}
152+
}
153+
}
154+
} catch (error) {
155+
// Invalid transfer
156+
}
157+
}
158+
return editors;
159+
}
160+
133161
export interface IFileDropData {
134162
name: string;
135163
data: VSBuffer;
@@ -195,8 +223,8 @@ export class ResourcesDropHandler {
195223
) {
196224
}
197225

198-
async handleDrop(event: DragEvent, resolveTargetGroup: () => IEditorGroup | undefined, afterDrop: (targetGroup: IEditorGroup | undefined) => void, targetIndex?: number): Promise<void> {
199-
const editors = extractEditorsDropData(event);
226+
async handleDrop(event: DragEvent | ITreeDataTransfer, resolveTargetGroup: () => IEditorGroup | undefined, afterDrop: (targetGroup: IEditorGroup | undefined) => void, targetIndex?: number): Promise<void> {
227+
const editors = event instanceof DragEvent ? extractEditorsDropData(event) : await extractTreeDropData(event);
200228
if (!editors.length) {
201229
return;
202230
}

src/vs/workbench/browser/parts/editor/editorDropTarget.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

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

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

4143
private readonly editorTransfer = LocalSelectionTransfer.getInstance<DraggedEditorIdentifier>();
4244
private readonly groupTransfer = LocalSelectionTransfer.getInstance<DraggedEditorGroupIdentifier>();
45+
private readonly treeItemsTransfer = LocalSelectionTransfer.getInstance<DraggedExtensionTreeItemsIdentifier>();
4346

4447
constructor(
4548
private accessor: IEditorGroupsAccessor,
4649
private groupView: IEditorGroupView,
4750
@IThemeService themeService: IThemeService,
4851
@IInstantiationService private instantiationService: IInstantiationService,
4952
@IEditorService private readonly editorService: IEditorService,
50-
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService
53+
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
54+
@ITreeViewsDragAndDropService private readonly treeViewsDragAndDropService: ITreeViewsDragAndDropService<ITreeDataTransfer>
5155
) {
5256
super(themeService);
5357

@@ -292,6 +296,24 @@ class DropOverlay extends Themable {
292296
}
293297
}
294298

299+
// Check for tree items
300+
else if (this.treeItemsTransfer.hasData(DraggedExtensionTreeItemsIdentifier.prototype)) {
301+
const data = this.treeItemsTransfer.getData(DraggedExtensionTreeItemsIdentifier.prototype);
302+
if (Array.isArray(data)) {
303+
const treeData = Promise.all(
304+
data.map(id => this.treeViewsDragAndDropService.removeDragOperationTransfer(id.identifier)));
305+
treeData.then(dataTransferItems => {
306+
const dropHandler = this.instantiationService.createInstance(ResourcesDropHandler, { allowWorkspaceOpen: true /* open workspace instead of file if dropped */ });
307+
dataTransferItems.forEach(dataTransferItem => {
308+
if (dataTransferItem) {
309+
dropHandler.handleDrop(dataTransferItem, () => ensureTargetGroup(), targetGroup => targetGroup?.focus());
310+
}
311+
});
312+
});
313+
}
314+
this.treeItemsTransfer.clearData(DraggedExtensionTreeItemsIdentifier.prototype);
315+
}
316+
295317
// Web: check for file transfer
296318
else if (isWeb && containsDragType(event, DataTransfers.FILES)) {
297319
let targetGroup: IEditorGroupView | undefined = undefined;

src/vs/workbench/browser/parts/views/treeView.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cance
5757
import { Command } from 'vs/editor/common/languages';
5858
import { isCancellationError } from 'vs/base/common/errors';
5959
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
60-
import { CodeDataTransfers, fillEditorsDragData } from 'vs/workbench/browser/dnd';
60+
import { CodeDataTransfers, DraggedExtensionTreeItemsIdentifier, fillEditorsDragData, LocalSelectionTransfer } from 'vs/workbench/browser/dnd';
6161
import { Schemas } from 'vs/base/common/network';
6262
import { ITreeViewsDragAndDropService } from 'vs/workbench/services/views/common/treeViewsDragAndDropService';
6363
import { generateUuid } from 'vs/base/common/uuid';
@@ -1241,6 +1241,8 @@ const TREE_DRAG_UUID_MIME = 'tree-dnd';
12411241

12421242
export class CustomTreeViewDragAndDrop implements ITreeDragAndDrop<ITreeItem> {
12431243
private readonly treeMimeType: string;
1244+
private readonly treeItemsTransfer = LocalSelectionTransfer.getInstance<DraggedExtensionTreeItemsIdentifier>();
1245+
12441246
constructor(
12451247
private readonly treeId: string,
12461248
@ILabelService private readonly labelService: ILabelService,
@@ -1262,6 +1264,7 @@ export class CustomTreeViewDragAndDrop implements ITreeDragAndDrop<ITreeItem> {
12621264
const uuid = generateUuid();
12631265
this.treeViewsDragAndDropService.addDragOperationTransfer(uuid, this.dndController.handleDrag(itemHandles, uuid));
12641266
originalEvent.dataTransfer.setData(TREE_DRAG_UUID_MIME, uuid);
1267+
this.treeItemsTransfer.setData([new DraggedExtensionTreeItemsIdentifier(uuid)], DraggedExtensionTreeItemsIdentifier.prototype);
12651268
}
12661269

12671270
private addResourceInfoToTransfer(originalEvent: DragEvent, resources: URI[]) {

src/vscode-dts/vscode.proposed.treeViewDragAndDrop.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ declare module 'vscode' {
102102
* When the items are dropped on **another tree item** in **the same tree**, your `TreeDataTransferItem` objects
103103
* will be preserved. See the documentation for `TreeDataTransferItem` for how best to take advantage of this.
104104
*
105+
* To add a data transfer item that can be dragged into the editor, use the application specific mime type "resourceurls".
106+
* The data for "resourceurls" should be an array of `toString()`ed Uris.
107+
*
105108
* The returned `TreeDataTransfer` will be merged with the original`TreeDataTransfer` for the operation.
106109
*
107110
* @param source The source items for the drag and drop operation.

0 commit comments

Comments
 (0)