Skip to content

Commit 04271d1

Browse files
committed
Add alternate dialog
1 parent 43d68b6 commit 04271d1

14 files changed

Lines changed: 415 additions & 31 deletions

File tree

src/vs/platform/contextkey/common/contextkeys.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ export const InputFocusedContext = new RawContextKey<boolean>(InputFocusedContex
1111
export const IsMacContext = new RawContextKey<boolean>('isMac', isMacintosh);
1212
export const IsLinuxContext = new RawContextKey<boolean>('isLinux', isLinux);
1313
export const IsWindowsContext = new RawContextKey<boolean>('isWindows', isWindows);
14+
15+
export const SupportsWorkspacesContext = new RawContextKey<boolean>('supportsWorkspaces', true);
16+
export const SupportsOpenFileFolderContext = new RawContextKey<boolean>('supportsOpenFileFolder', isMacintosh);

src/vs/platform/label/common/label.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export interface ILabelService {
1919
* If relative is passed returns a label relative to the workspace root that the uri belongs to.
2020
* If noPrefix is passed does not tildify the label and also does not prepand the root name for relative labels in a multi root scenario.
2121
*/
22-
getUriLabel(resource: URI, options?: { relative?: boolean, noPrefix?: boolean }): string;
22+
getUriLabel(resource: URI, options?: { relative?: boolean, noPrefix?: boolean, endWithSeparator?: boolean }): string;
2323
getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | IWorkspace), options?: { verbose: boolean }): string;
2424
getHostLabel(): string;
2525
registerFormatter(formatter: ResourceLabelFormatter): IDisposable;

src/vs/workbench/contrib/files/electron-browser/fileActions.contribution.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { ResourceContextKey } from 'vs/workbench/common/resources';
2323
import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService';
2424
import { URI } from 'vs/base/common/uri';
2525
import { Schemas } from 'vs/base/common/network';
26+
import { SupportsWorkspacesContext } from 'vs/platform/contextkey/common/contextkeys';
2627
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
2728

2829
// Contribute Global Actions
@@ -478,7 +479,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
478479
id: ADD_ROOT_FOLDER_COMMAND_ID,
479480
title: ADD_ROOT_FOLDER_LABEL
480481
},
481-
when: ContextKeyExpr.and(ExplorerRootContext)
482+
when: ContextKeyExpr.and(ExplorerRootContext, SupportsWorkspacesContext)
482483
});
483484

