themes.contribution.ts 6.3 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4
/*---------------------------------------------------------------------------------------------
 *  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 已提交
5

E
Erich Gamma 已提交
6 7
'use strict';

J
Johannes Rieken 已提交
8 9 10 11 12 13 14 15 16 17
import { localize } from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base';
import { Action } from 'vs/base/common/actions';
import { firstIndex } from 'vs/base/common/arrays';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IMessageService, Severity } from 'vs/platform/message/common/message';
import { Registry } from 'vs/platform/platform';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actionRegistry';
import { IQuickOpenService, IPickOpenEntry } from 'vs/workbench/services/quickopen/common/quickOpenService';
import { IThemeService } from 'vs/workbench/services/themes/common/themeService';
18
import { VIEWLET_ID, IExtensionsViewlet } from 'vs/workbench/parts/extensions/common/extensions';
J
Johannes Rieken 已提交
19
import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
B
Benjamin Pasero 已提交
20
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewletService';
J
Johannes Rieken 已提交
21
import { Delayer } from 'vs/base/common/async';
E
Erich Gamma 已提交
22

23
class SelectColorThemeAction extends Action {
E
Erich Gamma 已提交
24

J
Joao Moreno 已提交
25 26
	static ID = 'workbench.action.selectTheme';
	static LABEL = localize('selectTheme.label', "Color Theme");
E
Erich Gamma 已提交
27 28 29 30 31 32

	constructor(
		id: string,
		label: string,
		@IQuickOpenService private quickOpenService: IQuickOpenService,
		@IMessageService private messageService: IMessageService,
J
Joao Moreno 已提交
33 34 35
		@IThemeService private themeService: IThemeService,
		@IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService,
		@IViewletService private viewletService: IViewletService
E
Erich Gamma 已提交
36 37 38 39
	) {
		super(id, label);
	}

J
Joao Moreno 已提交
40
	run(): TPromise<void> {
M
Martin Aeschlimann 已提交
41 42
		return this.themeService.getColorThemes().then(themes => {
			const currentThemeId = this.themeService.getColorTheme();
J
Joao Moreno 已提交
43
			const currentTheme = themes.filter(theme => theme.id === currentThemeId)[0];
E
Erich Gamma 已提交
44

B
Benjamin Pasero 已提交
45
			const pickInMarketPlace = findInMarketplacePick(this.viewletService, 'category:themes');
46

J
Joao Moreno 已提交
47 48 49
			const picks: IPickOpenEntry[] = themes
				.map(theme => ({ id: theme.id, label: theme.label, description: theme.description }))
				.sort((t1, t2) => t1.label.localeCompare(t2.label));
E
Erich Gamma 已提交
50

J
Joao Moreno 已提交
51
			const selectTheme = (theme, broadcast) => {
52 53 54
				if (theme === pickInMarketPlace) {
					theme = currentTheme;
				}
M
Martin Aeschlimann 已提交
55
				this.themeService.setColorTheme(theme.id, broadcast)
56
					.done(null, err => this.messageService.show(Severity.Info, localize('problemChangingTheme', "Problem loading theme: {0}", err)));
J
Joao Moreno 已提交
57
			};
E
Erich Gamma 已提交
58

J
Joao Moreno 已提交
59 60 61
			const placeHolder = localize('themes.selectTheme', "Select Color Theme");
			const autoFocusIndex = firstIndex(picks, p => p.id === currentThemeId);
			const delayer = new Delayer<void>(100);
E
Erich Gamma 已提交
62

J
Joao Moreno 已提交
63
			if (this.extensionGalleryService.isEnabled()) {
64
				picks.push(pickInMarketPlace);
J
Joao Moreno 已提交
65
			}
E
Erich Gamma 已提交
66

B
Benjamin Pasero 已提交
67
			return this.quickOpenService.pick(picks, { placeHolder, autoFocus: { autoFocusIndex } })
J
Joao Moreno 已提交
68
				.then(
B
Benjamin Pasero 已提交
69 70 71
				theme => delayer.trigger(() => selectTheme(theme || currentTheme, true), 0),
				null,
				theme => delayer.trigger(() => selectTheme(theme, false))
J
Johannes Rieken 已提交
72
				);
E
Erich Gamma 已提交
73 74 75 76
		});
	}
}

77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
class SelectIconThemeAction extends Action {

	static ID = 'workbench.action.selectIconTheme';
	static LABEL = localize('selectIconTheme.label', "File Icon Theme");

	constructor(
		id: string,
		label: string,
		@IQuickOpenService private quickOpenService: IQuickOpenService,
		@IMessageService private messageService: IMessageService,
		@IThemeService private themeService: IThemeService,
		@IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService,
		@IViewletService private viewletService: IViewletService
	) {
		super(id, label);
	}

	run(): TPromise<void> {
		return this.themeService.getFileIconThemes().then(themes => {
			const currentThemeId = this.themeService.getFileIconTheme();
			const currentTheme = themes.filter(theme => theme.id === currentThemeId)[0];

99
			const pickInMarketPlace = findInMarketplacePick(this.viewletService, 'tag:icon-theme');
100

101 102 103 104 105 106 107
			const picks: IPickOpenEntry[] = themes
				.map(theme => ({ id: theme.id, label: theme.label, description: theme.description }))
				.sort((t1, t2) => t1.label.localeCompare(t2.label));

			picks.splice(0, 0, { id: '', label: localize('noIconThemeLabel', 'None'), description: localize('noIconThemeDesc', 'Disable file icons') });

			const selectTheme = (theme, broadcast) => {
108 109 110
				if (theme === pickInMarketPlace) {
					theme = currentTheme;
				}
111 112 113 114 115 116 117 118
				this.themeService.setFileIconTheme(theme && theme.id, broadcast)
					.done(null, err => this.messageService.show(Severity.Info, localize('problemChangingIconTheme', "Problem loading icon theme: {0}", err.message)));
			};

			const placeHolder = localize('themes.selectIconTheme', "Select File Icon Theme");
			const autoFocusIndex = firstIndex(picks, p => p.id === currentThemeId);
			const delayer = new Delayer<void>(100);

119 120 121 122

			if (this.extensionGalleryService.isEnabled()) {
				picks.push(pickInMarketPlace);
			}
123

B
Benjamin Pasero 已提交
124
			return this.quickOpenService.pick(picks, { placeHolder, autoFocus: { autoFocusIndex } })
125
				.then(
B
Benjamin Pasero 已提交
126 127 128
				theme => delayer.trigger(() => selectTheme(theme || currentTheme, true), 0),
				null,
				theme => delayer.trigger(() => selectTheme(theme, false))
129 130 131 132 133
				);
		});
	}
}

134 135 136 137 138 139 140 141 142 143 144 145 146
function findInMarketplacePick(viewletService: IViewletService, query: string) {
	return {
		id: 'themes.findmore',
		label: localize('findMore', "Find more in the Marketplace..."),
		separator: { border: true },
		alwaysShow: true,
		run: () => viewletService.openViewlet(VIEWLET_ID, true).then(viewlet => {
			(<IExtensionsViewlet>viewlet).search(query);
			viewlet.focus();
		})
	};
}

J
Joao Moreno 已提交
147
const category = localize('preferences', "Preferences");
148 149 150 151 152 153

const colorThemeDescriptor = new SyncActionDescriptor(SelectColorThemeAction, SelectColorThemeAction.ID, SelectColorThemeAction.LABEL);
Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions).registerWorkbenchAction(colorThemeDescriptor, 'Preferences: Color Theme', category);

const iconThemeDescriptor = new SyncActionDescriptor(SelectIconThemeAction, SelectIconThemeAction.ID, SelectIconThemeAction.LABEL);
Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions).registerWorkbenchAction(iconThemeDescriptor, 'Preferences: File Icon Theme', category);