kexi

kexifieldcombobox.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2005-2006 Jaroslaw Staniek <js@iidea.pl>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; see the file COPYING. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "kexifieldcombobox.h"
21
22#include <tqheader.h>
23#include <tqlayout.h>
24#include <tqlabel.h>
25#include <tqpushbutton.h>
26#include <tqcursor.h>
27#include <tqpoint.h>
28#include <tqapplication.h>
29#include <tqbitmap.h>
30#include <tqstyle.h>
31#include <tqlistbox.h>
32
33#include <kdebug.h>
34#include <kiconloader.h>
35#include <tdeconfig.h>
36#include <tdeglobalsettings.h>
37#include <tdelocale.h>
38
39#include <kexidb/tableschema.h>
40#include <kexidb/queryschema.h>
41#include <kexidb/utils.h>
42#include <kexiutils/utils.h>
43#include <kexidragobjects.h>
44#include <kexiproject.h>
45
47class KexiFieldComboBox::Private
48{
49 public:
50 Private()
51// : schema(0)
52 : keyIcon( SmallIcon("key") )
53 , noIcon( KexiUtils::emptyIcon(TDEIcon::Small) )
54 , table(true)
55 {
56 }
57 ~Private()
58 {
59// delete schema;
60 }
61 TQGuardedPtr<KexiProject> prj;
62// KexiDB::TableOrQuerySchema* schema;
63 TQPixmap keyIcon, noIcon;
64 TQString tableOrQueryName;
65 TQString fieldOrExpression;
66 TQMap<TQString, TQString> captions;
67 bool table : 1;
68};
69
70//------------------------
71
72KexiFieldComboBox::KexiFieldComboBox(TQWidget *parent, const char *name)
73 : KComboBox(true/*rw*/, parent, name)
74 , d(new Private())
75{
76 setInsertionPolicy(NoInsertion);
77 setCompletionMode(TDEGlobalSettings::CompletionPopupAuto);
78 setSizeLimit( 16 );
79 connect(this, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotActivated(int)));
80 connect(this, TQ_SIGNAL(returnPressed(const TQString &)), this, TQ_SLOT(slotReturnPressed(const TQString &)));
81
82// setAcceptDrops(true);
83// viewport()->setAcceptDrops(true);
84}
85
86KexiFieldComboBox::~KexiFieldComboBox()
87{
88 delete d;
89}
90
92{
93 if ((KexiProject*)d->prj==prj)
94 return;
95 d->prj = prj;
96 setTableOrQuery("", true);
97}
98
100{
101 return d->prj;
102}
103
104void KexiFieldComboBox::setTableOrQuery(const TQString& name, bool table)
105{
106 d->tableOrQueryName = name;
107 d->table = table;
108 clear();
109 d->captions.clear();
110 insertItem("");
111// delete d->schema;
112 if (d->tableOrQueryName.isEmpty() || !d->prj)
113 return;
114
115 KexiDB::TableOrQuerySchema tableOrQuery(d->prj->dbConnection(), d->tableOrQueryName.latin1(), d->table);
116 if (!tableOrQuery.table() && !tableOrQuery.query())
117 return;
118
119// bool hasPKeys = true; //t->hasPrimaryKeys();
120 KexiDB::QueryColumnInfo::Vector columns = tableOrQuery.columns();
121 const int count = columns.count();
122 for(int i=0; i < count; i++)
123 {
124 KexiDB::QueryColumnInfo *colinfo = columns[i];
125 insertItem(
126 (colinfo && (colinfo->field->isPrimaryKey() || colinfo->field->isUniqueKey()))
127 ? d->keyIcon
128 : d->noIcon
129 , TQString(colinfo->aliasOrName()));
130 completionObject()->addItem(colinfo->aliasOrName());
131 //store user-friendly caption (used by fieldOrExpressionCaption())
132 d->captions.insert( colinfo->aliasOrName(), colinfo->captionOrAliasOrName() );
133 }
134
135 //update selection
136 setFieldOrExpression(d->fieldOrExpression);
137}
138
139TQString KexiFieldComboBox::tableOrQueryName() const
140{
141 return d->tableOrQueryName;
142}
143
144bool KexiFieldComboBox::isTableAssigned() const
145{
146 return d->table;
147}
148
149void KexiFieldComboBox::setFieldOrExpression(const TQString& string)
150{
151 const TQString name(string); //string.stripWhiteSpace().lower());
152 const int pos = name.find('.');
153 if (pos==-1) {
154 d->fieldOrExpression = name;
155 }
156 else {
157 TQString objectName = name.left(pos);
158 if (d->tableOrQueryName!=objectName) {
159 d->fieldOrExpression = name;
160 setCurrentItem(0);
161 setCurrentText(name);
163 kexiwarn << "KexiFieldComboBox::setField(): invalid table/query name in '" << name << "'" << endl;
164 return;
165 }
166 d->fieldOrExpression = name.mid(pos+1);
167 }
168
169 TQListBoxItem *item = listBox()->findItem(d->fieldOrExpression);
170 if (!item) {
171 setCurrentItem(0);
172 setCurrentText(d->fieldOrExpression);
173 //todo: show 'the item doesn't match' info?
174 return;
175 }
176 setCurrentItem( listBox()->index(item) );
177}
178
180{
181 index++; //skip 1st empty item
182 if (index>=count()) {
183 kexiwarn << TQString("KexiFieldComboBox::setFieldOrExpression(int index): index %1 "
184 "out of range (0..%2)").arg(index).arg(count()-1) << endl;
185 index = -1;
186 }
187 if (index<=0) {
188 setCurrentItem(0);
189 d->fieldOrExpression = TQString();
190 }
191 else {
192 setCurrentItem(index);
193 d->fieldOrExpression = currentText();
194 }
195}
196
197TQString KexiFieldComboBox::fieldOrExpression() const
198{
199 return d->fieldOrExpression;
200}
201
203{
204 KexiDB::TableOrQuerySchema tableOrQuery(d->prj->dbConnection(), d->tableOrQueryName.latin1(), d->table);
205 if (!tableOrQuery.table() && !tableOrQuery.query())
206 return -1;
207
208 return currentItem()>0 ? (currentItem()-1) : -1;
209}
210
211TQString KexiFieldComboBox::fieldOrExpressionCaption() const
212{
213 return d->captions[ d->fieldOrExpression ];
214}
215
216void KexiFieldComboBox::slotActivated(int i)
217{
218 d->fieldOrExpression = text(i);
219 emit selected();
220}
221
222void KexiFieldComboBox::slotReturnPressed(const TQString & text)
223{
224 //text is available: select item for this text:
225 int index;
226 if (text.isEmpty()) {
227 index = 0;
228 }
229 else {
230 TQListBoxItem *item = listBox()->findItem( text, TQt::ExactMatch );
231 if (!item)
232 return;
233 index = listBox()->index( item );
234 if (index < 1)
235 return;
236 }
237 setCurrentItem( index );
238 slotActivated( index );
239}
240
241void KexiFieldComboBox::focusOutEvent( TQFocusEvent *e )
242{
243 KComboBox::focusOutEvent( e );
244 // accept changes if the focus is moved
245 if (!KexiUtils::hasParent(this, focusWidget())) //(a check needed because drop-down listbox also causes a focusout)
246 slotReturnPressed(currentText());
247}
248
249#include "kexifieldcombobox.moc"
bool isPrimaryKey() const
Definition field.h:234
bool isUniqueKey() const
Definition field.h:237
Helper class that assigns additional information for the column in a query.
Definition queryschema.h:49
TQCString aliasOrName() const
Definition queryschema.h:59
TQString captionOrAliasOrName() const
Definition queryschema.h:65
QuerySchema * query() const
TableSchema * table() const
KexiProject * project() const
void setFieldOrExpression(const TQString &string)
void setProject(KexiProject *prj)
Sets global project that is used to retrieve schema informationm for this combo box.
A project's main controller.
Definition kexiproject.h:68
KEXIUTILS_EXPORT TQPixmap emptyIcon(TDEIcon::Group iconGroup)
bool hasParent(TQObject *par, TQObject *o)