extensionsActions.ts 8.3 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

J
Joao Moreno 已提交
6
import 'vs/css!./media/extensionActions';
J
Joao Moreno 已提交
7
import { localize } from 'vs/nls';
J
Joao Moreno 已提交
8
import { TPromise } from 'vs/base/common/winjs.base';
E
Erich Gamma 已提交
9
import { Action } from 'vs/base/common/actions';
J
Joao Moreno 已提交
10
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
J
Joao Moreno 已提交
11
import { ReloadWindowAction } from 'vs/workbench/electron-browser/actions';
12
import { IExtension, ExtensionState, IExtensionsWorkbenchService, VIEWLET_ID, IExtensionsViewlet } from './extensions';
13
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
14 15 16
import { ToggleViewletAction } from 'vs/workbench/browser/viewlet';
import { IViewletService } from 'vs/workbench/services/viewlet/common/viewletService';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
J
Joao Moreno 已提交
17

18 19
export class InstallAction extends Action {

J
Joao Moreno 已提交
20 21
	private static InstallLabel = localize('installAction', "Install");
	private static InstallingLabel = localize('installing', "Installing");
J
Joao Moreno 已提交
22
	private disposables: IDisposable[] = [];
23

24 25 26 27
	constructor(
		private extension: IExtension,
		@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
	) {
J
Joao Moreno 已提交
28
		super('extensions.install', InstallAction.InstallLabel, 'extension-action install', false);
29

30
		this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update()));
J
Joao Moreno 已提交
31
		this.update();
32 33
	}

J
Joao Moreno 已提交
34
	private update(): void {
35
		this.enabled = this.extensionsWorkbenchService.canInstall(this.extension) && this.extension.state === ExtensionState.Uninstalled;
J
Joao Moreno 已提交
36
		this.label = this.extension.state === ExtensionState.Installing ? InstallAction.InstallingLabel : InstallAction.InstallLabel;
37 38
	}

J
Joao Moreno 已提交
39
	run(): TPromise<any> {
40
		return this.extensionsWorkbenchService.install(this.extension);
41 42
	}

J
Joao Moreno 已提交
43 44 45
	dispose(): void {
		super.dispose();
		this.disposables = dispose(this.disposables);
46 47
	}
}
J
Joao Moreno 已提交
48

J
Joao Moreno 已提交
49
export class UninstallAction extends Action {
J
Joao Moreno 已提交
50

J
Joao Moreno 已提交
51
	private disposables: IDisposable[] = [];
J
Joao Moreno 已提交
52

53 54 55 56
	constructor(
		private extension: IExtension,
		@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
	) {
J
Joao Moreno 已提交
57
		super('extensions.uninstall', localize('uninstall', "Uninstall"), 'extension-action uninstall', false);
J
Joao Moreno 已提交
58

59
		this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.updateEnablement()));
J
Joao Moreno 已提交
60 61
		this.updateEnablement();
	}
J
Joao Moreno 已提交
62

J
Joao Moreno 已提交
63
	private updateEnablement(): void {
J
Joao Moreno 已提交
64 65
		this.enabled = this.extension.state === ExtensionState.Installed
			|| this.extension.state === ExtensionState.NeedsRestart;
J
Joao Moreno 已提交
66
	}
J
Joao Moreno 已提交
67

J
Joao Moreno 已提交
68
	run(): TPromise<any> {
J
Joao Moreno 已提交
69
		if (!window.confirm(localize('deleteSure', "Are you sure you want to uninstall '{0}'?", this.extension.displayName))) {
J
Joao Moreno 已提交
70 71
			return TPromise.as(null);
		}
J
Joao Moreno 已提交
72

73
		return this.extensionsWorkbenchService.uninstall(this.extension);
J
Joao Moreno 已提交
74
	}
J
Joao Moreno 已提交
75

J
Joao Moreno 已提交
76 77 78 79 80
	dispose(): void {
		super.dispose();
		this.disposables = dispose(this.disposables);
	}
}
J
Joao Moreno 已提交
81 82 83 84 85 86 87

export class CombinedInstallAction extends Action {

	private installAction: InstallAction;
	private uninstallAction: UninstallAction;
	private disposables: IDisposable[] = [];

88 89 90 91
	constructor(
		private extension: IExtension,
		@IInstantiationService instantiationService: IInstantiationService
	) {
J
Joao Moreno 已提交
92 93
		super('extensions.combinedInstall', '', '', false);

94 95
		this.installAction = instantiationService.createInstance(InstallAction, extension);
		this.uninstallAction = instantiationService.createInstance(UninstallAction, extension);
J
Joao Moreno 已提交
96 97 98
		this.disposables.push(this.installAction, this.uninstallAction);

		this.disposables.push(this.installAction.addListener2(Action.ENABLED, () => this.update()));
J
Joao Moreno 已提交
99
		this.disposables.push(this.installAction.addListener2(Action.LABEL, () => this.update()));
J
Joao Moreno 已提交
100 101 102 103 104 105 106 107 108 109 110 111 112
		this.disposables.push(this.uninstallAction.addListener2(Action.ENABLED, () => this.update()));
		this.update();
	}

