55
66import * as nls from 'vs/nls' ;
77import { IWindowOpenable } from 'vs/platform/windows/common/windows' ;
8- import { IPickAndOpenOptions , ISaveDialogOptions , IOpenDialogOptions , FileFilter } from 'vs/platform/dialogs/common/dialogs' ;
8+ import { IPickAndOpenOptions , ISaveDialogOptions , IOpenDialogOptions , FileFilter , IFileDialogService , IDialogService , ConfirmResult , getConfirmMessage } from 'vs/platform/dialogs/common/dialogs' ;
99import { IWorkspaceContextService , WorkbenchState } from 'vs/platform/workspace/common/workspace' ;
1010import { IHistoryService } from 'vs/workbench/services/history/common/history' ;
1111import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService' ;
@@ -20,8 +20,9 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
2020import { IFileService } from 'vs/platform/files/common/files' ;
2121import { IOpenerService } from 'vs/platform/opener/common/opener' ;
2222import { IHostService } from 'vs/workbench/services/host/browser/host' ;
23+ import Severity from 'vs/base/common/severity' ;
2324
24- export abstract class AbstractFileDialogService {
25+ export abstract class AbstractFileDialogService implements IFileDialogService {
2526
2627 _serviceBrand : undefined ;
2728
@@ -34,6 +35,7 @@ export abstract class AbstractFileDialogService {
3435 @IConfigurationService protected readonly configurationService : IConfigurationService ,
3536 @IFileService protected readonly fileService : IFileService ,
3637 @IOpenerService protected readonly openerService : IOpenerService ,
38+ @IDialogService private readonly dialogService : IDialogService
3739 ) { }
3840
3941 defaultFilePath ( schemeFilter = this . getSchemeFilterForWindow ( ) ) : URI | undefined {
@@ -78,6 +80,40 @@ export abstract class AbstractFileDialogService {
7880 return this . defaultFilePath ( schemeFilter ) ;
7981 }
8082
83+ async showSaveConfirm ( fileNameOrResources : string | URI [ ] ) : Promise < ConfirmResult > {
84+ if ( this . environmentService . isExtensionDevelopment ) {
85+ return ConfirmResult . DONT_SAVE ; // no veto when we are in extension dev mode because we cannot assume we run interactive (e.g. tests)
86+ }
87+
88+ if ( Array . isArray ( fileNameOrResources ) && fileNameOrResources . length === 0 ) {
89+ return ConfirmResult . DONT_SAVE ;
90+ }
91+
92+ let message : string ;
93+ if ( typeof fileNameOrResources === 'string' || fileNameOrResources . length === 1 ) {
94+ message = nls . localize ( 'saveChangesMessage' , "Do you want to save the changes you made to {0}?" , typeof fileNameOrResources === 'string' ? fileNameOrResources : resources . basename ( fileNameOrResources [ 0 ] ) ) ;
95+ } else {
96+ message = getConfirmMessage ( nls . localize ( 'saveChangesMessages' , "Do you want to save the changes to the following {0} files?" , fileNameOrResources . length ) , fileNameOrResources ) ;
97+ }
98+
99+ const buttons : string [ ] = [
100+ Array . isArray ( fileNameOrResources ) && fileNameOrResources . length > 1 ? nls . localize ( { key : 'saveAll' , comment : [ '&& denotes a mnemonic' ] } , "&&Save All" ) : nls . localize ( { key : 'save' , comment : [ '&& denotes a mnemonic' ] } , "&&Save" ) ,
101+ nls . localize ( { key : 'dontSave' , comment : [ '&& denotes a mnemonic' ] } , "Do&&n't Save" ) ,
102+ nls . localize ( 'cancel' , "Cancel" )
103+ ] ;
104+
105+ const { choice } = await this . dialogService . show ( Severity . Warning , message , buttons , {
106+ cancelId : 2 ,
107+ detail : nls . localize ( 'saveChangesDetail' , "Your changes will be lost if you don't save them." )
108+ } ) ;
109+
110+ switch ( choice ) {
111+ case 0 : return ConfirmResult . SAVE ;
112+ case 1 : return ConfirmResult . DONT_SAVE ;
113+ default : return ConfirmResult . CANCEL ;
114+ }
115+ }
116+
81117 protected abstract addFileSchemaIfNeeded ( schema : string ) : string [ ] ;
82118
83119 protected async pickFileFolderAndOpenSimplified ( schema : string , options : IPickAndOpenOptions , preferNewWindow : boolean ) : Promise < any > {
@@ -179,4 +215,12 @@ export abstract class AbstractFileDialogService {
179215 protected getFileSystemSchema ( options : { availableFileSystems ?: readonly string [ ] , defaultUri ?: URI } ) : string {
180216 return options . availableFileSystems && options . availableFileSystems [ 0 ] || this . getSchemeFilterForWindow ( ) ;
181217 }
218+
219+ abstract pickFileFolderAndOpen ( options : IPickAndOpenOptions ) : Promise < void > ;
220+ abstract pickFileAndOpen ( options : IPickAndOpenOptions ) : Promise < void > ;
221+ abstract pickFolderAndOpen ( options : IPickAndOpenOptions ) : Promise < void > ;
222+ abstract pickWorkspaceAndOpen ( options : IPickAndOpenOptions ) : Promise < void > ;
223+ abstract pickFileToSave ( options : ISaveDialogOptions ) : Promise < URI | undefined > ;
224+ abstract showSaveDialog ( options : ISaveDialogOptions ) : Promise < URI | undefined > ;
225+ abstract showOpenDialog ( options : IOpenDialogOptions ) : Promise < URI [ ] | undefined > ;
182226}
0 commit comments