Skip to content

Commit 9633847

Browse files
committed
Merge branch 'development' of https://github.com/danielhrisca/asammdf into development
2 parents 74f3606 + 2930ab4 commit 9633847

File tree

3 files changed

+147
-3
lines changed

3 files changed

+147
-3
lines changed

src/asammdf/gui/ui/file_widget.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,16 @@ def setupUi(self, file_widget):
6969

7070
self.channels_layout.addWidget(self.channel_view)
7171

72+
self.channels_search_name = QLineEdit(self.verticalLayoutWidget)
73+
self.channels_search_name.setObjectName(u"channels_search_name")
74+
self.channels_search_name.setClearButtonEnabled(True)
75+
self.channels_layout.addWidget(self.channels_search_name)
76+
77+
self.channels_search_bus = QLineEdit(self.verticalLayoutWidget)
78+
self.channels_search_bus.setObjectName(u"channels_search_bus")
79+
self.channels_search_bus.setClearButtonEnabled(True)
80+
self.channels_layout.addWidget(self.channels_search_bus)
81+
7282
self.channels_tree = TreeWidget(self.verticalLayoutWidget)
7383
self.channels_tree.setObjectName(u"channels_tree")
7484

@@ -180,6 +190,16 @@ def setupUi(self, file_widget):
180190

181191
self.verticalLayout_2.addWidget(self.filter_view)
182192

193+
self.filter_search_name = QLineEdit(self.modify)
194+
self.filter_search_name.setObjectName(u"filter_search_name")
195+
self.filter_search_name.setClearButtonEnabled(True)
196+
self.verticalLayout_2.addWidget(self.filter_search_name)
197+
198+
self.filter_search_bus = QLineEdit(self.modify)
199+
self.filter_search_bus.setObjectName(u"filter_search_bus")
200+
self.filter_search_bus.setClearButtonEnabled(True)
201+
self.verticalLayout_2.addWidget(self.filter_search_bus)
202+
183203
self.filter_tree = TreeWidget(self.modify)
184204
self.filter_tree.setObjectName(u"filter_tree")
185205

@@ -1086,6 +1106,8 @@ def retranslateUi(self, file_widget):
10861106
self.channel_view.setItemText(0, QCoreApplication.translate("file_widget", u"Natural sort", None))
10871107
self.channel_view.setItemText(1, QCoreApplication.translate("file_widget", u"Internal file structure", None))
10881108
self.channel_view.setItemText(2, QCoreApplication.translate("file_widget", u"Selected channels only", None))
1109+
self.channels_search_name.setPlaceholderText(QCoreApplication.translate("file_widget", u"channel pattern", None))
1110+
self.channels_search_bus.setPlaceholderText(QCoreApplication.translate("file_widget", u"source pattern", None))
10891111

10901112
___qtreewidgetitem = self.channels_tree.headerItem()
10911113
___qtreewidgetitem.setText(0, QCoreApplication.translate("file_widget", u"Channels", None));
@@ -1128,6 +1150,8 @@ def retranslateUi(self, file_widget):
11281150
self.filter_view.setItemText(0, QCoreApplication.translate("file_widget", u"Natural sort", None))
11291151
self.filter_view.setItemText(1, QCoreApplication.translate("file_widget", u"Internal file structure", None))
11301152
self.filter_view.setItemText(2, QCoreApplication.translate("file_widget", u"Selected channels only", None))
1153+
self.filter_search_name.setPlaceholderText(QCoreApplication.translate("file_widget", u"channel pattern", None))
1154+
self.filter_search_bus.setPlaceholderText(QCoreApplication.translate("file_widget", u"source pattern", None))
11311155

11321156
___qtreewidgetitem1 = self.filter_tree.headerItem()
11331157
___qtreewidgetitem1.setText(0, QCoreApplication.translate("file_widget", u"Channels", None));

