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.
koffice/kexi/widget/kexifieldcombobox.cpp

251 lines
6.4 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 <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 <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;
}
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)").arg(index).arg(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(focusWidget()))) //(a check needed because drop-down listbox also causes a focusout)
slotReturnPressed(currentText());
}
#include "kexifieldcombobox.moc"