diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index 575eebe161823..34a24cfec2377 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -306,6 +306,9 @@ Registry.as(ConfigurationExtensions.Configuration) }, { type: 'array', + items: { + type: 'string', + }, description: localize('extensions.allow.version.description', "Allow or disallow specific versions of the extension. To specifcy a platform specific version, use the format `platform@1.2.3`, e.g. `win32-x64@1.2.3`. Supported platforms are `win32-x64`, `win32-arm64`, `linux-x64`, `linux-arm64`, `linux-armhf`, `alpine-x64`, `alpine-arm64`, `darwin-x64`, `darwin-arm64`"), }, ] diff --git a/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css index fed56f72b90e1..5c2a8af08ec46 100644 --- a/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css @@ -522,6 +522,10 @@ opacity: 0.9; } +.settings-editor > .settings-body .settings-tree-container .setting-item-contents .complex-object-edit-in-settings-button-container { + margin-top: 9px; +} + .settings-editor > .settings-body .settings-tree-container .setting-item-contents .setting-item-markdown a, .settings-editor > .settings-body .settings-tree-container .setting-item-contents .edit-in-settings-button, .settings-editor > .settings-body .settings-tree-container .setting-item-contents .setting-item-markdown a > code { diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index ce54a54ab03c1..d4d1b8458acee 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -689,6 +689,10 @@ interface ISettingComplexItemTemplate extends ISettingItemTemplate { validationErrorMessageElement: HTMLElement; } +interface ISettingComplexObjectItemTemplate extends ISettingComplexItemTemplate { + objectSettingWidget: ObjectSettingDropdownWidget; +} + interface ISettingListItemTemplate extends ISettingItemTemplate { listWidget: ListSettingWidget; validationErrorMessageElement: HTMLElement; @@ -725,6 +729,7 @@ const SETTINGS_INCLUDE_TEMPLATE_ID = 'settings.include.template'; const SETTINGS_OBJECT_TEMPLATE_ID = 'settings.object.template'; const SETTINGS_BOOL_OBJECT_TEMPLATE_ID = 'settings.boolObject.template'; const SETTINGS_COMPLEX_TEMPLATE_ID = 'settings.complex.template'; +const SETTINGS_COMPLEX_OBJECT_TEMPLATE_ID = 'settings.complexObject.template'; const SETTINGS_NEW_EXTENSIONS_TEMPLATE_ID = 'settings.newExtensions.template'; const SETTINGS_ELEMENT_TEMPLATE_ID = 'settings.group.template'; const SETTINGS_EXTENSION_TOGGLE_TEMPLATE_ID = 'settings.extensionToggle.template'; @@ -1205,6 +1210,46 @@ export class SettingComplexRenderer extends AbstractSettingRenderer implements I } } +class SettingComplexObjectRenderer extends SettingComplexRenderer implements ITreeRenderer { + + override templateId = SETTINGS_COMPLEX_OBJECT_TEMPLATE_ID; + + override renderTemplate(container: HTMLElement): ISettingComplexObjectItemTemplate { + const common = this.renderCommonTemplate(null, container, 'list'); + + const objectSettingWidget = common.toDispose.add(this._instantiationService.createInstance(ObjectSettingDropdownWidget, common.controlElement)); + objectSettingWidget.domNode.classList.add(AbstractSettingRenderer.CONTROL_CLASS); + + const openSettingsButton = DOM.append(DOM.append(common.controlElement, $('.complex-object-edit-in-settings-button-container')), $('a.complex-object.edit-in-settings-button')); + openSettingsButton.classList.add(AbstractSettingRenderer.CONTROL_CLASS); + openSettingsButton.role = 'button'; + + const validationErrorMessageElement = $('.setting-item-validation-message'); + common.containerElement.appendChild(validationErrorMessageElement); + + const template: ISettingComplexObjectItemTemplate = { + ...common, + button: openSettingsButton, + validationErrorMessageElement, + objectSettingWidget + }; + + this.addSettingElementFocusHandler(template); + + return template; + } + + protected override renderValue(dataElement: SettingsTreeSettingElement, template: ISettingComplexObjectItemTemplate, onChange: (value: string) => void): void { + const items = getObjectDisplayValue(dataElement); + template.objectSettingWidget.setValue(items, { + settingKey: dataElement.setting.key, + showAddButton: false, + isReadOnly: true, + }); + super.renderValue(dataElement, template, onChange); + } +} + class SettingArrayRenderer extends AbstractSettingRenderer implements ITreeRenderer { templateId = SETTINGS_ARRAY_TEMPLATE_ID; @@ -2128,6 +2173,7 @@ export class SettingTreeRenderers extends Disposable { this._instantiationService.createInstance(SettingNumberRenderer, this.settingActions, actionFactory), this._instantiationService.createInstance(SettingArrayRenderer, this.settingActions, actionFactory), this._instantiationService.createInstance(SettingComplexRenderer, this.settingActions, actionFactory), + this._instantiationService.createInstance(SettingComplexObjectRenderer, this.settingActions, actionFactory), this._instantiationService.createInstance(SettingTextRenderer, this.settingActions, actionFactory), this._instantiationService.createInstance(SettingMultilineTextRenderer, this.settingActions, actionFactory), this._instantiationService.createInstance(SettingExcludeRenderer, this.settingActions, actionFactory), @@ -2417,6 +2463,10 @@ class SettingsTreeDelegate extends CachedListVirtualDelegate { - if (Array.isArray(schema.anyOf)) { - return schema.anyOf; + let schemaType: 'simple' | 'complex' | false = 'simple'; + for (const schema of schemas) { + for (const subSchema of Array.isArray(schema.anyOf) ? schema.anyOf : [schema]) { + const subSchemaType = getObjectRenderableSchemaType(subSchema, key); + if (subSchemaType === false) { + return false; + } + if (subSchemaType === 'complex') { + schemaType = 'complex'; + } } - return [schema]; - }).flat(); + } - return flatSchemas.every((schema) => isObjectRenderableSchema(schema, key)); + return schemaType; } function settingTypeEnumRenderable(_type: string | string[]) { diff --git a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts index e7b237c053054..258984d755f42 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts @@ -165,8 +165,8 @@ export abstract class AbstractListSettingWidget extend return this.model.items; } - get inReadMode(): boolean { - return this.model.items.every(item => !item.editing); + protected get isReadOnly(): boolean { + return false; } constructor( @@ -373,6 +373,10 @@ export abstract class AbstractListSettingWidget extend return; } + if (this.isReadOnly) { + return; + } + const item = this.model.items[targetIdx]; if (item) { this.editSetting(targetIdx); @@ -481,6 +485,9 @@ export class ListSettingWidget extends Abst } protected getActionsForItem(item: TListDataItem, idx: number): IAction[] { + if (this.isReadOnly) { + return []; + } return [ { class: ThemeIcon.asClassName(settingsEditIcon), @@ -520,7 +527,7 @@ export class ListSettingWidget extends Abst } protected addDragAndDrop(rowElement: HTMLElement, item: TListDataItem, idx: number) { - if (this.inReadMode) { + if (this.model.items.every(item => !item.editing)) { rowElement.draggable = true; rowElement.classList.add('draggable'); } else { @@ -898,8 +905,9 @@ export interface IObjectKeySuggester { interface IObjectSetValueOptions { settingKey: string; showAddButton: boolean; - keySuggester: IObjectKeySuggester; - valueSuggester: IObjectValueSuggester; + isReadOnly?: boolean; + keySuggester?: IObjectKeySuggester; + valueSuggester?: IObjectValueSuggester; } interface IObjectRenderEditWidgetOptions { @@ -911,6 +919,7 @@ interface IObjectRenderEditWidgetOptions { } export class ObjectSettingDropdownWidget extends AbstractListSettingWidget { + private editable: boolean = true; private currentSettingKey: string = ''; private showAddButton: boolean = true; private keySuggester: IObjectKeySuggester = () => undefined; @@ -926,6 +935,7 @@ export class ObjectSettingDropdownWidget extends AbstractListSettingWidget