def _init_central_widget(self): self._lbl_icon_config = IconLabel(self, qtawesome.icon("fa.cog")) self._lbl_icon_config.setHoverEffect(True) self._lbl_icon_config.setEnabled(self.codec_frame.isConfigurable()) self._lbl_icon_config.setToolTip("Configure") self._lbl_icon_config.clicked.connect(self.clicked) return self._lbl_icon_config
def _init_central_widget(self): self._lbl_icon_down = IconLabel(self, qtawesome.icon("fa.chevron-down")) self._lbl_icon_down.setHoverEffect(True) self._lbl_icon_down.setToolTip("Move down") self._lbl_icon_down.setEnabled(self.codec_frame.hasNextFrame()) self._lbl_icon_down.clicked.connect(self.clicked) return self._lbl_icon_down
def _init_central_widget(self): self._lbl_icon_up = IconLabel(self, qtawesome.icon("fa.chevron-up")) self._lbl_icon_up.setHoverEffect(True) self._lbl_icon_up.setToolTip("Move up") self._lbl_icon_up.setEnabled(self.codec_frame.getFrameIndex() >= 2) self._lbl_icon_up.clicked.connect(self.clicked) return self._lbl_icon_up
def _init_hidden_dialog(self): """ Inits the icon which opens the hidden dialog on mouse press. """ about_label = IconLabel( self, QIcon( os.path.join(self._context.getAppPath(), 'images', 'hidden.png'))) about_label.mousePressEvent = lambda e: self._show_hidden_dialog() return about_label
def _init_central_widget(self): self._lbl_icon_close = IconLabel(self, qtawesome.icon("fa.times")) self._lbl_icon_close.setHoverEffect(True) self._lbl_icon_close.setToolTip("Close") self._lbl_icon_close.clicked.connect(self.clicked) # First codec frame can not be closed self._lbl_icon_close.setEnabled( self.codec_frame.hasPreviousFrame()) return self._lbl_icon_close
def _init_about_tab(self): tab = QWidget(self) base_layout = QHBoxLayout() base_layout.setAlignment(QtCore.Qt.AlignVCenter) if datetime.now().month == 12: logo = os.path.join(self._context.getAppPath(), 'images', 'dpp_xmas.png') else: logo = os.path.join(self._context.getAppPath(), 'images', 'dpp.png') icon_frame = QFrame() icon_layout = QHBoxLayout() icon_label = IconLabel(self, QIcon(logo)) icon_label.mouseDoubleClickEvent = lambda evt: self._context.toggleDebugMode( ) icon_label.setFixedSize(QSize(180, 180)) icon_layout.setAlignment(QtCore.Qt.AlignLeft) icon_layout.setContentsMargins(10, 10, 10, 10) icon_layout.addWidget(icon_label) icon_frame.setLayout(icon_layout) base_layout.addWidget(icon_frame) form_frame = QFrame(self) form_layout = QFormLayout() form_layout.setAlignment(QtCore.Qt.AlignLeft) form_layout.addRow(QLabel("<font size='18'>Decoder++</font>"), QLabel("")) form_layout.addRow(QLabel(""), QLabel("")) form_layout.addRow(QLabel("Core-Development: "), QLabel("")) form_layout.addRow(QLabel(""), QLabel("Thomas Engel")) form_layout.addRow(QLabel("Plugin-Development: "), QLabel("")) plugin_authors = self._context.plugins().authors() for plugin_author in plugin_authors: plugin_author_label = QLabel(plugin_author) # Show tooltip with all plugin names. # Enable automatic text wrapping of tooltip by using rich-text. plugin_author_label.setToolTip("<font>{}</font>".format(", ".join( sorted(set( self._context.plugins().names(author=plugin_author)))))) form_layout.addRow(QLabel(""), plugin_author_label) form_layout.addRow(QLabel("Inspired By: "), QLabel("")) form_layout.addRow(QLabel(""), QLabel("PortSwigger's Burp Decoder")) form_layout.addRow(QLabel("Powered By: "), QLabel("")) form_layout.addRow(QLabel(""), QLabel("PyQt5")) form_layout.addRow(QLabel(""), QLabel("QtAwesome")) form_layout.addRow(QLabel(""), QLabel("QScintilla")) form_layout.addRow(QLabel("Website: "), QLabel("")) form_layout.addRow( QLabel(""), QLabel( "<a href='https://github.com/bytebutcher/decoder-plus-plus/'>https://github.com/bytebutcher/decoder-plus-plus</a>" )) form_frame.setLayout(form_layout) base_layout.addWidget(form_frame) base_layout.addWidget(HSpacer()) tab.setLayout(base_layout) return tab
def __init__(self, icon: QIcon, count: int = 0, parent=None): super(__class__, self).__init__(parent) self._icon = IconLabel(parent, icon) self._icon.setHoverEffect(True) self._icon.clicked.connect(lambda: self.icon_clicked.emit()) self._label = QLabel(self) self.setCount(count) layout = QHBoxLayout() layout.addWidget(self._icon) layout.addWidget(self._label) layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout)
def __init__(self, parent=None): super(__class__, self).__init__(parent) layout = QHBoxLayout() self._icons = dict() self._icons[self.ICON_READY] = qtawesome.icon("fa.check") self._icons[self.ICON_INFO] = qtawesome.icon("fa.info") self._icons[self.ICON_ERROR] = qtawesome.icon("fa.exclamation") self._log_info_count_widget = MessageWidget.CountWidget( qtawesome.icon("fa.info-circle"), 0, self) self._log_info_count_widget.icon_clicked.connect( lambda: self.infoClicked.emit()) self._log_info_count_widget.mouseDoubleClickEvent = lambda e: self.infoClicked.emit( ) self._log_error_count_widget = MessageWidget.CountWidget( qtawesome.icon("fa.exclamation-triangle"), 0, self) self._log_error_count_widget.icon_clicked.connect( lambda: self.errorClicked.emit()) self._log_error_count_widget.mouseDoubleClickEvent = lambda e: self.errorClicked.emit( ) layout.addWidget(self._log_info_count_widget) layout.addWidget(self._log_error_count_widget) line = QFrame(self) line.setGeometry(QRect(320, 150, 118, 3)) line.setFrameShape(QFrame.VLine) line.setFrameShadow(QFrame.Sunken) layout.addWidget(line, 0, Qt.AlignLeft) self._log_message_icon_label = IconLabel( self, self._get_icon(self.ICON_READY)) self._log_message_icon_label.setHoverEffect(True) self._log_message_icon_label.clicked.connect( lambda evt: self.messageClicked.emit()) self._log_message_icon_label.setHoverEffect(True) self._log_message_text_label = ClickableLabel("Ready.") self._log_message_text_label.doubleClicked.connect( lambda e: self.messageClicked.emit()) layout.addWidget(self._log_message_icon_label) layout.addWidget(self._log_message_text_label) self.setLayout(layout)
class ConfigButtonHeaderItem(ClickableCodecFrameHeaderItem): def __init__(self, codec_frame: 'ui.codec_frame.CodecFrame'): super(__class__, self).__init__(codec_frame) self.setCentralWidget(self._init_central_widget()) def _init_central_widget(self): self._lbl_icon_config = IconLabel(self, qtawesome.icon("fa.cog")) self._lbl_icon_config.setHoverEffect(True) self._lbl_icon_config.setEnabled(self.codec_frame.isConfigurable()) self._lbl_icon_config.setToolTip("Configure") self._lbl_icon_config.clicked.connect(self.clicked) return self._lbl_icon_config def refresh(self): self._lbl_icon_config.setEnabled(self.codec_frame.isConfigurable())
class UpButtonHeaderItem(ClickableCodecFrameHeaderItem): def __init__(self, codec_frame: 'ui.codec_frame.CodecFrame'): super(__class__, self).__init__(codec_frame) self.setCentralWidget(self._init_central_widget()) def _init_central_widget(self): self._lbl_icon_up = IconLabel(self, qtawesome.icon("fa.chevron-up")) self._lbl_icon_up.setHoverEffect(True) self._lbl_icon_up.setToolTip("Move up") self._lbl_icon_up.setEnabled(self.codec_frame.getFrameIndex() >= 2) self._lbl_icon_up.clicked.connect(self.clicked) return self._lbl_icon_up def refresh(self): self._lbl_icon_up.setEnabled(self.codec_frame.getFrameIndex() >= 2)
class CountWidget(QFrame): """ A widget with an icon and a counter. """ icon_clicked = pyqtSignal() def __init__(self, icon: QIcon, count: int = 0, parent=None): super(__class__, self).__init__(parent) self._icon = IconLabel(parent, icon) self._icon.setHoverEffect(True) self._icon.clicked.connect(lambda: self.icon_clicked.emit()) self._label = QLabel(self) self.setCount(count) layout = QHBoxLayout() layout.addWidget(self._icon) layout.addWidget(self._label) layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) def setCount(self, count: int): """ Sets the counter to the specified value. """ self._label.setText(str(count)) def getCount(self) -> int: """ Returns the counter. """ return int(self._label.text()) def incrementCount(self): """ Increments the counter. """ self._label.setText(str(self.getCount() + 1)) def decrementCount(self): """ Decrements the counter. """ self._label.setText(str(self.getCount() - 1)) def resetCount(self): """ Resets the counter to zero. """ self.setCount(0)
class CloseButtonHeaderItem(ClickableCodecFrameHeaderItem): def __init__(self, codec_frame: 'ui.codec_frame.CodecFrame'): super(__class__, self).__init__(codec_frame) self.setCentralWidget(self._init_central_widget()) def _init_central_widget(self): self._lbl_icon_close = IconLabel(self, qtawesome.icon("fa.times")) self._lbl_icon_close.setHoverEffect(True) self._lbl_icon_close.setToolTip("Close") self._lbl_icon_close.clicked.connect(self.clicked) # First codec frame can not be closed self._lbl_icon_close.setEnabled( self.codec_frame.hasPreviousFrame()) return self._lbl_icon_close def refresh(self): # First codec frame can not be closed self._lbl_icon_close.setEnabled( self.codec_frame.hasPreviousFrame())
class DownButtonHeaderItem(ClickableCodecFrameHeaderItem): def __init__(self, codec_frame: 'ui.codec_frame.CodecFrame'): super(__class__, self).__init__(codec_frame) self.setCentralWidget(self._init_central_widget()) def _init_central_widget(self): self._lbl_icon_down = IconLabel(self, qtawesome.icon("fa.chevron-down")) self._lbl_icon_down.setHoverEffect(True) self._lbl_icon_down.setToolTip("Move down") self._lbl_icon_down.setEnabled(self.codec_frame.hasNextFrame()) self._lbl_icon_down.clicked.connect(self.clicked) return self._lbl_icon_down def refresh(self): # Only when there is a next codec frame it can be moved down. # Note, that the first codec frame can not be moved either. self._lbl_icon_down.setEnabled( self.codec_frame.hasNextFrame() and self.codec_frame.hasPreviousFrame())
class MessageWidget(QFrame): """ Widget which shows messages. """ messageReceived = pyqtSignal('PyQt_PyObject', 'PyQt_PyObject') messageClicked = pyqtSignal() infoClicked = pyqtSignal() errorClicked = pyqtSignal() ICON_READY = "ICON_READY" ICON_INFO = "ICON_INFO" ICON_ERROR = "ICON_ERROR" class CountWidget(QFrame): """ A widget with an icon and a counter. """ icon_clicked = pyqtSignal() def __init__(self, icon: QIcon, count: int = 0, parent=None): super(__class__, self).__init__(parent) self._icon = IconLabel(parent, icon) self._icon.setHoverEffect(True) self._icon.clicked.connect(lambda: self.icon_clicked.emit()) self._label = QLabel(self) self.setCount(count) layout = QHBoxLayout() layout.addWidget(self._icon) layout.addWidget(self._label) layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) def setCount(self, count: int): """ Sets the counter to the specified value. """ self._label.setText(str(count)) def getCount(self) -> int: """ Returns the counter. """ return int(self._label.text()) def incrementCount(self): """ Increments the counter. """ self._label.setText(str(self.getCount() + 1)) def decrementCount(self): """ Decrements the counter. """ self._label.setText(str(self.getCount() - 1)) def resetCount(self): """ Resets the counter to zero. """ self.setCount(0) def __init__(self, parent=None): super(__class__, self).__init__(parent) layout = QHBoxLayout() self._icons = dict() self._icons[self.ICON_READY] = qtawesome.icon("fa.check") self._icons[self.ICON_INFO] = qtawesome.icon("fa.info") self._icons[self.ICON_ERROR] = qtawesome.icon("fa.exclamation") self._log_info_count_widget = MessageWidget.CountWidget( qtawesome.icon("fa.info-circle"), 0, self) self._log_info_count_widget.icon_clicked.connect( lambda: self.infoClicked.emit()) self._log_info_count_widget.mouseDoubleClickEvent = lambda e: self.infoClicked.emit( ) self._log_error_count_widget = MessageWidget.CountWidget( qtawesome.icon("fa.exclamation-triangle"), 0, self) self._log_error_count_widget.icon_clicked.connect( lambda: self.errorClicked.emit()) self._log_error_count_widget.mouseDoubleClickEvent = lambda e: self.errorClicked.emit( ) layout.addWidget(self._log_info_count_widget) layout.addWidget(self._log_error_count_widget) line = QFrame(self) line.setGeometry(QRect(320, 150, 118, 3)) line.setFrameShape(QFrame.VLine) line.setFrameShadow(QFrame.Sunken) layout.addWidget(line, 0, Qt.AlignLeft) self._log_message_icon_label = IconLabel( self, self._get_icon(self.ICON_READY)) self._log_message_icon_label.setHoverEffect(True) self._log_message_icon_label.clicked.connect( lambda evt: self.messageClicked.emit()) self._log_message_icon_label.setHoverEffect(True) self._log_message_text_label = ClickableLabel("Ready.") self._log_message_text_label.doubleClicked.connect( lambda e: self.messageClicked.emit()) layout.addWidget(self._log_message_icon_label) layout.addWidget(self._log_message_text_label) self.setLayout(layout) def _get_icon(self, type: str): """ Returns an icon of the specified type. :param type: the type of the icon (e.g. READY, INFO, ERROR). """ return self._icons[type] def _log_message(self, type: str, message: str): """ Emits a message event. :param type: the type of the message (e.g. info, error, debug). :param message: the message. """ self.messageReceived.emit(type, message) def showDebug(self, message: str, log_only: bool = False): """ Adds debug message to the log. """ self._log_message("DEBUG", message) def showInfo(self, message: str, log_only: bool = False): """ Shows info message in the statusbar. Adds info message to the log. Increments info count. """ self._log_message("INFO", message) self._log_info_count_widget.incrementCount() if not log_only: self.showMessage(message, self.ICON_INFO) def showError(self, message: str, log_only: bool = False): """ Shows error message in the statusbar. Adds error message to the log. Increments error count. """ self._log_message("ERROR", message) self._log_error_count_widget.incrementCount() if not log_only: self.showMessage(message, self.ICON_ERROR) def showMessage(self, message: str, icon_type: str): """ Displays a message (shortened to 100 characters) for 5 seconds in the statusbar. :param message: the message to display. :param icon_type: the type of the icon (e.g. INFO, ERROR). """ if message: def _show_ready(): self._log_message_icon_label.setIcon( self._get_icon(self.ICON_READY)) self._log_message_text_label.setText("Ready.") message = self._shorten_message(message, 100) self._log_message_icon_label.setIcon(self._get_icon(icon_type)) self._log_message_text_label.setText(message) QTimer.singleShot(5000, _show_ready) def _shorten_message(self, message: str, max_length: int): """ Removes new-lines and shortens message to the specified max_length. :param message: the message to shorten. :param max_length: the max length of the message. :return: the shortened message. """ if not message: return "" merged_lines = " ".join(message.splitlines()) if len(merged_lines) > (max_length - 3): return merged_lines[:(max_length - 3)] + "..." else: return merged_lines def resetCount(self): """ Resets the info- and error-log-counters to zero. """ self._log_info_count_widget.resetCount() self._log_error_count_widget.resetCount()