package VariantDelegate; use strict; use warnings; use QtCore4; use QtGui4; use QtCore4::isa qw( Qt::ItemDelegate ); use List::Util qw( min ); sub boolExp() { return this->{boolExp}; } sub byteArrayExp() { return this->{byteArrayExp}; } sub charExp() { return this->{charExp}; } sub colorExp() { return this->{colorExp}; } sub dateExp() { return this->{dateExp}; } sub dateTimeExp() { return this->{dateTimeExp}; } sub doubleExp() { return this->{doubleExp}; } sub pointExp() { return this->{pointExp}; } sub rectExp() { return this->{rectExp}; } sub signedIntegerExp() { return this->{signedIntegerExp}; } sub sizeExp() { return this->{sizeExp}; } sub timeExp() { return this->{timeExp}; } sub unsignedIntegerExp() { return this->{unsignedIntegerExp}; } sub NEW { my ($class, $parent) = @_; $class->SUPER::NEW($parent); this->{boolExp} = Qt::RegExp(); this->{byteArrayExp} = Qt::RegExp(); this->{charExp} = Qt::RegExp(); this->{colorExp} = Qt::RegExp(); this->{dateExp} = Qt::RegExp(); this->{dateTimeExp} = Qt::RegExp(); this->{doubleExp} = Qt::RegExp(); this->{pointExp} = Qt::RegExp(); this->{rectExp} = Qt::RegExp(); this->{signedIntegerExp} = Qt::RegExp(); this->{timeExp} = Qt::RegExp(); this->{unsignedIntegerExp} = Qt::RegExp(); boolExp->setPattern('true|false'); boolExp->setCaseSensitivity(Qt::CaseInsensitive()); byteArrayExp->setPattern('[\\x00-\\xff]*'); charExp->setPattern('.'); colorExp->setPattern('\\(([0-9]*),([0-9]*),([0-9]*),([0-9]*)\\)'); doubleExp->setPattern(''); pointExp->setPattern('\\((-?[0-9]*),(-?[0-9]*)\\)'); rectExp->setPattern('\\((-?[0-9]*),(-?[0-9]*),(-?[0-9]*),(-?[0-9]*)\\)'); signedIntegerExp->setPattern('-?[0-9]*'); this->{sizeExp} = Qt::RegExp(pointExp); unsignedIntegerExp->setPattern('[0-9]*'); dateExp->setPattern('([0-9]{,4})-([0-9]{,2})-([0-9]{,2})'); timeExp->setPattern('([0-9]{,2}):([0-9]{,2}):([0-9]{,2})'); dateTimeExp->setPattern(dateExp->pattern() . 'T' . timeExp->pattern()); } sub paint { my ($painter, $option, $index) = @_; if ($index->column() == 2) { my $value = $index->model()->data($index, Qt::UserRole()); if (!isSupportedType($value->type())) { my $myOption = $option; $myOption->setState( $myOption->state & ~Qt::Style::State_Enabled() ); this->SUPER::paint($painter, $myOption, $index); return; } } this->SUPER::paint($painter, $option, $index); } sub createEditor { my ($parent, $option, $index) = @_; if ($index->column() != 2) { return undef; } my $originalValue = $index->model()->data($index, Qt::UserRole()); if (!isSupportedType($originalValue->type())) { return undef; } my $lineEdit = Qt::LineEdit($parent); $lineEdit->setFrame(0); my $regExp; if ( $originalValue->type() == Qt::Variant::Bool() ) { $regExp = boolExp; } elsif ( $originalValue->type() == Qt::Variant::ByteArray() ) { $regExp = byteArrayExp; } elsif ( $originalValue->type() == Qt::Variant::Char() ) { $regExp = charExp; } elsif ( $originalValue->type() == Qt::Variant::Color() ) { $regExp = colorExp; } elsif ( $originalValue->type() == Qt::Variant::Date() ) { $regExp = dateExp; } elsif ( $originalValue->type() == Qt::Variant::DateTime() ) { $regExp = dateTimeExp; } elsif ( $originalValue->type() == Qt::Variant::Double() ) { $regExp = doubleExp; } elsif ( $originalValue->type() == Qt::Variant::Int() || $originalValue->type() == Qt::Variant::LongLong() ) { $regExp = signedIntegerExp; } elsif ( $originalValue->type() == Qt::Variant::Point() ) { $regExp = pointExp; } elsif ( $originalValue->type() == Qt::Variant::Rect() ) { $regExp = rectExp; } elsif ( $originalValue->type() == Qt::Variant::Size() ) { $regExp = sizeExp; } elsif ( $originalValue->type() == Qt::Variant::Time() ) { $regExp = timeExp; } elsif ( $originalValue->type() == Qt::Variant::UInt() || $originalValue->type() == Qt::Variant::ULongLong() ) { $regExp = unsignedIntegerExp; } if ($regExp) { my $validator = Qt::RegExpValidator($regExp, $lineEdit); $lineEdit->setValidator($validator); } return $lineEdit; } sub setEditorData { my ($editor, $index) = @_; my $value = $index->model()->data($index, Qt::UserRole()); my $lineEdit = $editor; if ($lineEdit->isa('Qt::LineEdit')) { $lineEdit->setText(displayText($value)); } } sub setModelData { my ($editor, $model, $index) = @_; my $lineEdit = $editor; if ($lineEdit->isa('Qt::LineEdit') && !$lineEdit->isModified()) { return; } my $text = $lineEdit->text(); $DB::single=1; my $validator = $lineEdit->validator(); if ($validator) { my $pos; if ($validator->validate($text, $pos) != Qt::Validator::Acceptable()) { return; } } my $originalValue = $index->model()->data($index, Qt::UserRole()); my $value; if ( $originalValue->type() == Qt::Variant::Char() ) { $value = Qt::Variant( Qt::Char( substr $text, 0, 1 ) ); } elsif ( $originalValue->type() == Qt::Variant::Color() ) { colorExp->exactMatch($text); $value = Qt::Variant( Qt::Color(min(colorExp->cap(1), 255), min(colorExp->cap(2), 255), min(colorExp->cap(3), 255), min(colorExp->cap(4), 255)) ); } elsif ( $originalValue->type() == Qt::Variant::Date() ) { my $date = Qt::Date::fromString($text, Qt::ISODate()); if (!$date->isValid()) { return; } $value = Qt::Variant( $date ); } elsif ( $originalValue->type() == Qt::Variant::DateTime() ) { my $dateTime = Qt::DateTime::fromString($text, Qt::ISODate()); if (!$dateTime->isValid()) { return; } $value = Qt::Variant( $dateTime ); } elsif ( $originalValue->type() == Qt::Variant::Point() ) { pointExp->exactMatch($text); $value = Qt::Variant( Qt::Point(pointExp->cap(1), pointExp->cap(2)) ); } elsif ( $originalValue->type() == Qt::Variant::Rect() ) { rectExp->exactMatch($text); $value = Qt::Variant( Qt::Rect(rectExp->cap(1), rectExp->cap(2), rectExp->cap(3), rectExp->cap(4)) ); } elsif ( $originalValue->type() == Qt::Variant::Size() ) { sizeExp->exactMatch($text); $value = Qt::Variant( Qt::Size(sizeExp->cap(1), sizeExp->cap(2)) ); } elsif ( $originalValue->type() == Qt::Variant::StringList() ) { $value = Qt::Variant( [split m/,/, $text] ); } elsif ( $originalValue->type() == Qt::Variant::Time() ) { my $time = Qt::Time::fromString($text, Qt::ISODate()); if (!$time->isValid()) { return; } $value = Qt::Variant( $time ); } else { $value = Qt::Variant( Qt::String( $text ) ); $value->convert($originalValue->type()); } $model->setData($index, Qt::Variant(Qt::String(displayText($value))), Qt::DisplayRole()); $model->setData($index, $value, Qt::UserRole()); } sub isSupportedType { my ($type) = @_; if ( $type == Qt::Variant::Bool() || $type == Qt::Variant::ByteArray() || $type == Qt::Variant::Char() || $type == Qt::Variant::Color() || $type == Qt::Variant::Date() || $type == Qt::Variant::DateTime() || $type == Qt::Variant::Double() || $type == Qt::Variant::Int() || $type == Qt::Variant::LongLong() || $type == Qt::Variant::Point() || $type == Qt::Variant::Rect() || $type == Qt::Variant::Size() || $type == Qt::Variant::String() || $type == Qt::Variant::StringList() || $type == Qt::Variant::Time() || $type == Qt::Variant::UInt() || $type == Qt::Variant::ULongLong() ) { return 1; } else { return 0; } } sub displayText { my ($value) = @_; if ( $value->type() == Qt::Variant::Bool() || $value->type() == Qt::Variant::ByteArray() || $value->type() == Qt::Variant::Char() || $value->type() == Qt::Variant::Double() || $value->type() == Qt::Variant::Int() || $value->type() == Qt::Variant::LongLong() || $value->type() == Qt::Variant::String() || $value->type() == Qt::Variant::UInt() || $value->type() == Qt::Variant::ULongLong() ) { return $value->toString(); } elsif( $value->type() == Qt::Variant::Color() ) { my $color = $value->value(); return Qt::String('(%1,%2,%3,%4)') ->arg($color->red())->arg($color->green()) ->arg($color->blue())->arg($color->alpha()); } elsif( $value->type() == Qt::Variant::Date() ) { return $value->toDate()->toString(Qt::ISODate()); } elsif( $value->type() == Qt::Variant::DateTime() ) { return $value->toDateTime()->toString(Qt::ISODate()); } elsif( $value->type() == Qt::Variant::Invalid() ) { return ''; } elsif( $value->type() == Qt::Variant::Point() ) { my $point = $value->toPoint(); return Qt::String('(%1,%2)')->arg($point->x())->arg($point->y()); } elsif( $value->type() == Qt::Variant::Rect() ) { my $rect = $value->toRect(); return Qt::String('(%1,%2,%3,%4)') ->arg($rect->x())->arg($rect->y()) ->arg($rect->width())->arg($rect->height()); } elsif( $value->type() == Qt::Variant::Size() ) { my $size = $value->toSize(); return Qt::String('(%1,%2)')->arg($size->width())->arg($size->height()); } elsif( $value->type() == Qt::Variant::StringList() ) { return join ',', @{$value->toStringList()}; } elsif( $value->type() == Qt::Variant::Time() ) { return $value->toTime()->toString(Qt::ISODate()); } else { } return Qt::String('<%1>')->arg($value->typeName()); } 1;