diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index 65bb4afb1dd..e198a29483d 100644 --- a/src/vs/workbench/api/browser/viewsExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsExtensionPoint.ts @@ -8,7 +8,7 @@ import { forEach } from 'vs/base/common/collections'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import * as resources from 'vs/base/common/resources'; import { ExtensionMessageCollector, ExtensionsRegistry, IExtensionPoint, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry'; -import { ViewContainer, IViewsRegistry, ITreeViewDescriptor, IViewContainersRegistry, Extensions as ViewContainerExtensions, TEST_VIEW_CONTAINER_ID, IViewDescriptor, ViewContainerLocation } from 'vs/workbench/common/views'; +import { ViewContainer, IViewsRegistry, ITreeViewDescriptor, IViewContainersRegistry, Extensions as ViewContainerExtensions, TEST_VIEW_CONTAINER_ID, IViewDescriptor, ViewContainerLocation, IViewDescriptorService } from 'vs/workbench/common/views'; import { CustomTreeViewPane, CustomTreeView } from 'vs/workbench/browser/parts/views/customView'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { coalesce, } from 'vs/base/common/arrays'; @@ -325,8 +325,9 @@ class ViewsExtensionHandler implements IWorkbenchContribution { @IThemeService themeService: IThemeService, @IContextMenuService contextMenuService: IContextMenuService, @IExtensionService extensionService: IExtensionService, + @IViewDescriptorService viewDescriptorService: IViewDescriptorService ) { - super(id, `${id}.state`, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService); + super(id, `${id}.state`, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService); } } diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index 4220c47084b..f5b71ab1813 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -131,6 +131,7 @@ export class PanelPart extends CompositePart implements IPanelService { getCompositePinnedAction: (compositeId: string) => this.getCompositeActions(compositeId).pinnedAction, getOnCompositeClickAction: (compositeId: string) => this.instantiationService.createInstance(PanelActivityAction, assertIsDefined(this.getPanel(compositeId))), getContextMenuActions: () => [ + ...this.getContextMenuActions(), ...PositionPanelActionConfigs // show the contextual menu item if it is not in that position .filter(({ when }) => contextKeyService.contextMatchesRules(when)) @@ -160,6 +161,16 @@ export class PanelPart extends CompositePart implements IPanelService { this.onDidRegisterPanels([...this.getPanels()]); } + private getContextMenuActions(): readonly IAction[] { + const activePanel = this.getActivePanel(); + + if (!activePanel) { + return []; + } + + return activePanel.getContextMenuActions(); + } + private onDidRegisterPanels(panels: PanelDescriptor[]): void { for (const panel of panels) { const cachedPanel = this.getCachedPanels().filter(({ id }) => id === panel.id)[0]; diff --git a/src/vs/workbench/browser/parts/views/viewPaneContainer.ts b/src/vs/workbench/browser/parts/views/viewPaneContainer.ts index 7730d4b4b7c..e264cb74b0a 100644 --- a/src/vs/workbench/browser/parts/views/viewPaneContainer.ts +++ b/src/vs/workbench/browser/parts/views/viewPaneContainer.ts @@ -25,7 +25,7 @@ import { PaneView, IPaneViewOptions, IPaneOptions, Pane, DefaultPaneDndControlle import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; -import { Extensions as ViewContainerExtensions, IView, FocusedViewContext, IViewContainersRegistry, IViewDescriptor, ViewContainer } from 'vs/workbench/common/views'; +import { Extensions as ViewContainerExtensions, IView, FocusedViewContext, IViewContainersRegistry, IViewDescriptor, ViewContainer, IViewDescriptorService, Extensions as ViewsExtensions, ViewContainerLocation, IViewsService, IViewsRegistry } from 'vs/workbench/common/views'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { assertIsDefined } from 'vs/base/common/types'; @@ -307,7 +307,8 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer { @IExtensionService protected extensionService: IExtensionService, @IThemeService protected themeService: IThemeService, @IStorageService protected storageService: IStorageService, - @IWorkspaceContextService protected contextService: IWorkspaceContextService + @IWorkspaceContextService protected contextService: IWorkspaceContextService, + @IViewDescriptorService protected viewDescriptorService: IViewDescriptorService ) { super(id, themeService, storageService); @@ -389,14 +390,32 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer { } getContextMenuActions(viewDescriptor?: IViewDescriptor): IAction[] { + + if (this.isViewMergedWithContainer()) { + const viewId = this.panes[0].id; + viewDescriptor = Registry.as(ViewsExtensions.ViewsRegistry).getView(viewId)!; + } + const result: IAction[] = []; if (viewDescriptor) { - result.push({ - id: `${viewDescriptor.id}.removeView`, - label: nls.localize('hideView', "Hide"), - enabled: viewDescriptor.canToggleVisibility, - run: () => this.toggleViewVisibility(viewDescriptor.id) - }); + + if (!this.isViewMergedWithContainer()) { + result.push({ + id: `${viewDescriptor.id}.removeView`, + label: nls.localize('hideView', "Hide"), + enabled: viewDescriptor.canToggleVisibility, + run: () => this.toggleViewVisibility(viewDescriptor!.id) + }); + } + + if (viewDescriptor.canMoveView) { + result.push({ + id: `${viewDescriptor.id}.removeView`, + label: this.isViewMergedWithContainer() ? nls.localize('toggleSpecificViewLocation', "Toggle {0} View Location", viewDescriptor.name) : nls.localize('toggleViewLocation', "Toggle View Location"), + enabled: true, + run: () => this.moveView(viewDescriptor!) + }); + } } const viewToggleActions = this.viewsModel.viewDescriptors.map(viewDescriptor => ({ @@ -653,6 +672,16 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer { this.viewsModel.setVisible(viewId, visible); } + protected moveView(viewDescriptor: IViewDescriptor): void { + const viewContainerRegistry = Registry.as(ViewsExtensions.ViewContainersRegistry); + const currentLocation = viewContainerRegistry.getViewContainerLocation(this.viewContainer); + this.viewDescriptorService.moveView(viewDescriptor, currentLocation === ViewContainerLocation.Sidebar ? ViewContainerLocation.Panel : ViewContainerLocation.Sidebar); + + this.instantiationService.invokeFunction(accessor => { + const viewsService = accessor.get(IViewsService); + viewsService.openView(viewDescriptor.id, true); + }); + } private addPane(pane: ViewPane, size: number, index = this.paneItems.length - 1): void { const onDidFocus = pane.onDidFocus(() => this.lastFocusedPane = pane); diff --git a/src/vs/workbench/browser/parts/views/views.ts b/src/vs/workbench/browser/parts/views/views.ts index ba567a47619..96ab993a64e 100644 --- a/src/vs/workbench/browser/parts/views/views.ts +++ b/src/vs/workbench/browser/parts/views/views.ts @@ -23,6 +23,16 @@ import { toggleClass, addClass } from 'vs/base/browser/dom'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IPaneComposite } from 'vs/workbench/common/panecomposite'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; +import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; +import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; class CounterSet implements IReadableSet { @@ -749,7 +759,8 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor constructor( @IContextKeyService private readonly contextKeyService: IContextKeyService, - @IStorageService private readonly storageService: IStorageService + @IStorageService private readonly storageService: IStorageService, + @IExtensionService private readonly extensionService: IExtensionService ) { super(); @@ -761,6 +772,16 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor this.cachedViewToContainer = this.getCachedViewPositions(); + for (const containerId of this.cachedViewToContainer.values()) { + if (containerId.startsWith('workbench.view.service.')) { + const locationStr = containerId.substr(23); + const location = locationStr.startsWith('pnl.') ? ViewContainerLocation.Panel : ViewContainerLocation.Sidebar; + const viewId = containerId.substr(27); + + + } + } + // Register all containers that were registered before this ctor this.viewContainersRegistry.all.forEach(viewContainer => this.onDidRegisterViewContainer(viewContainer)); @@ -777,6 +798,8 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor })); this._register(this.storageService.onDidChangeStorage((e) => { this.onDidStorageChange(e); })); + + this._register(this.extensionService.onDidRegisterExtensions(() => this.onDidRegisterExtensions())); } private registerGroupedViews(groupedViews: Map): void { @@ -807,6 +830,23 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor } } + private onDidRegisterExtensions(): void { + for (const [viewId, containerId] of this.cachedViewToContainer.entries()) { + // check if cached view container is registered + if (this.viewContainersRegistry.get(containerId)) { + continue; + } + + // check if view has been registered to default location + const viewContainer = this.viewsRegistry.getViewContainer(viewId); + if (viewContainer) { + this.addViews(viewContainer, [this.viewsRegistry.getView(viewId)!]); + } + } + + this.saveViewPositionsToCache(); + } + private onDidRegisterViews(views: IViewDescriptor[], viewContainer: ViewContainer): void { // When views are registered, we need to regroup them based on the cache const regroupedViews = this.regroupViews(viewContainer.id, views); @@ -844,6 +884,10 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor this.viewsRegistry.getViewContainer(viewId); } + getDefaultContainer(viewId: string): ViewContainer | null { + return this.viewsRegistry.getViewContainer(viewId) ?? null; + } + getViewDescriptors(container: ViewContainer): ViewDescriptorCollection { let viewDescriptorCollectionItem = this.viewDescriptorCollections.get(container); if (!viewDescriptorCollectionItem) { @@ -854,6 +898,16 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor return viewDescriptorCollectionItem!.viewDescriptorCollection; } + moveView(view: IViewDescriptor, location: ViewContainerLocation): void { + const previousContainer = this.getViewContainer(view.id); + if (previousContainer && this.viewContainersRegistry.getViewContainerLocation(previousContainer) === location) { + return; + } + + const container = this.registerViewContainerForSingleView(view.id, view.name, location); + this.moveViews([view], container); + } + moveViews(views: IViewDescriptor[], viewContainer: ViewContainer): void { if (!views.length) { return; @@ -869,6 +923,34 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor } } + private registerViewContainerForSingleView(viewId: string, viewName: string, location: ViewContainerLocation): ViewContainer { + const id = `workbench.view.service.${location === ViewContainerLocation.Panel ? 'pnl' : 'sbr'}${viewId}`; + + class MovedViewPanelViewPaneContainer extends ViewPaneContainer { + constructor( + @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, + @ITelemetryService telemetryService: ITelemetryService, + @IWorkspaceContextService protected contextService: IWorkspaceContextService, + @IStorageService protected storageService: IStorageService, + @IConfigurationService configurationService: IConfigurationService, + @IInstantiationService protected instantiationService: IInstantiationService, + @IThemeService themeService: IThemeService, + @IContextMenuService contextMenuService: IContextMenuService, + @IExtensionService extensionService: IExtensionService, + @IViewDescriptorService viewDescriptorService: IViewDescriptorService + ) { + super(id, `${id}.state`, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService); + } + } + + return this.viewContainersRegistry.registerViewContainer({ + id, + ctorDescriptor: new SyncDescriptor(MovedViewPanelViewPaneContainer), + name: viewName, + hideIfEmpty: true + }, location); + } + private getCachedViewPositions(): Map { return new Map(JSON.parse(this.cachedViewPositionsValue)); } @@ -942,6 +1024,10 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor } private onDidRegisterViewContainer(viewContainer: ViewContainer): void { + if (this.viewDescriptorCollections.has(viewContainer)) { + return; + } + const disposables = new DisposableStore(); const viewDescriptorCollection = disposables.add(new ViewDescriptorCollection(this.contextKeyService)); diff --git a/src/vs/workbench/browser/parts/views/viewsViewlet.ts b/src/vs/workbench/browser/parts/views/viewsViewlet.ts index 078939500ef..5a9ec03d8d2 100644 --- a/src/vs/workbench/browser/parts/views/viewsViewlet.ts +++ b/src/vs/workbench/browser/parts/views/viewsViewlet.ts @@ -8,7 +8,7 @@ import { IAction } from 'vs/base/common/actions'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IViewDescriptor } from 'vs/workbench/common/views'; +import { IViewDescriptor, IViewDescriptorService } 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'; @@ -43,10 +43,11 @@ export abstract class FilterViewPaneContainer extends ViewPaneContainer { @IThemeService themeService: IThemeService, @IContextMenuService contextMenuService: IContextMenuService, @IExtensionService extensionService: IExtensionService, - @IWorkspaceContextService contextService: IWorkspaceContextService + @IWorkspaceContextService contextService: IWorkspaceContextService, + @IViewDescriptorService viewDescriptorService: IViewDescriptorService ) { - super(viewletId, `${viewletId}.state`, { mergeViewWithContainerWhenSingleView: false }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService); + super(viewletId, `${viewletId}.state`, { mergeViewWithContainerWhenSingleView: false }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService); this._register(onDidChangeFilterValue(newFilterValue => { this.filterValue = newFilterValue; this.onFilterChanged(newFilterValue); diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index fa839f073ad..1703e2358fc 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -188,6 +188,8 @@ export interface IViewDescriptor { readonly canToggleVisibility?: boolean; + readonly canMoveView?: boolean; + // Applies only to newly created views readonly hideByDefault?: boolean; @@ -361,11 +363,15 @@ export interface IViewDescriptorService { _serviceBrand: undefined; + moveView(view: IViewDescriptor, location: ViewContainerLocation): void; + moveViews(views: IViewDescriptor[], viewContainer: ViewContainer): void; getViewDescriptors(container: ViewContainer): IViewDescriptorCollection; getViewContainer(viewId: string): ViewContainer | null; + + getDefaultContainer(viewId: string): ViewContainer | null; } // Custom views diff --git a/src/vs/workbench/contrib/debug/browser/debugViewlet.ts b/src/vs/workbench/contrib/debug/browser/debugViewlet.ts index df274ebb967..9e88fea88be 100644 --- a/src/vs/workbench/contrib/debug/browser/debugViewlet.ts +++ b/src/vs/workbench/contrib/debug/browser/debugViewlet.ts @@ -33,6 +33,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { TogglePanelAction } from 'vs/workbench/browser/panel'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { StartView } from 'vs/workbench/contrib/debug/browser/startView'; +import { IViewDescriptorService } from 'vs/workbench/common/views'; export class DebugViewPaneContainer extends ViewPaneContainer { @@ -59,9 +60,10 @@ export class DebugViewPaneContainer extends ViewPaneContainer { @IContextViewService private readonly contextViewService: IContextViewService, @IMenuService private readonly menuService: IMenuService, @IContextKeyService private readonly contextKeyService: IContextKeyService, - @INotificationService private readonly notificationService: INotificationService + @INotificationService private readonly notificationService: INotificationService, + @IViewDescriptorService viewDescriptorService: IViewDescriptorService ) { - super(VIEWLET_ID, `${VIEWLET_ID}.state`, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService); + super(VIEWLET_ID, `${VIEWLET_ID}.state`, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService); this._register(this.debugService.onDidChangeState(state => this.onDebugServiceStateChange(state))); this._register(this.debugService.onDidNewSession(() => this.updateToolBar())); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts index 8c450fe0b0c..7fcef790e02 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts @@ -35,7 +35,7 @@ import Severity from 'vs/base/common/severity'; import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IViewsRegistry, IViewDescriptor, Extensions, ViewContainer, IViewContainersRegistry } from 'vs/workbench/common/views'; +import { IViewsRegistry, IViewDescriptor, Extensions, ViewContainer, IViewContainersRegistry, IViewDescriptorService } from 'vs/workbench/common/views'; import { IStorageService, StorageScope } 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'; @@ -356,8 +356,9 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE @IContextKeyService contextKeyService: IContextKeyService, @IContextMenuService contextMenuService: IContextMenuService, @IExtensionService extensionService: IExtensionService, + @IViewDescriptorService viewDescriptorService: IViewDescriptorService ) { - super(VIEWLET_ID, `${VIEWLET_ID}.state`, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService); + super(VIEWLET_ID, `${VIEWLET_ID}.state`, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService); this.searchDelayer = new Delayer(500); this.nonEmptyWorkspaceContextKey = NonEmptyWorkspaceContext.bindTo(contextKeyService); diff --git a/src/vs/workbench/contrib/files/browser/explorerViewlet.ts b/src/vs/workbench/contrib/files/browser/explorerViewlet.ts index 82d603d63fb..cc45efefec9 100644 --- a/src/vs/workbench/contrib/files/browser/explorerViewlet.ts +++ b/src/vs/workbench/contrib/files/browser/explorerViewlet.ts @@ -20,7 +20,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { IViewsRegistry, IViewDescriptor, Extensions, ViewContainer, IViewContainersRegistry, ViewContainerLocation } from 'vs/workbench/common/views'; +import { IViewsRegistry, IViewDescriptor, Extensions, ViewContainer, IViewContainersRegistry, ViewContainerLocation, IViewDescriptorService } 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'; @@ -163,10 +163,11 @@ export class ExplorerViewPaneContainer extends ViewPaneContainer { @IContextKeyService contextKeyService: IContextKeyService, @IThemeService themeService: IThemeService, @IContextMenuService contextMenuService: IContextMenuService, - @IExtensionService extensionService: IExtensionService + @IExtensionService extensionService: IExtensionService, + @IViewDescriptorService viewDescriptorService: IViewDescriptorService ) { - super(VIEWLET_ID, ExplorerViewPaneContainer.EXPLORER_VIEWS_STATE, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService); + super(VIEWLET_ID, ExplorerViewPaneContainer.EXPLORER_VIEWS_STATE, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService); this.viewletVisibleContextKey = ExplorerViewletVisibleContext.bindTo(contextKeyService); diff --git a/src/vs/workbench/contrib/outline/browser/outline.contribution.ts b/src/vs/workbench/contrib/outline/browser/outline.contribution.ts index ae1804ccecc..ede8e9f4e6f 100644 --- a/src/vs/workbench/contrib/outline/browser/outline.contribution.ts +++ b/src/vs/workbench/contrib/outline/browser/outline.contribution.ts @@ -4,61 +4,24 @@ *--------------------------------------------------------------------------------------------*/ import { localize } from 'vs/nls'; -import { IViewsRegistry, IViewDescriptor, Extensions as ViewExtensions, ViewContainer, IViewContainersRegistry, ViewContainerLocation, IViewDescriptorService, IViewsService } from 'vs/workbench/common/views'; +import { IViewsRegistry, IViewDescriptor, Extensions as ViewExtensions } from 'vs/workbench/common/views'; import { OutlinePane } from './outlinePane'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import { OutlineConfigKeys, OutlineViewId } from 'vs/editor/contrib/documentSymbols/outline'; import { VIEW_CONTAINER } from 'vs/workbench/contrib/files/browser/explorerViewlet'; -import { Action } from 'vs/base/common/actions'; -import { IWorkbenchActionRegistry, Extensions as ActionsExtensions } from 'vs/workbench/common/actions'; -import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; -import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; -import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { IStorageService } from 'vs/platform/storage/common/storage'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; // import './outlineNavigation'; export const PANEL_ID = 'panel.view.outline'; -export class OutlineViewPaneContainer extends ViewPaneContainer { - constructor( - @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, - @ITelemetryService telemetryService: ITelemetryService, - @IWorkspaceContextService protected contextService: IWorkspaceContextService, - @IStorageService protected storageService: IStorageService, - @IConfigurationService configurationService: IConfigurationService, - @IInstantiationService protected instantiationService: IInstantiationService, - @IThemeService themeService: IThemeService, - @IContextMenuService contextMenuService: IContextMenuService, - @IExtensionService extensionService: IExtensionService, - ) { - super(PANEL_ID, `${PANEL_ID}.state`, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService); - } -} - -export const VIEW_CONTAINER_PANEL: ViewContainer = - Registry.as(ViewExtensions.ViewContainersRegistry).registerViewContainer({ - id: PANEL_ID, - ctorDescriptor: new SyncDescriptor(OutlineViewPaneContainer), - name: localize('name', "Outline"), - hideIfEmpty: true - }, ViewContainerLocation.Panel); - - const _outlineDesc = { id: OutlineViewId, name: localize('name', "Outline"), ctorDescriptor: new SyncDescriptor(OutlinePane), canToggleVisibility: true, + canMoveView: true, hideByDefault: false, collapsed: true, order: 2, @@ -68,37 +31,6 @@ const _outlineDesc = { Registry.as(ViewExtensions.ViewsRegistry).registerViews([_outlineDesc], VIEW_CONTAINER); -export class ToggleOutlinePositionAction extends Action { - - static ID = 'outline.view.togglePosition'; - static LABEL = 'Toggle Outline View Position'; - - constructor( - id: string, - label: string, - @IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService, - @IViewsService private readonly viewsService: IViewsService - ) { - super(id, label, '', true); - } - - async run(): Promise { - const inPanel = this.viewDescriptorService.getViewContainer(_outlineDesc.id) === VIEW_CONTAINER_PANEL; - if (!inPanel) { - this.viewDescriptorService.moveViews([_outlineDesc], VIEW_CONTAINER_PANEL); - this.viewsService.openView(OutlineViewId, true); - } else { - this.viewDescriptorService.moveViews([_outlineDesc], VIEW_CONTAINER); - this.viewsService.openView(OutlineViewId, true); - } - - } -} - -Registry.as(ActionsExtensions.WorkbenchActions) - .registerWorkbenchAction(SyncActionDescriptor.create(ToggleOutlinePositionAction, ToggleOutlinePositionAction.ID, ToggleOutlinePositionAction.LABEL), 'Show Release Notes'); - - Registry.as(ConfigurationExtensions.Configuration).registerConfiguration({ 'id': 'outline', 'order': 117, diff --git a/src/vs/workbench/contrib/remote/browser/remote.ts b/src/vs/workbench/contrib/remote/browser/remote.ts index af5e22dcfef..ebf20e84685 100644 --- a/src/vs/workbench/contrib/remote/browser/remote.ts +++ b/src/vs/workbench/contrib/remote/browser/remote.ts @@ -19,7 +19,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { FilterViewPaneContainer } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { VIEWLET_ID } from 'vs/workbench/contrib/remote/common/remote.contribution'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IViewDescriptor, IViewsRegistry, Extensions, ViewContainerLocation, IViewContainersRegistry } from 'vs/workbench/common/views'; +import { IViewDescriptor, IViewsRegistry, Extensions, ViewContainerLocation, IViewContainersRegistry, IViewDescriptorService } from 'vs/workbench/common/views'; import { Registry } from 'vs/platform/registry/common/platform'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { IOpenerService } from 'vs/platform/opener/common/opener'; @@ -435,9 +435,10 @@ export class RemoteViewPaneContainer extends FilterViewPaneContainer implements @IExtensionService extensionService: IExtensionService, @IRemoteExplorerService private readonly remoteExplorerService: IRemoteExplorerService, @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, - @IContextKeyService private readonly contextKeyService: IContextKeyService + @IContextKeyService private readonly contextKeyService: IContextKeyService, + @IViewDescriptorService viewDescriptorService: IViewDescriptorService ) { - super(VIEWLET_ID, remoteExplorerService.onDidChangeTargetType, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); + super(VIEWLET_ID, remoteExplorerService.onDidChangeTargetType, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService, viewDescriptorService); this.addConstantViewDescriptors([this.helpPanelDescriptor]); remoteHelpExtPoint.setHandler((extensions) => { let helpInformation: HelpInformation[] = []; diff --git a/src/vs/workbench/contrib/scm/browser/scmViewlet.ts b/src/vs/workbench/contrib/scm/browser/scmViewlet.ts index adc0b970af7..cb21f9aa0b9 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewlet.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewlet.ts @@ -25,7 +25,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { IViewsRegistry, Extensions } from 'vs/workbench/common/views'; +import { IViewsRegistry, Extensions, IViewDescriptorService } from 'vs/workbench/common/views'; import { Registry } from 'vs/platform/registry/common/platform'; import { nextTick } from 'vs/base/common/process'; import { RepositoryPane, RepositoryViewDescriptor } from 'vs/workbench/contrib/scm/browser/repositoryPane'; @@ -98,8 +98,9 @@ export class SCMViewPaneContainer extends ViewPaneContainer implements IViewMode @IExtensionService extensionService: IExtensionService, @IWorkspaceContextService protected contextService: IWorkspaceContextService, @IContextKeyService contextKeyService: IContextKeyService, + @IViewDescriptorService viewDescriptorService: IViewDescriptorService ) { - super(VIEWLET_ID, SCMViewPaneContainer.STATE_KEY, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService); + super(VIEWLET_ID, SCMViewPaneContainer.STATE_KEY, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService); this.menus = instantiationService.createInstance(SCMMenus, undefined); this._register(this.menus.onDidChangeTitle(this.updateTitleArea, this)); diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index 872915b2ea2..a60f85060e3 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -554,7 +554,7 @@ class RegisterSearchViewContribution implements IWorkbenchContribution { } } else { Registry.as(PanelExtensions.Panels).deregisterPanel(PANEL_ID); - viewsRegistry.registerViews([{ id: VIEW_ID, name: nls.localize('search', "Search"), ctorDescriptor: new SyncDescriptor(SearchView, [SearchViewPosition.SideBar]), canToggleVisibility: false }], viewContainer); + viewsRegistry.registerViews([{ id: VIEW_ID, name: nls.localize('search', "Search"), ctorDescriptor: new SyncDescriptor(SearchView, [SearchViewPosition.SideBar]), canToggleVisibility: false, canMoveView: true }], viewContainer); if (open) { viewletService.openViewlet(VIEWLET_ID); } diff --git a/src/vs/workbench/contrib/search/browser/searchViewlet.ts b/src/vs/workbench/contrib/search/browser/searchViewlet.ts index 592a3153e67..2754b71d7b8 100644 --- a/src/vs/workbench/contrib/search/browser/searchViewlet.ts +++ b/src/vs/workbench/contrib/search/browser/searchViewlet.ts @@ -15,6 +15,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { VIEWLET_ID, VIEW_ID } from 'vs/workbench/services/search/common/search'; import { SearchView } from 'vs/workbench/contrib/search/browser/searchView'; import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; +import { IViewDescriptorService } from 'vs/workbench/common/views'; export class SearchViewPaneContainer extends ViewPaneContainer { @@ -29,8 +30,9 @@ export class SearchViewPaneContainer extends ViewPaneContainer { @IThemeService themeService: IThemeService, @IContextMenuService contextMenuService: IContextMenuService, @IExtensionService extensionService: IExtensionService, + @IViewDescriptorService viewDescriptorService: IViewDescriptorService ) { - super(VIEWLET_ID, `${VIEWLET_ID}.state`, { mergeViewWithContainerWhenSingleView: true, donotShowContainerTitleWhenMergedWithContainer: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService); + super(VIEWLET_ID, `${VIEWLET_ID}.state`, { mergeViewWithContainerWhenSingleView: true, donotShowContainerTitleWhenMergedWithContainer: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService); } getSearchView(): SearchView | undefined {