class EditorSchemeDesigner(QDialog): """Editor Scheme Designer Class Widget""" def __init__(self, scheme, parent): super(EditorSchemeDesigner, self).__init__(parent, Qt.Dialog) self.original_style = copy.copy(resources.CUSTOM_SCHEME) self._avoid_on_loading, self.saved, self._components = True, False, {} self.setWindowTitle(translations.TR_PREFERENCES_EDITOR_SCHEME_DESIGNER) self.setMinimumSize(450, 480) self.setMaximumSize(500, 900) self.resize(450, 600) # all layouts and groupboxes group0 = QGroupBox(translations.TR_PROJECT_NAME) # scheme filename group1 = QGroupBox(translations.TR_PROJECT_PROPERTIES) # properties group2 = QGroupBox(translations.TR_PREVIEW) # quick preview thingy group0_hbox, group1_vbox = QHBoxLayout(group0), QVBoxLayout(group1) this_dialog_vbox, group2_vbox = QVBoxLayout(self), QVBoxLayout(group2) self._grid, scrollArea, frame = QGridLayout(), QScrollArea(), QFrame() # widgets self.line_name, btnSave = QLineEdit(), QPushButton( translations.TR_SAVE) self.line_name.setPlaceholderText(getuser().capitalize() + "s_scheme") group0_hbox.addWidget(self.line_name) group0_hbox.addWidget(btnSave) self.connect(btnSave, SIGNAL("clicked()"), self.save_scheme) _demo = "<center>" + ascii_letters # demo text for preview self.preview_label1, self.preview_label2 = QLabel(_demo), QLabel(_demo) group2_vbox.addWidget(self.preview_label1) group2_vbox.addWidget(self.preview_label2) # rows titles self._grid.addWidget(QLabel("<b>" + translations.TR_PROJECT_NAME), 0, 0) self._grid.addWidget(QLabel("<b>" + translations.TR_CODE), 0, 1) self._grid.addWidget( QLabel("<b>" + translations.TR_EDITOR_SCHEME_PICK_COLOR), 0, 2) # fill rows for key in sorted(tuple(resources.COLOR_SCHEME.keys())): self.add_item(key, scheme) self.preview_label1.setStyleSheet('background:transparent') self.preview_label2.setStyleSheet('color: transparent') # fill the scroll area frame.setLayout(self._grid) scrollArea.setWidget(frame) group1_vbox.addWidget(scrollArea) # put groups on the dialog this_dialog_vbox.addWidget(group1) this_dialog_vbox.addWidget(group2) this_dialog_vbox.addWidget(group0) self._avoid_on_loading = self._modified = False def add_item(self, key, scheme): """Take key and scheme arguments and fill up the grid with widgets.""" row = self._grid.rowCount() self._grid.addWidget(QLabel(key), row, 0) isnum = isinstance(scheme[key], int) text = QLineEdit(str(scheme[key])) self._grid.addWidget(text, row, 1) if not isnum: btn = QPushButton() btn.setToolTip(translations.TR_EDITOR_SCHEME_PICK_COLOR) self.apply_button_style(btn, scheme[key]) self._grid.addWidget(btn, row, 2) self.connect(text, SIGNAL("textChanged(QString)"), lambda: self.apply_button_style(btn, text.text())) self.connect(btn, SIGNAL("clicked()"), lambda: self._pick_color(text, btn)) else: self.connect(text, SIGNAL("textChanged(QString)"), self._preview_style) self._components[key] = (text, isnum) def apply_button_style(self, btn, color_name): """Take a button widget and color name and apply as stylesheet.""" if QColor(color_name).isValid(): self._modified = True btn.setStyleSheet('background:' + color_name) self.preview_label1.setStyleSheet('background:' + color_name) self.preview_label2.setStyleSheet('color:' + color_name) self._preview_style() def _pick_color(self, lineedit, btn): """Pick a color name using lineedit and button data.""" color = QColorDialog.getColor(QColor(lineedit.text()), self, translations.TR_EDITOR_SCHEME_PICK_COLOR) if color.isValid(): lineedit.setText(str(color.name())) self.apply_button_style(btn, color.name()) def _preview_style(self): """Live preview style on editor.""" if self._avoid_on_loading: return scheme = {} keys = sorted(tuple(resources.COLOR_SCHEME.keys())) for key in keys: isnum = self._components[key][1] if isnum: num = self._components[key][0].text() if num.isdigit(): scheme[key] = int(num) else: scheme[key] = 0 else: scheme[key] = self._components[key][0].text() resources.CUSTOM_SCHEME = scheme editorWidget = self._get_editor() if editorWidget is not None: editorWidget.restyle(editorWidget.lang) editorWidget.highlight_current_line() return scheme def _get_editor(self): """Return current Editor.""" main_container = IDE.get_service("main_container") editorWidget = main_container.get_current_editor() return editorWidget def reject(self): """Reject this dialog.""" if self._modified: answer = QMessageBox.No answer = QMessageBox.question( self, translations.TR_PREFERENCES_EDITOR_SCHEME_DESIGNER, (translations.TR_IDE_CONFIRM_EXIT_TITLE + ".\n" + translations.TR_PREFERENCES_GENERAL_CONFIRM_EXIT + "?"), QMessageBox.Yes, QMessageBox.No) if answer == QMessageBox.No: return super(EditorSchemeDesigner, self).reject() def hideEvent(self, event): """Handle Hide event on this dialog.""" super(EditorSchemeDesigner, self).hideEvent(event) resources.CUSTOM_SCHEME = self.original_style editorWidget = self._get_editor() if editorWidget is not None: editorWidget.restyle(editorWidget.lang) 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') def save_scheme(self): """Save current scheme.""" name = self.line_name.text().strip() if not self._is_valid_scheme_name(name): QMessageBox.information( self, translations.TR_PREFERENCES_EDITOR_SCHEME_DESIGNER, translations.TR_SCHEME_INVALID_NAME) return fileName = ('{0}.color'.format( file_manager.create_path(resources.EDITOR_SKINS, name))) answer = True if file_manager.file_exists(fileName): answer = QMessageBox.question( self, translations.TR_PREFERENCES_EDITOR_SCHEME_DESIGNER, translations.TR_WANT_OVERWRITE_FILE + ": {0}?".format(fileName), QMessageBox.Yes, QMessageBox.No) if answer in (QMessageBox.Yes, True): scheme = self._preview_style() self.original_style = copy.copy(scheme) json_manager.save_editor_skins(fileName, scheme) self._modified = False self.saved = True qsettings = IDE.ninja_settings() qsettings.setValue('preferences/editor/scheme', name) QMessageBox.information( self, translations.TR_PREFERENCES_EDITOR_SCHEME_DESIGNER, translations.TR_SCHEME_SAVED + ": {0}.".format(fileName)) self.close() elif answer == QMessageBox.Yes: QMessageBox.information( self, translations.TR_PREFERENCES_EDITOR_SCHEME_DESIGNER, translations.TR_INVALID_FILENAME)
class ManualInstallWidget(QWidget): """Manually Installed plugins widget""" def __init__(self, parent): super(ManualInstallWidget, self).__init__() self._parent = parent vbox = QVBoxLayout(self) form = QFormLayout() self._txtName = QLineEdit() self._txtName.setPlaceholderText('my_plugin') self._txtVersion = QLineEdit() self._txtVersion.setPlaceholderText('0.1') form.addRow(translations.TR_PROJECT_NAME, self._txtName) form.addRow(translations.TR_VERSION, self._txtVersion) vbox.addLayout(form) hPath = QHBoxLayout() self._txtFilePath = QLineEdit() self._txtFilePath.setPlaceholderText( os.path.join(os.path.expanduser('~'), 'full', 'path', 'to', 'plugin.zip')) self._btnFilePath = QPushButton(QIcon(":img/open"), '') self.completer, self.dirs = QCompleter(self), QDirModel(self) self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot) self.completer.setModel(self.dirs) self._txtFilePath.setCompleter(self.completer) hPath.addWidget(QLabel(translations.TR_FILENAME)) hPath.addWidget(self._txtFilePath) hPath.addWidget(self._btnFilePath) vbox.addLayout(hPath) vbox.addSpacerItem( QSpacerItem(0, 1, QSizePolicy.Expanding, QSizePolicy.Expanding)) hbox = QHBoxLayout() hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) self._btnInstall = QPushButton(translations.TR_INSTALL) hbox.addWidget(self._btnInstall) vbox.addLayout(hbox) #Signals self.connect(self._btnFilePath, SIGNAL("clicked()"), self._load_plugin_path) self.connect(self._btnInstall, SIGNAL("clicked()"), self.install_plugin) def _load_plugin_path(self): """Ask the user a plugin filename""" path = QFileDialog.getOpenFileName(self, translations.TR_SELECT_PLUGIN_PATH) if path: self._txtFilePath.setText(path) def install_plugin(self): """Install a plugin manually""" if self._txtFilePath.text() and self._txtName.text(): plug = [] plug.append(self._txtName.text()) plug.append(self._txtVersion.text()) plug.append('') plug.append('') plug.append('') plug.append(self._txtFilePath.text()) self._parent.install_plugins_manually([plug])
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')