提交 e6c6e4f0 编写于 作者: B Benjamin Pasero

dropping multiple folders: open workspace

上级 0c59c951
......@@ -155,7 +155,7 @@ class NewWorkspaceAction extends BaseWorkspacesAction {
}
private createWorkspace(folders: URI[]): TPromise<void> {
const workspaceFolders = distinct(folders.map(folder => folder.toString(true /* encoding */)));
const workspaceFolders = distinct(folders.map(folder => folder.toString(true /* skip encoding to preserve drive letters readable */)));
return this.windowService.createAndOpenWorkspace(workspaceFolders);
}
......
......@@ -39,6 +39,7 @@ import { Themable, EDITOR_GROUP_HEADER_TABS_BACKGROUND, EDITOR_GROUP_HEADER_NO_T
import { attachProgressBarStyler } from 'vs/platform/theme/common/styler';
import { IMessageService } from 'vs/platform/message/common/message';
import { IFileService } from 'vs/platform/files/common/files';
import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
export enum Rochade {
NONE,
......@@ -152,7 +153,8 @@ export class EditorGroupsControl extends Themable implements IEditorGroupsContro
@IWindowsService private windowsService: IWindowsService,
@IThemeService themeService: IThemeService,
@IFileService private fileService: IFileService,
@IMessageService private messageService: IMessageService
@IMessageService private messageService: IMessageService,
@IWorkspacesService private workspacesService: IWorkspacesService
) {
super(themeService);
......@@ -1118,7 +1120,7 @@ export class EditorGroupsControl extends Themable implements IEditorGroupsContro
else {
const droppedResources = extractResources(e).filter(r => r.resource.scheme === 'file' || r.resource.scheme === 'untitled');
if (droppedResources.length) {
handleWorkspaceExternalDrop(droppedResources, $this.fileService, $this.messageService, $this.windowsService, $this.windowService).then(handled => {
handleWorkspaceExternalDrop(droppedResources, $this.fileService, $this.messageService, $this.windowsService, $this.windowService, $this.workspacesService).then(handled => {
if (handled) {
return;
}
......
......@@ -43,6 +43,7 @@ import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector }
import { TAB_INACTIVE_BACKGROUND, TAB_ACTIVE_BACKGROUND, TAB_ACTIVE_FOREGROUND, TAB_INACTIVE_FOREGROUND, TAB_BORDER, EDITOR_DRAG_AND_DROP_BACKGROUND, TAB_UNFOCUSED_ACTIVE_FOREGROUND, TAB_UNFOCUSED_INACTIVE_FOREGROUND } from 'vs/workbench/common/theme';
import { activeContrastBorder, contrastBorder } from 'vs/platform/theme/common/colorRegistry';
import { IFileService } from 'vs/platform/files/common/files';
import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
interface IEditorInputLabel {
name: string;
......@@ -74,7 +75,8 @@ export class TabsTitleControl extends TitleControl {
@IWindowService private windowService: IWindowService,
@IWindowsService private windowsService: IWindowsService,
@IThemeService themeService: IThemeService,
@IFileService private fileService: IFileService
@IFileService private fileService: IFileService,
@IWorkspacesService private workspacesService: IWorkspacesService
) {
super(contextMenuService, instantiationService, editorService, editorGroupService, contextKeyService, keybindingService, telemetryService, messageService, menuService, quickOpenService, themeService);
......@@ -691,7 +693,7 @@ export class TabsTitleControl extends TitleControl {
if (droppedResources.length) {
DOM.EventHelper.stop(e, true);
handleWorkspaceExternalDrop(droppedResources, this.fileService, this.messageService, this.windowsService, this.windowService).then(handled => {
handleWorkspaceExternalDrop(droppedResources, this.fileService, this.messageService, this.windowsService, this.windowService, this.workspacesService).then(handled => {
if (handled) {
return;
}
......
......@@ -40,10 +40,11 @@ import { ResourceContextKey } from 'vs/workbench/common/resources';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { Themable } from 'vs/workbench/common/theme';
import { IDraggedResource } from 'vs/base/browser/dnd';
import { WORKSPACE_EXTENSION } from 'vs/platform/workspaces/common/workspaces';
import { WORKSPACE_EXTENSION, IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
import { extname } from 'vs/base/common/paths';
import { IFileService } from 'vs/platform/files/common/files';
import { IWindowsService, IWindowService } from 'vs/platform/windows/common/windows';
import URI from 'vs/base/common/uri';
export interface IToolbarActions {
primary: IAction[];
......@@ -492,7 +493,8 @@ export function handleWorkspaceExternalDrop(
fileService: IFileService,
messageService: IMessageService,
windowsService: IWindowsService,
windowService: IWindowService
windowService: IWindowService,
workspacesService: IWorkspacesService
): TPromise<boolean /* handled */> {
// Return early if there are no external resources
......@@ -501,40 +503,54 @@ export function handleWorkspaceExternalDrop(
return TPromise.as(false);
}
const externalWorkspaceResources: { workspaces: URI[], folders: URI[] } = {
workspaces: [],
folders: []
};
return TPromise.join(externalResources.map(resource => {
// Check for Workspace
if (extname(resource.fsPath) === `.${WORKSPACE_EXTENSION}`) {
return TPromise.as(true); // Workspace
externalWorkspaceResources.workspaces.push(resource);
return void 0;
}
// Check for Folder
return fileService.resolveFile(resource).then(stat => stat.isDirectory, error => false);
})).then(res => {
return fileService.resolveFile(resource).then(stat => {
if (stat.isDirectory) {
externalWorkspaceResources.folders.push(stat.resource);
}
}, error => void 0);
})).then(_ => {
const { workspaces, folders } = externalWorkspaceResources;
// Return early if no external resource is a folder or workspace
const openAsWorkspace = res.some(res => !!res);
if (!openAsWorkspace) {
return false; // not handled as workspace
if (workspaces.length === 0 && folders.length === 0) {
return false;
}
// Pass focus to window
windowService.focusWindow();
// Ask the user when opening a potential large number of folders
let doOpen = true;
if (externalResources.length > 20) {
doOpen = messageService.confirm({
message: nls.localize('confirmOpen', "Are you sure you want to open {0} workspaces?", externalResources.length),
primaryButton: nls.localize({ key: 'confirmOpenButton', comment: ['&& denotes a mnemonic'] }, "&&Open"),
type: 'question'
});
let workspacesToOpen: TPromise<string[]>;
// Open in separate windows if we drop workspaces or just one folder
if (workspaces.length > 0 || folders.length === 1) {
workspacesToOpen = TPromise.as([...workspaces, ...folders].map(resources => resources.fsPath));
}
if (doOpen) {
windowsService.openWindow(externalResources.map(r => r.fsPath), { forceReuseWindow: true });
// Multiple folders: Create new workspace with folders and open
else if (folders.length > 1) {
workspacesToOpen = workspacesService.createWorkspace([...folders].map(folder => folder.toString(true /* skip encoding to preserve drive letters readable */))).then(workspace => [workspace.configPath]);
}
// Open
workspacesToOpen.then(workspaces => {
windowsService.openWindow(workspaces, { forceReuseWindow: true });
});
return true;
});
}
\ No newline at end of file
......@@ -895,7 +895,7 @@ export class FileDragAndDrop implements IDragAndDrop {
const currentRoots = this.contextService.getWorkspace().roots;
const newRoots = [...currentRoots, ...folders];
return this.windowService.createAndOpenWorkspace(distinct(newRoots.map(root => root.toString(true /* encoding */))));
return this.windowService.createAndOpenWorkspace(distinct(newRoots.map(root => root.toString(true /* skip encoding to preserve drive letters readable */))));
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册