|
@@ -0,0 +1,268 @@
|
|
|
+from PyQt4 import QtGui, QtCore
|
|
|
+import ast
|
|
|
+from ..base import kcgwidget as kcgw
|
|
|
+import os
|
|
|
+from .. import config
|
|
|
+try:
|
|
|
+ from pprint import pformat
|
|
|
+except ImportError:
|
|
|
+ def pformat(string, width=None):
|
|
|
+ return string
|
|
|
+
|
|
|
+class ConfigEntry(kcgw.KCGWidgets):
|
|
|
+ def __init__(self, comm='', conf='', type=str, multiline=False):
|
|
|
+ super(ConfigEntry, self).__init__()
|
|
|
+ self.layout = QtGui.QVBoxLayout()
|
|
|
+ self.entryLayout = QtGui.QHBoxLayout()
|
|
|
+ self.setLayout(self.layout)
|
|
|
+ self.toggle = self.createButton("?", connect=self.toggle)
|
|
|
+ self.toggle.setFixedWidth(20)
|
|
|
+
|
|
|
+ if len(comm.split("\n")) <= 4:
|
|
|
+ self.comment = self.createLabel(comm)
|
|
|
+ self.comment.setStyleSheet("color: grey;")
|
|
|
+ self.comment.setAlignment(QtCore.Qt.AlignRight)
|
|
|
+
|
|
|
+ else:
|
|
|
+ self.commentText = self.createLabel(comm)
|
|
|
+ self.commentText.setStyleSheet("color: grey;")
|
|
|
+ self.commentText.setAlignment(QtCore.Qt.AlignRight)
|
|
|
+
|
|
|
+ self.commentWidget = QtGui.QWidget()
|
|
|
+ self.comment = QtGui.QScrollArea()
|
|
|
+ self.comment.setAlignment(QtCore.Qt.AlignRight)
|
|
|
+ self.commlayout = QtGui.QVBoxLayout()
|
|
|
+ self.commentWidget.setLayout(self.commlayout)
|
|
|
+ self.commlayout.addWidget(self.commentText, alignment=QtCore.Qt.AlignRight)
|
|
|
+ self.comment.setWidget(self.commentWidget)
|
|
|
+ self.comment.text = lambda: self.commentText.text()
|
|
|
+
|
|
|
+ self.config = self.createLabel(conf)
|
|
|
+ self.config.setFixedWidth(200)
|
|
|
+ self.multiline = multiline
|
|
|
+ self.type = type
|
|
|
+ if not multiline:
|
|
|
+ self.value = self.createInput(width=300)
|
|
|
+ else:
|
|
|
+ self.value = QtGui.QTextEdit()
|
|
|
+ self.value.setFixedWidth(500)
|
|
|
+ try:
|
|
|
+ self.value.setText(pformat(getattr(config, conf), width=60, indent=4))
|
|
|
+ except AttributeError:
|
|
|
+ pass
|
|
|
+ self.layout.addWidget(self.comment)
|
|
|
+ self.layout.addLayout(self.entryLayout)
|
|
|
+ self.entryLayout.addWidget(self.config)
|
|
|
+ self.entryLayout.addWidget(self.value)
|
|
|
+ self.entryLayout.addWidget(self.toggle)
|
|
|
+ self.comment.hide()
|
|
|
+
|
|
|
+ def toggle(self):
|
|
|
+ self.comment.setHidden(not self.comment.isHidden())
|
|
|
+
|
|
|
+ def set_comment(self, comm):
|
|
|
+ self.comment.setText(comm)
|
|
|
+
|
|
|
+ def set_config(self, conf):
|
|
|
+ self.config.setText(conf)
|
|
|
+
|
|
|
+ def validate(self, mark=False):
|
|
|
+ if self.multiline:
|
|
|
+ try:
|
|
|
+ v, e = self.san(str(self.value.toPlainText()))
|
|
|
+ if e:
|
|
|
+ self.value.setText(v)
|
|
|
+ if type(config.leval(v)) == self.type:
|
|
|
+ self.value.setStyleSheet("background-color: #FFFFFF;")
|
|
|
+ return True
|
|
|
+ except (ValueError, config.NoValueException, SyntaxError):
|
|
|
+ pass
|
|
|
+ else:
|
|
|
+ try:
|
|
|
+ v, e = self.san(str(self.value.text()))
|
|
|
+ if e:
|
|
|
+ self.value.setText(v)
|
|
|
+ if type(config.leval(v)) == self.type:
|
|
|
+ self.value.setStyleSheet("background-color: #FFFFFF;")
|
|
|
+ return True
|
|
|
+ except (ValueError, config.NoValueException, SyntaxError):
|
|
|
+ pass
|
|
|
+ if mark:
|
|
|
+ self.value.setStyleSheet("background-color: #FFAAAA;")
|
|
|
+ return False
|
|
|
+
|
|
|
+ def san(self, val):
|
|
|
+ err = False
|
|
|
+ if self.type == str:
|
|
|
+ val.replace('"', '\'')
|
|
|
+ if val[0] == "'":
|
|
|
+ if not val[-1] == "'":
|
|
|
+ val += "'"
|
|
|
+ err = True
|
|
|
+ elif val[-1] == "'":
|
|
|
+ val = "'" + val
|
|
|
+ err = True
|
|
|
+ else:
|
|
|
+ val = '"' + val + '"'
|
|
|
+ err = False
|
|
|
+ return val, err
|
|
|
+
|
|
|
+ def __str__(self):
|
|
|
+ comment = ''
|
|
|
+ for line in str(self.comment.text()).split('\n'):
|
|
|
+ comment += "# " + line + '\n'
|
|
|
+ if self.multiline:
|
|
|
+ val = self.value.toPlainText()
|
|
|
+ else:
|
|
|
+ val = self.value.text()
|
|
|
+
|
|
|
+ val, e = self.san(val)
|
|
|
+
|
|
|
+ return str(comment + self.config.text() + " = " + str(val))
|
|
|
+
|
|
|
+
|
|
|
+class ConfigSetup(kcgw.KCGWidgets):
|
|
|
+ machine_comments = ["Bunches per turn of accelerator (integer value)",
|
|
|
+ "Save headerinformation in file (bool value)",
|
|
|
+ "Revolution time (double value)"
|
|
|
+ ]
|
|
|
+ ui_comments = ['NOTE: This value will be overwritten when the language is changed in the gui-settings\n'
|
|
|
+ 'possible languages:\n'
|
|
|
+ '"en_GB" - English\n'
|
|
|
+ '"de_DE" - German',
|
|
|
+ 'default_save_location: use "pwd" for current working\n'
|
|
|
+ 'directory KCG will always save in a subdirectory to\n'
|
|
|
+ 'this given path and save files in this directory',
|
|
|
+ 'default_subdirectory_name_format: this is the\n'
|
|
|
+ 'naming scheme for the subdirectory in which the\n'
|
|
|
+ 'files are saved. Format of this string:\n'
|
|
|
+ '"{tag1}text{tag2}text" etc.\n'
|
|
|
+ 'possible tags:\n'
|
|
|
+ '{dateG} will produce e.g. 04.01.2015\n'
|
|
|
+ '{dateGd} will produce e.g. 04_01_2015\n'
|
|
|
+ '{dateA} will pdoduce e.g. 01-04-2015\n'
|
|
|
+ '{times} will produce e.g. 14_04\n'
|
|
|
+ '{timel} will produce e.g. 14_04_12\n'
|
|
|
+ '{d} the Day in 2 digit format\n'
|
|
|
+ '{m} the Month in 2 digit format\n'
|
|
|
+ '{y} the Year in 4 digit Format\n'
|
|
|
+ '{H} the Hour in 2 digit format\n'
|
|
|
+ '{M} the minute in 2 digit format\n'
|
|
|
+ '{S} the seconds in 2 digit format\n'
|
|
|
+ '{timestamp} unix timestamp without msec\n'
|
|
|
+ '{user} the current logged in user\n'
|
|
|
+ '{sessionname} Ask for session name at startup\n'
|
|
|
+ '{ask} always ask for a foldername',
|
|
|
+ 'reask on cancel in dialog or use {user}_{dateGd}-{timel} as default when cancel is pressed?',
|
|
|
+ 'Show advanced table view per default? (boolean value)'
|
|
|
+ ]
|
|
|
+ logging_comments = ['These are PVs that will be possible to insert into log files\n'
|
|
|
+ 'This variable is to be a list consisting of touples of two entries,\n'
|
|
|
+ 'the first ist the Text that describes the value and the second is the EPICS PV that\n'
|
|
|
+ 'holds that value',
|
|
|
+ 'This pv is used to determine if epics pvs are accessible' ,
|
|
|
+ 'Path to your epics base installation',
|
|
|
+ 'List of Entries that are default to save in Log\n'
|
|
|
+ 'Possible Values are:\n'
|
|
|
+ '"Number of Orbits" \n'
|
|
|
+ '"Number of Skipped Orbits" \n'
|
|
|
+ '"Number of Acquisitions" \n'
|
|
|
+ '"Time between Acquisitions" \n'
|
|
|
+ '"Pilot Bunch Simulator" \n'
|
|
|
+ '"Header saved" \n'
|
|
|
+ '"T/H Delay" \n'
|
|
|
+ '"ADC 1 Delay" \n'
|
|
|
+ '"ADC 2 Delay" \n'
|
|
|
+ '"ADC 3 Delay" \n'
|
|
|
+ '"ADC 4 Delay" \n'
|
|
|
+ 'All of the description text entries in epics_log_entry_pvs, see above \n'
|
|
|
+ 'NOTE: These entries have to match the aforementioned strings exactly'
|
|
|
+ ]
|
|
|
+ machine_configs = ['bunches_per_turn',
|
|
|
+ 'save_header',
|
|
|
+ 'tRev']
|
|
|
+ ui_configs = ['language',
|
|
|
+ 'default_save_location',
|
|
|
+ 'default_subdirectory_name',
|
|
|
+ 'force_ask',
|
|
|
+ 'show_advanced_control']
|
|
|
+ logging_configs = ['epics_log_entry_pvs',
|
|
|
+ 'epics_test_pv',
|
|
|
+ 'epics_base_path',
|
|
|
+ 'default_log_entries']
|
|
|
+ machine_types = [int, bool, float]
|
|
|
+ ui_types = [str, str, str, bool, bool]
|
|
|
+ logging_types = [list, str, str, list]
|
|
|
+ def __init__(self):
|
|
|
+ super(ConfigSetup, self).__init__()
|
|
|
+ self.configs = []
|
|
|
+ self.result = False
|
|
|
+ self.resize(800, 600)
|
|
|
+ self.mainlayout = QtGui.QVBoxLayout()
|
|
|
+ # self.textEdit = QtGui.QTextEdit()
|
|
|
+ # self.layout.addWidget(self.textEdit)
|
|
|
+ # with open(os.path.dirname(__file__)+'/../config.cfg', 'r') as f:
|
|
|
+ # self.textEdit.setText(f.read())
|
|
|
+ self.setLayout(self.mainlayout)
|
|
|
+ self.scrollWidget = QtGui.QScrollArea()
|
|
|
+ self.heading = self.createLabel("Initial Configuration Setup")
|
|
|
+ self.heading.setStyleSheet("font-size:25pt;")
|
|
|
+ self.mainlayout.addWidget(self.heading)
|
|
|
+ self.mainlayout.addWidget(self.scrollWidget)
|
|
|
+ self.saveButton = self.createButton("save", connect=self.save)
|
|
|
+ self.mainlayout.addWidget(self.saveButton)
|
|
|
+
|
|
|
+ self.wid = QtGui.QWidget()
|
|
|
+ self.layout = QtGui.QVBoxLayout()
|
|
|
+ self.wid.setLayout(self.layout)
|
|
|
+
|
|
|
+ self.machine_label = self.createLabel("Machine")
|
|
|
+ self.machine_label.setStyleSheet("font-size: 20pt;")
|
|
|
+ self.layout.addWidget(self.machine_label)
|
|
|
+ self.configs.append("\n[Machine]")
|
|
|
+ for comm, conf, type in zip(self.machine_comments, self.machine_configs, self.machine_types):
|
|
|
+ self.configs.append(ConfigEntry(comm, conf, type))
|
|
|
+ self.layout.addWidget(self.configs[-1])
|
|
|
+
|
|
|
+
|
|
|
+ self.ui_label = self.createLabel("Ui")
|
|
|
+ self.ui_label.setStyleSheet("font-size: 20pt;")
|
|
|
+ self.layout.addWidget(self.ui_label)
|
|
|
+ self.configs.append("\n[Ui]")
|
|
|
+ for comm, conf, type in zip(self.ui_comments, self.ui_configs, self.ui_types):
|
|
|
+ self.configs.append(ConfigEntry(comm, conf, type))
|
|
|
+ self.layout.addWidget(self.configs[-1])
|
|
|
+
|
|
|
+ self.logging_label = self.createLabel("Logging")
|
|
|
+ self.logging_label.setStyleSheet("font-size:20pt;")
|
|
|
+ self.layout.addWidget(self.logging_label)
|
|
|
+ self.configs.append("\n[Logging]")
|
|
|
+ for comm, conf, type in zip(self.logging_comments, self.logging_configs, self.logging_types):
|
|
|
+ if conf == 'epics_log_entry_pvs' or conf == 'default_log_entries':
|
|
|
+ self.configs.append(ConfigEntry(comm, conf, type, multiline=True))
|
|
|
+ else:
|
|
|
+ self.configs.append(ConfigEntry(comm, conf, type))
|
|
|
+ self.layout.addWidget(self.configs[-1])
|
|
|
+
|
|
|
+
|
|
|
+ self.scrollWidget.setWidget(self.wid)
|
|
|
+ def save(self):
|
|
|
+ if not os.path.isdir(os.path.expanduser("~")+"/.kcg"):
|
|
|
+ os.mkdir(os.path.expanduser("~")+"/.kcg")
|
|
|
+
|
|
|
+ abort = False
|
|
|
+ for item in self.configs:
|
|
|
+ if type(item) == str:
|
|
|
+ continue
|
|
|
+ if not item.validate(mark=True):
|
|
|
+ abort = True
|
|
|
+ if abort:
|
|
|
+ return
|
|
|
+
|
|
|
+ with open(os.path.expanduser("~")+'/.kcg/config.cfg', 'w+') as f:
|
|
|
+ for item in self.configs:
|
|
|
+ f.write(str(item)+'\n')
|
|
|
+ self.result = True
|
|
|
+ self.close()
|
|
|
+
|
|
|
+
|