提交 44674775 编写于 作者: A Alex Ross

Add show local option for Save As on remote

Fixes https://github.com/microsoft/vscode-remote-release/issues/712
上级 0ad6f54c
......@@ -206,6 +206,11 @@ export interface IFileDialogService {
*/
pickWorkspaceAndOpen(options: IPickAndOpenOptions): Promise<void>;
/**
* Shows a save file file dialog and save the file at the chosen file URI.
*/
pickFileToSave(options: ISaveDialogOptions): Promise<URI | undefined>;
/**
* Shows a save file dialog and returns the chosen file URI.
*/
......
......@@ -54,6 +54,24 @@ export class OpenLocalFileAction extends Action {
}
}
export class SaveLocalFileAction extends Action {
static readonly ID = 'workbench.action.files.saveLocalFile';
static LABEL = nls.localize('saveLocalFile', "Save Local File...");
constructor(
id: string,
label: string,
@IFileDialogService private readonly dialogService: IFileDialogService
) {
super(id, label);
}
run(event?: any, data?: ITelemetryData): Promise<any> {
return this.dialogService.pickFileToSave({ availableFileSystems: [Schemas.file] });
}
}
export class OpenFolderAction extends Action {
static readonly ID = 'workbench.action.files.openFolder';
......
......@@ -14,7 +14,7 @@ import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform';
import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, OpenTwitterUrlAction, OpenRequestFeatureUrlAction, OpenPrivacyStatementUrlAction, OpenLicenseUrlAction, OpenNewsletterSignupUrlAction } from 'vs/workbench/electron-browser/actions/helpActions';
import { ToggleSharedProcessAction, InspectContextKeysAction, ToggleScreencastModeAction, ToggleDevToolsAction } from 'vs/workbench/electron-browser/actions/developerActions';
import { ShowAboutDialogAction, ZoomResetAction, ZoomOutAction, ZoomInAction, ToggleFullScreenAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, OpenRecentAction, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ReloadWindowAction, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-browser/actions/windowActions';
import { AddRootFolderAction, GlobalRemoveRootFolderAction, OpenWorkspaceAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, OpenFileFolderAction, OpenFileAction, OpenFolderAction, CloseWorkspaceAction, OpenLocalFileAction, OpenLocalFolderAction, OpenLocalFileFolderAction } from 'vs/workbench/browser/actions/workspaceActions';
import { AddRootFolderAction, GlobalRemoveRootFolderAction, OpenWorkspaceAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, OpenFileFolderAction, OpenFileAction, OpenFolderAction, CloseWorkspaceAction, OpenLocalFileAction, OpenLocalFolderAction, OpenLocalFileFolderAction, SaveLocalFileAction } from 'vs/workbench/browser/actions/workspaceActions';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { inQuickOpenContext, getQuickNavigateHandler } from 'vs/workbench/browser/parts/quickopen/quickopen';
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
......@@ -45,6 +45,7 @@ import product from 'vs/platform/product/node/product';
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenLocalFolderAction, OpenLocalFolderAction.ID, OpenLocalFolderAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_O) }, RemoteFileDialogContext), 'File: Open Local Folder...', fileCategory);
}
registry.registerWorkbenchAction(new SyncActionDescriptor(SaveLocalFileAction, SaveLocalFileAction.ID, SaveLocalFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_S }, RemoteFileDialogContext), 'File: Save Local File...', fileCategory);
registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenRecentAction, QuickOpenRecentAction.ID, QuickOpenRecentAction.LABEL), 'File: Quick Open Recent...', fileCategory);
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenRecentAction, OpenRecentAction.ID, OpenRecentAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_R, mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_R } }), 'File: Open Recent...', fileCategory);
registry.registerWorkbenchAction(new SyncActionDescriptor(CloseWorkspaceAction, CloseWorkspaceAction.ID, CloseWorkspaceAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_F) }), 'File: Close Workspace', fileCategory);
......
......@@ -187,6 +187,25 @@ export class FileDialogService implements IFileDialogService {
return this.windowService.pickWorkspaceAndOpen(this.toNativeOpenDialogOptions(options));
}
async pickFileToSave(options: ISaveDialogOptions): Promise<URI | undefined> {
const schema = this.getFileSystemSchema(options);
if (this.shouldUseSimplified(schema)) {
if (!options.availableFileSystems) {
options.availableFileSystems = this.ensureFileSchema(schema); // always allow file as well
}
options.title = nls.localize('saveFileAs.title', 'Save As');
return this.saveRemoteResource(options);
}
const result = await this.windowService.showSaveDialog(this.toNativeSaveDialogOptions(options));
if (result) {
return URI.file(result);
}
return;
}
private toNativeSaveDialogOptions(options: ISaveDialogOptions): Electron.SaveDialogOptions {
return {
defaultPath: options.defaultUri && options.defaultUri.fsPath || options.defaultFileName,
......
......@@ -23,7 +23,7 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { equalsIgnoreCase, format, startsWithIgnoreCase } from 'vs/base/common/strings';
import { OpenLocalFileAction, OpenLocalFileFolderAction, OpenLocalFolderAction } from 'vs/workbench/browser/actions/workspaceActions';
import { OpenLocalFileAction, OpenLocalFileFolderAction, OpenLocalFolderAction, SaveLocalFileAction } from 'vs/workbench/browser/actions/workspaceActions';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment';
import { isValidBasename } from 'vs/base/common/extpath';
......@@ -211,7 +211,12 @@ export class RemoteFileDialog {
if (this.options && this.options.availableFileSystems && (this.options.availableFileSystems.length > 1)) {
this.filePickBox.customButton = true;
this.filePickBox.customLabel = nls.localize('remoteFileDialog.local', 'Show Local');
const action = this.allowFileSelection ? (this.allowFolderSelection ? OpenLocalFileFolderAction : OpenLocalFileAction) : OpenLocalFolderAction;
let action;
if (isSave) {
action = SaveLocalFileAction;
} else {
action = this.allowFileSelection ? (this.allowFolderSelection ? OpenLocalFileFolderAction : OpenLocalFileAction) : OpenLocalFolderAction;
}
const keybinding = this.keybindingService.lookupKeybinding(action.ID);
if (keybinding) {
const label = keybinding.getLabel();
......@@ -251,7 +256,10 @@ export class RemoteFileDialog {
}
this.options.defaultUri = undefined;
this.filePickBox.hide();
if (this.requiresTrailing) {
if (isSave) {
// Remove defaultUri and filters to get a consistant experience with the keybinding.
this.options.defaultUri = undefined;
this.options.filters = undefined;
return this.fileDialogService.showSaveDialog(this.options).then(result => {
doResolve(this, result);
});
......
......@@ -653,7 +653,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
// Help user to find a name for the file by opening it first
await this.editorService.openEditor({ resource, options: { revealIfOpened: true, preserveFocus: true, } });
return this.fileDialogService.showSaveDialog(this.getSaveDialogOptions(defaultUri));
return this.fileDialogService.pickFileToSave(this.getSaveDialogOptions(defaultUri));
}
private getSaveDialogOptions(defaultUri: URI): ISaveDialogOptions {
......
......@@ -439,6 +439,9 @@ export class TestFileDialogService implements IFileDialogService {
public pickWorkspaceAndOpen(_options: IPickAndOpenOptions): Promise<any> {
return Promise.resolve(0);
}
public pickFileToSave(_options: ISaveDialogOptions): Promise<URI | undefined> {
return Promise.resolve(undefined);
}
public showSaveDialog(_options: ISaveDialogOptions): Promise<URI | undefined> {
return Promise.resolve(undefined);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册