class Utilities { func withQuickFolder( action : Action, folder : File ) = action.split().apply { onDemand( ::buildFolderMenu.curry( folder ) ) } // A split menu. Click to open the folder, Pull down to choose from the files/subfolders. func quickFolder( label : String, folder : File ) = SplitMenu( label, ::openFolder.curry(folder) ) .onDemand( ::buildFolderMenu.curry( folder ) ) // Creates Features for each of the folder's files/subfolders. The features open the file/subfolder in a new tab. func buildFolderMenu( folder : File ) = mapFilesToOpenFeatures( folder.filesAndFolders() ) func buildFolderMenuFromContext( context : Context ) = mapFilesToOpenFeatures( (context.value as File).filesAndFolders() ) func openFolder( folder : File ) { openContext( Context( Context.FOLDER, folder ) ) } func mapFilesToOpenFeatures( files : List ) : List { val result = listOf() for ( file in files ) { result.add( Action( file.nameOrSlash(), HelperFunctions::openFile.curry( file ) ) ) } return result } /** * Creates a StringProperty asking for file extensions. * Convert the value to a list using `extensionsStringToList`. */ func extensionsProperty( defaultValue : String ) = stringProperty( "File Extensions", defaultValue ) .rows( 1 ).columns( 0 ) .description( """File extensions separated by whitespace. The word NONE will match files without an extensions. Leave blank to search all files.""" ) /** * Takes the value from `str` and converts it to a List. * An empty list implies search all files. * The special value "NONE" is converted to "". */ func extensionsStringToList( str : String ) : List { if ( str.isEmpty() ) { return listOf() } else { val result = str.split( "\\s+" ).toList() if (result.contains("NONE")) { result.remove( "NONE" ) result.add("") } return result } } }