workspaceActions.ts 9.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

'use strict';

import { TPromise } from 'vs/base/common/winjs.base';
import { Action } from 'vs/base/common/actions';
import nls = require('vs/nls');
S
Sandeep Somavarapu 已提交
11
import { distinct } from 'vs/base/common/arrays';
12
import { IWindowService } from 'vs/platform/windows/common/windows';
13
import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
14
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
B
Benjamin Pasero 已提交
15 16 17
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import URI from 'vs/base/common/uri';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
B
Benjamin Pasero 已提交
18
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
19
import { WORKSPACE_FILTER } from 'vs/platform/workspaces/common/workspaces';
B
Benjamin Pasero 已提交
20 21 22 23
import { IMessageService, Severity } from 'vs/platform/message/common/message';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { isLinux } from 'vs/base/common/platform';
import { dirname } from 'vs/base/common/paths';
24
import { mnemonicButtonLabel } from 'vs/base/common/labels';
B
Benjamin Pasero 已提交
25 26
import { isParent } from 'vs/platform/files/common/files';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
27 28 29 30 31 32 33 34 35 36 37 38 39 40

export class OpenFolderAction extends Action {

	static ID = 'workbench.action.files.openFolder';
	static LABEL = nls.localize('openFolder', "Open Folder...");

	constructor(
		id: string,
		label: string,
		@IWindowService private windowService: IWindowService
	) {
		super(id, label);
	}

41
	run(event?: any, data?: ITelemetryData): TPromise<any> {
B
Benjamin Pasero 已提交
42
		return this.windowService.pickFolderAndOpen({ telemetryExtraData: data });
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
	}
}

export class OpenFileFolderAction extends Action {

	static ID = 'workbench.action.files.openFileFolder';
	static LABEL = nls.localize('openFileFolder', "Open...");

	constructor(
		id: string,
		label: string,
		@IWindowService private windowService: IWindowService
	) {
		super(id, label);
	}

59
	run(event?: any, data?: ITelemetryData): TPromise<any> {
B
Benjamin Pasero 已提交
60
		return this.windowService.pickFileFolderAndOpen({ telemetryExtraData: data });
61
	}
B
Benjamin Pasero 已提交
62 63
}

B
Benjamin Pasero 已提交
64
export abstract class BaseWorkspacesAction extends Action {
B
Benjamin Pasero 已提交
65 66 67 68 69

	constructor(
		id: string,
		label: string,
		protected windowService: IWindowService,
B
Benjamin Pasero 已提交
70 71
		protected environmentService: IEnvironmentService,
		protected contextService: IWorkspaceContextService
B
Benjamin Pasero 已提交
72 73 74 75
	) {
		super(id, label);
	}

B
Benjamin Pasero 已提交
76
	protected pickFolders(buttonLabel: string, title: string): string[] {
77
		let defaultPath: string;
78
		const workspace = this.contextService.getWorkspace();
S
Sandeep Somavarapu 已提交
79
		if (workspace.folders.length > 0) {
80
			defaultPath = dirname(workspace.folders[0].uri.fsPath); // pick the parent of the first root by default
81 82
		}

B
Benjamin Pasero 已提交
83
		return this.windowService.showOpenDialog({
B
Benjamin Pasero 已提交
84 85
			buttonLabel,
			title,
B
Benjamin Pasero 已提交
86
			properties: ['multiSelections', 'openDirectory', 'createDirectory'],
87
			defaultPath
B
Benjamin Pasero 已提交
88 89
		});
	}
B
Benjamin Pasero 已提交
90 91
}

B
Benjamin Pasero 已提交
92
export class AddRootFolderAction extends BaseWorkspacesAction {
B
Benjamin Pasero 已提交
93

B
Benjamin Pasero 已提交
94 95
	static ID = 'workbench.action.addRootFolder';
	static LABEL = nls.localize('addFolderToWorkspace', "Add Folder to Workspace...");
B
Benjamin Pasero 已提交
96 97 98 99

	constructor(
		id: string,
		label: string,
B
Benjamin Pasero 已提交
100
		@IWindowService windowService: IWindowService,
B
Benjamin Pasero 已提交
101
		@IWorkspaceContextService contextService: IWorkspaceContextService,
S
Sandeep Somavarapu 已提交
102
		@IEnvironmentService environmentService: IEnvironmentService,
B
Benjamin Pasero 已提交
103 104 105
		@IInstantiationService private instantiationService: IInstantiationService,
		@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService,
		@IViewletService private viewletService: IViewletService
B
Benjamin Pasero 已提交
106
	) {
S
Sandeep Somavarapu 已提交
107
		super(id, label, windowService, environmentService, contextService);
B
Benjamin Pasero 已提交
108 109 110
	}

