提交 3eab9bb1 编写于 作者: B Benjamin Pasero

first cut actions to save/open workspace

上级 1eea444b
......@@ -355,8 +355,22 @@ export class CodeMenu {
const openRecent = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miOpenRecent', comment: ['&& denotes a mnemonic'] }, "Open &&Recent")), submenu: openRecentMenu, enabled: openRecentMenu.items.length > 0 });
const isMultiRootEnabled = (product.quality !== 'stable'); // TODO@Ben multi root
const createWorkspace = this.createMenuItem(nls.localize({ key: 'miCreateWorkspace', comment: ['&& denotes a mnemonic'] }, "&&Create Workspace..."), 'workbench.action.createWorkspace', this.windowsService.getWindowCount() > 0);
const workspacesMenu = new Menu();
const workspaces = new MenuItem({ label: this.mnemonicLabel(nls.localize({ key: 'miWorkspaces', comment: ['&& denotes a mnemonic'] }, "Workspaces")), submenu: workspacesMenu });
const newWorkspace = this.createMenuItem(nls.localize({ key: 'miNewWorkspace', comment: ['&& denotes a mnemonic'] }, "&&New Workspace..."), 'workbench.action.createWorkspace', this.windowsService.getWindowCount() > 0);
const openWorkspace = this.createMenuItem(nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "&&Open Workspace..."), 'workbench.action.openWorkspace');
const saveWorkspace = this.createMenuItem(nls.localize({ key: 'miSaveWorkspace', comment: ['&& denotes a mnemonic'] }, "&&Save Workspace..."), 'workbench.action.saveWorkspace', this.windowsService.getWindowCount() > 0);
const addFolder = this.createMenuItem(nls.localize({ key: 'miAddFolderToWorkspace', comment: ['&& denotes a mnemonic'] }, "&&Add Folder to Workspace..."), 'workbench.action.addRootFolder', this.windowsService.getWindowCount() > 0);
[
newWorkspace,
openWorkspace,
__separator__(),
saveWorkspace,
__separator__(),
addFolder
].forEach(item => workspacesMenu.append(item));
const saveFile = this.createMenuItem(nls.localize({ key: 'miSave', comment: ['&& denotes a mnemonic'] }, "&&Save"), 'workbench.action.files.save', this.windowsService.getWindowCount() > 0);
const saveFileAs = this.createMenuItem(nls.localize({ key: 'miSaveAs', comment: ['&& denotes a mnemonic'] }, "Save &&As..."), 'workbench.action.files.saveAs', this.windowsService.getWindowCount() > 0);
......@@ -385,8 +399,7 @@ export class CodeMenu {
!isMacintosh ? openFolder : null,
openRecent,
isMultiRootEnabled ? __separator__() : null,
isMultiRootEnabled ? createWorkspace : null,
isMultiRootEnabled ? addFolder : null,
isMultiRootEnabled ? workspaces : null,
__separator__(),
saveFile,
saveFileAs,
......
......@@ -99,6 +99,7 @@ export interface IWindowService {
onWindowTitleDoubleClick(): TPromise<void>;
showMessageBox(options: Electron.ShowMessageBoxOptions): number;
showSaveDialog(options: Electron.SaveDialogOptions, callback?: (fileName: string) => void): string;
showOpenDialog(options: Electron.OpenDialogOptions, callback?: (fileNames: string[]) => void): string[];
}
export type MenuBarVisibility = 'default' | 'visible' | 'toggle' | 'hidden';
......
......@@ -111,4 +111,12 @@ export class WindowService implements IWindowService {
return remote.dialog.showSaveDialog(remote.getCurrentWindow(), options); // https://github.com/electron/electron/issues/4936
}
showOpenDialog(options: Electron.OpenDialogOptions, callback?: (fileNames: string[]) => void): string[] {
if (callback) {
return remote.dialog.showOpenDialog(remote.getCurrentWindow(), options, callback);
}
return remote.dialog.showOpenDialog(remote.getCurrentWindow(), options); // https://github.com/electron/electron/issues/4936
}
}
......@@ -16,7 +16,7 @@ import { IEnvironmentService } from "vs/platform/environment/common/environment"
export const IWorkspacesMainService = createDecorator<IWorkspacesMainService>('workspacesMainService');
export const IWorkspacesService = createDecorator<IWorkspacesService>('workspacesService');
export const WORKSPACE_EXTNAME = '.code';
export const WORKSPACE_EXTENSION = 'code';
export interface IWorkspaceIdentifier {
id: string;
......@@ -39,6 +39,7 @@ export interface IWorkspacesService {
_serviceBrand: any;
createWorkspace(folders?: string[]): TPromise<IWorkspaceIdentifier>;
saveWorkspace(workspace: IWorkspaceIdentifier, target: string): TPromise<IWorkspaceIdentifier>;
}
export function getWorkspaceLabel(environmentService: IEnvironmentService, workspace: IWorkspaceIdentifier): string {
......
......@@ -11,6 +11,7 @@ import { IWorkspacesService, IWorkspaceIdentifier } from 'vs/platform/workspaces
export interface IWorkspacesChannel extends IChannel {
call(command: 'createWorkspace', arg: [string[]]): TPromise<string>;
call(command: 'saveWorkspace', arg: [IWorkspaceIdentifier, string]): TPromise<IWorkspaceIdentifier>;
call(command: string, arg?: any): TPromise<any>;
}
......@@ -21,6 +22,7 @@ export class WorkspacesChannel implements IWorkspacesChannel {
call(command: string, arg?: any): TPromise<any> {
switch (command) {
case 'createWorkspace': return this.service.createWorkspace(arg);
case 'saveWorkspace': return this.service.saveWorkspace(arg[0], arg[1]);
}
return void 0;
......@@ -36,4 +38,8 @@ export class WorkspacesChannelClient implements IWorkspacesService {
createWorkspace(folders?: string[]): TPromise<IWorkspaceIdentifier> {
return this.channel.call('createWorkspace', folders);
}
saveWorkspace(workspace: IWorkspaceIdentifier, target: string): TPromise<IWorkspaceIdentifier> {
return this.channel.call('saveWorkspace', [workspace, target]);
}
}
\ No newline at end of file
......@@ -5,7 +5,7 @@
'use strict';
import { IWorkspacesMainService, IWorkspaceIdentifier, IStoredWorkspace, WORKSPACE_EXTNAME } from "vs/platform/workspaces/common/workspaces";
import { IWorkspacesMainService, IWorkspaceIdentifier, IStoredWorkspace, WORKSPACE_EXTENSION } from "vs/platform/workspaces/common/workspaces";
import { TPromise } from "vs/base/common/winjs.base";
import { isParent } from "vs/platform/files/common/files";
import { IEnvironmentService } from "vs/platform/environment/common/environment";
......@@ -13,6 +13,8 @@ import { extname, join } from "path";
import { mkdirp, writeFile } from "vs/base/node/pfs";
import { readFileSync } from "fs";
import { isLinux } from "vs/base/common/platform";
import { copy } from "vs/base/node/extfs";
import { nfcall } from "vs/base/common/async";
export class WorkspacesMainService implements IWorkspacesMainService {
......@@ -25,7 +27,7 @@ export class WorkspacesMainService implements IWorkspacesMainService {
}
public resolveWorkspaceSync(path: string): IWorkspaceIdentifier {
const isWorkspace = this.isInsideWorkspacesHome(path) || extname(path) === WORKSPACE_EXTNAME;
const isWorkspace = this.isInsideWorkspacesHome(path) || extname(path) === `.${WORKSPACE_EXTENSION}`;
if (!isWorkspace) {
return null; // does not look like a valid workspace config file
}
......@@ -78,4 +80,10 @@ export class WorkspacesMainService implements IWorkspacesMainService {
public isUntitledWorkspace(workspace: IWorkspaceIdentifier): boolean {
return this.isInsideWorkspacesHome(workspace.configPath);
}
public saveWorkspace(workspace: IWorkspaceIdentifier, target: string): TPromise<IWorkspaceIdentifier> {
return nfcall(copy, workspace.configPath, target).then(() => {
return this.resolveWorkspaceSync(target);
});
}
}
\ No newline at end of file
......@@ -8,7 +8,7 @@
import { TPromise } from 'vs/base/common/winjs.base';
import { Action } from 'vs/base/common/actions';
import nls = require('vs/nls');
import { IWindowService } from 'vs/platform/windows/common/windows';
import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows';
import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
......@@ -16,6 +16,7 @@ import URI from 'vs/base/common/uri';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IChoiceService, Severity } from "vs/platform/message/common/message";
import { IInstantiationService } from "vs/platform/instantiation/common/instantiation";
import { WORKSPACE_EXTENSION, IWorkspacesService } from "vs/platform/workspaces/common/workspaces";
export class OpenFolderAction extends Action {
......@@ -103,10 +104,7 @@ export class CreateWorkspaceAction extends Action {
id: string,
label: string,
@IWindowService private windowService: IWindowService,
@IChoiceService private choiceService: IChoiceService,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService,
@IViewletService private viewletService: IViewletService
) {
super(id, label);
}
......@@ -139,3 +137,81 @@ export class RemoveRootFolderAction extends Action {
return this.workspaceEditingService.removeRoots([this.rootUri]);
}
}
const codeWorkspaceFilter = [{ name: nls.localize('codeWorkspace', "Code Workspace"), extensions: [WORKSPACE_EXTENSION] }];
export class SaveWorkspaceAction extends Action {
static ID = 'workbench.action.saveWorkspace';
static LABEL = nls.localize('saveWorkspaceAction', "Save Workspace...");
constructor(
id: string,
label: string,
@IWindowService private windowService: IWindowService,
@IChoiceService private choiceService: IChoiceService,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IWorkspacesService private workspacesService: IWorkspacesService,
@IInstantiationService private instantiationService: IInstantiationService,
@IWindowsService private windowsService: IWindowsService
) {
super(id, label);
}
public run(): TPromise<any> {
if (!this.contextService.hasMultiFolderWorkspace()) {
return this.choiceService.choose(Severity.Info, nls.localize('notSupported2', "Saving a workspace is only possible when a workspace is opened."), [CreateWorkspaceAction.LABEL, nls.localize('cancel', "Cancel")], 1)
.then(option => {
if (option === 0) {
return this.instantiationService.createInstance(CreateWorkspaceAction, CreateWorkspaceAction.ID, CreateWorkspaceAction.LABEL).run();
}
return null;
});
}
const target = this.windowService.showSaveDialog({
buttonLabel: nls.localize('save', "Save"),
title: nls.localize('saveWorkspace', "Save Workspace"),
filters: codeWorkspaceFilter
});
if (target) {
const workspace = this.contextService.getWorkspace();
return this.workspacesService.saveWorkspace({ id: workspace.id, configPath: workspace.configuration.fsPath }, target).then(workspace => {
return this.windowsService.openWindow([workspace.configPath]);
});
}
return TPromise.as(false);
}
}
export class OpenWorkspaceAction extends Action {
static ID = 'workbench.action.openWorkspace';
static LABEL = nls.localize('openWorkspaceAction', "Open Workspace...");
constructor(
id: string,
label: string,
@IWindowService private windowService: IWindowService,
@IWindowsService private windowsService: IWindowsService
) {
super(id, label);
}
public run(): TPromise<any> {
const files = this.windowService.showOpenDialog({
buttonLabel: nls.localize('open', "Open"),
title: nls.localize('openWorkspace', "Open Workspace"),
filters: codeWorkspaceFilter,
properties: ['openFile']
});
if (!files || !files.length) {
return TPromise.as(null);
}
return this.windowsService.openWindow([files[0]]);
}
}
\ No newline at end of file
......@@ -18,7 +18,7 @@ import { CloseEditorAction, KeybindingsReferenceAction, OpenDocumentationUrlActi
import { MessagesVisibleContext } from 'vs/workbench/electron-browser/workbench';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import { registerCommands } from 'vs/workbench/electron-browser/commands';
import { AddRootFolderAction, CreateWorkspaceAction } from 'vs/workbench/browser/actions/fileActions';
import { AddRootFolderAction, CreateWorkspaceAction, OpenWorkspaceAction, SaveWorkspaceAction } from 'vs/workbench/browser/actions/fileActions';
// Contribute Commands
registerCommands();
......@@ -85,6 +85,8 @@ workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(Decrea
if (product.quality !== 'stable') {
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(CreateWorkspaceAction, CreateWorkspaceAction.ID, CreateWorkspaceAction.LABEL), 'Files: Create Workspace...', fileCategory);
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(AddRootFolderAction, AddRootFolderAction.ID, AddRootFolderAction.LABEL), 'Files: Add Folder to Workspace...', fileCategory);
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenWorkspaceAction, OpenWorkspaceAction.ID, OpenWorkspaceAction.LABEL), 'Files: Open Workspace...', fileCategory);
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(SaveWorkspaceAction, SaveWorkspaceAction.ID, SaveWorkspaceAction.LABEL), 'Files: Save Workspace...', fileCategory);
}
// Developer related actions
......
......@@ -930,6 +930,10 @@ export class TestWindowService implements IWindowService {
showSaveDialog(options: Electron.SaveDialogOptions, callback?: (fileName: string) => void): string {
return void 0;
}
showOpenDialog(options: Electron.OpenDialogOptions, callback?: (fileNames: string[]) => void): string[] {
return void 0;
}
}
export class TestLifecycleService implements ILifecycleService {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册