from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5 import QtWidgets
import sas.qtgui.Utilities.GuiUtils as GuiUtils
[docs]class ModelViewDelegate(QtWidgets.QStyledItemDelegate):
"""
Custom delegate for appearance and behavior control of the model view
"""
[docs] def __init__(self, parent=None):
"""
Overwrite generic constructor to allow for some globals
"""
super(ModelViewDelegate, self).__init__()
# Main parameter table view columns
self.param_error=-1
self.param_property=0
self.param_value=1
self.param_min=2
self.param_max=3
self.param_unit=4
[docs] def fancyColumns(self):
return [self.param_value, self.param_min, self.param_max, self.param_unit]
[docs] def addErrorColumn(self):
"""
Modify local column pointers
Note: the reverse is never required!
"""
self.param_property=0
self.param_value=1
self.param_error=2
self.param_min=3
self.param_max=4
self.param_unit=5
[docs] def paint(self, painter, option, index):
"""
Overwrite generic painter for certain columns
"""
if index.column() in self.fancyColumns():
# Units - present in nice HTML
options = QtWidgets.QStyleOptionViewItem(option)
self.initStyleOption(options,index)
style = QtWidgets.QApplication.style() if options.widget is None else options.widget.style()
# Prepare document for inserting into cell
doc = QtGui.QTextDocument()
# Convert the unit description into HTML
text_html = GuiUtils.convertUnitToHTML(str(options.text))
doc.setHtml(text_html)
doc.setDocumentMargin(1)
# delete the original content
options.text = ""
style.drawControl(QtWidgets.QStyle.CE_ItemViewItem, options, painter, options.widget);
context = QtGui.QAbstractTextDocumentLayout.PaintContext()
textRect = style.subElementRect(QtWidgets.QStyle.SE_ItemViewItemText, options)
painter.save()
rect = textRect.topLeft()
x = rect.x()
y = rect.y()
x += 3 # magic value for rendering nice display in the table
y += 2 # magic value for rendering nice display in the table
rect.setX(x)
rect.setY(y)
painter.translate(rect)
painter.setClipRect(textRect.translated(-rect))
# Draw the QTextDocument in the cell
doc.documentLayout().draw(painter, context)
painter.restore()
else:
# Just the default paint
QtWidgets.QStyledItemDelegate.paint(self, painter, option, index)
[docs] def createEditor(self, widget, option, index):
"""
Overwrite generic editor for certain columns
"""
if not index.isValid():
return 0
if index.column() == self.param_value: #only in the value column
editor = QtWidgets.QLineEdit(widget)
validator = GuiUtils.DoubleValidator()
editor.setValidator(validator)
return editor
if index.column() in [self.param_property, self.param_error, self.param_unit]:
# Set some columns uneditable
return None
if index.column() in (self.param_min, self.param_max):
# Check if the edit role is set
if not (index.flags() & QtCore.Qt.ItemIsEditable):
return None
return super(ModelViewDelegate, self).createEditor(widget, option, index)
[docs] def setModelData(self, editor, model, index):
"""
Overwrite generic model update method for certain columns
"""
if index.column() in (self.param_min, self.param_max):
try:
value_float = float(editor.text())
except ValueError:
# TODO: present the failure to the user
# balloon popup? tooltip? cell background colour flash?
return
QtWidgets.QStyledItemDelegate.setModelData(self, editor, model, index)
[docs]class PolyViewDelegate(QtWidgets.QStyledItemDelegate):
"""
Custom delegate for appearance and behavior control of the polydispersity view
"""
POLYDISPERSE_FUNCTIONS = ['rectangle', 'array', 'lognormal', 'gaussian', 'schulz']
combo_updated = QtCore.pyqtSignal(str, int)
filename_updated = QtCore.pyqtSignal(int)
[docs] def __init__(self, parent=None):
"""
Overwrite generic constructor to allow for some globals
"""
super(PolyViewDelegate, self).__init__()
self.poly_parameter = 0
self.poly_pd = 1
self.poly_error = None
self.poly_min = 2
self.poly_max = 3
self.poly_npts = 4
self.poly_nsigs = 5
self.poly_function = 6
self.poly_filename = 7
[docs] def editableParameters(self):
return [self.poly_pd, self.poly_min, self.poly_max, self.poly_npts, self.poly_nsigs]
[docs] def columnDict(self):
return {self.poly_pd: 'width',
self.poly_min: 'min',
self.poly_max: 'max',
self.poly_npts: 'npts',
self.poly_nsigs: 'nsigmas'}
[docs] def addErrorColumn(self):
"""
Modify local column pointers
Note: the reverse is never required!
"""
self.poly_parameter = 0
self.poly_pd = 1
self.poly_error = 2
self.poly_min = 3
self.poly_max = 4
self.poly_npts = 5
self.poly_nsigs = 6
self.poly_function = 7
self.poly_filename = 8
[docs] def createEditor(self, widget, option, index):
# Remember the current choice
if not index.isValid():
return 0
elif index.column() == self.poly_filename:
# Notify the widget that we want to change the filename
self.filename_updated.emit(index.row())
return None
elif index.column() in self.editableParameters():
self.editor = QtWidgets.QLineEdit(widget)
validator = GuiUtils.DoubleValidator()
self.editor.setValidator(validator)
return self.editor
else:
QtWidgets.QStyledItemDelegate.createEditor(self, widget, option, index)
[docs] def paint(self, painter, option, index):
"""
Overwrite generic painter for certain columns
"""
if index.column() in (self.poly_pd, self.poly_min, self.poly_max):
# Units - present in nice HTML
options = QtWidgets.QStyleOptionViewItem(option)
self.initStyleOption(options,index)
style = QtWidgets.QApplication.style() if options.widget is None else options.widget.style()
# Prepare document for inserting into cell
doc = QtGui.QTextDocument()
current_font = painter.font()
doc.setDefaultFont(current_font)
# Convert the unit description into HTML
text_html = GuiUtils.convertUnitToHTML(str(options.text))
doc.setHtml(text_html)
# delete the original content
options.text = ""
style.drawControl(QtWidgets.QStyle.CE_ItemViewItem, options, painter, options.widget);
context = QtGui.QAbstractTextDocumentLayout.PaintContext()
textRect = style.subElementRect(QtWidgets.QStyle.SE_ItemViewItemText, options)
painter.save()
rect = textRect.topLeft()
y = rect.y()
y += 5.0 # magic value for rendering nice display in the table
rect.setY(y)
painter.translate(rect)
painter.setClipRect(textRect.translated(-rect))
# Draw the QTextDocument in the cell
doc.documentLayout().draw(painter, context)
painter.restore()
else:
# Just the default paint
QtWidgets.QStyledItemDelegate.paint(self, painter, option, index)
[docs]class MagnetismViewDelegate(QtWidgets.QStyledItemDelegate):
"""
Custom delegate for appearance and behavior control of the magnetism view
"""
[docs] def __init__(self, parent=None):
"""
Overwrite generic constructor to allow for some globals
"""
super(MagnetismViewDelegate, self).__init__()
self.mag_parameter = 0
self.mag_value = 1
self.mag_min = 2
self.mag_max = 3
self.mag_unit = 4
[docs] def editableParameters(self):
return [self.mag_value, self.mag_min, self.mag_max]
[docs] def addErrorColumn(self):
"""
Modify local column pointers
Note: the reverse is never required!
"""
self.mag_parameter = 0
self.mag_value = 1
self.mag_min = 3
self.mag_max = 4
self.mag_unit = 5
[docs] def createEditor(self, widget, option, index):
# Remember the current choice
current_text = index.data()
if not index.isValid():
return 0
if index.column() in self.editableParameters():
editor = QtWidgets.QLineEdit(widget)
validator = GuiUtils.DoubleValidator()
editor.setValidator(validator)
return editor
else:
QtWidgets.QStyledItemDelegate.createEditor(self, widget, option, index)
[docs] def paint(self, painter, option, index):
"""
Overwrite generic painter for certain columns
"""
if index.column() in (self.mag_value, self.mag_min, self.mag_max, self.mag_unit):
# Units - present in nice HTML
options = QtWidgets.QStyleOptionViewItem(option)
self.initStyleOption(options,index)
style = QtWidgets.QApplication.style() if options.widget is None else options.widget.style()
# Prepare document for inserting into cell
doc = QtGui.QTextDocument()
current_font = painter.font()
doc.setDefaultFont(current_font)
# Convert the unit description into HTML
text_html = GuiUtils.convertUnitToHTML(str(options.text))
doc.setHtml(text_html)
# delete the original content
options.text = ""
style.drawControl(QtWidgets.QStyle.CE_ItemViewItem, options, painter, options.widget);
context = QtGui.QAbstractTextDocumentLayout.PaintContext()
textRect = style.subElementRect(QtWidgets.QStyle.SE_ItemViewItemText, options)
painter.save()
rect = textRect.topLeft()
y = rect.y()
y += 6.0 # magic value for rendering nice display in the table
rect.setY(y)
painter.translate(rect)
painter.setClipRect(textRect.translated(-rect))
# Draw the QTextDocument in the cell
doc.documentLayout().draw(painter, context)
painter.restore()
else:
# Just the default paint
QtWidgets.QStyledItemDelegate.paint(self, painter, option, index)