From f6da7e420c6df667fa6a71f2ffc60fcfee1b765a Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 5 Jun 2018 22:31:09 +0200 Subject: [PATCH] Fix #48535 - Close --- .../browser/viewsContainersExtensionPoint.ts | 13 +- .../api/browser/viewsExtensionPoint.ts | 57 ++++---- src/vs/workbench/browser/parts/views/views.ts | 45 +++--- .../browser/parts/views/viewsViewlet.ts | 9 +- src/vs/workbench/common/views.ts | 133 ++++++++++++------ .../parts/debug/browser/debugViewlet.ts | 7 +- src/vs/workbench/parts/debug/common/debug.ts | 4 + .../electron-browser/debug.contribution.ts | 12 +- .../parts/extensions/common/extensions.ts | 3 + .../electron-browser/extensionsViewlet.ts | 28 ++-- src/vs/workbench/parts/files/common/files.ts | 6 + .../files/electron-browser/explorerViewlet.ts | 20 +-- .../electron-browser/outline.contribution.ts | 5 +- .../quickopen/browser/viewPickerHandler.ts | 13 +- src/vs/workbench/parts/scm/common/scm.ts | 6 +- .../parts/scm/electron-browser/scmViewlet.ts | 12 +- .../test/browser/parts/views/views.test.ts | 53 +++---- 17 files changed, 248 insertions(+), 178 deletions(-) diff --git a/src/vs/workbench/api/browser/viewsContainersExtensionPoint.ts b/src/vs/workbench/api/browser/viewsContainersExtensionPoint.ts index fd4e99fc810..23e4d1540ca 100644 --- a/src/vs/workbench/api/browser/viewsContainersExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsContainersExtensionPoint.ts @@ -20,8 +20,8 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IExtensionService, IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; -import { ViewLocation } from 'vs/workbench/common/views'; -import { ViewsViewlet } from 'vs/workbench/browser/parts/views/viewsViewlet'; +import { Extensions as ViewContainerExtensions, IViewContainersRegistry, TEST_VIEWLET_ID } from 'vs/workbench/common/views'; +import { ViewContainerViewlet } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { forEach } from 'vs/base/common/collections'; @@ -83,7 +83,7 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { const cssClass = `extensionViewlet-test`; const icon = require.toUrl('./media/test.svg'); - this.registerCustomViewlet({ id: ViewLocation.TEST.id, title, icon }, TEST_VIEW_CONTAINER_ORDER, cssClass); + this.registerCustomViewlet({ id: TEST_VIEWLET_ID, title, icon }, TEST_VIEW_CONTAINER_ORDER, cssClass); } private handleAndRegisterCustomViewContainers() { @@ -142,15 +142,16 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { } private registerCustomViewlet(descriptor: IUserFriendlyViewsContainerDescriptor, order: number, cssClass: string): void { + const viewContainersRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); const viewletRegistry = Registry.as(ViewletExtensions.Viewlets); const id = descriptor.id; if (!viewletRegistry.getViewlet(id)) { - const location: ViewLocation = ViewLocation.register(id); + viewContainersRegistry.registerViewContainer(id); // Register as viewlet - class CustomViewlet extends ViewsViewlet { + class CustomViewlet extends ViewContainerViewlet { constructor( @IPartService partService: IPartService, @ITelemetryService telemetryService: ITelemetryService, @@ -162,7 +163,7 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { @IContextMenuService contextMenuService: IContextMenuService, @IExtensionService extensionService: IExtensionService ) { - super(id, location, `${id}.state`, true, partService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); + super(id, `${id}.state`, true, partService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); } } const viewletDescriptor = new ViewletDescriptor( diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index 60246a02cb1..d70fc465c8e 100644 --- a/src/vs/workbench/api/browser/viewsExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsExtensionPoint.ts @@ -8,7 +8,7 @@ import { localize } from 'vs/nls'; import { forEach } from 'vs/base/common/collections'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { ExtensionMessageCollector, ExtensionsRegistry, IExtensionPoint } from 'vs/workbench/services/extensions/common/extensionsRegistry'; -import { ViewLocation, ViewsRegistry, ICustomViewDescriptor } from 'vs/workbench/common/views'; +import { ViewContainer, ViewsRegistry, ICustomViewDescriptor, IViewContainersRegistry, Extensions as ViewContainerExtensions } from 'vs/workbench/common/views'; import { CustomTreeViewPanel, CustomTreeViewer } from 'vs/workbench/browser/parts/views/customView'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { coalesce, } from 'vs/base/common/arrays'; @@ -18,6 +18,9 @@ import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ProgressLocation } from 'vs/platform/progress/common/progress'; +import { VIEWLET_ID as EXPLORER } from 'vs/workbench/parts/files/common/files'; +import { VIEWLET_ID as SCM } from 'vs/workbench/parts/scm/common/scm'; +import { VIEWLET_ID as DEBUG } from 'vs/workbench/parts/debug/common/debug'; interface IUserFriendlyViewDescriptor { id: string; @@ -84,9 +87,13 @@ const viewsContribution: IJSONSchema = { const viewsExtensionPoint: IExtensionPoint<{ [loc: string]: IUserFriendlyViewDescriptor[] }> = ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: IUserFriendlyViewDescriptor[] }>('views', [viewsContainersExtensionPoint], viewsContribution); class ViewsContainersExtensionHandler implements IWorkbenchContribution { + + private viewContainersRegistry: IViewContainersRegistry; + constructor( @IInstantiationService private instantiationService: IInstantiationService ) { + this.viewContainersRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); this.handleAndRegisterCustomViews(); } @@ -100,21 +107,21 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { return; } - let location = this.getViewLocation(entry.key); - if (!location) { + let container = this.getViewContainer(entry.key); + if (!container) { collector.warn(localize('ViewContainerDoesnotExist', "View container '{0}' does not exist and all views registered to it will be added to 'Explorer'.", entry.key)); - location = ViewLocation.Explorer; + container = this.viewContainersRegistry.get(EXPLORER); } - const registeredViews = ViewsRegistry.getViews(location); + const registeredViews = ViewsRegistry.getViews(container); const viewIds = []; const viewDescriptors = coalesce(entry.value.map(item => { // validate if (viewIds.indexOf(item.id) !== -1) { - collector.error(localize('duplicateView1', "Cannot register multiple views with same id `{0}` in the location `{1}`", item.id, location.id)); + collector.error(localize('duplicateView1', "Cannot register multiple views with same id `{0}` in the view container `{1}`", item.id, container.id)); return null; } if (registeredViews.some(v => v.id === item.id)) { - collector.error(localize('duplicateView2', "A view with id `{0}` is already registered in the location `{1}`", item.id, location.id)); + collector.error(localize('duplicateView2', "A view with id `{0}` is already registered in the view container `{1}`", item.id, container.id)); return null; } @@ -122,11 +129,11 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { id: item.id, name: item.name, ctor: CustomTreeViewPanel, - location, + container, when: ContextKeyExpr.deserialize(item.when), canToggleVisibility: true, - collapsed: this.showCollapsed(location), - treeViewer: this.instantiationService.createInstance(CustomTreeViewer, item.id, this.getProgressLocation(location)) + collapsed: this.showCollapsed(container), + treeViewer: this.instantiationService.createInstance(CustomTreeViewer, item.id, this.getProgressLocation(container)) }; viewIds.push(viewDescriptor.id); @@ -138,13 +145,13 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { }); } - private getProgressLocation(location: ViewLocation): ProgressLocation { - switch (location.id) { - case ViewLocation.Explorer.id: + private getProgressLocation(container: ViewContainer): ProgressLocation { + switch (container.id) { + case EXPLORER: return ProgressLocation.Explorer; - case ViewLocation.SCM.id: + case SCM: return ProgressLocation.Scm; - case ViewLocation.Debug.id: + case DEBUG: return null /* No debug progress location yet */; } return null; @@ -175,20 +182,20 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { } - private getViewLocation(value: string): ViewLocation { + private getViewContainer(value: string): ViewContainer { switch (value) { - case 'explorer': return ViewLocation.Explorer; - case 'debug': return ViewLocation.Debug; - case 'scm': return ViewLocation.SCM; - default: return ViewLocation.get(`workbench.view.extension.${value}`); + case 'explorer': return this.viewContainersRegistry.get(EXPLORER); + case 'debug': return this.viewContainersRegistry.get(DEBUG); + case 'scm': return this.viewContainersRegistry.get(SCM); + default: return this.viewContainersRegistry.get(`workbench.view.extension.${value}`); } } - private showCollapsed(location: ViewLocation): boolean { - switch (location) { - case ViewLocation.Explorer: - case ViewLocation.SCM: - case ViewLocation.Debug: + private showCollapsed(container: ViewContainer): boolean { + switch (container.id) { + case EXPLORER: + case SCM: + case DEBUG: return true; } return false; diff --git a/src/vs/workbench/browser/parts/views/views.ts b/src/vs/workbench/browser/parts/views/views.ts index 8309b9a3c7b..224f3bafbff 100644 --- a/src/vs/workbench/browser/parts/views/views.ts +++ b/src/vs/workbench/browser/parts/views/views.ts @@ -7,7 +7,7 @@ import 'vs/css!./media/views'; import { Disposable } from 'vs/base/common/lifecycle'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IViewsService, ViewsRegistry, IViewsViewlet, ViewLocation, IViewDescriptor } from 'vs/workbench/common/views'; +import { IViewsService, ViewsRegistry, IViewsViewlet, ViewContainer, IViewDescriptor, IViewContainersRegistry, Extensions as ViewContainerExtensions, TEST_VIEWLET_ID } from 'vs/workbench/common/views'; import { Registry } from 'vs/platform/registry/common/platform'; import { ViewletRegistry, Extensions as ViewletExtensions } from 'vs/workbench/browser/viewlet'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; @@ -18,9 +18,9 @@ import { Event, chain, filterEvent, Emitter } from 'vs/base/common/event'; import { sortedDiff, firstIndex, move } from 'vs/base/common/arrays'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; -function filterViewEvent(location: ViewLocation, event: Event): Event { +function filterViewEvent(container: ViewContainer, event: Event): Event { return chain(event) - .map(views => views.filter(view => view.location === location)) + .map(views => views.filter(view => view.container === container)) .filter(views => views.length > 0) .event; } @@ -77,20 +77,20 @@ class ViewDescriptorCollection extends Disposable { } constructor( - location: ViewLocation, + container: ViewContainer, @IContextKeyService private contextKeyService: IContextKeyService ) { super(); - const onRelevantViewsRegistered = filterViewEvent(location, ViewsRegistry.onViewsRegistered); + const onRelevantViewsRegistered = filterViewEvent(container, ViewsRegistry.onViewsRegistered); this._register(onRelevantViewsRegistered(this.onViewsRegistered, this)); - const onRelevantViewsDeregistered = filterViewEvent(location, ViewsRegistry.onViewsDeregistered); + const onRelevantViewsDeregistered = filterViewEvent(container, ViewsRegistry.onViewsDeregistered); this._register(onRelevantViewsDeregistered(this.onViewsDeregistered, this)); const onRelevantContextChange = filterEvent(contextKeyService.onDidChangeContext, e => e.affectsSome(this.contextKeys)); this._register(onRelevantContextChange(this.onContextChanged, this)); - this.onViewsRegistered(ViewsRegistry.getViews(location)); + this.onViewsRegistered(ViewsRegistry.getViews(container)); } private onViewsRegistered(viewDescriptors: IViewDescriptor[]): any { @@ -211,12 +211,12 @@ export class ContributableViewsModel extends Disposable { readonly onDidMove: Event<{ from: IViewDescriptorRef; to: IViewDescriptorRef; }> = this._onDidMove.event; constructor( - location: ViewLocation, + container: ViewContainer, contextKeyService: IContextKeyService, protected viewStates = new Map(), ) { super(); - const viewDescriptorCollection = this._register(new ViewDescriptorCollection(location, contextKeyService)); + const viewDescriptorCollection = this._register(new ViewDescriptorCollection(container, contextKeyService)); this._register(viewDescriptorCollection.onDidChange(() => this.onDidChangeViewDescriptors(viewDescriptorCollection.viewDescriptors))); this.onDidChangeViewDescriptors(viewDescriptorCollection.viewDescriptors); @@ -413,7 +413,7 @@ export class PersistentContributableViewsModel extends ContributableViewsModel { private contextService: IWorkspaceContextService; constructor( - location: ViewLocation, + container: ViewContainer, viewletStateStorageId: string, @IContextKeyService contextKeyService: IContextKeyService, @IStorageService storageService: IStorageService, @@ -422,7 +422,7 @@ export class PersistentContributableViewsModel extends ContributableViewsModel { const hiddenViewsStorageId = `${viewletStateStorageId}.hidden`; const viewStates = PersistentContributableViewsModel.loadViewsStates(viewletStateStorageId, hiddenViewsStorageId, storageService, contextService); - super(location, contextKeyService, viewStates); + super(container, contextKeyService, viewStates); this.viewletStateStorageId = viewletStateStorageId; this.hiddenViewsStorageId = hiddenViewsStorageId; @@ -494,15 +494,16 @@ export class ViewsService extends Disposable implements IViewsService { ) { super(); - ViewLocation.all.forEach(viewLocation => this.onDidRegisterViewLocation(viewLocation)); - this._register(ViewLocation.onDidRegister(viewLocation => this.onDidRegisterViewLocation(viewLocation))); - this._register(Registry.as(ViewletExtensions.Viewlets).onDidRegister(viewlet => this.viewletService.setViewletEnablement(viewlet.id, this.storageService.getBoolean(`viewservice.${viewlet.id}.enablement`, StorageScope.GLOBAL, viewlet.id !== ViewLocation.TEST.id)))); + const viewContainersRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); + viewContainersRegistry.all.forEach(viewContainer => this.onDidRegisterViewContainer(viewContainer)); + this._register(viewContainersRegistry.onDidRegister(viewContainer => this.onDidRegisterViewContainer(viewContainer))); + this._register(Registry.as(ViewletExtensions.Viewlets).onDidRegister(viewlet => this.viewletService.setViewletEnablement(viewlet.id, this.storageService.getBoolean(`viewservice.${viewlet.id}.enablement`, StorageScope.GLOBAL, viewlet.id !== TEST_VIEWLET_ID)))); } openView(id: string, focus: boolean): TPromise { const viewDescriptor = ViewsRegistry.getView(id); if (viewDescriptor) { - const viewletDescriptor = this.viewletService.getViewlet(viewDescriptor.location.id); + const viewletDescriptor = this.viewletService.getViewlet(viewDescriptor.container.id); if (viewletDescriptor) { return this.viewletService.openViewlet(viewletDescriptor.id) .then((viewlet: IViewsViewlet) => { @@ -516,15 +517,15 @@ export class ViewsService extends Disposable implements IViewsService { return TPromise.as(null); } - private onDidRegisterViewLocation(viewLocation: ViewLocation): void { - const viewDescriptorCollection = this._register(this.instantiationService.createInstance(ViewDescriptorCollection, viewLocation)); - this._register(viewDescriptorCollection.onDidChange(() => this.updateViewletEnablement(viewLocation, viewDescriptorCollection))); - this.lifecycleService.when(LifecyclePhase.Eventually).then(() => this.updateViewletEnablement(viewLocation, viewDescriptorCollection)); + private onDidRegisterViewContainer(viewContainer: ViewContainer): void { + const viewDescriptorCollection = this._register(this.instantiationService.createInstance(ViewDescriptorCollection, viewContainer)); + this._register(viewDescriptorCollection.onDidChange(() => this.updateViewletEnablement(viewContainer, viewDescriptorCollection))); + this.lifecycleService.when(LifecyclePhase.Eventually).then(() => this.updateViewletEnablement(viewContainer, viewDescriptorCollection)); } - private updateViewletEnablement(viewLocation: ViewLocation, viewDescriptorCollection: ViewDescriptorCollection): void { + private updateViewletEnablement(viewContainer: ViewContainer, viewDescriptorCollection: ViewDescriptorCollection): void { const enabled = viewDescriptorCollection.viewDescriptors.length > 0; - this.viewletService.setViewletEnablement(viewLocation.id, enabled); - this.storageService.store(`viewservice.${viewLocation.id}.enablement`, enabled, StorageScope.GLOBAL); + this.viewletService.setViewletEnablement(viewContainer.id, enabled); + this.storageService.store(`viewservice.${viewContainer.id}.enablement`, enabled, StorageScope.GLOBAL); } } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/views/viewsViewlet.ts b/src/vs/workbench/browser/parts/views/viewsViewlet.ts index 71370c7bec3..9f95a21a6eb 100644 --- a/src/vs/workbench/browser/parts/views/viewsViewlet.ts +++ b/src/vs/workbench/browser/parts/views/viewsViewlet.ts @@ -13,7 +13,7 @@ import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { firstIndex } from 'vs/base/common/arrays'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { ViewLocation, IViewDescriptor, IViewsViewlet } from 'vs/workbench/common/views'; +import { IViewDescriptor, IViewsViewlet, IViewContainersRegistry, Extensions as ViewContainerExtensions } from 'vs/workbench/common/views'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -31,6 +31,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IPartService } from 'vs/workbench/services/part/common/partService'; import { localize } from 'vs/nls'; import { IAddedViewDescriptorRef, IViewDescriptorRef, PersistentContributableViewsModel } from 'vs/workbench/browser/parts/views/views'; +import { Registry } from 'vs/platform/registry/common/platform'; export abstract class TreeViewsViewletPanel extends ViewletPanel { @@ -107,7 +108,7 @@ export interface IViewletViewOptions extends IViewletPanelOptions { viewletSettings: object; } -export abstract class ViewsViewlet extends PanelViewlet implements IViewsViewlet { +export abstract class ViewContainerViewlet extends PanelViewlet implements IViewsViewlet { private readonly viewletSettings: Object; private didLayout = false; @@ -121,7 +122,6 @@ export abstract class ViewsViewlet extends PanelViewlet implements IViewsViewlet constructor( id: string, - location: ViewLocation, viewletStateStorageId: string, showHeaderInTitleWhenSingleView: boolean, @IPartService partService: IPartService, @@ -135,7 +135,8 @@ export abstract class ViewsViewlet extends PanelViewlet implements IViewsViewlet ) { super(id, { showHeaderInTitleWhenSingleView, dnd: new DefaultPanelDndController() }, partService, contextMenuService, telemetryService, themeService); - this.viewsModel = this._register(this.instantiationService.createInstance(PersistentContributableViewsModel, location, viewletStateStorageId)); + const container = Registry.as(ViewContainerExtensions.ViewContainersRegistry).get(id); + this.viewsModel = this._register(this.instantiationService.createInstance(PersistentContributableViewsModel, container, viewletStateStorageId)); this.viewletSettings = this.getMemento(storageService, Scope.WORKSPACE); this.visibleViewsStorageId = `${id}.numberOfVisibleViews`; diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index c37ce9f7939..388553473ed 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -15,46 +15,87 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { IDisposable } from 'vs/base/common/lifecycle'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; import { values } from 'vs/base/common/map'; +import { Registry } from 'vs/platform/registry/common/platform'; -export class ViewLocation { - - private static readonly _onDidRegister: Emitter = new Emitter(); - static readonly onDidRegister: Event = ViewLocation._onDidRegister.event; - - private static locations: Map = new Map(); - static register(id: string): ViewLocation { - if (!ViewLocation.locations.has(id)) { - const viewLocation = new ViewLocation(id); - ViewLocation.locations.set(id, viewLocation); - ViewLocation._onDidRegister.fire(viewLocation); - } - return ViewLocation.get(id); - } - static get(value: string): ViewLocation { - return ViewLocation.locations.get(value); - } - static get all(): ViewLocation[] { - return values(ViewLocation.locations); - } - - static readonly Explorer: ViewLocation = ViewLocation.register('workbench.view.explorer'); - static readonly Debug: ViewLocation = ViewLocation.register('workbench.view.debug'); - static readonly Extensions: ViewLocation = ViewLocation.register('workbench.view.extensions'); - static readonly SCM: ViewLocation = ViewLocation.register('workbench.view.scm'); - static readonly TEST: ViewLocation = ViewLocation.register('workbench.view.extension.test'); - - private constructor(private _id: string) { } - get id(): string { return this._id; } +export const TEST_VIEWLET_ID = 'workbench.view.extension.test'; +export namespace Extensions { + export const ViewContainersRegistry = 'workbench.registry.view.containers'; } +export interface IViewContainersRegistry { + /** + * An event that is triggerred when a view container is registered. + */ + readonly onDidRegister: Event; + + /** + * All registered view containers + */ + readonly all: ViewContainer[]; + + /** + * Registers a view container with given id + * No op if a view container is already registered with the given id. + * + * @param id of the view container. + * + * @returns the registered ViewContainer. + */ + registerViewContainer(id: string): ViewContainer; + + /** + * Returns the view container with given id. + * + * @param id + * @returns the view container with given id. + */ + get(id: string): ViewContainer; +} + +export class ViewContainer { + protected constructor(private _id: string) { } + get id(): string { return this._id; } +} + +class ViewContainersRegistryImpl implements IViewContainersRegistry { + + private readonly _onDidRegister: Emitter = new Emitter(); + readonly onDidRegister: Event = this._onDidRegister.event; + + private viewContainers: Map = new Map(); + + get all(): ViewContainer[] { + return values(this.viewContainers); + } + + registerViewContainer(id: string): ViewContainer { + if (!this.viewContainers.has(id)) { + const viewContainer = new class extends ViewContainer { + constructor() { + super(id); + } + }; + this.viewContainers.set(id, viewContainer); + this._onDidRegister.fire(viewContainer); + } + return this.get(id); + } + + get(id: string): ViewContainer { + return this.viewContainers.get(id); + } +} + +Registry.add(Extensions.ViewContainersRegistry, new ViewContainersRegistryImpl()); + export interface IViewDescriptor { readonly id: string; readonly name: string; - readonly location: ViewLocation; + readonly container: ViewContainer; // TODO do we really need this?! readonly ctor: any; @@ -80,9 +121,9 @@ export interface IViewsRegistry { registerViews(views: IViewDescriptor[]): void; - deregisterViews(ids: string[], location: ViewLocation): void; + deregisterViews(ids: string[], container: ViewContainer): void; - getViews(loc: ViewLocation): IViewDescriptor[]; + getViews(loc: ViewContainer): IViewDescriptor[]; getView(id: string): IViewDescriptor; @@ -96,20 +137,20 @@ export const ViewsRegistry: IViewsRegistry = new class implements IViewsRegistry private readonly _onViewsDeregistered: Emitter = new Emitter(); readonly onViewsDeregistered: Event = this._onViewsDeregistered.event; - private _viewLocations: ViewLocation[] = []; - private _views: Map = new Map(); + private _viewContainer: ViewContainer[] = []; + private _views: Map = new Map(); registerViews(viewDescriptors: IViewDescriptor[]): void { if (viewDescriptors.length) { for (const viewDescriptor of viewDescriptors) { - let views = this._views.get(viewDescriptor.location); + let views = this._views.get(viewDescriptor.container); if (!views) { views = []; - this._views.set(viewDescriptor.location, views); - this._viewLocations.push(viewDescriptor.location); + this._views.set(viewDescriptor.container, views); + this._viewContainer.push(viewDescriptor.container); } if (views.some(v => v.id === viewDescriptor.id)) { - throw new Error(localize('duplicateId', "A view with id '{0}' is already registered in the location '{1}'", viewDescriptor.id, viewDescriptor.location.id)); + throw new Error(localize('duplicateId', "A view with id '{0}' is already registered in the container '{1}'", viewDescriptor.id, viewDescriptor.container.id)); } views.push(viewDescriptor); } @@ -117,8 +158,8 @@ export const ViewsRegistry: IViewsRegistry = new class implements IViewsRegistry } } - deregisterViews(ids: string[], location: ViewLocation): void { - const views = this._views.get(location); + deregisterViews(ids: string[], container: ViewContainer): void { + const views = this._views.get(container); if (!views) { return; @@ -129,23 +170,23 @@ export const ViewsRegistry: IViewsRegistry = new class implements IViewsRegistry if (viewsToDeregister.length) { const remaningViews = views.filter(view => ids.indexOf(view.id) === -1); if (remaningViews.length) { - this._views.set(location, remaningViews); + this._views.set(container, remaningViews); } else { - this._views.delete(location); - this._viewLocations.splice(this._viewLocations.indexOf(location), 1); + this._views.delete(container); + this._viewContainer.splice(this._viewContainer.indexOf(container), 1); } this._onViewsDeregistered.fire(viewsToDeregister); } } - getViews(loc: ViewLocation): IViewDescriptor[] { + getViews(loc: ViewContainer): IViewDescriptor[] { return this._views.get(loc) || []; } getView(id: string): IViewDescriptor { - for (const viewLocation of this._viewLocations) { - const viewDescriptor = (this._views.get(viewLocation) || []).filter(v => v.id === id)[0]; + for (const viewContainer of this._viewContainer) { + const viewDescriptor = (this._views.get(viewContainer) || []).filter(v => v.id === id)[0]; if (viewDescriptor) { return viewDescriptor; } diff --git a/src/vs/workbench/parts/debug/browser/debugViewlet.ts b/src/vs/workbench/parts/debug/browser/debugViewlet.ts index 3c52b35c976..04f9c90f3db 100644 --- a/src/vs/workbench/parts/debug/browser/debugViewlet.ts +++ b/src/vs/workbench/parts/debug/browser/debugViewlet.ts @@ -9,7 +9,7 @@ import { Action, IAction } from 'vs/base/common/actions'; import * as DOM from 'vs/base/browser/dom'; import { TPromise } from 'vs/base/common/winjs.base'; import { IActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; -import { ViewsViewlet } from 'vs/workbench/browser/parts/views/viewsViewlet'; +import { ViewContainerViewlet } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { IDebugService, VIEWLET_ID, State, VARIABLES_VIEW_ID, WATCH_VIEW_ID, CALLSTACK_VIEW_ID, BREAKPOINTS_VIEW_ID, IDebugConfiguration } from 'vs/workbench/parts/debug/common/debug'; import { StartAction, ToggleReplAction, ConfigureAction, AbstractDebugAction, SelectAndStartAction, FocusSessionAction } from 'vs/workbench/parts/debug/browser/debugActions'; import { StartDebugActionItem, FocusSessionActionItem } from 'vs/workbench/parts/debug/browser/debugActionItems'; @@ -28,10 +28,9 @@ import { memoize } from 'vs/base/common/decorators'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { DebugActionsWidget } from 'vs/workbench/parts/debug/browser/debugActionsWidget'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { ViewLocation } from 'vs/workbench/common/views'; import { ViewletPanel } from 'vs/workbench/browser/parts/views/panelViewlet'; -export class DebugViewlet extends ViewsViewlet { +export class DebugViewlet extends ViewContainerViewlet { private startDebugActionItem: StartDebugActionItem; private progressRunner: IProgressRunner; @@ -54,7 +53,7 @@ export class DebugViewlet extends ViewsViewlet { @IKeybindingService private keybindingService: IKeybindingService, @IContextViewService private contextViewService: IContextViewService, ) { - super(VIEWLET_ID, ViewLocation.Debug, `${VIEWLET_ID}.state`, false, partService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); + super(VIEWLET_ID, `${VIEWLET_ID}.state`, false, partService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); this.progressRunner = null; diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index 8645bb02a0d..ca0ddfcb9ca 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -21,8 +21,12 @@ import { RawContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/con import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IDisposable } from 'vs/base/common/lifecycle'; +import { IViewContainersRegistry, ViewContainer, Extensions as ViewContainerExtensions } from 'vs/workbench/common/views'; +import { Registry } from 'vs/platform/registry/common/platform'; export const VIEWLET_ID = 'workbench.view.debug'; +export const VIEW_CONTAINER: ViewContainer = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer(VIEWLET_ID); + export const VARIABLES_VIEW_ID = 'workbench.debug.variablesView'; export const WATCH_VIEW_ID = 'workbench.debug.watchExpressionsView'; export const CALLSTACK_VIEW_ID = 'workbench.debug.callStackView'; diff --git a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts index c6fe531b8ab..4026503292e 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts @@ -23,7 +23,7 @@ import { CallStackView } from 'vs/workbench/parts/debug/electron-browser/callSta import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; import { IDebugService, VIEWLET_ID, REPL_ID, CONTEXT_NOT_IN_DEBUG_MODE, CONTEXT_IN_DEBUG_MODE, INTERNAL_CONSOLE_OPTIONS_SCHEMA, - CONTEXT_DEBUG_STATE, VARIABLES_VIEW_ID, CALLSTACK_VIEW_ID, WATCH_VIEW_ID, BREAKPOINTS_VIEW_ID + CONTEXT_DEBUG_STATE, VARIABLES_VIEW_ID, CALLSTACK_VIEW_ID, WATCH_VIEW_ID, BREAKPOINTS_VIEW_ID, VIEW_CONTAINER } from 'vs/workbench/parts/debug/common/debug'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; @@ -40,7 +40,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { registerCommands } from 'vs/workbench/parts/debug/browser/debugCommands'; import { IQuickOpenRegistry, Extensions as QuickOpenExtensions, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen'; import { StatusBarColorProvider } from 'vs/workbench/parts/debug/browser/statusbarColorProvider'; -import { ViewLocation, ViewsRegistry } from 'vs/workbench/common/views'; +import { ViewsRegistry } from 'vs/workbench/common/views'; import { isMacintosh } from 'vs/base/common/platform'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import URI from 'vs/base/common/uri'; @@ -108,10 +108,10 @@ Registry.as(PanelExtensions.Panels).registerPanel(new PanelDescri Registry.as(PanelExtensions.Panels).setDefaultPanelId(REPL_ID); // Register default debug views -ViewsRegistry.registerViews([{ id: VARIABLES_VIEW_ID, name: nls.localize('variables', "Variables"), ctor: VariablesView, order: 10, weight: 40, location: ViewLocation.Debug, canToggleVisibility: true }]); -ViewsRegistry.registerViews([{ id: WATCH_VIEW_ID, name: nls.localize('watch', "Watch"), ctor: WatchExpressionsView, order: 20, weight: 10, location: ViewLocation.Debug, canToggleVisibility: true }]); -ViewsRegistry.registerViews([{ id: CALLSTACK_VIEW_ID, name: nls.localize('callStack', "Call Stack"), ctor: CallStackView, order: 30, weight: 30, location: ViewLocation.Debug, canToggleVisibility: true }]); -ViewsRegistry.registerViews([{ id: BREAKPOINTS_VIEW_ID, name: nls.localize('breakpoints', "Breakpoints"), ctor: BreakpointsView, order: 40, weight: 20, location: ViewLocation.Debug, canToggleVisibility: true }]); +ViewsRegistry.registerViews([{ id: VARIABLES_VIEW_ID, name: nls.localize('variables', "Variables"), ctor: VariablesView, order: 10, weight: 40, container: VIEW_CONTAINER, canToggleVisibility: true }]); +ViewsRegistry.registerViews([{ id: WATCH_VIEW_ID, name: nls.localize('watch', "Watch"), ctor: WatchExpressionsView, order: 20, weight: 10, container: VIEW_CONTAINER, canToggleVisibility: true }]); +ViewsRegistry.registerViews([{ id: CALLSTACK_VIEW_ID, name: nls.localize('callStack', "Call Stack"), ctor: CallStackView, order: 30, weight: 30, container: VIEW_CONTAINER, canToggleVisibility: true }]); +ViewsRegistry.registerViews([{ id: BREAKPOINTS_VIEW_ID, name: nls.localize('breakpoints', "Breakpoints"), ctor: BreakpointsView, order: 40, weight: 20, container: VIEW_CONTAINER, canToggleVisibility: true }]); // register action to open viewlet const registry = Registry.as(WorkbenchActionRegistryExtensions.WorkbenchActions); diff --git a/src/vs/workbench/parts/extensions/common/extensions.ts b/src/vs/workbench/parts/extensions/common/extensions.ts index 6697ce40301..0a8636cb1ef 100644 --- a/src/vs/workbench/parts/extensions/common/extensions.ts +++ b/src/vs/workbench/parts/extensions/common/extensions.ts @@ -9,8 +9,11 @@ import { Event } from 'vs/base/common/event'; import { TPromise } from 'vs/base/common/winjs.base'; import { IPager } from 'vs/base/common/paging'; import { IQueryOptions, IExtensionManifest, LocalExtensionType, EnablementState, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IViewContainersRegistry, ViewContainer, Extensions as ViewContainerExtensions } from 'vs/workbench/common/views'; +import { Registry } from 'vs/platform/registry/common/platform'; export const VIEWLET_ID = 'workbench.view.extensions'; +export const VIEW_CONTAINER: ViewContainer = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer(VIEWLET_ID); export interface IExtensionsViewlet extends IViewlet { search(text: string): void; diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 3714af7ede4..640fd2f2564 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -24,7 +24,7 @@ import { append, $, addStandardDisposableListener, EventType, addClass, removeCl import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, ExtensionState, AutoUpdateConfigurationKey, ShowRecommendationsOnlyOnDemandKey } from '../common/extensions'; +import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, ExtensionState, AutoUpdateConfigurationKey, ShowRecommendationsOnlyOnDemandKey, VIEW_CONTAINER } from '../common/extensions'; import { ShowEnabledExtensionsAction, ShowInstalledExtensionsAction, ShowRecommendedExtensionsAction, ShowPopularExtensionsAction, ShowDisabledExtensionsAction, ShowOutdatedExtensionsAction, ClearExtensionsInputAction, ChangeSortAction, UpdateAllAction, CheckForUpdatesAction, DisableAllAction, EnableAllAction, @@ -41,8 +41,8 @@ import { IActivityService, ProgressBadge, NumberBadge } from 'vs/workbench/servi import { IThemeService } from 'vs/platform/theme/common/themeService'; import { inputForeground, inputBackground, inputBorder } from 'vs/platform/theme/common/colorRegistry'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ViewsRegistry, ViewLocation, IViewDescriptor } from 'vs/workbench/common/views'; -import { ViewsViewlet } from 'vs/workbench/browser/parts/views/viewsViewlet'; +import { ViewsRegistry, IViewDescriptor } from 'vs/workbench/common/views'; +import { ViewContainerViewlet } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IContextKeyService, ContextKeyExpr, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey'; @@ -92,7 +92,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id: 'extensions.listView', name: localize('marketPlace', "Marketplace"), - location: ViewLocation.Extensions, + container: VIEW_CONTAINER, ctor: ExtensionsListView, when: ContextKeyExpr.and(ContextKeyExpr.not('donotshowExtensions'), ContextKeyExpr.has('searchExtensions'), ContextKeyExpr.not('searchInstalledExtensions'), ContextKeyExpr.not('searchBuiltInExtensions'), ContextKeyExpr.not('recommendedExtensions')), weight: 100 @@ -103,7 +103,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id: 'extensions.installedList', name: localize('installedExtensions', "Installed"), - location: ViewLocation.Extensions, + container: VIEW_CONTAINER, ctor: InstalledExtensionsView, when: ContextKeyExpr.and(ContextKeyExpr.not('donotshowExtensions'), ContextKeyExpr.not('searchExtensions')), order: 1, @@ -115,7 +115,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id: 'extensions.searchInstalledList', name: localize('searchInstalledExtensions', "Installed"), - location: ViewLocation.Extensions, + container: VIEW_CONTAINER, ctor: InstalledExtensionsView, when: ContextKeyExpr.and(ContextKeyExpr.not('donotshowExtensions'), ContextKeyExpr.has('searchInstalledExtensions')), weight: 100 @@ -126,7 +126,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id: 'extensions.recommendedList', name: localize('recommendedExtensions', "Recommended"), - location: ViewLocation.Extensions, + container: VIEW_CONTAINER, ctor: RecommendedExtensionsView, when: ContextKeyExpr.and(ContextKeyExpr.not('donotshowExtensions'), ContextKeyExpr.not('searchExtensions'), ContextKeyExpr.has('defaultRecommendedExtensions')), weight: 70, @@ -139,7 +139,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id: 'extensions.otherrecommendedList', name: localize('otherRecommendedExtensions', "Other Recommendations"), - location: ViewLocation.Extensions, + container: VIEW_CONTAINER, ctor: RecommendedExtensionsView, when: ContextKeyExpr.and(ContextKeyExpr.not('donotshowExtensions'), ContextKeyExpr.has('recommendedExtensions')), weight: 50, @@ -152,7 +152,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id: 'extensions.workspaceRecommendedList', name: localize('workspaceRecommendedExtensions', "Workspace Recommendations"), - location: ViewLocation.Extensions, + container: VIEW_CONTAINER, ctor: WorkspaceRecommendedExtensionsView, when: ContextKeyExpr.and(ContextKeyExpr.not('donotshowExtensions'), ContextKeyExpr.has('recommendedExtensions'), ContextKeyExpr.has('nonEmptyWorkspace')), weight: 50, @@ -165,7 +165,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id: 'extensions.builtInExtensionsList', name: localize('builtInExtensions', "Features"), - location: ViewLocation.Extensions, + container: VIEW_CONTAINER, ctor: BuiltInExtensionsView, when: ContextKeyExpr.and(ContextKeyExpr.not('donotshowExtensions'), ContextKeyExpr.has('searchBuiltInExtensions')), weight: 100, @@ -177,7 +177,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id: 'extensions.builtInThemesExtensionsList', name: localize('builtInThemesExtensions', "Themes"), - location: ViewLocation.Extensions, + container: VIEW_CONTAINER, ctor: BuiltInThemesExtensionsView, when: ContextKeyExpr.and(ContextKeyExpr.not('donotshowExtensions'), ContextKeyExpr.has('searchBuiltInExtensions')), weight: 100, @@ -189,7 +189,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id: 'extensions.builtInBasicsExtensionsList', name: localize('builtInBasicsExtensions', "Programming Languages"), - location: ViewLocation.Extensions, + container: VIEW_CONTAINER, ctor: BuiltInBasicsExtensionsView, when: ContextKeyExpr.and(ContextKeyExpr.not('donotshowExtensions'), ContextKeyExpr.has('searchBuiltInExtensions')), weight: 100, @@ -198,7 +198,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio } } -export class ExtensionsViewlet extends ViewsViewlet implements IExtensionsViewlet { +export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensionsViewlet { private onSearchChange: EventOf; private nonEmptyWorkspaceContextKey: IContextKey; @@ -234,7 +234,7 @@ export class ExtensionsViewlet extends ViewsViewlet implements IExtensionsViewle @IContextMenuService contextMenuService: IContextMenuService, @IExtensionService extensionService: IExtensionService ) { - super(VIEWLET_ID, ViewLocation.Extensions, `${VIEWLET_ID}.state`, true, partService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); + super(VIEWLET_ID, `${VIEWLET_ID}.state`, true, partService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); this.searchDelayer = new ThrottledDelayer(500); this.nonEmptyWorkspaceContextKey = NonEmptyWorkspaceContext.bindTo(contextKeyService); diff --git a/src/vs/workbench/parts/files/common/files.ts b/src/vs/workbench/parts/files/common/files.ts index 1ddc3245d5f..26c9bd956ca 100644 --- a/src/vs/workbench/parts/files/common/files.ts +++ b/src/vs/workbench/parts/files/common/files.ts @@ -21,11 +21,17 @@ import { IModeService } from 'vs/editor/common/services/modeService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IViewlet } from 'vs/workbench/common/viewlet'; import { InputFocusedContextKey } from 'vs/platform/workbench/common/contextkeys'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { IViewContainersRegistry, Extensions as ViewContainerExtensions, ViewContainer } from 'vs/workbench/common/views'; /** * Explorer viewlet id. */ export const VIEWLET_ID = 'workbench.view.explorer'; +/** + * Explorer viewlet container. + */ +export const VIEW_CONTAINER: ViewContainer = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer(VIEWLET_ID); export interface IExplorerViewlet extends IViewlet { getExplorerView(): IExplorerView; diff --git a/src/vs/workbench/parts/files/electron-browser/explorerViewlet.ts b/src/vs/workbench/parts/files/electron-browser/explorerViewlet.ts index 5cbc914aa1d..57326f16477 100644 --- a/src/vs/workbench/parts/files/electron-browser/explorerViewlet.ts +++ b/src/vs/workbench/parts/files/electron-browser/explorerViewlet.ts @@ -10,8 +10,8 @@ import { localize } from 'vs/nls'; import { IActionRunner } from 'vs/base/common/actions'; import { TPromise } from 'vs/base/common/winjs.base'; import * as DOM from 'vs/base/browser/dom'; -import { VIEWLET_ID, ExplorerViewletVisibleContext, IFilesConfiguration, OpenEditorsVisibleContext, OpenEditorsVisibleCondition, IExplorerViewlet } from 'vs/workbench/parts/files/common/files'; -import { ViewsViewlet, IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; +import { VIEWLET_ID, ExplorerViewletVisibleContext, IFilesConfiguration, OpenEditorsVisibleContext, OpenEditorsVisibleCondition, IExplorerViewlet, VIEW_CONTAINER } from 'vs/workbench/parts/files/common/files'; +import { ViewContainerViewlet, IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; import { ActionRunner, FileViewletState } from 'vs/workbench/parts/files/electron-browser/views/explorerViewer'; import { ExplorerView, IExplorerViewOptions } from 'vs/workbench/parts/files/electron-browser/views/explorerView'; @@ -26,7 +26,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { ViewsRegistry, ViewLocation, IViewDescriptor } from 'vs/workbench/common/views'; +import { ViewsRegistry, IViewDescriptor } from 'vs/workbench/common/views'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { Disposable } from 'vs/base/common/lifecycle'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; @@ -60,7 +60,7 @@ export class ExplorerViewletViewsContribution extends Disposable implements IWor } private registerViews(): void { - const viewDescriptors = ViewsRegistry.getViews(ViewLocation.Explorer); + const viewDescriptors = ViewsRegistry.getViews(VIEW_CONTAINER); let viewDescriptorsToRegister = []; let viewDescriptorsToDeregister: string[] = []; @@ -95,7 +95,7 @@ export class ExplorerViewletViewsContribution extends Disposable implements IWor ViewsRegistry.registerViews(viewDescriptorsToRegister); } if (viewDescriptorsToDeregister.length) { - ViewsRegistry.deregisterViews(viewDescriptorsToDeregister, ViewLocation.Explorer); + ViewsRegistry.deregisterViews(viewDescriptorsToDeregister, VIEW_CONTAINER); } } @@ -103,7 +103,7 @@ export class ExplorerViewletViewsContribution extends Disposable implements IWor return { id: OpenEditorsView.ID, name: OpenEditorsView.NAME, - location: ViewLocation.Explorer, + container: VIEW_CONTAINER, ctor: OpenEditorsView, order: 0, when: OpenEditorsVisibleCondition, @@ -115,7 +115,7 @@ export class ExplorerViewletViewsContribution extends Disposable implements IWor return { id: EmptyView.ID, name: EmptyView.NAME, - location: ViewLocation.Explorer, + container: VIEW_CONTAINER, ctor: EmptyView, order: 1, canToggleVisibility: false @@ -126,7 +126,7 @@ export class ExplorerViewletViewsContribution extends Disposable implements IWor return { id: ExplorerView.ID, name: localize('folders', "Folders"), - location: ViewLocation.Explorer, + container: VIEW_CONTAINER, ctor: ExplorerView, order: 1, canToggleVisibility: false @@ -144,7 +144,7 @@ export class ExplorerViewletViewsContribution extends Disposable implements IWor } } -export class ExplorerViewlet extends ViewsViewlet implements IExplorerViewlet { +export class ExplorerViewlet extends ViewContainerViewlet implements IExplorerViewlet { private static readonly EXPLORER_VIEWS_STATE = 'workbench.explorer.views.state'; @@ -165,7 +165,7 @@ export class ExplorerViewlet extends ViewsViewlet implements IExplorerViewlet { @IContextMenuService contextMenuService: IContextMenuService, @IExtensionService extensionService: IExtensionService ) { - super(VIEWLET_ID, ViewLocation.Explorer, ExplorerViewlet.EXPLORER_VIEWS_STATE, true, partService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); + super(VIEWLET_ID, ExplorerViewlet.EXPLORER_VIEWS_STATE, true, partService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); this.viewletState = new FileViewletState(); this.viewletVisibleContextKey = ExplorerViewletVisibleContext.bindTo(contextKeyService); diff --git a/src/vs/workbench/parts/outline/electron-browser/outline.contribution.ts b/src/vs/workbench/parts/outline/electron-browser/outline.contribution.ts index ffcccb8a0be..f89d36ec269 100644 --- a/src/vs/workbench/parts/outline/electron-browser/outline.contribution.ts +++ b/src/vs/workbench/parts/outline/electron-browser/outline.contribution.ts @@ -6,15 +6,16 @@ import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { localize } from 'vs/nls'; -import { IViewsService, ViewLocation, ViewsRegistry, IViewDescriptor } from 'vs/workbench/common/views'; +import { IViewsService, ViewsRegistry, IViewDescriptor } from 'vs/workbench/common/views'; import { OutlinePanel } from './outlinePanel'; import { MenuRegistry } from 'vs/platform/actions/common/actions'; +import { VIEW_CONTAINER } from 'vs/workbench/parts/files/common/files'; const _outlineDesc = { id: 'code.outline', name: localize('name', "Outline"), ctor: OutlinePanel, - location: ViewLocation.Explorer, + container: VIEW_CONTAINER, canToggleVisibility: true, hideByDefault: false, order: 2 diff --git a/src/vs/workbench/parts/quickopen/browser/viewPickerHandler.ts b/src/vs/workbench/parts/quickopen/browser/viewPickerHandler.ts index 67702340e3e..711590c7b4a 100644 --- a/src/vs/workbench/parts/quickopen/browser/viewPickerHandler.ts +++ b/src/vs/workbench/parts/quickopen/browser/viewPickerHandler.ts @@ -19,9 +19,10 @@ import { Action } from 'vs/base/common/actions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { fuzzyContains, stripWildcards } from 'vs/base/common/strings'; import { matchesFuzzy } from 'vs/base/common/filters'; -import { ViewsRegistry, ViewLocation, IViewsService } from 'vs/workbench/common/views'; +import { ViewsRegistry, ViewContainer, IViewsService, IViewContainersRegistry, Extensions as ViewContainerExtensions } from 'vs/workbench/common/views'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ViewletDescriptor } from 'vs/workbench/browser/viewlet'; +import { Registry } from 'vs/platform/registry/common/platform'; export const VIEW_PICKER_PREFIX = 'view '; @@ -121,8 +122,8 @@ export class ViewPickerHandler extends QuickOpenHandler { private getViewEntries(): ViewEntry[] { const viewEntries: ViewEntry[] = []; - const getViewEntriesForViewlet = (viewlet: ViewletDescriptor, viewLocation: ViewLocation): ViewEntry[] => { - const views = ViewsRegistry.getViews(viewLocation); + const getViewEntriesForViewlet = (viewlet: ViewletDescriptor, viewContainer: ViewContainer): ViewEntry[] => { + const views = ViewsRegistry.getViews(viewContainer); const result: ViewEntry[] = []; if (views.length) { for (const view of views) { @@ -144,9 +145,9 @@ export class ViewPickerHandler extends QuickOpenHandler { // Viewlet Views viewlets.forEach((viewlet, index) => { - const viewLocation: ViewLocation = ViewLocation.get(viewlet.id); - if (viewLocation) { - const viewEntriesForViewlet: ViewEntry[] = getViewEntriesForViewlet(viewlet, viewLocation); + const viewContainer: ViewContainer = Registry.as(ViewContainerExtensions.ViewContainersRegistry).get(viewlet.id); + if (viewContainer) { + const viewEntriesForViewlet: ViewEntry[] = getViewEntriesForViewlet(viewlet, viewContainer); viewEntries.push(...viewEntriesForViewlet); } }); diff --git a/src/vs/workbench/parts/scm/common/scm.ts b/src/vs/workbench/parts/scm/common/scm.ts index df029c458ce..df666e72994 100644 --- a/src/vs/workbench/parts/scm/common/scm.ts +++ b/src/vs/workbench/parts/scm/common/scm.ts @@ -5,4 +5,8 @@ 'use strict'; -export const VIEWLET_ID = 'workbench.view.scm'; \ No newline at end of file +import { Registry } from 'vs/platform/registry/common/platform'; +import { IViewContainersRegistry, ViewContainer, Extensions as ViewContainerExtensions } from 'vs/workbench/common/views'; + +export const VIEWLET_ID = 'workbench.view.scm'; +export const VIEW_CONTAINER: ViewContainer = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer(VIEWLET_ID); \ No newline at end of file diff --git a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts index 0e9c249e135..b7b1c3f6baa 100644 --- a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts +++ b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts @@ -13,12 +13,12 @@ import { domEvent, stop } from 'vs/base/browser/event'; import { basename } from 'vs/base/common/paths'; import { onUnexpectedError } from 'vs/base/common/errors'; import { IDisposable, dispose, combinedDisposable, empty as EmptyDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { PanelViewlet, ViewletPanel } from 'vs/workbench/browser/parts/views/panelViewlet'; +import { PanelViewlet, ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; import { append, $, addClass, toggleClass, trackFocus, Dimension, addDisposableListener } from 'vs/base/browser/dom'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { List } from 'vs/base/browser/ui/list/listWidget'; import { IDelegate, IRenderer, IListContextMenuEvent, IListEvent } from 'vs/base/browser/ui/list/list'; -import { VIEWLET_ID } from 'vs/workbench/parts/scm/common/scm'; +import { VIEWLET_ID, VIEW_CONTAINER } from 'vs/workbench/parts/scm/common/scm'; import { FileLabel } from 'vs/workbench/browser/labels'; import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge'; import { ISCMService, ISCMRepository, ISCMResourceGroup, ISCMResource, InputValidationType } from 'vs/workbench/services/scm/common/scm'; @@ -57,7 +57,7 @@ import { ThrottledDelayer } from 'vs/base/common/async'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import { IViewDescriptorRef, PersistentContributableViewsModel, IAddedViewDescriptorRef } from 'vs/workbench/browser/parts/views/views'; -import { ViewLocation, IViewDescriptor, IViewsViewlet } from 'vs/workbench/common/views'; +import { IViewDescriptor, IViewsViewlet } from 'vs/workbench/common/views'; import { IPanelDndController, Panel } from 'vs/base/browser/ui/splitview/panelview'; export interface ISpliceEvent { @@ -1084,7 +1084,7 @@ export class SCMViewlet extends PanelViewlet implements IViewModel, IViewsViewle this.menus = instantiationService.createInstance(SCMMenus, undefined); this.menus.onDidChangeTitle(this.updateTitleArea, this, this.disposables); - this.contributedViews = new PersistentContributableViewsModel(ViewLocation.SCM, 'scm.views', contextKeyService, storageService, contextService); + this.contributedViews = new PersistentContributableViewsModel(VIEW_CONTAINER, 'scm.views', contextKeyService, storageService, contextService); this.disposables.push(this.contributedViews); } @@ -1360,9 +1360,9 @@ export class SCMViewlet extends PanelViewlet implements IViewModel, IViewsViewle const panelsToAdd: { panel: ViewletPanel, size: number, index: number }[] = []; for (const { viewDescriptor, collapsed, index, size } of added) { - const panel = this.instantiationService.createInstance(viewDescriptor.ctor, { + const panel = this.instantiationService.createInstance(viewDescriptor.ctor, { id: viewDescriptor.id, - name: viewDescriptor.name, + title: viewDescriptor.name, actionRunner: this.getActionRunner(), expanded: !collapsed }) as ViewletPanel; diff --git a/src/vs/workbench/test/browser/parts/views/views.test.ts b/src/vs/workbench/test/browser/parts/views/views.test.ts index 0c1cfed91f3..0f4ef153328 100644 --- a/src/vs/workbench/test/browser/parts/views/views.test.ts +++ b/src/vs/workbench/test/browser/parts/views/views.test.ts @@ -5,14 +5,15 @@ import * as assert from 'assert'; import { ContributableViewsModel } from 'vs/workbench/browser/parts/views/views'; -import { ViewLocation, ViewsRegistry, IViewDescriptor } from 'vs/workbench/common/views'; +import { ViewsRegistry, IViewDescriptor, IViewContainersRegistry, Extensions as ViewContainerExtensions } from 'vs/workbench/common/views'; import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyService'; import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { move } from 'vs/base/common/arrays'; +import { Registry } from 'vs/platform/registry/common/platform'; -const location = ViewLocation.register('test'); +const container = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer('test'); class ViewDescriptorSequence { @@ -44,12 +45,12 @@ suite('ContributableViewsModel', () => { }); test('empty model', function () { - const model = new ContributableViewsModel(location, contextKeyService); + const model = new ContributableViewsModel(container, contextKeyService); assert.equal(model.visibleViewDescriptors.length, 0); }); test('register/unregister', function () { - const model = new ContributableViewsModel(location, contextKeyService); + const model = new ContributableViewsModel(container, contextKeyService); const seq = new ViewDescriptorSequence(model); assert.equal(model.visibleViewDescriptors.length, 0); @@ -58,7 +59,7 @@ suite('ContributableViewsModel', () => { const viewDescriptor: IViewDescriptor = { id: 'view1', ctor: null, - location, + container, name: 'Test View 1' }; @@ -69,14 +70,14 @@ suite('ContributableViewsModel', () => { assert.deepEqual(model.visibleViewDescriptors[0], viewDescriptor); assert.deepEqual(seq.elements[0], viewDescriptor); - ViewsRegistry.deregisterViews(['view1'], location); + ViewsRegistry.deregisterViews(['view1'], container); assert.equal(model.visibleViewDescriptors.length, 0); assert.equal(seq.elements.length, 0); }); test('when contexts', async function () { - const model = new ContributableViewsModel(location, contextKeyService); + const model = new ContributableViewsModel(container, contextKeyService); const seq = new ViewDescriptorSequence(model); assert.equal(model.visibleViewDescriptors.length, 0); @@ -85,7 +86,7 @@ suite('ContributableViewsModel', () => { const viewDescriptor: IViewDescriptor = { id: 'view1', ctor: null, - location, + container, name: 'Test View 1', when: ContextKeyExpr.equals('showview1', true) }; @@ -110,7 +111,7 @@ suite('ContributableViewsModel', () => { assert.equal(model.visibleViewDescriptors.length, 0, 'view should disappear'); assert.equal(seq.elements.length, 0); - ViewsRegistry.deregisterViews(['view1'], location); + ViewsRegistry.deregisterViews(['view1'], container); assert.equal(model.visibleViewDescriptors.length, 0, 'view should not be there anymore'); assert.equal(seq.elements.length, 0); @@ -121,11 +122,11 @@ suite('ContributableViewsModel', () => { }); test('when contexts - multiple', async function () { - const model = new ContributableViewsModel(location, contextKeyService); + const model = new ContributableViewsModel(container, contextKeyService); const seq = new ViewDescriptorSequence(model); - const view1: IViewDescriptor = { id: 'view1', ctor: null, location, name: 'Test View 1' }; - const view2: IViewDescriptor = { id: 'view2', ctor: null, location, name: 'Test View 2', when: ContextKeyExpr.equals('showview2', true) }; + const view1: IViewDescriptor = { id: 'view1', ctor: null, container, name: 'Test View 1' }; + const view2: IViewDescriptor = { id: 'view2', ctor: null, container, name: 'Test View 2', when: ContextKeyExpr.equals('showview2', true) }; ViewsRegistry.registerViews([view1, view2]); assert.deepEqual(model.visibleViewDescriptors, [view1], 'only view1 should be visible'); @@ -140,15 +141,15 @@ suite('ContributableViewsModel', () => { assert.deepEqual(model.visibleViewDescriptors, [view1, view2], 'both views should be visible'); assert.deepEqual(seq.elements, [view1, view2], 'both views should be visible'); - ViewsRegistry.deregisterViews([view1.id, view2.id], location); + ViewsRegistry.deregisterViews([view1.id, view2.id], container); }); test('when contexts - multiple 2', async function () { - const model = new ContributableViewsModel(location, contextKeyService); + const model = new ContributableViewsModel(container, contextKeyService); const seq = new ViewDescriptorSequence(model); - const view1: IViewDescriptor = { id: 'view1', ctor: null, location, name: 'Test View 1', when: ContextKeyExpr.equals('showview1', true) }; - const view2: IViewDescriptor = { id: 'view2', ctor: null, location, name: 'Test View 2' }; + const view1: IViewDescriptor = { id: 'view1', ctor: null, container, name: 'Test View 1', when: ContextKeyExpr.equals('showview1', true) }; + const view2: IViewDescriptor = { id: 'view2', ctor: null, container, name: 'Test View 2' }; ViewsRegistry.registerViews([view1, view2]); assert.deepEqual(model.visibleViewDescriptors, [view2], 'only view2 should be visible'); @@ -163,16 +164,16 @@ suite('ContributableViewsModel', () => { assert.deepEqual(model.visibleViewDescriptors, [view1, view2], 'both views should be visible'); assert.deepEqual(seq.elements, [view1, view2], 'both views should be visible'); - ViewsRegistry.deregisterViews([view1.id, view2.id], location); + ViewsRegistry.deregisterViews([view1.id, view2.id], container); }); test('setVisible', function () { - const model = new ContributableViewsModel(location, contextKeyService); + const model = new ContributableViewsModel(container, contextKeyService); const seq = new ViewDescriptorSequence(model); - const view1: IViewDescriptor = { id: 'view1', ctor: null, location, name: 'Test View 1', canToggleVisibility: true }; - const view2: IViewDescriptor = { id: 'view2', ctor: null, location, name: 'Test View 2', canToggleVisibility: true }; - const view3: IViewDescriptor = { id: 'view3', ctor: null, location, name: 'Test View 3', canToggleVisibility: true }; + const view1: IViewDescriptor = { id: 'view1', ctor: null, container, name: 'Test View 1', canToggleVisibility: true }; + const view2: IViewDescriptor = { id: 'view2', ctor: null, container, name: 'Test View 2', canToggleVisibility: true }; + const view3: IViewDescriptor = { id: 'view3', ctor: null, container, name: 'Test View 3', canToggleVisibility: true }; ViewsRegistry.registerViews([view1, view2, view3]); assert.deepEqual(model.visibleViewDescriptors, [view1, view2, view3]); @@ -206,18 +207,18 @@ suite('ContributableViewsModel', () => { assert.deepEqual(model.visibleViewDescriptors, [view1, view2, view3], 'view2 should show'); assert.deepEqual(seq.elements, [view1, view2, view3]); - ViewsRegistry.deregisterViews([view1.id, view2.id, view3.id], location); + ViewsRegistry.deregisterViews([view1.id, view2.id, view3.id], container); assert.deepEqual(model.visibleViewDescriptors, []); assert.deepEqual(seq.elements, []); }); test('move', function () { - const model = new ContributableViewsModel(location, contextKeyService); + const model = new ContributableViewsModel(container, contextKeyService); const seq = new ViewDescriptorSequence(model); - const view1: IViewDescriptor = { id: 'view1', ctor: null, location, name: 'Test View 1' }; - const view2: IViewDescriptor = { id: 'view2', ctor: null, location, name: 'Test View 2' }; - const view3: IViewDescriptor = { id: 'view3', ctor: null, location, name: 'Test View 3' }; + const view1: IViewDescriptor = { id: 'view1', ctor: null, container, name: 'Test View 1' }; + const view2: IViewDescriptor = { id: 'view2', ctor: null, container, name: 'Test View 2' }; + const view3: IViewDescriptor = { id: 'view3', ctor: null, container, name: 'Test View 3' }; ViewsRegistry.registerViews([view1, view2, view3]); assert.deepEqual(model.visibleViewDescriptors, [view1, view2, view3], 'model views should be OK');