QVariant RelationalProxyModel::getRelationData(QModelIndex index) const { int column = index.column(); if (not m_relations.contains(column)) return QVariant(); const QSqlRelation relation = m_relations[column]; QVariant related_id = sourceModel()->data(mapToSource(index)); QSqlDriver *driver = QSqlDatabase::database().driver(); QSqlRecord search_record; search_record.append(QSqlField(relation.indexColumn(), QVariant::Int)); search_record.setValue(relation.indexColumn(), QVariant(related_id.toInt())); QString where_statement = driver->sqlStatement(QSqlDriver::WhereStatement, relation.tableName(), search_record, false); QString select_statement = driver->sqlStatement(QSqlDriver::SelectStatement, relation.tableName(), QSqlDatabase::database().record(relation.tableName()), false); QSqlQuery query(QString("%1 %2").arg(select_statement, where_statement)); query.next(); if (not query.isValid()) return QVariant(); return query.record().value(relation.displayColumn()); }
void QRelation::populateModel() { if (!isValid()) return; Q_ASSERT(m_parent != NULL); if (!model) { model = new QSqlTableModel(m_parent, m_parent->database()); model->setTable(rel.tableName()); model->select(); } }
void ComboBoxFileldDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QString pole = index.model()->data(index.sibling(index.row(),0)).toString(); int j; for(int i=0;i<fieldName.count();i++){ QString s = model->headerData( fieldName.at(i) , Qt::Horizontal).toString(); s.replace("\n"," "); if (s==pole){ j=fieldName.at(i); break; } } QSqlRelation rel = model->relation(j); if (index.column()>2){ if (rel.indexColumn()!=QString("")){ QSqlQuery query; query.exec(QString("SELECT * FROM %1 WHERE %2='%3'").arg(rel.tableName()).arg(rel.indexColumn()).arg(index.model()->data(index).toString())); while (query.next()) drawDisplay(painter, option, option.rect,query.record().value(rel.displayColumn()).toString()); return; } if (model->data(model->index(0,j), Qt::EditRole).type() == QVariant::Date){ drawDisplay(painter, option, option.rect, index.model()->data(index, Qt::EditRole).toDate().toString("dd.MM.yyyy")); return; } if (this->model->data(this->model->index(0,j), Qt::EditRole).type() == QVariant::Bool){ if (index.model()->data(index, Qt::DisplayRole).toInt()>0) drawDisplay(painter, option, option.rect, tr("Да")); else drawDisplay(painter, option, option.rect, tr("Нет")); drawFocus(painter, option, option.rect); return; } } QItemDelegate::paint(painter, option, index); }
/*! \reimp */ QString QSqlRelationalTableModel::selectStatement() const { Q_D(const QSqlRelationalTableModel); QString query; if (tableName().isEmpty()) return query; if (d->relations.isEmpty()) return QSqlTableModel::selectStatement(); QString tList; QString fList; QString where; QSqlRecord rec = d->baseRec; QStringList tables; const QRelation nullRelation; // Count how many times each field name occurs in the record QHash<QString, int> fieldNames; QStringList fieldList; for (int i = 0; i < rec.count(); ++i) { QSqlRelation relation = d->relations.value(i, nullRelation).rel; QString name; if (relation.isValid()) { // Count the display column name, not the original foreign key name = relation.displayColumn(); if (d->db.driver()->isIdentifierEscaped(name, QSqlDriver::FieldName)) name = d->db.driver()->stripDelimiters(name, QSqlDriver::FieldName); QSqlRecord rec = database().record(relation.tableName()); for (int i = 0; i < rec.count(); ++i) { if (name.compare(rec.fieldName(i), Qt::CaseInsensitive) == 0) { name = rec.fieldName(i); break; } } } else name = rec.fieldName(i); fieldNames.insert(name, fieldNames.value(name, 0) + 1); fieldList.append(name); } for (int i = 0; i < rec.count(); ++i) { QSqlRelation relation = d->relations.value(i, nullRelation).rel; if (relation.isValid()) { QString relTableAlias = QString::fromLatin1("relTblAl_%1").arg(i); if (!fList.isEmpty()) fList.append(QLatin1String(", ")); fList.append(d->relationField(relTableAlias,relation.displayColumn())); // If there are duplicate field names they must be aliased if (fieldNames.value(fieldList[i]) > 1) { QString relTableName = relation.tableName().section(QChar::fromLatin1('.'), -1, -1); if (d->db.driver()->isIdentifierEscaped(relTableName, QSqlDriver::TableName)) relTableName = d->db.driver()->stripDelimiters(relTableName, QSqlDriver::TableName); QString displayColumn = relation.displayColumn(); if (d->db.driver()->isIdentifierEscaped(displayColumn, QSqlDriver::FieldName)) displayColumn = d->db.driver()->stripDelimiters(displayColumn, QSqlDriver::FieldName); fList.append(QString::fromLatin1(" AS %1_%2_%3").arg(relTableName).arg(displayColumn).arg(fieldNames.value(fieldList[i]))); fieldNames.insert(fieldList[i], fieldNames.value(fieldList[i])-1); } // this needs fixing!! the below if is borken. tables.append(relation.tableName().append(QLatin1Char(' ')).append(relTableAlias)); if(!where.isEmpty()) where.append(QLatin1String(" AND ")); where.append(d->relationField(tableName(), d->db.driver()->escapeIdentifier(rec.fieldName(i), QSqlDriver::FieldName))); where.append(QLatin1String(" = ")); where.append(d->relationField(relTableAlias, relation.indexColumn())); } else { if (!fList.isEmpty()) fList.append(QLatin1String(", ")); fList.append(d->relationField(tableName(), d->db.driver()->escapeIdentifier(rec.fieldName(i), QSqlDriver::FieldName))); } } if (!tables.isEmpty()) tList.append(tables.join(QLatin1String(", "))); if (fList.isEmpty()) return query; if(!tList.isEmpty()) tList.prepend(QLatin1String(", ")); tList.prepend(tableName()); query.append(QLatin1String("SELECT ")); query.append(fList).append(QLatin1String(" FROM ")).append(tList); qAppendWhereClause(query, where, filter()); QString orderBy = orderByClause(); if (!orderBy.isEmpty()) query.append(QLatin1Char(' ')).append(orderBy); return query; }
/*! \reimp */ QString QSqlRelationalTableModel::selectStatement() const { Q_D(const QSqlRelationalTableModel); if (tableName().isEmpty()) return QString(); if (d->relations.isEmpty()) return QSqlTableModel::selectStatement(); // Count how many times each field name occurs in the record QHash<QString, int> fieldNames; QStringList fieldList; for (int i = 0; i < d->baseRec.count(); ++i) { QSqlRelation relation = d->relations.value(i).rel; QString name; if (relation.isValid()) { // Count the display column name, not the original foreign key name = relation.displayColumn(); if (d->db.driver()->isIdentifierEscaped(name, QSqlDriver::FieldName)) name = d->db.driver()->stripDelimiters(name, QSqlDriver::FieldName); const QSqlRecord rec = database().record(relation.tableName()); for (int i = 0; i < rec.count(); ++i) { if (name.compare(rec.fieldName(i), Qt::CaseInsensitive) == 0) { name = rec.fieldName(i); break; } } } else { name = d->baseRec.fieldName(i); } fieldNames[name] = fieldNames.value(name, 0) + 1; fieldList.append(name); } QString fList; QString conditions; QString from = Sql::from(tableName()); for (int i = 0; i < d->baseRec.count(); ++i) { QSqlRelation relation = d->relations.value(i).rel; const QString tableField = d->fullyQualifiedFieldName(tableName(), d->db.driver()->escapeIdentifier(d->baseRec.fieldName(i), QSqlDriver::FieldName)); if (relation.isValid()) { const QString relTableAlias = Sql::relTablePrefix(i); QString displayTableField = d->fullyQualifiedFieldName(relTableAlias, relation.displayColumn()); // Duplicate field names must be aliased if (fieldNames.value(fieldList[i]) > 1) { QString relTableName = relation.tableName().section(QChar::fromLatin1('.'), -1, -1); if (d->db.driver()->isIdentifierEscaped(relTableName, QSqlDriver::TableName)) relTableName = d->db.driver()->stripDelimiters(relTableName, QSqlDriver::TableName); QString displayColumn = relation.displayColumn(); if (d->db.driver()->isIdentifierEscaped(displayColumn, QSqlDriver::FieldName)) displayColumn = d->db.driver()->stripDelimiters(displayColumn, QSqlDriver::FieldName); const QString alias = QString::fromLatin1("%1_%2_%3").arg(relTableName).arg(displayColumn).arg(fieldNames.value(fieldList[i])); displayTableField = Sql::as(displayTableField, alias); --fieldNames[fieldList[i]]; } fList = Sql::comma(fList, displayTableField); // Join related table const QString tblexpr = Sql::concat(relation.tableName(), relTableAlias); const QString relTableField = d->fullyQualifiedFieldName(relTableAlias, relation.indexColumn()); const QString cond = Sql::eq(tableField, relTableField); if (d->joinMode == QSqlRelationalTableModel::InnerJoin) { // FIXME: InnerJoin code is known to be broken. // Use LeftJoin mode if you want correct behavior. from = Sql::comma(from, tblexpr); conditions = Sql::et(conditions, cond); } else { from = Sql::concat(from, Sql::leftJoin(tblexpr)); from = Sql::concat(from, Sql::on(cond)); } } else { fList = Sql::comma(fList, tableField); } } if (fList.isEmpty()) return QString(); const QString stmt = Sql::concat(Sql::select(fList), from); const QString where = Sql::where(Sql::et(Sql::paren(conditions), Sql::paren(filter()))); return Sql::concat(Sql::concat(stmt, where), orderByClause()); }
/*! \reimp */ QString QSqlRelationalTableModel::selectStatement() const { Q_D(const QSqlRelationalTableModel); QString query; if (tableName().isEmpty()) return query; if (d->relations.isEmpty()) return QSqlTableModel::selectStatement(); QString tList; QString fList; QString where; QSqlRecord rec = d->baseRec; QStringList tables; const QRelation nullRelation; // Count how many times each field name occurs in the record QHash<QString, int> fieldNames; for (int i = 0; i < rec.count(); ++i) { QSqlRelation relation = d->relations.value(i, nullRelation).rel; QString name; if (relation.isValid()) // Count the display column name, not the original foreign key name = relation.displayColumn(); else name = rec.fieldName(i); fieldNames.insert(name, fieldNames.value(name, 0) + 1); } for (int i = 0; i < rec.count(); ++i) { QSqlRelation relation = d->relations.value(i, nullRelation).rel; if (relation.isValid()) { QString relTableAlias = QString::fromLatin1("relTblAl_%1").arg(i); fList.append(d->escapedRelationField(relTableAlias, relation.displayColumn())); // If there are duplicate field names they must be aliased if (fieldNames.value(relation.displayColumn()) > 1) fList.append(QString::fromLatin1(" AS %1_%2").arg(relation.tableName()).arg(relation.displayColumn())); fList.append(QLatin1Char(',')); if (!tables.contains(relation.tableName())) tables.append(d->db.driver()->escapeIdentifier(relation.tableName(), QSqlDriver::TableName).append(QLatin1String(" ")).append( d->db.driver()->escapeIdentifier(relTableAlias, QSqlDriver::TableName))); where.append(d->escapedRelationField(tableName(), rec.fieldName(i))); where.append(QLatin1Char('=')); where.append(d->escapedRelationField(relTableAlias, relation.indexColumn())); where.append(QLatin1String(" AND ")); } else { fList.append(d->escapedRelationField(tableName(), rec.fieldName(i))); fList.append(QLatin1Char(',')); } } if (!tables.isEmpty()) tList.append(tables.join(QLatin1String(","))).append(QLatin1String(",")); if (fList.isEmpty()) return query; tList.prepend(QLatin1Char(',')).prepend(d->db.driver()->escapeIdentifier(tableName(), QSqlDriver::TableName)); // truncate tailing comma tList.chop(1); fList.chop(1); query.append(QLatin1String("SELECT ")); query.append(fList).append(QLatin1String(" FROM ")).append(tList); if (!where.isEmpty()) where.chop(5); qAppendWhereClause(query, where, filter()); QString orderBy = orderByClause(); if (!orderBy.isEmpty()) query.append(QLatin1Char(' ')).append(orderBy); return query; }
// Предоставление редактора QWidget* ComboBoxFileldDelegate::createEditor ( QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index ) const { if (index.column()>2){ // QMessageBox::critical(0,"",index.model()->data(index.sibling(index.row(),0)).toString()); QString pole = index.model()->data(index.sibling(index.row(),0)).toString(); int j; for(int i=0;i<fieldName.count();i++){ QString s = model->headerData( fieldName.at(i) , Qt::Horizontal).toString(); s.replace("\n"," "); if (s==pole){ j=fieldName.at(i); break; } } //QMessageBox::critical(0,"",QString("%1").arg(j)); QSqlRelation rel = model->relation(j); if (rel.indexColumn()!=QString("")){ //QMessageBox::critical(0,"",rel.indexColumn()+" "+rel.displayColumn()+" "+rel.tableName()); QComboBox * pRes = new QComboBox(parent); QSqlTableModel* relModel = new QSqlTableModel; relModel->setTable(rel.tableName()); relModel->select(); pRes->setModel(relModel); pRes->setModelColumn(relModel->fieldIndex(rel.displayColumn())); return pRes; } if (model->data(model->index(0,j), Qt::EditRole).type() == QVariant::Date){ QDateEdit* pRes = new QDateEdit(parent); pRes->setCalendarPopup(true); pRes->setDisplayFormat("dd.MM.yyyy"); return pRes; } if (model->data(model->index(0,j), Qt::EditRole).type() == QVariant::Bool){ QComboBox * pRes = new QComboBox(parent); pRes->addItem(tr("Нет")); pRes->addItem(tr("Да")); return pRes; } return QItemDelegate::createEditor(parent,option,index); } QComboBox * pRes = new QComboBox(parent); switch (index.column()) { case 0: { QStringList field; for(int i=0;i<fieldName.count();i++){ QString s = model->headerData( fieldName.at(i) , Qt::Horizontal).toString(); s.replace("\n"," "); field<<s; } pRes->addItems(field); break; } case 1: { pRes->addItem(tr(" ")); pRes->addItem(tr("не")); break; } case 2: { pRes->addItem(tr("равно")); pRes->addItem(tr("похоже на")); pRes->addItem(tr("больше")); pRes->addItem(tr("меньше")); break; } } // это строка нужна для того чтобы по enter и esc завершалось редактирование итд pRes->installEventFilter(const_cast<ComboBoxFileldDelegate*>(this)); return pRes; };
// Предоставление редактора QWidget* ComboBoxMailDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { if (index.column() == 1) { // QMessageBox::critical(0,"",index.model()->data(index.sibling(index.row(),0)).toString()); QString pole = index.model()->data(index.sibling(index.row(), 0)).toString(); int j; for (int i = 0; i < fieldName.count(); i++) { QString s = model->headerData(fieldName.at(i) , Qt::Horizontal).toString(); s.replace("\n", " "); if (s == pole) { j = fieldName.at(i); break; } } //QMessageBox::critical(0,"",QString("%1").arg(j)); QSqlRelation rel = model->relation(j); if (rel.indexColumn() != QString("")) { //QMessageBox::critical(0,"",rel.indexColumn()+" "+rel.displayColumn()+" "+rel.tableName()); QComboBox* pRes = new QComboBox(parent); QSqlTableModel* relModel = new QSqlTableModel; relModel->setTable(rel.tableName()); /* Удаление выбранных значений в кому */ if (pole == tr("Кому")) { QString relFilter = QString("user_id != '00000000-0000-0000-0000-000000000000'"); for (int i = 0; i < index.model()->rowCount(); i++) { QString pole = index.model()->data(index.sibling(i, 0)).toString(); if (pole == tr("Кому") && index.row() != i) { QString val = index.model()->data(index.sibling(i, 1)).toString(); if ( val != QString("")) relFilter = QString("%1 and not user_id = '%2'").arg(relFilter).arg(val); } //QMessageBox::critical(0,"",index.model()->data(index.sibling(i,1)).toString()); } //QMessageBox::critical(0,"","-"+relFilter+"-"); relModel->setFilter(relFilter); } relModel->select(); pRes->setModel(relModel); pRes->setModelColumn(relModel->fieldIndex(rel.displayColumn())); return pRes; } if (model->data(model->index(0, j)).type() == QVariant::Date) { QDateEdit* pRes = new QDateEdit(parent); pRes->setCalendarPopup(true); pRes->setDisplayFormat("dd.MM.yyyy"); return pRes; } if (model->data(model->index(0, j)).type() == QVariant::Bool) { QComboBox* pRes = new QComboBox(parent); pRes->addItem(tr("Нет")); pRes->addItem(tr("Да")); return pRes; } return QItemDelegate::createEditor(parent, option, index); } if (index.column() == 0) { QComboBox* pRes = new QComboBox(parent); bool typeflag = true; bool priorflag = true; bool recipientflag = true; bool beginflag = true; bool endflag = true; for (int i = 0; i < index.model()->rowCount(); i++) { QString pole = index.model()->data(index.sibling(i, 0)).toString(); if (pole == tr("Тип") && index.row() != i) typeflag = false; if (pole == tr("Приоритет") && index.row() != i) priorflag = false; if (pole == tr("Начало") && index.row() != i) beginflag = false; if (pole == tr("Конец") && index.row() != i) endflag = false; } //if (recipientflag) pRes->addItem(tr("Кому")); if (typeflag) pRes->addItem(tr("Тип")); if (priorflag) pRes->addItem(tr("Приоритет")); if (beginflag) pRes->addItem(tr("Начало")); if (endflag) pRes->addItem(tr("Конец")); //pRes->addItem(tr("Копия")); // это строка нужна для того чтобы по enter и esc завершалось редактирование итд pRes->installEventFilter(const_cast<ComboBoxMailDelegate*>(this)); return pRes; } return QItemDelegate::createEditor(parent, option, index); };