master
Ondřej Hruška 6 yıl önce
işleme 50b9942ecf
İmzalayan: MightyPork
GPG Anahtar Kimliği: 2C5FD5035250423D
  1. 128
      gexync.py
  2. 81
      ini_syntax.py

@ -0,0 +1,128 @@
#!/bin/env python3
import gex
import sys
from PyQt4 import QtGui, QtCore
import ini_syntax
class GexIniEditor(QtGui.QMainWindow):
"""
Gexync is a GEX ini file editor.
The editor loads the INI file through the communication interface
without having to mount the virtual filesystem, which is unreliable
on some systems.
This utility allows live editing of the UNITS.INI file.
On save, a new version is loaded with formatting and error messages
generated by GEX, as if the virtual config filesystem was re-mounted.
The editor does not keep GEX claimed, instead does so only when needed.
This allows testing of the current configuration without having to close
and reopen the editor.
"""
def __init__(self, xferLambda):
self.xferLambda = xferLambda
self.filenum = int(sys.argv[1]) if len(sys.argv)>1 else 0
super().__init__()
self.initUI()
# TODO let user pick GEX device if multiple
def initToolbar(self):
icon = self.style().standardIcon(QtGui.QStyle.SP_BrowserReload)
loadAction = QtGui.QAction(icon, 'Reload', self)
loadAction.setShortcut('Ctrl+O')
loadAction.triggered.connect(self.gexLoad)
icon = self.style().standardIcon(QtGui.QStyle.SP_DialogSaveButton)
syncAction = QtGui.QAction(icon, 'Write Changes', self)
syncAction.setShortcut('Ctrl+S')
syncAction.triggered.connect(self.gexSync)
icon = self.style().standardIcon(QtGui.QStyle.SP_DialogOkButton)
persAction = QtGui.QAction(icon, 'Persist', self)
persAction.setShortcut('Ctrl+P')
persAction.triggered.connect(self.gexPersist)
self.toolbar = self.addToolBar('Toolbar')
self.toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
self.toolbar.addAction(loadAction)
self.toolbar.addAction(syncAction)
self.toolbar.addSeparator()
self.toolbar.addAction(persAction)
def initEditor(self):
self.editor = QtGui.QPlainTextEdit()
# Editor background and text color
pal = QtGui.QPalette()
bgc = QtGui.QColor(0xFFFFF6)
pal.setColor(QtGui.QPalette.Base, bgc)
textc = QtGui.QColor(0x000000)
pal.setColor(QtGui.QPalette.Text, textc)
self.editor.setPalette(pal)
# Font
font = QtGui.QFont('Liberation Mono', 12)
font.setStyleHint(QtGui.QFont.TypeWriter)
self.editor.setFont(font)
# Initial size
self.highlight = ini_syntax.IniHighlighter(self.editor.document())
def initUI(self):
self.setWindowTitle('GEX config file editor')
self.initToolbar()
self.initEditor()
self.setCentralWidget(self.editor)
self.show()
self.gexLoad()
def gexLoad(self):
self.editor.setPlainText("")
self.editor.repaint()
client = gex.Client(self.xferLambda(), load_units=False)
read_ini = client.ini_read(self.filenum)
client.close()
self.editor.setPlainText(read_ini)
self.highlight.rehighlight()
self.setWindowTitle('GEX config file editor')
def gexSync(self):
new_txt = self.editor.toPlainText()
self.editor.setPlainText("")
self.editor.repaint()
client = gex.Client(self.xferLambda(), load_units=False)
client.ini_write(new_txt)
read_ini = client.ini_read(self.filenum)
client.close()
self.editor.setPlainText(read_ini)
self.highlight.rehighlight()
self.setWindowTitle('*GEX config file editor')
def gexPersist(self):
client = gex.Client(self.xferLambda(), load_units=False)
client.ini_persist()
client.close()
self.setWindowTitle('GEX config file editor')
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
editor = GexIniEditor(lambda: gex.TrxRawUSB())
# editor = GexIniEditor(lambda: gex.TrxSerialThread(port='/dev/ttyUSB1',
# baud=57600))
# centered resize
w = 800
h = 900
ss = app.desktop().availableGeometry().size()
editor.setGeometry(int(ss.width() / 2 - w / 2), int(ss.height() / 2 - h / 2), w, h)
sys.exit(app.exec_())

@ -0,0 +1,81 @@
# syntax.py
# This is a companion file to gexync.py
# based on https://wiki.python.org/moin/PyQt/Python%20syntax%20highlighting
from PyQt4.QtCore import QRegExp
from PyQt4.QtGui import QColor, QTextCharFormat, QFont, QSyntaxHighlighter
def format(color, style=''):
"""Return a QTextCharFormat with the given attributes.
"""
_color = QColor()
_color.setNamedColor(color)
_format = QTextCharFormat()
_format.setForeground(_color)
if 'bold' in style:
_format.setFontWeight(QFont.Bold)
if 'italic' in style:
_format.setFontItalic(True)
return _format
# Syntax styles that can be shared by all languages
STYLES = {
'operator': format('red'),
'string': format('magenta'),
'comment': format('#6C8A70', 'italic'),
'key': format('#008AFF'),
'numbers': format('brown'),
'section': format('black', 'bold'),
}
class IniHighlighter (QSyntaxHighlighter):
# Python braces
def __init__(self, document):
QSyntaxHighlighter.__init__(self, document)
rules = [
(r'=', 0, STYLES['operator']),
(r'\b[YN]\b', 0, STYLES['numbers']),
# Double-quoted string, possibly containing escape sequences
(r'"[^"\\]*(\\.[^"\\]*)*"', 0, STYLES['string']),
# Single-quoted string, possibly containing escape sequences
(r"'[^'\\]*(\\.[^'\\]*)*'", 0, STYLES['string']),
# Numeric literals
(r'\b[+-]?[0-9]+\b', 0, STYLES['numbers']),
(r'\b[+-]?0[xX][0-9A-Fa-f]+\b', 0, STYLES['numbers']),
(r'\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b', 0, STYLES['numbers']),
# From '#' until a newline
(r'#[^\n]*', 0, STYLES['comment']),
(r'^\[.+\]', 0, STYLES['section']),
(r'^[a-zA-Z0-9_-]+\s?=', 0, STYLES['key']),
]
# Build a QRegExp for each pattern
self.rules = [(QRegExp(pat), index, fmt)
for (pat, index, fmt) in rules]
def highlightBlock(self, text):
"""Apply syntax highlighting to the given block of text.
"""
# Do other syntax formatting
for expression, nth, format in self.rules:
index = expression.indexIn(text, 0)
while index >= 0:
# We actually want the index of the nth match
index = expression.pos(nth)
length = len(expression.cap(nth))
self.setFormat(index, length, format)
index = expression.indexIn(text, index + length)
self.setCurrentBlockState(0)
Yükleniyor…
İptal
Kaydet