src/eric7/EricWidgets/EricListSelectionDialog.py

branch
eric7
changeset 10215
d476667171a1
parent 9768
e2b622afb5ff
child 10439
21c28b0f9e41
--- a/src/eric7/EricWidgets/EricListSelectionDialog.py	Mon Sep 25 12:09:23 2023 +0200
+++ b/src/eric7/EricWidgets/EricListSelectionDialog.py	Tue Sep 26 18:26:21 2023 +0200
@@ -31,13 +31,15 @@
         message="",
         checkBoxSelection=False,
         doubleClickOk=False,
+        emptySelectionOk=False,
+        showSelectAll=False,
         parent=None,
     ):
         """
         Constructor
 
         @param entries list of entries to select from
-        @type list of str
+        @type list of str or list of tuple of (str, Any)
         @param selectionMode selection mode for the list
         @type QAbstractItemView.SelectionMode
         @param title title of the dialog
@@ -50,6 +52,10 @@
         @param doubleClickOk flag indicating to accept the dialog upon a
             double click of an item (single selection only)
         @type bool
+        @param emptySelectionOk flag indicating that an empty selection is allowed
+        @type bool
+        @param showSelectAll flag indicating to show a 'Select All' button
+        @type bool
         @param parent reference to the parent widget
         @type QWidget
         """
@@ -63,22 +69,39 @@
 
         self.__checkCount = 0
         self.__isCheckBoxSelection = checkBoxSelection
-        if self.__isCheckBoxSelection:
-            self.selectionList.setSelectionMode(
-                QAbstractItemView.SelectionMode.NoSelection
-            )
-            for entry in entries:
+        self.__doubleClickOk = doubleClickOk
+        self.__emptySelectionOk = emptySelectionOk
+
+        self.selectionList.setSelectionMode(
+            QAbstractItemView.SelectionMode.NoSelection
+            if self.__isCheckBoxSelection
+            else selectionMode
+        )
+
+        for entry in entries:
+            if isinstance(entry, tuple):
+                itm = QListWidgetItem(entry[0])
+                itm.setData(Qt.ItemDataRole.UserRole, entry[1])
+            else:
                 itm = QListWidgetItem(entry)
+            if self.__isCheckBoxSelection:
                 itm.setFlags(
                     Qt.ItemFlag.ItemIsUserCheckable | Qt.ItemFlag.ItemIsEnabled
                 )
                 itm.setCheckState(Qt.CheckState.Unchecked)
-                self.selectionList.addItem(itm)
-        else:
-            self.selectionList.setSelectionMode(selectionMode)
-            self.selectionList.addItems(entries)
+            self.selectionList.addItem(itm)
 
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(False)
+        if showSelectAll:
+            self.buttonBox.addButton(
+                self.tr("Deselect All"), QDialogButtonBox.ButtonRole.ActionRole
+            ).clicked.connect(lambda: self.__selectAll(False))
+            self.buttonBox.addButton(
+                self.tr("Select All"), QDialogButtonBox.ButtonRole.ActionRole
+            ).clicked.connect(lambda: self.__selectAll(True))
+
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
+            emptySelectionOk
+        )
 
     @pyqtSlot()
     def on_selectionList_itemSelectionChanged(self):
@@ -87,9 +110,10 @@
         """
         if not self.__isCheckBoxSelection:
             self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
-                len(self.selectionList.selectedItems()) > 0
+                len(self.selectionList.selectedItems()) > 0 or self.__emptySelectionOk
             )
 
+    @pyqtSlot(QListWidgetItem)
     def on_selectionList_itemChanged(self, itm):
         """
         Private slot handling a change of an item.
@@ -103,7 +127,7 @@
             elif self.__checkCount > 0:
                 self.__checkCount -= 1
             self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
-                self.__checkCount > 0
+                self.__checkCount > 0 or self.__emptySelectionOk
             )
 
     @pyqtSlot(QListWidgetItem)
@@ -118,23 +142,66 @@
             not self.__isCheckBoxSelection
             and self.selectionList.selectionMode()
             == QAbstractItemView.SelectionMode.SingleSelection
+            and self.__doubleClickOk
         ):
             self.accept()
 
+    def __selectAll(self, state):
+        """
+        Private method to select or deselect all entries.
+
+        @param state flag indicating the desired selection state
+        @type bool
+        """
+        for row in range(self.selectionList.count()):
+            item = self.selectionList.item(row)
+            if self.__isCheckBoxSelection:
+                if state:
+                    item.setCheckState(Qt.CheckState.Checked)
+                else:
+                    item.setCheckState(Qt.CheckState.Unchecked)
+            else:
+                item.setSelected(state)
+
+    def setSelection(self, selection):
+        """
+        Public method to preselect a list of entries.
+
+        @param selection list of selected entries
+        @type list of str
+        """
+        for name in selection:
+            itemList = self.selectionList.findItems(
+                name, Qt.MatchFlag.MatchCaseSensitive | Qt.MatchFlag.MatchStartsWith
+            )
+            if itemList:
+                if self.__isCheckBoxSelection:
+                    itemList[0].setCheckState(Qt.CheckState.Checked)
+                else:
+                    itemList[0].setSelected(True)
+
     def getSelection(self):
         """
         Public method to retrieve the selected items.
 
         @return selected entries
-        @rtype list of str
+        @rtype list of str or list of tuple of (str, Any)
         """
         entries = []
         if self.__isCheckBoxSelection:
             for row in range(self.selectionList.count()):
                 item = self.selectionList.item(row)
                 if item.checkState() == Qt.CheckState.Checked:
-                    entries.append(item.text())
+                    data = item.data(Qt.ItemDataRole.UserRole)
+                    if data is None:
+                        entries.append(item.text())
+                    else:
+                        entries.append((item.text(), data))
         else:
             for item in self.selectionList.selectedItems():
-                entries.append(item.text())
+                data = item.data(Qt.ItemDataRole.UserRole)
+                if data is None:
+                    entries.append(item.text())
+                else:
+                    entries.append((item.text(), data))
         return entries

eric ide

mercurial