diff --git a/ameba_control_panel/managers/log_manager.py b/ameba_control_panel/managers/log_manager.py index 82de855..dcc4358 100644 --- a/ameba_control_panel/managers/log_manager.py +++ b/ameba_control_panel/managers/log_manager.py @@ -36,6 +36,8 @@ class LogManager(QObject): self._search_worker: Optional[SearchWorker] = None self._matches: List[int] = [] self._match_index = -1 + self._last_needle = "" + self._last_case = False self._flush_timer = QTimer(self) self._flush_timer.setInterval(config.LOG_FLUSH_INTERVAL_MS) @@ -87,6 +89,8 @@ class LogManager(QObject): visible = [line for line in to_flush if line.direction != Direction.TX] if visible: self.view.log_view.append_lines(visible) + if self._matches: + self._invalidate_search() # Adaptive: slow down flush when queue is heavy to reduce UI stalls pending_count = len(self._pending) if pending_count > 500: @@ -96,12 +100,17 @@ class LogManager(QObject): else: self._flush_timer.setInterval(config.LOG_FLUSH_INTERVAL_MS) + def _invalidate_search(self) -> None: + self._matches.clear() + self._match_index = -1 + self._last_needle = "" + self._last_case = False + self.view.log_view.set_matches([], -1) + def clear(self) -> None: self.buffer.clear() self.view.log_view.clear_log() - self._matches.clear() - self._match_index = -1 - self.view.log_view.set_matches([], -1) + self._invalidate_search() def save(self) -> None: dlg = QFileDialog(self.view, "Save Log", str(Path.home() / "ameba_log.txt")) @@ -126,14 +135,21 @@ class LogManager(QObject): if self._search_worker and self._search_worker.isRunning(): return needle = self.view.find_input.text() - self.view.log_view.set_needle(needle, self.view.case_checkbox.isChecked()) + case = self.view.case_checkbox.isChecked() + # If needle unchanged and we already have matches, just advance + if needle == self._last_needle and case == self._last_case and self._matches: + self.find_next() + return + self._last_needle = needle + self._last_case = case + self.view.log_view.set_needle(needle, case) if not needle: self.view.log_view.set_matches([], -1) self._matches = [] self._match_index = -1 return lines = [l.as_display() for l in self.view.log_view.displayed_lines()] - self._search_worker = SearchWorker(lines, needle, self.view.case_checkbox.isChecked()) + self._search_worker = SearchWorker(lines, needle, case) self._search_worker.finished.connect(self._on_search_finished) self._search_worker.start()