markersPanel.ts 7.6 KB
Newer Older
1 2 3 4 5 6
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import 'vs/css!./media/markers';
S
Sandeep Somavarapu 已提交
7

S
Sandeep Somavarapu 已提交
8 9
import * as errors from 'vs/base/common/errors';
import * as Set from 'vs/base/common/set';
S
Sandeep Somavarapu 已提交
10
import URI from 'vs/base/common/uri';
11
import { TPromise } from 'vs/base/common/winjs.base';
S
Sandeep Somavarapu 已提交
12
import { Delayer } from 'vs/base/common/async';
13
import dom = require('vs/base/browser/dom');
14 15
import lifecycle = require('vs/base/common/lifecycle');
import builder = require('vs/base/browser/builder');
S
Sandeep Somavarapu 已提交
16
import {Action} from 'vs/base/common/actions';
17
import {IActionItem} from 'vs/base/browser/ui/actionbar/actionbar';
18 19
import { IMarkerService } from 'vs/platform/markers/common/markers';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
20
import { IEventService } from 'vs/platform/event/common/event';
21
import { Panel } from 'vs/workbench/browser/panel';
S
Sandeep Somavarapu 已提交
22
import {IAction} from 'vs/base/common/actions';
23
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
24 25 26
import Constants from 'vs/workbench/parts/markers/common/constants';
import { MarkersModel } from 'vs/workbench/parts/markers/common/markersModel';
import {Controller} from 'vs/workbench/parts/markers/browser/markersTreeController';
27
import Tree = require('vs/base/parts/tree/browser/tree');
S
Sandeep Somavarapu 已提交
28
import {CollapseAllAction} from 'vs/base/parts/tree/browser/treeDefaults';
29
import TreeImpl = require('vs/base/parts/tree/browser/treeImpl');
30
import * as Viewer from 'vs/workbench/parts/markers/browser/markersTreeViewer';
31
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
32
import { ActionProvider } from 'vs/workbench/parts/markers/browser/markersActionProvider';
33
import { FilterAction, FilterInputBoxActionItem } from 'vs/workbench/parts/markers/browser/markersPanelActions';
34 35 36

export class MarkersPanel extends Panel {

37
	public markersModel: MarkersModel;
S
Sandeep Somavarapu 已提交
38
	private toDispose: lifecycle.IDisposable[];
S
Sandeep Somavarapu 已提交
39 40 41
	private delayedRefresh: Delayer<void>;

	private tree: Tree.ITree;
42
	private autoExpanded: Set.ArraySet<string>;
43

S
Sandeep Somavarapu 已提交
44
	private actions: IAction[];
45
	private filterAction: FilterAction;
S
Sandeep Somavarapu 已提交
46 47
	private collapseAllAction: IAction;

S
Sandeep Somavarapu 已提交
48
	private treeContainer: HTMLElement;
S
Sandeep Somavarapu 已提交
49 50 51
	private messageBoxContainer: HTMLElement;
	private messageBox: HTMLElement;

52 53 54 55
	constructor(
		@IInstantiationService private instantiationService: IInstantiationService,
		@IMarkerService private markerService: IMarkerService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
56
		@IEventService private eventService: IEventService,
57 58 59
		@ITelemetryService telemetryService: ITelemetryService
	) {
		super(Constants.MARKERS_PANEL_ID, telemetryService);
S
Sandeep Somavarapu 已提交
60
		this.markersModel= new MarkersModel();
S
Sandeep Somavarapu 已提交
61
		this.toDispose = [];
S
Sandeep Somavarapu 已提交
62
		this.delayedRefresh= new Delayer<void>(1000);
63
		this.autoExpanded= new Set.ArraySet<string>();
64 65 66 67
	}

	public create(parent: builder.Builder): TPromise<void> {
		super.create(parent);
68
		dom.addClass(parent.getHTMLElement(), 'markers-panel');
69

S
Sandeep Somavarapu 已提交
70 71
		let container= dom.append(parent.getHTMLElement(), dom.emmet('.markers-panel-container'));

72
		this.createMessageBox(container);
S
Sandeep Somavarapu 已提交
73 74
		this.createTree(container);

S
Sandeep Somavarapu 已提交
75
		this.createActions();
76
		this.createListeners();
77 78

		this.render();
S
Sandeep Somavarapu 已提交
79

80 81 82
		return TPromise.as(null);
	}

83
	public getTitle():string {
S
Sandeep Somavarapu 已提交
84
		let markerStatistics= this.markerService.getStatistics();
S
Sandeep Somavarapu 已提交
85
		return this.markersModel.getTitle(markerStatistics);
S
Sandeep Somavarapu 已提交
86 87
	}

88 89 90 91
	public layout(dimension: builder.Dimension): void {
		this.tree.layout(dimension.height);
	}

S
Sandeep Somavarapu 已提交
92
	public focus(): void {
S
Sandeep Somavarapu 已提交
93
		if (this.markersModel.hasFilteredResources()) {
94 95 96 97
			this.tree.DOMFocus();
			if (!this.tree.getFocus()) {
				this.tree.focusFirst();
			}
S
Sandeep Somavarapu 已提交
98
		}
S
Sandeep Somavarapu 已提交
99 100 101
	}

