Skip to content

Commit

Permalink
IDEA-352824 Support Multiple Projects for Maven and Gradle
Browse files Browse the repository at this point in the history
NewWorkspaceDialog refactored

GitOrigin-RevId: 9851f0456faf306746b99eaf3cf552e9cc3c877c
  • Loading branch information
dmitry-avdeev authored and intellij-monorepo-bot committed May 21, 2024
1 parent f35e27a commit 640c0ac
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 19 deletions.
2 changes: 1 addition & 1 deletion platform/ide-core/api-dump-unreviewed.txt
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ com.intellij.ide.workspace.ImportedProjectSettings
- a:getWorkspace():com.intellij.openapi.project.Project
*:com.intellij.ide.workspace.SubprojectHandler
- *sf:Companion:com.intellij.ide.workspace.SubprojectHandler$Companion
- a:canImportFromFile(com.intellij.openapi.project.Project,com.intellij.openapi.vfs.VirtualFile):Z
- a:canImportFromFile(com.intellij.openapi.vfs.VirtualFile):Z
- a:getSubprojectIcon():javax.swing.Icon
- a:getSubprojects(com.intellij.openapi.project.Project):java.util.List
- a:importFromProject(com.intellij.openapi.project.Project,Z):com.intellij.ide.workspace.ImportedProjectSettings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface SubprojectHandler {
}

fun getSubprojects(project: Project): List<Subproject>
fun canImportFromFile(project: Project, file: VirtualFile): Boolean
fun canImportFromFile(file: VirtualFile): Boolean
fun removeSubprojects(subprojects: List<Subproject>)
fun importFromProject(project: Project, newWorkspace: Boolean): ImportedProjectSettings?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ internal open class CreateWorkspaceAction: BaseWorkspaceAction(false) {

@RequiresEdt
internal fun createWorkspace(project: Project): Boolean {
val dialog = NewWorkspaceDialog(project, listOf(requireNotNull(project.basePath)))
val subprojects = SubprojectHandler.getAllSubprojects(project).associateBy { it.projectPath }
val dialog = NewWorkspaceDialog(project, subprojects.values)
if (!dialog.showAndGet()) return false

val settings = importSettingsFromProject(project, true)
Expand All @@ -52,7 +53,7 @@ internal fun createWorkspace(project: Project): Boolean {
for (importedSetting in settings) {
importedSetting.applyTo(workspace)
}
dialog.selectedPaths.forEach { linkToWorkspace(workspace, it) }
dialog.projectPaths.forEach { linkToWorkspace(workspace, it) }
}
}
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,18 @@ internal class ManageWorkspaceAction: BaseWorkspaceAction(true) {
override fun actionPerformed(e: AnActionEvent) {
val project = requireNotNull(e.project)
val subprojects = SubprojectHandler.getAllSubprojects(project)
val subprojectPaths = subprojects.map { it.projectPath }
val dialog = NewWorkspaceDialog(project, subprojectPaths)
val dialog = NewWorkspaceDialog(project, subprojects)
if (!dialog.showAndGet()) return

if (dialog.projectName != project.name) {
(project as ProjectEx).setProjectName(dialog.projectName)
ProjectView.getInstance(project).currentProjectViewPane?.updateFromRoot(true)
}
val set = dialog.selectedPaths.toSet()
val set = dialog.projectPaths.toSet()
val removed = subprojects.filter { !set.contains(it.projectPath) }
removeSubprojects(removed)

val added = dialog.selectedPaths.filter { !subprojectPaths.contains(it) }
val added = dialog.projectPaths.filter { !subprojects.any { subproject -> subproject.projectPath == it } }
addToWorkspace(project, added)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.project.guessProjectDir
import com.intellij.openapi.ui.DialogWrapper
import com.intellij.openapi.ui.TextFieldWithBrowseButton
import com.intellij.openapi.util.NlsSafe
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.ui.CollectionListModel
import com.intellij.ui.ColoredListCellRenderer
import com.intellij.ui.IdeBorderFactory
import com.intellij.ui.ToolbarDecorator
import com.intellij.ui.components.JBList
Expand All @@ -25,16 +27,20 @@ import java.io.File
import java.nio.file.Path
import java.nio.file.Paths
import javax.swing.Action
import javax.swing.Icon
import javax.swing.JComponent
import javax.swing.JList

internal class NewWorkspaceDialog(
val project: Project,
initialProjects: List<String>
initialProjects: Collection<Subproject>
) : DialogWrapper(project) {
private lateinit var nameField: JBTextField
private lateinit var locationField: TextFieldWithBrowseButton
private val listModel = CollectionListModel(initialProjects)
private val projectList = JBList(listModel)
private val listModel = CollectionListModel(initialProjects.map { Item(it.projectPath, it.handler.subprojectIcon) })
private val projectList = JBList(listModel).apply {
cellRenderer = Renderer()
}

val projectName: String get() = nameField.text
val location: Path get() = Paths.get(locationField.text)
Expand All @@ -51,8 +57,8 @@ internal class NewWorkspaceDialog(
init()
}

val selectedPaths: List<String>
get() = listModel.items
val projectPaths: List<String>
get() = listModel.items.map { it.path }

override fun createCenterPanel(): JComponent {
val suggestLocation = RecentProjectsManager.getInstance().suggestNewProjectLocation()
Expand Down Expand Up @@ -110,9 +116,19 @@ internal class NewWorkspaceDialog(
val files = browseForProjects(project)
val allItems = listModel.items
for (file in files) {
val path = file.path
if (allItems.contains(path)) continue
listModel.add(path)
if (allItems.any { it.path == file.path }) continue
val handler = getHandlers(file).firstOrNull() ?: continue
listModel.add(Item(file.path, handler.subprojectIcon))
}
}

private data class Item(@NlsSafe val path: String, val icon: Icon?)

private class Renderer: ColoredListCellRenderer<Item>() {
override fun customizeCellRenderer(list: JList<out Item>, value: Item?, index: Int, selected: Boolean, hasFocus: Boolean) {
value ?: return
icon = value.icon
append(value.path)
}
}
}
Expand All @@ -121,7 +137,7 @@ private fun browseForProjects(project: Project): Array<out VirtualFile> {
val handlers = SubprojectHandler.EP_NAME.extensionList
val descriptor = FileChooserDescriptor(true, true, false, false, false, true)
descriptor.title = LangBundle.message("chooser.title.select.file.or.directory.to.import")
descriptor.withFileFilter { file -> handlers.any { it.canImportFromFile(project, file) } }
descriptor.withFileFilter { file -> handlers.any { it.canImportFromFile(file) } }
return FileChooser.chooseFiles(descriptor, project, project.guessProjectDir()?.parent)
}

Expand Down
4 changes: 4 additions & 0 deletions platform/lang-impl/src/com/intellij/ide/workspace/util.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.vfs.VirtualFile
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

Expand All @@ -15,6 +16,9 @@ internal class MyCoroutineScopeService(val scope: CoroutineScope)

internal fun getCoroutineScope(workspace: Project) = workspace.service<MyCoroutineScopeService>().scope

internal fun getHandlers(file: VirtualFile): List<SubprojectHandler> =
SubprojectHandler.EP_NAME.extensionList.filter { it.canImportFromFile(file) }

internal fun addToWorkspace(project: Project, projectPaths: List<String>) {
getCoroutineScope(project).launch {
projectPaths.forEach { s ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import javax.swing.Icon

internal class GradleSubprojectHandler : ExternalSubprojectHandler(GradleConstants.SYSTEM_ID) {

override fun canImportFromFile(project: Project, file: VirtualFile): Boolean {
override fun canImportFromFile(file: VirtualFile): Boolean {
return canOpenGradleProject(file)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ internal class MavenSubprojectHandler : SubprojectHandler {
.map { MavenSubproject(project, it, this) }
}

override fun canImportFromFile(project: Project, file: VirtualFile): Boolean {
override fun canImportFromFile(file: VirtualFile): Boolean {
return MavenOpenProjectProvider().canOpenProject(file)
}

Expand Down

0 comments on commit 640c0ac

Please sign in to comment.