/* This file is part of the KDE project Copyright (C) 2005-2006 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 "kexifieldcombobox.h" #include <tqheader.h> #include <tqlayout.h> #include <tqlabel.h> #include <tqpushbutton.h> #include <tqcursor.h> #include <tqpoint.h> #include <tqapplication.h> #include <tqbitmap.h> #include <tqstyle.h> #include <tqlistbox.h> #include <kdebug.h> #include <kiconloader.h> #include <tdeversion.h> #include <kconfig.h> #include <kglobalsettings.h> #include <klocale.h> #include <kexidb/tableschema.h> #include <kexidb/queryschema.h> #include <kexidb/utils.h> #include <kexiutils/utils.h> #include <kexidragobjects.h> #include <kexiproject.h> //! @internal class KexiFieldComboBox::Private { public: Private() // : schema(0) : keyIcon( SmallIcon("key") ) , noIcon( KexiUtils::emptyIcon(KIcon::Small) ) , table(true) { } ~Private() { // delete schema; } TQGuardedPtr<KexiProject> prj; // KexiDB::TableOrQuerySchema* schema; TQPixmap keyIcon, noIcon; TQString tableOrQueryName; TQString fieldOrExpression; TQMap<TQString, TQString> captions; bool table : 1; }; //------------------------ KexiFieldComboBox::KexiFieldComboBox(TQWidget *parent, const char *name) : KComboBox(true/*rw*/, parent, name) , d(new Private()) { setInsertionPolicy(NoInsertion); setCompletionMode(KGlobalSettings::CompletionPopupAuto); setSizeLimit( 16 ); connect(this, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotActivated(int))); connect(this, TQT_SIGNAL(returnPressed(const TQString &)), this, TQT_SLOT(slotReturnPressed(const TQString &))); // setAcceptDrops(true); // viewport()->setAcceptDrops(true); } KexiFieldComboBox::~KexiFieldComboBox() { delete d; } void KexiFieldComboBox::setProject(KexiProject *prj) { if ((KexiProject*)d->prj==prj) return; d->prj = prj; setTableOrQuery("", true); } KexiProject* KexiFieldComboBox::project() const { return d->prj; } void KexiFieldComboBox::setTableOrQuery(const TQString& name, bool table) { d->tableOrQueryName = name; d->table = table; clear(); d->captions.clear(); insertItem(""); // delete d->schema; if (d->tableOrQueryName.isEmpty() || !d->prj) return; KexiDB::TableOrQuerySchema tableOrQuery(d->prj->dbConnection(), d->tableOrQueryName.latin1(), d->table); if (!tableOrQuery.table() && !tableOrQuery.query()) return; // bool hasPKeys = true; //t->hasPrimaryKeys(); KexiDB::QueryColumnInfo::Vector columns = tableOrQuery.columns(); const int count = columns.count(); for(int i=0; i < count; i++) { KexiDB::QueryColumnInfo *colinfo = columns[i]; insertItem( (colinfo && (colinfo->field->isPrimaryKey() || colinfo->field->isUniqueKey())) ? d->keyIcon : d->noIcon , TQString(colinfo->aliasOrName())); completionObject()->addItem(colinfo->aliasOrName()); //store user-friendly caption (used by fieldOrExpressionCaption()) d->captions.insert( colinfo->aliasOrName(), colinfo->captionOrAliasOrName() ); } //update selection setFieldOrExpression(d->fieldOrExpression); } TQString KexiFieldComboBox::tableOrQueryName() const { return d->tableOrQueryName; } bool KexiFieldComboBox::isTableAssigned() const { return d->table; } void KexiFieldComboBox::setFieldOrExpression(const TQString& string) { const TQString name(string); //string.stripWhiteSpace().lower()); const int pos = name.find('.'); if (pos==-1) { d->fieldOrExpression = name; } else { TQString objectName = name.left(pos); if (d->tableOrQueryName!=objectName) { d->fieldOrExpression = name; setCurrentItem(0); setCurrentText(name); //! @todo show error kexiwarn << "KexiFieldComboBox::setField(): invalid table/query name in '" << name << "'" << endl; return; } d->fieldOrExpression = name.mid(pos+1); } TQListBoxItem *item = listBox()->findItem(d->fieldOrExpression); if (!item) { setCurrentItem(0); setCurrentText(d->fieldOrExpression); //todo: show 'the item doesn't match' info? return; } setCurrentItem( listBox()->index(item) ); } void KexiFieldComboBox::setFieldOrExpression(int index) { index++; //skip 1st empty item if (index>=count()) { kexiwarn << TQString("KexiFieldComboBox::setFieldOrExpression(int index): index %1 " "out of range (0..%2)").tqarg(index).tqarg(count()-1) << endl; index = -1; } if (index<=0) { setCurrentItem(0); d->fieldOrExpression = TQString(); } else { setCurrentItem(index); d->fieldOrExpression = currentText(); } } TQString KexiFieldComboBox::fieldOrExpression() const { return d->fieldOrExpression; } int KexiFieldComboBox::indexOfField() const { KexiDB::TableOrQuerySchema tableOrQuery(d->prj->dbConnection(), d->tableOrQueryName.latin1(), d->table); if (!tableOrQuery.table() && !tableOrQuery.query()) return -1; return currentItem()>0 ? (currentItem()-1) : -1; } TQString KexiFieldComboBox::fieldOrExpressionCaption() const { return d->captions[ d->fieldOrExpression ]; } void KexiFieldComboBox::slotActivated(int i) { d->fieldOrExpression = text(i); emit selected(); } void KexiFieldComboBox::slotReturnPressed(const TQString & text) { //text is available: select item for this text: int index; if (text.isEmpty()) { index = 0; } else { TQListBoxItem *item = listBox()->findItem( text, TQt::ExactMatch ); if (!item) return; index = listBox()->index( item ); if (index < 1) return; } setCurrentItem( index ); slotActivated( index ); } void KexiFieldComboBox::focusOutEvent( TQFocusEvent *e ) { KComboBox::focusOutEvent( e ); // accept changes if the focus is moved if (!KexiUtils::hasParent(TQT_TQOBJECT(this), TQT_TQOBJECT(tqfocusWidget()))) //(a check needed because drop-down listbox also causes a focusout) slotReturnPressed(currentText()); } #include "kexifieldcombobox.moc"