提交 dbce60b0 编写于 作者: S Sandeep Somavarapu

Fix #68408

上级 ebf55c18
......@@ -28,7 +28,7 @@ import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, IExtension
import { RatingsWidget, InstallCountWidget, RemoteBadgeWidget } from 'vs/workbench/contrib/extensions/electron-browser/extensionsWidgets';
import { EditorOptions } from 'vs/workbench/common/editor';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { CombinedInstallAction, UpdateAction, ExtensionEditorDropDownAction, ReloadAction, MaliciousStatusLabelAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction, EnableDropDownAction, DisableDropDownAction, StatusLabelAction } from 'vs/workbench/contrib/extensions/electron-browser/extensionsActions';
import { CombinedInstallAction, UpdateAction, ExtensionEditorDropDownAction, ReloadAction, MaliciousStatusLabelAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction, EnableDropDownAction, DisableDropDownAction, StatusLabelAction, SetFileIconThemeAction, SetColorThemeAction } from 'vs/workbench/contrib/extensions/electron-browser/extensionsActions';
import { WebviewElement } from 'vs/workbench/contrib/webview/electron-browser/webviewElement';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
......@@ -367,6 +367,8 @@ export class ExtensionEditor extends BaseEditor {
reloadAction,
this.instantiationService.createInstance(StatusLabelAction),
this.instantiationService.createInstance(UpdateAction),
this.instantiationService.createInstance(SetColorThemeAction),
this.instantiationService.createInstance(SetFileIconThemeAction),
this.instantiationService.createInstance(EnableDropDownAction),
this.instantiationService.createInstance(DisableDropDownAction, runningExtensions),
this.instantiationService.createInstance(CombinedInstallAction),
......
......@@ -55,7 +55,7 @@ import { clipboard } from 'electron';
import { IPartService } from 'vs/workbench/services/part/common/partService';
import { alert } from 'vs/base/browser/ui/aria/aria';
import { coalesce } from 'vs/base/common/arrays';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { IWorkbenchThemeService, COLOR_THEME_SETTING } from 'vs/workbench/services/themes/common/workbenchThemeService';
function toExtensionDescription(local: ILocalExtension): IExtensionDescription {
return {
......@@ -147,7 +147,6 @@ export class InstallAction extends ExtensionAction {
@IInstantiationService private readonly instantiationService: IInstantiationService,
@INotificationService private readonly notificationService: INotificationService,
@IOpenerService private readonly openerService: IOpenerService,
@IQuickInputService private readonly quickInputService: IQuickInputService,
@IExtensionService private readonly runtimeExtensionService: IExtensionService,
@IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService
) {
......@@ -183,8 +182,22 @@ export class InstallAction extends ExtensionAction {
const extension = await this.install(this.extension);
if (extension.local && extension.local.manifest.contributes && extension.local.manifest.contributes.themes && extension.local.manifest.contributes.themes.length) {
return this.applyInstalledTheme(extension.local);
if (extension.local) {
const runningExtension = await this.getRunningExtension(extension.local);
if (runningExtension) {
const colorThemes = await this.workbenchThemeService.getColorThemes(runningExtension.identifier);
const fileIconThemes = await this.workbenchThemeService.getFileIconThemes(runningExtension.identifier);
if (colorThemes.length && !fileIconThemes.length) {
const action = this.instantiationService.createInstance(SetColorThemeAction);
action.extension = extension;
return action.run(true);
}
if (!colorThemes.length && fileIconThemes.length) {
const action = this.instantiationService.createInstance(SetFileIconThemeAction);
action.extension = extension;
return action.run(true);
}
}
}
}
......@@ -202,25 +215,6 @@ export class InstallAction extends ExtensionAction {
});
}
private async applyInstalledTheme(extension: ILocalExtension): Promise<void> {
const runningExtension = await this.getRunningExtension(extension);
if (runningExtension) {
const currentTheme = this.workbenchThemeService.getColorTheme();
const themes = await this.workbenchThemeService.getColorThemes(runningExtension.identifier);
const delayer = new Delayer<void>(100);
const picks: (IQuickPickItem | IQuickPickSeparator)[] = themes.map(theme => (<IQuickPickItem>{ label: theme.label, id: theme.id }));
picks.push(<IQuickPickSeparator>{ type: 'separator' });
picks.push(<IQuickPickItem>{ label: localize('stay with current theme', "Stay with current theme ({0})", currentTheme.label), id: currentTheme.id });
const pickedTheme = await this.quickInputService.pick(
picks,
{
placeHolder: localize('apply installed theme', "Apply installed theme or press Escape to cancel."),
onDidFocus: item => delayer.trigger(() => this.workbenchThemeService.setColorTheme(item.id, ConfigurationTarget.MEMORY).then(() => undefined))
});
this.workbenchThemeService.setColorTheme(pickedTheme ? pickedTheme.id : currentTheme.id, undefined);
}
}
private async getRunningExtension(extension: ILocalExtension): Promise<IExtensionDescription | null> {
const runningExtension = await this.runtimeExtensionService.getExtension(extension.identifier.id);
if (runningExtension) {
......@@ -1111,6 +1105,138 @@ export class ReloadAction extends ExtensionAction {
}
}
export class SetColorThemeAction extends ExtensionAction {
private static readonly EnabledClass = 'extension-action theme';
private static readonly DisabledClass = `${SetColorThemeAction.EnabledClass} disabled`;
private disposables: IDisposable[] = [];
constructor(
@IExtensionService extensionService: IExtensionService,
@IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService,
@IQuickInputService private readonly quickInputService: IQuickInputService,
@IConfigurationService private readonly configurationService: IConfigurationService
) {
super(`extensions.colorTheme`, localize('color theme', "Set Color Theme"), SetColorThemeAction.DisabledClass, false);
Event.any<any>(extensionService.onDidChangeExtensions, workbenchThemeService.onDidColorThemeChange)(() => this.update(), this, this.disposables);
this.update();
}
async update(): Promise<void> {
this.enabled = false;
if (this.extension) {
const isInstalled = this.extension.state === ExtensionState.Installed;
if (isInstalled) {
const colorThemes = await this.workbenchThemeService.getColorThemes(new ExtensionIdentifier(this.extension.identifier.id));
this.enabled = colorThemes.length > 0;
}
}
this.class = this.enabled ? SetColorThemeAction.EnabledClass : SetColorThemeAction.DisabledClass;
}
async run(showCurrentTheme: boolean): Promise<any> {
await this.update();
if (!this.enabled) {
return;
}
let colorThemes = await this.workbenchThemeService.getColorThemes(new ExtensionIdentifier(this.extension.identifier.id));
const currentTheme = this.workbenchThemeService.getColorTheme();
showCurrentTheme = showCurrentTheme || colorThemes.some(t => t.id === currentTheme.id);
if (showCurrentTheme) {
colorThemes = colorThemes.filter(t => t.id !== currentTheme.id);
}
const delayer = new Delayer<any>(100);
const picks: (IQuickPickItem | IQuickPickSeparator)[] = [];
picks.push(...colorThemes.map(theme => (<IQuickPickItem>{ label: theme.label, id: theme.id })));
if (showCurrentTheme) {
picks.push(<IQuickPickSeparator>{ type: 'separator', label: localize('current', "Current") });
picks.push(<IQuickPickItem>{ label: currentTheme.label, id: currentTheme.id });
}
const pickedTheme = await this.quickInputService.pick(
picks,
{
placeHolder: localize('select color theme', "Select Color Theme"),
onDidFocus: item => delayer.trigger(() => this.workbenchThemeService.setColorTheme(item.id, undefined))
});
let confValue = this.configurationService.inspect(COLOR_THEME_SETTING);
const target = typeof confValue.workspace !== 'undefined' ? ConfigurationTarget.WORKSPACE : ConfigurationTarget.USER;
return this.workbenchThemeService.setColorTheme(pickedTheme ? pickedTheme.id : currentTheme.id, target);
}
dispose() {
this.disposables = dispose(this.disposables);
super.dispose();
}
}
export class SetFileIconThemeAction extends ExtensionAction {
private static readonly EnabledClass = 'extension-action theme';
private static readonly DisabledClass = `${SetFileIconThemeAction.EnabledClass} disabled`;
private disposables: IDisposable[] = [];
constructor(
@IExtensionService extensionService: IExtensionService,
@IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService,
@IQuickInputService private readonly quickInputService: IQuickInputService,
@IConfigurationService private readonly configurationService: IConfigurationService
) {
super(`extensions.fileIconTheme`, localize('file icon theme', "Set File Icon Theme"), SetFileIconThemeAction.DisabledClass, false);
Event.any<any>(extensionService.onDidChangeExtensions, workbenchThemeService.onDidFileIconThemeChange)(() => this.update(), this, this.disposables);
this.update();
}
async update(): Promise<void> {
this.enabled = false;
if (this.extension) {
const isInstalled = this.extension.state === ExtensionState.Installed;
if (isInstalled) {
const fileIconThemes = await this.workbenchThemeService.getFileIconThemes(new ExtensionIdentifier(this.extension.identifier.id));
this.enabled = fileIconThemes.length > 0;
}
}
this.class = this.enabled ? SetFileIconThemeAction.EnabledClass : SetFileIconThemeAction.DisabledClass;
}
async run(showCurrentTheme: boolean): Promise<any> {
await this.update();
if (!this.enabled) {
return;
}
let fileIconThemes = await this.workbenchThemeService.getFileIconThemes(new ExtensionIdentifier(this.extension.identifier.id));
const currentTheme = this.workbenchThemeService.getFileIconTheme();
showCurrentTheme = showCurrentTheme || fileIconThemes.some(t => t.id === currentTheme.id);
if (showCurrentTheme) {
fileIconThemes = fileIconThemes.filter(t => t.id !== currentTheme.id);
}
const delayer = new Delayer<any>(100);
const picks: (IQuickPickItem | IQuickPickSeparator)[] = [];
picks.push(...fileIconThemes.map(theme => (<IQuickPickItem>{ label: theme.label, id: theme.id })));
if (showCurrentTheme) {
picks.push(<IQuickPickSeparator>{ type: 'separator', label: localize('current', "Current") });
picks.push(<IQuickPickItem>{ label: currentTheme.label, id: currentTheme.id });
}
const pickedTheme = await this.quickInputService.pick(
picks,
{
placeHolder: localize('select file icon theme', "Select File Icon Theme"),
onDidFocus: item => delayer.trigger(() => this.workbenchThemeService.setFileIconTheme(item.id, undefined))
});
let confValue = this.configurationService.inspect(COLOR_THEME_SETTING);
const target = typeof confValue.workspace !== 'undefined' ? ConfigurationTarget.WORKSPACE : ConfigurationTarget.USER;
return this.workbenchThemeService.setFileIconTheme(pickedTheme ? pickedTheme.id : currentTheme.id, target);
}
dispose() {
this.disposables = dispose(this.disposables);
super.dispose();
}
}
export class OpenExtensionsViewletAction extends ShowViewletAction {
static ID = VIEWLET_ID;
......
......@@ -31,6 +31,7 @@
.monaco-action-bar .action-item.disabled .action-label.extension-action.install:not(.installing),
.monaco-action-bar .action-item.disabled .action-label.extension-action.uninstall:not(.uninstalling),
.monaco-action-bar .action-item.disabled .action-label.extension-action.update,
.monaco-action-bar .action-item.disabled .action-label.extension-action.theme,
.monaco-action-bar .action-item.disabled .action-label.extension-action.extension-editor-dropdown-action,
.monaco-action-bar .action-item.disabled .action-label.extension-action.reload,
.monaco-action-bar .action-item.disabled .action-label.disable-status.hide,
......
......@@ -61,7 +61,7 @@ export interface IWorkbenchThemeService extends IThemeService {
setFileIconTheme(iconThemeId: string | undefined, settingsTarget: ConfigurationTarget | undefined): Promise<IFileIconTheme>;
getFileIconTheme(): IFileIconTheme;
getFileIconThemes(): Promise<IFileIconTheme[]>;
getFileIconThemes(extensionId?: ExtensionIdentifier): Promise<IFileIconTheme[]>;
onDidFileIconThemeChange: Event<IFileIconTheme>;
}
......
......@@ -460,8 +460,9 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
}
}
public getFileIconThemes(): Promise<IFileIconTheme[]> {
return this.iconThemeStore.getFileIconThemes();
public async getFileIconThemes(extensionId?: ExtensionIdentifier): Promise<IFileIconTheme[]> {
const filIconThemes = await this.iconThemeStore.getFileIconThemes();
return extensionId ? filIconThemes.filter(c => c.extensionData && ExtensionIdentifier.equals(new ExtensionIdentifier(c.extensionData.extensionId), extensionId)) : filIconThemes;
}
public getFileIconTheme() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册