|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2002 Peter Simonsson <psn@linux.se>
|
|
|
|
Copyright (C) 2003-2007 Jaroslaw Staniek <js@iidea.pl>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this program; see the file COPYING. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <tqstyle.h>
|
|
|
|
#include <tqwindowsstyle.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
|
|
|
|
#include "kexicomboboxbase.h"
|
|
|
|
#include <widget/utils/kexicomboboxdropdownbutton.h>
|
|
|
|
#include "kexicomboboxpopup.h"
|
|
|
|
#include "kexitableview.h"
|
|
|
|
#include "kexitableitem.h"
|
|
|
|
#include "kexi.h"
|
|
|
|
|
|
|
|
#include <klineedit.h>
|
|
|
|
|
|
|
|
KexiComboBoxBase::KexiComboBoxBase()
|
|
|
|
{
|
|
|
|
m_internalEditorValueChanged = false; //user has text or other value inside editor
|
|
|
|
m_slotInternalEditorValueChanged_enabled = true;
|
|
|
|
m_mouseBtnPressedWhenPopupVisible = false;
|
|
|
|
m_insideCreatePopup = false;
|
|
|
|
m_setValueOrTextInInternalEditor_enabled = true;
|
|
|
|
m_updatePopupSelectionOnShow = true;
|
|
|
|
m_moveCursorToEndInInternalEditor_enabled = true;
|
|
|
|
m_selectAllInInternalEditor_enabled = true;
|
|
|
|
m_setValueInInternalEditor_enabled = true;
|
|
|
|
m_setVisibleValueOnSetValueInternal = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
KexiComboBoxBase::~KexiComboBoxBase()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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()->KexiDataAwareObjectInterface::data();
|
|
|
|
const int boundColumn = lookupFieldSchema->boundColumn();
|
|
|
|
KexiTableViewData::Iterator it(tvData->iterator());
|
|
|
|
int row=0;
|
|
|
|
for (;it.current();++it, row++)
|
|
|
|
{
|
|
|
|
if (it.current()->at(boundColumn).toInt(&ok) == rowUid && ok || !ok)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!ok || !it.current()) //item not found: highlight 1st row, if available
|
|
|
|
return -1;
|
|
|
|
return row;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiComboBoxBase::setValueInternal(const TQVariant& add_, bool removeOld)
|
|
|
|
{
|
|
|
|
Q_UNUSED(removeOld);
|
|
|
|
m_mouseBtnPressedWhenPopupVisible = false;
|
|
|
|
m_updatePopupSelectionOnShow = true;
|
|
|
|
TQString add(add_.toString());
|
|
|
|
if (add.isEmpty()) {
|
|
|
|
KexiTableViewData *relData = column() ? column()->relatedData() : 0;
|
|
|
|
TQVariant 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()->setHighlightedRow(rowToHighlight);
|
|
|
|
|
|
|
|
const int visibleColumn = lookupFieldSchema->visibleColumn( popup()->tableView()->KexiDataAwareObjectInterface::data()->columnsCount() );
|
|
|
|
if (m_setVisibleValueOnSetValueInternal && -1!=visibleColumn) {
|
|
|
|
//only for table views
|
|
|
|
KexiTableItem *it = popup()->tableView()->highlightedItem();
|
|
|
|
if (it)
|
|
|
|
valueToSet = it->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).stripWhiteSpace();
|
|
|
|
}
|
|
|
|
if (hasValueToSet)
|
|
|
|
setValueOrTextInInternalEditor( valueToSet );
|
|
|
|
/*impl.*/moveCursorToEndInInternalEditor();
|
|
|
|
/*impl.*/selectAllInInternalEditor();
|
|
|
|
|
|
|
|
if (popup()) {
|
|
|
|
if (origValue().isNull()) {
|
|
|
|
popup()->tableView()->clearSelection();
|
|
|
|
popup()->tableView()->setHighlightedRow(0);
|
|
|
|
} else {
|
|
|
|
if (relData) {
|
|
|
|
if (rowToHighlight!=-1)
|
|
|
|
popup()->tableView()->setHighlightedRow(rowToHighlight);
|
|
|
|
}
|
|
|
|
else if (!lookupFieldSchema) {
|
|
|
|
//popup()->tableView()->selectRow(origValue().toInt());
|
|
|
|
popup()->tableView()->setHighlightedRow(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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KexiTableItem* KexiComboBoxBase::selectItemForEnteredValueInLookupTable(const TQVariant& v)
|
|
|
|
{
|
|
|
|
KexiDB::LookupFieldSchema *lookupFieldSchema = this->lookupFieldSchema();
|
|
|
|
if (!popup() || !lookupFieldSchema)
|
|
|
|
return 0; //safety
|
|
|
|
//-not effective for large sets: please cache it!
|
|
|
|
//.stripWhiteSpace() is not generic!
|
|
|
|
|
|
|
|
const bool valueIsText = v.type()==TQVariant::String || v.type()==TQVariant::CString; //most common case
|
|
|
|
const TQString txt( valueIsText ? v.toString().stripWhiteSpace().lower() : TQString() );
|
|
|
|
KexiTableViewData *lookupData = popup()->tableView()->KexiDataAwareObjectInterface::data();
|
|
|
|
const int visibleColumn = lookupFieldSchema->visibleColumn( lookupData->columnsCount() );
|
|
|
|
if (-1 == visibleColumn)
|
|
|
|
return 0;
|
|
|
|
KexiTableViewData::Iterator it(lookupData->iterator());
|
|
|
|
int row;
|
|
|
|
for (row = 0;it.current();++it, row++) {
|
|
|
|
if (valueIsText) {
|
|
|
|
if (it.current()->at(visibleColumn).toString().stripWhiteSpace().lower() == txt)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (it.current()->at(visibleColumn) == v)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_setValueOrTextInInternalEditor_enabled = false; // <-- this is the entered value,
|
|
|
|
// so do not change the internal editor's contents
|
|
|
|
if (it.current())
|
|
|
|
popup()->tableView()->selectRow(row);
|
|
|
|
else
|
|
|
|
popup()->tableView()->clearSelection();
|
|
|
|
|
|
|
|
m_setValueOrTextInInternalEditor_enabled = true;
|
|
|
|
|
|
|
|
return it.current();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KexiComboBoxBase::valueForString(const TQString& str, int* row,
|
|
|
|
uint lookInColumn, uint returnFromColumn, bool allowNulls)
|
|
|
|
{
|
|
|
|
KexiTableViewData *relData = column() ? column()->relatedData() : 0;
|
|
|
|
if (!relData)
|
|
|
|
return TQString(); //safety
|
|
|
|
//use 'related table data' model
|
|
|
|
//-not effective for large sets: please cache it!
|
|
|
|
//.stripWhiteSpace() is not generic!
|
|
|
|
|
|
|
|
const TQString txt = str.stripWhiteSpace().lower();
|
|
|
|
KexiTableViewData::Iterator it( relData->iterator() );
|
|
|
|
for (*row = 0;it.current();++it, (*row)++) {
|
|
|
|
if (it.current()->at(lookInColumn).toString().stripWhiteSpace().lower()==txt)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (it.current())
|
|
|
|
return it.current()->at(returnFromColumn).toString();
|
|
|
|
|
|
|
|
*row = -1;
|
|
|
|
|
|
|
|
if (column() && column()->relatedDataEditable())
|
|
|
|
return str; //new value entered and that's allowed
|
|
|
|
|
|
|
|
kexiwarn << "KexiComboBoxBase::valueForString(): no related row found, ID will be painted!" << endl;
|
|
|
|
if (allowNulls)
|
|
|
|
return TQString();
|
|
|
|
return str; //for sanity but it's weird to show id to the user
|
|
|
|
}
|
|
|
|
|
|
|
|
TQVariant 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
|
|
|
|
KexiTableItem *it = popup() ? popup()->tableView()->selectedItem() : 0;
|
|
|
|
return it ? it->at(0) : origValue();//TQVariant();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ((lookupFieldSchema = this->lookupFieldSchema()))
|
|
|
|
{
|
|
|
|
if (lookupFieldSchema->boundColumn()==-1)
|
|
|
|
return origValue();
|
|
|
|
KexiTableItem *it = popup() ? popup()->tableView()->selectedItem() : 0;
|
|
|
|
if (/*!it &&*/ m_internalEditorValueChanged && !m_userEnteredValue.toString().isEmpty()) { //
|
|
|
|
//try to select a row using the user-entered text
|
|
|
|
if (!popup()) {
|
|
|
|
TQVariant prevUserEnteredValue = m_userEnteredValue;
|
|
|
|
createPopup(false);
|
|
|
|
m_userEnteredValue = prevUserEnteredValue;
|
|
|
|
}
|
|
|
|
it = selectItemForEnteredValueInLookupTable( m_userEnteredValue );
|
|
|
|
}
|
|
|
|
return it ? it->at( lookupFieldSchema->boundColumn() ) : TQVariant();
|
|
|
|
}
|
|
|
|
else if (popup()) {
|
|
|
|
//use 'enum hints' model
|
|
|
|
const int row = popup()->tableView()->currentRow();
|
|
|
|
if (row>=0)
|
|
|
|
return TQVariant( row );
|
|
|
|
}
|
|
|
|
|
|
|
|
if (valueFromInternalEditor().toString().isEmpty())
|
|
|
|
return TQVariant();
|
|
|
|
/*! \todo don't return just 1st row, but use autocompletion feature
|
|
|
|
and: show message box if entered text does not match! */
|
|
|
|
return origValue(); //unchanged
|
|
|
|
}
|
|
|
|
|
|
|
|
TQVariant KexiComboBoxBase::visibleValueForLookupField()
|
|
|
|
{
|
|
|
|
KexiDB::LookupFieldSchema *lookupFieldSchema = this->lookupFieldSchema();
|
|
|
|
if (!popup() || !lookupFieldSchema)
|
|
|
|
return TQVariant();
|
|
|
|
const int visibleColumn = lookupFieldSchema->visibleColumn( popup()->tableView()->KexiDataAwareObjectInterface::data()->columnsCount() );
|
|
|
|
if (-1 == visibleColumn)
|
|
|
|
return TQVariant();
|
|
|
|
KexiTableItem *it = popup()->tableView()->selectedItem();
|
|
|
|
return it ? it->at( TQMIN( (uint)visibleColumn, it->count()-1)/*sanity*/ ) : TQVariant();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQVariant KexiComboBoxBase::visibleValue()
|
|
|
|
{
|
|
|
|
return m_visibleValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiComboBoxBase::clear()
|
|
|
|
{
|
|
|
|
if (popup())
|
|
|
|
popup()->hide();
|
|
|
|
slotInternalEditorValueChanged(TQVariant());
|
|
|
|
}
|
|
|
|
|
|
|
|
tristate KexiComboBoxBase::valueChangedInternal()
|
|
|
|
{
|
|
|
|
//avoid comparing values:
|
|
|
|
KexiTableViewData *relData = column() ? column()->relatedData() : 0;
|
|
|
|
KexiDB::LookupFieldSchema *lookupFieldSchema = this->lookupFieldSchema();
|
|
|
|
if (relData || lookupFieldSchema) {
|
|
|
|
if (m_internalEditorValueChanged)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
//use 'related table data' model
|
|
|
|
KexiTableItem *it = popup() ? popup()->tableView()->selectedItem() : 0;
|
|
|
|
if (!it)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
//use 'enum hints' model
|
|
|
|
const int row = popup() ? popup()->tableView()->currentRow() : -1;
|
|
|
|
if (row<0 && !m_internalEditorValueChanged/*true if text box is cleared*/)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cancelled;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KexiComboBoxBase::valueIsNull()
|
|
|
|
{
|
|
|
|
// bool ok;
|
|
|
|
TQVariant v( value() );
|
|
|
|
return v.isNull();
|
|
|
|
// return !ok || v.isNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KexiComboBoxBase::valueIsEmpty()
|
|
|
|
{
|
|
|
|
return valueIsNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiComboBoxBase::showPopup()
|
|
|
|
{
|
|
|
|
createPopup(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiComboBoxBase::createPopup(bool show)
|
|
|
|
{
|
|
|
|
if (!field())
|
|
|
|
return;
|
|
|
|
m_insideCreatePopup = true;
|
|
|
|
TQWidget* thisWidget = dynamic_cast<TQWidget*>(this);
|
|
|
|
TQWidget *widgetToFocus = internalEditor() ? internalEditor() : thisWidget;
|
|
|
|
if (!popup()) {
|
|
|
|
setPopup( column() ? new KexiComboBoxPopup(thisWidget, *column())
|
|
|
|
: new KexiComboBoxPopup(thisWidget, *field()) );
|
|
|
|
TQObject::connect(popup(), TQ_SIGNAL(rowAccepted(KexiTableItem*,int)),
|
|
|
|
thisWidget, TQ_SLOT(slotRowAccepted(KexiTableItem*,int)));
|
|
|
|
TQObject::connect(popup()->tableView(), TQ_SIGNAL(itemSelected(KexiTableItem*)),
|
|
|
|
thisWidget, TQ_SLOT(slotItemSelected(KexiTableItem*)));
|
|
|
|
|
|
|
|
popup()->setFocusProxy( widgetToFocus );
|
|
|
|
popup()->tableView()->setFocusProxy( widgetToFocus );
|
|
|
|
popup()->installEventFilter(thisWidget);
|
|
|
|
|
|
|
|
if (origValue().isNull())
|
|
|
|
popup()->tableView()->clearSelection();
|
|
|
|
else {
|
|
|
|
popup()->tableView()->selectRow( 0 );
|
|
|
|
popup()->tableView()->setHighlightedRow( 0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (show && internalEditor() && !internalEditor()->isVisible())
|
|
|
|
/*emit*/editRequested();
|
|
|
|
|
|
|
|
TQPoint posMappedToGlobal = mapFromParentToGlobal(thisWidget->pos());
|
|
|
|
if (posMappedToGlobal != TQPoint(-1,-1)) {
|
|
|
|
//! todo alter the position to fit the popup within screen boundaries
|
|
|
|
popup()->move( posMappedToGlobal + TQPoint(0, thisWidget->height()) );
|
|
|
|
//to avoid flickering: first resize to 0-height, then show and resize back to prev. height
|
|
|
|
const int w = popupWidthHint();
|
|
|
|
popup()->resize(w, 0);
|
|
|
|
if (show)
|
|
|
|
popup()->show();
|
|
|
|
popup()->updateSize(w);
|
|
|
|
if (m_updatePopupSelectionOnShow) {
|
|
|
|
int rowToHighlight = -1;
|
|
|
|
KexiDB::LookupFieldSchema *lookupFieldSchema = this->lookupFieldSchema();
|
|
|
|
KexiTableViewData *relData = column() ? column()->relatedData() : 0;
|
|
|
|
if (lookupFieldSchema) {
|
|
|
|
rowToHighlight = rowToHighlightForLookupTable();
|
|
|
|
}
|
|
|
|
else if (relData) {
|
|
|
|
(void)valueForString(origValue().toString(), &rowToHighlight, 0, 1);
|
|
|
|
}
|
|
|
|
else //enum hint
|
|
|
|
rowToHighlight = origValue().toInt();
|
|
|
|
|
|
|
|
/*-->*/ m_moveCursorToEndInInternalEditor_enabled = show;
|
|
|
|
m_selectAllInInternalEditor_enabled = show;
|
|
|
|
m_setValueInInternalEditor_enabled = show;
|
|
|
|
if (rowToHighlight==-1) {
|
|
|
|
rowToHighlight = TQMAX( popup()->tableView()->highlightedRow(), 0);
|
|
|
|
setValueInInternalEditor(TQVariant());
|
|
|
|
}
|
|
|
|
popup()->tableView()->selectRow( rowToHighlight );
|
|
|
|
popup()->tableView()->setHighlightedRow( rowToHighlight );
|
|
|
|
if (rowToHighlight < popup()->tableView()->rowsPerPage())
|
|
|
|
popup()->tableView()->ensureCellVisible( 0, -1 );
|
|
|
|
|
|
|
|
/*-->*/ m_moveCursorToEndInInternalEditor_enabled = true;
|
|
|
|
m_selectAllInInternalEditor_enabled = true;
|
|
|
|
m_setValueInInternalEditor_enabled = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (show) {
|
|
|
|
moveCursorToEndInInternalEditor();
|
|
|
|
selectAllInInternalEditor();
|
|
|
|
widgetToFocus->setFocus();
|
|
|
|
}
|
|
|
|
m_insideCreatePopup = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiComboBoxBase::hide()
|
|
|
|
{
|
|
|
|
if (popup())
|
|
|
|
popup()->hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiComboBoxBase::slotRowAccepted(KexiTableItem * item, int row)
|
|
|
|
{
|
|
|
|
Q_UNUSED(row);
|
|
|
|
//update our value
|
|
|
|
//..nothing to do?
|
|
|
|
updateButton();
|
|
|
|
slotItemSelected(item);
|
|
|
|
/*emit*/acceptRequested();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiComboBoxBase::acceptPopupSelection()
|
|
|
|
{
|
|
|
|
if (!popup())
|
|
|
|
return;
|
|
|
|
KexiTableItem *item = popup()->tableView()->highlightedItem();
|
|
|
|
if (item) {
|
|
|
|
popup()->tableView()->selectRow( popup()->tableView()->highlightedRow() );
|
|
|
|
slotRowAccepted(item, -1);
|
|
|
|
}
|
|
|
|
popup()->hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiComboBoxBase::slotItemSelected(KexiTableItem*)
|
|
|
|
{
|
|
|
|
kexidbg << "KexiComboBoxBase::slotItemSelected(): m_visibleValue = " << m_visibleValue << endl;
|
|
|
|
|
|
|
|
TQVariant valueToSet;
|
|
|
|
KexiTableViewData *relData = column() ? column()->relatedData() : 0;
|
|
|
|
KexiDB::LookupFieldSchema *lookupFieldSchema = this->lookupFieldSchema();
|
|
|
|
|
|
|
|
m_visibleValue = lookupFieldSchema ? visibleValueForLookupField() : TQVariant();
|
|
|
|
|
|
|
|
if (relData) {
|
|
|
|
//use 'related table data' model
|
|
|
|
KexiTableItem *item = popup()->tableView()->selectedItem();
|
|
|
|
if (item)
|
|
|
|
valueToSet = item->at(1);
|
|
|
|
}
|
|
|
|
else if (lookupFieldSchema) {
|
|
|
|
KexiTableItem *item = popup()->tableView()->selectedItem();
|
|
|
|
const int visibleColumn = lookupFieldSchema->visibleColumn( popup()->tableView()->KexiDataAwareObjectInterface::data()->columnsCount() );
|
|
|
|
if (item && visibleColumn!=-1 /* && (int)item->size() >= visibleColumn --already checked*/) {
|
|
|
|
valueToSet = item->at( TQMIN( (uint)visibleColumn, item->count()-1)/*sanity*/ );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
//use 'enum hints' model
|
|
|
|
valueToSet = field()->enumHint( popup()->tableView()->currentRow() );
|
|
|
|
if (valueToSet.toString().isEmpty() && !m_insideCreatePopup) {
|
|
|
|
clear();
|
|
|
|
TQWidget* thisWidget = dynamic_cast<TQWidget*>(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;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiComboBoxBase::slotInternalEditorValueChanged(const TQVariant& v)
|
|
|
|
{
|
|
|
|
if (!m_slotInternalEditorValueChanged_enabled)
|
|
|
|
return;
|
|
|
|
m_userEnteredValue = v;
|
|
|
|
m_internalEditorValueChanged = true;
|
|
|
|
if (v.toString().isEmpty()) {
|
|
|
|
if (popup()) {
|
|
|
|
popup()->tableView()->clearSelection();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiComboBoxBase::setValueOrTextInInternalEditor(const TQVariant& value)
|
|
|
|
{
|
|
|
|
if (!m_setValueOrTextInInternalEditor_enabled)
|
|
|
|
return;
|
|
|
|
setValueInInternalEditor( value );
|
|
|
|
//this text is not entered by hand:
|
|
|
|
m_userEnteredValue = TQVariant();
|
|
|
|
m_internalEditorValueChanged = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KexiComboBoxBase::handleKeyPressForPopup( TQKeyEvent *ke )
|
|
|
|
{
|
|
|
|
const int k = ke->key();
|
|
|
|
int highlightedOrSelectedRow = popup() ? popup()->tableView()->highlightedRow() : -1;
|
|
|
|
if (popup() && highlightedOrSelectedRow < 0)
|
|
|
|
highlightedOrSelectedRow = popup()->tableView()->currentRow();
|
|
|
|
|
|
|
|
const bool enterPressed = k==TQt::Key_Enter || k==TQt::Key_Return;
|
|
|
|
|
|
|
|
// The editor may be active but the pull down menu not existant/visible,
|
|
|
|
// e.g. when the user has pressed a normal button to activate the editor
|
|
|
|
// Don't handle the event here in that case.
|
|
|
|
if (!popup() || (!enterPressed && !popup()->isVisible())) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (k) {
|
|
|
|
case TQt::Key_Up:
|
|
|
|
popup()->tableView()->setHighlightedRow(
|
|
|
|
TQMAX(highlightedOrSelectedRow-1, 0) );
|
|
|
|
updateTextForHighlightedRow();
|
|
|
|
return true;
|
|
|
|
case TQt::Key_Down:
|
|
|
|
popup()->tableView()->setHighlightedRow(
|
|
|
|
TQMIN(highlightedOrSelectedRow+1, popup()->tableView()->rows()-1) );
|
|
|
|
updateTextForHighlightedRow();
|
|
|
|
return true;
|
|
|
|
case TQt::Key_PageUp:
|
|
|
|
popup()->tableView()->setHighlightedRow(
|
|
|
|
TQMAX(highlightedOrSelectedRow-popup()->tableView()->rowsPerPage(), 0) );
|
|
|
|
updateTextForHighlightedRow();
|
|
|
|
return true;
|
|
|
|
case TQt::Key_PageDown:
|
|
|
|
popup()->tableView()->setHighlightedRow(
|
|
|
|
TQMIN(highlightedOrSelectedRow+popup()->tableView()->rowsPerPage(),
|
|
|
|
popup()->tableView()->rows()-1) );
|
|
|
|
updateTextForHighlightedRow();
|
|
|
|
return true;
|
|
|
|
case TQt::Key_Home:
|
|
|
|
popup()->tableView()->setHighlightedRow( 0 );
|
|
|
|
updateTextForHighlightedRow();
|
|
|
|
return true;
|
|
|
|
case TQt::Key_End:
|
|
|
|
popup()->tableView()->setHighlightedRow( popup()->tableView()->rows()-1 );
|
|
|
|
updateTextForHighlightedRow();
|
|
|
|
return true;
|
|
|
|
case TQt::Key_Enter:
|
|
|
|
case TQt::Key_Return: //accept
|
|
|
|
//select row that is highlighted
|
|
|
|
if (popup()->tableView()->highlightedRow()>=0)
|
|
|
|
popup()->tableView()->selectRow( popup()->tableView()->highlightedRow() );
|
|
|
|
//do not return true: allow to process event
|
|
|
|
default: ;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiComboBoxBase::updateTextForHighlightedRow()
|
|
|
|
{
|
|
|
|
KexiTableItem *item = popup() ? popup()->tableView()->highlightedItem() : 0;
|
|
|
|
if (item)
|
|
|
|
slotItemSelected(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiComboBoxBase::undoChanges()
|
|
|
|
{
|
|
|
|
KexiDB::LookupFieldSchema *lookupFieldSchema = this->lookupFieldSchema();
|
|
|
|
if (lookupFieldSchema) {
|
|
|
|
// kexidbg << "KexiComboBoxBase::undoChanges(): m_visibleValue BEFORE = " << m_visibleValue << endl;
|
|
|
|
if (popup())
|
|
|
|
popup()->tableView()->selectRow( popup()->tableView()->highlightedRow() );
|
|
|
|
m_visibleValue = visibleValueForLookupField();
|
|
|
|
// kexidbg << "KexiComboBoxBase::undoChanges(): m_visibleValue AFTER = " << m_visibleValue << endl;
|
|
|
|
setValueOrTextInInternalEditor( m_visibleValue );
|
|
|
|
}
|
|
|
|
}
|