Source code for ccpn.ui.gui.popups.SimpleAttributeEditorPopupABC
"""
Abstract base class to easily implement a popup to edit attributes of V3 layer objects
"""
#=========================================================================================
# Licence, Reference and Credits
#=========================================================================================
__copyright__ = "Copyright (C) CCPN project (http://www.ccpn.ac.uk) 2014 - 2021"
__credits__ = ("Ed Brooksbank, Joanna Fox, Victoria A Higman, Luca Mureddu, Eliza Płoskoń",
"Timothy J Ragan, Brian O Smith, Gary S Thompson & Geerten W Vuister")
__licence__ = ("CCPN licence. See http://www.ccpn.ac.uk/v3-software/downloads/license")
__reference__ = ("Skinner, S.P., Fogh, R.H., Boucher, W., Ragan, T.J., Mureddu, L.G., & Vuister, G.W.",
"CcpNmr AnalysisAssign: a flexible platform for integrated NMR analysis",
"J.Biomol.Nmr (2016), 66, 111-124, http://doi.org/10.1007/s10858-016-0060-y")
#=========================================================================================
# Last code modification
#=========================================================================================
__modifiedBy__ = "$modifiedBy: Ed Brooksbank $"
__dateModified__ = "$dateModified: 2021-11-09 15:26:01 +0000 (Tue, November 09, 2021) $"
__version__ = "$Revision: 3.0.4 $"
#=========================================================================================
# Created
#=========================================================================================
__author__ = "$Author: CCPN $"
__date__ = "$Date: 2017-03-30 11:28:58 +0100 (Thu, March 30, 2017) $"
#=========================================================================================
# Start of code
#=========================================================================================
from functools import partial
from ccpn.ui.gui.lib.ChangeStateHandler import changeState
from ccpn.ui.gui.widgets.Label import Label
from ccpn.ui.gui.widgets.LineEdit import LineEdit
from ccpn.ui.gui.popups.Dialog import CcpnDialogMainWidget, _verifyPopupApply
from ccpn.core.lib.ContextManagers import queueStateChange
from ccpn.ui.gui.popups.AttributeEditorPopupABC import getAttributeTipText
from ccpn.util.Common import stringToCamelCase
[docs]class SimpleAttributeEditorPopupABC(CcpnDialogMainWidget):
"""
Abstract base class to implement a popup for editing simple properties
"""
klass = None # The class whose properties are edited/displayed
attributes = [] # A list of (attributeName, getFunction, setFunction, kwds) tuples;
# get/set-Function have getattr, setattr profile
# if setFunction is None: display attribute value without option to change value
# kwds: optional kwds passed to LineEdit constructor
hWidth = None
FIXEDWIDTH = True
FIXEDHEIGHT = True
def __init__(self, parent=None, mainWindow=None, obj=None, size=None, **kwds):
"""
Initialise the widget
"""
super().__init__(parent, setLayout=True,
windowTitle='Edit ' + self.klass.className, size=size, **kwds)
self.mainWindow = mainWindow
self.application = mainWindow.application
self.project = mainWindow.application.project
self.current = mainWindow.application.current
self.obj = obj
row = 0
self.labels = {} # An (attributeName, Label-widget) dict
self.edits = {} # An (attributeName, LineEdit-widget) dict
for _label, getFunction, setFunction, kwds in self.attributes:
# value = getFunction(self.obj, attr)
attr = stringToCamelCase(_label)
editable = setFunction is not None
self.labels[attr] = Label(self.mainWidget, _label, grid=(row, 0))
self.edits[attr] = LineEdit(self.mainWidget, textAlignment='left', editable=editable,
vAlign='t', grid=(row, 1), **kwds)
self.edits[attr].textChanged.connect(partial(self._queueSetValue, attr, getFunction, setFunction, row))
if self.hWidth:
self.labels[attr].setFixedWidth(self.hWidth)
tipText = getAttributeTipText(self.klass, attr)
self.labels[attr].setToolTip(tipText)
row += 1
# set up the required buttons for the dialog
self.setOkButton(callback=self._okClicked, enabled=False)
self.setCancelButton(callback=self._cancelClicked)
self.setHelpButton(callback=self._helpClicked, enabled=False)
if self.EDITMODE:
self.setRevertButton(callback=self._revertClicked, enabled=False)
self.setDefaultButton(CcpnDialogMainWidget.CANCELBUTTON)
# populate the widgets
self._populate()
# make the buttons appear
self.__postInit__()
self._okButton = self.dialogButtons.button(self.OKBUTTON)
self._cancelButton = self.dialogButtons.button(self.CANCELBUTTON)
self._helpButton = self.dialogButtons.button(self.HELPBUTTON)
self._revertButton = self.dialogButtons.button(self.RESETBUTTON)
def _populate(self):
"""Populate the widgets while blocking the queue changes dict
"""
self._changes.clear()
with self._changes.blockChanges():
for _label, getFunction, _, _ in self.attributes:
attr = stringToCamelCase(_label)
if getFunction and attr in self.edits:
value = getFunction(self.obj, attr)
self.edits[attr].setText(str(value) if value is not None else '')
def _getChangeState(self):
"""Get the change state from the _changes dict
"""
if not self._changes.enabled:
return None
applyState = True
revertState = False
allChanges = True if self._changes else False
return changeState(self, allChanges, applyState, revertState, self._okButton, None, self._revertButton, self._currentNumApplies)
@queueStateChange(_verifyPopupApply)
def _queueSetValue(self, attr, getFunction, setFunction, dim, _value):
"""Queue the function for setting the attribute in the calling object
"""
value = self.edits[attr].text()
oldValue = str(getFunction(self.obj, attr))
if value != oldValue:
return partial(self._setValue, attr, setFunction, value)
def _setValue(self, attr, setFunction, value):
"""Function for setting the attribute, called by _applyAllChanges
"""
setFunction(self.obj, attr, value)
def _refreshGLItems(self):
"""emit a signal to rebuild any required GL items
Not required here
"""
pass