Last active
February 9, 2023 13:38
-
-
Save Bouni/c5f035df354eba66c5347e3a84886863 to your computer and use it in GitHub Desktop.
NaturalSortedListCtrl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""ListCtrl with Natural sorting capability""" | |
import re | |
import wx | |
import wx.lib.mixins.listctrl as listmix | |
class NaturalSortedListCtrl(wx.ListCtrl, listmix.ColumnSorterMixin): | |
"""ListCtrl with Natural sorting capability""" | |
def __init__(self, parent, columns): | |
wx.ListCtrl.__init__(self, parent, style=wx.LC_REPORT) | |
self.itemDataMap = {} # pylint: disable=invalid-name | |
for index, col in enumerate(columns): | |
self.InsertColumn(index, col) | |
listmix.ColumnSorterMixin.__init__(self, numColumns=0) | |
def AddData(self, data: dict): | |
"""Add or Update one or multiple items""" | |
for item in data: | |
# Update existing entry | |
if item in self.itemDataMap: | |
self.itemDataMap[item] = data[item] | |
index = self.FindItem(0, data[item][0]) | |
self.SetItemData(index, item) | |
for n, value in enumerate(data[item]): | |
self.SetItem(index, n, value) | |
self.SetColumnWidth(n, wx.LIST_AUTOSIZE) | |
# Insert new entry | |
else: | |
self.itemDataMap[item] = data[item] | |
index = self.InsertItem(0, data[item][0]) | |
self.SetItemData(index, item) | |
for n, value in enumerate(data[item]): | |
self.SetItem(index, n, value) | |
self.SetColumnWidth(n, wx.LIST_AUTOSIZE) | |
self.SetColumnCount(len(self.itemDataMap)) | |
def DeleteData(self, data: list): | |
"""Delete one or multiple items from the list by their id""" | |
for number in data: | |
item = self.itemDataMap[number] | |
self.DeleteItem(self.FindItem(0, item[0])) | |
del self.itemDataMap[number] | |
self.SetColumnCount(len(self.itemDataMap)) | |
def GetListCtrl(self): | |
"""Required by ColumnSorterMixin""" | |
return self | |
def GetColumnSorter(self): | |
"""Returns a callable object to be used for comparing column values when sorting.""" | |
return self.NaturalColumnSorter | |
def NaturalColumnSorter(self, key1, key2): | |
"""Compare two values and return 0 if equal, 1 or -1 if sort up or down""" | |
ascending = self._colSortFlag[self._col] | |
a = self.itemDataMap[key1][self._col] | |
b = self.itemDataMap[key2][self._col] | |
if a == b: | |
return 0 | |
def convert(text): | |
return int(text) if text.isdigit() else text.lower() | |
def alphanum_key(key): | |
return [convert(c) for c in re.split("([0-9]+)", str(key))] | |
natorder = sorted([a, b], key=alphanum_key, reverse=bool(ascending)) | |
return -1 if natorder.index(a) == 0 else 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment