kexilookupcolumnpage.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2006 Jaroslaw Staniek <js@iidea.pl>
3
4 This library 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 library 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 library; see the file COPYING.LIB. 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 "kexilookupcolumnpage.h"
21
22#include <tqlabel.h>
23#include <tqlayout.h>
24#include <tqtooltip.h>
25#include <tqheader.h>
26
27#include <kiconloader.h>
28#include <tdelocale.h>
29#include <tdetoolbarbutton.h>
30#include <kdebug.h>
31#include <tdepopupmenu.h>
32
33#include <widget/kexipropertyeditorview.h>
34#include <widget/kexidatasourcecombobox.h>
35#include <widget/kexifieldlistview.h>
36#include <widget/kexifieldcombobox.h>
37#include <widget/kexismalltoolbutton.h>
38#include <kexidb/connection.h>
39#include <kexiproject.h>
40
41#include <koproperty/property.h>
42#include <koproperty/utils.h>
43
44TQString mimeTypeToType(const TQString& mimeType)
45{
46 if (mimeType=="kexi/table")
47 return "table";
48 else if (mimeType=="kexi/query")
49 return "query";
51 return mimeType;
52}
53
54TQString typeToMimeType(const TQString& type)
55{
56 if (type=="table")
57 return "kexi/table";
58 else if (type=="query")
59 return "kexi/query";
61 return type;
62}
63
64//----------------------------------------------
65
67class KexiLookupColumnPage::Private
68{
69 public:
70 Private()
71 : currentFieldUid(-1)
72 , insideClearRowSourceSelection(false)
73 , propertySetEnabled(true)
74 {
75 }
76 ~Private()
77 {
78 }
79
80 bool hasPropertySet() const {
81 return propertySet;
82 }
83
84 void setPropertySet(KoProperty::Set* aPropertySet) {
85 propertySet = aPropertySet;
86 }
87
88 TQVariant propertyValue(const TQCString& propertyName) const {
89 return propertySet ? propertySet->property(propertyName).value() : TQVariant();
90 }
91
92 void changeProperty(const TQCString &property, const TQVariant &value)
93 {
94 if (!propertySetEnabled)
95 return;
96 propertySet->changeProperty(property, value);
97 }
98
99 void updateInfoLabelForPropertySet(const TQString& textToDisplayForNullSet) {
101 objectInfoLabel, propertySet, textToDisplayForNullSet);
102 }
103
104 KexiDataSourceComboBox *rowSourceCombo;
105 KexiFieldComboBox *boundColumnCombo, *visibleColumnCombo;
106 KexiObjectInfoLabel *objectInfoLabel;
107 TQLabel *rowSourceLabel, *boundColumnLabel, *visibleColumnLabel;
108 TQToolButton *clearRowSourceButton, *gotoRowSourceButton, *clearBoundColumnButton,
109 *clearVisibleColumnButton;
111 int currentFieldUid;
112
113 bool insideClearRowSourceSelection : 1;
115 bool propertySetEnabled : 1;
116
117 private:
120 TQGuardedPtr<KoProperty::Set> propertySet;
121};
122
123//----------------------------------------------
124
125KexiLookupColumnPage::KexiLookupColumnPage(TQWidget *parent)
126 : TQWidget(parent)
127 , d(new Private())
128{
129 setName("KexiLookupColumnPage");
130
131 TQVBoxLayout *vlyr = new TQVBoxLayout(this);
132 d->objectInfoLabel = new KexiObjectInfoLabel(this, "KexiObjectInfoLabel");
133 vlyr->addWidget(d->objectInfoLabel);
134
135//todo d->noDataSourceAvailableSingleText = i18n("No data source could be assigned for this widget.");
136//todo d->noDataSourceAvailableMultiText = i18n("No data source could be assigned for multiple widgets.");
137
138 //-Row Source
139 TQWidget *contents = new TQWidget(this);
140 vlyr->addWidget(contents);
141 TQVBoxLayout *contentsVlyr = new TQVBoxLayout(contents);
142
143 TQHBoxLayout *hlyr = new TQHBoxLayout(contentsVlyr);
144 d->rowSourceLabel = new TQLabel(i18n("Row source:"), contents);
145 d->rowSourceLabel->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Fixed);
146 d->rowSourceLabel->setMargin(2);
147 d->rowSourceLabel->setMinimumHeight(IconSize(TDEIcon::Small)+4);
148 d->rowSourceLabel->setAlignment(TQt::AlignLeft|TQt::AlignBottom);
149 hlyr->addWidget(d->rowSourceLabel);
150
151 d->gotoRowSourceButton = new KexiSmallToolButton(contents, TQString(), "goto", "gotoRowSourceButton");
152 d->gotoRowSourceButton->setMinimumHeight(d->rowSourceLabel->minimumHeight());
153 TQToolTip::add(d->gotoRowSourceButton, i18n("Go to selected row source"));
154 hlyr->addWidget(d->gotoRowSourceButton);
155 connect(d->gotoRowSourceButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotGotoSelectedRowSource()));
156
157 d->clearRowSourceButton = new KexiSmallToolButton(contents, TQString(),
158 "clear_left", "clearRowSourceButton");
159 d->clearRowSourceButton->setMinimumHeight(d->rowSourceLabel->minimumHeight());
160 TQToolTip::add(d->clearRowSourceButton, i18n("Clear row source"));
161 hlyr->addWidget(d->clearRowSourceButton);
162 connect(d->clearRowSourceButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(clearRowSourceSelection()));
163
164 d->rowSourceCombo = new KexiDataSourceComboBox(contents, "rowSourceCombo");
165 d->rowSourceLabel->setBuddy(d->rowSourceCombo);
166 contentsVlyr->addWidget(d->rowSourceCombo);
167
168 contentsVlyr->addSpacing(8);
169
170 //- Bound Column
171 hlyr = new TQHBoxLayout(contentsVlyr);
172 d->boundColumnLabel = new TQLabel(i18n("Bound column:"), contents);
173 d->boundColumnLabel->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Fixed);
174 d->boundColumnLabel->setMargin(2);
175 d->boundColumnLabel->setMinimumHeight(IconSize(TDEIcon::Small)+4);
176 d->boundColumnLabel->setAlignment(TQt::AlignLeft|TQt::AlignBottom);
177 hlyr->addWidget(d->boundColumnLabel);
178
179 d->clearBoundColumnButton = new KexiSmallToolButton(contents, TQString(),
180 "clear_left", "clearBoundColumnButton");
181 d->clearBoundColumnButton->setMinimumHeight(d->boundColumnLabel->minimumHeight());
182 TQToolTip::add(d->clearBoundColumnButton, i18n("Clear bound column"));
183 hlyr->addWidget(d->clearBoundColumnButton);
184 connect(d->clearBoundColumnButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(clearBoundColumnSelection()));
185
186 d->boundColumnCombo = new KexiFieldComboBox(contents, "boundColumnCombo");
187 d->boundColumnLabel->setBuddy(d->boundColumnCombo);
188 contentsVlyr->addWidget(d->boundColumnCombo);
189
190 contentsVlyr->addSpacing(8);
191
192 //- Visible Column
193 hlyr = new TQHBoxLayout(contentsVlyr);
194 d->visibleColumnLabel = new TQLabel(i18n("Visible column:"), contents);
195 d->visibleColumnLabel->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Fixed);
196 d->visibleColumnLabel->setMargin(2);
197 d->visibleColumnLabel->setMinimumHeight(IconSize(TDEIcon::Small)+4);
198 d->visibleColumnLabel->setAlignment(TQt::AlignLeft|TQt::AlignBottom);
199 hlyr->addWidget(d->visibleColumnLabel);
200
201 d->clearVisibleColumnButton = new KexiSmallToolButton(contents, TQString(),
202 "clear_left", "clearVisibleColumnButton");
203 d->clearVisibleColumnButton->setMinimumHeight(d->visibleColumnLabel->minimumHeight());
204 TQToolTip::add(d->clearVisibleColumnButton, i18n("Clear visible column"));
205 hlyr->addWidget(d->clearVisibleColumnButton);
206 connect(d->clearVisibleColumnButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(clearVisibleColumnSelection()));
207
208 d->visibleColumnCombo = new KexiFieldComboBox(contents, "visibleColumnCombo");
209 d->visibleColumnLabel->setBuddy(d->visibleColumnCombo);
210 contentsVlyr->addWidget(d->visibleColumnCombo);
211
212 vlyr->addStretch(1);
213
214 connect(d->rowSourceCombo, TQ_SIGNAL(textChanged(const TQString &)),
215 this, TQ_SLOT(slotRowSourceTextChanged(const TQString &)));
216 connect(d->rowSourceCombo, TQ_SIGNAL(dataSourceChanged()), this, TQ_SLOT(slotRowSourceChanged()));
217 connect(d->boundColumnCombo, TQ_SIGNAL(selected()), this, TQ_SLOT(slotBoundColumnSelected()));
218 connect(d->visibleColumnCombo, TQ_SIGNAL(selected()), this, TQ_SLOT(slotVisibleColumnSelected()));
219
220 clearBoundColumnSelection();
221 clearVisibleColumnSelection();
222}
223
224KexiLookupColumnPage::~KexiLookupColumnPage()
225{
226 delete d;
227}
228
229void KexiLookupColumnPage::setProject(KexiProject *prj)
230{
231 d->rowSourceCombo->setProject(prj,
232 true/*showTables*/, true/*showQueries*/
233 );
234 d->boundColumnCombo->setProject(prj);
235 d->visibleColumnCombo->setProject(prj);
236}
237
238void KexiLookupColumnPage::assignPropertySet(KoProperty::Set* propertySet)
239{
240 if (!d->hasPropertySet() && !propertySet)
241 return;
242 if (propertySet && d->currentFieldUid == (*propertySet)["uid"].value().toInt())
243 return; //already assigned
244
245 d->propertySetEnabled = false;
246 d->setPropertySet( propertySet );
247 d->updateInfoLabelForPropertySet( i18n("No field selected") );
248
249 const bool hasRowSource = d->hasPropertySet() && !d->propertyValue("rowSourceType").isNull()
250 && !d->propertyValue("rowSource").isNull();
251
252 TQString rowSource, rowSourceType;
253 if (hasRowSource) {
254 rowSourceType = typeToMimeType( d->propertyValue("rowSourceType").toString() );
255 rowSource = d->propertyValue("rowSource").toString();
256 }
257 d->rowSourceCombo->setDataSource( rowSourceType, rowSource );
258 d->rowSourceLabel->setEnabled( d->hasPropertySet() );
259 d->rowSourceCombo->setEnabled( d->hasPropertySet() );
260 if (!d->hasPropertySet())
261 d->clearRowSourceButton->setEnabled( false );
262
263 int boundColumn = -1, visibleColumn = -1;
264 if (d->rowSourceCombo->isSelectionValid()) {
265 boundColumn = d->propertyValue("boundColumn").toInt();
266 visibleColumn = d->propertyValue("visibleColumn").toInt();
267 }
268 d->boundColumnCombo->setFieldOrExpression(boundColumn);
269 d->visibleColumnCombo->setFieldOrExpression(visibleColumn);
270 updateBoundColumnWidgetsAvailability();
271 d->propertySetEnabled = true;
272}
273
274void KexiLookupColumnPage::clearBoundColumnSelection()
275{
276 d->boundColumnCombo->setCurrentText("");
277 d->boundColumnCombo->setFieldOrExpression(TQString());
278 slotBoundColumnSelected();
279 d->clearBoundColumnButton->setEnabled(false);
280}
281
282void KexiLookupColumnPage::slotBoundColumnSelected()
283{
284// KexiDB::Field::Type dataType = KexiDB::Field::InvalidType;
286/*disabled KexiDB::Field *field = d->fieldListView->schema()->field( d->boundColumnCombo->fieldOrExpression() );
287 if (field)
288 dataType = field->type();
289*/
290 d->clearBoundColumnButton->setEnabled( !d->boundColumnCombo->fieldOrExpression().isEmpty() );
291 if (!d->boundColumnCombo->fieldOrExpression().isEmpty()) {
292 kdDebug() << endl;
293 }
294
295 // update property set
296 if (d->hasPropertySet()) {
297 d->changeProperty("boundColumn", d->boundColumnCombo->indexOfField());
298 }
299/*
300 emit boundColumnChanged(
301 d->boundColumnCombo->fieldOrExpression(),
302 d->boundColumnCombo->fieldOrExpressionCaption(),
303 dataType
304 );*/
305}
306
307void KexiLookupColumnPage::clearVisibleColumnSelection()
308{
309 d->visibleColumnCombo->setCurrentText("");
310 d->visibleColumnCombo->setFieldOrExpression(TQString());
311 slotVisibleColumnSelected();
312 d->clearVisibleColumnButton->setEnabled(false);
313}
314
315void KexiLookupColumnPage::slotVisibleColumnSelected()
316{
317// KexiDB::Field::Type dataType = KexiDB::Field::InvalidType;
319 d->clearVisibleColumnButton->setEnabled( !d->visibleColumnCombo->fieldOrExpression().isEmpty() );
320
321 // update property set
322 if (d->hasPropertySet()) {
324 d->changeProperty("visibleColumn", d->visibleColumnCombo->indexOfField());
325 }
326}
327
328void KexiLookupColumnPage::slotRowSourceChanged()
329{
330 if (!d->rowSourceCombo->project())
331 return;
332 TQString mime = d->rowSourceCombo->selectedMimeType();
333 bool rowSourceFound = false;
334 TQString name = d->rowSourceCombo->selectedName();
335 if ((mime=="kexi/table" || mime=="kexi/query") && d->rowSourceCombo->isSelectionValid()) {
337 d->rowSourceCombo->project()->dbConnection(), name.latin1(), mime=="kexi/table");
338 if (tableOrQuery->table() || tableOrQuery->query()) {
339//disabled d->fieldListView->setSchema( tableOrQuery );
340/*tmp*/ delete tableOrQuery;
341 rowSourceFound = true;
342 d->boundColumnCombo->setTableOrQuery(name, mime=="kexi/table");
343 d->visibleColumnCombo->setTableOrQuery(name, mime=="kexi/table");
344 }
345 else {
346 delete tableOrQuery;
347 }
348 }
349 if (!rowSourceFound) {
350 d->boundColumnCombo->setTableOrQuery("", true);
351 d->visibleColumnCombo->setTableOrQuery("", true);
352 }
353 clearBoundColumnSelection();
354 clearVisibleColumnSelection();
355 d->clearRowSourceButton->setEnabled(rowSourceFound);
356 d->gotoRowSourceButton->setEnabled(rowSourceFound);
357/* disabled
358 if (dataSourceFound) {
359 slotFieldListViewSelectionChanged();
360 } else {
361 d->addField->setEnabled(false);
362 }*/
363 updateBoundColumnWidgetsAvailability();
364
365 //update property set
366 if (d->hasPropertySet()) {
367 d->changeProperty("rowSourceType", mimeTypeToType(mime));
368 d->changeProperty("rowSource", name);
369 }
370
371//disabled emit formDataSourceChanged(mime, name);
373}
374
375void KexiLookupColumnPage::slotRowSourceTextChanged(const TQString & string)
376{
377 Q_UNUSED(string);
378 const bool enable = d->rowSourceCombo->isSelectionValid();
379 if (enable) {
380 updateBoundColumnWidgetsAvailability();
381 }
382 else {
383 clearRowSourceSelection( d->rowSourceCombo->selectedName().isEmpty()/*alsoClearComboBox*/ );
384 }
385}
386
387void KexiLookupColumnPage::clearRowSourceSelection(bool alsoClearComboBox)
388{
389 if (d->insideClearRowSourceSelection)
390 return;
391 d->insideClearRowSourceSelection = true;
392 if (alsoClearComboBox && !d->rowSourceCombo->selectedName().isEmpty())
393 d->rowSourceCombo->setDataSource("", "");
394 d->clearRowSourceButton->setEnabled(false);
395 d->gotoRowSourceButton->setEnabled(false);
396 d->insideClearRowSourceSelection = false;
397}
398
399void KexiLookupColumnPage::slotGotoSelectedRowSource()
400{
401 TQString mime = d->rowSourceCombo->selectedMimeType();
402 if (mime=="kexi/table" || mime=="kexi/query") {
403 if (d->rowSourceCombo->isSelectionValid())
404 emit jumpToObjectRequested(mime.latin1(), d->rowSourceCombo->selectedName().latin1());
405 }
406}
407
408void KexiLookupColumnPage::updateBoundColumnWidgetsAvailability()
409{
410 const bool hasRowSource = d->rowSourceCombo->isSelectionValid();
411 d->boundColumnCombo->setEnabled( hasRowSource );
412 d->boundColumnLabel->setEnabled( hasRowSource );
413 d->clearBoundColumnButton->setEnabled( hasRowSource && !d->boundColumnCombo->fieldOrExpression().isEmpty() );
414 d->visibleColumnCombo->setEnabled( hasRowSource );
415 d->visibleColumnLabel->setEnabled( hasRowSource );
416 d->clearVisibleColumnButton->setEnabled( hasRowSource && !d->visibleColumnCombo->fieldOrExpression().isEmpty() );
417}
418
419#include "kexilookupcolumnpage.moc"
QuerySchema * query() const
TableSchema * table() const
A combo box listing availabe data sources (tables and queries) with icons.
void jumpToObjectRequested(const TQCString &mime, const TQCString &name)
Signal emitted when helper button 'Go to selected row sourcesource' is clicked.
void assignPropertySet(KoProperty::Set *propertySet)
Receives a pointer to a new property set (from KexiFormView::managerPropertyChanged())
Helper class displaying small icon with class name and object name.
A project's main controller.
Definition kexiproject.h:68
static void updateInfoLabelForPropertySet(KexiObjectInfoLabel *infoLabel, KoProperty::Set *set, const TQString &textToDisplayForNullSet=TQString())
A small tool button with icon and optional text.