	private update(): void {
		if (this.installAction.enabled) {
			this.enabled = true;
			this.label = this.installAction.label;
			this.class = this.installAction.class;
		} else if (this.uninstallAction.enabled) {
			this.enabled = true;
			this.label = this.uninstallAction.label;
			this.class = this.uninstallAction.class;
J
Joao Moreno 已提交
113 114 115 116
		} else if (this.extension.state === ExtensionState.Installing) {
			this.enabled = false;
			this.label = this.installAction.label;
			this.class = this.installAction.class;
J
Joao Moreno 已提交
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
		} else {
			this.enabled = false;
		}
	}

	run(): TPromise<any> {
		if (this.installAction.enabled) {
			return this.installAction.run();
		} else if (this.uninstallAction.enabled) {
			return this.uninstallAction.run();
		}

		return TPromise.as(null);
	}

J
Joao Moreno 已提交
132 133 134 135 136 137 138 139
	dispose(): void {
		super.dispose();
		this.disposables = dispose(this.disposables);
	}
}

export class UpdateAction extends Action {

J
Joao Moreno 已提交
140
	private static EnabledClass = 'extension-action update';
J
Joao Moreno 已提交
141 142 143 144
	private static DisabledClass = `${ UpdateAction.EnabledClass } disabled`;

	private disposables: IDisposable[] = [];

145 146 147 148
	constructor(
		private extension: IExtension,
		@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
	) {
J
Joao Moreno 已提交
149
		super('extensions.update', localize('updateAction', "Update"), UpdateAction.DisabledClass, false);
J
Joao Moreno 已提交
150

151
		this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.updateEnablement()));
J
Joao Moreno 已提交
152 153 154 155
		this.updateEnablement();
	}

	private updateEnablement(): void {
156
		const canInstall = this.extensionsWorkbenchService.canInstall(this.extension);
J
Joao Moreno 已提交
157 158
		const isInstalled = this.extension.state === ExtensionState.Installed
			|| this.extension.state === ExtensionState.NeedsRestart;
J
Joao Moreno 已提交
159

J
Joao Moreno 已提交
160
		this.enabled = canInstall && isInstalled && this.extension.outdated;
J
Joao Moreno 已提交
161 162 163 164
		this.class = this.enabled ? UpdateAction.EnabledClass : UpdateAction.DisabledClass;
	}

	run(): TPromise<any> {
165
		return this.extensionsWorkbenchService.install(this.extension);
J
Joao Moreno 已提交
166 167
	}

J
Joao Moreno 已提交
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
	dispose(): void {
		super.dispose();
		this.disposables = dispose(this.disposables);
	}
}

export class EnableAction extends Action {

	private static EnabledClass = 'extension-action enable';
	private static DisabledClass = `${ EnableAction.EnabledClass } disabled`;

	private disposables: IDisposable[] = [];

	constructor(
		private extension: IExtension,
		@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
		@IInstantiationService private instantiationService: IInstantiationService
	) {
		super('extensions.enable', localize('enableAction', "Enable"), EnableAction.DisabledClass, false);

		this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.updateEnablement()));
		this.updateEnablement();
	}

	private updateEnablement(): void {
		this.enabled = this.extension.state === ExtensionState.NeedsRestart;
		this.class = this.enabled ? EnableAction.EnabledClass : EnableAction.DisabledClass;
	}

	run(): TPromise<any> {
		if (!window.confirm(localize('restart', "In order to enable this extension, this window of VS Code needs to be restarted.\n\nDo you want to continue?"))) {
			return TPromise.as(null);
		}

		const action = this.instantiationService.createInstance(ReloadWindowAction, ReloadWindowAction.ID, localize('restartNow', "Restart Now"));
		return action.run();
	}

J
Joao Moreno 已提交
206 207 208 209
	dispose(): void {
		super.dispose();
		this.disposables = dispose(this.disposables);
	}
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
}

export class OpenExtensionsViewletAction extends ToggleViewletAction {

	static ID = 'workbench.extensions.showViewlet';
	static LABEL = localize('toggleExtensionsViewlet', "Show Extensions");

	constructor(
		id: string,
		label: string,
		@IViewletService viewletService: IViewletService,
		@IWorkbenchEditorService editorService: IWorkbenchEditorService
	) {
		super(id, label, VIEWLET_ID, viewletService, editorService);
	}
}

export class ListOutdatedExtensionsAction extends Action {

	static ID = 'workbench.extensions.action.listOutdatedExtensions';
	static LABEL = localize('showOutdatedExtensions', "Show Outdated Extensions");

	constructor(
		id: string,
		label: string,
		@IViewletService private viewletService: IViewletService
	) {
		super(id, label, null, true);
	}

	run(): TPromise<void> {

		return this.viewletService.openViewlet(VIEWLET_ID, true)
			.then(viewlet => viewlet as IExtensionsViewlet)
			.then(viewlet => {
				viewlet.search('@outdated', true);
				viewlet.focus();
			});
	}

	protected isEnabled(): boolean {
		return true;
	}
}