@@ -164,9 +164,11 @@ export class CustomTreeView extends Disposable implements ITreeView {
164164 private domNode ! : HTMLElement ;
165165 private treeContainer ! : HTMLElement ;
166166 private _messageValue : string | undefined ;
167+ private _canSelectMany : boolean = false ;
167168 private messageElement ! : HTMLDivElement ;
168169 private tree : WorkbenchAsyncDataTree < ITreeItem , ITreeItem , FuzzyScore > | undefined ;
169170 private treeLabels : ResourceLabels | undefined ;
171+
170172 private root : ITreeItem ;
171173 private elementsToRefresh : ITreeItem [ ] = [ ] ;
172174 private menus : TitleMenus ;
@@ -253,6 +255,14 @@ export class CustomTreeView extends Disposable implements ITreeView {
253255 this . updateMessage ( ) ;
254256 }
255257
258+ get canSelectMany ( ) : boolean {
259+ return this . _canSelectMany ;
260+ }
261+
262+ set canSelectMany ( canSelectMany : boolean ) {
263+ this . _canSelectMany = canSelectMany ;
264+ }
265+
256266 get hasIconForParentNode ( ) : boolean {
257267 return this . _hasIconForParentNode ;
258268 }
@@ -372,12 +382,14 @@ export class CustomTreeView extends Disposable implements ITreeView {
372382 collapseByDefault : ( e : ITreeItem ) : boolean => {
373383 return e . collapsibleState !== TreeItemCollapsibleState . Expanded ;
374384 } ,
375- multipleSelectionSupport : false
376- } ) ) ;
385+ multipleSelectionSupport : this . canSelectMany ,
386+ } ) as WorkbenchAsyncDataTree < ITreeItem , ITreeItem , FuzzyScore > ) ;
377387 aligner . tree = this . tree ;
388+ const actionRunner = new MultipleSelectionActionRunner ( ( ) => this . tree ! . getSelection ( ) ) ;
389+ renderer . actionRunner = actionRunner ;
378390
379391 this . tree . contextKeyService . createKey < boolean > ( this . id , true ) ;
380- this . _register ( this . tree . onContextMenu ( e => this . onContextMenu ( treeMenus , e ) ) ) ;
392+ this . _register ( this . tree . onContextMenu ( e => this . onContextMenu ( treeMenus , e , actionRunner ) ) ) ;
381393 this . _register ( this . tree . onDidChangeSelection ( e => this . _onDidChangeSelection . fire ( e . elements ) ) ) ;
382394 this . _register ( this . tree . onDidChangeCollapseState ( e => {
383395 if ( ! e . node . element ) {
@@ -406,7 +418,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
406418 } ) ) ;
407419 }
408420
409- private onContextMenu ( treeMenus : TreeMenus , treeEvent : ITreeContextMenuEvent < ITreeItem > ) : void {
421+ private onContextMenu ( treeMenus : TreeMenus , treeEvent : ITreeContextMenuEvent < ITreeItem > , actionRunner : MultipleSelectionActionRunner ) : void {
410422 const node : ITreeItem | null = treeEvent . element ;
411423 if ( node === null ) {
412424 return ;
@@ -442,7 +454,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
442454
443455 getActionsContext : ( ) => ( < TreeViewItemHandleArg > { $treeViewId : this . id , $treeItemHandle : node . handle } ) ,
444456
445- actionRunner : new MultipleSelectionActionRunner ( ( ) => this . tree ! . getSelection ( ) )
457+ actionRunner
446458 } ) ;
447459 }
448460
@@ -686,6 +698,8 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
686698 static readonly ITEM_HEIGHT = 22 ;
687699 static readonly TREE_TEMPLATE_ID = 'treeExplorer' ;
688700
701+ private _actionRunner : MultipleSelectionActionRunner | undefined ;
702+
689703 constructor (
690704 private treeViewId : string ,
691705 private menus : TreeMenus ,
@@ -703,6 +717,10 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
703717 return TreeRenderer . TREE_TEMPLATE_ID ;
704718 }
705719
720+ set actionRunner ( actionRunner : MultipleSelectionActionRunner ) {
721+ this . _actionRunner = actionRunner ;
722+ }
723+
706724 renderTemplate ( container : HTMLElement ) : ITreeExplorerTemplateData {
707725 DOM . addClass ( container , 'custom-view-tree-node-item' ) ;
708726
@@ -740,8 +758,11 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
740758
741759 templateData . icon . style . backgroundImage = iconUrl ? `url('${ DOM . asDomUri ( iconUrl ) . toString ( true ) } ')` : '' ;
742760 DOM . toggleClass ( templateData . icon , 'custom-view-tree-node-item-icon' , ! ! iconUrl ) ;
743- templateData . actionBar . context = ( < TreeViewItemHandleArg > { $treeViewId : this . treeViewId , $treeItemHandle : node . handle } ) ;
761+ templateData . actionBar . context = < TreeViewItemHandleArg > { $treeViewId : this . treeViewId , $treeItemHandle : node . handle } ;
744762 templateData . actionBar . push ( this . menus . getResourceActions ( node ) , { icon : true , label : false } ) ;
763+ if ( this . _actionRunner ) {
764+ templateData . actionBar . actionRunner = this . _actionRunner ;
765+ }
745766 this . setAlignment ( templateData . container , node ) ;
746767 templateData . elementDisposable = ( this . themeService . onDidFileIconThemeChange ( ( ) => this . setAlignment ( templateData . container , node ) ) ) ;
747768 }
@@ -822,23 +843,23 @@ class Aligner extends Disposable {
822843
823844class MultipleSelectionActionRunner extends ActionRunner {
824845
825- constructor ( private getSelectedResources : ( ( ) => any [ ] ) ) {
846+ constructor ( private getSelectedResources : ( ( ) => ITreeItem [ ] ) ) {
826847 super ( ) ;
827848 }
828849
829- runAction ( action : IAction , context : any ) : Promise < any > {
830- if ( action instanceof MenuItemAction ) {
831- const selection = this . getSelectedResources ( ) ;
832- const filteredSelection = selection . filter ( s => s !== context ) ;
833-
834- if ( selection . length === filteredSelection . length || selection . length === 1 ) {
835- return action . run ( context ) ;
836- }
837-
838- return action . run ( context , ... filteredSelection ) ;
850+ runAction ( action : IAction , context : TreeViewItemHandleArg ) : Promise < any > {
851+ const selection = this . getSelectedResources ( ) ;
852+ let selectionHandleArgs : TreeViewItemHandleArg [ ] | undefined = undefined ;
853+ if ( selection . length > 1 ) {
854+ selectionHandleArgs = [ ] ;
855+ selection . forEach ( selected => {
856+ if ( selected . handle !== context . $treeItemHandle ) {
857+ selectionHandleArgs ! . push ( { $treeViewId : context . $treeViewId , $treeItemHandle : selected . handle } ) ;
858+ }
859+ } ) ;
839860 }
840861
841- return super . runAction ( action , context ) ;
862+ return action . run ( ... [ context , selectionHandleArgs ] ) ;
842863 }
843864}
844865
0 commit comments