/*!
    \reimp
*/
QVariant QSqlRelationalTableModel::data(const QModelIndex &index, int role) const
{
    Q_D(const QSqlRelationalTableModel);

    if (role == Qt::DisplayRole && index.column() >= 0 && index.column() < d->relations.count() &&
            d->relations.value(index.column()).isValid()) {
        QRelation &relation = d->relations[index.column()];
        if (!relation.isDictionaryInitialized())
            relation.populateDictionary();

        //only perform a dictionary lookup for the display value
        //when the value at index has been changed or added.
        //At an unmodified index, the underlying model will
        //already have the correct display value.
        if (d->strategy != OnFieldChange) {
            const QSqlTableModelPrivate::ModifiedRow row = d->cache.value(index.row());
            if (row.op() != QSqlTableModelPrivate::None && row.rec().isGenerated(index.column())) {
                if (d->strategy == OnManualSubmit || row.op() != QSqlTableModelPrivate::Delete) {
                    QVariant v = row.rec().value(index.column());
                    if (v.isValid())
                        return relation.dictionary[v.toString()];
                }
            }
        }
    }
    return QSqlTableModel::data(index, role);
}
/*! \reimp
*/
Qt::ItemFlags QSqlTableModel::flags(const QModelIndex &index) const
{
    Q_D(const QSqlTableModel);
    if (index.internalPointer() || index.column() < 0 || index.column() >= d->rec.count()
        || index.row() < 0)
        return 0;

    bool editable = true;

    if (d->rec.field(index.column()).isReadOnly()) {
        editable = false;
    }
    else {
        const QSqlTableModelPrivate::ModifiedRow mrow = d->cache.value(index.row());
        if (mrow.op() == QSqlTableModelPrivate::Delete) {
            editable = false;
        }
        else if (d->strategy == OnFieldChange) {
            if (mrow.op() != QSqlTableModelPrivate::Insert)
                if (!isDirty(index) && isDirty())
                    editable = false;
        }
        else if (d->strategy == OnRowChange) {
            if (mrow.submitted() && isDirty())
                editable = false;
        }
    }

    if (!editable)
        return QSqlQueryModel::flags(index);
    else
        return QSqlQueryModel::flags(index) | Qt::ItemIsEditable;
}
/*!
    \reimp
*/
QVariant QSqlTableModel::data(const QModelIndex &index, int role) const
{
    Q_D(const QSqlTableModel);
    if (!index.isValid() || (role != Qt::DisplayRole && role != Qt::EditRole))
        return QVariant();

    const QSqlTableModelPrivate::ModifiedRow mrow = d->cache.value(index.row());
    if (mrow.op() != QSqlTableModelPrivate::None)
        return mrow.rec().value(index.column());

    return QSqlQueryModel::data(index, role);
}
/*!
    \since 5.1
    Returns a record containing the fields represented in the primary key set to the values
    at \a row. If no primary key is defined, the returned record will contain all fields.

    \sa primaryKey()
*/
QSqlRecord QSqlTableModel::primaryValues(int row) const
{
    Q_D(const QSqlTableModel);

    const QSqlRecord &pIndex = d->primaryIndex.isEmpty() ? d->rec : d->primaryIndex;

    QSqlTableModelPrivate::ModifiedRow mr = d->cache.value(row);
    if (mr.op() != QSqlTableModelPrivate::None)
        return mr.primaryValues(pIndex);
    else
        return QSqlQueryModel::record(row).keyValues(pIndex);
}
/*!
\since 5.0
    Returns the record at \a row in the model.

    If \a row is the index of a valid row, the record
    will be populated with values from that row.

    If the model is not initialized, an empty record will be
    returned.

    \sa QSqlRecord::isEmpty()
*/
QSqlRecord QSqlTableModel::record(int row) const
{
    Q_D(const QSqlTableModel);

    // the query gets the values from virtual data()
    QSqlRecord rec = QSqlQueryModel::record(row);

    // get generated flags from the cache
    const QSqlTableModelPrivate::ModifiedRow mrow = d->cache.value(row);
    if (mrow.op() != QSqlTableModelPrivate::None) {
        const QSqlRecord crec = mrow.rec();
        for (int i = 0, cnt = rec.count(); i < cnt; ++i)
            rec.setGenerated(i, crec.isGenerated(i));
    }

    return rec;
}
/*!
    Returns \c true if the value at the index \a index is dirty, otherwise false.
    Dirty values are values that were modified in the model
    but not yet written into the database.

    If \a index is invalid or points to a non-existing row, false is returned.
*/
bool QSqlTableModel::isDirty(const QModelIndex &index) const
{
    Q_D(const QSqlTableModel);
    if (!index.isValid())
        return false;

    const QSqlTableModelPrivate::ModifiedRow row = d->cache.value(index.row());
    if (row.submitted())
        return false;

    return row.op() == QSqlTableModelPrivate::Insert
           || row.op() == QSqlTableModelPrivate::Delete
           || (row.op() == QSqlTableModelPrivate::Update
               && row.rec().isGenerated(index.column()));
}