src/asammdf/gui/ui/file_widget.ui

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,26 @@
108108
</item>
109109
</widget>
110110
</item>
111+
<item>
112+
<widget class="QLineEdit" name="channels_search_name">
113+
<property name="placeholderText">
114+
<string>channel pattern</string>
115+
</property>
116+
<property name="clearButtonEnabled">
117+
<bool>true</bool>
118+
</property>
119+
</widget>
120+
</item>
121+
<item>
122+
<widget class="QLineEdit" name="channels_search_bus">
123+
<property name="placeholderText">
124+
<string>source pattern</string>
125+
</property>
126+
<property name="clearButtonEnabled">
127+
<bool>true</bool>
128+
</property>
129+
</widget>
130+
</item>
111131
<item>
112132
<widget class="TreeWidget" name="channels_tree">
113133
<property name="toolTip">
@@ -338,6 +358,26 @@
338358
</item>
339359
</widget>
340360
</item>
361+
<item>
362+
<widget class="QLineEdit" name="filter_search_name">
363+
<property name="placeholderText">
364+
<string>channel pattern</string>
365+
</property>
366+
<property name="clearButtonEnabled">
367+
<bool>true</bool>
368+
</property>
369+
</widget>
370+
</item>
371+
<item>
372+
<widget class="QLineEdit" name="filter_search_bus">
373+
<property name="placeholderText">
374+
<string>source pattern</string>
375+
</property>
376+
<property name="clearButtonEnabled">
377+
<bool>true</bool>
378+
</property>
379+
</widget>
380+
</item>
341381
<item>
342382
<widget class="TreeWidget" name="filter_tree">
343383
<property name="toolTip">

src/asammdf/gui/widgets/file.py

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,24 @@ def __init__(
309309
self.mdi_area.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded)
310310
self.splitter.addWidget(self.mdi_area)
311311

312+
self.channel_search_update_timer = QtCore.QTimer(self)
313+
self.channel_search_update_timer.setSingleShot(True)
314+
self.channel_search_update_timer.setInterval(200) # ms delay
315+
self.channel_search_update_timer.timeout.connect(partial(self._update_inline_search, widget=self.channels_tree))
316+
self.channels_search_name.textChanged.connect(self.channel_search_update_timer.start)
317+
self.channels_search_name.pattern = None
318+
self.channels_search_bus.textChanged.connect(self.channel_search_update_timer.start)
319+
self.channels_search_bus.pattern = None
312320
self.channels_tree.itemDoubleClicked.connect(self.show_info)
321+
322+
self.filter_search_update_timer = QtCore.QTimer(self)
323+
self.filter_search_update_timer.setSingleShot(True)
324+
self.filter_search_update_timer.setInterval(200) # ms delay
325+
self.filter_search_update_timer.timeout.connect(partial(self._update_inline_search, widget=self.filter_tree))
326+
self.filter_search_name.textChanged.connect(self.filter_search_update_timer.start)
327+
self.filter_search_name.pattern = None
328+
self.filter_search_bus.textChanged.connect(self.filter_search_update_timer.start)
329+
self.filter_search_bus.pattern = None
313330
self.filter_tree.itemDoubleClicked.connect(self.show_info)
314331

315332
self.channel_view.setCurrentIndex(-1)
@@ -534,6 +551,49 @@ def update_all_channel_trees(self):
534551
for widget in widgetList:
535552
self._update_channel_tree(widget=widget)
536553

