@@ -30,9 +30,8 @@ import javax.swing.filechooser.FileNameExtensionFilter
3030import javax.swing.tree.*
3131
3232class PrettifySettingsComponent {
33- private val mainPanel: JPanel
3433 private val rootNode = DefaultMutableTreeNode (" Mappings" )
35- private val treeModel = DefaultTreeModel (rootNode)
34+ private val treeModel = MappingTreeModel (rootNode)
3635 private val mappingsTree = Tree (treeModel).apply {
3736 isRootVisible = false
3837 showsRootHandles = true
@@ -53,8 +52,7 @@ class PrettifySettingsComponent {
5352 }
5453 private val json = Json { prettyPrint = true }
5554 private var resetButton: AnAction ? = null
56-
57- init {
55+ private val mainPanel = JPanel (BorderLayout ()).apply {
5856 val toolbarDecorator = ToolbarDecorator .createDecorator(mappingsTree)
5957 .setAddAction { addNewMapping() }
6058 .setRemoveAction { removeSelectedMapping() }
@@ -81,9 +79,14 @@ class PrettifySettingsComponent {
8179 }
8280 }.also { resetButton = it })
8381
84- mainPanel = JPanel (BorderLayout ()).apply {
85- add(toolbarDecorator.createPanel(), BorderLayout .CENTER )
86- border = IdeBorderFactory .createTitledBorder(" Symbol Mappings" , false )
82+ add(toolbarDecorator.createPanel(), BorderLayout .CENTER )
83+ border = IdeBorderFactory .createTitledBorder(" Symbol Mappings" , false )
84+ }
85+
86+ private inner class MappingTreeModel (root : TreeNode ) : DefaultTreeModel(root) {
87+ override fun isLeaf (node : Any? ): Boolean {
88+ if (node !is DefaultMutableTreeNode ) return true
89+ return node.userObject is MappingEntry
8790 }
8891 }
8992
@@ -116,29 +119,32 @@ class PrettifySettingsComponent {
116119
117120 private fun addMappingToTree (mapping : MappingEntry ) {
118121 // Find or create category node
119- var categoryNode = findOrCreateCategoryNode(mapping.category)
122+ val categoryNode = findOrCreateCategoryNode(mapping.category)
120123 val mappingNode = DefaultMutableTreeNode (mapping)
121124 treeModel.insertNodeInto(mappingNode, categoryNode, categoryNode.childCount)
122125 expandAllNodes()
123126 }
124127
125128 private fun findOrCreateCategoryNode (category : String ): DefaultMutableTreeNode {
129+ // Search for existing category node
126130 for (i in 0 until rootNode.childCount) {
127131 val node = rootNode.getChildAt(i) as DefaultMutableTreeNode
128132 if (node.userObject.toString() == category) {
129133 return node
130134 }
131135 }
132- val newNode = DefaultMutableTreeNode (category)
133- treeModel.insertNodeInto(newNode, rootNode, rootNode.childCount)
134- return newNode
136+
137+ // Create new category node if not found
138+ val categoryNode = DefaultMutableTreeNode (category)
139+ treeModel.insertNodeInto(categoryNode, rootNode, rootNode.childCount)
140+ return categoryNode
135141 }
136142
137143 private fun removeSelectedMapping () {
138- val node = mappingsTree.lastSelectedPathComponent as ? DefaultMutableTreeNode ? : return
139- if (node .userObject is MappingEntry ) {
140- treeModel.removeNodeFromParent(node)
141- }
144+ val selectedNode = mappingsTree.selectionPath?.lastPathComponent as ? DefaultMutableTreeNode ? : return
145+ if (selectedNode .userObject ! is MappingEntry ) return
146+
147+ treeModel.removeNodeFromParent(selectedNode)
142148 }
143149
144150 private class MappingTransferable (private val mapping : MappingEntry ) : Transferable {
@@ -157,6 +163,13 @@ class PrettifySettingsComponent {
157163 private inner class MappingTransferHandler (private val tree : JTree ) : TransferHandler() {
158164 override fun getSourceActions (c : JComponent ): Int = TransferHandler .MOVE
159165
166+ override fun createTransferable (component : JComponent ): Transferable ? {
167+ val node = tree.selectionPath?.lastPathComponent as ? DefaultMutableTreeNode ? : return null
168+ if (node.userObject !is MappingEntry ) return null
169+
170+ return MappingTransferable (node.userObject as MappingEntry )
171+ }
172+
160173 override fun canImport (support : TransferSupport ): Boolean {
161174 if (! support.isDrop) return false
162175 support.setShowDropLocation(true )
@@ -166,15 +179,8 @@ class PrettifySettingsComponent {
166179 val targetPath = dropLocation.path ? : return false
167180 val targetNode = targetPath.lastPathComponent as DefaultMutableTreeNode
168181
169- // Allow dropping only on root or category nodes
170- return targetNode == rootNode || targetNode.parent == rootNode
171- }
172-
173- override fun createTransferable (component : JComponent ): Transferable ? {
174- val node = tree.selectionPath?.lastPathComponent as ? DefaultMutableTreeNode ? : return null
175- if (node.userObject !is MappingEntry ) return null
176-
177- return MappingTransferable (node.userObject as MappingEntry )
182+ // Allow dropping only on category nodes (not root)
183+ return targetNode.parent == rootNode
178184 }
179185
180186 override fun importData (support : TransferSupport ): Boolean {
@@ -183,24 +189,33 @@ class PrettifySettingsComponent {
183189 val dropLocation = support.getDropLocation() as ? JTree .DropLocation ? : return false
184190 val targetPath = dropLocation.path ? : return false
185191 val targetNode = targetPath.lastPathComponent as DefaultMutableTreeNode
192+ val childIndex = dropLocation.childIndex
186193
187194 val draggedNode = tree.selectionPath?.lastPathComponent as ? DefaultMutableTreeNode ? : return false
188195 val draggedMapping = draggedNode.userObject as ? MappingEntry ? : return false
189196
190- // Determine target category
191- val targetCategory = when {
192- targetNode == rootNode -> draggedMapping.category
193- targetNode.parent == rootNode -> targetNode.userObject.toString()
194- else -> return false
195- }
196-
197- treeModel.removeNodeFromParent(draggedNode)
197+ // Target category is always the category we're dropping on
198+ val targetCategory = targetNode.userObject.toString()
198199
199200 // Create new mapping with target category
200201 val newMapping = draggedMapping.copy(category = targetCategory)
201202
202- // Add to target category
203- addMappingToTree(newMapping)
203+ // Calculate insert index
204+ val insertIndex = if (childIndex >= 0 ) childIndex else targetNode.childCount
205+
206+ // Create and insert the new node
207+ val newMappingNode = DefaultMutableTreeNode (newMapping)
208+
209+ // First insert the new node
210+ treeModel.insertNodeInto(newMappingNode, targetNode, insertIndex)
211+
212+ // Then remove the old node
213+ treeModel.removeNodeFromParent(draggedNode)
214+
215+ // Make sure the new node is visible
216+ val newPath = TreePath (newMappingNode.path)
217+ tree.scrollPathToVisible(newPath)
218+ tree.selectionPath = newPath
204219
205220 expandAllNodes()
206221 return true
0 commit comments