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(); } }