def set_client(self, record, value, test_state=True): internal = record.values[self.name] self.set(record, value, test_state) digits = self.attrs.get('digits', (14, 2)) # Use floatToText as the comparison we inherited from the GTK client failed for us in some cases # were python was considering the difference between 145,13 and 145,12 as 0,009999999 instead of 0,01 # Converting to string the numbers with the appropiate number of digits make it much easier. if Numeric.floatToText(internal, digits) != Numeric.floatToText( record.values[self.name], digits): if not record.isFieldReadOnly(self.name): self.changed(record)
def updateAggregates(self): if self.treeModel.group and self.aggregates: if self.treeModel.group.unloadedIds(): self.uiUpdateAggregates.show() calculate = False else: self.uiUpdateAggregates.hide() calculate = True else: calculate = False self.uiUpdateAggregates.hide() for agg in self.aggregates: # As we don't want the aggregates to force loading all records # don't calculate aggregates if there are unloaded records. if calculate: value = 0.0 for model in self.treeModel.group: value += model.value(agg['name']) agg['widget'].setText( Numeric.floatToText( value, agg['digits'], True ) ) else: agg['widget'].setText( '-' )
def data(self, index, role=Qt.DisplayRole): if not self.group: return QVariant() if role in (Qt.DisplayRole, Qt.EditRole) or (self._showToolTips and role == Qt.ToolTipRole): value = self.value(index.row(), index.column(), index.internalPointer()) fieldType = self.fieldType(index.column(), index.internalPointer()) if fieldType in ['one2many', 'many2many']: return QVariant('(%d)' % value.count()) elif fieldType == 'selection': field = self.fields[self.field(index.column())] for x in field['selection']: if x[0] == value: return QVariant(str(x[1])) return QVariant() elif fieldType == 'date' and value: return QVariant( Calendar.dateToText(Calendar.storageToDate(value))) elif fieldType == 'datetime' and value: return QVariant( Calendar.dateTimeToText(Calendar.storageToDateTime(value))) elif fieldType == 'float': # If we use the default conversion big numbers are shown # in scientific notation. Also we have to respect the number # of decimal digits given by the server. field = self.fields[self.field(index.column())] if role == Qt.EditRole: thousands = False else: thousands = True return QVariant( Numeric.floatToText(value, field.get('digits', None), thousands)) elif fieldType == 'integer': return QVariant(Numeric.integerToText(value)) elif fieldType == 'float_time': return QVariant(Calendar.floatTimeToText(value)) elif fieldType == 'binary': if value: return QVariant(_('%d bytes') % len(value)) else: return QVariant() elif fieldType == 'boolean': return QVariant(bool(value)) elif fieldType == 'button': if role == Qt.ToolTipRole: fieldName = self.field(index.column()) return QVariant(self.buttons[fieldName].get('string', '')) return QVariant() else: if value == False or value == None: return QVariant() else: # If the text has several lines put them all in a single one return QVariant(str(value).replace('\n', ' ')) elif role == Qt.DecorationRole: fieldType = self.fieldType(index.column(), index.internalPointer()) if fieldType == 'button': fieldName = self.field(index.column()) return QVariant( Icons.kdeIcon(self.buttons[fieldName].get('icon'))) if self.field(index.column()) == self.iconField: # Not all models necessarily have the icon so check that first model = self.record(index.row(), index.internalPointer()) if model and self.icon in model.values: return QVariant(Icons.kdeIcon(model.value(self.icon))) else: return QVariant() else: return QVariant() elif role == Qt.BackgroundRole: if not self.showBackgroundColor: return QVariant() field = self.fields[self.field(index.column())] model = self.record(index.row(), index.internalPointer()) # We need to ensure we're not being asked about a non existent row. # This happens in some special cases (an editable tree in a one2many field, # such as the case of fiscal year inside sequences). # Note that trying to avoid processing this function if index.row() > self.rowCount()-1 # works to avoid this but has problems with some tree structures (such as the menu). # So we need to make the check here. if not model: return QVariant() # Priorize readonly to required as if it's readonly the # user doesn't mind if it's required as she won't be able # to change it anyway. if not model.isFieldValid(self.field(index.column())): color = '#FF6969' elif 'readonly' in field and field['readonly']: color = 'lightgrey' elif 'required' in field and field['required']: color = '#ddddff' else: color = 'white' return QVariant(QBrush(QColor(color))) elif role == Qt.ForegroundRole: if not self.colors: return QVariant() model = self.record(index.row(), index.internalPointer()) # We need to ensure we're not being asked about a non existent row. # This happens in some special cases (an editable tree in a one2many field, # such as the case of fiscal year inside sequences). # Note that trying to avoid processing this function if index.row() > self.rowCount()-1 # works to avoid this but has problems with some tree structures (such as the menu). # So we need to make the check here. if not model: return QVariant() palette = QPalette() color = palette.color(QPalette.WindowText) for (c, expression) in self.colors: if model.evaluateExpression(expression, checkLoad=False): color = c break return QVariant(QBrush(QColor(color))) elif role == Qt.TextAlignmentRole: fieldType = self.fieldType(index.column(), index.internalPointer()) if fieldType in [ 'integer', 'float', 'float_time', 'time', 'date', 'datetime' ]: return QVariant(Qt.AlignRight | Qt.AlignVCenter) else: return QVariant(Qt.AlignLeft | Qt.AlignVCenter) elif role == KooModel.IdRole: model = self.record(index.row(), index.internalPointer()) return QVariant(model.id) elif role == KooModel.ValueRole: value = self.value(index.row(), index.column(), index.internalPointer()) fieldType = self.fieldType(index.column(), index.internalPointer()) if fieldType in ['one2many', 'many2many']: # By now, return the same as DisplayRole for these return QVariant('(%d)' % value.count()) elif fieldType == 'selection': # By now, return the same as DisplayRole for these field = self.fields[self.field(index.column())] for x in field['selection']: if x[0] == value: return QVariant(str(x[1])) return QVariant() elif fieldType == 'date' and value: return QVariant(Calendar.storageToDate(value)) elif fieldType == 'datetime' and value: return QVariant(Calendar.storageToDateTime(value)) elif fieldType == 'float': # If we use the default conversion big numbers are shown # in scientific notation. Also we have to respect the number # of decimal digits given by the server. field = self.fields[self.field(index.column())] return QVariant( Numeric.floatToText(value, field.get('digits', None))) elif fieldType == 'float_time': return QVariant(value) elif fieldType == 'binary': if value: return QVariant(QByteArray.fromBase64(value)) else: return QVariant() elif fieldType == 'boolean': return QVariant(bool(value)) else: if value == False or value == None: return QVariant() else: return QVariant(str(value)) else: return QVariant()
def correctValue(self, value, fieldName, relatedFieldName): text = value if relatedFieldName: fieldType = self.relatedFields[relatedFieldName].get('type') else: fieldType = self.fields[fieldName].get('type') if fieldType == 'date': value = Calendar.textToDate(value) text = Calendar.dateToText(value) value = Calendar.dateToStorage(value) elif fieldType == 'datetime': value = Calendar.textToDateTime(value) text = Calendar.dateTimeToText(value) value = Calendar.dateTimeToStorage(value) elif fieldType == 'float_time': value = Calendar.textToFloatTime(value) text = Calendar.floatTimeToText(value) value = Calendar.floatTimeToStorage(value) elif fieldType == 'time': value = Calendar.textToTime(value) text = Calendar.timeToText(value) value = Calendar.timeToStorage(value) elif fieldType == 'float': value = Numeric.textToFloat(value) or 0.0 text = Numeric.floatToText(value) elif fieldType == 'integer': value = Numeric.textToInteger(value) or 0.0 text = Numeric.integerToText(value) elif fieldType == 'selection': if relatedFieldName: options = self.relatedFields[relatedFieldName]['selection'] else: options = self.fields[fieldName]['selection'] text = [] keys = [] for selection in options: # If text matches exactly one of the options of the selection field # do not 'accept' other options. Otherwise, all options that contain # the text will be 'accepted'. if value.lower().strip() == selection[1].lower().strip(): keys = [selection[0]] text = [selection[1]] break if value.lower() in selection[1].lower(): keys.append(selection[0]) text.append(selection[1]) value = keys text = ', '.join(text) elif fieldType == 'boolean': options = [ (True, _('True')), (False, _('False')), ] text = '' for selection in options: if value.lower() in selection[1].lower(): value = selection[0] text = selection[1] break if not text: value = options[1][0] text = options[1][1] return (value, text)
field = self.fields[self.field(index.column())] for x in field['selection']: if x[0] == value: return QVariant(unicode(x[1])) return QVariant() elif fieldType == 'date' and value: return QVariant(Calendar.storageToDate(value)) elif fieldType == 'datetime' and value: return QVariant(Calendar.storageToDateTime(value)) elif fieldType == 'float': # If we use the default conversion big numbers are shown # in scientific notation. Also we have to respect the number # of decimal digits given by the server. field = self.fields[self.field(index.column())] return QVariant( Numeric.floatToText(value, field.get('digits', None))) elif fieldType == 'float_time': return QVariant(value) elif fieldType == 'binary': if value: return QVariant(QByteArray.fromBase64(value)) else: return QVariant() elif fieldType == 'boolean': return QVariant(bool(value)) else: if value == False or value == None: return QVariant() else: return QVariant(unicode(value)) else: