@@ -22,8 +22,7 @@ import { IProgressService } from 'vs/platform/progress/common/progress';
2222import { ITree , IDataSource , IRenderer , ContextMenuEvent } from 'vs/base/parts/tree/browser/tree' ;
2323import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey' ;
2424import { ActionItem , ActionBar , IActionItemProvider } from 'vs/base/browser/ui/actionbar/actionbar' ;
25- import { ViewsRegistry , TreeItemCollapsibleState , ITreeItem , ITreeViewDataProvider , TreeViewItemHandleArg } from 'vs/workbench/common/views' ;
26- import { IExtensionService } from 'vs/platform/extensions/common/extensions' ;
25+ import { TreeItemCollapsibleState , ITreeItem , TreeViewItemHandleArg , ITreeItemViewer , ICustomViewsService , ITreeViewDataProvider , ViewsRegistry , ICustomViewDescriptor } from 'vs/workbench/common/views' ;
2726import { IViewletViewOptions , IViewOptions , FileIconThemableWorkbenchTree , ViewsViewletPanel } from 'vs/workbench/browser/parts/views/viewsViewlet' ;
2827import { ICommandService } from 'vs/platform/commands/common/commands' ;
2928import { WorkbenchTree , WorkbenchTreeController } from 'vs/platform/list/browser/listService' ;
@@ -33,8 +32,48 @@ import { basename } from 'vs/base/common/paths';
3332import { FileKind } from 'vs/platform/files/common/files' ;
3433import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService' ;
3534import { IConfigurationService } from 'vs/platform/configuration/common/configuration' ;
35+ import { IExtensionService } from 'vs/platform/extensions/common/extensions' ;
36+
37+ export class CustomViewsService implements ICustomViewsService {
3638
37- class TreeViewer extends Disposable {
39+ _serviceBrand : any ;
40+
41+ private viewers : Map < string , ITreeItemViewer > = new Map < string , ITreeItemViewer > ( ) ;
42+
43+ constructor (
44+ @IInstantiationService private instantiationService : IInstantiationService
45+ ) {
46+ }
47+
48+ getTreeItemViewer ( id : string ) : ITreeItemViewer {
49+ let viewer = this . viewers . get ( id ) ;
50+ if ( ! viewer ) {
51+ viewer = this . createViewer ( id ) ;
52+ if ( viewer ) {
53+ this . viewers . set ( id , viewer ) ;
54+ }
55+ }
56+ return viewer ;
57+ }
58+
59+ registerTreeViewDataProvider ( id : string , dataProvider : ITreeViewDataProvider ) : void {
60+ const treeViewer = this . getTreeItemViewer ( id ) ;
61+ if ( treeViewer ) {
62+ treeViewer . dataProvider = dataProvider ;
63+ dataProvider . onDispose ( ( ) => treeViewer . dataProvider = null ) ;
64+ }
65+ }
66+
67+ private createViewer ( id : string ) : ITreeItemViewer {
68+ const viewDeescriptor = < ICustomViewDescriptor > ViewsRegistry . getView ( id ) ;
69+ if ( viewDeescriptor && viewDeescriptor . treeItemView ) {
70+ return this . instantiationService . createInstance ( TreeItemViewer , id ) ;
71+ }
72+ return null ;
73+ }
74+ }
75+
76+ export class TreeItemViewer extends Disposable implements ITreeItemViewer {
3877
3978 private isVisible : boolean = false ;
4079 private activated : boolean = false ;
@@ -43,6 +82,7 @@ class TreeViewer extends Disposable {
4382 private treeInputPromise : TPromise < void > ;
4483 private elementsToRefresh : ITreeItem [ ] = [ ] ;
4584
85+ private _dataProvider : ITreeViewDataProvider ;
4686 private dataProviderElementChangeListener : IDisposable ;
4787
4888 constructor (
@@ -52,6 +92,37 @@ class TreeViewer extends Disposable {
5292 super ( ) ;
5393 }
5494
95+ get dataProvider ( ) : ITreeViewDataProvider {
96+ return this . _dataProvider ;
97+ }
98+
99+ set dataProvider ( dataProvider : ITreeViewDataProvider ) {
100+ this . _dataProvider = dataProvider ;
101+ if ( this . dataProviderElementChangeListener ) {
102+ this . dataProviderElementChangeListener . dispose ( ) ;
103+ }
104+ if ( this . dataProvider ) {
105+ this . dataProviderElementChangeListener = this . _register ( this . dataProvider . onDidChange ( element => this . refresh ( element ) ) ) ;
106+ this . refresh ( null ) ;
107+ }
108+ }
109+
110+ refresh ( elements : ITreeItem [ ] ) : TPromise < void > {
111+ if ( this . tree ) {
112+ if ( ! elements ) {
113+ const root : ITreeItem = this . tree . getInput ( ) ;
114+ root . children = null ; // reset children
115+ elements = [ root ] ;
116+ }
117+ if ( this . isVisible ) {
118+ return this . doRefresh ( elements ) ;
119+ } else {
120+ this . elementsToRefresh . push ( ...elements ) ;
121+ }
122+ }
123+ return TPromise . as ( null ) ;
124+ }
125+
55126 setTree ( tree : ITree ) : void {
56127 this . tree = tree ;
57128 this . setInput ( ) ;
@@ -118,61 +189,15 @@ class TreeViewer extends Disposable {
118189 private setInput ( ) : TPromise < void > {
119190 if ( this . tree ) {
120191 if ( ! this . treeInputPromise ) {
121- if ( this . listenToDataProvider ( ) ) {
122- this . treeInputPromise = this . tree . setInput ( new Root ( ) ) ;
123- } else {
124- this . treeInputPromise = new TPromise < void > ( ( c , e ) => {
125- this . _register ( ViewsRegistry . onTreeViewDataProviderRegistered ( id => {
126- if ( this . id === id ) {
127- if ( this . listenToDataProvider ( ) ) {
128- this . tree . setInput ( new Root ( ) ) . then ( ( ) => c ( null ) ) ;
129- }
130- }
131- } ) ) ;
132- } ) ;
133- }
192+ this . treeInputPromise = this . tree . setInput ( new Root ( ) ) ;
134193 }
135194 return this . treeInputPromise ;
136195 }
137196 return TPromise . as ( null ) ;
138197 }
139198
140- private listenToDataProvider ( ) : boolean {
141- let dataProvider = ViewsRegistry . getTreeViewDataProvider ( this . id ) ;
142- if ( dataProvider ) {
143- if ( this . dataProviderElementChangeListener ) {
144- this . dataProviderElementChangeListener . dispose ( ) ;
145- }
146- this . dataProviderElementChangeListener = this . _register ( dataProvider . onDidChange ( element => this . refresh ( element ) ) ) ;
147- const disposable = dataProvider . onDispose ( ( ) => {
148- this . dataProviderElementChangeListener . dispose ( ) ;
149- this . tree . setInput ( new Root ( ) ) ;
150- disposable . dispose ( ) ;
151- } ) ;
152- return true ;
153- }
154- return false ;
155- }
156-
157- private refresh ( elements : ITreeItem [ ] ) : void {
158- if ( this . tree ) {
159- if ( ! elements ) {
160- const root : ITreeItem = this . tree . getInput ( ) ;
161- root . children = null ; // reset children
162- elements = [ root ] ;
163- }
164- if ( this . isVisible ) {
165- this . doRefresh ( elements ) ;
166- } else {
167- this . elementsToRefresh . push ( ...elements ) ;
168- }
169- }
170- }
171-
172- private doRefresh ( elements : ITreeItem [ ] ) : void {
173- for ( const element of elements ) {
174- this . tree . refresh ( element ) ;
175- }
199+ private doRefresh ( elements : ITreeItem [ ] ) : TPromise < void > {
200+ return TPromise . join ( elements . map ( e => this . tree . refresh ( e ) ) ) as TPromise ;
176201 }
177202}
178203
@@ -181,7 +206,7 @@ export class CustomTreeViewPanel extends ViewsViewletPanel {
181206 private menus : Menus ;
182207 private treeContainer : HTMLElement ;
183208 private tree : WorkbenchTree ;
184- private treeViewer : TreeViewer ;
209+ private treeViewer : TreeItemViewer ;
185210
186211 constructor (
187212 options : IViewletViewOptions ,
@@ -191,12 +216,13 @@ export class CustomTreeViewPanel extends ViewsViewletPanel {
191216 @IInstantiationService private instantiationService : IInstantiationService ,
192217 @IThemeService private themeService : IWorkbenchThemeService ,
193218 @ICommandService private commandService : ICommandService ,
194- @IConfigurationService configurationService : IConfigurationService
219+ @IConfigurationService configurationService : IConfigurationService ,
220+ @ICustomViewsService customViewsService : ICustomViewsService ,
195221 ) {
196222 super ( { ...( options as IViewOptions ) , ariaHeaderLabel : options . name } , keybindingService , contextMenuService , configurationService ) ;
197223 this . menus = this . instantiationService . createInstance ( Menus , this . id ) ;
198224 this . menus . onDidChangeTitle ( ( ) => this . updateActions ( ) , this , this . disposables ) ;
199- this . treeViewer = this . instantiationService . createInstance ( TreeViewer , this . id ) ;
225+ this . treeViewer = < TreeItemViewer > customViewsService . getTreeItemViewer ( this . id ) ;
200226 this . disposables . push ( this . treeViewer ) ;
201227 this . updateTreeVisibility ( ) ;
202228 }
@@ -213,7 +239,7 @@ export class CustomTreeViewPanel extends ViewsViewletPanel {
213239 renderBody ( container : HTMLElement ) : void {
214240 this . treeContainer = DOM . append ( container , DOM . $ ( '.tree-explorer-viewlet-tree-view' ) ) ;
215241 const actionItemProvider = ( action : IAction ) => this . getActionItem ( action ) ;
216- const dataSource = this . instantiationService . createInstance ( TreeDataSource , this . id ) ;
242+ const dataSource = this . instantiationService . createInstance ( TreeDataSource , this . treeViewer ) ;
217243 const renderer = this . instantiationService . createInstance ( TreeRenderer , this . id , this . menus , actionItemProvider ) ;
218244 const controller = this . instantiationService . createInstance ( TreeController , this . id , this . menus ) ;
219245 this . tree = this . instantiationService . createInstance ( FileIconThemableWorkbenchTree ,
@@ -301,7 +327,7 @@ class Root implements ITreeItem {
301327class TreeDataSource implements IDataSource {
302328
303329 constructor (
304- private id : string ,
330+ private treeItemViewer : ITreeItemViewer ,
305331 @IProgressService private progressService : IProgressService
306332 ) {
307333 }
@@ -311,7 +337,7 @@ class TreeDataSource implements IDataSource {
311337 }
312338
313339 public hasChildren ( tree : ITree , node : ITreeItem ) : boolean {
314- if ( ! this . getDataProvider ( ) ) {
340+ if ( ! this . treeItemViewer . dataProvider ) {
315341 return false ;
316342 }
317343 return node . collapsibleState === TreeItemCollapsibleState . Collapsed || node . collapsibleState === TreeItemCollapsibleState . Expanded ;
@@ -322,9 +348,8 @@ class TreeDataSource implements IDataSource {
322348 return TPromise . as ( node . children ) ;
323349 }
324350
325- const dataProvider = this . getDataProvider ( ) ;
326- if ( dataProvider ) {
327- const promise = node instanceof Root ? dataProvider . getElements ( ) : dataProvider . getChildren ( node ) ;
351+ if ( this . treeItemViewer . dataProvider ) {
352+ const promise = node instanceof Root ? this . treeItemViewer . dataProvider . getElements ( ) : this . treeItemViewer . dataProvider . getChildren ( node ) ;
328353 this . progressService . showWhile ( promise , 100 ) ;
329354 return promise . then ( children => {
330355 node . children = children ;
@@ -342,10 +367,6 @@ class TreeDataSource implements IDataSource {
342367 public getParent ( tree : ITree , node : any ) : TPromise < any > {
343368 return TPromise . as ( null ) ;
344369 }
345-
346- private getDataProvider ( ) : ITreeViewDataProvider {
347- return ViewsRegistry . getTreeViewDataProvider ( this . id ) ;
348- }
349370}
350371
351372interface ITreeExplorerTemplateData {
0 commit comments