484485
MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {

src/vs/workbench/contrib/files/electron-browser/fileActions.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import { AsyncDataTree } from 'vs/base/browser/ui/tree/asyncDataTree';
4646
import { ExplorerItem } from 'vs/workbench/contrib/files/common/explorerModel';
4747
import { onUnexpectedError } from 'vs/base/common/errors';
4848
import { sequence } from 'vs/base/common/async';
49+
import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts';
4950

5051
export const NEW_FILE_COMMAND_ID = 'explorer.newFile';
5152
export const NEW_FILE_LABEL = nls.localize('newFile', "New File");
@@ -874,8 +875,8 @@ export class ShowOpenedFileInNewWindow extends Action {
874875
}
875876

876877
public run(): Promise<any> {
877-
const fileResource = toResource(this.editorService.activeEditor, { supportSideBySide: true, filter: Schemas.file /* todo@remote */ });
878-
if (fileResource) {
878+
const fileResource = toResource(this.editorService.activeEditor, { supportSideBySide: true });
879+
if (fileResource && (fileResource.scheme === Schemas.file || fileResource.scheme === REMOTE_HOST_SCHEME)) {
879880
this.windowService.openWindow([{ uri: fileResource, typeHint: 'file' }], { forceNewWindow: true, forceOpenWorkspaceAsFile: true });
880881
} else {
881882
this.notificationService.info(nls.localize('openFileToShowInNewWindow', "Open a file first to open in new window"));

src/vs/workbench/electron-browser/shell.contribution.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/co
2121
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
2222
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
2323
import { ADD_ROOT_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands';
24-
import { IsMacContext } from 'vs/platform/contextkey/common/contextkeys';
24+
import { SupportsOpenFileFolderContext, SupportsWorkspacesContext, IsMacContext } from 'vs/platform/contextkey/common/contextkeys';
2525
import { NoEditorsVisibleContext, SingleEditorGroupsContext } from 'vs/workbench/common/editor';
2626
import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows';
2727

@@ -61,12 +61,9 @@ workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(Switch
6161
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(QuickSwitchWindow, QuickSwitchWindow.ID, QuickSwitchWindow.LABEL), 'Quick Switch Window...');
6262
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenRecentAction, QuickOpenRecentAction.ID, QuickOpenRecentAction.LABEL), 'File: Quick Open Recent...', fileCategory);
6363

64-
if (isMacintosh) {
65-
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenFileFolderAction, OpenFileFolderAction.ID, OpenFileFolderAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }), 'File: Open...', fileCategory);
66-
} else {
67-
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenFileAction, OpenFileAction.ID, OpenFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }), 'File: Open File...', fileCategory);
68-
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenFolderAction, OpenFolderAction.ID, OpenFolderAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_O) }), 'File: Open Folder...', fileCategory);
69-
}
64+
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenFileFolderAction, OpenFileFolderAction.ID, OpenFileFolderAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }), 'File: Open...', fileCategory, SupportsOpenFileFolderContext);
65+
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenFileAction, OpenFileAction.ID, OpenFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }), 'File: Open File...', fileCategory, SupportsOpenFileFolderContext.toNegated());
66+
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenFolderAction, OpenFolderAction.ID, OpenFolderAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_O) }), 'File: Open Folder...', fileCategory, SupportsOpenFileFolderContext.toNegated());
7067

7168
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(CloseWorkspaceAction, CloseWorkspaceAction.ID, CloseWorkspaceAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_F) }), 'File: Close Workspace', fileCategory);
7269

@@ -115,10 +112,10 @@ workbenchActionsRegistry.registerWorkbenchAction(
115112
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleFullScreenAction, ToggleFullScreenAction.ID, ToggleFullScreenAction.LABEL, { primary: KeyCode.F11, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_F } }), 'View: Toggle Full Screen', viewCategory);
116113

117114
const workspacesCategory = nls.localize('workspaces', "Workspaces");
118-
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(AddRootFolderAction, AddRootFolderAction.ID, AddRootFolderAction.LABEL), 'Workspaces: Add Folder to Workspace...', workspacesCategory);
115+
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(AddRootFolderAction, AddRootFolderAction.ID, AddRootFolderAction.LABEL), 'Workspaces: Add Folder to Workspace...', workspacesCategory, SupportsWorkspacesContext);
119116
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(GlobalRemoveRootFolderAction, GlobalRemoveRootFolderAction.ID, GlobalRemoveRootFolderAction.LABEL), 'Workspaces: Remove Folder from Workspace...', workspacesCategory);
120-
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenWorkspaceAction, OpenWorkspaceAction.ID, OpenWorkspaceAction.LABEL), 'Workspaces: Open Workspace...', workspacesCategory);
121-
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(SaveWorkspaceAsAction, SaveWorkspaceAsAction.ID, SaveWorkspaceAsAction.LABEL), 'Workspaces: Save Workspace As...', workspacesCategory);
117+
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenWorkspaceAction, OpenWorkspaceAction.ID, OpenWorkspaceAction.LABEL), 'Workspaces: Open Workspace...', workspacesCategory, SupportsWorkspacesContext);
118+
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(SaveWorkspaceAsAction, SaveWorkspaceAsAction.ID, SaveWorkspaceAsAction.LABEL), 'Workspaces: Save Workspace As...', workspacesCategory, SupportsWorkspacesContext);
122119
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(DuplicateWorkspaceInNewWindowAction, DuplicateWorkspaceInNewWindowAction.ID, DuplicateWorkspaceInNewWindowAction.LABEL), 'Workspaces: Duplicate Workspace in New Window', workspacesCategory);
123120

