# Drag and drop from Tree View to List

**URL:** <https://forum.inductiveautomation.com/t/drag-and-drop-from-tree-view-to-list/65479>\
**Category:** Ignition\
**Tags:** vision\
**Created:** [October 20, 2022, 5:41pm UTC](https://forum.inductiveautomation.com/t/drag-and-drop-from-tree-view-to-list/65479 "2022-10-20T17:41:51Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [October 24, 2022, 8:06pm UTC](https://forum.inductiveautomation.com/t/drag-and-drop-from-tree-view-to-list/65479/3 "2022-10-24T20:06:12Z")

</div>

Okay a little bit of work and understanding, and taking @paul-griffith's tip, and I was able to accomplish this.

This will do multi or single selection, and will handle dragging folders. The drop listener also filters out duplicate paths.

You'll want to add this code to a custom function on your Tree View component that you call from the `InternalFrameActivated` event on the window.

```auto
def addDragSource(self):
	from java.awt.dnd import DragSourceAdapter, DragGestureListener, DragSource, DnDConstants
	from java.awt.datatransfer import DataFlavor, Transferable
	
	#A custom transferable which allows a List to be transfered
	#via Drag and Drop.
	class customTransferable(Transferable):
		_transferData = None
		def __init__ (self,data):
			self._transferData = data
		
		def getTransferData(self,flavor):
			return self._transferData
		
		def getTransferDataFlavors(self):
			return [DataFlavor(list,'List')]
		
		def isDataFlavorSupported(self,flavor):
			if not DataFlavor(list,'List'):
				return False
			return True
	
	#Custom listener to build the transferable when a drag gesture is recognized.
	#Takes in a component (assumes PMITreeView)		
	class customDragGestureListener(DragGestureListener):
		_comp = None
		_selectedPaths = []
		def __init__ (self,comp):
			self._comp = comp
			
		def dragGestureRecognized(self,e):
			dataFlavor = DataFlavor(list,'List')
			
			self.addPaths(self._comp.selectedPaths)
			
			transferable = customTransferable(self._selectedPaths)
			e.startDrag(DragSource.DefaultCopyDrop,transferable)
	
		def addPaths(self,paths):
			for path in paths:
				if not self._comp.separationCharacter in path:
					#this is a root folder, add all sub paths of this folder
					subPaths = [subPath for subPath in self._comp.data.getColumnAsList(0) if path in subPath]
					self.addPaths(subPaths) 
				#if path is found in first columnn then it is a folder.
				#only add paths that aren't in 
				elif path in self._comp.data.getColumnAsList(0):
					#build subPaths list
					subPaths = [row['path'] + '/{}'.format(row['text'])	for row in system.dataset.toPyDataSet(self._comp.data) if row['path'] == path]
					self.addPaths(subPaths)
				elif not path in self._selectedPaths:
					self._selectedPaths.append(path)
				
	
	ds = DragSource.getDefaultDragSource()
	ds.createDefaultDragGestureRecognizer(self, DnDConstants.ACTION_COPY, customDragGestureListener(self))

```

Then add this to the `List` component. You will also need to call this from `InternalFrameActivated`

```python
def addDropTarget(self):
	from java.awt.dnd import DropTargetAdapter, DropTarget
	from java.awt.datatransfer import DataFlavor
	class customDropListener(DropTargetAdapter):
		_comp = None
		def __init__ (self,comp):
			self._comp = comp
		def drop(self,e):
			e.acceptDrop(e.getDropAction())
			self._comp.addData(e.getTransferable().getTransferData(DataFlavor(list,'List')))
			e.dropComplete(True)
			
	DropTarget(self,customDropListener(self))

```

I also used a custom `addData` function on the `List` here for the filtering.

```python
def addData(self,data):
	paths = self.data.getColumnAsList(0)
	
	if not paths and not self.data.columnCount:
		#this takes care of an empty dataset
		self.data = system.dataset.addColumn(self.data,[],'Paths',str)
	newRows = [[path] for path in data if not path in paths]
	self.data = system.dataset.addRows(self.data,newRows)

```

---

_[View the full topic](https://forum.inductiveautomation.com/t/drag-and-drop-from-tree-view-to-list/65479)._
