1from PyQt5.QtCore import Qt, QEvent, pyqtSignal, pyqtSlot 2from PyQt5.QtGui import QDragEnterEvent, QContextMenuEvent, QIcon, QDropEvent 3from PyQt5.QtWidgets import QListWidget, QMenu 4 5from urh import settings 6 7 8class ListWidget(QListWidget): 9 internalMove = pyqtSignal() 10 deleteElement = pyqtSignal() 11 12 def __init__(self, parent=None): 13 super().__init__(parent) 14 self.installEventFilter(self) 15 self.active_element = 0 16 self.active_element_text = "" 17 self.context_menu_pos = None 18 19 def dropEvent(self, event: QDropEvent): 20 super().dropEvent(event) 21 if self.count() > 0: 22 item = self.itemAt(event.pos()) 23 if item is not None: 24 index = self.indexFromItem(item).row() 25 self.setCurrentRow(index) 26 else: 27 self.setCurrentRow(self.count()-1) 28 29 def dragEnterEvent(self, event: QDragEnterEvent): 30 self.active_element = self.indexAt(event.pos()).row() 31 event.accept() 32 super().dragEnterEvent(event) 33 34 def eventFilter(self, sender, event): 35 if event.type() == QEvent.ChildRemoved: 36 self.internalMove.emit() 37 elif event.type() == QEvent.KeyPress and event.key() in (Qt.Key_Delete, Qt.Key_Backspace)\ 38 and self.currentItem() is not None: 39 item = self.currentRow() 40 item_name = self.currentItem().text() 41 self.active_element_text = item_name 42 self.takeItem(item) 43 self.deleteElement.emit() 44 return False 45 46 def create_context_menu(self): 47 menu = QMenu() 48 item = self.indexAt(self.context_menu_pos).row() 49 if item < 0: 50 return menu 51 52 item_name = self.item(item).text() 53 54 # Menu Entries 55 rm_action = menu.addAction(self.tr("Delete")) 56 rm_action.setIcon(QIcon.fromTheme("list-remove")) 57 rm_action.triggered.connect(self.on_rm_action_triggered) 58 if settings.DECODING_DISABLED_PREFIX in item_name: 59 disable_function = menu.addAction(self.tr("Enable")) 60 else: 61 disable_function = menu.addAction(self.tr("Disable")) 62 63 disable_function.triggered.connect(self.on_disable_function_triggered) 64 65 menu.addSeparator() 66 clear_all_action = menu.addAction(self.tr("Clear All")) 67 clear_all_action.triggered.connect(self.on_clear_all_action_triggered) 68 return menu 69 70 def contextMenuEvent(self, event: QContextMenuEvent): 71 self.context_menu_pos = event.pos() 72 menu = self.create_context_menu() 73 menu.exec_(self.mapToGlobal(event.pos())) 74 self.context_menu_pos = None 75 76 @pyqtSlot() 77 def on_rm_action_triggered(self): 78 item = self.indexAt(self.context_menu_pos).row() 79 item_name = self.item(item).text() 80 self.active_element_text = item_name 81 self.takeItem(item) 82 self.deleteElement.emit() 83 84 @pyqtSlot() 85 def on_disable_function_triggered(self): 86 item = self.indexAt(self.context_menu_pos).row() 87 item_name = self.item(item).text() 88 if settings.DECODING_DISABLED_PREFIX in item_name: 89 item_name = item_name[len(settings.DECODING_DISABLED_PREFIX):] 90 else: 91 item_name = settings.DECODING_DISABLED_PREFIX + item_name 92 self.takeItem(item) 93 self.insertItem(item, item_name) 94 self.internalMove.emit() 95 96 @pyqtSlot() 97 def on_clear_all_action_triggered(self): 98 while self.count() > 0: 99 self.takeItem(0) 100 self.deleteElement.emit() 101