124121
CommandsRegistry.registerCommand(OpenWorkspaceConfigFileAction.ID, serviceAccessor => {
@@ -178,7 +175,7 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
178175
title: nls.localize({ key: 'miOpenFile', comment: ['&& denotes a mnemonic'] }, "&&Open File...")
179176
},
180177
order: 1,
181-
when: IsMacContext.toNegated()
178+
when: SupportsOpenFileFolderContext.toNegated()
182179
});
183180

184181
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
@@ -188,7 +185,7 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
188185
title: nls.localize({ key: 'miOpenFolder', comment: ['&& denotes a mnemonic'] }, "Open &&Folder...")
189186
},
190187
order: 2,
191-
when: IsMacContext.toNegated()
188+
when: SupportsOpenFileFolderContext.toNegated()
192189
});
193190

194191
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
@@ -198,7 +195,7 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
198195
title: nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open...")
199196
},
200197
order: 1,
201-
when: IsMacContext
198+
when: SupportsOpenFileFolderContext
202199
});
203200

204201
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
@@ -207,7 +204,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
207204
id: OpenWorkspaceAction.ID,
208205
title: nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "Open Wor&&kspace...")
209206
},
210-
order: 3
207+
order: 3,
208+
when: SupportsWorkspacesContext
211209
});
212210

213211
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
@@ -234,7 +232,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
234232
id: ADD_ROOT_FOLDER_COMMAND_ID,
235233
title: nls.localize({ key: 'miAddFolderToWorkspace', comment: ['&& denotes a mnemonic'] }, "A&&dd Folder to Workspace...")
236234
},
237-
order: 1
235+
order: 1,
236+
when: SupportsWorkspacesContext
238237
});
239238

240239
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
@@ -243,7 +242,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
243242
id: SaveWorkspaceAsAction.ID,
244243
title: nls.localize('miSaveWorkspaceAs', "Save Workspace As...")
245244
},
246-
order: 2
245+
order: 2,
246+
when: SupportsWorkspacesContext
247247
});
248248

