/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; import Event, { Emitter } from 'vs/base/common/event'; import { TPromise } from 'vs/base/common/winjs.base'; import { ExtHostContext, MainThreadTreeViewsShape, ExtHostTreeViewsShape, MainContext, IExtHostContext } from '../node/extHost.protocol'; import { IMessageService, Severity } from 'vs/platform/message/common/message'; import { ViewsRegistry } from 'vs/workbench/parts/views/browser/viewsRegistry'; import { ITreeViewDataProvider, ITreeItem, TreeItemCollapsibleState } from 'vs/workbench/parts/views/common/views'; import { extHostNamedCustomer } from "vs/workbench/api/electron-browser/extHostCustomers"; @extHostNamedCustomer(MainContext.MainThreadTreeViews) export class MainThreadTreeViews implements MainThreadTreeViewsShape { private _proxy: ExtHostTreeViewsShape; constructor( extHostContext: IExtHostContext, @IMessageService private messageService: IMessageService ) { this._proxy = extHostContext.get(ExtHostContext.ExtHostTreeViews); } public dispose(): void { // TODO@Sandeep: please implement this // will be called when the extension host process is gone. } $registerView(treeViewId: string): void { ViewsRegistry.registerTreeViewDataProvider(treeViewId, new TreeViewDataProvider(treeViewId, this._proxy, this.messageService)); } $refresh(treeViewId: string, treeItemHandles: number[]): void { const treeViewDataProvider: TreeViewDataProvider = ViewsRegistry.getTreeViewDataProvider(treeViewId); if (treeViewDataProvider) { treeViewDataProvider.refresh(treeItemHandles); } } } type TreeItemHandle = number; class TreeViewDataProvider implements ITreeViewDataProvider { private _onDidChange: Emitter = new Emitter(); readonly onDidChange: Event = this._onDidChange.event; private childrenMap: Map = new Map(); private itemsMap: Map = new Map(); constructor(private treeViewId: string, private _proxy: ExtHostTreeViewsShape, private messageService: IMessageService ) { } getElements(): TPromise { return this._proxy.$getElements(this.treeViewId) .then(elements => { this.postGetElements(null, elements); return elements; }, err => this.messageService.show(Severity.Error, err)); } getChildren(treeItem: ITreeItem): TPromise { if (treeItem.children) { return TPromise.as(treeItem.children); } return this._proxy.$getChildren(this.treeViewId, treeItem.handle) .then(children => { this.postGetElements(treeItem.handle, children); return children; }, err => this.messageService.show(Severity.Error, err)); } refresh(treeItemHandles: number[]) { if (treeItemHandles && treeItemHandles.length) { let treeItems = treeItemHandles.map(treeItemHandle => this.itemsMap.get(treeItemHandle)) .filter(treeItem => !!treeItem); if (treeItems.length) { this._onDidChange.fire(treeItems); } } else { this._onDidChange.fire(); } } private clearChildren(treeItemHandle: TreeItemHandle): void { const children = this.childrenMap.get(treeItemHandle); if (children) { for (const child of children) { this.clearChildren(child); this.itemsMap.delete(child); } this.childrenMap.delete(treeItemHandle); } } private postGetElements(parent: TreeItemHandle, children: ITreeItem[]) { this.setElements(parent, children); } private setElements(parent: TreeItemHandle, children: ITreeItem[]) { if (children && children.length) { for (const child of children) { this.itemsMap.set(child.handle, child); if (child.children && child.children.length) { this.setElements(child.handle, child.children); } } if (parent) { this.childrenMap.set(parent, children.map(child => child.handle)); } } } private populateElementsToExpand(elements: ITreeItem[], toExpand: ITreeItem[]) { for (const element of elements) { if (element.collapsibleState === TreeItemCollapsibleState.Expanded) { toExpand.push(element); if (element.children && element.children.length) { this.populateElementsToExpand(element.children, toExpand); } } } } }