def __init__(self, parent=None, editable=True, nullable=True, field_name='date', validator=DateValidator(), **kwargs): CustomEditor.__init__(self, parent) self.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) self.setObjectName(field_name) self.date_format = local_date_format() line_edit = DecoratedLineEdit() line_edit.setValidator(validator) line_edit.setObjectName('date_line_edit') line_edit.set_minimum_width( six.text_type( QtCore.QDate(2000, 12, 22).toString(self.date_format))) line_edit.setPlaceholderText( QtCore.QDate(2000, 1, 1).toString(self.date_format)) # The order of creation of this widgets and their parenting # seems very sensitive under windows and creates system crashes # so don't change this without extensive testing on windows special_date_menu = QtWidgets.QMenu(self) calendar_widget_action = QtWidgets.QWidgetAction(special_date_menu) self.calendar_widget = QtGui.QCalendarWidget(special_date_menu) self.calendar_widget.activated.connect(self.calendar_widget_activated) self.calendar_widget.clicked.connect(self.calendar_widget_activated) calendar_widget_action.setDefaultWidget(self.calendar_widget) self.calendar_action_trigger.connect(special_date_menu.hide) special_date_menu.addAction(calendar_widget_action) special_date_menu.addAction(_('Today')) special_date_menu.addAction(_('Far future')) self.special_date = QtWidgets.QToolButton(self) self.special_date.setIcon(self.special_date_icon.getQIcon()) self.special_date.setAutoRaise(True) self.special_date.setToolTip(_('Calendar and special dates')) self.special_date.setMenu(special_date_menu) self.special_date.setPopupMode(QtWidgets.QToolButton.InstantPopup) self.special_date.setFixedHeight(self.get_height()) self.special_date.setFocusPolicy(Qt.ClickFocus) # end of sensitive part if nullable: special_date_menu.addAction(_('Clear')) self.hlayout = QtWidgets.QHBoxLayout() self.hlayout.addWidget(line_edit) self.hlayout.addWidget(self.special_date) self.hlayout.setContentsMargins(0, 0, 0, 0) self.hlayout.setSpacing(0) self.hlayout.setAlignment(Qt.AlignRight | Qt.AlignVCenter) self.setContentsMargins(0, 0, 0, 0) self.setLayout(self.hlayout) self.minimum = datetime.date.min self.maximum = datetime.date.max self.setFocusProxy(line_edit) line_edit.editingFinished.connect(self.line_edit_finished) special_date_menu.triggered.connect(self.set_special_date)
class VirtualAddressEditor(CustomEditor): def __init__(self, parent=None, address_type=None, field_name='virtual_address', **kwargs): """ :param address_type: limit the allowed address to be entered to be of a certain time, can be 'phone', 'fax', 'email', 'mobile', 'pager'. If set to None, all types are allowed. Upto now, the corrected address returned by the address validator is not yet taken into account. """ CustomEditor.__init__(self, parent) self.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) self.setObjectName(field_name) self._address_type = address_type self.layout = QtWidgets.QHBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.combo = QtWidgets.QComboBox() self.combo.addItems(camelot.types.VirtualAddress.virtual_address_types) self.layout.addWidget(self.combo) self.editor = DecoratedLineEdit(self) self.editor.set_minimum_width(30) if address_type: self.combo.setVisible(False) idx = camelot.types.VirtualAddress.virtual_address_types.index( address_type) self.combo.setCurrentIndex(idx) self.layout.addWidget(self.editor) self.setFocusProxy(self.editor) nullIcon = Icon('tango/16x16/apps/internet-mail.png').getQIcon() self.label = QtWidgets.QToolButton() self.label.setIcon(nullIcon) self.label.setAutoRaise(True) self.label.setEnabled(False) self.label.setToolButtonStyle(Qt.ToolButtonIconOnly) self.label.setFocusPolicy(Qt.ClickFocus) self.label.clicked.connect(self.mail_click) self.label.hide() self.layout.addWidget(self.label) self.editor.editingFinished.connect(self.emit_editing_finished) self.combo.currentIndexChanged.connect(self.comboIndexChanged) self.setLayout(self.layout) self.update_validator() @QtCore.qt_slot() def comboIndexChanged(self): self.update_validator() self.emit_editing_finished() def set_value(self, value): value = CustomEditor.set_value(self, value) if value is None: self.editor.setText('') else: self.editor.setText(value[1]) idx = camelot.types.VirtualAddress.virtual_address_types.index( self._address_type or value[0]) self.combo.setCurrentIndex(idx) icon = Icon('tango/16x16/devices/printer.png').getQIcon() if six.text_type(self.combo.currentText()) == 'fax': icon = Icon('tango/16x16/devices/printer.png').getQIcon() if six.text_type(self.combo.currentText()) == 'email': icon = Icon('tango/16x16/apps/internet-mail.png').getQIcon() self.label.setIcon(icon) self.label.show() else: self.label.hide() self.label.setIcon(icon) self.label.setToolButtonStyle(Qt.ToolButtonIconOnly) self.update_validator() def get_value(self): address_value = six.text_type(self.editor.text()) if not len(address_value): value = None else: value = (six.text_type(self.combo.currentText()), address_value) return CustomEditor.get_value(self) or value def set_enabled(self, editable=True): self.combo.setEnabled(editable) self.editor.setEnabled(editable) if not editable: self.label.setEnabled(False) else: if self.combo.currentText() == 'email': self.label.setEnabled(True) def update_validator(self): address_type = six.text_type(self.combo.currentText()) validator = validators.get(address_type, any_character_validator) # change the validator instead of the regexp of the validator to inform # the editor it needs to update its background color self.editor.setValidator(validator) @QtCore.qt_slot() def mail_click(self): address = self.editor.text() url = QtCore.QUrl() url.setUrl(u'mailto:%s?subject=Subject' % six.text_type(address)) QtGui.QDesktopServices.openUrl(url) def emit_editing_finished(self): self.value = [] self.value.append(six.text_type(self.combo.currentText())) self.value.append(six.text_type(self.editor.text())) self.set_value(self.value) # emiting editingFinished without a value for the mechanism itself will lead to # integrity errors if self.value[1]: self.editingFinished.emit() def set_background_color(self, background_color): set_background_color_palette(self.editor, background_color) def set_field_attributes(self, **kwargs): super(VirtualAddressEditor, self).set_field_attributes(**kwargs) self.set_enabled(kwargs.get('editable', False)) self.setToolTip(six.text_type(kwargs.get('tooltip') or ''))