Skip to content

Commit

Permalink
dialogs - Allow multiple selection on Open...
Browse files Browse the repository at this point in the history
fixes #12905

- allow multiple selection in doOpen dialog
- handle an array or a single URI or undefined when closing dialog

Contributed on behalf of ST Microelectronics

Signed-off-by: Remi Schnekenburger <[email protected]>

Address review comments

- remove checks for files against workspace URI
- update variable name to a more representative one
- Simplify algorithm for single selected URI case
- update signatures to indicate an array of files or folders can be opened rather than a single element
  • Loading branch information
rschnekenbu committed Sep 28, 2023
1 parent e0b4cb9 commit 6ee97b3
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- [core] fixed logger level propagation when log config file changes at runtime [#12566](https://github.com/eclipse-theia/theia/pull/12566) - Contributed on behalf of STMicroelectronics
- [core] improve frontend startup time [#12936](https://github.com/eclipse-theia/theia/pull/12936) - Contributed on behalf of STMicroelectronics
- [dev-packages] restore src-gen frontend production behavior [12950](https://github.com/eclipse-theia/theia/pull/12950) - Contributed on behalf of STMicroelectronics
- [dialogs] allow multiple selection on Open... [#12923](https://github.com/eclipse-theia/theia/pull/12923) - Contributed on behalf of STMicroelectronics.
- [vscode] stub TestController invalidateTestResults [#12944](https://github.com/eclipse-theia/theia/pull/12944) - Contributed by STMicroelectronics
- [vscode] support iconPath in QuickPickItem [#12945](https://github.com/eclipse-theia/theia/pull/12945) - Contributed by STMicroelectronics
- [vsx-registry] added a hint to extension fetching ENOTFOUND errors [#12858](https://github.com/eclipse-theia/theia/pull/12858) - Contributed by STMicroelectronics
Expand Down
76 changes: 51 additions & 25 deletions packages/workspace/src/browser/workspace-frontend-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,50 +262,76 @@ export class WorkspaceFrontendContribution implements CommandContribution, Keybi
* This is the generic `Open` method. Opens files and directories too. Resolves to the opened URI.
* Except when you are on either Windows or Linux `AND` running in electron. If so, it opens a file.
*/
protected async doOpen(): Promise<URI | undefined> {
protected async doOpen(): Promise<URI[] | undefined> {
if (!isOSX && this.isElectron()) {
return this.doOpenFile();
}
const [rootStat] = await this.workspaceService.roots;
const destinationUri = await this.fileDialogService.showOpenDialog({
let selectedUris = await this.fileDialogService.showOpenDialog({
title: WorkspaceCommands.OPEN.dialogLabel,
canSelectFolders: true,
canSelectFiles: true
canSelectFiles: true,
canSelectMany: true
}, rootStat);
if (destinationUri && this.getCurrentWorkspaceUri()?.toString() !== destinationUri.toString()) {
const destination = await this.fileService.resolve(destinationUri);
if (destination.isDirectory) {
this.workspaceService.open(destinationUri);
} else {
await open(this.openerService, destinationUri);
if (selectedUris) {
if (!Array.isArray(selectedUris)) {
selectedUris = [selectedUris];
}
const folders: URI[] = [];
// Only open files then open all folders in a new workspace, as done with Electron see doOpenFolder.
for (const uri of selectedUris) {
const destination = await this.fileService.resolve(uri);
if (destination.isDirectory) {
if (this.getCurrentWorkspaceUri()?.toString() !== uri.toString()) {
folders.push(uri);
}
} else {
await open(this.openerService, uri);
}
}
return destinationUri;
if (folders.length > 0) {
const openableURI = await this.getOpenableWorkspaceUri(folders);
if (openableURI && (!this.workspaceService.workspace || !openableURI.isEqual(this.workspaceService.workspace.resource))) {
this.workspaceService.open(openableURI);
}
}

return selectedUris;
}
return undefined;
}

/**
* Opens a file after prompting the `Open File` dialog. Resolves to `undefined`, if
* Opens a set of files after prompting the `Open File` dialog. Resolves to `undefined`, if
* - the workspace root is not set,
* - the file to open does not exist, or
* - it was not a file, but a directory.
*
* Otherwise, resolves to the URI of the file.
* Otherwise, resolves to the set of URIs of the files.
*/
protected async doOpenFile(): Promise<URI | undefined> {
protected async doOpenFile(): Promise<URI[] | undefined> {
const props: OpenFileDialogProps = {
title: WorkspaceCommands.OPEN_FILE.dialogLabel,
canSelectFolders: false,
canSelectFiles: true
canSelectFiles: true,
canSelectMany: true
};
const [rootStat] = await this.workspaceService.roots;
const destinationFileUri = await this.fileDialogService.showOpenDialog(props, rootStat);
if (destinationFileUri) {
const destinationFile = await this.fileService.resolve(destinationFileUri);
if (!destinationFile.isDirectory) {
await open(this.openerService, destinationFileUri);
return destinationFileUri;
let selectedFilesUris: MaybeArray<URI> | undefined = await this.fileDialogService.showOpenDialog(props, rootStat);
if (selectedFilesUris) {
if (!Array.isArray(selectedFilesUris)) {
selectedFilesUris = [selectedFilesUris];
}

const result = [];
for (const uri of selectedFilesUris) {
const destination = await this.fileService.resolve(uri);
if (destination.isFile) {
await open(this.openerService, uri);
result.push(uri);
}
}
return result;
}
return undefined;
}
Expand All @@ -329,11 +355,11 @@ export class WorkspaceFrontendContribution implements CommandContribution, Keybi
const [rootStat] = await this.workspaceService.roots;
const targetFolders = await this.fileDialogService.showOpenDialog(props, rootStat);
if (targetFolders) {
const openableURI = await this.getOpenableWorkspaceUri(targetFolders);
if (openableURI) {
if (!this.workspaceService.workspace || !openableURI.isEqual(this.workspaceService.workspace.resource)) {
this.workspaceService.open(openableURI);
return openableURI;
const openableUri = await this.getOpenableWorkspaceUri(targetFolders);
if (openableUri) {
if (!this.workspaceService.workspace || !openableUri.isEqual(this.workspaceService.workspace.resource)) {
this.workspaceService.open(openableUri);
return openableUri;
}
};
}
Expand Down

0 comments on commit 6ee97b3

Please sign in to comment.