1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 """Contains classes for using custom delegates"""
29
30 import logging
31
32 logger = logging.getLogger('camelot.view.controls.delegates')
33
34 from PyQt4 import QtGui
35 from PyQt4 import QtCore
36 from PyQt4.QtCore import Qt
37
38 import datetime
39 import StringIO
40
41 import camelot.types
42 from camelot.view.controls import editors
43 from camelot.view.model_thread import get_model_thread
44
45
46 """Dictionary mapping widget types to an associated delegate"""
47
48 _registered_delegates_ = {}
49 verbose = False
50
52 text = index.model().data(index, Qt.DisplayRole).toString()
53 color = QtGui.QColor(235, 233, 237)
54 painter.save()
55
56 painter.fillRect(option.rect, color)
57 painter.setPen(QtGui.QColor(Qt.darkGray))
58 painter.drawText(option.rect.x()+2,
59 option.rect.y(),
60 option.rect.width()-4,
61 option.rect.height(),
62 Qt.AlignVCenter,
63 text)
64
65 painter.restore()
66
68 return lambda:constant
69
70
72 """Manages custom delegates"""
73
77
79 self.columnsdesc = columnsdesc
80
82 """Inserts a custom column delegate"""
83 if verbose:
84 logger.debug('inserting delegate for column %s' % column)
85 delegate.setParent(self)
86 self.delegates[column] = delegate
87 self.connect(delegate, QtCore.SIGNAL('commitData(QWidget*)'), self.commitData)
88 self.connect(delegate, QtCore.SIGNAL('closeEditor(QWidget*)'), self.closeEditor)
89
91 self.emit(QtCore.SIGNAL('commitData(QWidget*)'), editor)
92
94 self.emit(QtCore.SIGNAL('closeEditor(QWidget*)'), editor)
95
97 """Removes custom column delegate"""
98 logger.debug('removing a new custom column delegate')
99 if column in self.delegates:
100 del self.delegates[column]
101
102 - def paint(self, painter, option, index):
103 """Use a custom delegate paint method if it exists"""
104 delegate = self.delegates.get(index.column())
105 if delegate is not None:
106 delegate.paint(painter, option, index)
107 else:
108 QtGui.QItemDelegate.paint(self, painter, option, index)
109
111 """Use a custom delegate createEditor method if it exists"""
112 delegate = self.delegates.get(index.column())
113 if delegate is not None:
114 return delegate.createEditor(parent, option, index)
115 else:
116 QtGui.QItemDelegate.createEditor(self, parent, option, index)
117
119 """Use a custom delegate setEditorData method if it exists"""
120 if verbose:
121 logger.debug('setting editor data for column %s' % index.column())
122 delegate = self.delegates.get(index.column())
123 if delegate is not None:
124 if verbose:
125 logger.debug('got delegate')
126 delegate.setEditorData(editor, index)
127 else:
128 QtGui.QItemDelegate.setEditorData(self, editor, index)
129 if verbose:
130 logger.debug('data set')
131
133 """Use a custom delegate setModelData method if it exists"""
134 logger.debug('setting model data for column %s' % index.column())
135 delegate = self.delegates.get(index.column())
136 if delegate is not None:
137 delegate.setModelData(editor, model, index)
138 else:
139 QtGui.QItemDelegate.setModelData(self, editor, model, index)
140
142 option = QtGui.QStyleOptionViewItem()
143 delegate = self.delegates.get(index.column())
144 if delegate is not None:
145 return delegate.sizeHint(option, index)
146 else:
147 return QtGui.QItemDelegate.sizeHint(option, index)
148
149
151 """Custom delegate for integer values"""
152
153 - def __init__(self, minimum=0, maximum=100, parent=None):
157
159 editor = QtGui.QSpinBox(parent)
160 editor.setRange(self.minimum, self.maximum)
161 editor.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
162 return editor
163
167
171
172 _registered_delegates_[QtGui.QSpinBox] = IntegerColumnDelegate
173
174
175 -class PlainTextColumnDelegate(QtGui.QItemDelegate):
176 """Custom delegate for simple string values"""
177
178 - def __init__(self, maxlength=None, parent=None):
179 super(PlainTextColumnDelegate, self).__init__(parent)
180 self.maxlength = maxlength
181
182 - def paint(self, painter, option, index):
183 if (option.state & QtGui.QStyle.State_Selected):
184 QtGui.QItemDelegate.paint(self, painter, option, index)
185 elif not self.parent().columnsdesc[index.column()][1]['editable']:
186 _paint_not_editable(painter, option, index)
187 else:
188 QtGui.QItemDelegate.paint(self, painter, option, index)
189
190 - def createEditor(self, parent, option, index):
191 editor = QtGui.QLineEdit(parent)
192 editor.setMaxLength(self.maxlength)
193 if not self.parent().columnsdesc[index.column()][1]['editable']:
194 editor.setEnabled(False)
195 return editor
196
197 - def setEditorData(self, editor, index):
198 value = index.model().data(index, Qt.EditRole).toString()
199 editor.setText(value)
200
201 - def setModelData(self, editor, model, index):
202 model.setData(index, create_constant_function(unicode(editor.text())))
203
204 _registered_delegates_[QtGui.QLineEdit] = PlainTextColumnDelegate
205
206
208 - def __init__(self, format, default, nullable, parent=None):
209 super(TimeColumnDelegate, self).__init__(parent)
210 self.nullable = nullable
211 self.format = format
212 self.default = default
213
215 editor = QtGui.QTimeEdit(parent)
216 editor.setDisplayFormat(self.format)
217 return editor
218
220 value = index.model().data(index, Qt.EditRole).toTime()
221 editor.index = index
222 if value:
223 editor.setTime(value)
224 else:
225 editor.setTime(editor.minimumTime())
226
231
232
234 - def __init__(self, parent, format, nullable, **kwargs):
237
239 editor = QtGui.QDateTimeEdit(parent)
240 editor.setDisplayFormat(self.format)
241 return editor
242
244 value = index.model().data(index, Qt.EditRole).toDateTime()
245 if value:
246 editor.setDateTime(value)
247 else:
248 editor.setDateTime(editor.minimumDateTime())
249
250
252 """Custom delegate for date values"""
253
254 - def __init__(self,
255 format='dd/MM/yyyy',
256 default=None,
257 nullable=True,
258 parent=None):
259
260 super(DateColumnDelegate, self).__init__(parent)
261 self.format = format
262 self.default = default
263 self.nullable = nullable
264
269
271 editor = self.sender()
272 self.emit(QtCore.SIGNAL('commitData(QWidget*)'), editor)
273
274
282
293
294 _registered_delegates_[editors.DateEditor] = DateColumnDelegate
295
296
298 - def __init__(self, parts, parent=None):
302
307
309 editor = self.sender()
310 self.emit(QtCore.SIGNAL('commitData(QWidget*)'), editor)
311
312
314 value = index.data(Qt.EditRole).toPyObject()
315 if value:
316 for part_editor, part in zip(editor.part_editors, value):
317 part_editor.setText(unicode(part))
318
320 return self._dummy_editor.sizeHint()
321
327
328 _registered_delegates_[editors.CodeEditor] = CodeColumnDelegate
329
330
334
336 editor = self.sender()
337 self.emit(QtCore.SIGNAL('commitData(QWidget*)'), editor)
338
339
344
350
354
355 _registered_delegates_[editors.VirtualAddressEditor] = \
356 VirtualAddressColumnDelegate
357
358
360 """Custom delegate for float values"""
361
362 - def __init__(self, minimum=-100.0, maximum=100.0, precision=3,
363 editable=True, parent=None, **kwargs):
364 super(FloatColumnDelegate, self).__init__(parent)
365 self.minimum = minimum
366 self.maximum = maximum
367 self.precision = precision
368 self.editable = editable
369
371 editor = QtGui.QDoubleSpinBox(parent)
372 editor.setReadOnly(self.editable==False)
373 editor.setRange(self.minimum, self.maximum)
374 editor.setDecimals(self.precision)
375 editor.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
376 editor.setSingleStep(1.0)
377 return editor
378
382
386
387 _registered_delegates_[QtGui.QDoubleSpinBox] = FloatColumnDelegate
388
389
391 """Custom delegate for many 2 one relations"""
392
393 - def __init__(self, admin, embedded=False, parent=None, **kwargs):
401
409
412
414 if editor.entity_instance_getter:
415 model.setData(index, editor.entity_instance_getter)
416
418 editor = self.sender()
419 self.emit(QtCore.SIGNAL('commitData(QWidget*)'), editor)
420
422 return self._dummy_editor.sizeHint()
423
424 _registered_delegates_[editors.Many2OneEditor] = Many2OneColumnDelegate
425
426
428 """Custom delegate for many 2 one relations"""
429
430 - def __init__(self, parent=None, **kwargs):
435
441
447
450
451 _registered_delegates_[editors.One2ManyEditor] = One2ManyColumnDelegate
452
453
455 """Custom delegate for boolean values"""
456
459
461 editor = QtGui.QCheckBox(parent)
462 return editor
463
465 checked = index.model().data(index, Qt.EditRole).toBool()
466 editor.setChecked(checked)
467
470
471 - def paint(self, painter, option, index):
472 painter.save()
473 self.drawBackground(painter, option, index)
474 checked = index.model().data(index, Qt.EditRole).toBool()
475 check_option = QtGui.QStyleOptionButton()
476 check_option.rect = option.rect
477 check_option.palette = option.palette
478 if checked:
479 check_option.state = option.state | QtGui.QStyle.State_On
480 else:
481 check_option.state = option.state | QtGui.QStyle.State_Off
482 QtGui.QApplication.style().drawControl(QtGui.QStyle.CE_CheckBox, check_option, painter)
483 painter.restore()
484
485 _registered_delegates_[QtGui.QCheckBox] = BoolColumnDelegate
486
487
493
495 s = StringIO.StringIO()
496 data = index.data(Qt.EditRole).toPyObject()
497 if data:
498 editor.image = data.image
499 data = data.image.copy()
500 data.thumbnail((100, 100))
501 data.save(s, 'png')
502 s.seek(0)
503 pixmap = QtGui.QPixmap()
504 pixmap.loadFromData(s.read())
505 s.close()
506 editor.setPixmap(pixmap)
507 else:
508
509 editor.clearFirstImage()
510
512 editor = self.sender()
513 self.emit(QtCore.SIGNAL('commitData(QWidget*)'), editor)
514
515
518
519 _registered_delegates_[editors.ImageEditor] = ImageColumnDelegate
520
521
522 -class RichTextColumnDelegate(QtGui.QItemDelegate):
523 - def __init__(self, parent = None, **kwargs):
524 super(RichTextColumnDelegate, self).__init__(parent)
525 self.kwargs = kwargs
526
527 - def createEditor(self, parent, option, index):
528 editor = editors.RichTextEditor(parent, **self.kwargs)
529 self.connect(editor, QtCore.SIGNAL('editingFinished()'), self.commitAndCloseEditor)
530 return editor
531
533 editor = self.sender()
534 self.emit(QtCore.SIGNAL('commitData(QWidget*)'), editor)
535
536
537 - def setEditorData(self, editor, index):
538 html = index.model().data(index, Qt.EditRole).toString()
539 if html:
540 editor.setHtml(html)
541 else:
542 editor.clear()
543
544 - def setModelData(self, editor, model, index):
546
547 _registered_delegates_[editors.RichTextEditor] = RichTextColumnDelegate
548
549
551 - def __init__(self, choices, parent=None, **kwargs):
554
556 if variant.canConvert(QtCore.QVariant.String):
557 return unicode(variant.toString())
558 else:
559 return variant.toPyObject()
560
562 editor = QtGui.QComboBox(parent)
563
564 def create_choices_getter(model, row):
565
566 def getChoices():
567 return list(self.choices(model._get_object(row)))
568
569 return getChoices
570
571 def create_choices_setter(editor):
572
573 def setChoices(choices):
574 allready_in_combobox = dict((self.qvariantToPython(editor.itemData(i)),i) for i in range(editor.count()))
575 for i,(value,name) in enumerate(choices):
576 if value not in allready_in_combobox:
577 editor.insertItem(i, unicode(name), QtCore.QVariant(value))
578 else:
579
580
581 editor.setItemText(i, unicode(name))
582
583 return setChoices
584
585 get_model_thread().post(create_choices_getter(index.model(), index.row()), create_choices_setter(editor))
586 return editor
587
589 data = self.qvariantToPython(index.model().data(index, Qt.EditRole))
590 if data!=None:
591 for i in range(editor.count()):
592 if data == self.qvariantToPython(editor.itemData(i)):
593 editor.setCurrentIndex(i)
594 return
595
596
597
598 editor.insertItem(editor.count(), '...', QtCore.QVariant(data))
599 editor.setCurrentIndex(editor.count()-1)
600
604
605 _registered_delegates_[QtGui.QComboBox] = ComboBoxColumnDelegate
606