554+
def _update_inline_search(self, widget=None):
555+
# Move all regex logic here
556+
# Mark search bar as red if regex is not valid
557+
# If both are valid, then parse and call _update_channel_tree
558+
if widget is self.channels_tree:
559+
search_name = self.channels_search_name
560+
search_bus = self.channels_search_bus
561+
else:
562+
search_name = self.filter_search_name
563+
search_bus = self.filter_search_bus
564+
do_update = True
565+
566+
valid_text_color = QtGui.QPalette()
567+
valid_text_color.setColor(QtGui.QPalette.Text, QtCore.Qt.white)
568+
error_text_color = QtGui.QPalette()
569+
error_text_color.setColor(QtGui.QPalette.Text, QtCore.Qt.red)
570+
try:
571+
name_pattern = ".*" + search_name.text().strip() + ".*"
572+
if name_pattern.islower():
573+
name_pattern = re.compile(name_pattern, re.IGNORECASE)
574+
else:
575+
name_pattern = re.compile(name_pattern)
576+
search_name.pattern = name_pattern
577+
search_name.setPalette(valid_text_color)
578+
except re.error:
579+
search_name.setPalette(error_text_color)
580+
do_update = False
581+
582+
try:
583+
bus_pattern = ".*" + search_bus.text().strip() + ".*"
584+
if bus_pattern.islower():
585+
bus_pattern = re.compile(bus_pattern, re.IGNORECASE)
586+
else:
587+
bus_pattern = re.compile(bus_pattern)
588+
search_bus.pattern = bus_pattern
589+
search_bus.setPalette(valid_text_color)
590+
except re.error:
591+
search_bus.setPalette(error_text_color)
592+
do_update = False
593+
594+
if do_update:
595+
self._update_channel_tree(widget=widget)
596+
537597
def _update_channel_tree(self, index=None, widget=None, force=False):
538598
if widget is None:
539599
widget = self.channels_tree
@@ -544,6 +604,8 @@ def _update_channel_tree(self, index=None, widget=None, force=False):
544604
return
545605

546606
view = self.channel_view if widget is self.channels_tree else self.filter_view
607+
search_name = self.channels_search_name if widget is self.channels_tree else self.filter_search_name
608+
search_bus = self.channels_search_bus if widget is self.channels_tree else self.filter_search_bus
547609

548610
iterator = QtWidgets.QTreeWidgetItemIterator(widget)
549611
signals = set()
@@ -567,12 +629,24 @@ def _update_channel_tree(self, index=None, widget=None, force=False):
567629
widget.mode = view.currentText()
568630

569631
if widget.mode == "Natural sort":
632+
search_name.setVisible(True)
633+
search_bus.setVisible(True)
634+
570635
items = []
571636
for i, group in enumerate(self.mdf.groups):
572637
for j, ch in enumerate(group.channels):
573638
entry = i, j
574639

575-
channel = MinimalTreeItem(entry, ch.name, strings=[ch.name], origin_uuid=self.uuid)
640+
# Limit search to 10k items and apply search filters
641+
if len(items) >= 10_000:
642+
break
643+
if search_name.pattern and not search_name.pattern.search(ch.name):
644+
continue
645+
bus = group.channel_group.acq_source.path or "None"
646+
if search_bus.pattern and not search_bus.pattern.search(bus):
647+
continue
648+
649+
channel = MinimalTreeItem(entry, ch.name, strings=[f"{ch.name} —— {bus:<10}"], origin_uuid=self.uuid)
576650
channel.setToolTip(0, f"{ch.name} @ group {i}, index {j}")
577651

578652
if entry in signals:
@@ -589,8 +663,10 @@ def _update_channel_tree(self, index=None, widget=None, force=False):
589663
widget.addTopLevelItems(items)
590664

591665
elif widget.mode == "Internal file structure":
592-
items = []
666+
search_name.setVisible(False)
667+
search_bus.setVisible(False)
593668

669+
items = []
594670
for i, group in enumerate(self.mdf.groups):
595671
entry = i, 0xFFFFFFFFFFFFFFFF
596672

@@ -663,6 +739,10 @@ def _update_channel_tree(self, index=None, widget=None, force=False):
663739
widget.addTopLevelItems(items)
664740

665741
else:
742+
# widget.mode == "Selected channels only"
743+
search_name.setVisible(False)
744+
search_bus.setVisible(False)
745+
666746
items = []
667747
for entry in signals:
668748
gp_index, ch_index = entry
@@ -1663,7 +1743,7 @@ def close(self):
16631743

16641744
if windows:
16651745
unsaved = False
1666-
1746+
16671747
if hexdigest:
16681748
worker = md5()
16691749
try:

0 commit comments

Comments
 (0)