	public run(): TPromise<any> {
111 112 113
		let addFoldersPromise: TPromise<void>;

		// Workspace
114 115 116 117 118
		if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
			const folders = super.pickFolders(mnemonicButtonLabel(nls.localize({ key: 'add', comment: ['&& denotes a mnemonic'] }, "&&Add")), nls.localize('addFolderToWorkspaceTitle', "Add Folder to Workspace"));
			if (!folders || !folders.length) {
				return TPromise.as(null);
			}
119

120 121 122 123 124 125
			addFoldersPromise = this.workspaceEditingService.addFolders(folders.map(folder => URI.file(folder)));
		}

		// Empty or Folder
		else {
			addFoldersPromise = this.instantiationService.createInstance(NewWorkspaceAction, NewWorkspaceAction.ID, NewWorkspaceAction.LABEL, this.contextService.getWorkspace().folders.map(folder => folder.uri)).run();
B
Benjamin Pasero 已提交
126
		}
127

128 129
		// Add and show Files Explorer viewlet
		return addFoldersPromise.then(() => this.viewletService.openViewlet(this.viewletService.getDefaultViewletId(), true));
S
Sandeep Somavarapu 已提交
130
	}
B
Benjamin Pasero 已提交
131
}
S
Sandeep Somavarapu 已提交
132

133
class NewWorkspaceAction extends BaseWorkspacesAction {
B
Benjamin Pasero 已提交
134 135 136 137 138 139 140

	static ID = 'workbench.action.newWorkspace';
	static LABEL = nls.localize('newWorkspace', "New Workspace...");

	constructor(
		id: string,
		label: string,
141
		private presetRoots: URI[],
B
Benjamin Pasero 已提交
142 143
		@IWindowService windowService: IWindowService,
		@IWorkspaceContextService contextService: IWorkspaceContextService,
S
Sandeep Somavarapu 已提交
144
		@IEnvironmentService environmentService: IEnvironmentService,
145
		@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService
146
	) {
S
Sandeep Somavarapu 已提交
147
		super(id, label, windowService, environmentService, contextService);
148 149
	}

S
Sandeep Somavarapu 已提交
150
	public run(): TPromise<any> {
151
		const folders = super.pickFolders(mnemonicButtonLabel(nls.localize({ key: 'select', comment: ['&& denotes a mnemonic'] }, "&&Select")), nls.localize('selectWorkspace', "Select Folders for Workspace"));
152
		if (folders && folders.length) {
153
			return this.createWorkspace([...this.presetRoots, ...folders.map(folder => URI.file(folder))]);
B
Benjamin Pasero 已提交
154
		}
B
Benjamin Pasero 已提交
155

B
Benjamin Pasero 已提交
156 157
		return TPromise.as(null);
	}
S
Sandeep Somavarapu 已提交
158

B
Benjamin Pasero 已提交
159
	private createWorkspace(folders: URI[]): TPromise<void> {
160
		const workspaceFolders = distinct(folders.map(folder => folder.fsPath), folder => isLinux ? folder : folder.toLowerCase());
161

162
		return this.workspaceEditingService.createAndEnterWorkspace(workspaceFolders);
163 164 165
	}
}

I
isidor 已提交
166
export class RemoveRootFolderAction extends Action {
B
Benjamin Pasero 已提交
167

I
isidor 已提交
168
	static ID = 'workbench.action.removeRootFolder';
169
	static LABEL = nls.localize('removeFolderFromWorkspace', "Remove Folder from Workspace");
B
Benjamin Pasero 已提交
170 171

	constructor(
I
isidor 已提交
172
		private rootUri: URI,
B
Benjamin Pasero 已提交
173 174 175 176 177 178 179 180
		id: string,
		label: string,
		@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService
	) {
		super(id, label);
	}

	public run(): TPromise<any> {
S
Sandeep Somavarapu 已提交
181
		return this.workspaceEditingService.removeFolders([this.rootUri]);
B
Benjamin Pasero 已提交
182
	}
I
isidor 已提交
183
}
184

185
export class SaveWorkspaceAsAction extends BaseWorkspacesAction {
186

187 188
	static ID = 'workbench.action.saveWorkspaceAs';
	static LABEL = nls.localize('saveWorkspaceAsAction', "Save Workspace As...");
189 190 191 192

	constructor(
		id: string,
		label: string,
B
Benjamin Pasero 已提交
193 194
		@IWindowService windowService: IWindowService,
		@IEnvironmentService environmentService: IEnvironmentService,
B
Benjamin Pasero 已提交
195
		@IWorkspaceContextService contextService: IWorkspaceContextService,
196 197
		@IMessageService private messageService: IMessageService,
		@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService
198
	) {
S
Sandeep Somavarapu 已提交
199
		super(id, label, windowService, environmentService, contextService);
200 201 202
	}

	public run(): TPromise<any> {
203 204
		const workspaceState = this.contextService.getWorkbenchState();
		if (workspaceState === WorkbenchState.EMPTY) {
S
Sandeep Somavarapu 已提交
205
			this.messageService.show(Severity.Info, nls.localize('saveEmptyWorkspaceNotSupported', "Please open a workspace first to save."));
206

S
Sandeep Somavarapu 已提交
207
			return TPromise.as(null);
S
Sandeep Somavarapu 已提交
208 209
		}

S
Sandeep Somavarapu 已提交
210 211
		const configPath = this.getNewWorkspaceConfigPath();
		if (configPath) {
212
			switch (workspaceState) {
213

214
				case WorkbenchState.FOLDER:
215
					const workspaceFolders = this.contextService.getWorkspace().folders.map(root => root.uri.fsPath);
216
					return this.workspaceEditingService.createAndEnterWorkspace(workspaceFolders, configPath);
217

218
				case WorkbenchState.WORKSPACE:
219
					return this.workspaceEditingService.saveAndEnterWorkspace(configPath);
S
Sandeep Somavarapu 已提交
220 221
			}
		}
S
Sandeep Somavarapu 已提交
222

S
Sandeep Somavarapu 已提交
223 224 225
		return TPromise.as(null);
	}

226
	private getNewWorkspaceConfigPath(): string {
B
Benjamin Pasero 已提交
227 228
		const workspace = this.contextService.getWorkspace();
		let defaultPath: string;
229
		if (workspace.configuration && !this.isUntitledWorkspace(workspace.configuration.fsPath)) {
B
Benjamin Pasero 已提交
230
			defaultPath = workspace.configuration.fsPath;
S
Sandeep Somavarapu 已提交
231
		} else if (workspace.folders.length > 0) {
232
			defaultPath = dirname(workspace.folders[0].uri.fsPath); // pick the parent of the first root by default
B
Benjamin Pasero 已提交
233 234
		}

S
Sandeep Somavarapu 已提交
235
		return this.windowService.showSaveDialog({
236
			buttonLabel: mnemonicButtonLabel(nls.localize({ key: 'save', comment: ['&& denotes a mnemonic'] }, "&&Save")),
S
Sandeep Somavarapu 已提交
237 238
			title: nls.localize('saveWorkspace', "Save Workspace"),
			filters: WORKSPACE_FILTER,
B
Benjamin Pasero 已提交
239
			defaultPath
S
Sandeep Somavarapu 已提交
240
		});
241
	}
B
Benjamin Pasero 已提交
242 243 244 245

	private isUntitledWorkspace(path: string): boolean {
		return isParent(path, this.environmentService.workspacesHome, !isLinux /* ignore case */);
	}
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
}

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,
	) {
		super(id, label);
	}

	public run(): TPromise<any> {
262
		return this.windowService.openWorkspace();
263
	}
264 265
}

266 267 268 269 270 271 272 273 274 275 276 277
export class OpenWorkspaceConfigFileAction extends Action {

	public static ID = 'workbench.action.openWorkspaceConfigFile';
	public static LABEL = nls.localize('openWorkspaceConfigFile', "Open Workspace Configuration File");

	constructor(
		id: string,
		label: string,
		@IWorkspaceContextService private workspaceContextService: IWorkspaceContextService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService
	) {
		super(id, label);
B
Benjamin Pasero 已提交
278

279
		this.enabled = !!this.workspaceContextService.getWorkspace().configuration;
280 281 282 283 284
	}

	public run(): TPromise<any> {
		return this.editorService.openEditor({ resource: this.workspaceContextService.getWorkspace().configuration });
	}
285
}