@@ -23,7 +23,7 @@ import { DefaultPanelDndController } from 'vs/base/browser/ui/splitview/panelvie
2323import { WorkbenchTree , IListService } from 'vs/platform/list/browser/listService' ;
2424import { IWorkbenchThemeService , IFileIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService' ;
2525import { ITreeConfiguration , ITreeOptions } from 'vs/base/parts/tree/browser/tree' ;
26- import { Event } from 'vs/base/common/event' ;
26+ import { Event , Emitter } from 'vs/base/common/event' ;
2727import { IConfigurationService } from 'vs/platform/configuration/common/configuration' ;
2828import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService' ;
2929import { localize } from 'vs/nls' ;
@@ -112,7 +112,7 @@ export abstract class ViewContainerViewlet extends PanelViewlet implements IView
112112 } ) ) ;
113113
114114 result . push ( ...viewToggleActions ) ;
115- const parentActions = super . getContextMenuActions ( ) ;
115+ const parentActions = this . getViewletContextMenuActions ( ) ;
116116 if ( viewToggleActions . length && parentActions . length ) {
117117 result . push ( new Separator ( ) ) ;
118118 }
@@ -121,6 +121,10 @@ export abstract class ViewContainerViewlet extends PanelViewlet implements IView
121121 return result ;
122122 }
123123
124+ protected getViewletContextMenuActions ( ) {
125+ return super . getContextMenuActions ( ) ;
126+ }
127+
124128 setVisible ( visible : boolean ) : void {
125129 super . setVisible ( visible ) ;
126130 this . panels . filter ( view => view . isVisible ( ) !== visible )
@@ -264,7 +268,7 @@ export abstract class ViewContainerViewlet extends PanelViewlet implements IView
264268 } ) ;
265269 }
266270
267- private toggleViewVisibility ( viewId : string ) : void {
271+ protected toggleViewVisibility ( viewId : string ) : void {
268272 const visible = ! this . viewsModel . isVisible ( viewId ) ;
269273 type ViewsToggleVisibilityClassification = {
270274 viewId : { classification : 'SystemMetaData' , purpose : 'FeatureInsight' } ;
@@ -321,6 +325,109 @@ export abstract class ViewContainerViewlet extends PanelViewlet implements IView
321325 }
322326}
323327
328+ export abstract class FilterViewContainerViewlet extends ViewContainerViewlet {
329+ private constantViewDescriptors : Map < string , IViewDescriptor > = new Map ( ) ;
330+ private allViews : Map < string , Map < string , IViewDescriptor > > = new Map ( ) ;
331+ private filterValue : string ;
332+
333+ protected onDidChangeFilterValue : Emitter < string > = new Emitter ( ) ;
334+
335+ constructor (
336+ viewletId : string ,
337+ @IConfigurationService configurationService : IConfigurationService ,
338+ @IWorkbenchLayoutService layoutService : IWorkbenchLayoutService ,
339+ @ITelemetryService telemetryService : ITelemetryService ,
340+ @IStorageService storageService : IStorageService ,
341+ @IInstantiationService instantiationService : IInstantiationService ,
342+ @IThemeService themeService : IThemeService ,
343+ @IContextMenuService contextMenuService : IContextMenuService ,
344+ @IExtensionService extensionService : IExtensionService ,
345+ @IWorkspaceContextService contextService : IWorkspaceContextService
346+ ) {
347+ super ( viewletId , `${ viewletId } .state` , false , configurationService , layoutService , telemetryService , storageService , instantiationService , themeService , contextMenuService , extensionService , contextService ) ;
348+ this . _register ( this . onDidChangeFilterValue . event ( newFilterValue => {
349+ this . filterValue = newFilterValue ;
350+ this . onFilterChanged ( newFilterValue ) ;
351+ } ) ) ;
352+
353+ this . _register ( this . viewsModel . onDidChangeActiveViews ( ( viewDescriptors ) => {
354+ viewDescriptors . forEach ( descriptor => {
355+ let filterOnValue = this . getFilterOn ( descriptor ) ;
356+ if ( ! filterOnValue ) {
357+ return ;
358+ }
359+ if ( ! this . allViews . has ( filterOnValue ) ) {
360+ this . allViews . set ( filterOnValue , new Map ( ) ) ;
361+ }
362+ this . allViews . get ( filterOnValue ) ! . set ( descriptor . id , descriptor ) ;
363+ if ( filterOnValue !== this . filterValue ) {
364+ this . viewsModel . setVisible ( descriptor . id , false ) ;
365+ }
366+ } ) ;
367+ } ) ) ;
368+ }
369+
370+ protected addConstantViewDescriptors ( constantViewDescriptors : IViewDescriptor [ ] ) {
371+ constantViewDescriptors . forEach ( viewDescriptor => this . constantViewDescriptors . set ( viewDescriptor . id , viewDescriptor ) ) ;
372+ }
373+
374+ protected abstract getFilterOn ( viewDescriptor : IViewDescriptor ) : string | undefined ;
375+
376+ private onFilterChanged ( newFilterValue : string ) {
377+ this . getViewsNotForTarget ( newFilterValue ) . forEach ( item => this . viewsModel . setVisible ( item . id , false ) ) ;
378+ this . getViewsForTarget ( newFilterValue ) . forEach ( item => this . viewsModel . setVisible ( item . id , true ) ) ;
379+ }
380+
381+ getContextMenuActions ( ) : IAction [ ] {
382+ const result : IAction [ ] = [ ] ;
383+ let viewToggleActions : IAction [ ] = Array . from ( this . constantViewDescriptors . values ( ) ) . map ( viewDescriptor => ( < IAction > {
384+ id : `${ viewDescriptor . id } .toggleVisibility` ,
385+ label : viewDescriptor . name ,
386+ checked : this . viewsModel . isVisible ( viewDescriptor . id ) ,
387+ enabled : viewDescriptor . canToggleVisibility ,
388+ run : ( ) => this . toggleViewVisibility ( viewDescriptor . id )
389+ } ) ) ;
390+
391+ result . push ( ...viewToggleActions ) ;
392+ const parentActions = this . getViewletContextMenuActions ( ) ;
393+ if ( viewToggleActions . length && parentActions . length ) {
394+ result . push ( new Separator ( ) ) ;
395+ }
396+
397+ result . push ( ...parentActions ) ;
398+ return result ;
399+ }
400+
401+ private getViewsForTarget ( target : string ) : IViewDescriptor [ ] {
402+ return this . allViews . has ( target ) ? Array . from ( this . allViews . get ( target ) ! . values ( ) ) : [ ] ;
403+ }
404+
405+ private getViewsNotForTarget ( target : string ) : IViewDescriptor [ ] {
406+ const iterable = this . allViews . keys ( ) ;
407+ let key = iterable . next ( ) ;
408+ let views : IViewDescriptor [ ] = [ ] ;
409+ while ( ! key . done ) {
410+ if ( key . value !== target ) {
411+ views = views . concat ( this . getViewsForTarget ( key . value ) ) ;
412+ }
413+ key = iterable . next ( ) ;
414+ }
415+ return views ;
416+ }
417+
418+ onDidAddViews ( added : IAddedViewDescriptorRef [ ] ) : ViewletPanel [ ] {
419+ const panels : ViewletPanel [ ] = super . onDidAddViews ( added ) ;
420+ for ( let i = 0 ; i < added . length ; i ++ ) {
421+ if ( this . constantViewDescriptors . has ( added [ i ] . viewDescriptor . id ) ) {
422+ panels [ i ] . setExpanded ( false ) ;
423+ }
424+ }
425+ return panels ;
426+ }
427+
428+ abstract getTitle ( ) : string ;
429+ }
430+
324431export class FileIconThemableWorkbenchTree extends WorkbenchTree {
325432
326433 constructor (
0 commit comments