from PySide6.QtGui import QIcon from PySide6.QtWidgets import QDialog, QLineEdit, QLabel, QGridLayout, QCheckBox, QListWidget, QListWidgetItem, \ QPushButton, QDialogButtonBox, QMessageBox, QSizePolicy from raven.ui.bigtext.highlight_regex import HighlightRegex from raven.ui.bigtext.highlighting import Highlighting from raven.ui.colorbutton import ColorButton from raven.ui.hbox import HBox from raven.settings.settings import Settings from raven.i18n import _ class PayloadItem(QListWidgetItem): def __init__(self, text: str, payload=None): super(PayloadItem, self).__init__(text) self.payload = payload class HighlightingDialog(QDialog): def __init__(self, settings: Settings): super(HighlightingDialog, self).__init__() self.setWindowTitle(_("Manage Highlighting")) self.setModal(True) self._settings = settings form_grid = QGridLayout(self) self.layout = form_grid row = 0 self.list = QListWidget(self) form_grid.addWidget(self.list, row, 0, 1, 2) row = row + 1 self.btn_add = QPushButton(QIcon.fromTheme("list-add"), _("Add")) self.btn_add.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)) self.btn_add.pressed.connect(self._add) self.btn_update = QPushButton(QIcon.fromTheme("stock_edit"), _("Update")) self.btn_update.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)) self.btn_update.pressed.connect(self._update) self.btn_delete = QPushButton(QIcon.fromTheme("list-remove"), _("Remove")) self.btn_delete.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)) self.btn_delete.pressed.connect(self._delete) self.btn_move_up = QPushButton(QIcon.fromTheme("go-up"), _("Up")) self.btn_move_up.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)) self.btn_move_up.pressed.connect(self._move_up) self.btn_move_down = QPushButton(QIcon.fromTheme("go-down"), _("Down")) self.btn_move_down.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)) self.btn_move_down.pressed.connect(self._move_down) button_box = HBox(self.btn_update, self.btn_add, self.btn_delete, self.btn_move_up, self.btn_move_down) form_grid.addWidget(button_box, row, 0, 1, 2) row = row + 1 self.query = QLineEdit(self) form_grid.addWidget(QLabel(_("Query:")), row, 0) form_grid.addWidget(self.query, row, 1) row = row + 1 self.ignore_case = QCheckBox(_("Ignore Case")) self.ignore_case.setChecked(True) form_grid.addWidget(self.ignore_case, row, 0, 1, 2) row = row + 1 self.is_regex = QCheckBox(_("Regular Expression")) self.is_regex.setChecked(True) form_grid.addWidget(self.is_regex, row, 0, 1, 2) row = row + 1 form_grid.addWidget(QLabel(_("Hit Background:")), row, 0) self.hit_background_color = ColorButton("ccb400") form_grid.addWidget(self.hit_background_color, row, 1) row = row + 1 form_grid.addWidget(QLabel(_("Line Background:")), row, 0) self.line_background_color = ColorButton("fff080") form_grid.addWidget(self.line_background_color, row, 1) row = row + 1 self.buttons = QDialogButtonBox() self.buttons.setStandardButtons(QDialogButtonBox.StandardButton.Cancel | QDialogButtonBox.StandardButton.Ok) self.buttons.accepted.connect(self._save) self.buttons.rejected.connect(self.close) form_grid.addWidget(self.buttons, row, 0, 1, 2) self._load_existing_hightlighters() self.list.setCurrentItem(None) self._selection_changed() self.list.itemSelectionChanged.connect(self._selection_changed) def _add(self): highlighter = HighlightRegex( self.query.text(), self.ignore_case.isChecked(), self.is_regex.isChecked(), self.hit_background_color.color, self.line_background_color.color ) item = PayloadItem(self.query.text(), highlighter) item.setBackground(highlighter.hit_background_brush()) self.list.addItem(item) self.list.setCurrentItem(item) def _update(self): item: PayloadItem = self.list.currentItem() highlighter: HighlightRegex = item.payload highlighter.query = self.query.text() highlighter.ignore_case = self.ignore_case.isChecked() highlighter.is_regex = self.is_regex.isChecked() highlighter.hit_background_color = self.hit_background_color.color highlighter.line_background_color = self.line_background_color.color item.setText(self.query.text()) item.setBackground(highlighter.hit_background_brush()) def _delete(self): index = self.list.selectedIndexes()[0] selected_index = index.row() self.list.takeItem(selected_index) def _move_up(self): index = self.list.currentIndex() selected_index = index.row() item = self.list.takeItem(selected_index) self.list.insertItem(selected_index - 1, item) self.list.setCurrentIndex(index.siblingAtRow(selected_index - 1)) def _move_down(self): index = self.list.selectedIndexes()[0] selected_index = index.row() item = self.list.takeItem(selected_index) self.list.insertItem(selected_index + 1, item) self.list.setCurrentIndex(index.sibling(selected_index + 1, 0)) def _save(self): if self._is_dirty(): unsaved = QMessageBox(QMessageBox.Icon.Question, _("unsaved changes"), _("You have unsaved changes.")) unsaved.setStandardButtons(QMessageBox.Cancel | QMessageBox.StandardButton.Discard) result = unsaved.exec() if result == QMessageBox.StandardButton.Cancel: return highlighters = [] for index in range(0, self.list.count()): item: PayloadItem = self.list.item(index) highlighters.append(item.payload) Highlighting.write_config(self._settings, highlighters) self.close() def _selection_changed(self): if len(self.list.selectedIndexes()) == 0: self.btn_update.setDisabled(True) self.btn_delete.setDisabled(True) self.btn_move_up.setDisabled(True) self.btn_move_down.setDisabled(True) if len(self.list.selectedIndexes()) == 1: selected_index = self.list.selectedIndexes()[0].row() self.btn_update.setDisabled(False) self.btn_delete.setDisabled(False) self.btn_move_up.setDisabled(selected_index == 0) self.btn_move_down.setDisabled(selected_index + 1 >= self.list.count()) item: PayloadItem = self.list.item(selected_index) highlighter: HighlightRegex = item.payload self.query.setText(highlighter.query) self.ignore_case.setChecked(highlighter.ignore_case) self.is_regex.setChecked(highlighter.is_regex) self.hit_background_color.set_color(highlighter.hit_background_color) self.line_background_color.set_color(highlighter.line_background_color) def _is_dirty(self): if len(self.list.selectedIndexes()) == 0: dirty = False if len(self.list.selectedIndexes()) == 1: item: PayloadItem = self.list.currentItem() highlighter: HighlightRegex = item.payload dirty = self.query.text() != highlighter.query \ or self.ignore_case.isChecked() != highlighter.ignore_case \ or self.is_regex.isChecked() != highlighter.is_regex \ or self.hit_background_color.color != highlighter.hit_background_color \ or self.line_background_color.color != highlighter.line_background_color else: dirty = False return dirty def _load_existing_hightlighters(self): highlighters: [HighlightRegex] = Highlighting.read_config(self._settings) first_item = None for highlighter in highlighters: item = PayloadItem(str(highlighter.query)) item.payload = highlighter item.setBackground(highlighter.hit_background_brush()) self.list.addItem(item) if not first_item: first_item = item