提交 0ecbfa0f 编写于 作者: I isidor

explorer decoration provider refactor

fixes #50866
上级 aa8f371e
......@@ -74,11 +74,12 @@ export class ExplorerItem {
private _isSymbolicLink: boolean;
private _isReadonly: boolean;
private children: Map<string, ExplorerItem>;
private _isError: boolean;
public parent: ExplorerItem;
public isDirectoryResolved: boolean;
constructor(resource: URI, public root: ExplorerItem, isSymbolicLink?: boolean, isReadonly?: boolean, isDirectory?: boolean, name: string = resources.basenameOrAuthority(resource), mtime?: number, etag?: string) {
constructor(resource: URI, public root: ExplorerItem, isSymbolicLink?: boolean, isReadonly?: boolean, isDirectory?: boolean, name: string = resources.basenameOrAuthority(resource), mtime?: number, etag?: string, isError?: boolean) {
this.resource = resource;
this._name = name;
this.isDirectory = !!isDirectory;
......@@ -86,6 +87,7 @@ export class ExplorerItem {
this._isReadonly = !!isReadonly;
this.etag = etag;
this.mtime = mtime;
this._isError = !!isError;
if (!this.root) {
this.root = this;
......@@ -106,6 +108,10 @@ export class ExplorerItem {
return this._isReadonly;
}
public get isError(): boolean {
return this._isError;
}
public set isDirectory(value: boolean) {
if (value !== this._isDirectory) {
this._isDirectory = value;
......@@ -118,10 +124,6 @@ export class ExplorerItem {
}
public get nonexistentRoot(): boolean {
return this.isRoot && !this.isDirectoryResolved && this.isDirectory;
}
public get name(): string {
return this._name;
}
......@@ -145,8 +147,8 @@ export class ExplorerItem {
return this === this.root;
}
public static create(raw: IFileStat, root: ExplorerItem, resolveTo?: URI[]): ExplorerItem {
const stat = new ExplorerItem(raw.resource, root, raw.isSymbolicLink, raw.isReadonly, raw.isDirectory, raw.name, raw.mtime, raw.etag);
public static create(raw: IFileStat, root: ExplorerItem, resolveTo?: URI[], isError = false): ExplorerItem {
const stat = new ExplorerItem(raw.resource, root, raw.isSymbolicLink, raw.isReadonly, raw.isDirectory, raw.name, raw.mtime, raw.etag, isError);
// Recursively add children if present
if (stat.isDirectory) {
......@@ -195,6 +197,7 @@ export class ExplorerItem {
local.isDirectoryResolved = disk.isDirectoryResolved;
local._isSymbolicLink = disk.isSymbolicLink;
local._isReadonly = disk.isReadonly;
local._isError = disk.isError;
// Merge Children if resolved
if (mergingDirectories && disk.isDirectoryResolved) {
......
......@@ -12,27 +12,35 @@ import { Model } from 'vs/workbench/parts/files/common/explorerModel';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IDecorationsProvider, IDecorationData } from 'vs/workbench/services/decorations/browser/decorations';
import { listInvalidItemForeground } from 'vs/platform/theme/common/colorRegistry';
import { IDisposable } from 'vscode-xterm';
import { dispose } from 'vs/base/common/lifecycle';
export class ExplorerDecorationsProvider implements IDecorationsProvider {
readonly label: string = localize('label', "Explorer");
private _onDidChange = new Emitter<URI[]>();
private toDispose: IDisposable[];
constructor(
private model: Model,
@IWorkspaceContextService contextService: IWorkspaceContextService
) {
contextService.onDidChangeWorkspaceFolders(e => {
this.toDispose = [];
this.toDispose.push(contextService.onDidChangeWorkspaceFolders(e => {
this._onDidChange.fire(e.changed.concat(e.added).map(wf => wf.uri));
});
}));
}
get onDidChange(): Event<URI[]> {
return this._onDidChange.event;
}
changed(uris: URI[]): void {
this._onDidChange.fire(uris);
}
provideDecorations(resource: URI): IDecorationData {
const fileStat = this.model.findClosest(resource);
if (fileStat && fileStat.nonexistentRoot) {
if (fileStat && fileStat.isRoot && fileStat.isError) {
return {
tooltip: localize('canNotResolve', "Can not resolve workspace folder"),
letter: '!',
......@@ -48,4 +56,8 @@ export class ExplorerDecorationsProvider implements IDecorationsProvider {
return undefined;
}
dispose(): IDisposable[] {
return dispose(this.toDispose);
}
}
......@@ -78,6 +78,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView
private settings: object;
private treeContainer: HTMLElement;
private dragHandler: DelayedDragHandler;
private decorationProvider: ExplorerDecorationsProvider;
private isDisposed: boolean;
constructor(
......@@ -114,7 +115,9 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView
(event: IConfigurationChangeEvent) => event.affectsConfiguration(FILES_EXCLUDE_CONFIG)
);
decorationService.registerDecorationsProvider(new ExplorerDecorationsProvider(this.model, contextService));
this.decorationProvider = new ExplorerDecorationsProvider(this.model, contextService);
decorationService.registerDecorationsProvider(this.decorationProvider);
this.disposables.push(this.decorationProvider);
}
private getFileEventsExcludes(root?: URI): glob.IExpression {
......@@ -782,7 +785,10 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView
});
}
const promise = this.resolveRoots(targetsToResolve, targetsToExpand);
const promise = this.resolveRoots(targetsToResolve, targetsToExpand).then(result => {
this.decorationProvider.changed(targetsToResolve.map(t => t.root.resource));
return result;
});
this.progressService.showWhile(promise, this.partService.isCreated() ? 800 : 3200 /* less ugly initial startup */);
return promise;
......@@ -798,7 +804,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView
mtime: 0,
etag: undefined,
isDirectory: true
}, root);
}, root, undefined, true);
const setInputAndExpand = (input: ExplorerItem | Model, statsToExpand: ExplorerItem[]) => {
// Make sure to expand all folders that where expanded in the previous session
......@@ -842,7 +848,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView
let delayer = new Delayer(100);
let delayerPromise: TPromise;
return TPromise.join(targetsToResolve.map((target, index) => this.fileService.resolveFile(target.resource, target.options)
.then(result => result.isDirectory ? ExplorerItem.create(result, target.root, target.options.resolveTo) : errorFileStat(target.resource, target.root), err => errorFileStat(target.resource, target.root))
.then(result => result.isDirectory ? ExplorerItem.create(result, target.root, target.options.resolveTo) : errorFileStat(target.resource, target.root), () => errorFileStat(target.resource, target.root))
.then(modelStat => {
// Subsequent refresh: Merge stat into our local model and refresh tree
if (index < this.model.roots.length) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册