kexi

kexifieldcombobox.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2005-2006 Jaroslaw Staniek <js@iidea.pl>
00003 
00004    This program is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this program; see the file COPYING.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "kexifieldcombobox.h"
00021 
00022 #include <qheader.h>
00023 #include <qlayout.h>
00024 #include <qlabel.h>
00025 #include <qpushbutton.h>
00026 #include <qcursor.h>
00027 #include <qpoint.h>
00028 #include <qapplication.h>
00029 #include <qbitmap.h>
00030 #include <qstyle.h>
00031 #include <qlistbox.h>
00032 
00033 #include <kdebug.h>
00034 #include <kiconloader.h>
00035 #include <kdeversion.h>
00036 #include <kconfig.h>
00037 #include <kglobalsettings.h>
00038 #include <klocale.h>
00039 
00040 #include <kexidb/tableschema.h>
00041 #include <kexidb/queryschema.h>
00042 #include <kexidb/utils.h>
00043 #include <kexiutils/utils.h>
00044 #include <kexidragobjects.h>
00045 #include <kexiproject.h>
00046 
00048 class KexiFieldComboBox::Private
00049 {
00050     public:
00051         Private()
00052 //       : schema(0)
00053          : keyIcon( SmallIcon("key") )
00054          , noIcon( KexiUtils::emptyIcon(KIcon::Small) )
00055          , table(true)
00056         {
00057         }
00058         ~Private()
00059         {
00060 //          delete schema;
00061         }
00062         QGuardedPtr<KexiProject> prj;
00063 //      KexiDB::TableOrQuerySchema* schema;
00064         QPixmap keyIcon, noIcon;
00065         QString tableOrQueryName;
00066         QString fieldOrExpression;
00067         QMap<QString, QString> captions;
00068         bool table : 1;
00069 };
00070 
00071 //------------------------
00072 
00073 KexiFieldComboBox::KexiFieldComboBox(QWidget *parent, const char *name)
00074  : KComboBox(true/*rw*/, parent, name)
00075  , d(new Private())
00076 {
00077     setInsertionPolicy(NoInsertion);
00078     setCompletionMode(KGlobalSettings::CompletionPopupAuto);
00079     setSizeLimit( 16 );
00080     connect(this, SIGNAL(activated(int)), this, SLOT(slotActivated(int)));
00081     connect(this, SIGNAL(returnPressed(const QString &)), this, SLOT(slotReturnPressed(const QString &)));
00082 
00083 //  setAcceptDrops(true);
00084 //  viewport()->setAcceptDrops(true);
00085 }
00086 
00087 KexiFieldComboBox::~KexiFieldComboBox()
00088 {
00089     delete d;
00090 }
00091 
00092 void KexiFieldComboBox::setProject(KexiProject *prj)
00093 {
00094     if ((KexiProject*)d->prj==prj)
00095         return;
00096     d->prj = prj;
00097     setTableOrQuery("", true);
00098 }
00099 
00100 KexiProject* KexiFieldComboBox::project() const
00101 {
00102     return d->prj;
00103 }
00104 
00105 void KexiFieldComboBox::setTableOrQuery(const QString& name, bool table)
00106 {
00107     d->tableOrQueryName = name;
00108     d->table = table;
00109     clear();
00110     d->captions.clear();
00111     insertItem("");
00112 //  delete d->schema;
00113     if (d->tableOrQueryName.isEmpty() || !d->prj)
00114         return;
00115 
00116     KexiDB::TableOrQuerySchema tableOrQuery(d->prj->dbConnection(), d->tableOrQueryName.latin1(), d->table);
00117     if (!tableOrQuery.table() && !tableOrQuery.query())
00118         return;
00119 
00120 //  bool hasPKeys = true; //t->hasPrimaryKeys();
00121     KexiDB::QueryColumnInfo::Vector columns = tableOrQuery.columns();
00122     const int count = columns.count();
00123     for(int i=0; i < count; i++)
00124     {
00125         KexiDB::QueryColumnInfo *colinfo = columns[i];
00126         insertItem(
00127             (colinfo && (colinfo->field->isPrimaryKey() || colinfo->field->isUniqueKey()))
00128             ? d->keyIcon
00129             : d->noIcon
00130             , colinfo->aliasOrName());
00131         completionObject()->addItem(colinfo->aliasOrName());
00132         //store user-friendly caption (used by fieldOrExpressionCaption())
00133         d->captions.insert( colinfo->aliasOrName(), colinfo->captionOrAliasOrName() );
00134     }
00135 
00136     //update selection
00137     setFieldOrExpression(d->fieldOrExpression);
00138 }
00139 
00140 QString KexiFieldComboBox::tableOrQueryName() const
00141 {
00142     return d->tableOrQueryName;
00143 }
00144 
00145 bool KexiFieldComboBox::isTableAssigned() const
00146 {
00147     return d->table;
00148 }
00149 
00150 void KexiFieldComboBox::setFieldOrExpression(const QString& string)
00151 {
00152     const QString name(string); //string.stripWhiteSpace().lower());
00153     const int pos = name.find('.');
00154     if (pos==-1) {
00155         d->fieldOrExpression = name;
00156     }
00157     else {
00158         QString objectName = name.left(pos);
00159         if (d->tableOrQueryName!=objectName) {
00160             d->fieldOrExpression = name;
00161             setCurrentItem(0);
00162             setCurrentText(name);
00164             kexiwarn << "KexiFieldComboBox::setField(): invalid table/query name in '" << name << "'" << endl;
00165             return;
00166         }
00167         d->fieldOrExpression = name.mid(pos+1);
00168     }
00169 
00170     QListBoxItem *item = listBox()->findItem(d->fieldOrExpression);
00171     if (!item) {
00172         setCurrentItem(0);
00173         setCurrentText(d->fieldOrExpression);
00174         //todo: show 'the item doesn't match' info?
00175         return;
00176     }
00177     setCurrentItem( listBox()->index(item) );
00178 }
00179 
00180 void KexiFieldComboBox::setFieldOrExpression(int index)
00181 {
00182     index++; //skip 1st empty item
00183     if (index>=count()) {
00184         kexiwarn << QString("KexiFieldComboBox::setFieldOrExpression(int index): index %1 "
00185             "out of range (0..%2)").arg(index).arg(count()-1) << endl;
00186         index = -1;
00187     }
00188     if (index<=0) {
00189         setCurrentItem(0);
00190         d->fieldOrExpression = QString::null;
00191     }
00192     else {
00193         setCurrentItem(index);
00194         d->fieldOrExpression = currentText();
00195     }
00196 }
00197 
00198 QString KexiFieldComboBox::fieldOrExpression() const
00199 {
00200     return d->fieldOrExpression;
00201 }
00202 
00203 int KexiFieldComboBox::indexOfField() const
00204 {
00205     KexiDB::TableOrQuerySchema tableOrQuery(d->prj->dbConnection(), d->tableOrQueryName.latin1(), d->table);
00206     if (!tableOrQuery.table() && !tableOrQuery.query())
00207         return -1;
00208 
00209     return currentItem()>0 ? (currentItem()-1) : -1;
00210 }
00211 
00212 QString KexiFieldComboBox::fieldOrExpressionCaption() const
00213 {
00214     return d->captions[ d->fieldOrExpression ];
00215 }
00216 
00217 void KexiFieldComboBox::slotActivated(int i)
00218 {
00219     d->fieldOrExpression = text(i);
00220     emit selected();
00221 }
00222 
00223 void KexiFieldComboBox::slotReturnPressed(const QString & text)
00224 {
00225     //text is available: select item for this text:
00226     int index;
00227     if (text.isEmpty()) {
00228         index = 0;
00229     }
00230     else {
00231         QListBoxItem *item = listBox()->findItem( text, Qt::ExactMatch );
00232         if (!item)
00233             return;
00234         index = listBox()->index( item );
00235         if (index < 1)
00236             return;
00237     }
00238     setCurrentItem( index );
00239     slotActivated( index );
00240 }
00241 
00242 void KexiFieldComboBox::focusOutEvent( QFocusEvent *e )
00243 {
00244     KComboBox::focusOutEvent( e );
00245     // accept changes if the focus is moved
00246     if (!KexiUtils::hasParent(this, focusWidget())) //(a check needed because drop-down listbox also causes a focusout)
00247         slotReturnPressed(currentText());
00248 }
00249 
00250 #include "kexifieldcombobox.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys