#include "qvariantedit.h" #include #include #include QStringList StringListEdit::value() const { QStringList l; for (int i = 0; i < combo->count(); ++i) l << combo->itemText(i); return l; } void StringListEdit::setValue(const QStringList & v) { int pi = combo->currentIndex(); combo->clear(); if (!v.isEmpty()) { combo->addItems(v); if (pi < combo->count() && pi >= 0) { combo->setCurrentIndex(pi); } else { combo->setCurrentIndex(0); } } } void StringListEdit::addItem() { combo->addItem(combo->currentText()); emit valueChanged(); } void StringListEdit::delItem() { if (combo->currentIndex() < 0) return; combo->removeItem(combo->currentIndex()); emit valueChanged(); } void StringListEdit::clear() { if (combo->count() == 0) return; combo->clear(); emit valueChanged(); } StringListEdit::StringListEdit(QWidget * parent): QWidget(parent) { lay = new QBoxLayout(QBoxLayout::LeftToRight); combo = new EComboBox(this); combo->setEditable(true); combo->setLineEdit(new CLineEdit); combo->setInsertPolicy(QComboBox::NoInsert); butt_apply = new QPushButton(this); butt_add = new QPushButton(this); butt_del = new QPushButton(this); butt_clear = new QPushButton(this); butt_apply->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); butt_add->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); butt_del->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); butt_clear->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); butt_apply->setIcon(QIcon(":/icons/list-edit-apply.png")); butt_add->setIcon(QIcon(":/icons/list-add.png")); butt_del->setIcon(QIcon(":/icons/list-remove.png")); butt_clear->setIcon(QIcon(":/icons/edit-clear.png")); butt_apply->setToolTip(tr("Apply")); butt_add->setToolTip(tr("Add")); butt_del->setToolTip(tr("Remove")); butt_clear->setToolTip(tr("Clear")); lay->setContentsMargins(0, 0, 0, 0); lay->setSpacing(2); lay->addWidget(combo); lay->addWidget(butt_apply); lay->addWidget(butt_add); lay->addWidget(butt_del); lay->addWidget(butt_clear); setLayout(lay); connect(combo->lineEdit(), SIGNAL(returnPressed()), this, SLOT(editItem())); connect(combo, SIGNAL(rowsChanged()), this, SIGNAL(valueChanged())); connect(butt_apply, SIGNAL(clicked(bool)), this, SLOT(editItem())); connect(butt_add, SIGNAL(clicked(bool)), this, SLOT(addItem())); connect(butt_del, SIGNAL(clicked(bool)), this, SLOT(delItem())); connect(butt_clear, &QPushButton::clicked, [this](){ if (QMessageBox::question(this, tr("Clear All"), tr("Clear All?"), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok) clear(); }); } void StringListEdit::changeEvent(QEvent * e) { QWidget::changeEvent(e); if (e->type() == QEvent::LanguageChange) { butt_add->setToolTip(tr("Add")); butt_del->setToolTip(tr("Remove")); butt_clear->setToolTip(tr("Clear")); return; } } void StringListEdit::editItem() { int ci = combo->currentIndex(); if (ci < 0) return; combo->setItemText(ci, combo->currentText()); emit valueChanged(); } PathEdit::PathEdit(QWidget * parent): QWidget(parent), lay(QBoxLayout::LeftToRight, this) { is_dir = is_abs = is_save = false; filter = tr("All files(*)"); line = new CLineEdit(this); butt_select = new QPushButton(this); butt_select->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); butt_select->setIcon(QIcon(":/icons/document-open.png")); butt_select->setToolTip(tr("Choose") + " ..."); lay.setContentsMargins(0, 0, 0, 0); lay.addWidget(line); lay.addWidget(butt_select); connect(line, SIGNAL(textChanged(QString)), this, SIGNAL(valueChanged())); connect(butt_select, SIGNAL(clicked(bool)), this, SLOT(select())); } void PathEdit::changeEvent(QEvent * e) { QWidget::changeEvent(e); if (e->type() == QEvent::LanguageChange) { butt_select->setToolTip(tr("Choose") + " ..."); return; } } void PathEdit::resizeEvent(QResizeEvent *) { butt_select->setMaximumHeight(line->height()); } void PathEdit::setValue(const QString & v) { line->setText(v); if (!is_dir && is_save) butt_select->setIcon(QIcon(":/icons/document-save.png")); else butt_select->setIcon(QIcon(":/icons/document-open.png")); } void PathEdit::select() { QString ret; if (is_dir) ret = QFileDialog::getExistingDirectory(this, tr("Select directory"), value()); else { if (is_save) ret = QFileDialog::getSaveFileName(this, tr("Select file"), value(), filter); else ret = QFileDialog::getOpenFileName(this, tr("Select file"), value(), filter); } if (ret.isEmpty()) return; if (!is_abs) ret = QDir::current().relativeFilePath(ret); line->setText(ret); emit valueChanged(); } QVariantEdit::QVariantEdit(QWidget * parent): QWidget(parent) { setLayout(new QBoxLayout(QBoxLayout::TopToBottom)); layout()->setContentsMargins(0, 0, 0, 0); _empty = 0; _line = 0; _check = 0; _color = 0; _list = 0; _date = 0; _spin = 0; _espin = 0; _rect = 0; _point = 0; _path = 0; _enum = 0; _custom =_cur_edit = 0; _recreate(QVariant()); } QVariantEdit::~QVariantEdit() { _delete(); } void QVariantEdit::resizeEvent(QResizeEvent * e) { QWidget::resizeEvent(e); } void QVariantEdit::_recreate(const QVariant & new_value) { if (!new_value.isValid()) { if (_cur_edit != _empty) _delete(); if (_empty == 0) { _empty = new QLabel(tr("Invalid value"), this); _empty->setAlignment(Qt::AlignCenter); _cur_edit = _empty; _resize(); } _value = new_value; return; } if (_value.userType() == new_value.userType()) { _value = new_value; return; } _delete(); #if QT_VERSION_MAJOR <= 5 switch (new_value.type()) { #else switch (new_value.metaType().id()) { #endif #if QT_VERSION_MAJOR <= 5 case QVariant::Bool: #else case QMetaType::Bool: #endif _check = new QCheckBox(this); _check->setAutoFillBackground(true); _cur_edit = _check; connect(_check, SIGNAL(toggled(bool)), this, SLOT(_changed())); break; #if QT_VERSION_MAJOR <= 5 case QVariant::Int: #else case QMetaType::Int: #endif _spin = new QDoubleSpinBox(this); _spin->setDecimals(0); _spin->setRange(-0x7FFFFFFF, 0x7FFFFFFF); _cur_edit = _spin; connect(_spin, SIGNAL(valueChanged(double)), this, SLOT(_changed())); break; #if QT_VERSION_MAJOR <= 5 case QVariant::UInt: #else case QMetaType::UInt: #endif _spin = new QDoubleSpinBox(this); _spin->setDecimals(0); _spin->setRange(0, 0xFFFFFFFF); _cur_edit = _spin; connect(_spin, SIGNAL(valueChanged(double)), this, SLOT(_changed())); break; #if QT_VERSION_MAJOR <= 5 case QVariant::LongLong: #else case QMetaType::LongLong: #endif _spin = new QDoubleSpinBox(this); _spin->setDecimals(0); _spin->setRange(-0x7FFFFFFFFFFFFFFFL, 0x7FFFFFFFFFFFFFFFL); _cur_edit = _spin; connect(_spin, SIGNAL(valueChanged(double)), this, SLOT(_changed())); break; #if QT_VERSION_MAJOR <= 5 case QVariant::ULongLong: #else case QMetaType::ULongLong: #endif _spin = new QDoubleSpinBox(this); _spin->setDecimals(0); _spin->setRange(0L, 0x7FFFFFFFFFFFFFFFL); _cur_edit = _spin; connect(_spin, SIGNAL(valueChanged(double)), this, SLOT(_changed())); break; #if QT_VERSION_MAJOR <= 5 case QVariant::Double: #else case QMetaType::Double: #endif _espin = new EvalSpinBox(this); _cur_edit = _espin; connect(_espin, SIGNAL(valueChanged(double)), this, SLOT(_changed())); break; #if QT_VERSION_MAJOR <= 5 case QVariant::Color: #else case QMetaType::QColor: #endif _color = new ColorButton(this); _color->setUseAlphaChannel(true); _cur_edit = _color; connect(_color, SIGNAL(colorChanged(QColor)), this, SLOT(_changed())); break; #if QT_VERSION_MAJOR <= 5 case QVariant::String: #else case QMetaType::QString: #endif _line = new CLineEdit(this); _cur_edit = _line; connect(_line, SIGNAL(textChanged(QString)), this, SLOT(_changed())); break; #if QT_VERSION_MAJOR <= 5 case QVariant::StringList: #else case QMetaType::QStringList: #endif _list = new StringListEdit(this); _cur_edit = _list; connect(_list, SIGNAL(valueChanged()), this, SLOT(_changed())); break; #if QT_VERSION_MAJOR <= 5 case QVariant::Rect: #else case QMetaType::QRect: #endif _rect = new QRectEdit(this); _rect->setDecimals(0); _cur_edit = _rect; connect(_rect, SIGNAL(valueChanged(QRectF)), this, SLOT(_changed())); break; #if QT_VERSION_MAJOR <= 5 case QVariant::RectF: #else case QMetaType::QRectF: #endif _rect = new QRectEdit(this); _rect->setDecimals(3); _cur_edit = _rect; connect(_rect, SIGNAL(valueChanged(QRectF)), this, SLOT(_changed())); break; #if QT_VERSION_MAJOR <= 5 case QVariant::Point: #else case QMetaType::QPoint: #endif _point = new QPointEdit(this); _point->setDecimals(0); _cur_edit = _point; connect(_point, SIGNAL(valueChanged(QPointF)), this, SLOT(_changed())); break; #if QT_VERSION_MAJOR <= 5 case QVariant::PointF: #else case QMetaType::QPointF: #endif _point = new QPointEdit(this); _point->setDecimals(3); _cur_edit = _point; connect(_point, SIGNAL(valueChanged(QPointF)), this, SLOT(_changed())); break; #if QT_VERSION_MAJOR <= 5 case QVariant::Date: #else case QMetaType::QDate: #endif _date = new QDateEdit(this); _cur_edit = _date; connect(_date, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(_changed())); break; #if QT_VERSION_MAJOR <= 5 case QVariant::Time: #else case QMetaType::QTime: #endif _date = new QTimeEdit(this); _cur_edit = _date; connect(_date, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(_changed())); break; #if QT_VERSION_MAJOR <= 5 case QVariant::DateTime: #else case QMetaType::QDateTime: #endif _date = new QDateTimeEdit(this); _cur_edit = _date; connect(_date, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(_changed())); break; default: break; } if (!_cur_edit) { if (new_value.canConvert()) { _enum = new EComboBox(this); _setEnum(new_value.value()); _cur_edit = _enum; connect(_enum, SIGNAL(currentIndexChanged(int)), this, SLOT(_changed())); } if (new_value.canConvert()) { _path = new PathEdit(this); _setFile(new_value.value()); _cur_edit = _path; connect(_path, SIGNAL(valueChanged()), this, SLOT(_changed())); } if (new_value.canConvert()) { _path = new PathEdit(this); _setDir(new_value.value()); _cur_edit = _path; connect(_path, SIGNAL(valueChanged()), this, SLOT(_changed())); } if (!_cur_edit) { // try custom QVariantEditorFactoryBase * f = QVariantEditorFactories::editorFactory(new_value.userType()); if (f) { QWidget * fw = f->createEditor(); if (fw) { fw->setParent(this); _custom = fw; _cur_edit = _custom; connect(_custom, SIGNAL(valueChanged()), this, SLOT(_changed())); } } } } if (_cur_edit) { _resize(); } _value = new_value; } QVariant QVariantEdit::value() const { #if QT_VERSION_MAJOR <= 5 switch (_value.type()) { #else switch (_value.metaType().id()) { #endif #if QT_VERSION_MAJOR <= 5 case QVariant::Bool: #else case QMetaType::Bool: #endif return _check->isChecked(); #if QT_VERSION_MAJOR <= 5 case QVariant::Int: #else case QMetaType::Int: #endif return int(_spin->value()); #if QT_VERSION_MAJOR <= 5 case QVariant::UInt: #else case QMetaType::UInt: #endif return (unsigned int)(_spin->value()); #if QT_VERSION_MAJOR <= 5 case QVariant::LongLong: #else case QMetaType::LongLong: #endif return qlonglong(_spin->value()); #if QT_VERSION_MAJOR <= 5 case QVariant::ULongLong: #else case QMetaType::ULongLong: #endif return qulonglong(_spin->value()); #if QT_VERSION_MAJOR <= 5 case QVariant::Double: #else case QMetaType::Double: #endif return _espin->value(); #if QT_VERSION_MAJOR <= 5 case QVariant::Color: #else case QMetaType::QColor: #endif return _color->color(); #if QT_VERSION_MAJOR <= 5 case QVariant::String: #else case QMetaType::QString: #endif return _line->text(); #if QT_VERSION_MAJOR <= 5 case QVariant::StringList: #else case QMetaType::QStringList: #endif return _list->value(); #if QT_VERSION_MAJOR <= 5 case QVariant::Rect: #else case QMetaType::QRect: #endif return _rect->value().toRect(); #if QT_VERSION_MAJOR <= 5 case QVariant::RectF: #else case QMetaType::QRectF: #endif return _rect->value(); #if QT_VERSION_MAJOR <= 5 case QVariant::Point: #else case QMetaType::QPoint: #endif return _point->value().toPoint(); #if QT_VERSION_MAJOR <= 5 case QVariant::PointF: #else case QMetaType::QPointF: #endif return _point->value(); #if QT_VERSION_MAJOR <= 5 case QVariant::Date: #else case QMetaType::QDate: #endif return _date->date(); #if QT_VERSION_MAJOR <= 5 case QVariant::Time: #else case QMetaType::QTime: #endif return _date->time(); #if QT_VERSION_MAJOR <= 5 case QVariant::DateTime: #else case QMetaType::QDateTime: #endif return _date->dateTime(); default: if (_value.canConvert() && _enum) { QAD::Enum ret; for (int i = 0; i < _enum->count(); ++i) ret.enum_list << QAD::Enumerator(_enum->itemData(i).toInt(), _enum->itemText(i)); ret.enum_name = _enum->property("enum_name").toString(); ret.selected = _enum->currentText(); return QVariant::fromValue(ret); } if (_value.canConvert() && _path) { if (!_path->is_dir) { QAD::File ret; ret.file = _path->value(); ret.filter = _path->filter; ret.is_abs = _path->is_abs; ret.is_save = _path->is_save; return QVariant::fromValue(ret); } } if (_value.canConvert() && _path) { if (_path->is_dir) { QAD::Dir ret; ret.dir = _path->value(); ret.is_abs = _path->is_abs; return QVariant::fromValue(ret); } } if (_custom) { return _custom->property("value"); } } return QVariant(); } void QVariantEdit::setValue(const QVariant & v) { _recreate(v); if (_cur_edit) _cur_edit->blockSignals(true); if (_line) {_line->setText(v.toString());} if (_check) {_check->setChecked(v.toBool()); _check->setText(v.toBool() ? "true" : "false");} if (_color) {_color->setColor(v.value());} if (_list) {_list->setValue(v.toStringList());} if (_date) {_date->setDateTime(v.toDateTime());} if (_spin) {_spin->setValue(v.toDouble());} if (_espin) {_espin->setValue(v.toDouble());} if (_rect) {_rect->setValue(v.toRectF());} if (_point) {_point->setValue(v.toPointF());} if (_path) { if (_path->is_dir) _setDir(v.value()); else _setFile(v.value()); } if (_enum) {_setEnum(v.value());} if (_custom) {_setCustom(v);} if (_cur_edit) _cur_edit->blockSignals(false); } void QVariantEdit::_delete() { if (_cur_edit) delete _cur_edit; _cur_edit = 0; _custom = 0; _empty = 0; _line = 0; _check = 0; _color = 0; _list = 0; _date = 0; _spin = 0; _espin = 0; _rect = 0; _point = 0; _path = 0; _enum = 0; } void QVariantEdit::_resize() { if (!_cur_edit) return; layout()->addWidget(_cur_edit); } void QVariantEdit::_newPath() { _delete(); _path = new PathEdit(this); _cur_edit = _path; _value = _value.toString(); connect(_path, SIGNAL(valueChanged()), this, SLOT(_changed())); _resize(); } void QVariantEdit::_setEnum(const QAD::Enum & v) { _enum->clear(); _enum->setProperty("enum_name", v.enum_name); foreach (const QAD::Enumerator & e, v.enum_list) _enum->addItem(e.name, QVariant(e.value)); int i(0); for (i = 0; i < _enum->count(); ++i) if (_enum->itemText(i) == v.selected) { _enum->setCurrentIndex(i); break; } if (i == _enum->count()) _enum->setCurrentIndex(-1); } void QVariantEdit::_setFile(const QAD::File & v) { _path->is_dir = false; _path->filter = v.filter; _path->is_abs = v.is_abs; _path->is_save = v.is_save; _path->setValue(v.file); } void QVariantEdit::_setDir(const QAD::Dir & v) { _path->is_dir = true; _path->is_abs = v.is_abs; _path->setValue(v.dir); } void QVariantEdit::_setCustom(const QVariant & v) { _custom->setProperty("value", v); } void QVariantEdit::_changed() { if (_check) _check->setText(_check->isChecked() ? "true" : "false"); emit valueChanged(value()); }