Files
qad/qad_sql_table/sql_record_widget.cpp
Бычков Андрей ba8bc27298 1
git-svn-id: svn://db.shs.com.ru/libs@1 a8b55f48-bf90-11e4-a774-851b48703e85
2015-02-28 21:28:53 +00:00

330 lines
11 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)) 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)) {
QList<QPair<int, QString> > & rv(relations[f.name()]);
bool ok = false;
int sv(f.value().toInt(&ok));
if (!ok)
((QComboBox*)val)->setCurrentIndex(-1);
else {
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())) {
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);
}
}
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)) {
ret += ((QComboBox*)w)->itemData(((QComboBox*)w)->currentIndex(), Qt::UserRole).toString();
}
}
return ret;
}
bool SQLRecordWidget::isEmpty() const {
return layout()->count() < 2;
}
void SQLRecordWidget::updateRelations() {
relations.clear();
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), QSqlDatabase::database(connection_name));
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);
}
}