int KexiComboBoxBase::rowToHighlightForLookupTable() const
{
    if (!popup())
        return -1;//err
    KexiDB::LookupFieldSchema *lookupFieldSchema = this->lookupFieldSchema();
    if (!lookupFieldSchema)
        return -1;
    if (lookupFieldSchema->boundColumn() == -1)
        return -1; //err
    bool ok;
    const int rowUid = origValue().toInt();
//! @todo for now we're assuming the id is INTEGER
    KexiTableViewData *tvData = popup()->tableView()->data();
    const int boundColumn = lookupFieldSchema->boundColumn();
    int row = -1;
    for (KexiTableViewData::Iterator it(tvData->constBegin()); it != tvData->constEnd(); ++it) {
        row++;
        KexiDB::RecordData* record = *it;
        if (record->at(boundColumn).toInt(&ok) == rowUid && ok)
            return row;
        if (!ok)
            break;
    }
    //item not found: highlight 1st row, if available
    return -1;
}
KexiDB::LookupFieldSchema *KexiComboBoxBase::lookupFieldSchema() const
{
    if (field() && field()->table()) {
        KexiDB::LookupFieldSchema *lookupFieldSchema = field()->table()->lookupFieldSchema(*field());
        if (lookupFieldSchema && !lookupFieldSchema->rowSource().name().isEmpty())
            return lookupFieldSchema;
    }
    return 0;
}
QVariant KexiComboBoxBase::visibleValueForLookupField()
{
    KexiDB::LookupFieldSchema *lookupFieldSchema = this->lookupFieldSchema();
    if (!popup() || !lookupFieldSchema)
        return QVariant();
    const int visibleColumn = lookupFieldSchema->visibleColumn(popup()->tableView()->data()->columnsCount());
    if (-1 == visibleColumn)
        return QVariant();
    KexiDB::RecordData *record = popup()->tableView()->selectedItem();
    return record ? record->at(qMin(visibleColumn, record->count() - 1)/*sanity*/) : QVariant();
}
static bool hasEnumType(const KexiTableViewColumn &column)
{
    /*not db-aware case*/
    if (column.relatedData())
        return true;
    /*db-aware case*/
    if (!column.field() || !column.field()->table())
        return false;
    KexiDB::LookupFieldSchema *lookupFieldSchema = column.field()->table()->lookupFieldSchema(*column.field());
    if (!lookupFieldSchema)
        return false;
    if (lookupFieldSchema->rowSource().name().isEmpty())
        return false;
    return true;
}
QVariant KexiComboBoxBase::value()
{
    KexiTableViewData *relData = column() ? column()->relatedData() : 0;
    KexiDB::LookupFieldSchema *lookupFieldSchema = 0;
    if (relData) {
        if (m_internalEditorValueChanged) {
            //we've user-entered text: look for id
//TODO: make error if matching text not found?
            int rowToHighlight;
            return valueForString(m_userEnteredValue.toString(), &rowToHighlight, 1, 0, true/*allowNulls*/);
        } else {
            //use 'related table data' model
            KexiDB::RecordData *record = popup() ? popup()->tableView()->selectedItem() : 0;
            return record ? record->at(0) : origValue();
        }
    } else if ((lookupFieldSchema = this->lookupFieldSchema())) {
        if (lookupFieldSchema->boundColumn() == -1)
            return origValue();
        KexiDB::RecordData *record = popup() ? popup()->tableView()->selectedItem() : 0;
        if (/*!record &&*/ m_internalEditorValueChanged && !m_userEnteredValue.toString().isEmpty()) { //
            //try to select a row using the user-entered text
            if (!popup()) {
                QVariant prevUserEnteredValue = m_userEnteredValue;
                createPopup(false);
                m_userEnteredValue = prevUserEnteredValue;
            }
            record = selectItemForEnteredValueInLookupTable(m_userEnteredValue);
        }
        return record ? record->at(lookupFieldSchema->boundColumn()) : QVariant();
    } else if (popup()) {
        //use 'enum hints' model
        const int row = popup()->tableView()->currentRow();
        if (row >= 0)
            return QVariant(row);
    }

    if (valueFromInternalEditor().toString().isEmpty())
        return QVariant();
    /*! \todo don't return just 1st row, but use autocompletion feature
          and: show message box if entered text does not match! */
    return origValue(); //unchanged
}
void KexiComboBoxBase::slotItemSelected(KexiDB::RecordData*)
{
    //kDebug(44010) << "m_visibleValue=" << m_visibleValue;

    QVariant valueToSet;
    KexiTableViewData *relData = column() ? column()->relatedData() : 0;
    KexiDB::LookupFieldSchema *lookupFieldSchema = this->lookupFieldSchema();

    m_visibleValue = lookupFieldSchema ? visibleValueForLookupField() : QVariant();

    if (relData) {
        //use 'related table data' model
        KexiDB::RecordData *record = popup()->tableView()->selectedItem();
        if (record)
            valueToSet = record->at(1);
    } else if (lookupFieldSchema) {
        KexiDB::RecordData *record = popup()->tableView()->selectedItem();
        const int visibleColumn = lookupFieldSchema->visibleColumn(popup()->tableView()->data()->columnsCount());
        if (record && visibleColumn != -1 /* && (int)item->size() >= visibleColumn --already checked*/) {
            valueToSet = record->at(qMin(visibleColumn, record->count() - 1)/*sanity*/);
        }
    } else {
        //use 'enum hints' model
        valueToSet = field()->enumHint(popup()->tableView()->currentRow());
        if (valueToSet.toString().isEmpty() && !m_insideCreatePopup) {
            clear();
            QWidget* thisWidget = dynamic_cast<QWidget*>(this);
            thisWidget->parentWidget()->setFocus();
            return;
        }
    }
    setValueOrTextInInternalEditor(valueToSet);
    if (m_setValueOrTextInInternalEditor_enabled) {
        moveCursorToEndInInternalEditor();
        selectAllInInternalEditor();
    }
    // a new (temp) popup table index is selected: do not update selection next time:
    m_updatePopupSelectionOnShow = false;
}
KexiDB::RecordData* KexiComboBoxBase::selectItemForEnteredValueInLookupTable(const QVariant& v)
{
    KexiDB::LookupFieldSchema *lookupFieldSchema = this->lookupFieldSchema();
    if (!popup() || !lookupFieldSchema)
        return 0; //safety
//-not effective for large sets: please cache it!
//.trimmed() is not generic!

    const bool valueIsText = v.type() == QVariant::String || v.type() == QVariant::CString; //most common case
    const QString txt(valueIsText ? v.toString().trimmed() : QString());
    KexiTableViewData *lookupData = popup()->tableView()->data();
    const int visibleColumn = lookupFieldSchema->visibleColumn(lookupData->columnsCount());
    if (-1 == visibleColumn)
        return 0;
    KexiTableViewData::Iterator it(lookupData->constBegin());
    int row;
    for (row = 0;it != lookupData->constEnd();++it, row++) {
        if (valueIsText) {
            if ((*it)->at(visibleColumn).toString().trimmed().compare(txt, Qt::CaseInsensitive) == 0)
                break;
        } else {
            if ((*it)->at(visibleColumn) == v)
                break;
        }
    }

    m_setValueOrTextInInternalEditor_enabled = false; // <-- this is the entered value,
    //     so do not change the internal editor's contents
    if (it != lookupData->constEnd())
        popup()->tableView()->selectRow(row);
    else
        popup()->tableView()->clearSelection();

    m_setValueOrTextInInternalEditor_enabled = true;

    return it != lookupData->constEnd() ? *it : 0;
}
void KexiComboBoxBase::setValueInternal(const QVariant& add_, bool removeOld)
{
    Q_UNUSED(removeOld);
    m_mouseBtnPressedWhenPopupVisible = false;
    m_updatePopupSelectionOnShow = true;
    QString add(add_.toString());
    if (add.isEmpty()) {
        KexiTableViewData *relData = column() ? column()->relatedData() : 0;
        QVariant valueToSet;
        bool hasValueToSet = true;
        int rowToHighlight = -1;
        KexiDB::LookupFieldSchema *lookupFieldSchema = this->lookupFieldSchema();
        if (lookupFieldSchema) {
            //use 'lookup field' model
//! @todo support more RowSourceType's, not only table
            if (lookupFieldSchema->boundColumn() == -1)
//! @todo errmsg
                return;
            if (m_setVisibleValueOnSetValueInternal) {
                //only for table views
                if (!popup())
                    createPopup(false/*!show*/);
            }
            if (popup()) {
                const int rowToHighlight = rowToHighlightForLookupTable();
                popup()->tableView()->setHighlightedRecord(rowToHighlight);

                const int visibleColumn = lookupFieldSchema->visibleColumn(popup()->tableView()->data()->columnsCount());
                if (m_setVisibleValueOnSetValueInternal && -1 != visibleColumn) {
                    //only for table views
                    KexiDB::RecordData *record = popup()->tableView()->highlightedItem();
                    if (record)
                        valueToSet = record->at(visibleColumn);
                } else {
                    hasValueToSet = false;
                }
            }
        } else if (relData) {
            //use 'related table data' model
            valueToSet = valueForString(origValue().toString(), &rowToHighlight, 0, 1);
        } else {
            //use 'enum hints' model
            const int row = origValue().toInt();
            valueToSet = field()->enumHint(row).trimmed();
        }
        if (hasValueToSet)
            setValueOrTextInInternalEditor(valueToSet);
        /*impl.*/moveCursorToEndInInternalEditor();
        /*impl.*/selectAllInInternalEditor();

        if (popup()) {
            if (origValue().isNull()) {
                popup()->tableView()->clearSelection();
                popup()->tableView()->setHighlightedRecord(0);
            } else {
                if (relData) {
                    if (rowToHighlight != -1)
                        popup()->tableView()->setHighlightedRecord(rowToHighlight);
                } else if (!lookupFieldSchema) {
                    //popup()->tableView()->selectRow(origValue().toInt());
                    popup()->tableView()->setHighlightedRecord(origValue().toInt());
                }
            }
        }
    } else {
        //todo: autocompl.?
        if (popup())
            popup()->tableView()->clearSelection();
        /*impl.*/setValueInInternalEditor(add); //not setLineEditText(), because 'add' is entered by user!
        //setLineEditText( add );
        /*impl.*/moveCursorToEndInInternalEditor();
    }
}