提交 5da820a3 编写于 作者: B Benjamin Pasero

restore ability to drop folders or *.vsix into Code

上级 1d8a0023
......@@ -42,17 +42,19 @@ export class DelayedDragHandler {
}
}
export function extractResources(e: DragEvent): URI[] {
export function extractResources(e: DragEvent, externalOnly?: boolean): URI[] {
const resources: URI[] = [];
if (e.dataTransfer.types.length > 0) {
// Check for in-app DND
const rawData = e.dataTransfer.getData(e.dataTransfer.types[0]);
if (rawData) {
try {
resources.push(URI.parse(rawData));
} catch (error) {
// Invalid URI
if (!externalOnly) {
const rawData = e.dataTransfer.getData(e.dataTransfer.types[0]);
if (rawData) {
try {
resources.push(URI.parse(rawData));
} catch (error) {
// Invalid URI
}
}
}
......
......@@ -40,6 +40,29 @@
margin-top: 7px; /* Center the select box */
}
#monaco-workbench-drop-overlay {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 3000000;
}
.vs #monaco-workbench-drop-overlay {
background-color: rgba(51,153,255, 0.18);
}
.vs-dark #monaco-workbench-drop-overlay {
background-color: rgba(83, 89, 93, 0.5);
}
.hc-black #monaco-workbench-drop-overlay {
background: none !important;
outline: 2px dashed #f38518;
outline-offset: -2px;
}
/* ---------- Light Theme ---------- */
.vs .monaco-workbench { background-color: #F3F3F3; }
......
......@@ -8,7 +8,10 @@
import platform = require('vs/base/common/platform');
import URI from 'vs/base/common/uri';
import DOM = require('vs/base/browser/dom');
import workbenchEditorCommon = require('vs/workbench/common/editor');
import DND = require('vs/base/browser/dnd');
import {Builder, $} from 'vs/base/browser/builder';
import {Identifiers} from 'vs/workbench/common/constants';
import {asFileEditorInput} from 'vs/workbench/common/editor';
import {IViewletService} from 'vs/workbench/services/viewlet/common/viewletService';
import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService';
import {IStorageService} from 'vs/platform/storage/common/storage';
......@@ -17,6 +20,8 @@ import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {IEditorGroupService} from 'vs/workbench/services/group/common/groupService';
import {ipcRenderer as ipc, shell, remote} from 'electron';
import * as fs from 'fs';
import * as path from 'path';
const dialog = remote.dialog;
......@@ -29,6 +34,13 @@ export interface IWindowConfiguration {
};
}
enum DraggedFileType {
UNKNOWN,
FILE,
EXTENSION,
FOLDER
}
export class ElectronWindow {
private win: Electron.BrowserWindow;
private windowId: number;
......@@ -53,7 +65,7 @@ export class ElectronWindow {
// React to editor input changes (Mac only)
if (platform.platform === platform.Platform.Mac) {
this.editorGroupService.onEditorsChanged(() => {
let fileInput = workbenchEditorCommon.asFileEditorInput(this.editorService.getActiveEditorInput(), true);
let fileInput = asFileEditorInput(this.editorService.getActiveEditorInput(), true);
let representedFilename = '';
if (fileInput) {
representedFilename = fileInput.getResource().fsPath;
......@@ -63,11 +75,61 @@ export class ElectronWindow {
});
}
// Prevent a dropped link from opening within
[DOM.EventType.DRAG_OVER, DOM.EventType.DROP].forEach(event => {
let draggedExternalResources: URI[];
let dropOverlay: Builder;
function cleanUp(): void {
draggedExternalResources = void 0;
if (dropOverlay) {
dropOverlay.destroy();
dropOverlay = void 0;
}
}
// Detect resources dropped into Code from outside
window.document.body.addEventListener(DOM.EventType.DRAG_OVER, (e: DragEvent) => {
DOM.EventHelper.stop(e);
if (!draggedExternalResources) {
draggedExternalResources = DND.extractResources(e, true /* external only */);
// Show Code wide overlay if we detect a Folder or Extension to be dragged
if (draggedExternalResources.some(r => {
const kind = this.getFileKind(r);
return kind === DraggedFileType.FOLDER || kind === DraggedFileType.EXTENSION;
})) {
dropOverlay = $(window.document.getElementById(Identifiers.WORKBENCH_CONTAINER))
.div({ id: 'monaco-workbench-drop-overlay' })
.on(DOM.EventType.DROP, (e: DragEvent) => {
DOM.EventHelper.stop(e, true);
this.focus(); // make sure this window has focus so that the open call reaches the right window!
ipc.send('vscode:windowOpen', draggedExternalResources.map(r => r.fsPath)); // handled from browser process
cleanUp();
})
.on([DOM.EventType.DRAG_LEAVE, DOM.EventType.DRAG_END], () => {
cleanUp();
});
}
}
});
// Clear our map and overlay on any finish of DND outside the overlay
[DOM.EventType.DROP, DOM.EventType.DRAG_END].forEach(event => {
window.document.body.addEventListener(event, (e: DragEvent) => {
DOM.EventHelper.stop(e);
});
if (!dropOverlay || e.target !== dropOverlay.getHTMLElement()) {
DOM.EventHelper.stop(e); // this prevents opening a real URL inside the shell
cleanUp();
}
}, true /* use capture because components within may preventDefault() when they accept the drop */);
});
// prevent opening a real URL inside the shell
window.document.body.addEventListener(DOM.EventType.DROP, (e: DragEvent) => {
DOM.EventHelper.stop(e);
});
// Handle window.open() calls
......@@ -86,20 +148,19 @@ export class ElectronWindow {
};
}
public open(pathsToOpen: string[]): void;
public open(fileResource: URI): void;
public open(pathToOpen: string): void;
public open(arg1: any): void {
let pathsToOpen: string[];
if (Array.isArray(arg1)) {
pathsToOpen = arg1;
} else if (typeof arg1 === 'string') {
pathsToOpen = [arg1];
} else {
pathsToOpen = [(<URI>arg1).fsPath];
private getFileKind(resource: URI): DraggedFileType {
if (path.extname(resource.fsPath) === '.vsix') {
return DraggedFileType.EXTENSION;
}
let kind = DraggedFileType.UNKNOWN;
try {
kind = fs.statSync(resource.fsPath).isDirectory() ? DraggedFileType.FOLDER : DraggedFileType.FILE;
} catch (error) {
// Do not fail in DND handler
}
ipc.send('vscode:windowOpen', pathsToOpen); // handled from browser process
return kind;
}
public openNew(): void {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册