class PopupCompleter(QFrame): def __init__(self): QFrame.__init__(self, None, Qt.FramelessWindowHint | Qt.ToolTip) vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self.listWidget = QListWidget() self.listWidget.setMinimumHeight(300) vbox.addWidget(self.listWidget) def reload(self, model): """Reload the data of the Popup Completer, and restart the state.""" self.listWidget.clear() self.add_help() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) self.listWidget.setCurrentRow(6) def clear(self): """Remove all the items of the list (deleted), and reload the help.""" self.listWidget.clear() def refresh(self, model): """Refresh the list when the user search for some word.""" self.listWidget.clear() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) if model: self.listWidget.setCurrentItem(model[0][0]) def fetch_more(self, model): """Add more items to the list on user scroll.""" for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) def add_help(self): #Load help fileItem = QListWidgetItem( QIcon(resources.IMAGES['locate-file']), '@\t(Filter only by Files)') font = fileItem.font() font.setBold(True) fileItem.setSizeHint(QSize(20, 30)) fileItem.setBackground(QBrush(Qt.lightGray)) fileItem.setForeground(QBrush(Qt.black)) fileItem.setFont(font) self.listWidget.addItem(fileItem) classItem = QListWidgetItem( QIcon(resources.IMAGES['locate-class']), '<\t(Filter only by Classes)') self.listWidget.addItem(classItem) classItem.setSizeHint(QSize(20, 30)) classItem.setBackground(QBrush(Qt.lightGray)) classItem.setForeground(QBrush(Qt.black)) classItem.setFont(font) methodItem = QListWidgetItem( QIcon(resources.IMAGES['locate-function']), '>\t(Filter only by Methods)') self.listWidget.addItem(methodItem) methodItem.setSizeHint(QSize(20, 30)) methodItem.setBackground(QBrush(Qt.lightGray)) methodItem.setForeground(QBrush(Qt.black)) methodItem.setFont(font) attributeItem = QListWidgetItem( QIcon(resources.IMAGES['locate-attributes']), '-\t(Filter only by Attributes)') self.listWidget.addItem(attributeItem) attributeItem.setSizeHint(QSize(20, 30)) attributeItem.setBackground(QBrush(Qt.lightGray)) attributeItem.setForeground(QBrush(Qt.black)) attributeItem.setFont(font) thisFileItem = QListWidgetItem( QIcon(resources.IMAGES['locate-on-this-file']), '.\t(Filter only by Classes and Methods in this File)') font = thisFileItem.font() font.setBold(True) thisFileItem.setSizeHint(QSize(20, 30)) thisFileItem.setBackground(QBrush(Qt.lightGray)) thisFileItem.setForeground(QBrush(Qt.black)) thisFileItem.setFont(font) self.listWidget.addItem(thisFileItem) nonPythonItem = QListWidgetItem( QIcon(resources.IMAGES['locate-nonpython']), '!\t(Filter only by Non Python Files)') self.listWidget.addItem(nonPythonItem) nonPythonItem.setSizeHint(QSize(20, 30)) nonPythonItem.setBackground(QBrush(Qt.lightGray)) nonPythonItem.setForeground(QBrush(Qt.black)) nonPythonItem.setFont(font)
class EditorGeneral(QWidget): def __init__(self, main): QWidget.__init__(self) self._main = main vbox = QVBoxLayout(self) groupBoxTypo = QGroupBox('Typography:') groupBoxScheme = QGroupBox('Scheme Color:') #Settings settings = QSettings() settings.beginGroup('preferences') settings.beginGroup('editor') #Typo gridTypo = QGridLayout(groupBoxTypo) self.btnEditorFont = QPushButton(settings.value('font', 'Monospace, 11').toString()) gridTypo.addWidget(QLabel('Editor Font:'), 0, 0, Qt.AlignRight) gridTypo.addWidget(self.btnEditorFont, 0, 1) #Scheme hbox = QHBoxLayout(groupBoxScheme) self.listScheme = QListWidget() self.listScheme.addItem('default') self.schemes = loader.load_editor_skins() for item in self.schemes: self.listScheme.addItem(item) items = self.listScheme.findItems(settings.value('scheme', '').toString(), Qt.MatchExactly) if items: self.listScheme.setCurrentItem(items[0]) else: self.listScheme.setCurrentRow(0) hbox.addWidget(self.listScheme) settings.endGroup() settings.endGroup() vbox.addWidget(groupBoxTypo) vbox.addWidget(groupBoxScheme) vbox.addWidget(QLabel('Scheme Color requires restart.')) #Signals self.connect(self.btnEditorFont, SIGNAL("clicked()"), self._load_editor_font) def _load_editor_font(self): font = self._load_font(self._get_font_from_string(self.btnEditorFont.text()), self) self.btnEditorFont.setText(font) def _get_font_from_string(self, font): if (font.isEmpty()): return QFont("Monospace", 11) listFont = font.remove(' ').split(',') return QFont(listFont[0], listFont[1].toInt()[0]) def _load_font(self, initialFont, parent=0): font, ok = QFontDialog.getFont(initialFont, parent) if ok: newFont = font.toString().split(',') return newFont[0] + ', ' + newFont[1] else: return initialFont def save(self): settings = QSettings() settings.beginGroup('preferences') settings.beginGroup('editor') settings.setValue('font', self.btnEditorFont.text()) editor = self._main._central.obtain_editor() editor.set_font(self._get_font_from_string(self.btnEditorFont.text())) settings.setValue('scheme', self.listScheme.currentItem().text()) settings.endGroup() settings.endGroup()
class EditorGeneral(QWidget): def __init__(self, parent): super(EditorGeneral, self).__init__() self._preferences = parent vbox = QVBoxLayout(self) self.original_style = copy.copy(resources.CUSTOM_SCHEME) self.current_scheme = 'default' groupBoxMini = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_MINIMAP) groupBoxTypo = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_TYPOGRAPHY) groupBoxScheme = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_SCHEME) #Minimap formMini = QGridLayout(groupBoxMini) self._checkShowMinimap = QCheckBox() self._spinMaxOpacity = QSpinBox() self._spinMaxOpacity.setMaximum(100) self._spinMaxOpacity.setMinimum(0) self._spinMinOpacity = QSpinBox() self._spinMinOpacity.setMaximum(100) self._spinMinOpacity.setMinimum(0) self._spinSize = QSpinBox() self._spinSize.setMaximum(100) self._spinSize.setMinimum(0) formMini.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_ENABLE_MINIMAP), 0, 0, Qt.AlignRight) formMini.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_MAX_OPACITY), 1, 0, Qt.AlignRight) formMini.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_MIN_OPACITY), 2, 0, Qt.AlignRight) formMini.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_AREA_MINIMAP), 3, 0, Qt.AlignRight) formMini.addWidget(self._checkShowMinimap, 0, 1) formMini.addWidget(self._spinMaxOpacity, 1, 1) formMini.addWidget(self._spinMinOpacity, 2, 1) formMini.addWidget(self._spinSize, 3, 1) #Typo gridTypo = QGridLayout(groupBoxTypo) self._btnEditorFont = QPushButton('') gridTypo.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_EDITOR_FONT), 0, 0, Qt.AlignRight) gridTypo.addWidget(self._btnEditorFont, 0, 1) #Scheme hbox = QHBoxLayout(groupBoxScheme) self._listScheme = QListWidget() hbox.addWidget(self._listScheme) vbox.addWidget(groupBoxMini) vbox.addWidget(groupBoxTypo) vbox.addWidget(groupBoxScheme) #Settings qsettings = IDE.ninja_settings() qsettings.beginGroup('preferences') qsettings.beginGroup('editor') self._checkShowMinimap.setChecked(settings.SHOW_MINIMAP) self._spinMaxOpacity.setValue(settings.MINIMAP_MAX_OPACITY * 100) self._spinMinOpacity.setValue(settings.MINIMAP_MIN_OPACITY * 100) self._spinSize.setValue(settings.SIZE_PROPORTION * 100) self._btnEditorFont.setText( ', '.join([settings.FONT_FAMILY, str(settings.FONT_SIZE)])) self._listScheme.clear() self._listScheme.addItem('default') self._schemes = json_manager.load_editor_skins() for item in self._schemes: self._listScheme.addItem(item) items = self._listScheme.findItems( qsettings.value('scheme', defaultValue='', type='QString'), Qt.MatchExactly) if items: self._listScheme.setCurrentItem(items[0]) else: self._listScheme.setCurrentRow(0) qsettings.endGroup() qsettings.endGroup() #Signals self.connect(self._btnEditorFont, SIGNAL("clicked()"), self._load_editor_font) self.connect(self._listScheme, SIGNAL("itemSelectionChanged()"), self._preview_style) self.connect(self._preferences, SIGNAL("savePreferences()"), self.save) def showEvent(self, event): super(EditorGeneral, self).showEvent(event) self.thread_callback = ui_tools.ThreadExecution(self._get_editor_skins) self.connect(self.thread_callback, SIGNAL("finished()"), self._show_editor_skins) self.thread_callback.start() def _get_editor_skins(self): qsettings = IDE.ninja_settings() qsettings.beginGroup('preferences') qsettings.beginGroup('editor') self._schemes = json_manager.load_editor_skins() self._selected_scheme = qsettings.value('scheme', defaultValue='', type='QString') qsettings.endGroup() qsettings.endGroup() def _show_editor_skins(self): self._listScheme.clear() self._listScheme.addItem('default') for item in self._schemes: self._listScheme.addItem(item) items = self._listScheme.findItems( self._selected_scheme, Qt.MatchExactly) if items: self._listScheme.setCurrentItem(items[0]) else: self._listScheme.setCurrentRow(0) self.thread_callback.wait() def hideEvent(self, event): super(EditorGeneral, self).hideEvent(event) resources.CUSTOM_SCHEME = self.original_style main_container = IDE.get_service('main_container') editorWidget = main_container.get_current_editor() if editorWidget is not None: editorWidget.restyle(editorWidget.lang) editorWidget._sidebarWidget.repaint() def _preview_style(self): scheme = self._listScheme.currentItem().text() if scheme == self.current_scheme: return main_container = IDE.get_service('main_container') editorWidget = main_container.get_current_editor() if editorWidget is not None: resources.CUSTOM_SCHEME = self._schemes.get(scheme, resources.COLOR_SCHEME) editorWidget.restyle(editorWidget.lang) editorWidget._sidebarWidget.repaint() self.current_scheme = scheme def _load_editor_font(self): try: font = self._load_font( self._get_font_from_string(self._btnEditorFont.text()), self) self._btnEditorFont.setText(font) except: QMessageBox.warning(self, translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_TITLE, translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_BODY) def _get_font_from_string(self, font): if not font: font = QFont(settings.FONT_FAMILY, settings.FONT_SIZE) else: listFont = font.split(',') font = QFont(listFont[0].strip(), int(listFont[1].strip())) return font def _load_font(self, initialFont, parent=0): font, ok = QFontDialog.getFont(initialFont, parent) if ok: newFont = font.toString().split(',') else: newFont = initialFont.toString().split(',') return newFont[0] + ', ' + newFont[1] def save(self): qsettings = IDE.ninja_settings() settings.SHOW_MINIMAP = self._checkShowMinimap.isChecked() settings.MINIMAP_MAX_OPACITY = self._spinMaxOpacity.value() / 100.0 settings.MINIMAP_MIN_OPACITY = self._spinMinOpacity.value() / 100.0 settings.SIZE_PROPORTION = self._spinSize.value() / 100.0 qsettings.setValue('preferences/editor/minimapShow', settings.SHOW_MINIMAP) qsettings.setValue('preferences/editor/minimapMaxOpacity', settings.MINIMAP_MAX_OPACITY) qsettings.setValue('preferences/editor/minimapMinOpacity', settings.MINIMAP_MIN_OPACITY) qsettings.setValue('preferences/editor/minimapSizeProportion', settings.SIZE_PROPORTION) fontText = self._btnEditorFont.text().replace(' ', '') settings.FONT_FAMILY = fontText.split(',')[0] settings.FONT_SIZE = int(fontText.split(',')[1]) qsettings.setValue('preferences/editor/fontFamily', settings.FONT_FAMILY) qsettings.setValue('preferences/editor/fontSize', settings.FONT_SIZE) scheme = self._listScheme.currentItem().text() self.original_style = resources.CUSTOM_SCHEME qsettings.setValue('preferences/editor/scheme', scheme) resources.CUSTOM_SCHEME = self._schemes.get(scheme, resources.COLOR_SCHEME)
class PopupCompleter(QFrame): def __init__(self): QFrame.__init__(self, None, Qt.FramelessWindowHint | Qt.ToolTip) vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self.listWidget = QListWidget() self.listWidget.setMinimumHeight(350) vbox.addWidget(self.listWidget) self.listWidget.currentItemChanged.connect(self._repaint_items) def _repaint_items(self, current, previous): if current is not None: widget = self.listWidget.itemWidget(current) if widget is not None: widget.set_selected() if previous is not None: widget = self.listWidget.itemWidget(previous) if widget is not None: widget.set_not_selected() def reload(self, model): """Reload the data of the Popup Completer, and restart the state.""" self.listWidget.clear() self.add_help() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) self.listWidget.setCurrentRow(8) def clear(self): """Remove all the items of the list (deleted), and reload the help.""" self.listWidget.clear() def refresh(self, model, has_text=True): """Refresh the list when the user search for some word.""" self.listWidget.clear() if not has_text: self.add_help() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) if model: self.listWidget.setCurrentItem(model[0][0]) else: self.add_no_found() def fetch_more(self, model): """Add more items to the list on user scroll.""" for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) def add_no_found(self): """Load no results found message""" noFoundItem = self._create_help_item(resources.IMAGES['delete'], translations.TR_NO_RESULTS) self.listWidget.addItem(noFoundItem) def add_help(self): #Load help fileItem = self._create_help_item(resources.IMAGES['locate-file'], translations.TR_ONLY_FILES) self.listWidget.addItem(fileItem) classItem = self._create_help_item(resources.IMAGES['locate-class'], translations.TR_ONLY_CLASSES) self.listWidget.addItem(classItem) methodItem = self._create_help_item( resources.IMAGES['locate-function'], translations.TR_ONLY_METHODS) self.listWidget.addItem(methodItem) attributeItem = self._create_help_item( resources.IMAGES['locate-attributes'], translations.TR_ONLY_ATRIBUTES) self.listWidget.addItem(attributeItem) thisFileItem = self._create_help_item( resources.IMAGES['locate-on-this-file'], translations.TR_ONLY_CLASSES_METHODS) self.listWidget.addItem(thisFileItem) tabsItem = self._create_help_item(resources.IMAGES['locate-tab'], translations.TR_ONLY_CURRENT_TABS) self.listWidget.addItem(tabsItem) lineItem = self._create_help_item(resources.IMAGES['locate-line'], translations.TR_GO_TO_LINE) self.listWidget.addItem(lineItem) nonPythonItem = self._create_help_item( resources.IMAGES['locate-nonpython'], translations.TR_ONLY_NON_PYTHON) self.listWidget.addItem(nonPythonItem) def _create_help_item(self, image, text): Item = QListWidgetItem(QIcon(image), text) font = Item.font() font.setBold(True) Item.setSizeHint(QSize(20, 30)) Item.setBackground(QBrush(Qt.lightGray)) Item.setForeground(QBrush(Qt.black)) Item.setFont(font) return Item
class EditorGeneral(QWidget): def __init__(self, main): QWidget.__init__(self) self._main = main vbox = QVBoxLayout(self) groupBoxTypo = QGroupBox('Typography:') groupBoxScheme = QGroupBox('Scheme Color:') #Settings settings = QSettings() settings.beginGroup('preferences') settings.beginGroup('editor') #Typo gridTypo = QGridLayout(groupBoxTypo) self.btnEditorFont = QPushButton( settings.value('font', 'Monospace, 11').toString()) gridTypo.addWidget(QLabel('Editor Font:'), 0, 0, Qt.AlignRight) gridTypo.addWidget(self.btnEditorFont, 0, 1) #Scheme hbox = QHBoxLayout(groupBoxScheme) self.listScheme = QListWidget() self.listScheme.addItem('default') self.schemes = loader.load_editor_skins() for item in self.schemes: self.listScheme.addItem(item) items = self.listScheme.findItems( settings.value('scheme', '').toString(), Qt.MatchExactly) if items: self.listScheme.setCurrentItem(items[0]) else: self.listScheme.setCurrentRow(0) hbox.addWidget(self.listScheme) settings.endGroup() settings.endGroup() vbox.addWidget(groupBoxTypo) vbox.addWidget(groupBoxScheme) vbox.addWidget(QLabel('Scheme Color requires restart.')) #Signals self.connect(self.btnEditorFont, SIGNAL("clicked()"), self._load_editor_font) def _load_editor_font(self): font = self._load_font( self._get_font_from_string(self.btnEditorFont.text()), self) self.btnEditorFont.setText(font) def _get_font_from_string(self, font): if (font.isEmpty()): return QFont("Monospace", 11) listFont = font.remove(' ').split(',') return QFont(listFont[0], listFont[1].toInt()[0]) def _load_font(self, initialFont, parent=0): font, ok = QFontDialog.getFont(initialFont, parent) if ok: newFont = font.toString().split(',') return newFont[0] + ', ' + newFont[1] else: return initialFont def save(self): settings = QSettings() settings.beginGroup('preferences') settings.beginGroup('editor') settings.setValue('font', self.btnEditorFont.text()) editor = self._main._central.obtain_editor() editor.set_font(self._get_font_from_string(self.btnEditorFont.text())) settings.setValue('scheme', self.listScheme.currentItem().text()) settings.endGroup() settings.endGroup()
class StringListDlg(QDialog): acceptedList = Signal(QStringList) def __init__(self, name, stringlist=None, parent=None): super(StringListDlg, self).__init__(parent) self.name = name self.create_widgets(stringlist) self.layout_widgets() self.setWindowTitle("Edit {0} List".format(self.name)) def create_widgets(self, stringlist): self.listWidget = QListWidget() if stringlist is not None: self.listWidget.addItems(stringlist) self.listWidget.setCurrentRow(0) def layout_widgets(self): buttonLayout = QVBoxLayout() for text, slot in (("&Add...", self.add), ("&Edit...", self.edit), ("&Remove...", self.remove), ("&Up", self.up), ("&Down", self.down), ("&Sort", self.listWidget.sortItems), ("Close", self.accept)): button = QPushButton(text) if not MAC: button.setFocusPolicy(Qt.NoFocus) if text == "Close": buttonLayout.addStretch() buttonLayout.addWidget(button) button.clicked.connect(slot) layout = QHBoxLayout() layout.addWidget(self.listWidget) layout.addLayout(buttonLayout) self.setLayout(layout) def add(self): row = self.listWidget.currentRow() title = "Add {0}".format(self.name) string, ok = QInputDialog.getText(self, title, title) if ok and not string.isEmpty(): self.listWidget.insertItem(row, string) def edit(self): row = self.listWidget.currentRow() item = self.listWidget.item(row) if item is not None: title = "Edit {0}".format(self.name) string, ok = QInputDialog.getText(self, title, title, QLineEdit.Normal, item.text()) if ok and not string.isEmpty(): item.setText(string) def remove(self): row = self.listWidget.currentRow() item = self.listWidget.item(row) if item is None: return reply = QMessageBox.question( self, "Remove {0}".format(self.name), "Remove {0} `{1}'?".format(self.name, unicode(item.text())), QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: item = self.listWidget.takeItem(row) del item def up(self): row = self.listWidget.currentRow() if row >= 1: item = self.listWidget.takeItem(row) self.listWidget.insertItem(row - 1, item) self.listWidget.setCurrentItem(item) def down(self): row = self.listWidget.currentRow() if row < self.listWidget.count() - 1: item = self.listWidget.takeItem(row) self.listWidget.insertItem(row + 1, item) self.listWidget.setCurrentItem(item) def reject(self): self.accept() def accept(self): self.stringlist = QStringList() for row in range(self.listWidget.count()): self.stringlist.append(self.listWidget.item(row).text()) self.acceptedList.emit(self.stringlist) QDialog.accept(self)
class EditorGeneral(QWidget): def __init__(self): QWidget.__init__(self) vbox = QVBoxLayout(self) groupBoxTypo = QGroupBox(self.tr("Typography:")) groupBoxScheme = QGroupBox(self.tr("Scheme Color:")) #Settings qsettings = QSettings() qsettings.beginGroup('preferences') qsettings.beginGroup('editor') #Typo gridTypo = QGridLayout(groupBoxTypo) self._btnEditorFont = QPushButton( ', '.join([settings.FONT_FAMILY, str(settings.FONT_SIZE)])) gridTypo.addWidget(QLabel( self.tr("Editor Font:")), 0, 0, Qt.AlignRight) gridTypo.addWidget(self._btnEditorFont, 0, 1) #Scheme hbox = QHBoxLayout(groupBoxScheme) self._listScheme = QListWidget() self._listScheme.addItem('default') self._schemes = json_manager.load_editor_skins() for item in self._schemes: self._listScheme.addItem(item) items = self._listScheme.findItems( qsettings.value('scheme', '').toString(), Qt.MatchExactly) if items: self._listScheme.setCurrentItem(items[0]) else: self._listScheme.setCurrentRow(0) hbox.addWidget(self._listScheme) qsettings.endGroup() qsettings.endGroup() vbox.addWidget(groupBoxTypo) vbox.addWidget(groupBoxScheme) #Signals self.connect(self._btnEditorFont, SIGNAL("clicked()"), self._load_editor_font) def _load_editor_font(self): try: font = self._load_font( self._get_font_from_string(self._btnEditorFont.text()), self) self._btnEditorFont.setText(font) except: QMessageBox.warning(self, self.tr("Invalid Font"), self.tr("This font can not be used in the Editor.")) def _get_font_from_string(self, font): if (font.isEmpty()): return QFont(settings.FONT_FAMILY, settings.FONT_SIZE) listFont = font.remove(' ').split(',') return QFont(listFont[0], listFont[1].toInt()[0]) def _load_font(self, initialFont, parent=0): font, ok = QFontDialog.getFont(initialFont, parent) if ok: newFont = font.toString().split(',') return newFont[0] + ', ' + newFont[1] else: return initialFont def save(self): qsettings = QSettings() qsettings.beginGroup('preferences') qsettings.beginGroup('editor') fontText = unicode(self._btnEditorFont.text().remove(' ')) settings.FONT_FAMILY = fontText.split(',')[0] settings.FONT_SIZE = int(fontText.split(',')[1]) qsettings.setValue('fontFamily', settings.FONT_FAMILY) qsettings.setValue('fontSize', settings.FONT_SIZE) editorWidget = main_container.MainContainer().get_actual_editor() scheme = unicode(self._listScheme.currentItem().text()) if type(editorWidget) == editor.Editor: editorWidget.set_font(settings.FONT_FAMILY, settings.FONT_SIZE) qsettings.setValue('scheme', scheme) resources.CUSTOM_SCHEME = self._schemes.get(scheme, resources.COLOR_SCHEME) qsettings.endGroup() qsettings.endGroup() main_container.MainContainer().apply_editor_theme(settings.FONT_FAMILY, settings.FONT_SIZE) misc_container.MiscContainer()._console.restyle()
class EditorGeneral(QWidget): """EditorGeneral widget class.""" def __init__(self, parent): super(EditorGeneral, self).__init__() self._preferences, vbox = parent, QVBoxLayout(self) self.original_style = copy.copy(resources.CUSTOM_SCHEME) self.current_scheme, self._modified_editors = 'default', [] self._font = settings.FONT groupBoxMini = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_MINIMAP) groupBoxTypo = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_TYPOGRAPHY) groupBoxScheme = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_SCHEME) #Minimap formMini = QGridLayout(groupBoxMini) formMini.setContentsMargins(5, 15, 5, 5) self._checkShowMinimap = QCheckBox( translations.TR_PREFERENCES_EDITOR_GENERAL_ENABLE_MINIMAP) self._spinMaxOpacity = QSpinBox() self._spinMaxOpacity.setRange(0, 100) self._spinMaxOpacity.setSuffix("% Max.") self._spinMinOpacity = QSpinBox() self._spinMinOpacity.setRange(0, 100) self._spinMinOpacity.setSuffix("% Min.") self._spinSize = QSpinBox() self._spinSize.setMaximum(100) self._spinSize.setMinimum(0) self._spinSize.setSuffix( translations.TR_PREFERENCES_EDITOR_GENERAL_AREA_MINIMAP) formMini.addWidget(self._checkShowMinimap, 0, 1) formMini.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_SIZE_MINIMAP), 1, 0, Qt.AlignRight) formMini.addWidget(self._spinSize, 1, 1) formMini.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_OPACITY), 2, 0, Qt.AlignRight) formMini.addWidget(self._spinMinOpacity, 2, 1) formMini.addWidget(self._spinMaxOpacity, 2, 2) #Typo gridTypo = QGridLayout(groupBoxTypo) gridTypo.setContentsMargins(5, 15, 5, 5) self._btnEditorFont = QPushButton('') gridTypo.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_EDITOR_FONT), 0, 0, Qt.AlignRight) gridTypo.addWidget(self._btnEditorFont, 0, 1) #Scheme vboxScheme = QVBoxLayout(groupBoxScheme) vboxScheme.setContentsMargins(5, 15, 5, 5) self._listScheme = QListWidget() vboxScheme.addWidget(self._listScheme) hbox = QHBoxLayout() btnDownload = QPushButton( translations.TR_PREFERENCES_EDITOR_DOWNLOAD_SCHEME) btnDownload.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.connect(btnDownload, SIGNAL("clicked()"), self._open_schemes_manager) hbox.addWidget(btnDownload) btnAdd = QPushButton(QIcon(":img/add"), translations.TR_EDITOR_CREATE_SCHEME) btnAdd.setIconSize(QSize(16, 16)) btnAdd.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.connect(btnAdd, SIGNAL("clicked()"), self._open_schemes_designer) btnRemove = QPushButton(QIcon(":img/delete"), translations.TR_EDITOR_REMOVE_SCHEME) btnRemove.setIconSize(QSize(16, 16)) btnRemove.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.connect(btnRemove, SIGNAL("clicked()"), self._remove_scheme) hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox.addWidget(btnAdd) hbox.addWidget(btnRemove) vboxScheme.addLayout(hbox) vbox.addWidget(groupBoxMini) vbox.addWidget(groupBoxTypo) vbox.addWidget(groupBoxScheme) #Settings qsettings = IDE.ninja_settings() qsettings.beginGroup('preferences') qsettings.beginGroup('editor') self._checkShowMinimap.setChecked(settings.SHOW_MINIMAP) if settings.IS_MAC_OS: self._spinMinOpacity.setValue(100) self._spinMaxOpacity.setValue(100) self._spinMinOpacity.setDisabled(True) self._spinMaxOpacity.setDisabled(True) else: self._spinMinOpacity.setValue(settings.MINIMAP_MIN_OPACITY * 100) self._spinMaxOpacity.setValue(settings.MINIMAP_MAX_OPACITY * 100) self._spinSize.setValue(settings.SIZE_PROPORTION * 100) btnText = ', '.join(self._font.toString().split(',')[0:2]) self._btnEditorFont.setText(btnText) self._listScheme.clear() self._listScheme.addItem('default') self._schemes = json_manager.load_editor_skins() for item in self._schemes: self._listScheme.addItem(item) items = self._listScheme.findItems( qsettings.value('scheme', defaultValue='', type='QString'), Qt.MatchExactly) if items: self._listScheme.setCurrentItem(items[0]) else: self._listScheme.setCurrentRow(0) qsettings.endGroup() qsettings.endGroup() #Signals self.connect(self._btnEditorFont, SIGNAL("clicked()"), self._load_editor_font) self.connect(self._listScheme, SIGNAL("itemSelectionChanged()"), self._preview_style) self.connect(self._preferences, SIGNAL("savePreferences()"), self.save) def _open_schemes_manager(self): ninjaide = IDE.get_service("ide") ninjaide.show_schemes() # refresh schemes def _open_schemes_designer(self): name = self._listScheme.currentItem().text() scheme = self._schemes.get(name, resources.COLOR_SCHEME) designer = preferences_editor_scheme_designer.EditorSchemeDesigner( scheme, self) designer.exec_() if designer.saved: scheme_name = designer.line_name.text() scheme = designer.original_style self._schemes[scheme_name] = scheme result = self._listScheme.findItems(scheme_name, Qt.MatchExactly) if not result: self._listScheme.addItem(scheme_name) def _remove_scheme(self): name = self._listScheme.currentItem().text() fileName = ('{0}.color'.format( file_manager.create_path(resources.EDITOR_SKINS, name))) file_manager.delete_file(fileName) item = self._listScheme.takeItem(self._listScheme.currentRow()) del item def hideEvent(self, event): super(EditorGeneral, self).hideEvent(event) resources.CUSTOM_SCHEME = self.original_style for editorWidget in self._modified_editors: try: editorWidget.restyle(editorWidget.lang) except RuntimeError: print('the editor has been removed') def _preview_style(self): scheme = self._listScheme.currentItem().text() if scheme == self.current_scheme: return main_container = IDE.get_service('main_container') if not main_container: return editorWidget = main_container.get_current_editor() if editorWidget is not None: resources.CUSTOM_SCHEME = self._schemes.get( scheme, resources.COLOR_SCHEME) editorWidget.restyle(editorWidget.lang) self._modified_editors.append(editorWidget) self.current_scheme = scheme def _load_editor_font(self): try: font, ok = QFontDialog.getFont(self._font, self) if ok: self._font = font btnText = ', '.join(self._font.toString().split(',')[0:2]) self._btnEditorFont.setText(btnText) except: QMessageBox.warning( self, translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_TITLE, translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_BODY) def save(self): qsettings = IDE.ninja_settings() settings.FONT = self._font qsettings.setValue('preferences/editor/font', settings.FONT) settings.SHOW_MINIMAP = self._checkShowMinimap.isChecked() settings.MINIMAP_MAX_OPACITY = self._spinMaxOpacity.value() / 100.0 settings.MINIMAP_MIN_OPACITY = self._spinMinOpacity.value() / 100.0 settings.SIZE_PROPORTION = self._spinSize.value() / 100.0 qsettings.setValue('preferences/editor/minimapMaxOpacity', settings.MINIMAP_MAX_OPACITY) qsettings.setValue('preferences/editor/minimapMinOpacity', settings.MINIMAP_MIN_OPACITY) qsettings.setValue('preferences/editor/minimapSizeProportion', settings.SIZE_PROPORTION) qsettings.setValue('preferences/editor/minimapShow', settings.SHOW_MINIMAP) scheme = self._listScheme.currentItem().text() resources.CUSTOM_SCHEME = self._schemes.get(scheme, resources.COLOR_SCHEME) qsettings.setValue('preferences/editor/scheme', scheme)
class EditorGeneral(QWidget): def __init__(self, parent): super(EditorGeneral, self).__init__() self._preferences = parent vbox = QVBoxLayout(self) self.original_style = copy.copy(resources.CUSTOM_SCHEME) self.current_scheme = 'default' groupBoxMini = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_MINIMAP) groupBoxTypo = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_TYPOGRAPHY) groupBoxScheme = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_SCHEME) #Minimap formMini = QGridLayout(groupBoxMini) self._checkShowMinimap = QCheckBox() self._spinMaxOpacity = QSpinBox() self._spinMaxOpacity.setMaximum(100) self._spinMaxOpacity.setMinimum(0) self._spinMinOpacity = QSpinBox() self._spinMinOpacity.setMaximum(100) self._spinMinOpacity.setMinimum(0) self._spinSize = QSpinBox() self._spinSize.setMaximum(100) self._spinSize.setMinimum(0) formMini.addWidget( QLabel(translations.TR_PREFERENCES_EDITOR_GENERAL_ENABLE_MINIMAP), 0, 0, Qt.AlignRight) formMini.addWidget( QLabel(translations.TR_PREFERENCES_EDITOR_GENERAL_MAX_OPACITY), 1, 0, Qt.AlignRight) formMini.addWidget( QLabel(translations.TR_PREFERENCES_EDITOR_GENERAL_MIN_OPACITY), 2, 0, Qt.AlignRight) formMini.addWidget( QLabel(translations.TR_PREFERENCES_EDITOR_GENERAL_AREA_MINIMAP), 3, 0, Qt.AlignRight) formMini.addWidget(self._checkShowMinimap, 0, 1) formMini.addWidget(self._spinMaxOpacity, 1, 1) formMini.addWidget(self._spinMinOpacity, 2, 1) formMini.addWidget(self._spinSize, 3, 1) #Typo gridTypo = QGridLayout(groupBoxTypo) self._btnEditorFont = QPushButton('') gridTypo.addWidget( QLabel(translations.TR_PREFERENCES_EDITOR_GENERAL_EDITOR_FONT), 0, 0, Qt.AlignRight) gridTypo.addWidget(self._btnEditorFont, 0, 1) #Scheme hbox = QHBoxLayout(groupBoxScheme) self._listScheme = QListWidget() hbox.addWidget(self._listScheme) vbox.addWidget(groupBoxMini) vbox.addWidget(groupBoxTypo) vbox.addWidget(groupBoxScheme) #Settings qsettings = IDE.ninja_settings() qsettings.beginGroup('preferences') qsettings.beginGroup('editor') self._checkShowMinimap.setChecked(settings.SHOW_MINIMAP) self._spinMaxOpacity.setValue(settings.MINIMAP_MAX_OPACITY * 100) self._spinMinOpacity.setValue(settings.MINIMAP_MIN_OPACITY * 100) self._spinSize.setValue(settings.SIZE_PROPORTION * 100) self._btnEditorFont.setText(', '.join( [settings.FONT_FAMILY, str(settings.FONT_SIZE)])) self._listScheme.clear() self._listScheme.addItem('default') self._schemes = json_manager.load_editor_skins() for item in self._schemes: self._listScheme.addItem(item) items = self._listScheme.findItems( qsettings.value('scheme', defaultValue='', type='QString'), Qt.MatchExactly) if items: self._listScheme.setCurrentItem(items[0]) else: self._listScheme.setCurrentRow(0) qsettings.endGroup() qsettings.endGroup() #Signals self.connect(self._btnEditorFont, SIGNAL("clicked()"), self._load_editor_font) self.connect(self._listScheme, SIGNAL("itemSelectionChanged()"), self._preview_style) self.connect(self._preferences, SIGNAL("savePreferences()"), self.save) def showEvent(self, event): super(EditorGeneral, self).showEvent(event) self.thread_callback = ui_tools.ThreadExecution(self._get_editor_skins) self.connect(self.thread_callback, SIGNAL("finished()"), self._show_editor_skins) self.thread_callback.start() def _get_editor_skins(self): qsettings = IDE.ninja_settings() qsettings.beginGroup('preferences') qsettings.beginGroup('editor') self._schemes = json_manager.load_editor_skins() self._selected_scheme = qsettings.value('scheme', defaultValue='', type='QString') qsettings.endGroup() qsettings.endGroup() def _show_editor_skins(self): self._listScheme.clear() self._listScheme.addItem('default') for item in self._schemes: self._listScheme.addItem(item) items = self._listScheme.findItems(self._selected_scheme, Qt.MatchExactly) if items: self._listScheme.setCurrentItem(items[0]) else: self._listScheme.setCurrentRow(0) self.thread_callback.wait() def hideEvent(self, event): super(EditorGeneral, self).hideEvent(event) resources.CUSTOM_SCHEME = self.original_style main_container = IDE.get_service('main_container') editorWidget = main_container.get_current_editor() if editorWidget is not None: editorWidget.restyle(editorWidget.lang) editorWidget._sidebarWidget.repaint() def _preview_style(self): scheme = self._listScheme.currentItem().text() if scheme == self.current_scheme: return main_container = IDE.get_service('main_container') editorWidget = main_container.get_current_editor() if editorWidget is not None: resources.CUSTOM_SCHEME = self._schemes.get( scheme, resources.COLOR_SCHEME) editorWidget.restyle(editorWidget.lang) editorWidget._sidebarWidget.repaint() self.current_scheme = scheme def _load_editor_font(self): try: font = self._load_font( self._get_font_from_string(self._btnEditorFont.text()), self) self._btnEditorFont.setText(font) except: QMessageBox.warning( self, translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_TITLE, translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_BODY) def _get_font_from_string(self, font): if not font: font = QFont(settings.FONT_FAMILY, settings.FONT_SIZE) else: listFont = font.split(',') font = QFont(listFont[0].strip(), int(listFont[1].strip())) return font def _load_font(self, initialFont, parent=0): font, ok = QFontDialog.getFont(initialFont, parent) if ok: newFont = font.toString().split(',') else: newFont = initialFont.toString().split(',') return newFont[0] + ', ' + newFont[1] def save(self): qsettings = IDE.ninja_settings() settings.SHOW_MINIMAP = self._checkShowMinimap.isChecked() settings.MINIMAP_MAX_OPACITY = self._spinMaxOpacity.value() / 100.0 settings.MINIMAP_MIN_OPACITY = self._spinMinOpacity.value() / 100.0 settings.SIZE_PROPORTION = self._spinSize.value() / 100.0 qsettings.setValue('preferences/editor/minimapShow', settings.SHOW_MINIMAP) qsettings.setValue('preferences/editor/minimapMaxOpacity', settings.MINIMAP_MAX_OPACITY) qsettings.setValue('preferences/editor/minimapMinOpacity', settings.MINIMAP_MIN_OPACITY) qsettings.setValue('preferences/editor/minimapSizeProportion', settings.SIZE_PROPORTION) fontText = self._btnEditorFont.text().replace(' ', '') settings.FONT_FAMILY = fontText.split(',')[0] settings.FONT_SIZE = int(fontText.split(',')[1]) qsettings.setValue('preferences/editor/fontFamily', settings.FONT_FAMILY) qsettings.setValue('preferences/editor/fontSize', settings.FONT_SIZE) scheme = self._listScheme.currentItem().text() self.original_style = resources.CUSTOM_SCHEME qsettings.setValue('preferences/editor/scheme', scheme) resources.CUSTOM_SCHEME = self._schemes.get(scheme, resources.COLOR_SCHEME)
class CAT(QSplitter, Script): def __init__(self): Script.__init__(self, "cat") self.vfs = vfs.vfs() self.type = "cat" self.icon = None self.currentCodec = "UTF-8" def start(self, args): self.args = args try: self.node = args["file"].value() except: pass def g_display(self): QSplitter.__init__(self) self.offsets = self.linecount() self.initShape() self.read(0) def initShape(self): self.hbox = QHBoxLayout() self.hbox.setContentsMargins(0, 0, 0, 0) self.listWidget = QListWidget() self.listWidget.setSortingEnabled(True) for codec in QTextCodec.availableCodecs(): self.listWidget.addItem(str(codec)) item = self.listWidget.findItems('UTF-8', Qt.MatchExactly)[0] self.listWidget.setCurrentItem(item) self.listWidget.scrollToItem(item) textAreaWidget = QWidget() self.hbox.addWidget(self.listWidget) self.connect(self.listWidget, SIGNAL("itemSelectionChanged()"), self.codecChanged) self.scroll = Scroll(self) self.text = TextEdit(self) self.hbox.addWidget(self.text) self.hbox.addWidget(self.scroll) textAreaWidget.setLayout(self.hbox) self.addWidget(self.listWidget) self.addWidget(textAreaWidget) self.setStretchFactor(0, 0) self.setStretchFactor(1, 1) def codecChanged(self): self.currentCodec = self.listWidget.selectedItems()[0].text() self.read(self.scroll.value()) def read(self, line): self.vfile = self.node.open() padd = 0 if line > padd: padd = 1 self.vfile.seek(self.offsets[line] + padd) self.text.clear() codec = QTextCodec.codecForName(self.currentCodec) decoder = codec.makeDecoder() self.text.textCursor().insertText( decoder.toUnicode(self.vfile.read(1024 * 10))) self.text.moveCursor(QTextCursor.Start) self.vfile.close() def linecount(self): offsets = [0] self.vfile = self.node.open() offsets.extend(self.vfile.indexes('\n')) self.vfile.close() self.lines = len(offsets) return offsets def updateWidget(self): pass def c_display(self): file = self.node.open() fsize = self.node.size() size = 0 self.buff = "" while size < fsize: try: tmp = file.read(4096) except vfsError, e: print self.buff break if len(tmp) == 0: print tmp break size += len(tmp) self.buff += tmp print tmp file.close() if len(self.buff): return self.buff
class PopupCompleter(QFrame): def __init__(self): QFrame.__init__(self, None, Qt.FramelessWindowHint | Qt.ToolTip) vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self.listWidget = QListWidget() self.listWidget.setMinimumHeight(350) vbox.addWidget(self.listWidget) self.listWidget.currentItemChanged.connect(self._repaint_items) def _repaint_items(self, current, previous): if current is not None: widget = self.listWidget.itemWidget(current) if widget is not None: widget.set_selected() if previous is not None: widget = self.listWidget.itemWidget(previous) if widget is not None: widget.set_not_selected() def reload(self, model): """Reload the data of the Popup Completer, and restart the state.""" self.listWidget.clear() self.add_help() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) self.listWidget.setCurrentRow(8) def clear(self): """Remove all the items of the list (deleted), and reload the help.""" self.listWidget.clear() def refresh(self, model, has_text=True): """Refresh the list when the user search for some word.""" self.listWidget.clear() if not has_text: self.add_help() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) if model: self.listWidget.setCurrentItem(model[0][0]) else: self.add_no_found() def fetch_more(self, model): """Add more items to the list on user scroll.""" for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) def add_no_found(self): #Load no results found message noFoundItem = QListWidgetItem( QIcon(resources.IMAGES['delete']), 'No results were found!') font = noFoundItem.font() font.setBold(True) noFoundItem.setSizeHint(QSize(20, 30)) noFoundItem.setBackground(QBrush(Qt.lightGray)) noFoundItem.setForeground(QBrush(Qt.black)) noFoundItem.setFont(font) self.listWidget.addItem(noFoundItem) def add_help(self): #Load help fileItem = QListWidgetItem( QIcon(resources.IMAGES['locate-file']), '@\t(Filter only by Files)') font = fileItem.font() font.setBold(True) fileItem.setSizeHint(QSize(20, 30)) fileItem.setBackground(QBrush(Qt.lightGray)) fileItem.setForeground(QBrush(Qt.black)) fileItem.setFont(font) self.listWidget.addItem(fileItem) classItem = QListWidgetItem( QIcon(resources.IMAGES['locate-class']), '<\t(Filter only by Classes)') self.listWidget.addItem(classItem) classItem.setSizeHint(QSize(20, 30)) classItem.setBackground(QBrush(Qt.lightGray)) classItem.setForeground(QBrush(Qt.black)) classItem.setFont(font) methodItem = QListWidgetItem( QIcon(resources.IMAGES['locate-function']), '>\t(Filter only by Methods)') self.listWidget.addItem(methodItem) methodItem.setSizeHint(QSize(20, 30)) methodItem.setBackground(QBrush(Qt.lightGray)) methodItem.setForeground(QBrush(Qt.black)) methodItem.setFont(font) attributeItem = QListWidgetItem( QIcon(resources.IMAGES['locate-attributes']), '-\t(Filter only by Attributes)') self.listWidget.addItem(attributeItem) attributeItem.setSizeHint(QSize(20, 30)) attributeItem.setBackground(QBrush(Qt.lightGray)) attributeItem.setForeground(QBrush(Qt.black)) attributeItem.setFont(font) thisFileItem = QListWidgetItem( QIcon(resources.IMAGES['locate-on-this-file']), '.\t(Filter only by Classes and Methods in this File)') font = thisFileItem.font() font.setBold(True) thisFileItem.setSizeHint(QSize(20, 30)) thisFileItem.setBackground(QBrush(Qt.lightGray)) thisFileItem.setForeground(QBrush(Qt.black)) thisFileItem.setFont(font) self.listWidget.addItem(thisFileItem) tabsItem = QListWidgetItem( QIcon(resources.IMAGES['locate-tab']), '/\t(Filter only by the current Tabs)') font = tabsItem.font() font.setBold(True) tabsItem.setSizeHint(QSize(20, 30)) tabsItem.setBackground(QBrush(Qt.lightGray)) tabsItem.setForeground(QBrush(Qt.black)) tabsItem.setFont(font) self.listWidget.addItem(tabsItem) lineItem = QListWidgetItem( QIcon(resources.IMAGES['locate-line']), ':\t(Go to Line)') font = lineItem.font() font.setBold(True) lineItem.setSizeHint(QSize(20, 30)) lineItem.setBackground(QBrush(Qt.lightGray)) lineItem.setForeground(QBrush(Qt.black)) lineItem.setFont(font) self.listWidget.addItem(lineItem) nonPythonItem = QListWidgetItem( QIcon(resources.IMAGES['locate-nonpython']), '!\t(Filter only by Non Python Files)') self.listWidget.addItem(nonPythonItem) nonPythonItem.setSizeHint(QSize(20, 30)) nonPythonItem.setBackground(QBrush(Qt.lightGray)) nonPythonItem.setForeground(QBrush(Qt.black)) nonPythonItem.setFont(font)
class ListEdit(QWidget): """A widget to edit a list of items (e.g. a list of directories).""" # emitted when anything changed in the listbox. changed = pyqtSignal() def __init__(self, *args, **kwargs): QWidget.__init__(self, *args, **kwargs) layout = QGridLayout(self) self.setLayout(layout) self.addButton = QPushButton(icons.get('list-add'), '') self.editButton = QPushButton(icons.get('document-edit'), '') self.removeButton = QPushButton(icons.get('list-remove'), '') self.listBox = QListWidget() layout.setContentsMargins(1, 1, 1, 1) layout.setSpacing(0) layout.addWidget(self.listBox, 0, 0, 8, 1) layout.addWidget(self.addButton, 0, 1) layout.addWidget(self.editButton, 1, 1) layout.addWidget(self.removeButton, 2, 1) @self.addButton.clicked.connect def addClicked(): item = self.createItem() if self.openEditor(item): self.addItem(item) @self.editButton.clicked.connect def editClicked(): item = self.listBox.currentItem() item and self.editItem(item) @self.removeButton.clicked.connect def removeClicked(): item = self.listBox.currentItem() if item: self.removeItem(item) @self.listBox.itemDoubleClicked.connect def itemDoubleClicked(item): item and self.editItem(item) self.listBox.model().layoutChanged.connect(self.changed) def updateSelection(): selected = bool(self.listBox.currentItem()) self.editButton.setEnabled(selected) self.removeButton.setEnabled(selected) self.changed.connect(updateSelection) self.listBox.itemSelectionChanged.connect(updateSelection) updateSelection() app.translateUI(self) def translateUI(self): self.addButton.setText(_("&Add...")) self.editButton.setText(_("&Edit...")) self.removeButton.setText(_("&Remove")) def createItem(self): return QListWidgetItem() def addItem(self, item): self.listBox.addItem(item) self.itemChanged(item) self.changed.emit() def removeItem(self, item): self.listBox.takeItem(self.listBox.row(item)) self.changed.emit() def editItem(self, item): if self.openEditor(item): self.itemChanged(item) self.changed.emit() def setCurrentItem(self, item): self.listBox.setCurrentItem(item) def setCurrentRow(self, row): self.listBox.setCurrentRow(row) def openEditor(self, item): """Opens an editor (dialog) for the item. Returns True if the dialog was accepted and the item edited. Returns False if the dialog was cancelled (the item must be left unedited). """ pass def itemChanged(self, item): """Called after an item has been added or edited. Re-implement to do something at this moment if needed, e.g. alter the text or display of other items. """ pass def setValue(self, strings): """Sets the listbox to a list of strings.""" self.listBox.clear() self.listBox.addItems(strings) self.changed.emit() def value(self): """Returns the list of paths in the listbox.""" return [self.listBox.item(i).text() for i in range(self.listBox.count())] def setItems(self, items): """Sets the listbox to a list of items.""" self.listBox.clear() for item in items: self.listBox.addItem(item) self.itemChanged(item) self.changed.emit() def items(self): """Returns the list of items in the listbox.""" return [self.listBox.item(i) for i in range(self.listBox.count())] def clear(self): """Clears the listbox.""" self.listBox.clear() self.changed.emit()
class CAT(QSplitter, Script): def __init__(self): Script.__init__(self, "cat") self.vfs = vfs.vfs() self.type = "cat" self.icon = None self.currentCodec = "UTF-8" def start(self, args): self.args = args try: self.node = args["file"].value() except: pass def g_display(self): QSplitter.__init__(self) self.offsets = self.linecount() self.initShape() self.read(0) def initShape(self): self.hbox = QHBoxLayout() self.hbox.setContentsMargins(0, 0, 0, 0) self.listWidget = QListWidget() self.listWidget.setSortingEnabled(True) for codec in QTextCodec.availableCodecs(): self.listWidget.addItem(str(codec)) item = self.listWidget.findItems('UTF-8', Qt.MatchExactly)[0] self.listWidget.setCurrentItem(item) self.listWidget.scrollToItem(item) textAreaWidget = QWidget() self.hbox.addWidget(self.listWidget) self.connect(self.listWidget, SIGNAL("itemSelectionChanged()"), self.codecChanged) self.scroll = Scroll(self) self.text = TextEdit(self) self.hbox.addWidget(self.text) self.hbox.addWidget(self.scroll) textAreaWidget.setLayout(self.hbox) self.addWidget(self.listWidget) self.addWidget(textAreaWidget) self.setStretchFactor(0, 0) self.setStretchFactor(1, 1) def codecChanged(self): self.currentCodec = self.listWidget.selectedItems()[0].text() self.read(self.scroll.value()) def read(self, line): self.vfile = self.node.open() padd = 0 if line > padd: padd = 1 self.vfile.seek(self.offsets[line]+padd) self.text.clear() codec = QTextCodec.codecForName(self.currentCodec) decoder = codec.makeDecoder() self.text.textCursor().insertText(decoder.toUnicode(self.vfile.read(1024*10))) self.text.moveCursor(QTextCursor.Start) self.vfile.close() def linecount(self): offsets = [0] self.vfile = self.node.open() offsets.extend(self.vfile.indexes('\n')) self.vfile.close() self.lines = len(offsets) return offsets def updateWidget(self): pass def c_display(self): file = self.node.open() fsize = self.node.size() size = 0 self.buff = "" while size < fsize: try: tmp = file.read(4096) except vfsError, e: print self.buff break if len(tmp) == 0: print tmp break size += len(tmp) self.buff += tmp print tmp file.close() if len(self.buff): return self.buff
class PopupCompleter(QFrame): def __init__(self): QFrame.__init__(self, None, Qt.FramelessWindowHint | Qt.ToolTip) vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self.listWidget = QListWidget() self.listWidget.setMinimumHeight(300) vbox.addWidget(self.listWidget) def reload(self, model): """Reload the data of the Popup Completer, and restart the state.""" self.listWidget.clear() self.add_help() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) self.listWidget.setCurrentRow(6) def clear(self): """Remove all the items of the list (deleted), and reload the help.""" self.listWidget.clear() def refresh(self, model): """Refresh the list when the user search for some word.""" self.listWidget.clear() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) if model: self.listWidget.setCurrentItem(model[0][0]) def fetch_more(self, model): """Add more items to the list on user scroll.""" for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) def add_help(self): #Load help fileItem = QListWidgetItem(QIcon(resources.IMAGES['locate-file']), '@\t(Filter only by Files)') font = fileItem.font() font.setBold(True) fileItem.setSizeHint(QSize(20, 30)) fileItem.setBackground(QBrush(Qt.lightGray)) fileItem.setForeground(QBrush(Qt.black)) fileItem.setFont(font) self.listWidget.addItem(fileItem) classItem = QListWidgetItem(QIcon(resources.IMAGES['locate-class']), '<\t(Filter only by Classes)') self.listWidget.addItem(classItem) classItem.setSizeHint(QSize(20, 30)) classItem.setBackground(QBrush(Qt.lightGray)) classItem.setForeground(QBrush(Qt.black)) classItem.setFont(font) methodItem = QListWidgetItem( QIcon(resources.IMAGES['locate-function']), '>\t(Filter only by Methods)') self.listWidget.addItem(methodItem) methodItem.setSizeHint(QSize(20, 30)) methodItem.setBackground(QBrush(Qt.lightGray)) methodItem.setForeground(QBrush(Qt.black)) methodItem.setFont(font) attributeItem = QListWidgetItem( QIcon(resources.IMAGES['locate-attributes']), '-\t(Filter only by Attributes)') self.listWidget.addItem(attributeItem) attributeItem.setSizeHint(QSize(20, 30)) attributeItem.setBackground(QBrush(Qt.lightGray)) attributeItem.setForeground(QBrush(Qt.black)) attributeItem.setFont(font) thisFileItem = QListWidgetItem( QIcon(resources.IMAGES['locate-on-this-file']), '.\t(Filter only by Classes and Methods in this File)') font = thisFileItem.font() font.setBold(True) thisFileItem.setSizeHint(QSize(20, 30)) thisFileItem.setBackground(QBrush(Qt.lightGray)) thisFileItem.setForeground(QBrush(Qt.black)) thisFileItem.setFont(font) self.listWidget.addItem(thisFileItem) nonPythonItem = QListWidgetItem( QIcon(resources.IMAGES['locate-nonpython']), '!\t(Filter only by Non Python Files)') self.listWidget.addItem(nonPythonItem) nonPythonItem.setSizeHint(QSize(20, 30)) nonPythonItem.setBackground(QBrush(Qt.lightGray)) nonPythonItem.setForeground(QBrush(Qt.black)) nonPythonItem.setFont(font)
class ListEdit(QWidget): """A widget to edit a list of items (e.g. a list of directories).""" # emitted when anything changed in the listbox. changed = pyqtSignal() def __init__(self, *args, **kwargs): QWidget.__init__(self, *args, **kwargs) layout = QGridLayout(self) self.setLayout(layout) self.addButton = QPushButton(icons.get('list-add'), '') self.editButton = QPushButton(icons.get('document-edit'), '') self.removeButton = QPushButton(icons.get('list-remove'), '') self.listBox = QListWidget() layout.setContentsMargins(1, 1, 1, 1) layout.setSpacing(0) layout.addWidget(self.listBox, 0, 0, 4, 1) layout.addWidget(self.addButton, 0, 1) layout.addWidget(self.editButton, 1, 1) layout.addWidget(self.removeButton, 2, 1) @self.addButton.clicked.connect def addClicked(): item = self.createItem() if self.openEditor(item): self.addItem(item) @self.editButton.clicked.connect def editClicked(): item = self.listBox.currentItem() item and self.editItem(item) @self.removeButton.clicked.connect def removeClicked(): item = self.listBox.currentItem() if item: self.removeItem(item) @self.listBox.itemDoubleClicked.connect def itemDoubleClicked(item): item and self.editItem(item) self.listBox.model().layoutChanged.connect(self.changed) def updateSelection(): selected = bool(self.listBox.currentItem()) self.editButton.setEnabled(selected) self.removeButton.setEnabled(selected) self.changed.connect(updateSelection) self.listBox.itemSelectionChanged.connect(updateSelection) updateSelection() app.translateUI(self) def translateUI(self): self.addButton.setText(_("&Add...")) self.editButton.setText(_("&Edit...")) self.removeButton.setText(_("&Remove")) def createItem(self): return QListWidgetItem() def addItem(self, item): self.listBox.addItem(item) self.itemChanged(item) self.changed.emit() def removeItem(self, item): self.listBox.takeItem(self.listBox.row(item)) self.changed.emit() def editItem(self, item): if self.openEditor(item): self.itemChanged(item) self.changed.emit() def setCurrentItem(self, item): self.listBox.setCurrentItem(item) def setCurrentRow(self, row): self.listBox.setCurrentRow(row) def openEditor(self, item): """Opens an editor (dialog) for the item. Returns True if the dialog was accepted and the item edited. Returns False if the dialog was cancelled (the item must be left unedited). """ pass def itemChanged(self, item): """Called after an item has been added or edited. Re-implement to do something at this moment if needed, e.g. alter the text or display of other items. """ pass def setValue(self, strings): """Sets the listbox to a list of strings.""" self.listBox.clear() self.listBox.addItems(strings) self.changed.emit() def value(self): """Returns the list of paths in the listbox.""" return [ self.listBox.item(i).text() for i in range(self.listBox.count()) ] def setItems(self, items): """Sets the listbox to a list of items.""" self.listBox.clear() for item in items: self.listBox.addItem(item) self.itemChanged(item) self.changed.emit() def items(self): """Returns the list of items in the listbox.""" return [self.listBox.item(i) for i in range(self.listBox.count())] def clear(self): """Clears the listbox.""" self.listBox.clear() self.changed.emit()
class StringListDlg(QDialog): acceptedList = Signal(QStringList) def __init__(self, name, stringlist=None, parent=None): super(StringListDlg, self).__init__(parent) self.name = name self.create_widgets(stringlist) self.layout_widgets() self.setWindowTitle("Edit {0} List".format(self.name)) def create_widgets(self, stringlist): self.listWidget = QListWidget() if stringlist is not None: self.listWidget.addItems(stringlist) self.listWidget.setCurrentRow(0) def layout_widgets(self): buttonLayout = QVBoxLayout() for text, slot in (("&Add...", self.add), ("&Edit...", self.edit), ("&Remove...", self.remove), ("&Up", self.up), ("&Down", self.down), ("&Sort", self.listWidget.sortItems), ("Close", self.accept)): button = QPushButton(text) if not MAC: button.setFocusPolicy(Qt.NoFocus) if text == "Close": buttonLayout.addStretch() buttonLayout.addWidget(button) button.clicked.connect(slot) layout = QHBoxLayout() layout.addWidget(self.listWidget) layout.addLayout(buttonLayout) self.setLayout(layout) def add(self): row = self.listWidget.currentRow() title = "Add {0}".format(self.name) string, ok = QInputDialog.getText(self, title, title) if ok and not string.isEmpty(): self.listWidget.insertItem(row, string) def edit(self): row = self.listWidget.currentRow() item = self.listWidget.item(row) if item is not None: title = "Edit {0}".format(self.name) string, ok = QInputDialog.getText(self, title, title, QLineEdit.Normal, item.text()) if ok and not string.isEmpty(): item.setText(string) def remove(self): row = self.listWidget.currentRow() item = self.listWidget.item(row) if item is None: return reply = QMessageBox.question(self, "Remove {0}".format( self.name), "Remove {0} `{1}'?".format( self.name, unicode(item.text())), QMessageBox.Yes|QMessageBox.No) if reply == QMessageBox.Yes: item = self.listWidget.takeItem(row) del item def up(self): row = self.listWidget.currentRow() if row >= 1: item = self.listWidget.takeItem(row) self.listWidget.insertItem(row - 1, item) self.listWidget.setCurrentItem(item) def down(self): row = self.listWidget.currentRow() if row < self.listWidget.count() - 1: item = self.listWidget.takeItem(row) self.listWidget.insertItem(row + 1, item) self.listWidget.setCurrentItem(item) def reject(self): self.accept() def accept(self): self.stringlist = QStringList() for row in range(self.listWidget.count()): self.stringlist.append(self.listWidget.item(row).text()) self.acceptedList.emit(self.stringlist) QDialog.accept(self)
class MainWindow(QMainWindow): """The main window widget for the program. """ def __init__(self, parent=None): super(MainWindow, self).__init__(parent) #### 1 CREATE AND INITIALIZE DATA STRUCTURES #### self.xLabel = None self.xSelection = DEFAULTX self.xSelection_old = None self.xArray = None self.yLabel = None self.ySelection = DEFAULTY self.ySelection_old = None self.yArray = None self.filename = None self.tdms_file_object = None self.channel_registry = {} # Y selector on Left self.ySelector = QListWidget() ySelectorLabel = QLabel("y axis channel") self.ySelector.setMaximumWidth(ySelectorLabel.sizeHint().width()) # File name and plot in the middle self.sourceFileName = QLabel("None") self.sourceFileName.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sourceFileLabel = QLabel("current file") sourceFileLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) # Matplotlib canvas fig = Figure(dpi=100) self.canvas = FigureCanvas(fig) self.canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) mpl_toolbar = NavigationToolbar(self.canvas, self.canvas) self.axes = fig.add_subplot(111) # X selector on bottom self.xSelector = QListWidget() self.xSelector.addItem("Time") self.xSelector.setFlow(0) xSelectorLabel = QLabel("x axis channel") self.xSelector.setMaximumHeight(self.xSelector.sizeHintForColumn(0)) # Offset and parameter widgets on the right top self.offsetThing = OffsetWidget() self.attributesThing = AttributesWidget() # Save channel on right bottom self.save_chan_chkbx = QCheckBox() save_chan_label = QLabel("Save Channel") # Status bar at the bottom self.fileSizeLabel = QLabel("File Size: {f_size:0>7.3f} MB".format(f_size=0.0)) self.fileSizeLabel.setFixedWidth(self.fileSizeLabel.sizeHint().width()+10) self.fileSizeLabel.setFrameStyle(QFrame.Panel|QFrame.Sunken) self.yChanLength = QLabel("Y Channel Length: {y_len:0>7.0f}".format(y_len=0.0)) self.yChanLength.setFixedWidth(self.yChanLength.sizeHint().width()+10) self.yChanLength.setFrameStyle(QFrame.Panel|QFrame.Sunken) self.xChanLength = QLabel("X Channel Length: {x_len:0>7.0f}".format(x_len=0.0)) self.xChanLength.setFixedWidth(self.xChanLength.sizeHint().width()+10) self.xChanLength.setFrameStyle(QFrame.Panel|QFrame.Sunken) status = self.statusBar() status.setSizeGripEnabled(False) status.addPermanentWidget(self.fileSizeLabel) status.addPermanentWidget(self.yChanLength) status.addPermanentWidget(self.xChanLength) status.showMessage("Ready", 5000) #2 Create the central widget self.centralWidget = QWidget() # Left Side selectorLayout = QVBoxLayout() #selectorLayout.addWidget(xSelectorLabel) #selectorLayout.addWidget(self.xSelector) selectorLayout.addWidget(ySelectorLabel) selectorLayout.addWidget(self.ySelector) selectorLayout.addStretch() # Center centralLayout = QVBoxLayout() fileNameLayout = QHBoxLayout() xSelectorLayout = QHBoxLayout() fileNameLayout.addWidget(sourceFileLabel) fileNameLayout.addWidget(self.sourceFileName) xSelectorLayout.addWidget(xSelectorLabel) xSelectorLayout.addWidget(self.xSelector) centralLayout.addLayout(fileNameLayout) centralLayout.addWidget(self.canvas) centralLayout.addWidget(mpl_toolbar) centralLayout.addLayout(xSelectorLayout) # Right bottom save_chan_layout = QHBoxLayout() save_chan_layout.addWidget(self.save_chan_chkbx) save_chan_layout.addWidget(save_chan_label) # Right Side rightLayout = QVBoxLayout() rightLayout.addWidget(self.offsetThing) rightLayout.addWidget(self.attributesThing) rightLayout.addStretch() rightLayout.addLayout(save_chan_layout) layout = QHBoxLayout() layout.addLayout(selectorLayout) layout.addLayout(centralLayout) layout.addLayout(rightLayout) self.centralWidget.setLayout(layout) self.setCentralWidget(self.centralWidget) self.resize(self.sizeHint()) #3 Create and set up any dock windows #4 Create actions and insert them into menus and toolbars fileQuitAction = self.createAction("&Quit", self.close, "Ctrl+Q", "exit", "Close the application") fileOpenAction = self.createAction("&Open TDMS File", self.fileOpen, QKeySequence.Open, "fileopen", "Open an existing TDMS file") fileExportAction = self.createAction("&Export", self.exprtToHDF5, "Ctrl+E", tip="Export the TDMS data to HDF5") self.fileMenu = self.menuBar().addMenu("&File") self.fileMenuActions = (fileOpenAction, fileExportAction, fileQuitAction) #self.addActions(self.fileMenu, self.fileMenuActions) self.xSelector.itemSelectionChanged.connect(self.make_x_selection) self.ySelector.itemSelectionChanged.connect(self.make_y_selection) self.offsetThing.new_offset.connect(self.subtract_offset) self.fileMenu.triggered.connect(self.update_file_menu) self.save_chan_chkbx.stateChanged.connect(self.toggle_save) #5 Read in application's settings settings = QSettings() # Restore the geometry and state of the main window from last use #self.restoreGeometry(settings.value("MainWindow/Geometry")) #self.restoreState(settings.value("MainWindow/State")) self.setWindowTitle("TDMS to HDF5 Converter") self.recentFiles = settings.value("RecentFiles") if not self.recentFiles: self.recentFiles = [] self.update_file_menu() def update_ui(self): pass def initVariables(self): self.xLabel = None self.xSelection = DEFAULTX self.xSelection_old = None self.xArray = None self.yLabel = None self.ySelection = DEFAULTY self.ySelection_old = None self.yArray = None self.filename = None self.tdms_file_object = None self.channel_registry = {} def createAction(self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, signal="triggered()"): # Create the action action = QAction(text, self) # Give it its icon if icon is not None: action.setIcon(QIcon(":/{icon}.png".format(icon=icon))) # Give it its shortcut if shortcut is not None: action.setShortcut(shortcut) # Set up its help/tip text if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) # Connect it to a signal if slot is not None: self.connect(action, SIGNAL(signal), slot) # Make it checkable if checkable: action.setCheckable(True) return action def addActions(self, target, actions): for action in actions: if action is None: target.addSeparator() else: target.addAction(action) def update_file_menu(self): self.fileMenu.clear() self.addActions(self.fileMenu, self.fileMenuActions[:-1]) current = self.filename if self.filename is not None else None recentFiles = [] for fname in self.recentFiles: if fname != current and QFile.exists(fname): recentFiles.append(fname) if recentFiles: self.fileMenu.addSeparator() for i, fname in enumerate(recentFiles): action = QAction("&{num} {name}".format(num=i+1, name=QFileInfo(fname).fileName()), self) action.setData(fname) action.triggered.connect(lambda: self.loadFile(fname)) self.fileMenu.addAction(action) self.fileMenu.addSeparator() self.fileMenu.addAction(self.fileMenuActions[-1]) def fileOpen(self): # Process 1 self.initVariables() basedir = os.path.dirname(self.filename) if self.filename is not None \ else "~/Documents/PhD/root/raw-data/sio2al149/CryoMeasurement" formats = "TDMS files (*.tdms)" fname = QFileDialog.getOpenFileName(self, "Open a TDMS File", basedir, formats) # Process 1.1 Collect file name if fname and QFile.exists(fname): self.loadFile(fname) def loadFile(self, fname): # Process 1.2 Generate TDMS file object self.add_recent_file(fname) self.tdms_file_object = TdmsFile(fname) self.filename = fname # Process 1.3 Read data into local structure if self.tdms_file_object: # Process 1.3.0 Generate group list group_list = self.tdms_file_object.groups() # Processes 1.3.1 through 1.3.3 Sort TDMS data for group in group_list: self.sortTDMSGroupData(group) message = "Loaded {f_name}".format(f_name=os.path.basename(fname)) self.sourceFileName.setText(os.path.basename(fname)) # Process 2.1 Populate channel selection lists self.update_selectors() else: message = "Failed to load {f_name}".format(f_name=os.path. basename(fname)) self.statusBar().showMessage(message, 5000) fsize = os.path.getsize(self.filename) self.fileSizeLabel.setText("File Size: {file_size:>7.3f} MB".format(file_size=fsize/1E6)) #TODO self.updateStatus(message) # see Rapid GUI ch06.pyw def add_recent_file(self, fname): if fname is None: return if not fname in self.recentFiles: self.recentFiles.insert(0, fname) while len(self.recentFiles) > 9: self.recentFiles.pop() def sortTDMSGroupData(self, group): # Process 1.3 Sort Group data # Process 1.3.1 Get <Group> Channels group_props = self.tdms_file_object.object(group).properties # Process 1.3.2 Get <Group> Properties group_chans = self.tdms_file_object.group_channels(group) # Process 1.3.3 Create a new channel in the registry for each channel # in the group for chan in group_chans: chan_name = chan.path.split('/')[-1].strip("'") # Process 1.3.3.1 Generate new channel object and fill with data # Some of the TDMS channels were created, but never populated with # data. The following weeds those out. try: new_chan = Channel(chan_name, device=group, meas_array=chan.data) except TypeError: self.statusBar().showMessage("Channel {chan} in {dev} has no data" .format(chan=chan_name, dev=group), 5000) try: new_chan.set_start_time(chan.property("wf_start_time")) new_chan.set_delta_time(chan.property("wf_increment")) new_chan.set_location('raw/{c2_name}'.format(c2_name=chan_name)) if chan_name not in ['TCap', 'xMagnet']: new_chan.set_write() # Some of the channel-specific properties were actually # saved in the group object's properties list. # We retrieve those here. # Process 1.3.3.2 Resort the group properties of TDMS ADWin if group == "ADWin": for atr_name in ADWIN_DICT[chan_name]: try: new_chan.attributes[atr_name] = \ group_props[atr_name] except KeyError: #print('The key {a_name} was not found.' # .format(a_name=atr_name)) #print('The keys available are\n') #print(group_props) pass # Process 1.3.3.3 Add new channel to the registry self.channel_registry[chan_name] = new_chan #print('\tChannel name:\t{ch_name}'.format(ch_name=chan_name)) except (KeyError, UnboundLocalError): pass #print('Error: Was unable to load {c3_name}' # .format(c3_name=chan_name)) def update_selectors(self): # Clear the selectors self.xSelector.clear() self.ySelector.clear() # Add the names of the channels in the registry to both selectors for key in self.channel_registry.keys(): self.xSelector.addItem(key) self.ySelector.addItem(key) # Add the time "channel" to the x selector self.xSelector.addItem('Time') # Sort the lists (alphabetically) otherwise the order constantly changes self.xSelector.sortItems() self.ySelector.sortItems() # Set the current x selector default default_x_item = self.xSelector.findItems(DEFAULTX, Qt.MatchExactly) self.xSelector.setCurrentItem(default_x_item[0]) # Set the current y selector default try: default_y_item = self.ySelector.findItems(DEFAULTY, Qt.MatchExactly) self.ySelector.setCurrentItem(default_y_item[0]) except IndexError: self.ySelector.setCurrentRow(0) self.xSelector.setMinimumHeight(self.xSelector.sizeHintForRow(0)*3) self.ySelector.setMinimumWidth(self.ySelector.sizeHintForColumn(0)+10) def exprtToHDF5(self): # Process 5 Save to HDF5 fname = self.filename.split('.')[0] + '.hdf5' basedir = "/home/chris/Documents/PhD/root/data/sio2al149/cryo_measurement" if not os.path.exists(basedir): os.makedirs(basedir) formats = "TDMS files (*.hdf5 *.h5 *.he5 *.hdf)" dialog = QFileDialog() dialog.setFilter(formats) dialog.setDefaultSuffix("*.hdf5") dialog.selectFile(os.path.join(basedir, fname)) dialog.setDirectory(basedir) if dialog.exec_(): fname = dialog.selectedFiles() else: return # Process 5.1 Create HDF5 file object hdf5_file_object = h5py.File(fname[0]) # Process 5.2 Create channels at their locations for chan in self.channel_registry: chan_obj = self.channel_registry[chan] chan_name = chan #print(chan, self.channel_registry[chan].location, # self.channel_registry[chan].write_to_file) # Process 5.2.1 Write channel data if self.channel_registry[chan].write_to_file: dset = hdf5_file_object.create_dataset(chan_obj.location, data=chan_obj.data) # Process 5.2.2 Write channel attributes for attr_name in self.channel_registry[chan].attributes: attr_value = self.channel_registry[chan].attributes[attr_name] # Convert the datetime format to a string if type(attr_value) is datetime: attr_value = attr_value.isoformat() # There's currently a wierd bug when dealing with python3 # strings. # This gets around that if type(attr_value) is str: #attr_value = attr_value.encode('utf-8') #attr_value = np.string_(attr_value, dtype="S10") attr_value = np.string_(attr_value) dset.attrs.create(attr_name, attr_value) # Process 5.3 Write data to file hdf5_file_object.flush() hdf5_file_object.close() def make_x_selection(self): self.x_change = True # Get the name of the newly selected channel self.xSelection = self.xSelector.currentItem().text() # Get the axis label self.xLabel = self.gen_axis_label(self.xSelection) # If the xSelection is time, use the time data instead of measurement # data if self.xSelection == 'Time': try: self.xArray = self.channel_registry[self.ySelection].time except KeyError: self.xArray = np.array([]) else: self.xArray = self.channel_registry[self.xSelection].data if self.yLabel: self.plotData() self.xSelection_old = self.xSelector.currentItem() self.x_change = False self.xChanLength.setText("X Channel Length: {x_len:>7.0f}".format(x_len=len(self.xArray))) def make_y_selection(self, offset=0.0): self.y_change = True # Get the names of the selected channels from the selectors try: self.ySelection = self.ySelector.currentItem().text() except AttributeError: self.ySelection = DEFAULTY # Set save channel checkbox state self.save_chan_chkbx.setChecked(self.channel_registry[self.ySelection] .write_to_file) # Get the axis label self.yLabel = self.gen_axis_label(self.ySelection) # Generate the y-channel array to be plotted self.yArray = self.channel_registry[self.ySelection].data - offset # Update the attributes view self.attributesThing.clear_attributes() self.attributesThing.select_chan(self.channel_registry[self.ySelection]) if self.xSelection == 'Time': self.make_x_selection() else: self.plotData() self.ySelection_old = self.ySelector.currentItem() self.y_change = False self.yChanLength.setText("Y Channel Length: {y_len:>7.0f}".format(y_len=len(self.yArray))) def gen_axis_label(self, chan_name): # Generate the axis labels based on the selected channels # Cycle through the labes in the AXESLABELS dictionary for axlbl in AXESLABELS.keys(): # Cycle through the channel names in each label's dictionary entry for cn in AXESLABELS[axlbl]: # If a channel equals one of the selections, save the label if chan_name == cn: label = axlbl return label def plotData(self): # Clear the plot self.axes.cla() # Turn on the grid self.axes.grid(True) # Set the labels try: self.axes.set_xlabel(self.xLabel) except UnboundLocalError: self.statusBar().showMessage("Could not generate an axis label for {chan}" .format(chan=self.xSelection), 5000) try: self.axes.set_ylabel(self.yLabel) except UnboundLocalError: self.statusBar().showMessage("Could not generate an axis label for {chan}" .format(chan=self.ySelection), 5000) # Try plotting the data. There are still no checks in place to make sure # the arrays are of the same length. try: # Plot the data and label it self.axes.plot(self.xArray, self.yArray, label=self.ySelection) # Show the legend self.axes.legend(loc=0) # Draw everything self.canvas.draw() except ValueError: QMessageBox.warning(self, "Unequal Arrays", "{y_chan} and {x_chan} " .format(y_chan=self.ySelection, x_chan=self.xSelection) + \ "are not the same length!") if self.x_change: self.xSelector.setCurrentItem(self.xSelection_old) elif self.y_change: self.ySelector.setCurrentItem(self.ySelection_old) def subtract_offset(self): "Subtract the offset entered from the currently selected y channel." offset = self.offsetThing.offset_entry.value() self.make_y_selection(offset=offset) def toggle_save(self): self.channel_registry[self.ySelection].write_to_file = \ self.save_chan_chkbx.isChecked() def create_new_channel(self, ch_name): "Create a new channel in the registry." #print(ch_name) pass def closeEvent(self, event): """Reimplementation of the close even handler. We have to reimplement this because not all close actions, e.g. clicking the X button, call the close() method. We want to catch this so we can give the user the opportunity to save unsaved changes before the program exits. """ settings = QSettings() #settings.setValue("MainWindow/Geometry", QVariant( # self.saveGeometry())) #settings.setValue("MainWindow/State", QVariant( # self.saveState())) if self.recentFiles: recentFiles = self.recentFiles else: recentFiles = [] settings.setValue("RecentFiles", recentFiles)
class RRepositoryBrowser(QDialog): def __init__(self, pipe, parent=None): QDialog.__init__(self, parent) mirror = robjects.r.getOption('repos') contrib_url = robjects.r.get('contrib.url', mode='function') available_packages = robjects.r.get('available.packages', mode='function') self.setWindowTitle("manageR - Install R Packages") self.setWindowIcon(QIcon(":icon")) p = available_packages() self.pipe = pipe self.names = QStringList(p.rownames) self.parent = parent self.packageList = QListWidget(self) self.packageList.setAlternatingRowColors(True) self.packageList.setEditTriggers(QAbstractItemView.NoEditTriggers) self.packageList.setSortingEnabled(True) self.packageList.setSelectionMode(QAbstractItemView.ExtendedSelection) self.packageList.setToolTip("Select packages to install") self.packageList.setWhatsThis("List of packages available on CRAN") self.packageList.insertItems(0, self.names) self.dependCheckbox = QCheckBox(self) self.dependCheckbox.setText("Install all dependencies") self.dependCheckbox.setChecked(True) self.closeCheckbox = QCheckBox(self) self.closeCheckbox.setText("Close dialog on completion") self.closeCheckbox.setChecked(False) filterEdit = QLineEdit(self) filterLabel = QLabel("Filter packages", self) self.outputEdit = QTextEdit(self) self.outputEdit.setReadOnly(True) self.outputEdit.setVisible(False) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Apply|QDialogButtonBox.Close) self.buttonBox.addButton("Details >>", QDialogButtonBox.ActionRole) vbox = QVBoxLayout(self) hbox = QHBoxLayout() hbox.addWidget(filterLabel) hbox.addWidget(filterEdit) vbox.addLayout(hbox) vbox.addWidget(self.dependCheckbox) vbox.addWidget(self.packageList) vbox.addWidget(self.closeCheckbox) vbox.addWidget(self.outputEdit) vbox.addWidget(self.buttonBox) self.started = False self.setMinimumSize(80,50) self.connect(filterEdit, SIGNAL("textChanged(QString)"), self.filterPackages) #self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject) self.connect(self.buttonBox, SIGNAL("clicked(QAbstractButton*)"), self.buttonClicked) def buttonClicked(self, button): if button.text() == "Details >>": self.showDetails() button.setText("Details <<") elif button.text() == "Details <<": self.hideDetails() button.setText("Details >>") if not self.started: if self.buttonBox.standardButton(button) == QDialogButtonBox.Apply: self.installPackages() else: self.reject() def showDetails(self): self.outputEdit.setVisible(True) def hideDetails(self): self.outputEdit.setVisible(False) def filterPackages(self, text): self.packageList.clear() self.packageList.insertItems(0, self.names.filter(QRegExp(r"^%s" % text))) firstItem = self.packageList.item(0) if firstItem.text().startsWith(text): self.packageList.setCurrentItem(firstItem) # else: # self.packageList.clearSelection() def currentPackages(self): return [unicode(item.text()) for item in self.packageList.selectedItems()] def installPackages(self): pkgs = self.currentPackages() count = len(pkgs) if count < 1: QMessageBox.warning(self, "manageR - Warning", "Please choose at least one valid package") return False pkgs = QStringList(pkgs).join("','") checked = self.dependCheckbox.isChecked() if checked: depends = "TRUE" else: depends = "FALSE" self.pipe.send("install.packages(c('%s'), dependencies=%s, repos=%s)" % (pkgs, depends, robjects.r.getOption("repos"))) self.started = True self.startTimer(30) return True def timerEvent(self, e): if self.started: try: output = self.pipe.recv() if output is None: self.started=False self.killTimer(e.timerId()) else: self.printOutput(output) except EOFError: pass QApplication.processEvents() def printOutput(self, output): self.outputEdit.insertPlainText(output) self.outputEdit.ensureCursorVisible()