Skip to content

Commit 73f3eeb

Browse files
author
Benjamin Pasero
committed
smarter open/save picker default paths (fix microsoft#22697)
1 parent b6bd1ae commit 73f3eeb

22 files changed

Lines changed: 290 additions & 155 deletions

File tree

src/vs/code/electron-main/menus.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,9 +356,26 @@ export class CodeMenu {
356356
newFile = this.createMenuItem(nls.localize({ key: 'miNewFile', comment: ['&& denotes a mnemonic'] }, "&&New File"), 'workbench.action.files.newUntitledFile');
357357
}
358358

359-
const open = new MenuItem(this.likeAction('workbench.action.files.openFileFolder', { label: this.mnemonicLabel(nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open...")), click: (menuItem, win, event) => this.windowsService.pickFileFolderAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) }));
360-
const openWorkspace = new MenuItem(this.likeAction('workbench.action.openWorkspace', { label: this.mnemonicLabel(nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "&&Open Workspace...")), click: (menuItem, win, event) => this.windowsService.openWorkspace(void 0, { forceNewWindow: this.isOptionClick(event) }) }));
361-
const openFolder = new MenuItem(this.likeAction('workbench.action.files.openFolder', { label: this.mnemonicLabel(nls.localize({ key: 'miOpenFolder', comment: ['&& denotes a mnemonic'] }, "Open &&Folder...")), click: (menuItem, win, event) => this.windowsService.pickFolderAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) }));
359+
let open: Electron.MenuItem;
360+
if (hasNoWindows) {
361+
open = new MenuItem(this.likeAction('workbench.action.files.openFileFolder', { label: this.mnemonicLabel(nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open...")), click: (menuItem, win, event) => this.windowsService.pickFileFolderAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) }));
362+
} else {
363+
open = this.createMenuItem(nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open..."), ['workbench.action.files.openFileFolder', 'workbench.action.files.openFileFolderInNewWindow']);
364+
}
365+
366+
let openWorkspace: Electron.MenuItem;
367+
if (hasNoWindows) {
368+
openWorkspace = new MenuItem(this.likeAction('workbench.action.openWorkspace', { label: this.mnemonicLabel(nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "&&Open Workspace...")), click: (menuItem, win, event) => this.windowsService.pickWorkspaceAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) }));
369+
} else {
370+
openWorkspace = this.createMenuItem(nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "&&Open Workspace..."), ['workbench.action.openWorkspace', 'workbench.action.openWorkspaceInNewWindow']);
371+
}
372+
373+
let openFolder: Electron.MenuItem;
374+
if (hasNoWindows) {
375+
openFolder = new MenuItem(this.likeAction('workbench.action.files.openFolder', { label: this.mnemonicLabel(nls.localize({ key: 'miOpenFolder', comment: ['&& denotes a mnemonic'] }, "Open &&Folder...")), click: (menuItem, win, event) => this.windowsService.pickFolderAndOpen({ forceNewWindow: this.isOptionClick(event), telemetryExtraData: { from: telemetryFrom } }) }));
376+
} else {
377+
openFolder = this.createMenuItem(nls.localize({ key: 'miOpenFolder', comment: ['&& denotes a mnemonic'] }, "Open &&Folder..."), ['workbench.action.files.openFolder', 'workbench.action.files.openFolderInNewWindow']);
378+
}
362379

363380
let openFile: Electron.MenuItem;
364381
if (hasNoWindows) {

src/vs/code/electron-main/windows.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,8 +1339,8 @@ export class WindowsManager implements IWindowsMainService {
13391339
return result;
13401340
}
13411341

1342-
public openWorkspace(win?: CodeWindow, options?: { forceNewWindow?: boolean }): void {
1343-
this.workspacesManager.openWorkspace(win, options);
1342+
public pickWorkspaceAndOpen(options: INativeOpenDialogOptions): void {
1343+
this.workspacesManager.pickWorkspaceAndOpen(options);
13441344
}
13451345

13461346
private onBeforeWindowUnload(e: IWindowUnloadEvent): void {
@@ -1755,13 +1755,8 @@ class WorkspacesManager {
17551755
});
17561756
}
17571757

1758-
public openWorkspace(window = this.windowsMainService.getLastActiveWindow(), options?: { forceNewWindow?: boolean }): void {
1759-
let defaultPath: string;
1760-
if (window && window.openedWorkspace && !this.workspacesService.isUntitledWorkspace(window.openedWorkspace)) {
1761-
defaultPath = dirname(window.openedWorkspace.configPath);
1762-
} else {
1763-
defaultPath = this.getWorkspaceDialogDefaultPath(window ? (window.openedWorkspace || window.openedFolderPath) : void 0);
1764-
}
1758+
public pickWorkspaceAndOpen(options: INativeOpenDialogOptions): void {
1759+
const window = this.windowsMainService.getWindowById(options.windowId) || this.windowsMainService.getFocusedWindow() || this.windowsMainService.getLastActiveWindow();
17651760

17661761
this.windowsMainService.pickFileAndOpen({
17671762
windowId: window ? window.id : void 0,
@@ -1770,9 +1765,11 @@ class WorkspacesManager {
17701765
title: localize('openWorkspaceTitle', "Open Workspace"),
17711766
filters: WORKSPACE_FILTER,
17721767
properties: ['openFile'],
1773-
defaultPath
1768+
defaultPath: options.dialogOptions && options.dialogOptions.defaultPath
17741769
},
1775-
forceNewWindow: options && options.forceNewWindow
1770+
forceNewWindow: options.forceNewWindow,
1771+
telemetryEventName: options.telemetryEventName,
1772+
telemetryExtraData: options.telemetryExtraData
17761773
});
17771774
}
17781775

@@ -1831,7 +1828,7 @@ class WorkspacesManager {
18311828
buttonLabel: mnemonicButtonLabel(localize({ key: 'save', comment: ['&& denotes a mnemonic'] }, "&&Save")),
18321829
title: localize('saveWorkspace', "Save Workspace"),
18331830
filters: WORKSPACE_FILTER,
1834-
defaultPath: this.getWorkspaceDialogDefaultPath(workspace)
1831+
defaultPath: this.getUntitledWorkspaceSaveDialogDefaultPath(workspace)
18351832
});
18361833

18371834
if (target) {
@@ -1847,7 +1844,7 @@ class WorkspacesManager {
18471844
}
18481845
}
18491846

1850-
private getWorkspaceDialogDefaultPath(workspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier): string {
1847+
private getUntitledWorkspaceSaveDialogDefaultPath(workspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier): string {
18511848
if (workspace) {
18521849
if (isSingleFolderWorkspaceIdentifier(workspace)) {
18531850
return dirname(workspace);
@@ -1862,6 +1859,7 @@ class WorkspacesManager {
18621859
}
18631860
}
18641861
}
1862+
18651863
return void 0;
18661864
}
18671865
}

src/vs/platform/windows/common/windows.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ export interface IWindowsService {
4343
pickFileFolderAndOpen(options: INativeOpenDialogOptions): TPromise<void>;
4444
pickFileAndOpen(options: INativeOpenDialogOptions): TPromise<void>;
4545
pickFolderAndOpen(options: INativeOpenDialogOptions): TPromise<void>;
46+
pickWorkspaceAndOpen(options: INativeOpenDialogOptions): TPromise<void>;
4647
reloadWindow(windowId: number): TPromise<void>;
4748
openDevTools(windowId: number): TPromise<void>;
4849
toggleDevTools(windowId: number): TPromise<void>;
4950
closeWorkspace(windowId: number): TPromise<void>;
50-
openWorkspace(windowId: number): TPromise<void>;
5151
createAndEnterWorkspace(windowId: number, folderPaths?: string[], path?: string): TPromise<IEnterWorkspaceResult>;
5252
saveAndEnterWorkspace(windowId: number, path: string): TPromise<IEnterWorkspaceResult>;
5353
toggleFullScreen(windowId: number): TPromise<void>;
@@ -115,11 +115,11 @@ export interface IWindowService {
115115
pickFileFolderAndOpen(options: INativeOpenDialogOptions): TPromise<void>;
116116
pickFileAndOpen(options: INativeOpenDialogOptions): TPromise<void>;
117117
pickFolderAndOpen(options: INativeOpenDialogOptions): TPromise<void>;
118+
pickWorkspaceAndOpen(options: INativeOpenDialogOptions): TPromise<void>;
118119
reloadWindow(): TPromise<void>;
119120
openDevTools(): TPromise<void>;
120121
toggleDevTools(): TPromise<void>;
121122
closeWorkspace(): TPromise<void>;
122-
openWorkspace(): TPromise<void>;
123123
updateTouchBar(items: ICommandAction[][]): TPromise<void>;
124124
createAndEnterWorkspace(folderPaths?: string[], path?: string): TPromise<IEnterWorkspaceResult>;
125125
saveAndEnterWorkspace(path: string): TPromise<IEnterWorkspaceResult>;

src/vs/platform/windows/common/windowsIpc.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ export interface IWindowsChannel extends IChannel {
2020
call(command: 'pickFileFolderAndOpen', arg: INativeOpenDialogOptions): TPromise<void>;
2121
call(command: 'pickFileAndOpen', arg: INativeOpenDialogOptions): TPromise<void>;
2222
call(command: 'pickFolderAndOpen', arg: INativeOpenDialogOptions): TPromise<void>;
23+
call(command: 'pickWorkspaceAndOpen', arg: INativeOpenDialogOptions): TPromise<void>;
2324
call(command: 'reloadWindow', arg: number): TPromise<void>;
2425
call(command: 'toggleDevTools', arg: number): TPromise<void>;
2526
call(command: 'closeWorkspace', arg: number): TPromise<void>;
26-
call(command: 'openWorkspace', arg: number): TPromise<void>;
2727
call(command: 'createAndEnterWorkspace', arg: [number, string[], string]): TPromise<IEnterWorkspaceResult>;
2828
call(command: 'saveAndEnterWorkspace', arg: [number, string]): TPromise<IEnterWorkspaceResult>;
2929
call(command: 'toggleFullScreen', arg: number): TPromise<void>;
@@ -82,11 +82,11 @@ export class WindowsChannel implements IWindowsChannel {
8282
case 'pickFileFolderAndOpen': return this.service.pickFileFolderAndOpen(arg);
8383
case 'pickFileAndOpen': return this.service.pickFileAndOpen(arg);
8484
case 'pickFolderAndOpen': return this.service.pickFolderAndOpen(arg);
85+
case 'pickWorkspaceAndOpen': return this.service.pickWorkspaceAndOpen(arg);
8586
case 'reloadWindow': return this.service.reloadWindow(arg);
8687
case 'openDevTools': return this.service.openDevTools(arg);
8788
case 'toggleDevTools': return this.service.toggleDevTools(arg);
8889
case 'closeWorkspace': return this.service.closeWorkspace(arg);
89-
case 'openWorkspace': return this.service.openWorkspace(arg);
9090
case 'createAndEnterWorkspace': return this.service.createAndEnterWorkspace(arg[0], arg[1], arg[2]);
9191
case 'saveAndEnterWorkspace': return this.service.saveAndEnterWorkspace(arg[0], arg[1]);
9292
case 'toggleFullScreen': return this.service.toggleFullScreen(arg);
@@ -154,6 +154,10 @@ export class WindowsChannelClient implements IWindowsService {
154154
return this.channel.call('pickFolderAndOpen', options);
155155
}
156156

157+
pickWorkspaceAndOpen(options: INativeOpenDialogOptions): TPromise<void> {
158+
return this.channel.call('pickWorkspaceAndOpen', options);
159+
}
160+
157161
reloadWindow(windowId: number): TPromise<void> {
158162
return this.channel.call('reloadWindow', windowId);
159163
}
@@ -170,10 +174,6 @@ export class WindowsChannelClient implements IWindowsService {
170174
return this.channel.call('closeWorkspace', windowId);
171175
}
172176

173-
openWorkspace(windowId: number): TPromise<void> {
174-
return this.channel.call('openWorkspace', windowId);
175-
}
176-
177177
createAndEnterWorkspace(windowId: number, folderPaths?: string[], path?: string): TPromise<IEnterWorkspaceResult> {
178178
return this.channel.call('createAndEnterWorkspace', [windowId, folderPaths, path]);
179179
}

src/vs/platform/windows/electron-browser/windowService.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ export class WindowService implements IWindowService {
5151
return this.windowsService.pickFolderAndOpen(options);
5252
}
5353

54+
pickWorkspaceAndOpen(options: INativeOpenDialogOptions): TPromise<void> {
55+
options.windowId = this.windowId;
56+
57+
return this.windowsService.pickWorkspaceAndOpen(options);
58+
}
59+
5460
reloadWindow(): TPromise<void> {
5561
return this.windowsService.reloadWindow(this.windowId);
5662
}
@@ -67,10 +73,6 @@ export class WindowService implements IWindowService {
6773
return this.windowsService.closeWorkspace(this.windowId);
6874
}
6975

70-
openWorkspace(): TPromise<void> {
71-
return this.windowsService.openWorkspace(this.windowId);
72-
}
73-
7476
createAndEnterWorkspace(folderPaths?: string[], path?: string): TPromise<IEnterWorkspaceResult> {
7577
return this.windowsService.createAndEnterWorkspace(this.windowId, folderPaths, path);
7678
}

src/vs/platform/windows/electron-main/windows.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ export interface IWindowsMainService {
6060
// methods
6161
ready(initialUserEnv: IProcessEnvironment): void;
6262
reload(win: ICodeWindow, cli?: ParsedArgs): void;
63-
openWorkspace(win?: ICodeWindow, options?: { forceNewWindow?: boolean }): void;
6463
createAndEnterWorkspace(win: ICodeWindow, folderPaths?: string[], path?: string): TPromise<IEnterWorkspaceResult>;
6564
saveAndEnterWorkspace(win: ICodeWindow, path: string): TPromise<IEnterWorkspaceResult>;
6665
closeWorkspace(win: ICodeWindow): void;
@@ -69,6 +68,7 @@ export interface IWindowsMainService {
6968
pickFileFolderAndOpen(options: INativeOpenDialogOptions): void;
7069
pickFolderAndOpen(options: INativeOpenDialogOptions): void;
7170
pickFileAndOpen(options: INativeOpenDialogOptions): void;
71+
pickWorkspaceAndOpen(options: INativeOpenDialogOptions): void;
7272
focusLastActive(cli: ParsedArgs, context: OpenContext): ICodeWindow;
7373
getLastActiveWindow(): ICodeWindow;
7474
waitForWindowCloseOrLoad(windowId: number): TPromise<void>;

src/vs/platform/windows/electron-main/windowsService.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ export class WindowsService implements IWindowsService, IDisposable {
7070
return TPromise.as(null);
7171
}
7272

73+
pickWorkspaceAndOpen(options: INativeOpenDialogOptions): TPromise<void> {
74+
this.windowsMainService.pickWorkspaceAndOpen(options);
75+
76+
return TPromise.as(null);
77+
}
78+
7379
reloadWindow(windowId: number): TPromise<void> {
7480
const codeWindow = this.windowsMainService.getWindowById(windowId);
7581

@@ -125,16 +131,6 @@ export class WindowsService implements IWindowsService, IDisposable {
125131
return TPromise.as(null);
126132
}
127133

128-
openWorkspace(windowId: number): TPromise<void> {
129-
const codeWindow = this.windowsMainService.getWindowById(windowId);
130-
131-
if (codeWindow) {
132-
this.windowsMainService.openWorkspace(codeWindow);
133-
}
134-
135-
return TPromise.as(null);
136-
}
137-
138134
createAndEnterWorkspace(windowId: number, folderPaths?: string[], path?: string): TPromise<IEnterWorkspaceResult> {
139135
const codeWindow = this.windowsMainService.getWindowById(windowId);
140136

src/vs/platform/workspace/common/workspace.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ export interface IWorkspaceContextService {
4848
onDidChangeWorkspaceFolders: Event<IWorkspaceFoldersChangeEvent>;
4949

5050
/**
51-
* Provides access to the workspace object the platform is running with. This may be null if the workbench was opened
52-
* without workspace (empty);
51+
* Provides access to the workspace object the platform is running with.
5352
*/
5453
getWorkspace(): IWorkspace;
5554

0 commit comments

Comments
 (0)