mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 13:00:58 +00:00
parent
96a37971fe
commit
21df88c9b4
|
@ -6,7 +6,7 @@
|
|||
.profiles-editor {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
max-width: 1200px;
|
||||
max-width: 1000px;
|
||||
margin: 20px auto 0px auto;
|
||||
}
|
||||
|
||||
|
@ -159,7 +159,7 @@
|
|||
}
|
||||
|
||||
.profiles-editor .contents-container .profile-tree-item-container.new-profile-resource-type-container > .profile-resource-type-label-container {
|
||||
width: 250px;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.profiles-editor .contents-container .profile-tree-item-container.new-profile-resource-type-container > .profile-select-container {
|
||||
|
|
|
@ -53,11 +53,12 @@ import { API_OPEN_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/ed
|
|||
import { SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { DEFAULT_LABELS_CONTAINER, IResourceLabel, ResourceLabels } from 'vs/workbench/browser/labels';
|
||||
import { IHoverDelegate } from 'vs/base/browser/ui/hover/hoverDelegate';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IDialogService, IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { AbstractUserDataProfileElement, IProfileElement, NewProfileElement, UserDataProfileElement, UserDataProfilesEditorModel } from 'vs/workbench/contrib/userDataProfile/browser/userDataProfilesEditorModel';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { WorkbenchToolBar } from 'vs/platform/actions/browser/toolbar';
|
||||
import { createInstantHoverDelegate } from 'vs/base/browser/ui/hover/hoverDelegateFactory';
|
||||
|
||||
export const profilesSashBorder = registerColor('profiles.sashBorder', { dark: PANEL_BORDER, light: PANEL_BORDER, hcDark: PANEL_BORDER, hcLight: PANEL_BORDER }, localize('profilesSashBorder', "The color of the Profiles editor splitview sash border."));
|
||||
|
||||
|
@ -80,6 +81,7 @@ export class UserDataProfilesEditor extends EditorPane implements IUserDataProfi
|
|||
@IStorageService storageService: IStorageService,
|
||||
@IUserDataProfileManagementService private readonly userDataProfileManagementService: IUserDataProfileManagementService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@IDialogService private readonly dialogService: IDialogService,
|
||||
@IFileDialogService private readonly fileDialogService: IFileDialogService,
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
|
@ -115,7 +117,7 @@ export class UserDataProfilesEditor extends EditorPane implements IUserDataProfi
|
|||
onDidChange: Event.None,
|
||||
element: sidebarView,
|
||||
minimumSize: 175,
|
||||
maximumSize: 300,
|
||||
maximumSize: 350,
|
||||
layout: (width, _, height) => {
|
||||
sidebarView.style.width = `${width}px`;
|
||||
if (height && this.profilesTree) {
|
||||
|
@ -123,7 +125,7 @@ export class UserDataProfilesEditor extends EditorPane implements IUserDataProfi
|
|||
this.profilesTree.layout(height - 38, width);
|
||||
}
|
||||
}
|
||||
}, 250, undefined, true);
|
||||
}, 300, undefined, true);
|
||||
this.splitView.addView({
|
||||
onDidChange: Event.None,
|
||||
element: contentsView,
|
||||
|
@ -192,7 +194,7 @@ export class UserDataProfilesEditor extends EditorPane implements IUserDataProfi
|
|||
if (this.templates.length) {
|
||||
actions.push(new SubmenuAction('from.template', localize('from template', "From Template"),
|
||||
this.templates.map(template => new Action(`template:${template.url}`, template.name, undefined, true, async () => {
|
||||
this.model?.createNewProfile(URI.parse(template.url));
|
||||
this.createNewProfile(URI.parse(template.url));
|
||||
}))));
|
||||
actions.push(new Separator());
|
||||
}
|
||||
|
@ -206,12 +208,7 @@ export class UserDataProfilesEditor extends EditorPane implements IUserDataProfi
|
|||
...defaultButtonStyles
|
||||
}));
|
||||
button.label = `$(add) ${localize('newProfile', "New Profile")}`;
|
||||
this._register(button.onDidClick(e => {
|
||||
if (this.model) {
|
||||
const element = this.model.createNewProfile();
|
||||
this.updateProfilesTree(element);
|
||||
}
|
||||
}));
|
||||
this._register(button.onDidClick(e => this.createNewProfile()));
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
|
@ -227,7 +224,7 @@ export class UserDataProfilesEditor extends EditorPane implements IUserDataProfi
|
|||
if (e.element instanceof AbstractUserDataProfileElement) {
|
||||
this.contextMenuService.showContextMenu({
|
||||
getAnchor: () => e.anchor,
|
||||
getActions: () => e.element instanceof AbstractUserDataProfileElement ? e.element.secondaryActions : [],
|
||||
getActions: () => e.element instanceof AbstractUserDataProfileElement ? e.element.contextMenuActions.slice(0) : [],
|
||||
getActionsContext: () => e.element
|
||||
});
|
||||
}
|
||||
|
@ -263,13 +260,28 @@ export class UserDataProfilesEditor extends EditorPane implements IUserDataProfi
|
|||
}
|
||||
const url = selectedItem.label === quickPick.value ? URI.parse(quickPick.value) : await this.getProfileUriFromFileSystem();
|
||||
if (url) {
|
||||
this.model?.createNewProfile(url);
|
||||
this.createNewProfile(url);
|
||||
}
|
||||
}));
|
||||
disposables.add(quickPick.onDidHide(() => disposables.dispose()));
|
||||
quickPick.show();
|
||||
}
|
||||
|
||||
private async createNewProfile(copyFrom?: URI | IUserDataProfile): Promise<void> {
|
||||
if (this.model?.profiles.some(p => p instanceof NewProfileElement)) {
|
||||
const result = await this.dialogService.confirm({
|
||||
type: 'info',
|
||||
message: localize('new profile exists', "A new profile is already being created. Do you want to discard it and create a new one?"),
|
||||
primaryButton: localize('discard', "Discard & Create"),
|
||||
cancelButton: localize('cancel', "Cancel")
|
||||
});
|
||||
if (!result.confirmed) {
|
||||
return;
|
||||
}
|
||||
this.model.revert();
|
||||
}
|
||||
this.model?.createNewProfile(copyFrom);
|
||||
}
|
||||
|
||||
private async getProfileUriFromFileSystem(): Promise<URI | null> {
|
||||
const profileLocation = await this.fileDialogService.showOpenDialog({
|
||||
|
@ -398,7 +410,7 @@ class ProfileTreeElementRenderer implements ITreeRenderer<IProfileElement, void,
|
|||
class ProfileWidget extends Disposable {
|
||||
|
||||
private readonly profileTitle: HTMLElement;
|
||||
private readonly actionbar: ActionBar;
|
||||
private readonly toolbar: WorkbenchToolBar;
|
||||
private readonly buttonContainer: HTMLElement;
|
||||
private readonly iconElement: HTMLElement;
|
||||
private readonly nameContainer: HTMLElement;
|
||||
|
@ -434,8 +446,12 @@ class ProfileWidget extends Disposable {
|
|||
this.profileTitle = append(title, $('span'));
|
||||
const actionsContainer = append(header, $('.profile-actions-container'));
|
||||
this.buttonContainer = append(actionsContainer, $('.profile-button-container'));
|
||||
this.actionbar = new ActionBar(actionsContainer);
|
||||
this.actionbar.setFocusable(true);
|
||||
this.toolbar = this._register(instantiationService.createInstance(WorkbenchToolBar,
|
||||
actionsContainer,
|
||||
{
|
||||
hoverDelegate: this._register(createInstantHoverDelegate()),
|
||||
}
|
||||
));
|
||||
|
||||
const body = append(parent, $('.profile-body'));
|
||||
|
||||
|
@ -685,10 +701,7 @@ class ProfileWidget extends Disposable {
|
|||
this.buttonContainer.classList.add('hide');
|
||||
}
|
||||
|
||||
this.actionbar.clear();
|
||||
if (profileElement.secondaryActions.length > 0) {
|
||||
this.actionbar.push(profileElement.secondaryActions.filter(a => !(a instanceof Separator)), { icon: true, label: false });
|
||||
}
|
||||
this.toolbar.setActions(profileElement.titleActions[0].slice(0), profileElement.titleActions[1].slice(0));
|
||||
|
||||
this.nameInput.focus();
|
||||
if (profileElement instanceof NewProfileElement) {
|
||||
|
@ -806,7 +819,6 @@ interface INewProfileResourceTemplateData extends IProfileResourceTemplateData {
|
|||
readonly label: HTMLElement;
|
||||
readonly selectContainer: HTMLElement;
|
||||
readonly selectBox: SelectBox;
|
||||
readonly description: HTMLElement;
|
||||
}
|
||||
|
||||
interface IProfileResourceChildTreeItemTemplateData extends IProfileResourceTemplateData {
|
||||
|
@ -907,12 +919,11 @@ class NewProfileResourceTreeRenderer extends AbstractProfileResourceTreeRenderer
|
|||
const container = append(parent, $('.profile-tree-item-container.new-profile-resource-type-container'));
|
||||
const labelContainer = append(container, $('.profile-resource-type-label-container'));
|
||||
const label = append(labelContainer, $('span.profile-resource-type-label'));
|
||||
const description = append(labelContainer, $('span.profile-resource-type-description', undefined, localize('use default', "Use Default Profile")));
|
||||
const selectBox = this._register(this.instantiationService.createInstance(SelectBox,
|
||||
[
|
||||
{ text: localize('copy', "Copy"), description: localize('copy from selected', "Copy from selected") },
|
||||
{ text: localize('empty', "Empty") },
|
||||
{ text: localize('exclude', "Exclude"), description: localize('use default', "Use Default Profile") }
|
||||
{ text: localize('copy', "Copy") },
|
||||
{ text: localize('default', "Use Default Profile") }
|
||||
],
|
||||
0,
|
||||
this.contextViewService,
|
||||
|
@ -924,7 +935,7 @@ class NewProfileResourceTreeRenderer extends AbstractProfileResourceTreeRenderer
|
|||
const selectContainer = append(container, $('.profile-select-container'));
|
||||
selectBox.render(selectContainer);
|
||||
|
||||
return { label, selectContainer, selectBox, description, disposables, elementDisposables: disposables.add(new DisposableStore()) };
|
||||
return { label, selectContainer, selectBox, disposables, elementDisposables: disposables.add(new DisposableStore()) };
|
||||
}
|
||||
|
||||
renderElement({ element: profileResourceTreeElement }: ITreeNode<ProfileResourceTreeElement, void>, index: number, templateData: INewProfileResourceTemplateData, height: number | undefined): void {
|
||||
|
@ -937,16 +948,10 @@ class NewProfileResourceTreeRenderer extends AbstractProfileResourceTreeRenderer
|
|||
throw new Error('NewProfileResourceTreeRenderer can only profile resoyrce types');
|
||||
}
|
||||
templateData.label.textContent = this.getResourceTypeTitle(element);
|
||||
templateData.description.classList.toggle('hide', !root.getFlag(element));
|
||||
templateData.selectBox.select(root.getCopyFlag(element) ? 0 : root.getFlag(element) ? 2 : 1);
|
||||
templateData.selectBox.select(root.getCopyFlag(element) ? 1 : root.getFlag(element) ? 2 : 0);
|
||||
templateData.elementDisposables.add(templateData.selectBox.onDidSelect(option => {
|
||||
root.setFlag(element, option.index === 2);
|
||||
root.setCopyFlag(element, option.index === 0);
|
||||
}));
|
||||
templateData.elementDisposables.add(root.onDidChange(e => {
|
||||
if (e.flags) {
|
||||
templateData.description.classList.toggle('hide', !root.getFlag(element));
|
||||
}
|
||||
root.setCopyFlag(element, option.index === 1);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -177,7 +177,8 @@ export abstract class AbstractUserDataProfileElement extends Disposable {
|
|||
}
|
||||
|
||||
abstract readonly primaryAction?: Action;
|
||||
abstract readonly secondaryActions: IAction[];
|
||||
abstract readonly titleActions: [IAction[], IAction[]];
|
||||
abstract readonly contextMenuActions: IAction[];
|
||||
}
|
||||
|
||||
export class UserDataProfileElement extends AbstractUserDataProfileElement implements IProfileElement {
|
||||
|
@ -190,7 +191,8 @@ export class UserDataProfileElement extends AbstractUserDataProfileElement imple
|
|||
|
||||
constructor(
|
||||
private _profile: IUserDataProfile,
|
||||
readonly secondaryActions: IAction[],
|
||||
readonly titleActions: [IAction[], IAction[]],
|
||||
readonly contextMenuActions: IAction[],
|
||||
@IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService,
|
||||
@IUserDataProfileManagementService private readonly userDataProfileManagementService: IUserDataProfileManagementService,
|
||||
@IUserDataProfilesService userDataProfilesService: IUserDataProfilesService,
|
||||
|
@ -273,7 +275,8 @@ export class NewProfileElement extends AbstractUserDataProfileElement implements
|
|||
name: string,
|
||||
copyFrom: URI | IUserDataProfile | undefined,
|
||||
readonly primaryAction: Action,
|
||||
readonly secondaryActions: Action[],
|
||||
readonly titleActions: [IAction[], IAction[]],
|
||||
readonly contextMenuActions: Action[],
|
||||
@IFileService private readonly fileService: IFileService,
|
||||
@IUserDataProfileImportExportService private readonly userDataProfileImportExportService: IUserDataProfileImportExportService,
|
||||
@IUserDataProfilesService userDataProfilesService: IUserDataProfilesService,
|
||||
|
@ -421,6 +424,7 @@ export class UserDataProfilesEditorModel extends EditorModel {
|
|||
readonly onDidChange = this._onDidChange.event;
|
||||
|
||||
constructor(
|
||||
@IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService,
|
||||
@IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService,
|
||||
@IUserDataProfileManagementService private readonly userDataProfileManagementService: IUserDataProfileManagementService,
|
||||
@IUserDataProfileImportExportService private readonly userDataProfileImportExportService: IUserDataProfileImportExportService,
|
||||
|
@ -453,16 +457,37 @@ export class UserDataProfilesEditorModel extends EditorModel {
|
|||
|
||||
private createProfileElement(profile: IUserDataProfile): [UserDataProfileElement, DisposableStore] {
|
||||
const disposables = new DisposableStore();
|
||||
const actions: IAction[] = [];
|
||||
actions.push(new Action('userDataProfile.copyFromProfile', localize('copyFromProfile', "Save As..."), ThemeIcon.asClassName(Codicon.copy), true, () => this.createNewProfile(profile)));
|
||||
actions.push(new Action('userDataProfile.export', localize('export', "Export..."), ThemeIcon.asClassName(Codicon.export), true, () => this.exportProfile(profile)));
|
||||
|
||||
const activateAction = disposables.add(new Action('userDataProfile.activate', localize('active', "Activate"), ThemeIcon.asClassName(Codicon.check), true, () => this.userDataProfileManagementService.switchProfile(profile)));
|
||||
activateAction.checked = this.userDataProfileService.currentProfile.id === profile.id;
|
||||
disposables.add(this.userDataProfileService.onDidChangeCurrentProfile(() => activateAction.checked = this.userDataProfileService.currentProfile.id === profile.id));
|
||||
const copyFromProfileAction = disposables.add(new Action('userDataProfile.copyFromProfile', localize('copyFromProfile', "Save As..."), ThemeIcon.asClassName(Codicon.copy), true, () => this.createNewProfile(profile)));
|
||||
const exportAction = disposables.add(new Action('userDataProfile.export', localize('export', "Export..."), ThemeIcon.asClassName(Codicon.export), true, () => this.exportProfile(profile)));
|
||||
const deleteAction = disposables.add(new Action('userDataProfile.delete', localize('delete', "Delete"), ThemeIcon.asClassName(Codicon.trash), true, () => this.removeProfile(profile)));
|
||||
|
||||
const titlePrimaryActions: IAction[] = [];
|
||||
titlePrimaryActions.push(activateAction);
|
||||
titlePrimaryActions.push(exportAction);
|
||||
if (!profile.isDefault) {
|
||||
actions.push(new Separator());
|
||||
actions.push(new Action('userDataProfile.delete', localize('delete', "Delete"), ThemeIcon.asClassName(Codicon.trash), true, () => this.removeProfile(profile)));
|
||||
titlePrimaryActions.push(deleteAction);
|
||||
}
|
||||
|
||||
const titleSecondaryActions: IAction[] = [];
|
||||
titleSecondaryActions.push(copyFromProfileAction);
|
||||
|
||||
const secondaryActions: IAction[] = [];
|
||||
secondaryActions.push(activateAction);
|
||||
secondaryActions.push(new Separator());
|
||||
secondaryActions.push(copyFromProfileAction);
|
||||
secondaryActions.push(exportAction);
|
||||
if (!profile.isDefault) {
|
||||
secondaryActions.push(new Separator());
|
||||
secondaryActions.push(deleteAction);
|
||||
}
|
||||
const profileElement = disposables.add(this.instantiationService.createInstance(UserDataProfileElement,
|
||||
profile,
|
||||
actions
|
||||
[titlePrimaryActions, titleSecondaryActions],
|
||||
secondaryActions,
|
||||
));
|
||||
return [profileElement, disposables];
|
||||
}
|
||||
|
@ -470,16 +495,16 @@ export class UserDataProfilesEditorModel extends EditorModel {
|
|||
createNewProfile(copyFrom?: URI | IUserDataProfile): IProfileElement {
|
||||
if (!this.newProfileElement) {
|
||||
const disposables = new DisposableStore();
|
||||
const discardAction = disposables.add(new Action('userDataProfile.discard', localize('discard', "Discard"), ThemeIcon.asClassName(Codicon.close), true, () => {
|
||||
this.removeNewProfile();
|
||||
this._onDidChange.fire(undefined);
|
||||
}));
|
||||
this.newProfileElement = disposables.add(this.instantiationService.createInstance(NewProfileElement,
|
||||
localize('untitled', "Untitled"),
|
||||
copyFrom,
|
||||
new Action('userDataProfile.create', localize('create', "Create & Apply"), undefined, true, () => this.saveNewProfile()),
|
||||
[
|
||||
new Action('userDataProfile.discard', localize('discard', "Discard"), ThemeIcon.asClassName(Codicon.close), true, () => {
|
||||
this.removeNewProfile();
|
||||
this._onDidChange.fire(undefined);
|
||||
})
|
||||
]
|
||||
disposables.add(new Action('userDataProfile.create', localize('create', "Create & Apply"), undefined, true, () => this.saveNewProfile())),
|
||||
[[discardAction], []],
|
||||
[discardAction],
|
||||
));
|
||||
this._profiles.push([this.newProfileElement, disposables]);
|
||||
this._onDidChange.fire(this.newProfileElement);
|
||||
|
|
Loading…
Reference in a new issue