@@ -53,31 +53,23 @@ function createMultiSelectItem(
5353 return result ;
5454}
5555
56- function createSingleSelectItem (
57- item : { Name : string ; Type : number } ,
58- parent ?: string ,
59- delimiter ?: string
60- ) : DocumentPickerItem {
61- const result : DocumentPickerItem = { label : item . Name , fullName : item . Name } ;
62- // Add the icon
56+ function createSingleSelectItem ( item : { Name : string ; Type : number } ) : vscode . QuickPickItem {
57+ // Determine the icon
58+ let icon = "$(symbol-file)" ;
6359 if ( item . Type == 0 ) {
6460 if ( item . Name . endsWith ( ".inc" ) ) {
65- result . label = "$(file-symlink-file) " + result . label ;
61+ icon = "$(file-symlink-file)" ;
6662 } else if ( item . Name . endsWith ( ".int" ) || item . Name . endsWith ( ".mac" ) ) {
67- result . label = "$(note) " + result . label ;
63+ icon = "$(note)" ;
6864 } else {
69- result . label = "$(symbol-misc) " + result . label ;
65+ icon = "$(symbol-misc)" ;
7066 }
7167 } else if ( item . Type == 4 ) {
72- result . label = "$(symbol-class) " + result . label ;
73- } else if ( ! [ 9 , 10 ] . includes ( item . Type ) ) {
74- result . label = "$(symbol-file) " + result . label ;
75- }
76- if ( parent ) {
77- // Update the full name if this is a nested item
78- result . fullName = parent + delimiter + item . Name ;
68+ icon = "$(symbol-class)" ;
69+ } else {
70+ icon = "$(symbol-file)" ;
7971 }
80- return result ;
72+ return { label : ` ${ icon } ${ item . Name } ` } ;
8173}
8274
8375/**
@@ -300,19 +292,12 @@ export async function pickDocument(
300292 let sys : "0" | "1" = "0" ;
301293 let gen : "0" | "1" = "0" ;
302294 let map : "0" | "1" = "1" ;
303- const query = "SELECT Name, Type FROM %Library.RoutineMgr_StudioOpenDialog(?,1,1,?,0,0,?,,0,?)" ;
304- const webApps = ( typeSuffix ?? "csp" ) == "csp" ? cspAppsForApi ( api ) : [ ] ;
305- const webAppRootItems = webApps . map ( ( app : string ) => {
306- return {
307- label : app ,
308- fullName : app ,
309- } ;
310- } ) ;
295+ const query = "SELECT Name, Type FROM %Library.RoutineMgr_StudioOpenDialog(?,1,1,?,1,0,?,,0,?)" ;
311296
312297 return new Promise < string > ( ( resolve ) => {
313- const quickPick = vscode . window . createQuickPick < DocumentPickerItem > ( ) ;
298+ const quickPick = vscode . window . createQuickPick ( ) ;
314299 quickPick . prompt =
315- "Select a package or folder to view its contents. Selecting '..' shows the previous level's contents. You may also type a full document name into the filter box and press 'Enter' to select that document ." ;
300+ "You may also type a full document name with extension into the filter box and press 'Enter' to select it ." ;
316301 quickPick . title = `${ prompt ? prompt : "Select a document" } ${ numberOfSteps ? `(${ step } /${ numberOfSteps } )` : `in namespace '${ api . ns } ' on server '${ api . serverId } '` } ` ;
317302 quickPick . ignoreFocusOut = true ;
318303 quickPick . buttons = [
@@ -337,32 +322,14 @@ export async function pickDocument(
337322 } ,
338323 ] ;
339324
340- const getRootItems = ( ) : Promise < void > => {
325+ const getItems = ( ) : Promise < void > => {
326+ quickPick . busy = true ;
341327 return api
342- . actionQuery ( `${ query } WHERE Type != 5 AND Type != 10` , [
343- typeSuffix ? `*.${ typeSuffix } ` : "*,'*.prj" ,
344- sys ,
345- gen ,
346- map ,
347- ] )
328+ . actionQuery ( query , [ typeSuffix ? `*.${ typeSuffix } ` : "*,'*.prj,'*.bpl,'*.dtl" , sys , gen , map ] )
348329 . then ( ( data ) => {
349- const rootitems : DocumentPickerItem [ ] = data . result . content . map ( ( i ) => createSingleSelectItem ( i ) ) ;
350- const findLastIndex = ( ) : number => {
351- let l = rootitems . length ;
352- while ( l -- ) {
353- if ( ! rootitems [ l ] . label . startsWith ( "$(" ) ) return l ;
354- }
355- return - 1 ;
356- } ;
357- rootitems . splice ( findLastIndex ( ) + 1 , 0 , ...webAppRootItems ) ;
358- return rootitems ;
359- } )
360- . then ( ( items ) => {
361- quickPick . items = items ;
330+ quickPick . items = data . result . content . map ( ( i ) => createSingleSelectItem ( i ) ) ;
362331 quickPick . selectedItems = [ ] ;
363- quickPick . value = "" ;
364332 quickPick . busy = false ;
365- quickPick . enabled = true ;
366333 } )
367334 . catch ( ( error ) => {
368335 quickPick . hide ( ) ;
@@ -371,8 +338,6 @@ export async function pickDocument(
371338 } ;
372339
373340 quickPick . onDidTriggerButton ( ( button ) => {
374- quickPick . busy = true ;
375- quickPick . enabled = false ;
376341 if ( button === vscode . QuickInputButtons . Back ) {
377342 resolve ( "" ) ; // signal "go back" to the caller
378343 quickPick . hide ( ) ;
@@ -385,108 +350,81 @@ export async function pickDocument(
385350 map = button . toggle . checked ? "1" : "0" ;
386351 }
387352 // Refresh the items list
388- getRootItems ( ) ;
353+ getItems ( ) ;
389354 } ) ;
390355 quickPick . onDidAccept ( ( ) => {
391356 quickPick . busy = true ;
392357 quickPick . enabled = false ;
393358 const item = quickPick . selectedItems [ 0 ] ;
394- if ( ! item || item . label . startsWith ( "$(" ) ) {
395- let doc = item ?. fullName ?? quickPick . value . trim ( ) ;
396- if ( ! item ) {
397- // The document name came from the value text, so validate it first
398- // Normalize the file extension case for classes and routines
399- doc = [ ".cls" , ".mac" , ".int" , ".inc" ] . includes ( doc . slice ( - 4 ) . toLowerCase ( ) )
400- ? doc . slice ( 0 , - 3 ) + doc . slice ( - 3 ) . toLowerCase ( )
401- : doc ;
402- // Expand the short form of %Library classes to the long form
403- doc =
404- doc . startsWith ( "%" ) && doc . split ( "." ) . length == 2 && doc . slice ( - 4 ) == ".cls"
405- ? `%Library.${ doc . slice ( 1 ) } `
406- : doc ;
407- if ( doc . endsWith ( ".cls" ) ) {
408- // Use StudioOpenDialog for classes so we don't expose Hidden ones
409- api
410- . actionQuery ( "SELECT Name, Type FROM %Library.RoutineMgr_StudioOpenDialog(?,1,1,1,1,0,1,,0,1)" , [ doc ] )
411- . then ( ( data ) => {
412- if ( data . result . content ?. length ) {
413- // doc is the name of a class that exists and is visible by the user
414- resolve ( doc ) ;
415- } else {
416- vscode . window . showErrorMessage (
417- `Class '${ doc . slice ( 0 , - 4 ) } ' does not exist, or is Hidden.` ,
418- "Dismiss"
419- ) ;
420- resolve ( undefined ) ;
421- }
422- } )
423- . catch ( ( ) => {
424- vscode . window . showErrorMessage (
425- `Internal Server Error encountered trying to validate class name '${ doc . slice ( 0 , - 4 ) } '.` ,
426- "Dismiss"
427- ) ;
428- resolve ( undefined ) ;
429- } )
430- . finally ( ( ) => quickPick . hide ( ) ) ;
431- } else {
432- api
433- . headDoc ( doc )
434- . then ( ( ) => resolve ( doc ) )
435- . catch ( ( error ) => {
436- vscode . window . showErrorMessage (
437- error ?. statusCode == 400
438- ? `'${ doc } ' is an invalid document name.`
439- : error ?. statusCode == 404
440- ? `Document '${ doc } ' does not exist.`
441- : `Internal Server Error encountered trying to validate document '${ doc } '.` ,
442- "Dismiss"
443- ) ;
444- resolve ( undefined ) ;
445- } )
446- . finally ( ( ) => quickPick . hide ( ) ) ;
447- }
448- } else {
449- // The document name came from an item so no validation is required
450- resolve ( doc ) ;
451- quickPick . hide ( ) ;
359+ let doc = item ?. label . slice ( item ?. label . indexOf ( " " ) + 1 ) ?? quickPick . value . trim ( ) ;
360+ if ( ! item ) {
361+ if ( typeSuffix && ! new RegExp ( `\\.${ typeSuffix } $` , "i" ) . test ( doc ) ) {
362+ // The text the user entered does not match the required type
363+ vscode . window . showErrorMessage (
364+ `Selected document '${ doc } ' does not have required extension '${ typeSuffix } '.` ,
365+ "Dismiss"
366+ ) ;
367+ resolve ( undefined ) ;
452368 }
453- } else {
454- // Replace the items with the folder's contents
455- if ( item . fullName == "" ) {
456- getRootItems ( ) ;
457- } else {
369+ // The document name came from the value text, so validate it first
370+ // Normalize the file extension case for classes and routines
371+ doc = [ ".cls" , ".mac" , ".int" , ".inc" ] . includes ( doc . slice ( - 4 ) . toLowerCase ( ) )
372+ ? doc . slice ( 0 , - 3 ) + doc . slice ( - 3 ) . toLowerCase ( )
373+ : doc ;
374+ // Expand the short form of %Library classes to the long form
375+ doc =
376+ doc . startsWith ( "%" ) && doc . split ( "." ) . length == 2 && doc . slice ( - 4 ) == ".cls"
377+ ? `%Library.${ doc . slice ( 1 ) } `
378+ : doc ;
379+ if ( doc . endsWith ( ".cls" ) ) {
380+ // Use StudioOpenDialog for classes so we don't expose Hidden ones
458381 api
459- . actionQuery ( query , [ ` ${ item . fullName } /* ${ typeSuffix ? `. ${ typeSuffix } ` : "" } ` , sys , gen , map ] )
382+ . actionQuery ( "SELECT Name, Type FROM %Library.RoutineMgr_StudioOpenDialog(?,1,1,1,1,0,1,,0,1)" , [ doc ] )
460383 . then ( ( data ) => {
461- const delim = item . fullName . includes ( "/" ) ? "/" : "." ;
462- const newItems : DocumentPickerItem [ ] = data . result . content . map ( ( i ) =>
463- createSingleSelectItem ( i , item . fullName , delim )
384+ if ( data . result . content ?. length ) {
385+ // doc is the name of a class that exists and is visible by the user
386+ resolve ( doc ) ;
387+ } else {
388+ vscode . window . showErrorMessage ( `Class '${ doc . slice ( 0 , - 4 ) } ' does not exist, or is Hidden.` , "Dismiss" ) ;
389+ resolve ( undefined ) ;
390+ }
391+ } )
392+ . catch ( ( ) => {
393+ vscode . window . showErrorMessage (
394+ `Internal Server Error encountered trying to validate class name '${ doc . slice ( 0 , - 4 ) } '.` ,
395+ "Dismiss"
464396 ) ;
465- let parentFullName =
466- delim == "/" && webApps . includes ( item . fullName )
467- ? ""
468- : item . fullName . split ( delim ) . slice ( 0 , - 1 ) . join ( delim ) ;
469- if ( parentFullName == "/" ) parentFullName = "" ;
470- quickPick . items = [ { label : ".." , fullName : parentFullName } ] . concat ( newItems ) ;
471- quickPick . value = "" ;
472- quickPick . selectedItems = [ ] ;
473- quickPick . busy = false ;
474- quickPick . enabled = true ;
397+ resolve ( undefined ) ;
475398 } )
399+ . finally ( ( ) => quickPick . hide ( ) ) ;
400+ } else {
401+ api
402+ . headDoc ( doc )
403+ . then ( ( ) => resolve ( doc ) )
476404 . catch ( ( error ) => {
477- quickPick . hide ( ) ;
478- handleError ( error , "Failed to get namespace contents." ) ;
479- } ) ;
405+ vscode . window . showErrorMessage (
406+ error ?. statusCode == 400
407+ ? `'${ doc } ' is an invalid document name.`
408+ : error ?. statusCode == 404
409+ ? `Document '${ doc } ' does not exist.`
410+ : `Internal Server Error encountered trying to validate document '${ doc } '.` ,
411+ "Dismiss"
412+ ) ;
413+ resolve ( undefined ) ;
414+ } )
415+ . finally ( ( ) => quickPick . hide ( ) ) ;
480416 }
417+ } else {
418+ // The document name came from an item so no validation is required
419+ resolve ( doc ) ;
420+ quickPick . hide ( ) ;
481421 }
482422 } ) ;
483423 quickPick . onDidHide ( ( ) => {
484424 resolve ( undefined ) ;
485425 quickPick . dispose ( ) ;
486426 } ) ;
487- quickPick . busy = true ;
488- quickPick . enabled = false ;
489427 quickPick . show ( ) ;
490- getRootItems ( ) ;
428+ getItems ( ) ;
491429 } ) ;
492430}
0 commit comments