mirror of
https://github.com/Microsoft/vscode
synced 2024-10-30 01:37:20 +00:00
Explorer: allow to drag and drop files between windows to copy them over (fixes #43307)
This commit is contained in:
parent
38ab734646
commit
c761649fa4
3 changed files with 37 additions and 11 deletions
|
@ -50,10 +50,15 @@ export const DataTransfers = {
|
|||
RESOURCES: 'ResourceURLs',
|
||||
|
||||
/**
|
||||
* Browser specific transfer type to download.
|
||||
* Browser specific transfer type to download
|
||||
*/
|
||||
DOWNLOAD_URL: 'DownloadURL',
|
||||
|
||||
/**
|
||||
* Browser specific transfer type for files
|
||||
*/
|
||||
FILES: 'Files',
|
||||
|
||||
/**
|
||||
* Typicaly transfer type for copy/paste transfers.
|
||||
*/
|
||||
|
|
|
@ -60,7 +60,8 @@ export interface ISerializedDraggedEditor {
|
|||
}
|
||||
|
||||
export const CodeDataTransfers = {
|
||||
EDITORS: 'CodeEditors'
|
||||
EDITORS: 'CodeEditors',
|
||||
FILES: 'CodeFiles'
|
||||
};
|
||||
|
||||
export function extractResources(e: DragEvent, externalOnly?: boolean): (IDraggedResource | IDraggedEditor)[] {
|
||||
|
@ -79,7 +80,7 @@ export function extractResources(e: DragEvent, externalOnly?: boolean): (IDragge
|
|||
resources.push({ resource: URI.parse(draggedEditor.resource), backupResource: URI.parse(draggedEditor.backupResource), viewState: draggedEditor.viewState, isExternal: false });
|
||||
});
|
||||
} catch (error) {
|
||||
// Invalid URI
|
||||
// Invalid transfer
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,7 +93,7 @@ export function extractResources(e: DragEvent, externalOnly?: boolean): (IDragge
|
|||
resources.push(...uriStrArray.map(uriStr => ({ resource: URI.parse(uriStr), isExternal: false })));
|
||||
}
|
||||
} catch (error) {
|
||||
// Invalid Resources
|
||||
// Invalid transfer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +102,7 @@ export function extractResources(e: DragEvent, externalOnly?: boolean): (IDragge
|
|||
if (e.dataTransfer && e.dataTransfer.files) {
|
||||
for (let i = 0; i < e.dataTransfer.files.length; i++) {
|
||||
const file = e.dataTransfer.files[i] as { path: string };
|
||||
if (file && file.path) {
|
||||
if (file && file.path && !resources.some(r => r.resource.fsPath === file.path) /* prevent duplicates */) {
|
||||
try {
|
||||
resources.push({ resource: URI.file(file.path), isExternal: true });
|
||||
} catch (error) {
|
||||
|
@ -110,6 +111,21 @@ export function extractResources(e: DragEvent, externalOnly?: boolean): (IDragge
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for CodeFiles transfer
|
||||
const rawCodeFiles = e.dataTransfer.getData(CodeDataTransfers.FILES);
|
||||
if (rawCodeFiles) {
|
||||
try {
|
||||
const codeFiles = JSON.parse(rawCodeFiles) as string[];
|
||||
codeFiles.forEach(codeFile => {
|
||||
if (!resources.some(r => r.resource.fsPath === codeFile) /* prevent duplicates */) {
|
||||
resources.push({ resource: URI.file(codeFile), isExternal: true });
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
// Invalid transfer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resources;
|
||||
|
|
|
@ -50,11 +50,13 @@ import { attachInputBoxStyler } from 'vs/platform/theme/common/styler';
|
|||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IWindowService } from 'vs/platform/windows/common/windows';
|
||||
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
|
||||
import { extractResources, SimpleFileResourceDragAndDrop } from 'vs/workbench/browser/dnd';
|
||||
import { extractResources, SimpleFileResourceDragAndDrop, CodeDataTransfers } from 'vs/workbench/browser/dnd';
|
||||
import { relative } from 'path';
|
||||
import { distinctParents } from 'vs/base/common/resources';
|
||||
import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { DataTransfers } from 'vs/base/browser/dnd';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
|
||||
export class FileDataSource implements IDataSource {
|
||||
constructor(
|
||||
|
@ -728,6 +730,11 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop {
|
|||
|
||||
// Apply some datatransfer types to allow for dragging the element outside of the application
|
||||
super.onDragStart(tree, data, originalEvent);
|
||||
|
||||
// The only custom data transfer we set from the explorer is a file transfer
|
||||
// to be able to DND between multiple code file explorers across windows
|
||||
const fileResources = sources.filter(s => !s.isDirectory && s.resource.scheme === Schemas.file).map(r => r.resource.fsPath);
|
||||
originalEvent.dataTransfer.setData(CodeDataTransfers.FILES, JSON.stringify(fileResources));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -741,15 +748,13 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop {
|
|||
|
||||
// Desktop DND
|
||||
if (fromDesktop) {
|
||||
const dragData = (<DesktopDragAndDropData>data).getData();
|
||||
|
||||
const types = dragData.types;
|
||||
const types: string[] = originalEvent.dataTransfer.types;
|
||||
const typesArray: string[] = [];
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
typesArray.push(types[i]);
|
||||
typesArray.push(types[i].toLowerCase()); // somehow the types are lowercase
|
||||
}
|
||||
|
||||
if (typesArray.length === 0 || !typesArray.some(type => { return type === 'Files'; })) {
|
||||
if (typesArray.indexOf(DataTransfers.FILES.toLowerCase()) === -1 && typesArray.indexOf(CodeDataTransfers.FILES.toLowerCase()) === -1) {
|
||||
return DRAG_OVER_REJECT;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue