mainThreadQuickOpen.ts 5.0 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.
 *--------------------------------------------------------------------------------------------*/
'use strict';

J
Johannes Rieken 已提交
7 8
import { TPromise } from 'vs/base/common/winjs.base';
import { asWinJsPromise } from 'vs/base/common/async';
C
Christof Marti 已提交
9 10
import { IPickOptions, IInputOptions, IQuickInputService, IQuickInput } from 'vs/platform/quickinput/common/quickInput';
import { InputBoxOptions, CancellationToken } from 'vscode';
11
import { ExtHostContext, MainThreadQuickOpenShape, ExtHostQuickOpenShape, MyQuickPickItems, MainContext, IExtHostContext } from '../node/extHost.protocol';
12
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
13

C
Christof Marti 已提交
14 15 16 17 18 19
interface MultiStepSession {
	handle: number;
	input: IQuickInput;
	token: CancellationToken;
}

20
@extHostNamedCustomer(MainContext.MainThreadQuickOpen)
21
export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
22

23
	private _proxy: ExtHostQuickOpenShape;
24
	private _quickInputService: IQuickInputService;
25 26 27 28
	private _doSetItems: (items: MyQuickPickItems[]) => any;
	private _doSetError: (error: Error) => any;
	private _contents: TPromise<MyQuickPickItems[]>;
	private _token: number = 0;
C
Christof Marti 已提交
29
	private _multiStep: MultiStepSession;
30

A
Alex Dima 已提交
31
	constructor(
32
		extHostContext: IExtHostContext,
33
		@IQuickInputService quickInputService: IQuickInputService
A
Alex Dima 已提交
34
	) {
35
		this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostQuickOpen);
36
		this._quickInputService = quickInputService;
37 38
	}

39 40 41
	public dispose(): void {
	}

C
Christof Marti 已提交
42 43 44 45 46 47 48
	$show(multiStepHandle: number | undefined, options: IPickOptions): TPromise<number | number[]> {

		const multiStep = typeof multiStepHandle === 'number';
		if (multiStep && !(this._multiStep && multiStepHandle === this._multiStep.handle && !this._multiStep.token.isCancellationRequested)) {
			return TPromise.as(undefined);
		}
		const input: IQuickInput = multiStep ? this._multiStep.input : this._quickInputService;
49 50 51

		const myToken = ++this._token;

52
		this._contents = new TPromise<MyQuickPickItems[]>((c, e) => {
53 54 55 56 57 58 59 60 61 62 63 64 65
			this._doSetItems = (items) => {
				if (myToken === this._token) {
					c(items);
				}
			};

			this._doSetError = (error) => {
				if (myToken === this._token) {
					e(error);
				}
			};
		});

C
Christof Marti 已提交
66
		if (options.canPickMany) {
C
Christof Marti 已提交
67
			return asWinJsPromise(token => input.pick(this._contents, options as { canPickMany: true }, token)).then(items => {
C
Christof Marti 已提交
68 69 70 71 72 73 74 75 76 77
				if (items) {
					return items.map(item => item.handle);
				}
				return undefined;
			}, undefined, progress => {
				if (progress) {
					this._proxy.$onItemSelected((<MyQuickPickItems>progress).handle);
				}
			});
		} else {
C
Christof Marti 已提交
78
			return asWinJsPromise(token => input.pick(this._contents, options, token)).then(item => {
C
Christof Marti 已提交
79 80 81 82 83 84 85 86 87 88
				if (item) {
					return item.handle;
				}
				return undefined;
			}, undefined, progress => {
				if (progress) {
					this._proxy.$onItemSelected((<MyQuickPickItems>progress).handle);
				}
			});
		}
89 90
	}

J
Johannes Rieken 已提交
91
	$setItems(items: MyQuickPickItems[]): TPromise<any> {
92 93 94
		if (this._doSetItems) {
			this._doSetItems(items);
		}
M
Matt Bierner 已提交
95
		return undefined;
96 97
	}

J
Johannes Rieken 已提交
98
	$setError(error: Error): TPromise<any> {
99 100 101
		if (this._doSetError) {
			this._doSetError(error);
		}
M
Matt Bierner 已提交
102
		return undefined;
103 104 105 106
	}

	// ---- input

C
Christof Marti 已提交
107 108 109 110 111 112 113
	$input(multiStepHandle: number | undefined, options: InputBoxOptions, validateInput: boolean): TPromise<string> {

		const multiStep = typeof multiStepHandle === 'number';
		if (multiStep && !(this._multiStep && multiStepHandle === this._multiStep.handle && !this._multiStep.token.isCancellationRequested)) {
			return TPromise.as(undefined);
		}
		const input: IQuickInput = multiStep ? this._multiStep.input : this._quickInputService;
114 115 116 117 118 119

		const inputOptions: IInputOptions = Object.create(null);

		if (options) {
			inputOptions.password = options.password;
			inputOptions.placeHolder = options.placeHolder;
120
			inputOptions.valueSelection = options.valueSelection;
121 122
			inputOptions.prompt = options.prompt;
			inputOptions.value = options.value;
123
			inputOptions.ignoreFocusLost = options.ignoreFocusOut;
124 125 126 127 128 129 130 131
		}

		if (validateInput) {
			inputOptions.validateInput = (value) => {
				return this._proxy.$validateInput(value);
			};
		}

C
Christof Marti 已提交
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
		return asWinJsPromise(token => input.input(inputOptions, token));
	}

	// ---- Multi-step input

	$multiStep(handle: number): TPromise<never> {
		let outerReject: (err: any) => void;
		let innerResolve: (value: void) => void;
		const promise = new TPromise<never>((_, rej) => outerReject = rej, () => innerResolve(undefined));
		this._quickInputService.multiStepInput((input, token) => {
			this._multiStep = { handle, input, token };
			const promise = new TPromise<void>(res => innerResolve = res);
			token.onCancellationRequested(() => innerResolve(undefined));
			return promise;
		})
			.then(() => promise.cancel(), err => outerReject(err))
			.then(() => {
				if (this._multiStep && this._multiStep.handle === handle) {
					this._multiStep = null;
				}
			});
		return promise;
154 155
	}
}