You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
251 lines
6.3 KiB
251 lines
6.3 KiB
/* 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 <qheader.h>
|
|
#include <qlayout.h>
|
|
#include <qlabel.h>
|
|
#include <qpushbutton.h>
|
|
#include <qcursor.h>
|
|
#include <qpoint.h>
|
|
#include <qapplication.h>
|
|
#include <qbitmap.h>
|
|
#include <qstyle.h>
|
|
#include <qlistbox.h>
|
|
|
|
#include <kdebug.h>
|
|
#include <kiconloader.h>
|
|
#include <kdeversion.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;
|
|
}
|
|
QGuardedPtr<KexiProject> prj;
|
|
// KexiDB::TableOrQuerySchema* schema;
|
|
QPixmap keyIcon, noIcon;
|
|
QString tableOrQueryName;
|
|
QString fieldOrExpression;
|
|
QMap<QString, QString> captions;
|
|
bool table : 1;
|
|
};
|
|
|
|
//------------------------
|
|
|
|
KexiFieldComboBox::KexiFieldComboBox(QWidget *parent, const char *name)
|
|
: KComboBox(true/*rw*/, parent, name)
|
|
, d(new Private())
|
|
{
|
|
setInsertionPolicy(NoInsertion);
|
|
setCompletionMode(KGlobalSettings::CompletionPopupAuto);
|
|
setSizeLimit( 16 );
|
|
connect(this, SIGNAL(activated(int)), this, SLOT(slotActivated(int)));
|
|
connect(this, SIGNAL(returnPressed(const QString &)), this, SLOT(slotReturnPressed(const QString &)));
|
|
|
|
// 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 QString& 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
|
|
, 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);
|
|
}
|
|
|
|
QString KexiFieldComboBox::tableOrQueryName() const
|
|
{
|
|
return d->tableOrQueryName;
|
|
}
|
|
|
|
bool KexiFieldComboBox::isTableAssigned() const
|
|
{
|
|
return d->table;
|
|
}
|
|
|
|
void KexiFieldComboBox::setFieldOrExpression(const QString& string)
|
|
{
|
|
const QString name(string); //string.stripWhiteSpace().lower());
|
|
const int pos = name.find('.');
|
|
if (pos==-1) {
|
|
d->fieldOrExpression = name;
|
|
}
|
|
else {
|
|
QString 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);
|
|
}
|
|
|
|
QListBoxItem *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 << QString("KexiFieldComboBox::setFieldOrExpression(int index): index %1 "
|
|
"out of range (0..%2)").arg(index).arg(count()-1) << endl;
|
|
index = -1;
|
|
}
|
|
if (index<=0) {
|
|
setCurrentItem(0);
|
|
d->fieldOrExpression = QString::null;
|
|
}
|
|
else {
|
|
setCurrentItem(index);
|
|
d->fieldOrExpression = currentText();
|
|
}
|
|
}
|
|
|
|
QString 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;
|
|
}
|
|
|
|
QString KexiFieldComboBox::fieldOrExpressionCaption() const
|
|
{
|
|
return d->captions[ d->fieldOrExpression ];
|
|
}
|
|
|
|
void KexiFieldComboBox::slotActivated(int i)
|
|
{
|
|
d->fieldOrExpression = text(i);
|
|
emit selected();
|
|
}
|
|
|
|
void KexiFieldComboBox::slotReturnPressed(const QString & text)
|
|
{
|
|
//text is available: select item for this text:
|
|
int index;
|
|
if (text.isEmpty()) {
|
|
index = 0;
|
|
}
|
|
else {
|
|
QListBoxItem *item = listBox()->findItem( text, Qt::ExactMatch );
|
|
if (!item)
|
|
return;
|
|
index = listBox()->index( item );
|
|
if (index < 1)
|
|
return;
|
|
}
|
|
setCurrentItem( index );
|
|
slotActivated( index );
|
|
}
|
|
|
|
void KexiFieldComboBox::focusOutEvent( QFocusEvent *e )
|
|
{
|
|
KComboBox::focusOutEvent( e );
|
|
// accept changes if the focus is moved
|
|
if (!KexiUtils::hasParent(this, focusWidget())) //(a check needed because drop-down listbox also causes a focusout)
|
|
slotReturnPressed(currentText());
|
|
}
|
|
|
|
#include "kexifieldcombobox.moc"
|