未验证 提交 a5ea66de 编写于 作者: A Alex Ross 提交者: GitHub

Refactor file dialog service to fix layer breaker (#81171)

Fixes #81161
上级 de039478
......@@ -37,7 +37,7 @@ import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remot
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { RemoteConnectionState, Deprecated_RemoteAuthorityContext, RemoteFileDialogContext } from 'vs/workbench/browser/contextkeys';
import { IDownloadService } from 'vs/platform/download/common/download';
import { OpenLocalFileFolderCommand, OpenLocalFileCommand, OpenLocalFolderCommand, SaveLocalFileCommand } from 'vs/workbench/services/dialogs/browser/remoteFileDialog';
import { OpenLocalFileFolderCommand, OpenLocalFileCommand, OpenLocalFolderCommand, SaveLocalFileCommand } from 'vs/workbench/services/dialogs/browser/simpleFileDialog';
const WINDOW_ACTIONS_COMMAND_ID = 'remote.showActions';
const CLOSE_REMOTE_COMMAND_ID = 'remote.closeRemote';
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { IWindowService, IURIToOpen, FileFilter } from 'vs/platform/windows/common/windows';
import { IPickAndOpenOptions, ISaveDialogOptions, IOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { URI } from 'vs/base/common/uri';
import { Schemas } from 'vs/base/common/network';
import * as resources from 'vs/base/common/resources';
import { IInstantiationService, } from 'vs/platform/instantiation/common/instantiation';
import { SimpleFileDialog } from 'vs/workbench/services/dialogs/browser/simpleFileDialog';
import { WORKSPACE_EXTENSION } from 'vs/platform/workspaces/common/workspaces';
import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IFileService } from 'vs/platform/files/common/files';
import { isWeb } from 'vs/base/common/platform';
import { IOpenerService } from 'vs/platform/opener/common/opener';
export class AbstractFileDialogService {
_serviceBrand: undefined;
constructor(
@IWindowService protected readonly windowService: IWindowService,
@IWorkspaceContextService protected readonly contextService: IWorkspaceContextService,
@IHistoryService protected readonly historyService: IHistoryService,
@IWorkbenchEnvironmentService protected readonly environmentService: IWorkbenchEnvironmentService,
@IInstantiationService protected readonly instantiationService: IInstantiationService,
@IConfigurationService protected readonly configurationService: IConfigurationService,
@IFileService protected readonly fileService: IFileService,
@IOpenerService protected readonly openerService: IOpenerService,
) { }
defaultFilePath(schemeFilter = this.getSchemeFilterForWindow()): URI | undefined {
// Check for last active file first...
let candidate = this.historyService.getLastActiveFile(schemeFilter);
// ...then for last active file root
if (!candidate) {
candidate = this.historyService.getLastActiveWorkspaceRoot(schemeFilter);
} else {
candidate = candidate && resources.dirname(candidate);
}
return candidate || undefined;
}
defaultFolderPath(schemeFilter = this.getSchemeFilterForWindow()): URI | undefined {
// Check for last active file root first...
let candidate = this.historyService.getLastActiveWorkspaceRoot(schemeFilter);
// ...then for last active file
if (!candidate) {
candidate = this.historyService.getLastActiveFile(schemeFilter);
}
return candidate && resources.dirname(candidate) || undefined;
}
defaultWorkspacePath(schemeFilter = this.getSchemeFilterForWindow()): URI | undefined {
// Check for current workspace config file first...
if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
const configuration = this.contextService.getWorkspace().configuration;
if (configuration && !isUntitledWorkspace(configuration, this.environmentService)) {
return resources.dirname(configuration) || undefined;
}
}
// ...then fallback to default file path
return this.defaultFilePath(schemeFilter);
}
protected addFileSchemaIfNeeded(schema: string): string[] {
// Include File schema unless the schema is web
// Don't allow untitled schema through.
if (isWeb) {
return schema === Schemas.untitled ? [Schemas.file] : [schema];
} else {
return schema === Schemas.untitled ? [Schemas.file] : (schema !== Schemas.file ? [schema, Schemas.file] : [schema]);
}
}
protected async pickFileFolderAndOpenSimplified(schema: string, options: IPickAndOpenOptions, preferNewWindow: boolean): Promise<any> {
const title = nls.localize('openFileOrFolder.title', 'Open File Or Folder');
const availableFileSystems = this.addFileSchemaIfNeeded(schema);
const uri = await this.pickResource({ canSelectFiles: true, canSelectFolders: true, canSelectMany: false, defaultUri: options.defaultUri, title, availableFileSystems });
if (uri) {
const stat = await this.fileService.resolve(uri);
const toOpen: IURIToOpen = stat.isDirectory ? { folderUri: uri } : { fileUri: uri };
if (stat.isDirectory || options.forceNewWindow || preferNewWindow) {
return this.windowService.openWindow([toOpen], { forceNewWindow: options.forceNewWindow });
} else {
return this.openerService.open(uri);
}
}
}
protected async pickFileAndOpenSimplified(schema: string, options: IPickAndOpenOptions, preferNewWindow: boolean): Promise<any> {
const title = nls.localize('openFile.title', 'Open File');
const availableFileSystems = this.addFileSchemaIfNeeded(schema);
const uri = await this.pickResource({ canSelectFiles: true, canSelectFolders: false, canSelectMany: false, defaultUri: options.defaultUri, title, availableFileSystems });
if (uri) {
if (options.forceNewWindow || preferNewWindow) {
return this.windowService.openWindow([{ fileUri: uri }], { forceNewWindow: options.forceNewWindow });
} else {
return this.openerService.open(uri);
}
}
}
protected async pickFolderAndOpenSimplified(schema: string, options: IPickAndOpenOptions): Promise<any> {
const title = nls.localize('openFolder.title', 'Open Folder');
const availableFileSystems = this.addFileSchemaIfNeeded(schema);
const uri = await this.pickResource({ canSelectFiles: false, canSelectFolders: true, canSelectMany: false, defaultUri: options.defaultUri, title, availableFileSystems });
if (uri) {
return this.windowService.openWindow([{ folderUri: uri }], { forceNewWindow: options.forceNewWindow });
}
}
protected async pickWorkspaceAndOpenSimplified(schema: string, options: IPickAndOpenOptions): Promise<any> {
const title = nls.localize('openWorkspace.title', 'Open Workspace');
const filters: FileFilter[] = [{ name: nls.localize('filterName.workspace', 'Workspace'), extensions: [WORKSPACE_EXTENSION] }];
const availableFileSystems = this.addFileSchemaIfNeeded(schema);
const uri = await this.pickResource({ canSelectFiles: true, canSelectFolders: false, canSelectMany: false, defaultUri: options.defaultUri, title, filters, availableFileSystems });
if (uri) {
return this.windowService.openWindow([{ workspaceUri: uri }], { forceNewWindow: options.forceNewWindow });
}
}
protected async pickFileToSaveSimplified(schema: string, options: ISaveDialogOptions): Promise<URI | undefined> {
if (!options.availableFileSystems) {
options.availableFileSystems = this.addFileSchemaIfNeeded(schema);
}
options.title = nls.localize('saveFileAs.title', 'Save As');
return this.saveRemoteResource(options);
}
protected async showSaveDialogSimplified(schema: string, options: ISaveDialogOptions): Promise<URI | undefined> {
if (!options.availableFileSystems) {
options.availableFileSystems = this.addFileSchemaIfNeeded(schema);
}
return this.saveRemoteResource(options);
}
protected async showOpenDialogSimplified(schema: string, options: IOpenDialogOptions): Promise<URI[] | undefined> {
if (!options.availableFileSystems) {
options.availableFileSystems = this.addFileSchemaIfNeeded(schema);
}
const uri = await this.pickResource(options);
return uri ? [uri] : undefined;
}
private pickResource(options: IOpenDialogOptions): Promise<URI | undefined> {
const simpleFileDialog = this.instantiationService.createInstance(SimpleFileDialog);
return simpleFileDialog.showOpenDialog(options);
}
private saveRemoteResource(options: ISaveDialogOptions): Promise<URI | undefined> {
const remoteFileDialog = this.instantiationService.createInstance(SimpleFileDialog);
return remoteFileDialog.showSaveDialog(options);
}
protected getSchemeFilterForWindow(): string {
return !this.environmentService.configuration.remoteAuthority ? Schemas.file : REMOTE_HOST_SCHEME;
}
protected getFileSystemSchema(options: { availableFileSystems?: string[], defaultUri?: URI }): string {
return options.availableFileSystems && options.availableFileSystems[0] || this.getSchemeFilterForWindow();
}
}
function isUntitledWorkspace(path: URI, environmentService: IWorkbenchEnvironmentService): boolean {
return resources.isEqualOrParent(path, environmentService.untitledWorkspacesHome);
}
......@@ -3,110 +3,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { IWindowService, INativeOpenDialogOptions, OpenDialogOptions, IURIToOpen, FileFilter, SaveDialogOptions } from 'vs/platform/windows/common/windows';
import { IPickAndOpenOptions, ISaveDialogOptions, IOpenDialogOptions, IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { URI } from 'vs/base/common/uri';
import { Schemas } from 'vs/base/common/network';
import * as resources from 'vs/base/common/resources';
import { IInstantiationService, optional } from 'vs/platform/instantiation/common/instantiation';
import { RemoteFileDialog } from 'vs/workbench/services/dialogs/browser/remoteFileDialog';
import { WORKSPACE_EXTENSION } from 'vs/platform/workspaces/common/workspaces';
import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IFileService } from 'vs/platform/files/common/files';
import { isWeb } from 'vs/base/common/platform';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { AbstractFileDialogService } from 'vs/workbench/services/dialogs/browser/abstractFileDialogService';
// TODO@Alex layer breaker
// tslint:disable-next-line: layering import-patterns
import { IElectronService } from 'vs/platform/electron/node/electron';
export class FileDialogService implements IFileDialogService {
_serviceBrand: undefined;
constructor(
@IWindowService private readonly windowService: IWindowService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IHistoryService private readonly historyService: IHistoryService,
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IFileService private readonly fileService: IFileService,
@IOpenerService private readonly openerService: IOpenerService,
@optional(IElectronService) private readonly electronService: IElectronService
) { }
defaultFilePath(schemeFilter = this.getSchemeFilterForWindow()): URI | undefined {
// Check for last active file first...
let candidate = this.historyService.getLastActiveFile(schemeFilter);
// ...then for last active file root
if (!candidate) {
candidate = this.historyService.getLastActiveWorkspaceRoot(schemeFilter);
} else {
candidate = candidate && resources.dirname(candidate);
}
return candidate || undefined;
}
defaultFolderPath(schemeFilter = this.getSchemeFilterForWindow()): URI | undefined {
// Check for last active file root first...
let candidate = this.historyService.getLastActiveWorkspaceRoot(schemeFilter);
// ...then for last active file
if (!candidate) {
candidate = this.historyService.getLastActiveFile(schemeFilter);
}
return candidate && resources.dirname(candidate) || undefined;
}
defaultWorkspacePath(schemeFilter = this.getSchemeFilterForWindow()): URI | undefined {
// Check for current workspace config file first...
if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
const configuration = this.contextService.getWorkspace().configuration;
if (configuration && !isUntitledWorkspace(configuration, this.environmentService)) {
return resources.dirname(configuration) || undefined;
}
}
// ...then fallback to default file path
return this.defaultFilePath(schemeFilter);
}
private toNativeOpenDialogOptions(options: IPickAndOpenOptions): INativeOpenDialogOptions {
return {
forceNewWindow: options.forceNewWindow,
telemetryExtraData: options.telemetryExtraData,
defaultPath: options.defaultUri && options.defaultUri.fsPath
};
}
private shouldUseSimplified(schema: string): { useSimplified: boolean, isSetting: boolean } {
const setting = (this.configurationService.getValue('files.simpleDialog.enable') === true);
return { useSimplified: (schema !== Schemas.file) || setting, isSetting: (schema === Schemas.file) && setting };
}
private addFileSchemaIfNeeded(schema: string): string[] {
// Include File schema unless the schema is web
// Don't allow untitled schema through.
if (isWeb) {
return schema === Schemas.untitled ? [Schemas.file] : [schema];
} else {
return schema === Schemas.untitled ? [Schemas.file] : (schema !== Schemas.file ? [schema, Schemas.file] : [schema]);
}
}
export class FileDialogService extends AbstractFileDialogService implements IFileDialogService {
async pickFileFolderAndOpen(options: IPickAndOpenOptions): Promise<any> {
const schema = this.getFileSystemSchema(options);
......@@ -115,30 +17,7 @@ export class FileDialogService implements IFileDialogService {
options.defaultUri = this.defaultFilePath(schema);
}
const shouldUseSimplified = this.shouldUseSimplified(schema);
if (shouldUseSimplified.useSimplified) {
const title = nls.localize('openFileOrFolder.title', 'Open File Or Folder');
const availableFileSystems = this.addFileSchemaIfNeeded(schema);
const uri = await this.pickRemoteResource({ canSelectFiles: true, canSelectFolders: true, canSelectMany: false, defaultUri: options.defaultUri, title, availableFileSystems });
if (uri) {
const stat = await this.fileService.resolve(uri);
const toOpen: IURIToOpen = stat.isDirectory ? { folderUri: uri } : { fileUri: uri };
if (stat.isDirectory || options.forceNewWindow || shouldUseSimplified.isSetting) {
return this.windowService.openWindow([toOpen], { forceNewWindow: options.forceNewWindow });
} else {
return this.openerService.open(uri);
}
}
return;
}
if (this.electronService) {
return this.electronService.pickFileFolderAndOpen(this.toNativeOpenDialogOptions(options));
}
return this.pickFileFolderAndOpenSimplified(schema, options, false);
}
async pickFileAndOpen(options: IPickAndOpenOptions): Promise<any> {
......@@ -148,26 +27,7 @@ export class FileDialogService implements IFileDialogService {
options.defaultUri = this.defaultFilePath(schema);
}
const shouldUseSimplified = this.shouldUseSimplified(schema);
if (shouldUseSimplified.useSimplified) {
const title = nls.localize('openFile.title', 'Open File');
const availableFileSystems = this.addFileSchemaIfNeeded(schema);
const uri = await this.pickRemoteResource({ canSelectFiles: true, canSelectFolders: false, canSelectMany: false, defaultUri: options.defaultUri, title, availableFileSystems });
if (uri) {
if (options.forceNewWindow || shouldUseSimplified.isSetting) {
return this.windowService.openWindow([{ fileUri: uri }], { forceNewWindow: options.forceNewWindow });
} else {
return this.openerService.open(uri);
}
}
return;
}
if (this.electronService) {
return this.electronService.pickFileAndOpen(this.toNativeOpenDialogOptions(options));
}
return this.pickFileAndOpenSimplified(schema, options, false);
}
async pickFolderAndOpen(options: IPickAndOpenOptions): Promise<any> {
......@@ -177,21 +37,7 @@ export class FileDialogService implements IFileDialogService {
options.defaultUri = this.defaultFolderPath(schema);
}
if (this.shouldUseSimplified(schema).useSimplified) {
const title = nls.localize('openFolder.title', 'Open Folder');
const availableFileSystems = this.addFileSchemaIfNeeded(schema);
const uri = await this.pickRemoteResource({ canSelectFiles: false, canSelectFolders: true, canSelectMany: false, defaultUri: options.defaultUri, title, availableFileSystems });
if (uri) {
return this.windowService.openWindow([{ folderUri: uri }], { forceNewWindow: options.forceNewWindow });
}
return;
}
if (this.electronService) {
return this.electronService.pickFolderAndOpen(this.toNativeOpenDialogOptions(options));
}
return this.pickFolderAndOpenSimplified(schema, options);
}
async pickWorkspaceAndOpen(options: IPickAndOpenOptions): Promise<void> {
......@@ -201,143 +47,23 @@ export class FileDialogService implements IFileDialogService {
options.defaultUri = this.defaultWorkspacePath(schema);
}
if (this.shouldUseSimplified(schema).useSimplified) {
const title = nls.localize('openWorkspace.title', 'Open Workspace');
const filters: FileFilter[] = [{ name: nls.localize('filterName.workspace', 'Workspace'), extensions: [WORKSPACE_EXTENSION] }];
const availableFileSystems = this.addFileSchemaIfNeeded(schema);
const uri = await this.pickRemoteResource({ canSelectFiles: true, canSelectFolders: false, canSelectMany: false, defaultUri: options.defaultUri, title, filters, availableFileSystems });
if (uri) {
return this.windowService.openWindow([{ workspaceUri: uri }], { forceNewWindow: options.forceNewWindow });
}
return;
}
if (this.electronService) {
return this.electronService.pickWorkspaceAndOpen(this.toNativeOpenDialogOptions(options));
}
return this.pickWorkspaceAndOpenSimplified(schema, options);
}
async pickFileToSave(options: ISaveDialogOptions): Promise<URI | undefined> {
const schema = this.getFileSystemSchema(options);
if (this.shouldUseSimplified(schema).useSimplified) {
if (!options.availableFileSystems) {
options.availableFileSystems = this.addFileSchemaIfNeeded(schema);
}
options.title = nls.localize('saveFileAs.title', 'Save As');
return this.saveRemoteResource(options);
}
if (this.electronService) {
const result = await this.electronService.showSaveDialog(this.toNativeSaveDialogOptions(options));
if (result && !result.canceled && result.filePath) {
return URI.file(result.filePath);
}
}
return;
}
private toNativeSaveDialogOptions(options: ISaveDialogOptions): SaveDialogOptions {
options.defaultUri = options.defaultUri ? URI.file(options.defaultUri.path) : undefined;
return {
defaultPath: options.defaultUri && options.defaultUri.fsPath,
buttonLabel: options.saveLabel,
filters: options.filters,
title: options.title
};
return this.pickFileToSaveSimplified(schema, options);
}
async showSaveDialog(options: ISaveDialogOptions): Promise<URI | undefined> {
const schema = this.getFileSystemSchema(options);
if (this.shouldUseSimplified(schema).useSimplified) {
if (!options.availableFileSystems) {
options.availableFileSystems = this.addFileSchemaIfNeeded(schema);
}
return this.saveRemoteResource(options);
}
if (this.electronService) {
const result = await this.electronService.showSaveDialog(this.toNativeSaveDialogOptions(options));
if (result && !result.canceled && result.filePath) {
return URI.file(result.filePath);
}
}
return;
return this.showSaveDialogSimplified(schema, options);
}
async showOpenDialog(options: IOpenDialogOptions): Promise<URI[] | undefined> {
const schema = this.getFileSystemSchema(options);
if (this.shouldUseSimplified(schema).useSimplified) {
if (!options.availableFileSystems) {
options.availableFileSystems = this.addFileSchemaIfNeeded(schema);
}
const uri = await this.pickRemoteResource(options);
return uri ? [uri] : undefined;
}
const defaultUri = options.defaultUri;
const newOptions: OpenDialogOptions = {
title: options.title,
defaultPath: defaultUri && defaultUri.fsPath,
buttonLabel: options.openLabel,
filters: options.filters,
properties: []
};
newOptions.properties!.push('createDirectory');
if (options.canSelectFiles) {
newOptions.properties!.push('openFile');
}
if (options.canSelectFolders) {
newOptions.properties!.push('openDirectory');
}
if (options.canSelectMany) {
newOptions.properties!.push('multiSelections');
}
if (this.electronService) {
const result = await this.electronService.showOpenDialog(newOptions);
return result && Array.isArray(result.filePaths) && result.filePaths.length > 0 ? result.filePaths.map(URI.file) : undefined;
}
return;
}
private pickRemoteResource(options: IOpenDialogOptions): Promise<URI | undefined> {
const remoteFileDialog = this.instantiationService.createInstance(RemoteFileDialog);
return remoteFileDialog.showOpenDialog(options);
}
private saveRemoteResource(options: ISaveDialogOptions): Promise<URI | undefined> {
const remoteFileDialog = this.instantiationService.createInstance(RemoteFileDialog);
return remoteFileDialog.showSaveDialog(options);
return this.showOpenDialogSimplified(schema, options);
}
private getSchemeFilterForWindow(): string {
return !this.environmentService.configuration.remoteAuthority ? Schemas.file : REMOTE_HOST_SCHEME;
}
private getFileSystemSchema(options: { availableFileSystems?: string[], defaultUri?: URI }): string {
return options.availableFileSystems && options.availableFileSystems[0] || this.getSchemeFilterForWindow();
}
}
function isUntitledWorkspace(path: URI, environmentService: IWorkbenchEnvironmentService): boolean {
return resources.isEqualOrParent(path, environmentService.untitledWorkspacesHome);
}
registerSingleton(IFileDialogService, FileDialogService, true);
......@@ -98,7 +98,7 @@ enum UpdateResult {
InvalidPath
}
export class RemoteFileDialog {
export class SimpleFileDialog {
private options!: IOpenDialogOptions;
private currentFolder!: URI;
private filePickBox!: IQuickPick<FileQuickPickItem>;
......@@ -303,7 +303,7 @@ export class RemoteFileDialog {
this.filePickBox.valueSelection = [this.filePickBox.value.length, this.filePickBox.value.length];
this.filePickBox.items = [];
function doResolve(dialog: RemoteFileDialog, uri: URI | undefined) {
function doResolve(dialog: SimpleFileDialog, uri: URI | undefined) {
if (uri) {
uri = resources.removeTrailingPathSeparator(uri);
}
......@@ -335,7 +335,7 @@ export class RemoteFileDialog {
}
});
function handleAccept(dialog: RemoteFileDialog) {
function handleAccept(dialog: SimpleFileDialog) {
if (dialog.busy) {
// Save the accept until the file picker is not busy.
dialog.onBusyChangeEmitter.event((busy: boolean) => {
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IWindowService, OpenDialogOptions, SaveDialogOptions, INativeOpenDialogOptions } from 'vs/platform/windows/common/windows';
import { IPickAndOpenOptions, ISaveDialogOptions, IOpenDialogOptions, IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { URI } from 'vs/base/common/uri';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IFileService } from 'vs/platform/files/common/files';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IElectronService } from 'vs/platform/electron/node/electron';
import { AbstractFileDialogService } from 'vs/workbench/services/dialogs/browser/abstractFileDialogService';
import { Schemas } from 'vs/base/common/network';
export class FileDialogService extends AbstractFileDialogService implements IFileDialogService {
_serviceBrand: undefined;
constructor(
@IWindowService windowService: IWindowService,
@IWorkspaceContextService contextService: IWorkspaceContextService,
@IHistoryService historyService: IHistoryService,
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
@IInstantiationService instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService,
@IFileService fileService: IFileService,
@IOpenerService openerService: IOpenerService,
@IElectronService private readonly electronService: IElectronService
) { super(windowService, contextService, historyService, environmentService, instantiationService, configurationService, fileService, openerService); }
private toNativeOpenDialogOptions(options: IPickAndOpenOptions): INativeOpenDialogOptions {
return {
forceNewWindow: options.forceNewWindow,
telemetryExtraData: options.telemetryExtraData,
defaultPath: options.defaultUri && options.defaultUri.fsPath
};
}
private shouldUseSimplified(schema: string): { useSimplified: boolean, isSetting: boolean } {
const setting = (this.configurationService.getValue('files.simpleDialog.enable') === true);
return { useSimplified: (schema !== Schemas.file) || setting, isSetting: (schema === Schemas.file) && setting };
}
async pickFileFolderAndOpen(options: IPickAndOpenOptions): Promise<any> {
const schema = this.getFileSystemSchema(options);
if (!options.defaultUri) {
options.defaultUri = this.defaultFilePath(schema);
}
const shouldUseSimplified = this.shouldUseSimplified(schema);
if (shouldUseSimplified.useSimplified) {
return this.pickFileFolderAndOpenSimplified(schema, options, shouldUseSimplified.isSetting);
}
return this.electronService.pickFileFolderAndOpen(this.toNativeOpenDialogOptions(options));
}
async pickFileAndOpen(options: IPickAndOpenOptions): Promise<any> {
const schema = this.getFileSystemSchema(options);
if (!options.defaultUri) {
options.defaultUri = this.defaultFilePath(schema);
}
const shouldUseSimplified = this.shouldUseSimplified(schema);
if (shouldUseSimplified.useSimplified) {
return this.pickFileAndOpenSimplified(schema, options, shouldUseSimplified.isSetting);
}
return this.electronService.pickFileAndOpen(this.toNativeOpenDialogOptions(options));
}
async pickFolderAndOpen(options: IPickAndOpenOptions): Promise<any> {
const schema = this.getFileSystemSchema(options);
if (!options.defaultUri) {
options.defaultUri = this.defaultFolderPath(schema);
}
if (this.shouldUseSimplified(schema).useSimplified) {
return this.pickFolderAndOpenSimplified(schema, options);
}
return this.electronService.pickFolderAndOpen(this.toNativeOpenDialogOptions(options));
}
async pickWorkspaceAndOpen(options: IPickAndOpenOptions): Promise<void> {
const schema = this.getFileSystemSchema(options);
if (!options.defaultUri) {
options.defaultUri = this.defaultWorkspacePath(schema);
}
if (this.shouldUseSimplified(schema).useSimplified) {
return this.pickWorkspaceAndOpenSimplified(schema, options);
}
return this.electronService.pickWorkspaceAndOpen(this.toNativeOpenDialogOptions(options));
}
async pickFileToSave(options: ISaveDialogOptions): Promise<URI | undefined> {
const schema = this.getFileSystemSchema(options);
if (this.shouldUseSimplified(schema).useSimplified) {
return this.pickFileToSaveSimplified(schema, options);
} else {
const result = await this.electronService.showSaveDialog(this.toNativeSaveDialogOptions(options));
if (result && !result.canceled && result.filePath) {
return URI.file(result.filePath);
}
}
return;
}
private toNativeSaveDialogOptions(options: ISaveDialogOptions): SaveDialogOptions {
options.defaultUri = options.defaultUri ? URI.file(options.defaultUri.path) : undefined;
return {
defaultPath: options.defaultUri && options.defaultUri.fsPath,
buttonLabel: options.saveLabel,
filters: options.filters,
title: options.title
};
}
async showSaveDialog(options: ISaveDialogOptions): Promise<URI | undefined> {
const schema = this.getFileSystemSchema(options);
if (this.shouldUseSimplified(schema).useSimplified) {
return this.showSaveDialogSimplified(schema, options);
}
const result = await this.electronService.showSaveDialog(this.toNativeSaveDialogOptions(options));
if (result && !result.canceled && result.filePath) {
return URI.file(result.filePath);
}
return;
}
async showOpenDialog(options: IOpenDialogOptions): Promise<URI[] | undefined> {
const schema = this.getFileSystemSchema(options);
if (this.shouldUseSimplified(schema).useSimplified) {
return this.showOpenDialogSimplified(schema, options);
}
const defaultUri = options.defaultUri;
const newOptions: OpenDialogOptions = {
title: options.title,
defaultPath: defaultUri && defaultUri.fsPath,
buttonLabel: options.openLabel,
filters: options.filters,
properties: []
};
newOptions.properties!.push('createDirectory');
if (options.canSelectFiles) {
newOptions.properties!.push('openFile');
}
if (options.canSelectFolders) {
newOptions.properties!.push('openDirectory');
}
if (options.canSelectMany) {
newOptions.properties!.push('multiSelections');
}
const result = await this.electronService.showOpenDialog(newOptions);
return result && Array.isArray(result.filePaths) && result.filePaths.length > 0 ? result.filePaths.map(URI.file) : undefined;
}
}
registerSingleton(IFileDialogService, FileDialogService, true);
......@@ -65,7 +65,6 @@ import 'vs/workbench/services/editor/browser/codeEditorService';
import 'vs/workbench/services/preferences/browser/preferencesService';
import 'vs/workbench/services/configuration/common/jsonEditingService';
import 'vs/workbench/services/textmodelResolver/common/textModelResolverService';
import 'vs/workbench/services/dialogs/browser/fileDialogService';
import 'vs/workbench/services/editor/browser/editorService';
import 'vs/workbench/services/history/browser/history';
import 'vs/workbench/services/activity/browser/activityService';
......
......@@ -27,6 +27,7 @@ import 'vs/workbench/electron-browser/desktop.main';
//#region --- workbench services
import 'vs/workbench/services/dialogs/electron-browser/fileDialogService';
import 'vs/workbench/services/integrity/node/integrityService';
import 'vs/workbench/services/textMate/electron-browser/textMateService';
import 'vs/workbench/services/search/node/searchService';
......
......@@ -42,6 +42,7 @@ import 'vs/workbench/services/update/browser/updateService';
import 'vs/workbench/contrib/stats/browser/workspaceStatsService';
import 'vs/workbench/services/workspace/browser/workspacesService';
import 'vs/workbench/services/dialogs/browser/dialogService';
import 'vs/workbench/services/dialogs/browser/fileDialogService';
import 'vs/workbench/services/host/browser/browserHostService';
import 'vs/workbench/services/request/browser/requestService';
import 'vs/workbench/browser/web.simpleservices';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册