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 <tdeversion.h>
36#include <tdeconfig.h>
37#include <tdeglobalsettings.h>
38#include <tdelocale.h>
39
40#include <kexidb/tableschema.h>
41#include <kexidb/queryschema.h>
42#include <kexidb/utils.h>
43#include <kexiutils/utils.h>
44#include <kexidragobjects.h>
45#include <kexiproject.h>
46
48class KexiFieldComboBox::Private
49{
50 public:
51 Private()
52// : schema(0)
53 : keyIcon( SmallIcon("key") )
54 , noIcon( KexiUtils::emptyIcon(TDEIcon::Small) )
55 , table(true)
56 {
57 }
58 ~Private()
59 {
60// delete schema;
61 }
62 TQGuardedPtr<KexiProject> prj;
63// KexiDB::TableOrQuerySchema* schema;
64 TQPixmap keyIcon, noIcon;
65 TQString tableOrQueryName;
66 TQString fieldOrExpression;
67 TQMap<TQString, TQString> captions;
68 bool table : 1;
69};
70
71//------------------------
72
73KexiFieldComboBox::KexiFieldComboBox(TQWidget *parent, const char *name)
74 : KComboBox(true/*rw*/, parent, name)
75 , d(new Private())
76{
77 setInsertionPolicy(NoInsertion);
78 setCompletionMode(TDEGlobalSettings::CompletionPopupAuto);
79 setSizeLimit( 16 );
80 connect(this, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotActivated(int)));
81 connect(this, TQ_SIGNAL(returnPressed(const TQString &)), this, TQ_SLOT(slotReturnPressed(const TQString &)));
82
83// setAcceptDrops(true);
84// viewport()->setAcceptDrops(true);
85}
86
87KexiFieldComboBox::~KexiFieldComboBox()
88{
89 delete d;
90}
91
92void KexiFieldComboBox::setProject(KexiProject *prj)
93{
94 if ((KexiProject*)d->prj==prj)
95 return;
96 d->prj = prj;
97 setTableOrQuery("", true);
98}
99
100KexiProject* KexiFieldComboBox::project() const
101{
102 return d->prj;
103}
104
105void KexiFieldComboBox::setTableOrQuery(const TQString& name, bool table)
106{
107 d->tableOrQueryName = name;
108 d->table = table;
109 clear();
110 d->captions.clear();
111 insertItem("");
112// delete d->schema;
113 if (d->tableOrQueryName.isEmpty() || !d->prj)
114 return;
115
116 KexiDB::TableOrQuerySchema tableOrQuery(d->prj->dbConnection(), d->tableOrQueryName.latin1(), d->table);
117 if (!tableOrQuery.table() && !tableOrQuery.query())
118 return;
119
120// bool hasPKeys = true; //t->hasPrimaryKeys();
121 KexiDB::QueryColumnInfo::Vector columns = tableOrQuery.columns();
122 const int count = columns.count();
123 for(int i=0; i < count; i++)
124 {
125 KexiDB::QueryColumnInfo *colinfo = columns[i];
126 insertItem(
127 (colinfo && (colinfo->field->isPrimaryKey() || colinfo->field->isUniqueKey()))
128 ? d->keyIcon
129 : d->noIcon
130 , TQString(colinfo->aliasOrName()));
131 completionObject()->addItem(colinfo->aliasOrName());
132 //store user-friendly caption (used by fieldOrExpressionCaption())
133 d->captions.insert( colinfo->aliasOrName(), colinfo->captionOrAliasOrName() );
134 }
135
136 //update selection
137 setFieldOrExpression(d->fieldOrExpression);
138}
139
140TQString KexiFieldComboBox::tableOrQueryName() const
141{
142 return d->tableOrQueryName;
143}
144
145bool KexiFieldComboBox::isTableAssigned() const
146{
147 return d->table;
148}
149
150void KexiFieldComboBox::setFieldOrExpression(const TQString& string)
151{
152 const TQString name(string); //string.stripWhiteSpace().lower());
153 const int pos = name.find('.');
154 if (pos==-1) {
155 d->fieldOrExpression = name;
156 }
157 else {
158 TQString objectName = name.left(pos);
159 if (d->tableOrQueryName!=objectName) {
160 d->fieldOrExpression = name;
161 setCurrentItem(0);
162 setCurrentText(name);
164 kexiwarn << "KexiFieldComboBox::setField(): invalid table/query name in '" << name << "'" << endl;
165 return;
166 }
167 d->fieldOrExpression = name.mid(pos+1);
168 }
169
170 TQListBoxItem *item = listBox()->findItem(d->fieldOrExpression);
171 if (!item) {
172 setCurrentItem(0);
173 setCurrentText(d->fieldOrExpression);
174 //todo: show 'the item doesn't match' info?
175 return;
176 }
177 setCurrentItem( listBox()->index(item) );
178}
179
180void KexiFieldComboBox::setFieldOrExpression(int index)
181{
182 index++; //skip 1st empty item
183 if (index>=count()) {
184 kexiwarn << TQString("KexiFieldComboBox::setFieldOrExpression(int index): index %1 "
185 "out of range (0..%2)").arg(index).arg(count()-1) << endl;
186 index = -1;
187 }
188 if (index<=0) {
189 setCurrentItem(0);
190 d->fieldOrExpression = TQString();
191 }
192 else {
193 setCurrentItem(index);
194 d->fieldOrExpression = currentText();
195 }
196}
197
198TQString KexiFieldComboBox::fieldOrExpression() const
199{
200 return d->fieldOrExpression;
201}
202
204{
205 KexiDB::TableOrQuerySchema tableOrQuery(d->prj->dbConnection(), d->tableOrQueryName.latin1(), d->table);
206 if (!tableOrQuery.table() && !tableOrQuery.query())
207 return -1;
208
209 return currentItem()>0 ? (currentItem()-1) : -1;
210}
211
212TQString KexiFieldComboBox::fieldOrExpressionCaption() const
213{
214 return d->captions[ d->fieldOrExpression ];
215}
216
217void KexiFieldComboBox::slotActivated(int i)
218{
219 d->fieldOrExpression = text(i);
220 emit selected();
221}
222
223void KexiFieldComboBox::slotReturnPressed(const TQString & text)
224{
225 //text is available: select item for this text:
226 int index;
227 if (text.isEmpty()) {
228 index = 0;
229 }
230 else {
231 TQListBoxItem *item = listBox()->findItem( text, TQt::ExactMatch );
232 if (!item)
233 return;
234 index = listBox()->index( item );
235 if (index < 1)
236 return;
237 }
238 setCurrentItem( index );
239 slotActivated( index );
240}
241
242void KexiFieldComboBox::focusOutEvent( TQFocusEvent *e )
243{
244 KComboBox::focusOutEvent( e );
245 // accept changes if the focus is moved
246 if (!KexiUtils::hasParent(this, focusWidget())) //(a check needed because drop-down listbox also causes a focusout)
247 slotReturnPressed(currentText());
248}
249
250#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
A project's main controller.
Definition kexiproject.h:68
General Utils.
Definition identifier.h:27
KEXIUTILS_EXPORT TQPixmap emptyIcon(TDEIcon::Group iconGroup)
bool hasParent(TQObject *par, TQObject *o)