355 lines
12 KiB
C++
355 lines
12 KiB
C++
#include "sql_record_widget.h"
|
|
#include <qpiconfig.h>
|
|
#include <QSqlRecord>
|
|
#include <QSqlField>
|
|
#include <QSqlError>
|
|
#include <QFormLayout>
|
|
#include <QLabel>
|
|
#include <QDoubleSpinBox>
|
|
#include <QCheckBox>
|
|
#include <QLineEdit>
|
|
#include <QComboBox>
|
|
#include <colorbutton.h>
|
|
#include <qpiconfigvaluewidget.h>
|
|
|
|
|
|
SQLRecordWidget::SQLRecordWidget(QWidget * parent): QWidget(parent) {
|
|
setLayout(new QFormLayout());
|
|
ro = false;
|
|
}
|
|
|
|
|
|
SQLRecordWidget::~SQLRecordWidget() {
|
|
}
|
|
|
|
|
|
void SQLRecordWidget::setRecord(const QSqlRecord & q, bool full_update) {
|
|
//qDebug() << (q.count() - hidden.size()) << (layout()->count() / 2);
|
|
if (full_update || (q.count() - hidden.size()) != (layout()->count() / 2)) createWidgets(q);
|
|
for (int i = 0; i < q.count(); ++i) {
|
|
QSqlField f = q.field(i);
|
|
QWidget * val = 0;
|
|
for (int w = 0; w < cws.size(); ++w)
|
|
if (cws[w]->objectName() == f.name()) {
|
|
val = cws[w];
|
|
break;
|
|
}
|
|
if (val == 0) continue;
|
|
if (qobject_cast<QLineEdit * >(val)) {
|
|
if (relations.contains(f.name())) {
|
|
bool ok = false;
|
|
int sv(f.value().toInt(&ok));
|
|
if (!ok)
|
|
qobject_cast<QLineEdit * >(val)->setText("");
|
|
else {
|
|
QList<QPair<int, QString> > & rv(relations[f.name()]);
|
|
for (int j = 0; j < rv.size(); ++j) {
|
|
if (sv == rv[j].first) {
|
|
qobject_cast<QLineEdit * >(val)->setText(rv[j].second);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} else
|
|
qobject_cast<QLineEdit * >(val)->setText(f.value().toString());
|
|
}
|
|
if (qobject_cast<QCheckBox * >(val)) qobject_cast<QCheckBox * >(val)->setChecked(f.value().toBool());
|
|
if (qobject_cast<QDoubleSpinBox * >(val)) qobject_cast<QDoubleSpinBox * >(val)->setValue(f.value().toDouble());
|
|
if (qobject_cast<ColorButton * >(val)) qobject_cast<ColorButton * >(val)->setColor(QColor::fromRgba(f.value().toUInt()));
|
|
if (qobject_cast<StringListEdit * >(val)) {
|
|
QString s = f.value().toString();
|
|
qobject_cast<StringListEdit * >(val)->setValue(s.isEmpty() ? QStringList() : s.split(";"));
|
|
}
|
|
if (qobject_cast<QComboBox * >(val)) {
|
|
bool ok = false;
|
|
int sv(f.value().toInt(&ok));
|
|
if (!ok)
|
|
((QComboBox*)val)->setCurrentIndex(-1);
|
|
else {
|
|
QList<QPair<int, QString> > & rv(relations[f.name()]);
|
|
for (int j = 0; j < rv.size(); ++j) {
|
|
if (sv == rv[j].first) {
|
|
((QComboBox*)val)->setCurrentIndex(j);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void SQLRecordWidget::setFixedValue(const QString & name, const QVariant & value) {
|
|
foreach (QWidget * w, cws) {
|
|
if (w->objectName() != name) continue;
|
|
if (qobject_cast<QLineEdit * >(w)) {qobject_cast<QLineEdit * >(w)->setText(value.toString()); qobject_cast<QLineEdit * >(w)->setReadOnly(true);}
|
|
if (qobject_cast<QCheckBox * >(w)) {qobject_cast<QCheckBox * >(w)->setChecked(value.toBool()); w->setEnabled(false);}
|
|
if (qobject_cast<QDoubleSpinBox * >(w)) {qobject_cast<QDoubleSpinBox * >(w)->setValue(value.toDouble()); qobject_cast<QDoubleSpinBox * >(w)->setReadOnly(true);}
|
|
if (qobject_cast<ColorButton * >(w)) {qobject_cast<ColorButton * >(w)->setColor(QColor::fromRgba(value.toUInt())); qobject_cast<ColorButton * >(w)->setEnabled(false);}
|
|
if (qobject_cast<StringListEdit * >(w)) {qobject_cast<StringListEdit * >(w)->setValue(QStringList()); qobject_cast<StringListEdit * >(w)->setEnabled(false);}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void SQLRecordWidget::clearValues() {
|
|
foreach (QWidget * w, cws) {
|
|
if (qobject_cast<QLineEdit * >(w)) qobject_cast<QLineEdit * >(w)->setText(QString());
|
|
if (qobject_cast<QCheckBox * >(w)) qobject_cast<QCheckBox * >(w)->setChecked(false);
|
|
if (qobject_cast<QDoubleSpinBox * >(w)) qobject_cast<QDoubleSpinBox * >(w)->setValue(0.);
|
|
if (qobject_cast<ColorButton * >(w)) qobject_cast<ColorButton * >(w)->setColor(Qt::black);
|
|
if (qobject_cast<StringListEdit * >(w)) qobject_cast<StringListEdit * >(w)->setValue(QStringList());
|
|
}
|
|
}
|
|
|
|
|
|
void SQLRecordWidget::createWidgets(const QSqlRecord & q) {
|
|
qDeleteAll(cws);
|
|
cws.clear();
|
|
delete layout();
|
|
QFormLayout * lay = new QFormLayout();
|
|
lay->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
|
|
lay->setLabelAlignment(Qt::AlignRight);
|
|
lay->setContentsMargins(0, 0, 0, 0);
|
|
setLayout(lay);
|
|
//qDebug() << "createWidgets" << q.count();
|
|
for (int i = 0; i < q.count(); ++i) {
|
|
QSqlField f = q.field(i);
|
|
if (hidden.contains(f.name())) continue;
|
|
QPair<QString, QString> ctr = trColumn(f.name());
|
|
QWidget * val = 0;
|
|
if (relations.contains(f.name())) {
|
|
if (ro) {
|
|
val = new QLineEdit();
|
|
} else {
|
|
val = new QComboBox();
|
|
QList<QPair<int, QString> > & rv(relations[f.name()]);
|
|
bool ok = false;
|
|
int sv(f.value().toInt(&ok));
|
|
for (int j = 0; j < rv.size(); ++j) {
|
|
((QComboBox*)val)->addItem(rv[j].second, rv[j].first);
|
|
if (ok)
|
|
if (sv == rv[j].first)
|
|
((QComboBox*)val)->setCurrentIndex(j);
|
|
}
|
|
if (!ok)
|
|
((QComboBox*)val)->setCurrentIndex(-1);
|
|
}
|
|
} else {
|
|
switch (fieldType(f)) {
|
|
case QVariant::Int:
|
|
case QVariant::UInt:
|
|
case QVariant::LongLong:
|
|
case QVariant::ULongLong:
|
|
case QVariant::Double:
|
|
val = new QDoubleSpinBox();
|
|
((QDoubleSpinBox*)val)->setRange(-1E+99, 1E+99);
|
|
((QDoubleSpinBox*)val)->setDecimals(3); break;
|
|
case QVariant::String:
|
|
val = new QLineEdit(); break;
|
|
case QVariant::Bool:
|
|
val = new QCheckBox(); break;
|
|
case QVariant::Color:
|
|
val = new ColorButton();
|
|
((ColorButton*)val)->setUseAlphaChannel(true);
|
|
((ColorButton*)val)->setUseNativeDialog(true);
|
|
break;
|
|
case QVariant::StringList:
|
|
val = new StringListEdit();
|
|
break;
|
|
default: break;
|
|
}
|
|
if (f.type() == QVariant::String || f.type() == QVariant::StringList) val->setProperty("_string", true);
|
|
}
|
|
if (val != 0) {
|
|
QString lt = ctr.first.left(1).toUpper() + ctr.first.right(ctr.first.length() - 1);
|
|
while (lt.endsWith("_")) lt.chop(1);
|
|
QLabel * lbl = new QLabel(lt + ":");
|
|
lbl->setToolTip(ctr.second);
|
|
cws << lbl;
|
|
val->setObjectName(f.name());
|
|
cws << val;
|
|
lay->addRow(lbl, val);
|
|
} else {
|
|
if (!hidden.contains(ctr.first))
|
|
hidden << ctr.first;
|
|
}
|
|
}
|
|
updateWidgets();
|
|
emit widgetsCreated();
|
|
}
|
|
|
|
|
|
void SQLRecordWidget::updateWidgets() {
|
|
foreach (QWidget * w, cws) {
|
|
if (qobject_cast<QLineEdit * >(w)) qobject_cast<QLineEdit * >(w)->setReadOnly(ro);
|
|
if (qobject_cast<QCheckBox * >(w)) qobject_cast<QCheckBox * >(w)->setEnabled(!ro);
|
|
if (qobject_cast<QDoubleSpinBox * >(w)) qobject_cast<QDoubleSpinBox * >(w)->setReadOnly(ro);
|
|
if (qobject_cast<ColorButton * >(w)) qobject_cast<ColorButton * >(w)->setEnabled(!ro);
|
|
if (qobject_cast<StringListEdit * >(w)) qobject_cast<StringListEdit * >(w)->setEnabled(!ro);
|
|
if (qobject_cast<QComboBox * >(w)) qobject_cast<QComboBox * >(w)->setEnabled(!ro);
|
|
}
|
|
}
|
|
|
|
|
|
QVariant::Type SQLRecordWidget::fieldType(const QSqlField & f) {
|
|
QString ft = ftypes.value(f.name());
|
|
if (ft.isEmpty()) return f.type();
|
|
if (ft == "l") return QVariant::StringList;
|
|
if (ft == "b") return QVariant::Bool;
|
|
if (ft == "n") return QVariant::Int;
|
|
if (ft == "f") return QVariant::Double;
|
|
if (ft == "c") return QVariant::Color;
|
|
if (ft == "r") return QVariant::Rect;
|
|
if (ft == "a") return QVariant::RectF;
|
|
if (ft == "p") return QVariant::Point;
|
|
if (ft == "v") return QVariant::PointF;
|
|
return QVariant::String;
|
|
}
|
|
|
|
|
|
void SQLRecordWidget::addTranslation(const QString & file) {
|
|
QPIConfig conf(file, QIODevice::ReadOnly, QPIConfig::Config);
|
|
QPIConfig::Branch ae = conf.allLeaves();
|
|
foreach (QPIConfig::Entry * e, ae)
|
|
translates[e->name()] = QPair<QString, QString>(e->value(), e->comment());
|
|
}
|
|
|
|
|
|
QString SQLRecordWidget::getValuesQuery() const {
|
|
QString ret("(");
|
|
bool first = true;
|
|
foreach (QWidget * w, cws) {
|
|
QWidget * vw(0);
|
|
if (qobject_cast<QLineEdit * >(w)) {if (!qobject_cast<QLineEdit * >(w)->text().isEmpty()) vw = w;}
|
|
if (qobject_cast<QCheckBox * >(w)) vw = w;
|
|
if (qobject_cast<QDoubleSpinBox * >(w)) vw = w;
|
|
if (qobject_cast<ColorButton * >(w)) vw = w;
|
|
if (qobject_cast<StringListEdit * >(w)) vw = w;
|
|
if (qobject_cast<QComboBox * >(w)) vw = w;
|
|
if (vw == 0) continue;
|
|
if (!first) ret += ",";
|
|
first = false;
|
|
ret += vw->objectName();
|
|
}
|
|
ret += ") VALUES (";
|
|
foreach (QWidget * w, cws) {
|
|
QWidget * vw(0);
|
|
if (qobject_cast<QLineEdit * >(w)) {
|
|
if (!qobject_cast<QLineEdit * >(w)->text().isEmpty()) {
|
|
vw = w;
|
|
bool q = w->property("_string").toBool();
|
|
if (q) ret += "'";
|
|
ret += qobject_cast<QLineEdit * >(w)->text();
|
|
if (q) ret += "'";
|
|
}
|
|
}
|
|
if (qobject_cast<QCheckBox * >(w)) {
|
|
vw = w;
|
|
ret += qobject_cast<QCheckBox * >(w)->isChecked() ? "1" : "0";
|
|
}
|
|
if (qobject_cast<QDoubleSpinBox * >(w)) {
|
|
vw = w;
|
|
ret += QString::number(qobject_cast<QDoubleSpinBox * >(w)->value());
|
|
}
|
|
if (qobject_cast<ColorButton * >(w)) {
|
|
vw = w;
|
|
ret += QString::number(qobject_cast<ColorButton * >(w)->color().rgba());
|
|
}
|
|
if (qobject_cast<StringListEdit * >(w)) {
|
|
vw = w;
|
|
ret += "'" + qobject_cast<StringListEdit * >(w)->value().join(";") + "'";
|
|
}
|
|
if (qobject_cast<QComboBox * >(w)) {
|
|
vw = w;
|
|
ret += ((QComboBox*)w)->itemData(((QComboBox*)w)->currentIndex(), Qt::UserRole).toString();
|
|
}
|
|
if (vw == 0) continue;
|
|
ret += ",";
|
|
}
|
|
if (ret.endsWith(",")) ret.chop(1);
|
|
ret += ")";
|
|
return ret;
|
|
}
|
|
|
|
|
|
QString SQLRecordWidget::getUpdateQuery() const {
|
|
QString ret;
|
|
bool first = true;
|
|
foreach (QWidget * w, cws) {
|
|
QWidget * vw(0);
|
|
if (qobject_cast<QLineEdit * >(w)) vw = w;
|
|
if (qobject_cast<QCheckBox * >(w)) vw = w;
|
|
if (qobject_cast<QDoubleSpinBox * >(w)) vw = w;
|
|
if (qobject_cast<ColorButton * >(w)) vw = w;
|
|
if (qobject_cast<StringListEdit * >(w)) vw = w;
|
|
if (qobject_cast<QComboBox * >(w)) vw = w;
|
|
if (vw == 0) continue;
|
|
if (!first) ret += ",";
|
|
first = false;
|
|
ret += vw->objectName() + "=";
|
|
if (qobject_cast<QLineEdit * >(w)) {
|
|
if (qobject_cast<QLineEdit * >(w)->text().isEmpty())
|
|
ret += "null";
|
|
else {
|
|
bool q = w->property("_string").toBool();
|
|
if (q) ret += "'";
|
|
ret += qobject_cast<QLineEdit * >(w)->text();
|
|
if (q) ret += "'";
|
|
}
|
|
}
|
|
if (qobject_cast<QCheckBox * >(w))
|
|
ret += qobject_cast<QCheckBox * >(w)->isChecked() ? "1" : "0";
|
|
if (qobject_cast<QDoubleSpinBox * >(w))
|
|
ret += QString::number(qobject_cast<QDoubleSpinBox * >(w)->value());
|
|
if (qobject_cast<ColorButton * >(w))
|
|
ret += QString::number(qobject_cast<ColorButton * >(w)->color().rgba());
|
|
if (qobject_cast<StringListEdit * >(w))
|
|
ret += "'" + qobject_cast<StringListEdit * >(w)->value().join(";") + "'";
|
|
if (qobject_cast<QComboBox * >(w)) {
|
|
QString cd = ((QComboBox*)w)->itemData(((QComboBox*)w)->currentIndex(), Qt::UserRole).toString();
|
|
ret += cd.isEmpty() ? "null" : cd;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
bool SQLRecordWidget::isEmpty() const {
|
|
return layout()->count() < 2;
|
|
}
|
|
|
|
|
|
void SQLRecordWidget::updateRelations() {
|
|
relations.clear();
|
|
QSqlDatabase db(QSqlDatabase::database(connection_name));
|
|
if (!db.isOpen()) return;
|
|
for (int i = 0; i < relations_src.size(); ++i) {
|
|
QSqlQuery q(QString("SELECT %1,%2 FROM %3").arg(relations_src[i].key, relations_src[i].ocol, relations_src[i].table), db);
|
|
QList<QPair<int, QString> > cr;
|
|
while (q.next())
|
|
cr << QPair<int, QString>(q.value(0).toInt(), q.value(1).toString());
|
|
relations[relations_src[i].tcol] = cr;
|
|
}
|
|
QFormLayout * lay = (QFormLayout*)layout();
|
|
if (!lay) return;
|
|
for (int i = 0; i < lay->rowCount(); ++i) {
|
|
QString name = lay->itemAt(i, QFormLayout::FieldRole)->widget()->objectName();
|
|
if (hidden.contains(name)) continue;
|
|
QComboBox * val = qobject_cast<QComboBox*>(lay->itemAt(i, QFormLayout::FieldRole)->widget());
|
|
if (!val) continue;
|
|
if (!relations.contains(name)) continue;
|
|
QList<QPair<int, QString> > & rv(relations[name]);
|
|
bool ok = false;
|
|
int sv(val->itemData(val->currentIndex()).toInt());
|
|
val->clear();
|
|
for (int j = 0; j < rv.size(); ++j) {
|
|
val->addItem(rv[j].second, rv[j].first);
|
|
if (sv == rv[j].first)
|
|
val->setCurrentIndex(j);
|
|
}
|
|
if (!ok)
|
|
val->setCurrentIndex(-1);
|
|
}
|
|
}
|