	public getActions(): IAction[] {
102
		this.collapseAllAction.enabled= this.markersModel.hasFilteredResources();
S
Sandeep Somavarapu 已提交
103 104 105
		return this.actions;
	}

106
	public refreshPanel(updateTitleArea: boolean= false):TPromise<any> {
107
		this.collapseAllAction.enabled= this.markersModel.hasFilteredResources();
108 109 110 111
		this.refreshAutoExpanded();
		if (updateTitleArea) {
			this.updateTitleArea();
		}
S
Sandeep Somavarapu 已提交
112 113 114 115 116 117 118 119
		dom.toggleClass(this.treeContainer, 'hidden', !this.markersModel.hasFilteredResources());
		this.renderMessage();
		if (this.markersModel.hasFilteredResources()) {
			return this.tree.refresh().then(() => {
				this.autoExpand();
			});
		}
		return TPromise.as(null);
120 121
	}

S
Sandeep Somavarapu 已提交
122 123 124 125 126 127
	private createMessageBox(parent: HTMLElement): void {
		this.messageBoxContainer= dom.append(parent, dom.emmet('.message-box-container'));
		this.messageBox= dom.append(this.messageBoxContainer, dom.emmet('p'));
	}

	private createTree(parent: HTMLElement):void {
S
Sandeep Somavarapu 已提交
128
		this.treeContainer= dom.append(parent, dom.emmet('.tree-container'));
S
Sandeep Somavarapu 已提交
129 130 131
		var actionProvider = this.instantiationService.createInstance(ActionProvider);
		var renderer = this.instantiationService.createInstance(Viewer.Renderer, this.getActionRunner(), actionProvider);
		var controller = this.instantiationService.createInstance(Controller);
S
Sandeep Somavarapu 已提交
132
		this.tree= new TreeImpl.Tree(this.treeContainer, {
S
Sandeep Somavarapu 已提交
133 134 135 136 137 138 139 140 141 142 143
			dataSource: new Viewer.DataSource(),
			renderer: renderer,
			controller: controller
		}, {
			indentPixels: 0,
			twistiePixels: 20,
		});
	}

	private createActions():void {
		this.collapseAllAction= this.instantiationService.createInstance(CollapseAllAction, this.tree, true);
144
		this.filterAction= new FilterAction(this);
S
Sandeep Somavarapu 已提交
145
		this.actions= [
146
					this.filterAction,
S
Sandeep Somavarapu 已提交
147 148 149 150 151 152 153
					this.collapseAllAction
				];
		this.actions.forEach(a => {
			this.toDispose.push(a);
		});
	}

154 155 156 157
	private createListeners(): void {
		this.toDispose.push(this.markerService.onMarkerChanged(this.onMarkerChanged.bind(this)));
	}

S
Sandeep Somavarapu 已提交
158 159
	private onMarkerChanged(changedResources: URI[]) {
		this.updateResources(changedResources);
S
Sandeep Somavarapu 已提交
160
		// this.delayedRefresh.trigger(() => {this.refreshPanel(true);});
161
		this.refreshPanel(true);
162 163
	}

S
Sandeep Somavarapu 已提交
164 165
	private updateResources(resources: URI[]) {
		resources.forEach((resource) => {
S
Sandeep Somavarapu 已提交
166
			let markers= this.markerService.read({resource: resource}).slice(0);
167 168 169 170
			this.markersModel.update(resource, markers);
			if (!this.markersModel.hasResource(resource)) {
				this.autoExpanded.unset(resource.toString());
			}
S
Sandeep Somavarapu 已提交
171
		});
S
Sandeep Somavarapu 已提交
172 173
	}

174 175
	private render(): void {
		let allMarkers = this.markerService.read().slice(0);
176
		this.markersModel.update(allMarkers);
S
Sandeep Somavarapu 已提交
177
		this.tree.setInput(this.markersModel).then(this.autoExpand.bind(this));
S
Sandeep Somavarapu 已提交
178
		dom.toggleClass(this.treeContainer, 'hidden', !this.markersModel.hasFilteredResources());
S
Sandeep Somavarapu 已提交
179 180 181 182 183 184
		this.renderMessage();
	}

	private renderMessage():void {
		let message= this.markersModel.getMessage();
		this.messageBox.textContent= message;
S
Sandeep Somavarapu 已提交
185
		dom.toggleClass(this.messageBoxContainer, 'hidden', this.markersModel.hasFilteredResources());
S
Sandeep Somavarapu 已提交
186 187
	}

188 189 190 191 192 193 194 195
	private refreshAutoExpanded(): void {
		this.markersModel.nonFilteredResources.forEach((resource) => {
			if (this.tree.isExpanded(resource)) {
				this.autoExpanded.unset(resource.uri.toString());
			}
		});
	}

S
Sandeep Somavarapu 已提交
196
	private autoExpand(): void {
197 198
		this.markersModel.filteredResources.forEach((resource) => {
			if (this.autoExpanded.contains(resource.uri.toString())) {
S
Sandeep Somavarapu 已提交
199 200
				return;
			}
201
			this.tree.expand(resource).done(null, errors.onUnexpectedError);
202
			this.autoExpanded.set(resource.uri.toString());
S
Sandeep Somavarapu 已提交
203
		});
204 205
	}

206 207 208 209 210
	public getActionItem(action: Action): IActionItem {
		if (action.id === 'workbench.markers.panel.action.filter') {
			return this.instantiationService.createInstance(FilterInputBoxActionItem, this, action);
		}
		return super.getActionItem(action);
S
Sandeep Somavarapu 已提交
211 212
	}

213
	public dispose(): void {
S
Sandeep Somavarapu 已提交
214
		this.delayedRefresh.cancel();
S
Sandeep Somavarapu 已提交
215
		this.toDispose = lifecycle.dispose(this.toDispose);
216 217 218
		super.dispose();
	}
}