mirror of
https://github.com/Microsoft/vscode
synced 2024-08-28 13:29:44 +00:00
Merge pull request #154925 from microsoft/sandy081/extensions-set-display-lang
show set display language action for lang pack extensions
This commit is contained in:
commit
764d22738f
|
@ -22,6 +22,7 @@ export interface ILanguagePackService {
|
|||
readonly _serviceBrand: undefined;
|
||||
getAvailableLanguages(): Promise<Array<ILanguagePackItem>>;
|
||||
getInstalledLanguages(): Promise<Array<ILanguagePackItem>>;
|
||||
getLocale(extension: IGalleryExtension): string | undefined;
|
||||
}
|
||||
|
||||
export abstract class LanguagePackBaseService extends Disposable implements ILanguagePackService {
|
||||
|
@ -51,7 +52,7 @@ export abstract class LanguagePackBaseService extends Disposable implements ILan
|
|||
const languagePackExtensions = result.firstPage.filter(e => e.properties.localizedLanguages?.length && e.tags.some(t => t.startsWith('lp-')));
|
||||
const allFromMarketplace: ILanguagePackItem[] = languagePackExtensions.map(lp => {
|
||||
const languageName = lp.properties.localizedLanguages?.[0];
|
||||
const locale = lp.tags.find(t => t.startsWith('lp-'))!.split('lp-')[1];
|
||||
const locale = this.getLocale(lp)!;
|
||||
const baseQuickPick = this.createQuickPickItem({ locale, label: languageName });
|
||||
return {
|
||||
...baseQuickPick,
|
||||
|
@ -68,6 +69,10 @@ export abstract class LanguagePackBaseService extends Disposable implements ILan
|
|||
return allFromMarketplace;
|
||||
}
|
||||
|
||||
getLocale(extension: IGalleryExtension): string | undefined {
|
||||
return extension.tags.find(t => t.startsWith('lp-'))?.split('lp-')[1];
|
||||
}
|
||||
|
||||
protected createQuickPickItem(languageItem: { locale: string; label?: string | undefined }): IQuickPickItem {
|
||||
const label = languageItem.label ?? languageItem.locale;
|
||||
let description: string | undefined = languageItem.locale !== languageItem.label ? languageItem.locale : undefined;
|
||||
|
|
|
@ -29,7 +29,7 @@ import {
|
|||
UpdateAction, ReloadAction, EnableDropDownAction, DisableDropDownAction, ExtensionStatusLabelAction, SetFileIconThemeAction, SetColorThemeAction,
|
||||
RemoteInstallAction, ExtensionStatusAction, LocalInstallAction, ToggleSyncExtensionAction, SetProductIconThemeAction,
|
||||
ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, UninstallAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction,
|
||||
InstallAnotherVersionAction, ExtensionEditorManageExtensionAction, WebInstallAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction, MigrateDeprecatedExtensionAction
|
||||
InstallAnotherVersionAction, ExtensionEditorManageExtensionAction, WebInstallAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction, MigrateDeprecatedExtensionAction, SetLanguageAction
|
||||
} from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
|
@ -329,6 +329,7 @@ export class ExtensionEditor extends EditorPane {
|
|||
|
||||
this.instantiationService.createInstance(EnableDropDownAction),
|
||||
this.instantiationService.createInstance(DisableDropDownAction),
|
||||
this.instantiationService.createInstance(SetLanguageAction),
|
||||
this.instantiationService.createInstance(RemoteInstallAction, false),
|
||||
this.instantiationService.createInstance(LocalInstallAction),
|
||||
this.instantiationService.createInstance(WebInstallAction),
|
||||
|
|
|
@ -56,7 +56,7 @@ import { IContextMenuProvider } from 'vs/base/browser/contextmenu';
|
|||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import * as Constants from 'vs/workbench/contrib/logs/common/logConstants';
|
||||
import { errorIcon, infoIcon, manageExtensionIcon, preReleaseIcon, syncEnabledIcon, syncIgnoredIcon, trustIcon, warningIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons';
|
||||
import { isIOS, isWeb } from 'vs/base/common/platform';
|
||||
import { isIOS, isWeb, language } from 'vs/base/common/platform';
|
||||
import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService';
|
||||
import { IWorkspaceTrustEnablementService, IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust';
|
||||
import { isVirtualWorkspace } from 'vs/platform/workspace/common/virtualWorkspace';
|
||||
|
@ -66,6 +66,7 @@ import { ViewContainerLocation } from 'vs/workbench/common/views';
|
|||
import { flatten } from 'vs/base/common/arrays';
|
||||
import { fromNow } from 'vs/base/common/date';
|
||||
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks';
|
||||
|
||||
export class PromptExtensionInstallFailureAction extends Action {
|
||||
|
||||
|
@ -264,11 +265,18 @@ export abstract class AbstractInstallAction extends ExtensionAction {
|
|||
|
||||
protected async computeAndUpdateEnablement(): Promise<void> {
|
||||
this.enabled = false;
|
||||
if (this.extension && !this.extension.isBuiltin) {
|
||||
if (this.extension.state === ExtensionState.Uninstalled && await this.extensionsWorkbenchService.canInstall(this.extension)) {
|
||||
this.enabled = this.installPreReleaseVersion ? this.extension.hasPreReleaseVersion : this.extension.hasReleaseVersion;
|
||||
this.updateLabel();
|
||||
}
|
||||
if (!this.extension) {
|
||||
return;
|
||||
}
|
||||
if (this.extension.isBuiltin) {
|
||||
return;
|
||||
}
|
||||
if (this.extensionsWorkbenchService.canSetLanguage(this.extension)) {
|
||||
return;
|
||||
}
|
||||
if (this.extension.state === ExtensionState.Uninstalled && await this.extensionsWorkbenchService.canInstall(this.extension)) {
|
||||
this.enabled = this.installPreReleaseVersion ? this.extension.hasPreReleaseVersion : this.extension.hasReleaseVersion;
|
||||
this.updateLabel();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1781,6 +1789,43 @@ export class SetProductIconThemeAction extends ExtensionAction {
|
|||
}
|
||||
}
|
||||
|
||||
export class SetLanguageAction extends ExtensionAction {
|
||||
|
||||
static readonly ID = 'workbench.extensions.action.setLanguageTheme';
|
||||
static readonly TITLE = { value: localize('workbench.extensions.action.setLanguageTheme', "Set Display Language"), original: 'Set Display Language' };
|
||||
|
||||
private static readonly EnabledClass = `${ExtensionAction.LABEL_ACTION_CLASS} theme`;
|
||||
private static readonly DisabledClass = `${SetLanguageAction.EnabledClass} disabled`;
|
||||
|
||||
constructor(
|
||||
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@ILanguagePackService private readonly languagePackService: ILanguagePackService,
|
||||
) {
|
||||
super(SetLanguageAction.ID, SetLanguageAction.TITLE.value, SetLanguageAction.DisabledClass, false);
|
||||
this.update();
|
||||
}
|
||||
|
||||
update(): void {
|
||||
this.enabled = false;
|
||||
this.class = SetLanguageAction.DisabledClass;
|
||||
if (!this.extension) {
|
||||
return;
|
||||
}
|
||||
if (!this.extensionsWorkbenchService.canSetLanguage(this.extension)) {
|
||||
return;
|
||||
}
|
||||
if (this.extension.gallery && language === this.languagePackService.getLocale(this.extension.gallery)) {
|
||||
return;
|
||||
}
|
||||
this.enabled = true;
|
||||
this.class = SetLanguageAction.EnabledClass;
|
||||
}
|
||||
|
||||
override async run(): Promise<any> {
|
||||
return this.extension && this.extensionsWorkbenchService.setLanguage(this.extension);
|
||||
}
|
||||
}
|
||||
|
||||
export class ShowRecommendedExtensionAction extends Action {
|
||||
|
||||
static readonly ID = 'workbench.extensions.action.showRecommendedExtension';
|
||||
|
@ -2273,6 +2318,10 @@ export class ExtensionStatusAction extends ExtensionAction {
|
|||
return;
|
||||
}
|
||||
|
||||
if (this.extensionsWorkbenchService.canSetLanguage(this.extension)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.extension.gallery && this.extension.state === ExtensionState.Uninstalled && !await this.extensionsWorkbenchService.canInstall(this.extension)) {
|
||||
if (this.extensionManagementServerService.localExtensionManagementServer || this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
const targetPlatform = await (this.extensionManagementServerService.localExtensionManagementServer ? this.extensionManagementServerService.localExtensionManagementServer!.extensionManagementService.getTargetPlatform() : this.extensionManagementServerService.remoteExtensionManagementServer!.extensionManagementService.getTargetPlatform());
|
||||
|
|
|
@ -13,7 +13,7 @@ import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
|||
import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IExtension, ExtensionContainers, ExtensionState, IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions';
|
||||
import { UpdateAction, ManageExtensionAction, ReloadAction, ExtensionStatusLabelAction, RemoteInstallAction, ExtensionStatusAction, LocalInstallAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction, WebInstallAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction, MigrateDeprecatedExtensionAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
import { UpdateAction, ManageExtensionAction, ReloadAction, ExtensionStatusLabelAction, RemoteInstallAction, ExtensionStatusAction, LocalInstallAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction, WebInstallAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction, MigrateDeprecatedExtensionAction, SetLanguageAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { RatingsWidget, InstallCountWidget, RecommendationWidget, RemoteBadgeWidget, ExtensionPackCountWidget as ExtensionPackBadgeWidget, SyncIgnoredWidget, ExtensionHoverWidget, ExtensionActivationStatusWidget, PreReleaseBookmarkWidget, extensionVerifiedPublisherIconColor } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets';
|
||||
import { IExtensionService, toExtension } from 'vs/workbench/services/extensions/common/extensions';
|
||||
|
@ -123,6 +123,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
|
|||
reloadAction,
|
||||
this.instantiationService.createInstance(InstallDropdownAction),
|
||||
this.instantiationService.createInstance(InstallingLabelAction),
|
||||
this.instantiationService.createInstance(SetLanguageAction),
|
||||
this.instantiationService.createInstance(RemoteInstallAction, false),
|
||||
this.instantiationService.createInstance(LocalInstallAction),
|
||||
this.instantiationService.createInstance(WebInstallAction),
|
||||
|
@ -186,16 +187,25 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
|
|||
|
||||
data.extensionDisposables = dispose(data.extensionDisposables);
|
||||
|
||||
const updateEnablement = async () => {
|
||||
let disabled = false;
|
||||
const deprecated = !!extension.deprecationInfo;
|
||||
const computeEnablement = async () => {
|
||||
if (extension.state === ExtensionState.Uninstalled) {
|
||||
disabled = deprecated || !(await this.extensionsWorkbenchService.canInstall(extension));
|
||||
if (!!extension.deprecationInfo) {
|
||||
return true;
|
||||
}
|
||||
if (this.extensionsWorkbenchService.canSetLanguage(extension)) {
|
||||
return false;
|
||||
}
|
||||
return !(await this.extensionsWorkbenchService.canInstall(extension));
|
||||
} else if (extension.local && !isLanguagePackExtension(extension.local.manifest)) {
|
||||
const runningExtensions = await this.extensionService.getExtensions();
|
||||
const runningExtension = runningExtensions.filter(e => areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, extension.identifier))[0];
|
||||
disabled = !(runningExtension && extension.server === this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension)));
|
||||
return !(runningExtension && extension.server === this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension)));
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const updateEnablement = async () => {
|
||||
const disabled = await computeEnablement();
|
||||
const deprecated = !!extension.deprecationInfo;
|
||||
data.element.classList.toggle('deprecated', deprecated);
|
||||
data.root.classList.toggle('disabled', disabled);
|
||||
};
|
||||
|
|
|
@ -45,8 +45,10 @@ import { isBoolean, isUndefined } from 'vs/base/common/types';
|
|||
import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService';
|
||||
import { IExtensionService, IExtensionsStatus } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { ExtensionEditor } from 'vs/workbench/contrib/extensions/browser/extensionEditor';
|
||||
import { isWeb } from 'vs/base/common/platform';
|
||||
import { isWeb, language } from 'vs/base/common/platform';
|
||||
import { GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings';
|
||||
import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks';
|
||||
import { ILocaleService } from 'vs/workbench/contrib/localization/common/locale';
|
||||
|
||||
interface IExtensionStateProvider<T> {
|
||||
(extension: Extension): T;
|
||||
|
@ -710,6 +712,8 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
|||
@IExtensionManifestPropertiesService private readonly extensionManifestPropertiesService: IExtensionManifestPropertiesService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@ILanguagePackService private readonly languagePackService: ILanguagePackService,
|
||||
@ILocaleService private readonly localeService: ILocaleService,
|
||||
) {
|
||||
super();
|
||||
const preferPreReleasesValue = configurationService.getValue('_extensions.preferPreReleases');
|
||||
|
@ -1248,6 +1252,34 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
|||
return this.installWithProgress(() => this.installFromGallery(extension, gallery, installOptions), gallery.displayName, progressLocation);
|
||||
}
|
||||
|
||||
canSetLanguage(extension: IExtension): boolean {
|
||||
if (!isWeb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!extension.gallery) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const locale = this.languagePackService.getLocale(extension.gallery);
|
||||
if (!locale) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async setLanguage(extension: IExtension): Promise<void> {
|
||||
if (!this.canSetLanguage(extension)) {
|
||||
throw new Error('Can not set language');
|
||||
}
|
||||
const locale = this.languagePackService.getLocale(extension.gallery!);
|
||||
if (locale === language) {
|
||||
return;
|
||||
}
|
||||
return this.localeService.setLocale({ id: locale, galleryExtension: extension.gallery, extensionId: extension.identifier.id, label: extension.displayName });
|
||||
}
|
||||
|
||||
setEnablement(extensions: IExtension | IExtension[], enablementState: EnablementState): Promise<void> {
|
||||
extensions = Array.isArray(extensions) ? extensions : [extensions];
|
||||
return this.promptAndSetEnablement(extensions, enablementState);
|
||||
|
|
|
@ -107,6 +107,8 @@ export interface IExtensionsWorkbenchService {
|
|||
uninstall(extension: IExtension): Promise<void>;
|
||||
installVersion(extension: IExtension, version: string, installOptions?: InstallOptions): Promise<IExtension>;
|
||||
reinstall(extension: IExtension): Promise<IExtension>;
|
||||
canSetLanguage(extension: IExtension): boolean;
|
||||
setLanguage(extension: IExtension): Promise<void>;
|
||||
setEnablement(extensions: IExtension | IExtension[], enablementState: EnablementState): Promise<void>;
|
||||
open(extension: IExtension, options?: IExtensionEditorOptions): Promise<void>;
|
||||
checkForUpdates(): Promise<void>;
|
||||
|
|
Loading…
Reference in a new issue