249249
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {

src/vs/workbench/electron-browser/workbench.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ import { IDecorationsService } from 'vs/workbench/services/decorations/browser/d
8787
import { ActivityService } from 'vs/workbench/services/activity/browser/activityService';
8888
import { URI } from 'vs/base/common/uri';
8989
import { IListService, ListService } from 'vs/platform/list/browser/listService';
90-
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext } from 'vs/platform/contextkey/common/contextkeys';
90+
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, SupportsOpenFileFolderContext, SupportsWorkspacesContext } from 'vs/platform/contextkey/common/contextkeys';
9191
import { IViewsService } from 'vs/workbench/common/views';
9292
import { ViewsService } from 'vs/workbench/browser/parts/views/views';
9393
import { INotificationService } from 'vs/platform/notification/common/notification';
@@ -109,7 +109,7 @@ import { ContextViewService } from 'vs/platform/contextview/browser/contextViewS
109109
import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService';
110110
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
111111
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
112-
import { FileDialogService } from 'vs/workbench/services/dialogs/electron-browser/dialogService';
112+
import { RemoteFileDialogService } from 'vs/workbench/services/dialogs/electron-browser/dialogService';
113113
import { LogStorageAction } from 'vs/platform/storage/node/storageService';
114114
import { Sizing, Direction, Grid, View } from 'vs/base/browser/ui/grid/grid';
115115
import { IEditor } from 'vs/editor/common/editorCommon';
@@ -425,7 +425,7 @@ export class Workbench extends Disposable implements IPartService {
425425
serviceCollection.set(IHistoryService, new SyncDescriptor(HistoryService));
426426

427427
// File Dialogs
428-
serviceCollection.set(IFileDialogService, new SyncDescriptor(FileDialogService));
428+
serviceCollection.set(IFileDialogService, new SyncDescriptor(RemoteFileDialogService));
429429

430430
// Backup File Service
431431
if (this.workbenchParams.configuration.backupPath) {
@@ -627,6 +627,12 @@ export class Workbench extends Disposable implements IPartService {
627627
IsMacContext.bindTo(this.contextKeyService);
628628
IsLinuxContext.bindTo(this.contextKeyService);
629629
IsWindowsContext.bindTo(this.contextKeyService);
630+
const supportsOpenFileFolderContextKey = SupportsOpenFileFolderContext.bindTo(this.contextKeyService);
631+
const supportsWorkspacesContextKey = SupportsWorkspacesContext.bindTo(this.contextKeyService);
632+
if (this.windowService.getConfiguration().remoteAuthority) {
633+
supportsOpenFileFolderContextKey.set(true);
634+
supportsWorkspacesContextKey.set(false);
635+
}
630636

631637
const sidebarVisibleContextRaw = new RawContextKey<boolean>('sidebarVisible', false);
632638
this.sideBarVisibleContext = sidebarVisibleContextRaw.bindTo(this.contextKeyService);

src/vs/workbench/services/dialogs/electron-browser/dialogService.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@ import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/
1515
import { IHistoryService } from 'vs/workbench/services/history/common/history';
1616
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
1717
import { URI } from 'vs/base/common/uri';
18+
import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts';
1819
import { Schemas } from 'vs/base/common/network';
1920
import * as resources from 'vs/base/common/resources';
2021
import { isParent } from 'vs/platform/files/common/files';
22+
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
23+
import { RemoteFileDialog } from 'vs/workbench/services/dialogs/electron-browser/remoteFileDialog';
2124

2225
interface IMassagedMessageBoxOptions {
2326

@@ -160,7 +163,8 @@ export class FileDialogService implements IFileDialogService {
160163
@IWindowService private readonly windowService: IWindowService,
161164
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
162165
@IHistoryService private readonly historyService: IHistoryService,
163-
@IEnvironmentService private readonly environmentService: IEnvironmentService
166+
@IEnvironmentService private readonly environmentService: IEnvironmentService,
167+
@IInstantiationService private readonly instantiationService: IInstantiationService,
164168
) { }
165169

166170
defaultFilePath(schemeFilter: string): URI | undefined {
@@ -273,6 +277,11 @@ export class FileDialogService implements IFileDialogService {
273277
});
274278
}
275279

280+
public showSaveRemoteDialog(options: ISaveDialogOptions): Promise<URI | undefined> {
281+
const remoteFileDialog = this.instantiationService.createInstance(RemoteFileDialog);
282+
return remoteFileDialog.showSaveDialog(options);
283+
}
284+
276285
showOpenDialog(options: IOpenDialogOptions): Promise<URI[] | undefined> {
277286
const defaultUri = options.defaultUri;
278287
if (defaultUri && defaultUri.scheme !== Schemas.file) {
@@ -303,6 +312,32 @@ export class FileDialogService implements IFileDialogService {
303312

304313
return this.windowService.showOpenDialog(newOptions).then(result => result ? result.map(URI.file) : undefined);
305314
}
315+
316+
public showOpenRemoteDialog(options: IOpenDialogOptions): Promise<void> {
317+
const remoteFileDialog = this.instantiationService.createInstance(RemoteFileDialog);
318+
return remoteFileDialog.showOpenDialog(options);
319+
}
320+
}
321+
322+
export class RemoteFileDialogService extends FileDialogService {
323+
324+
constructor(
325+
@IWindowService windowService: IWindowService,
326+
@IWorkspaceContextService contextService: IWorkspaceContextService,
327+
@IHistoryService historyService: IHistoryService,
328+
@IEnvironmentService environmentService: IEnvironmentService,
329+
@IInstantiationService instantiationService: IInstantiationService,
330+
) {
331+
super(windowService, contextService, historyService, environmentService, instantiationService);
332+
}
333+
334+
public showSaveDialog(options: ISaveDialogOptions): Promise<URI> {
335+
const defaultUri = options.defaultUri;
336+
if (defaultUri && defaultUri.scheme === REMOTE_HOST_SCHEME) {
337+
return this.showSaveRemoteDialog(options);
338+
}
339+
return super.showSaveDialog(options);
340+
}
306341
}
307342

308343
function isUntitledWorkspace(path: string, environmentService: IEnvironmentService): boolean {

0 commit comments

Comments
 (0)