diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index 0ebf0e9893dd91ecfc0dd1932612378138ccff25..191ae51ea6da5af7071840d043f17e3f7669fc65 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 } from 'vs/platform/extensions/common/extensionsRegistry'; -import { ViewLocation, ViewsRegistry, IViewDescriptor } from 'vs/workbench/browser/parts/views/viewsRegistry'; +import { ViewLocation, ViewsRegistry, IViewDescriptor } from 'vs/workbench/common/views'; import { TreeView } from 'vs/workbench/browser/parts/views/treeView'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { coalesce, } from 'vs/base/common/arrays'; diff --git a/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts b/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts index e9730fb0ed4206ea9e26f6de1fbbb874665a4ca7..67bd6438fe5dfd73ad2d4ed62abf4acf54a6a342 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts @@ -9,8 +9,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { Disposable } from 'vs/base/common/lifecycle'; import { ExtHostContext, MainThreadTreeViewsShape, ExtHostTreeViewsShape, MainContext, IExtHostContext } from '../node/extHost.protocol'; import { IMessageService, Severity } from 'vs/platform/message/common/message'; -import { ViewsRegistry } from 'vs/workbench/browser/parts/views/viewsRegistry'; -import { ITreeViewDataProvider, ITreeItem } from 'vs/workbench/common/views'; +import { ViewsRegistry, ITreeViewDataProvider, ITreeItem } from 'vs/workbench/common/views'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { assign } from 'vs/base/common/objects'; diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index 7c31277a9a3c8f9c18fb46e6fc7945dcef469dcb..a1cb7fc94687fc87dd90060d3702c5999331ffe1 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -22,11 +22,10 @@ import { IProgressService } from 'vs/platform/progress/common/progress'; import { ITree, IDataSource, IRenderer, ContextMenuEvent } from 'vs/base/parts/tree/browser/tree'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ActionItem, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; -import { ViewsRegistry } from 'vs/workbench/browser/parts/views/viewsRegistry'; +import { ViewsRegistry, TreeItemCollapsibleState, ITreeItem, ITreeViewDataProvider, TreeViewItemHandleArg } from 'vs/workbench/common/views'; import { IExtensionService } from 'vs/platform/extensions/common/extensions'; import { IViewletViewOptions, IViewOptions, TreeViewsViewletPanel, FileIconThemableWorkbenchTree } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { ICommandService } from 'vs/platform/commands/common/commands'; -import { TreeItemCollapsibleState, ITreeItem, ITreeViewDataProvider, TreeViewItemHandleArg } from 'vs/workbench/common/views'; import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService'; import { ResourceLabel } from 'vs/workbench/browser/labels'; import URI from 'vs/base/common/uri'; diff --git a/src/vs/workbench/browser/parts/views/viewsRegistry.ts b/src/vs/workbench/browser/parts/views/viewsRegistry.ts deleted file mode 100644 index aa8ccb4bdcaf4b37669a359e35081c8841c37fdc..0000000000000000000000000000000000000000 --- a/src/vs/workbench/browser/parts/views/viewsRegistry.ts +++ /dev/null @@ -1,149 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import Event, { Emitter } from 'vs/base/common/event'; -import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { ITreeViewDataProvider } from 'vs/workbench/common/views'; -import { localize } from 'vs/nls'; - -export class ViewLocation { - - static readonly Explorer = new ViewLocation('explorer'); - static readonly Debug = new ViewLocation('debug'); - static readonly Extensions = new ViewLocation('extensions'); - - constructor(private _id: string) { - } - - get id(): string { - return this._id; - } - - static getContributedViewLocation(value: string): ViewLocation { - switch (value) { - case ViewLocation.Explorer.id: return ViewLocation.Explorer; - case ViewLocation.Debug.id: return ViewLocation.Debug; - } - return void 0; - } -} - -export interface IViewDescriptor { - - readonly id: string; - - readonly name: string; - - readonly location: ViewLocation; - - // TODO do we really need this?! - readonly ctor: any; - - readonly when?: ContextKeyExpr; - - readonly order?: number; - - readonly weight?: number; - - readonly collapsed?: boolean; - - readonly canToggleVisibility?: boolean; -} - -export interface IViewsRegistry { - - readonly onViewsRegistered: Event; - - readonly onViewsDeregistered: Event; - - readonly onTreeViewDataProviderRegistered: Event; - - registerViews(views: IViewDescriptor[]): void; - - deregisterViews(ids: string[], location: ViewLocation): void; - - registerTreeViewDataProvider(id: string, factory: ITreeViewDataProvider): void; - - deregisterTreeViewDataProviders(): void; - - getViews(loc: ViewLocation): IViewDescriptor[]; - - getTreeViewDataProvider(id: string): ITreeViewDataProvider; - -} - -export const ViewsRegistry: IViewsRegistry = new class implements IViewsRegistry { - - private _onViewsRegistered: Emitter = new Emitter(); - readonly onViewsRegistered: Event = this._onViewsRegistered.event; - - private _onViewsDeregistered: Emitter = new Emitter(); - readonly onViewsDeregistered: Event = this._onViewsDeregistered.event; - - private _onTreeViewDataProviderRegistered: Emitter = new Emitter(); - readonly onTreeViewDataProviderRegistered: Event = this._onTreeViewDataProviderRegistered.event; - - private _views: Map = new Map(); - private _treeViewDataPoviders: Map = new Map(); - - registerViews(viewDescriptors: IViewDescriptor[]): void { - if (viewDescriptors.length) { - for (const viewDescriptor of viewDescriptors) { - let views = this._views.get(viewDescriptor.location); - if (!views) { - views = []; - this._views.set(viewDescriptor.location, views); - } - 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)); - } - views.push(viewDescriptor); - } - this._onViewsRegistered.fire(viewDescriptors); - } - } - - deregisterViews(ids: string[], location: ViewLocation): void { - const views = this._views.get(location); - - if (!views) { - return; - } - - const viewsToDeregister = views.filter(view => ids.indexOf(view.id) !== -1); - - if (viewsToDeregister.length) { - this._views.set(location, views.filter(view => ids.indexOf(view.id) === -1)); - } - - this._onViewsDeregistered.fire(viewsToDeregister); - } - - registerTreeViewDataProvider(id: string, factory: ITreeViewDataProvider) { - if (!this.isDataProviderRegistered(id)) { - // TODO: throw error - } - this._treeViewDataPoviders.set(id, factory); - this._onTreeViewDataProviderRegistered.fire(id); - } - - deregisterTreeViewDataProviders(): void { - this._treeViewDataPoviders.clear(); - } - - getViews(loc: ViewLocation): IViewDescriptor[] { - return this._views.get(loc) || []; - } - - getTreeViewDataProvider(id: string): ITreeViewDataProvider { - return this._treeViewDataPoviders.get(id); - } - - private isDataProviderRegistered(id: string): boolean { - let registered = false; - this._views.forEach(views => registered = registered || views.some(view => view.id === id)); - return registered; - } -}; diff --git a/src/vs/workbench/browser/parts/views/viewsViewlet.ts b/src/vs/workbench/browser/parts/views/viewsViewlet.ts index 346a1b1a23cda6709e5d4e14295bfc458d50b949..e2f5a2f40071e8d0f4a02c5b9a293097c1829b8e 100644 --- a/src/vs/workbench/browser/parts/views/viewsViewlet.ts +++ b/src/vs/workbench/browser/parts/views/viewsViewlet.ts @@ -17,7 +17,7 @@ import { DelayedDragHandler } from 'vs/base/browser/dnd'; import { IExtensionService } from 'vs/platform/extensions/common/extensions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { ViewsRegistry, ViewLocation, IViewDescriptor } from 'vs/workbench/browser/parts/views/viewsRegistry'; +import { ViewsRegistry, ViewLocation, IViewDescriptor, IViewsViewlet } 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'; @@ -259,7 +259,7 @@ export interface IViewState { order: number; } -export class ViewsViewlet extends PanelViewlet { +export class ViewsViewlet extends PanelViewlet implements IViewsViewlet { private viewHeaderContextMenuListeners: IDisposable[] = []; private viewletSettings: object; @@ -324,6 +324,15 @@ export class ViewsViewlet extends PanelViewlet { .then(() => void 0); } + focusView(id: string): void { + this.focus(); + const view = this.getView(id); + if (view) { + view.setExpanded(true); + view.focus(); + } + } + layout(dimension: Dimension): void { super.layout(dimension); this.dimension = dimension; diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index 5d7b138ae5e32174b605e2db605bd9b18b23c3ee..52bfe92583ae845d536ec9b639ffc92019c61174 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -4,9 +4,161 @@ *--------------------------------------------------------------------------------------------*/ import { TPromise } from 'vs/base/common/winjs.base'; -import Event from 'vs/base/common/event'; import { Command } from 'vs/editor/common/modes'; import { UriComponents } from 'vs/base/common/uri'; +import Event, { Emitter } from 'vs/base/common/event'; +import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { ITreeViewDataProvider } from 'vs/workbench/common/views'; +import { localize } from 'vs/nls'; +import { IViewlet } from 'vs/workbench/common/viewlet'; + +export class ViewLocation { + + static readonly Explorer = new ViewLocation('explorer'); + static readonly Debug = new ViewLocation('debug'); + static readonly Extensions = new ViewLocation('extensions'); + + constructor(private _id: string) { + } + + get id(): string { + return this._id; + } + + static getContributedViewLocation(value: string): ViewLocation { + switch (value) { + case ViewLocation.Explorer.id: return ViewLocation.Explorer; + case ViewLocation.Debug.id: return ViewLocation.Debug; + } + return void 0; + } +} + +export interface IViewDescriptor { + + readonly id: string; + + readonly name: string; + + readonly location: ViewLocation; + + // TODO do we really need this?! + readonly ctor: any; + + readonly when?: ContextKeyExpr; + + readonly order?: number; + + readonly weight?: number; + + readonly collapsed?: boolean; + + readonly canToggleVisibility?: boolean; +} + +export interface IViewsRegistry { + + readonly onViewsRegistered: Event; + + readonly onViewsDeregistered: Event; + + readonly onTreeViewDataProviderRegistered: Event; + + registerViews(views: IViewDescriptor[]): void; + + deregisterViews(ids: string[], location: ViewLocation): void; + + registerTreeViewDataProvider(id: string, factory: ITreeViewDataProvider): void; + + deregisterTreeViewDataProviders(): void; + + getViews(loc: ViewLocation): IViewDescriptor[]; + + getTreeViewDataProvider(id: string): ITreeViewDataProvider; + +} + +export const ViewsRegistry: IViewsRegistry = new class implements IViewsRegistry { + + private _onViewsRegistered: Emitter = new Emitter(); + readonly onViewsRegistered: Event = this._onViewsRegistered.event; + + private _onViewsDeregistered: Emitter = new Emitter(); + readonly onViewsDeregistered: Event = this._onViewsDeregistered.event; + + private _onTreeViewDataProviderRegistered: Emitter = new Emitter(); + readonly onTreeViewDataProviderRegistered: Event = this._onTreeViewDataProviderRegistered.event; + + private _views: Map = new Map(); + private _treeViewDataPoviders: Map = new Map(); + + registerViews(viewDescriptors: IViewDescriptor[]): void { + if (viewDescriptors.length) { + for (const viewDescriptor of viewDescriptors) { + let views = this._views.get(viewDescriptor.location); + if (!views) { + views = []; + this._views.set(viewDescriptor.location, views); + } + 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)); + } + views.push(viewDescriptor); + } + this._onViewsRegistered.fire(viewDescriptors); + } + } + + deregisterViews(ids: string[], location: ViewLocation): void { + const views = this._views.get(location); + + if (!views) { + return; + } + + const viewsToDeregister = views.filter(view => ids.indexOf(view.id) !== -1); + + if (viewsToDeregister.length) { + this._views.set(location, views.filter(view => ids.indexOf(view.id) === -1)); + } + + this._onViewsDeregistered.fire(viewsToDeregister); + } + + registerTreeViewDataProvider(id: string, factory: ITreeViewDataProvider) { + if (!this.isDataProviderRegistered(id)) { + // TODO: throw error + } + this._treeViewDataPoviders.set(id, factory); + this._onTreeViewDataProviderRegistered.fire(id); + } + + deregisterTreeViewDataProviders(): void { + this._treeViewDataPoviders.clear(); + } + + getViews(loc: ViewLocation): IViewDescriptor[] { + return this._views.get(loc) || []; + } + + getTreeViewDataProvider(id: string): ITreeViewDataProvider { + return this._treeViewDataPoviders.get(id); + } + + private isDataProviderRegistered(id: string): boolean { + let registered = false; + this._views.forEach(views => registered = registered || views.some(view => view.id === id)); + return registered; + } +}; + +export interface IViewsViewlet extends IViewlet { + + focusView(id: string): void; + +} + +// Custom view export type TreeViewItemHandleArg = { $treeViewId: string, diff --git a/src/vs/workbench/parts/debug/browser/debugViewlet.ts b/src/vs/workbench/parts/debug/browser/debugViewlet.ts index 803cb32cb64add0402b9af75e5785aea4025155f..67381c841c1609432ac39c17fef64ee085a875d9 100644 --- a/src/vs/workbench/parts/debug/browser/debugViewlet.ts +++ b/src/vs/workbench/parts/debug/browser/debugViewlet.ts @@ -22,7 +22,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; -import { ViewLocation } from 'vs/workbench/browser/parts/views/viewsRegistry'; +import { ViewLocation } from 'vs/workbench/common/views'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; 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 043476e62ced30fbfb13a41fd3427362c4652c1c..f8768ff718e8b2a4d777b43b7141ec0e642d9572 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts @@ -41,7 +41,7 @@ import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/edi import * as debugCommands from 'vs/workbench/parts/debug/electron-browser/debugCommands'; import { IQuickOpenRegistry, Extensions as QuickOpenExtensions, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen'; import { StatusBarColorProvider } from 'vs/workbench/parts/debug/electron-browser/statusbarColorProvider'; -import { ViewLocation, ViewsRegistry } from 'vs/workbench/browser/parts/views/viewsRegistry'; +import { ViewLocation, 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'; diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 5adfee8f751e4f2079317d5edaefbf07708db1d0..ac4d9aafbc78dbc565f88c3d136192c5d6b49881 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -45,7 +45,7 @@ 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/browser/parts/views/viewsRegistry'; +import { ViewsRegistry, ViewLocation, IViewDescriptor } from 'vs/workbench/common/views'; import { PersistentViewsViewlet, ViewsViewletPanel } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; diff --git a/src/vs/workbench/parts/files/electron-browser/explorerViewlet.ts b/src/vs/workbench/parts/files/electron-browser/explorerViewlet.ts index 7d3b763b318a379ba9551f6432ee7ebf5eb47001..7dd040a28c2b37482b722d2af1bfb940495c7100 100644 --- a/src/vs/workbench/parts/files/electron-browser/explorerViewlet.ts +++ b/src/vs/workbench/parts/files/electron-browser/explorerViewlet.ts @@ -30,50 +30,31 @@ import { IWorkbenchEditorService, DelegatingWorkbenchEditorService } from 'vs/wo import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { ViewsRegistry, ViewLocation, IViewDescriptor } from 'vs/workbench/browser/parts/views/viewsRegistry'; +import { ViewsRegistry, ViewLocation, 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'; -export class ExplorerViewlet extends PersistentViewsViewlet implements IExplorerViewlet { - private static readonly EXPLORER_VIEWS_STATE = 'workbench.explorer.views.state'; +export class ExplorerViewletViewsContribution extends Disposable implements IWorkbenchContribution { - private viewletState: FileViewletState; - private viewletVisibleContextKey: IContextKey; private openEditorsVisibleContextKey: IContextKey; constructor( - @ITelemetryService telemetryService: ITelemetryService, - @IWorkspaceContextService protected contextService: IWorkspaceContextService, - @IStorageService protected storageService: IStorageService, - @IEditorGroupService private editorGroupService: IEditorGroupService, - @IWorkbenchEditorService private editorService: IWorkbenchEditorService, + @IWorkspaceContextService private workspaceContextService: IWorkspaceContextService, @IConfigurationService private configurationService: IConfigurationService, - @IInstantiationService protected instantiationService: IInstantiationService, - @IContextKeyService contextKeyService: IContextKeyService, - @IThemeService themeService: IThemeService, - @IContextMenuService contextMenuService: IContextMenuService, - @IExtensionService extensionService: IExtensionService + @IContextKeyService contextKeyService: IContextKeyService ) { - super(VIEWLET_ID, ViewLocation.Explorer, ExplorerViewlet.EXPLORER_VIEWS_STATE, true, telemetryService, storageService, instantiationService, themeService, contextService, contextKeyService, contextMenuService, extensionService); - - this.viewletState = new FileViewletState(); - this.viewletVisibleContextKey = ExplorerViewletVisibleContext.bindTo(contextKeyService); - this.openEditorsVisibleContextKey = OpenEditorsVisibleContext.bindTo(contextKeyService); + super(); this.registerViews(); + + this.openEditorsVisibleContextKey = OpenEditorsVisibleContext.bindTo(contextKeyService); this.updateOpenEditorsVisibility(); + this._register(workspaceContextService.onDidChangeWorkbenchState(() => this.registerViews())); + this._register(workspaceContextService.onDidChangeWorkspaceFolders(() => this.registerViews())); this._register(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(e))); - this._register(this.contextService.onDidChangeWorkspaceName(e => this.updateTitleArea())); - this._register(this.contextService.onDidChangeWorkbenchState(() => this.registerViews())); - this._register(this.contextService.onDidChangeWorkspaceFolders(() => this.registerViews())); - } - - async create(parent: Builder): TPromise { - await super.create(parent); - - const el = parent.getHTMLElement(); - DOM.addClass(el, 'explorer-viewlet'); } private registerViews(): void { @@ -92,7 +73,7 @@ export class ExplorerViewlet extends PersistentViewsViewlet implements IExplorer if (!openEditorsViewDescriptorExists) { viewDescriptorsToRegister.push(openEditorsViewDescriptor); } - if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY || this.contextService.getWorkspace().folders.length === 0) { + if (this.workspaceContextService.getWorkbenchState() === WorkbenchState.EMPTY || this.workspaceContextService.getWorkspace().folders.length === 0) { if (explorerViewDescriptorExists) { viewDescriptorsToDeregister.push(explorerViewDescriptor.id); } @@ -157,7 +138,43 @@ export class ExplorerViewlet extends PersistentViewsViewlet implements IExplorer } private updateOpenEditorsVisibility(): void { - this.openEditorsVisibleContextKey.set(this.isOpenEditorsVisible()); + this.openEditorsVisibleContextKey.set(this.workspaceContextService.getWorkbenchState() === WorkbenchState.EMPTY || this.configurationService.getValue('explorer.openEditors.visible') !== 0); + } +} + +export class ExplorerViewlet extends PersistentViewsViewlet implements IExplorerViewlet { + + private static readonly EXPLORER_VIEWS_STATE = 'workbench.explorer.views.state'; + + private viewletState: FileViewletState; + private viewletVisibleContextKey: IContextKey; + + constructor( + @ITelemetryService telemetryService: ITelemetryService, + @IWorkspaceContextService protected contextService: IWorkspaceContextService, + @IStorageService protected storageService: IStorageService, + @IEditorGroupService private editorGroupService: IEditorGroupService, + @IWorkbenchEditorService private editorService: IWorkbenchEditorService, + @IConfigurationService private configurationService: IConfigurationService, + @IInstantiationService protected instantiationService: IInstantiationService, + @IContextKeyService contextKeyService: IContextKeyService, + @IThemeService themeService: IThemeService, + @IContextMenuService contextMenuService: IContextMenuService, + @IExtensionService extensionService: IExtensionService + ) { + super(VIEWLET_ID, ViewLocation.Explorer, ExplorerViewlet.EXPLORER_VIEWS_STATE, true, telemetryService, storageService, instantiationService, themeService, contextService, contextKeyService, contextMenuService, extensionService); + + this.viewletState = new FileViewletState(); + this.viewletVisibleContextKey = ExplorerViewletVisibleContext.bindTo(contextKeyService); + + this._register(this.contextService.onDidChangeWorkspaceName(e => this.updateTitleArea())); + } + + async create(parent: Builder): TPromise { + await super.create(parent); + + const el = parent.getHTMLElement(); + DOM.addClass(el, 'explorer-viewlet'); } private isOpenEditorsVisible(): boolean { diff --git a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts index ad7b20637ca9316b0b3ba6e326c143dd2926e0e5..1f3a9ba56f35f92a3b517d7adc459d34353f9b88 100644 --- a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts @@ -29,7 +29,7 @@ import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/edi import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import * as platform from 'vs/base/common/platform'; import { DirtyFilesTracker } from 'vs/workbench/parts/files/common/dirtyFilesTracker'; -import { ExplorerViewlet } from 'vs/workbench/parts/files/electron-browser/explorerViewlet'; +import { ExplorerViewlet, ExplorerViewletViewsContribution } from 'vs/workbench/parts/files/electron-browser/explorerViewlet'; import { IEditorRegistry, EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/editor'; import { DataUriEditorInput } from 'vs/workbench/common/editor/dataUriEditorInput'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; @@ -139,6 +139,9 @@ class FileEditorInputFactory implements IEditorInputFactory { Registry.as(EditorInputExtensions.EditorInputFactories).registerEditorInputFactory(FILE_EDITOR_INPUT_ID, FileEditorInputFactory); +// Register Explorer views +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(ExplorerViewletViewsContribution, LifecyclePhase.Starting); + // Register File Editor Tracker Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(FileEditorTracker, LifecyclePhase.Starting); diff --git a/src/vs/workbench/parts/quickopen/browser/viewPickerHandler.ts b/src/vs/workbench/parts/quickopen/browser/viewPickerHandler.ts index bcfefc9f74f8b3a3796b528c5cd900c8914a97c2..58741eab47b0c4ae7613a00747a2d0f14dbcf8eb 100644 --- a/src/vs/workbench/parts/quickopen/browser/viewPickerHandler.ts +++ b/src/vs/workbench/parts/quickopen/browser/viewPickerHandler.ts @@ -19,6 +19,12 @@ 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, IViewsViewlet } from 'vs/workbench/common/views'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { VIEWLET_ID as EXPLORER_VIEWLET_ID } from 'vs/workbench/parts/files/common/files'; +import { VIEWLET_ID as DEBUG_VIEWLET_ID } from 'vs/workbench/parts/debug/common/debug'; +import { VIEWLET_ID as EXTENSIONS_VIEWLET_ID } from 'vs/workbench/parts/extensions/common/extensions'; +import { ViewletDescriptor } from 'vs/workbench/browser/viewlet'; export const VIEW_PICKER_PREFIX = 'view '; @@ -69,7 +75,8 @@ export class ViewPickerHandler extends QuickOpenHandler { @IViewletService private viewletService: IViewletService, @IOutputService private outputService: IOutputService, @ITerminalService private terminalService: ITerminalService, - @IPanelService private panelService: IPanelService + @IPanelService private panelService: IPanelService, + @IContextKeyService private contextKeyService: IContextKeyService, ) { super(); } @@ -116,12 +123,31 @@ export class ViewPickerHandler extends QuickOpenHandler { private getViewEntries(): ViewEntry[] { const viewEntries: ViewEntry[] = []; + const getViewEntriesForViewlet = (viewlet: ViewletDescriptor, viewLocation: ViewLocation): ViewEntry[] => { + const views = ViewsRegistry.getViews(viewLocation); + const result: ViewEntry[] = []; + if (views.length) { + for (const view of views) { + if (this.contextKeyService.contextMatchesRules(view.when)) { + result.push(new ViewEntry(view.name, viewlet.name, () => this.viewletService.openViewlet(viewlet.id, true).done(viewlet => (viewlet).focusView(view.id), errors.onUnexpectedError))); + } + } + } + return result; + }; + // Viewlets const viewlets = this.viewletService.getViewlets(); viewlets.forEach((viewlet, index) => { - const viewsCategory = nls.localize('views', "Views"); - const entry = new ViewEntry(viewlet.name, viewsCategory, () => this.viewletService.openViewlet(viewlet.id, true).done(null, errors.onUnexpectedError)); - viewEntries.push(entry); + const viewLocation: ViewLocation = viewlet.id === EXPLORER_VIEWLET_ID ? ViewLocation.Explorer + : viewlet.id === DEBUG_VIEWLET_ID ? ViewLocation.Debug + : viewlet.id === EXTENSIONS_VIEWLET_ID ? ViewLocation.Extensions + : null; + + const viewEntriesForViewlet: ViewEntry[] = viewLocation ? getViewEntriesForViewlet(viewlet, viewLocation) + : [new ViewEntry(viewlet.name, nls.localize('views', "Views"), () => this.viewletService.openViewlet(viewlet.id, true).done(null, errors.onUnexpectedError))]; + + viewEntries.push(...viewEntriesForViewlet); }); const terminals = this.terminalService.terminalInstances;