package foldertree /** * A FolderTreeBehaviour, specific to gradle based projects, which can have many "src" folders. * as well as a "dist" folder. * * e.g. for the `featureful` project, we end up with the following choices : * "featureful" * "src/dist" * "src/main/kotlin" * "src/main/resources" * * The empty package-only folders are skipped over, so for example, "src/main/kotlin" lists the folder : * "src/main/kotlin/uk/co/nickthecoder/featureful" * */ class ProjectTreeBehaviour( form : ProjectTreeForm ) : FolderTreeBehaviour( form ) { constructor() : this( ProjectTreeForm() ) val folderActions = listOf() init { title = "Project" iconName = "project_folder" val projectFolder = form.folder.value val action = Action( projectFolder.name, this:>changeFolder.curry(projectFolder) ) folderActions.add( action ) val srcFolder = File( projectFolder, "src" ) if (srcFolder.isDirectory()) { scanSrc( projectFolder, 4 ) } } override meth toolbar() : List { val sup : List = super.toolbar() as List sup.add( sup.size() - 1, MenuFeature( "Select", folderActions ) ) return sup } meth scanSrc( folder : File, depth : int ) { if (depth == 0) return for ( dir in folders( folder ) ) { if ( dir.name == "src" ) { addSrc( dir ) } scanSrc( dir, depth-1 ) } } meth addSrc( src : File ) { for ( mainOrTest in src.folders() ) { if ( mainOrTest.name == "dist" ) { val placeName = mainOrTest.path.substring( form.folder.value.path.length() ) val action = Action( placeName, this:>changeFolder.curry(mainOrTest) ) folderActions.add( action ) } else { for (sub in mainOrTest.folders()) { val placeName = sub.path.substring( form.folder.value.path.length() ) var actual = sub var filesAndFolders = actual.filesAndFolders() while (filesAndFolders.size() == 1 && filesAndFolders[0].isDirectory()) { actual = filesAndFolders[0] filesAndFolders = actual.filesAndFolders() } val action = Action( placeName, this:>changeFolder.curry(actual) ) folderActions.add( action ) } } } } meth changeFolder( folder : File ) { form.folder.value = folder refresh() } } /** * We need a specific subclass of FolderTreeForm, so that `runner()` returns a ProjectTreeBehaviour, * and not a FolderTreeBehaviour. */ class ProjectTreeForm( folder : File ) : FolderTreeForm( "Project Folder", folder ) { constructor() : this( projectFolder() ) override meth runner() = ProjectTreeBehaviour( this ) }