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          : table(true)
00054         {
00055         }
00056         ~Private()
00057         {
00058 //          delete schema;
00059         }
00060         QGuardedPtr<KexiProject> prj;
00061 //      KexiDB::TableOrQuerySchema* schema;
00062         QPixmap keyIcon, noIcon;
00063         QString tableOrQueryName;
00064         QString fieldOrExpression;
00065         QMap<QString, QString> captions;
00066         bool table;
00067 };
00068 
00069 //------------------------
00070 
00071 KexiFieldComboBox::KexiFieldComboBox(QWidget *parent, const char *name)
00072  : KComboBox(true/*rw*/, parent, name)
00073  , d(new Private())
00074 {
00075     d->keyIcon = SmallIcon("key");
00076     d->noIcon = QPixmap(d->keyIcon.size());
00077     QBitmap bmp(d->noIcon.size());
00078     bmp.fill(Qt::color0);
00079     d->noIcon.setMask(bmp);
00080 
00081     setInsertionPolicy(NoInsertion);
00082     setCompletionMode(KGlobalSettings::CompletionPopupAuto);
00083     setSizeLimit( 16 );
00084     connect(this, SIGNAL(activated(int)), this, SLOT(slotActivated(int)));
00085     connect(this, SIGNAL(returnPressed(const QString &)), this, SLOT(slotReturnPressed(const QString &)));
00086 
00087 //  setAcceptDrops(true);
00088 //  viewport()->setAcceptDrops(true);
00089 }
00090 
00091 KexiFieldComboBox::~KexiFieldComboBox()
00092 {
00093     delete d;
00094 }
00095 
00096 void KexiFieldComboBox::setProject(KexiProject *prj)
00097 {
00098     if ((KexiProject*)d->prj==prj)
00099         return;
00100     d->prj = prj;
00101     setTableOrQuery("", true);
00102 }
00103 
00104 KexiProject* KexiFieldComboBox::project() const
00105 {
00106     return d->prj;
00107 }
00108 
00109 void KexiFieldComboBox::setTableOrQuery(const QString& name, bool table)
00110 {
00111     d->tableOrQueryName = name;
00112     d->table = table;
00113     clear();
00114     d->captions.clear();
00115     insertItem("");
00116 //  delete d->schema;
00117     if (d->tableOrQueryName.isEmpty() || !d->prj)
00118         return;
00119 
00120     KexiDB::TableOrQuerySchema tableOrQuery(d->prj->dbConnection(), d->tableOrQueryName.latin1(), d->table);
00121     if (!tableOrQuery.table() && !tableOrQuery.query())
00122         return;
00123 
00124 //  bool hasPKeys = true; //t->hasPrimaryKeys();
00125     KexiDB::QueryColumnInfo::Vector columns = tableOrQuery.columns();
00126     const int count = columns.count();
00127     for(int i=0; i < count; i++)
00128     {
00129         KexiDB::QueryColumnInfo *colinfo = columns[i];
00130         insertItem(
00131             (colinfo && (colinfo->field->isPrimaryKey() || colinfo->field->isUniqueKey()))
00132             ? d->keyIcon
00133             : d->noIcon
00134             , colinfo->aliasOrName());
00135         completionObject()->addItem(colinfo->aliasOrName());
00136         //store user-friendly caption (used by fieldOrExpressionCaption())
00137         d->captions.insert( colinfo->aliasOrName(), colinfo->captionOrAliasOrName() );
00138     }
00139 
00140     //update selection
00141     setFieldOrExpression(d->fieldOrExpression);
00142 }
00143 
00144 QString KexiFieldComboBox::tableOrQueryName() const
00145 {
00146     return d->tableOrQueryName;
00147 }
00148 
00149 bool KexiFieldComboBox::isTableAssigned() const
00150 {
00151     return d->table;
00152 }
00153 
00154 void KexiFieldComboBox::setFieldOrExpression(const QString& string)
00155 {
00156     const QString name(string); //string.stripWhiteSpace().lower());
00157     const int pos = name.find('.');
00158     if (pos==-1) {
00159         d->fieldOrExpression = name;
00160     }
00161     else {
00162         QString objectName = name.left(pos);
00163         if (d->tableOrQueryName!=objectName) {
00164             d->fieldOrExpression = name;
00165             setCurrentItem(0);
00166             setCurrentText(name);
00168             kexiwarn << "KexiFieldComboBox::setField(): invalid table/query name in '" << name << "'" << endl;
00169             return;
00170         }
00171         d->fieldOrExpression = name.mid(pos+1);
00172     }
00173 
00174     QListBoxItem *item = listBox()->findItem(d->fieldOrExpression);
00175     if (!item) {
00176         setCurrentItem(0);
00177         setCurrentText(d->fieldOrExpression);
00178         //todo: show 'the item doesn't match' info?
00179         return;
00180     }
00181     setCurrentItem( listBox()->index(item) );
00182 }
00183 
00184 void KexiFieldComboBox::setFieldOrExpression(int index)
00185 {
00186     index++; //skip 1st empty item
00187     if (index>=count()) {
00188         kexiwarn << QString("KexiFieldComboBox::setFieldOrExpression(int index): index %1 "
00189             "out of range (0..%2)").arg(index).arg(count()-1) << endl;
00190         index = -1;
00191     }
00192     if (index<=0) {
00193         setCurrentItem(0);
00194         d->fieldOrExpression = QString::null;
00195     }
00196     else {
00197         setCurrentItem(index);
00198         d->fieldOrExpression = currentText();
00199     }
00200 }
00201 
00202 QString KexiFieldComboBox::fieldOrExpression() const
00203 {
00204     return d->fieldOrExpression;
00205 }
00206 
00207 int KexiFieldComboBox::indexOfField() const
00208 {
00209     KexiDB::TableOrQuerySchema tableOrQuery(d->prj->dbConnection(), d->tableOrQueryName.latin1(), d->table);
00210     if (!tableOrQuery.table() && !tableOrQuery.query())
00211         return -1;
00212 
00213     return currentItem()>0 ? (currentItem()-1) : -1;
00214 }
00215 
00216 QString KexiFieldComboBox::fieldOrExpressionCaption() const
00217 {
00218     return d->captions[ d->fieldOrExpression ];
00219 }
00220 
00221 void KexiFieldComboBox::slotActivated(int i)
00222 {
00223     d->fieldOrExpression = text(i);
00224     emit selected();
00225 }
00226 
00227 void KexiFieldComboBox::slotReturnPressed(const QString & text)
00228 {
00229     //text is available: select item for this text:
00230     int index;
00231     if (text.isEmpty()) {
00232         index = 0;
00233     }
00234     else {
00235         QListBoxItem *item = listBox()->findItem( text, Qt::ExactMatch );
00236         if (!item)
00237             return;
00238         index = listBox()->index( item );
00239         if (index < 1)
00240             return;
00241     }
00242     setCurrentItem( index );
00243     slotActivated( index );
00244 }
00245 
00246 void KexiFieldComboBox::focusOutEvent( QFocusEvent *e )
00247 {
00248     KComboBox::focusOutEvent( e );
00249     // accept changes if the focus is moved
00250     if (!KexiUtils::hasParent(this, focusWidget())) //(a check needed because drop-down listbox also causes a focusout)
00251         slotReturnPressed(currentText());
00252 }
00253 
00254 #include "kexifieldcombobox.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys