class CustomCodeFrame(QFrame): poke_code = pyqtSignal(str, int, QByteArray) # code_set_label, code_id, new_bytes log = pyqtSignal(str, str) # msg, color def __init__(self, code_set, parent=None): super(CustomCodeFrame, self).__init__(parent) self.cs = code_set self.tmr_reset_bg_clr = QTimer(self) self.tmr_reset_bg_clr.setInterval(500) # ms self.tmr_reset_bg_clr.timeout.connect(self.resetBGColor) self.txt_label = QLineEdit(self) self.txt_label.setMaximumWidth(160) self.txt_label.setPlaceholderText('Label') self.txt_codes = QPlainTextEdit(self) self.txt_codes.setMaximumHeight(66) font = QFont('Monospace') font.setStyleHint(QFont.TypeWriter) self.txt_codes.setFont(font) self.txt_codes.cursorPositionChanged.connect(self.resetBGColor) icon_height = self.txt_label.height()*8/15 self.btn_poke = QPushButton(self) self.btn_poke.setIcon(QIcon('img/flaticon/draw39.png')) self.btn_poke.setIconSize(QSize(icon_height, icon_height)) self.btn_poke.setFixedSize(QSize(icon_height*1.5, icon_height*1.5)) self.btn_poke.setAutoFillBackground(True) self.btn_poke.setStyleSheet('background-color: white') self.btn_poke.setToolTip('Poke memory') self.btn_poke.clicked.connect(self.onPoke) self.layout = QHBoxLayout(self) self.layout.addWidget(self.txt_label) self.layout.setAlignment(self.txt_label, Qt.AlignTop) self.layout.addWidget(self.txt_codes) self.layout.setAlignment(self.txt_codes, Qt.AlignTop) self.layout.addWidget(self.btn_poke) self.layout.setAlignment(self.btn_poke, Qt.AlignTop) self.layout.setContentsMargins(0, 2, 0, 2) def setAlternateBGColor(self): self.setStyleSheet('CustomCodeFrame { background-color:rgb(248,248,248) }') def setErrorBGColor(self): self.txt_codes.setStyleSheet('background-color: rgb(255,128,128)') self.tmr_reset_bg_clr.start() def resetBGColor(self): if self.tmr_reset_bg_clr.isActive(): self.tmr_reset_bg_clr.stop() self.txt_codes.setStyleSheet('background-color: white') @pyqtSlot() def onPoke(self): try: parse_custom_codes(self.cs, str(self.txt_codes.toPlainText())) except SyntaxError, e: self.log.emit(str(e), 'red') self.setErrorBGColor() return if len(self.cs.c) <= 0: self.log.emit('POKE failed: no codes found', 'red') self.setErrorBGColor() return # Sequentially poke codes for code in self.cs.c: raw_bytes = struct.pack('>Q', code.dft_value)[-code.num_bytes:] self.poke_code.emit(code.label, code.id, QByteArray(raw_bytes))
class CustomCodeFrame(QFrame): poke_code = pyqtSignal(str, int, QByteArray) # code_set_label, code_id, new_bytes log = pyqtSignal(str, str) # msg, color def __init__(self, code_set, parent=None): super(CustomCodeFrame, self).__init__(parent) self.cs = code_set self.tmr_reset_bg_clr = QTimer(self) self.tmr_reset_bg_clr.setInterval(500) # ms self.tmr_reset_bg_clr.timeout.connect(self.resetBGColor) self.txt_label = QLineEdit(self) self.txt_label.setMaximumWidth(160) self.txt_label.setPlaceholderText('Label') self.txt_codes = QPlainTextEdit(self) self.txt_codes.setMaximumHeight(66) font = QFont('Monospace') font.setStyleHint(QFont.TypeWriter) self.txt_codes.setFont(font) self.txt_codes.cursorPositionChanged.connect(self.resetBGColor) icon_height = self.txt_label.height() * 8 / 15 self.btn_poke = QPushButton(self) self.btn_poke.setIcon(QIcon('img/flaticon/draw39.png')) self.btn_poke.setIconSize(QSize(icon_height, icon_height)) self.btn_poke.setFixedSize(QSize(icon_height * 1.5, icon_height * 1.5)) self.btn_poke.setAutoFillBackground(True) self.btn_poke.setStyleSheet('background-color: white') self.btn_poke.setToolTip('Poke memory') self.btn_poke.clicked.connect(self.onPoke) self.layout = QHBoxLayout(self) self.layout.addWidget(self.txt_label) self.layout.setAlignment(self.txt_label, Qt.AlignTop) self.layout.addWidget(self.txt_codes) self.layout.setAlignment(self.txt_codes, Qt.AlignTop) self.layout.addWidget(self.btn_poke) self.layout.setAlignment(self.btn_poke, Qt.AlignTop) self.layout.setContentsMargins(0, 2, 0, 2) def setAlternateBGColor(self): self.setStyleSheet( 'CustomCodeFrame { background-color:rgb(248,248,248) }') def setErrorBGColor(self): self.txt_codes.setStyleSheet('background-color: rgb(255,128,128)') self.tmr_reset_bg_clr.start() def resetBGColor(self): if self.tmr_reset_bg_clr.isActive(): self.tmr_reset_bg_clr.stop() self.txt_codes.setStyleSheet('background-color: white') @pyqtSlot() def onPoke(self): try: parse_custom_codes(self.cs, str(self.txt_codes.toPlainText())) except SyntaxError, e: self.log.emit(str(e), 'red') self.setErrorBGColor() return if len(self.cs.c) <= 0: self.log.emit('POKE failed: no codes found', 'red') self.setErrorBGColor() return # Sequentially poke codes for code in self.cs.c: raw_bytes = struct.pack('>Q', code.dft_value)[-code.num_bytes:] self.poke_code.emit(code.label, code.id, QByteArray(raw_bytes))
class ThemeEditor(QDialog): """ThemeEditor Scheme Designer Class Widget""" def __init__(self, parent): super(ThemeEditor, self).__init__(parent, Qt.Dialog) vbox = QVBoxLayout(self) hbox = QHBoxLayout() self.line_name = QLineEdit() self.btn_save = QPushButton(translations.TR_SAVE) self.line_name.setPlaceholderText(getuser().capitalize() + "s_theme") hbox.addWidget(self.line_name) hbox.addWidget(self.btn_save) self.edit_qss = QPlainTextEdit() css = 'QPlainTextEdit {color: %s; background-color: %s;' \ 'selection-color: %s; selection-background-color: %s;}' \ % (resources.CUSTOM_SCHEME.get( 'editor-text', resources.COLOR_SCHEME['Default']), resources.CUSTOM_SCHEME.get( 'EditorBackground', resources.COLOR_SCHEME['EditorBackground']), resources.CUSTOM_SCHEME.get( 'EditorSelectionColor', resources.COLOR_SCHEME['EditorSelectionColor']), resources.CUSTOM_SCHEME.get( 'EditorSelectionBackground', resources.COLOR_SCHEME['EditorSelectionBackground'])) self.edit_qss.setStyleSheet(css) self.btn_apply = QPushButton(self.tr("Apply Style Sheet")) hbox2 = QHBoxLayout() hbox2.addSpacerItem(QSpacerItem(10, 0, QSizePolicy.Expanding, QSizePolicy.Fixed)) hbox2.addWidget(self.btn_apply) hbox2.addSpacerItem(QSpacerItem(10, 0, QSizePolicy.Expanding, QSizePolicy.Fixed)) vbox.addWidget(self.edit_qss) vbox.addLayout(hbox) vbox.addLayout(hbox2) self.connect(self.btn_apply, SIGNAL("clicked()"), self.apply_stylesheet) self.connect(self.btn_save, SIGNAL("clicked()"), self.save_stylesheet) def apply_stylesheet(self): qss = self.edit_qss.toPlainText() QApplication.instance().setStyleSheet(qss) def save_stylesheet(self): try: file_name = "%s.qss" % self.line_name.text() if not self._is_valid_scheme_name(file_name): QMessageBox.information( self, translations.TR_PREFERENCES_THEME, translations.TR_SCHEME_INVALID_NAME) file_name = ('{0}.qss'.format( file_manager.create_path( resources.NINJA_THEME_DOWNLOAD, file_name))) content = self.edit_qss.toPlainText() answer = True if file_manager.file_exists(file_name): answer = QMessageBox.question( self, translations.TR_PREFERENCES_THEME, translations.TR_WANT_OVERWRITE_FILE + ": {0}?".format( file_name), QMessageBox.Yes, QMessageBox.No) if answer in (QMessageBox.Yes, True): self.apply_stylesheet() file_manager.store_file_content( file_name, content, newFile=True) self.close() except file_manager.NinjaFileExistsException as ex: QMessageBox.information( self, self.tr("File Already Exists"), (self.tr("Invalid File Name: the file '%s' already exists.") % ex.filename)) def _is_valid_scheme_name(self, name): """Check if a given name is a valid name for an editor scheme. Params: name := the name to check Returns: True if and only if the name is okay to use for a scheme. """ return name not in ('', 'Default')
class ThemeEditor(QDialog): """ThemeEditor Scheme Designer Class Widget""" def __init__(self, parent): super(ThemeEditor, self).__init__(parent, Qt.Dialog) vbox = QVBoxLayout(self) hbox = QHBoxLayout() self.line_name = QLineEdit() self.btn_save = QPushButton(translations.TR_SAVE) self.line_name.setPlaceholderText(getuser().capitalize() + "s_theme") hbox.addWidget(self.line_name) hbox.addWidget(self.btn_save) self.edit_qss = QPlainTextEdit() css = 'QPlainTextEdit {color: %s; background-color: %s;' \ 'selection-color: %s; selection-background-color: %s;}' \ % (resources.CUSTOM_SCHEME.get( 'editor-text', resources.COLOR_SCHEME['Default']), resources.CUSTOM_SCHEME.get( 'EditorBackground', resources.COLOR_SCHEME['EditorBackground']), resources.CUSTOM_SCHEME.get( 'EditorSelectionColor', resources.COLOR_SCHEME['EditorSelectionColor']), resources.CUSTOM_SCHEME.get( 'EditorSelectionBackground', resources.COLOR_SCHEME['EditorSelectionBackground'])) self.edit_qss.setStyleSheet(css) self.btn_apply = QPushButton(self.tr("Apply Style Sheet")) hbox2 = QHBoxLayout() hbox2.addSpacerItem( QSpacerItem(10, 0, QSizePolicy.Expanding, QSizePolicy.Fixed)) hbox2.addWidget(self.btn_apply) hbox2.addSpacerItem( QSpacerItem(10, 0, QSizePolicy.Expanding, QSizePolicy.Fixed)) vbox.addWidget(self.edit_qss) vbox.addLayout(hbox) vbox.addLayout(hbox2) self.connect(self.btn_apply, SIGNAL("clicked()"), self.apply_stylesheet) self.connect(self.btn_save, SIGNAL("clicked()"), self.save_stylesheet) def apply_stylesheet(self): qss = self.edit_qss.toPlainText() QApplication.instance().setStyleSheet(qss) def save_stylesheet(self): try: file_name = "%s.qss" % self.line_name.text() if not self._is_valid_scheme_name(file_name): QMessageBox.information(self, translations.TR_PREFERENCES_THEME, translations.TR_SCHEME_INVALID_NAME) file_name = ('{0}.qss'.format( file_manager.create_path(resources.NINJA_THEME_DOWNLOAD, file_name))) content = self.edit_qss.toPlainText() answer = True if file_manager.file_exists(file_name): answer = QMessageBox.question( self, translations.TR_PREFERENCES_THEME, translations.TR_WANT_OVERWRITE_FILE + ": {0}?".format(file_name), QMessageBox.Yes, QMessageBox.No) if answer in (QMessageBox.Yes, True): self.apply_stylesheet() file_manager.store_file_content(file_name, content, newFile=True) self.close() except file_manager.NinjaFileExistsException as ex: QMessageBox.information( self, self.tr("File Already Exists"), (self.tr("Invalid File Name: the file '%s' already exists.") % ex.filename)) def _is_valid_scheme_name(self, name): """Check if a given name is a valid name for an editor scheme. Params: name := the name to check Returns: True if and only if the name is okay to use for a scheme. """ return name not in ('', 'Default')