source: sasview/src/sas/qtgui/Perspectives/Fitting/ViewDelegate.py @ 085e3c9d

ESS_GUI_iss959
Last change on this file since 085e3c9d was 085e3c9d, checked in by Torin Cooper-Bennun <torin.cooper-bennun@…>, 6 years ago

improve S(Q) tab tree functionality

  • Property mode set to 100644
File size: 13.0 KB
Line 
1from PyQt5 import QtCore
2from PyQt5 import QtGui
3from PyQt5 import QtWidgets
4
5import sas.qtgui.Utilities.GuiUtils as GuiUtils
6
7import logging
8logger = logging.getLogger(__name__)
9
10class ModelViewDelegate(QtWidgets.QStyledItemDelegate):
11    """
12    Custom delegate for appearance and behavior control of the model view
13    """
14    def __init__(self, parent=None):
15        """
16        Overwrite generic constructor to allow for some globals
17        """
18        super(QtWidgets.QStyledItemDelegate, self).__init__()
19
20        # Main parameter table view columns
21        self.param_error=-1
22        self.param_property=0
23        self.param_value=1
24        self.param_min=2
25        self.param_max=3
26        self.param_unit=4
27
28    def fancyColumns(self):
29        return [self.param_value, self.param_min, self.param_max, self.param_unit]
30
31    def addErrorColumn(self):
32        """
33        Modify local column pointers
34        Note: the reverse is never required!
35        """
36        self.param_property=0
37        self.param_value=1
38        self.param_error=2
39        self.param_min=3
40        self.param_max=4
41        self.param_unit=5
42
43    def paint(self, painter, option, index):
44        """
45        Overwrite generic painter for certain columns
46        """
47        if index.column() in self.fancyColumns():
48            # Units - present in nice HTML
49            options = QtWidgets.QStyleOptionViewItem(option)
50            self.initStyleOption(options,index)
51
52            style = QtWidgets.QApplication.style() if options.widget is None else options.widget.style()
53
54            # Prepare document for inserting into cell
55            doc = QtGui.QTextDocument()
56
57            # Convert the unit description into HTML
58            text_html = GuiUtils.convertUnitToHTML(str(options.text))
59            doc.setHtml(text_html)
60
61            # delete the original content
62            options.text = ""
63            style.drawControl(QtWidgets.QStyle.CE_ItemViewItem, options, painter, options.widget);
64
65            context = QtGui.QAbstractTextDocumentLayout.PaintContext()
66            textRect = style.subElementRect(QtWidgets.QStyle.SE_ItemViewItemText, options)
67
68            painter.save()
69            painter.translate(textRect.topLeft())
70            painter.setClipRect(textRect.translated(-textRect.topLeft()))
71            # Draw the QTextDocument in the cell
72            doc.documentLayout().draw(painter, context)
73            painter.restore()
74        else:
75            # Just the default paint
76            QtWidgets.QStyledItemDelegate.paint(self, painter, option, index)
77
78    def createEditor(self, widget, option, index):
79        """
80        Overwrite generic editor for certain columns
81        """
82        if not index.isValid():
83            return 0
84        if index.column() == self.param_value: #only in the value column
85            editor = QtWidgets.QLineEdit(widget)
86            validator = GuiUtils.DoubleValidator()
87            editor.setValidator(validator)
88            return editor
89        if index.column() in [self.param_property, self.param_error, self.param_unit]:
90            # Set some columns uneditable
91            return None
92
93        return super(ModelViewDelegate, self).createEditor(widget, option, index)
94
95    def setModelData(self, editor, model, index):
96        """
97        Overwrite generic model update method for certain columns
98        """
99        if index.column() in (self.param_min, self.param_max):
100            try:
101                value_float = float(editor.text())
102            except ValueError:
103                # TODO: present the failure to the user
104                # balloon popup? tooltip? cell background colour flash?
105                return
106        QtWidgets.QStyledItemDelegate.setModelData(self, editor, model, index)
107
108class PolyViewDelegate(QtWidgets.QStyledItemDelegate):
109    """
110    Custom delegate for appearance and behavior control of the polydispersity view
111    """
112    POLYDISPERSE_FUNCTIONS = ['rectangle', 'array', 'lognormal', 'gaussian', 'schulz']
113
114    combo_updated = QtCore.pyqtSignal(str, int)
115    filename_updated = QtCore.pyqtSignal(int)
116
117    def __init__(self, parent=None):
118        """
119        Overwrite generic constructor to allow for some globals
120        """
121        super(QtWidgets.QStyledItemDelegate, self).__init__()
122
123        self.poly_parameter = 0
124        self.poly_pd = 1
125        self.poly_min = 2
126        self.poly_max = 3
127        self.poly_npts = 4
128        self.poly_nsigs = 5
129        self.poly_function = 6
130        self.poly_filename = 7
131
132    def editableParameters(self):
133        return [self.poly_pd, self.poly_min, self.poly_max, self.poly_npts, self.poly_nsigs]
134
135    def columnDict(self):
136        return {self.poly_pd:    'width',
137                self.poly_min:   'min',
138                self.poly_max:   'max',
139                self.poly_npts:  'npts',
140                self.poly_nsigs: 'nsigmas'}
141
142    def addErrorColumn(self):
143        """
144        Modify local column pointers
145        Note: the reverse is never required!
146        """
147        self.poly_parameter = 0
148        self.poly_pd = 1
149        self.poly_min = 3
150        self.poly_max = 4
151        self.poly_npts = 5
152        self.poly_nsigs = 6
153        self.poly_function = 7
154        self.poly_filename = 8
155
156    def createEditor(self, widget, option, index):
157        # Remember the current choice
158        if not index.isValid():
159            return 0
160        elif index.column() == self.poly_filename:
161            # Notify the widget that we want to change the filename
162            self.filename_updated.emit(index.row())
163            return None
164        elif index.column() in self.editableParameters():
165            self.editor = QtWidgets.QLineEdit(widget)
166            validator = GuiUtils.DoubleValidator()
167            self.editor.setValidator(validator)
168            return self.editor
169        else:
170            QtWidgets.QStyledItemDelegate.createEditor(self, widget, option, index)
171
172    def paint(self, painter, option, index):
173        """
174        Overwrite generic painter for certain columns
175        """
176        if index.column() in (self.poly_min, self.poly_max):
177            # Units - present in nice HTML
178            options = QtWidgets.QStyleOptionViewItem(option)
179            self.initStyleOption(options,index)
180
181            style = QtWidgets.QApplication.style() if options.widget is None else options.widget.style()
182
183            # Prepare document for inserting into cell
184            doc = QtGui.QTextDocument()
185
186            # Convert the unit description into HTML
187            text_html = GuiUtils.convertUnitToHTML(str(options.text))
188            doc.setHtml(text_html)
189
190            # delete the original content
191            options.text = ""
192            style.drawControl(QtWidgets.QStyle.CE_ItemViewItem, options, painter, options.widget);
193
194            context = QtGui.QAbstractTextDocumentLayout.PaintContext()
195            textRect = style.subElementRect(QtWidgets.QStyle.SE_ItemViewItemText, options)
196
197            painter.save()
198            painter.translate(textRect.topLeft())
199            painter.setClipRect(textRect.translated(-textRect.topLeft()))
200            # Draw the QTextDocument in the cell
201            doc.documentLayout().draw(painter, context)
202            painter.restore()
203        else:
204            # Just the default paint
205            QtWidgets.QStyledItemDelegate.paint(self, painter, option, index)
206
207class MagnetismViewDelegate(QtWidgets.QStyledItemDelegate):
208    """
209    Custom delegate for appearance and behavior control of the magnetism view
210    """
211    def __init__(self, parent=None):
212        """
213        Overwrite generic constructor to allow for some globals
214        """
215        super(QtWidgets.QStyledItemDelegate, self).__init__()
216
217        self.mag_parameter = 0
218        self.mag_value = 1
219        self.mag_min = 2
220        self.mag_max = 3
221        self.mag_unit = 4
222
223    def editableParameters(self):
224        return [self.mag_value, self.mag_min, self.mag_max]
225
226    def addErrorColumn(self):
227        """
228        Modify local column pointers
229        Note: the reverse is never required!
230        """
231        self.mag_parameter = 0
232        self.mag_value = 1
233        self.mag_min = 3
234        self.mag_max = 4
235        self.mag_unit = 5
236
237    def createEditor(self, widget, option, index):
238        # Remember the current choice
239        current_text = index.data()
240        if not index.isValid():
241            return 0
242        if index.column() in self.editableParameters():
243            editor = QtWidgets.QLineEdit(widget)
244            validator = GuiUtils.DoubleValidator()
245            editor.setValidator(validator)
246            return editor
247        else:
248            QtWidgets.QStyledItemDelegate.createEditor(self, widget, option, index)
249
250    def paint(self, painter, option, index):
251        """
252        Overwrite generic painter for certain columns
253        """
254        if index.column() in (self.mag_min, self.mag_max, self.mag_unit):
255            # Units - present in nice HTML
256            options = QtWidgets.QStyleOptionViewItem(option)
257            self.initStyleOption(options,index)
258
259            style = QtWidgets.QApplication.style() if options.widget is None else options.widget.style()
260
261            # Prepare document for inserting into cell
262            doc = QtGui.QTextDocument()
263
264            # Convert the unit description into HTML
265            text_html = GuiUtils.convertUnitToHTML(str(options.text))
266            doc.setHtml(text_html)
267
268            # delete the original content
269            options.text = ""
270            style.drawControl(QtWidgets.QStyle.CE_ItemViewItem, options, painter, options.widget);
271
272            context = QtGui.QAbstractTextDocumentLayout.PaintContext()
273            textRect = style.subElementRect(QtWidgets.QStyle.SE_ItemViewItemText, options)
274
275            painter.save()
276            painter.translate(textRect.topLeft())
277            painter.setClipRect(textRect.translated(-textRect.topLeft()))
278            # Draw the QTextDocument in the cell
279            doc.documentLayout().draw(painter, context)
280            painter.restore()
281        else:
282            # Just the default paint
283            QtWidgets.QStyledItemDelegate.paint(self, painter, option, index)
284
285class StructureViewDelegate(QtWidgets.QStyledItemDelegate):
286    """
287    Custom delegate for appearance and behaviour control of the structure
288    factor options view
289    """
290    def __init__(self, parent=None):
291        """
292        Override parent constructor
293        """
294
295        super(StructureViewDelegate, self).__init__()
296
297        self.fittingWidget = parent
298
299    def paint(self, painter, option, index):
300        """
301        Override generic painter
302        """
303        # TODO override this with something useful ... ?
304        super(StructureViewDelegate, self).paint(
305            painter, option, index
306        )
307
308    def createEditor(self, parent, option, index):
309        """
310        Override generic createEditor -- certain elements have combo boxes
311        """
312        print("gotta create me an editor")
313
314        model = self.fittingWidget.structureView.model()
315
316        if index.parent():
317            # we only care about child items since we don't edit top-level
318            # items in this view anyway
319            print("the item has a parent")
320
321            if index.column() == 1:
322                print("the item's col. is 1")
323                # col. 1 contains elements that may be combo boxes
324
325                # navigate to the parameter name through the parent item (it'll
326                # be on the same row, but col. 0)
327                parent_item = model.itemFromIndex(index.parent())
328                param_item = parent_item.child(index.row(), 0)
329
330                if param_item.text() == "mixture":
331                    print("gonna do a mixture combo box")
332                    # TODO: ONLY TEMPORARY EXAMPLE STUFF HERE RIGHT NOW
333                    cbox = QtWidgets.QComboBox(parent)
334                    cbox.addItems([
335                        "P(Q)*S(Q)",
336                        "P(Q)+S(Q)",
337                        "custom"
338                    ])
339                    return cbox
340
341                elif param_item.text() == "effective radius":
342                    print("gonna do an effective radius combo box")
343                    # TODO: ONLY TEMPORARY EXAMPLE STUFF HERE RIGHT NOW
344                    cbox = QtWidgets.QComboBox(parent)
345                    cbox.addItems([
346                        "ER_mean_curvature",
347                        "ER_equivalent_sphere",
348                        "ER_maximum_radius",
349                        "ER_minimum_radius"
350                    ])
351                    return cbox
352
353                elif param_item.text() == "volume fraction":
354                    print("gonna do a volume fraction combo box")
355                    # TODO: ONLY TEMPORARY EXAMPLE STUFF HERE RIGHT NOW
356                    cbox = QtWidgets.QComboBox(parent)
357                    cbox.addItems([
358                        "VR_something",
359                        "VR_something_else",
360                        "VR_something_completely_different"
361                    ])
362                    return cbox
363
364        # return default otherwise
365        print("let's do a normal thing instead")
366        return super(StructureViewDelegate, self).createEditor(
367            parent, option, index
368        )
Note: See TracBrowser for help on using the repository browser.