"""
GUI elements that help with atomic symbols
Copyright Schrodinger, LLC. All rights reserved.
"""
import string
from schrodinger.application.matsci import atomicsymbols
from schrodinger.Qt import QtGui
from schrodinger.ui.qt import swidgets
[docs]class ElementValidator(swidgets.EnforcingValidatorMixin, QtGui.QValidator):
"""
A QValidator to check if the input is a partial or valid atomic symbol.
Partial symbols are 1- or 2-(Uu) letter strings that could begin a valid
atomic symbol.
"""
[docs] def validate(self, text, pos):
"""
Check if the text is a partial or valid atomic symbol. Partial symbols
are strings that could begin a valid atomic symbol.
See PyQt documentation for argument and return value documentation.
"""
check = str(text)
if check in atomicsymbols.ATOMIC_SYMBOLS:
self.last_valid_value = check
return (self.Acceptable, text, pos)
elif check in atomicsymbols.SYMBOL_START or not check:
return (self.Intermediate, text, pos)
else:
return (self.Invalid, text, pos)
[docs]class AtomNameLabelValidator(swidgets.EnforcingValidatorMixin,
QtGui.QValidator):
"""
Manage validation of a atom name label.
"""
VALID_LABEL_PUNCTUATION = '_()[]'
[docs] def __init__(self, *args, **kwargs):
"""
Overwrite parent to set the valid label characters dictionary on
creation
"""
super().__init__(*args, **kwargs)
self.valid_label_chars = {
x for x in string.ascii_letters + string.digits +
self.VALID_LABEL_PUNCTUATION
}
[docs] def validate(self, value, position):
"""
See PyQt documentation for arguments and return values.
"""
if not value:
return self.Intermediate, value, position
if all(x in self.valid_label_chars for x in value):
return self.Acceptable, value, position
else:
return self.Invalid, value, position
[docs]class ElementListValidator(swidgets.EnforcingValidatorMixin, QtGui.QValidator):
"""
A QValidator to check if the inputs from a lineedit is a valid atomic symbols
separated by comma. Empty lines are treated as intermediate state. All symbols
are invalid. If input is not in atomicsymbol.ATOMIC_SYMBOLS then consider it
intermediate state. All other states are consider valid state.
"""
[docs] def validate(self, text, pos):
"""
Check if the text is a valid atomic symbols separated by comma.
See PyQt documentation for argument and return value documentation.
"""
check = str(text)
for token in check.split(','):
if token.strip() == '':
# An empty edit is temporarily acceptable
return (self.Intermediate, text, pos)
if not token.strip().isalpha():
# Non-letters data is not OK
return (self.Invalid, text, pos)
if token.strip() not in atomicsymbols.ATOMIC_SYMBOLS:
# Only letters, intermediate state
return (self.Intermediate, text, pos)
self.last_valid_value = check
return (self.Acceptable, text, pos)
[docs]class ElementEdit(swidgets.SLineEdit):
"""
A QLineEdit that only accepts atomic symbols and always contains the last
valid value when it loses keyboard focus
"""
[docs] def __init__(self, default, layout=None, **kwargs):
"""
Create an ElementEdit instance
:type default: str
:param default: Default atomic symbol
:type layout: QBoxLayout
:param layout: The layout to place this line edit into
"""
dator = ElementValidator()
swidgets.SLineEdit.__init__(self,
default,
validator=dator,
width=30,
always_valid=True,
layout=layout,
**kwargs)
[docs]class ElementListEdit(swidgets.SLabeledEdit):
"""
A QLineEdit that only accepts atomic symbols and always contains the last
valid value when it loses keyboard focus
"""
[docs] def __init__(self, text, layout=None, **kwargs):
"""
Create an ElementEdit instance
:type default: str
:param default: Default atomic symbol
:type layout: QBoxLayout
:param layout: The layout to place this line edit into
"""
dator = ElementListValidator()
super(ElementListEdit, self).__init__(text=text,
validator=dator,
layout=layout,
**kwargs)
[docs]class CoarseGrainNameEdit(swidgets.SLineEdit):
"""
A QLineEdit that only accepts valid coarse grain names and always contains
the last valid value when it loses keyboard focus
"""
[docs] def __init__(self, default, layout=None, **kwargs):
"""
Create an CoarseGrainNameEdit instance
:type default: str
:param default: Default atomic symbol
:type layout: QBoxLayout
:param layout: The layout to place this line edit into
"""
dator = AtomNameLabelValidator()
swidgets.SLineEdit.__init__(self,
default,
validator=dator,
width=50,
always_valid=True,
layout=layout,
**kwargs)