1 /* This file is part of the KDE project
2    Copyright (C) 2005 Cedric Pasteur <cedric.pasteur@free.fr>
3    Copyright (C) 2005 Christian Nitschkowski <segfault_ii@web.de>
4    Copyright (C) 2005-2007 Jarosław Staniek <staniek@kde.org>
5 
6    This program is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public
8    License as published by the Free Software Foundation; either
9    version 2 of the License, or (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Library General Public License for more details.
15 
16    You should have received a copy of the GNU Library General Public License
17    along with this program; see the file COPYING.  If not, write to
18    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20 */
21 
22 #include "kexidbautofield.h"
23 #include "kexidbcheckbox.h"
24 #include "kexidbimagebox.h"
25 #include "kexidblabel.h"
26 #include "kexidblineedit.h"
27 #include "kexidbtextedit.h"
28 #include "kexidbcombobox.h"
29 #include "KexiDBPushButton.h"
30 #include "kexidbform.h"
31 #include <kexi_global.h>
32 #include <formeditor/utils.h>
33 #include <kexiutils/utils.h>
34 
35 #include <KDbQuerySchema>
36 
37 #include <KLocalizedString>
38 
39 #include <QLabel>
40 #include <QApplication>
41 #include <QBoxLayout>
42 #include <QDebug>
43 
44 #define KexiDBAutoField_SPACING 10 //10 pixel for spacing between a label and an editor widget
45 
46 //! @internal
47 class Q_DECL_HIDDEN KexiDBAutoField::Private
48 {
49 public:
Private()50     Private() {
51     }
52 
53     WidgetType widgetType; //!< internal: equal to m_widgetType_property or equal to result
54                            //!< of widgetTypeForFieldType() if widgetTypeForFieldType is Auto
55     WidgetType  widgetType_property; //!< provides widget type or Auto
56     LabelPosition  lblPosition;
57     QBoxLayout  *layout;
58     QLabel  *label;
59     QString  caption;
60     KDbField::Type fieldTypeInternal;
61     QString fieldCaptionInternal;
62     QBrush baseBrush; //!< needed because for unbound mode editor==0
63     QBrush textBrush; //!< needed because for unbound mode editor==0
64     bool autoCaption;
65     bool focusPolicyChanged;
66     KDbConnection *conn = nullptr;
67 };
68 
69 //-------------------------------------
70 
KexiDBAutoField(const QString & text,WidgetType type,LabelPosition pos,QWidget * parent)71 KexiDBAutoField::KexiDBAutoField(const QString &text, WidgetType type, LabelPosition pos,
72                                  QWidget *parent)
73         : QWidget(parent)
74         , KexiFormDataItemInterface()
75         , KFormDesigner::DesignTimeDynamicChildWidgetHandler()
76         , d(new Private())
77 {
78     init(text, type, pos);
79 }
80 
KexiDBAutoField(QWidget * parent,LabelPosition pos)81 KexiDBAutoField::KexiDBAutoField(QWidget *parent, LabelPosition pos)
82         : QWidget(parent)
83         , KexiFormDataItemInterface()
84         , KFormDesigner::DesignTimeDynamicChildWidgetHandler()
85         , d(new Private())
86 {
87     init(QString()/*xi18n("Auto Field")*/, Auto, pos);
88 }
89 
~KexiDBAutoField()90 KexiDBAutoField::~KexiDBAutoField()
91 {
92     setUpdatesEnabled(false);
93     if (subwidget())
94         subwidget()->setUpdatesEnabled(false);
95     delete d;
96 }
97 
98 void
init(const QString & text,WidgetType type,LabelPosition pos)99 KexiDBAutoField::init(const QString &text, WidgetType type, LabelPosition pos)
100 {
101     d->fieldTypeInternal = KDbField::InvalidType;
102     d->layout = 0;
103     setSubwidget(0);
104     d->label = new QLabel(text, this);
105     d->label->installEventFilter(this);
106     d->autoCaption = true;
107     d->focusPolicyChanged = false;
108     d->widgetType = Auto;
109     d->widgetType_property = (type == Auto ? Text : type); //to force "differ" to be true in setWidgetType()
110     setLabelPosition(pos);
111     setWidgetType(type);
112     d->baseBrush = palette().base();
113     d->textBrush = palette().text();
114 }
115 
116 void
setWidgetType(WidgetType type)117 KexiDBAutoField::setWidgetType(WidgetType type)
118 {
119     const bool differ = (type != d->widgetType_property);
120     d->widgetType_property = type;
121     if (differ) {
122         if (type == Auto) {// try to guess type from data source type
123             if (visibleColumnInfo())
124                 d->widgetType = KexiDBAutoField::widgetTypeForFieldType(visibleColumnInfo()->field()->type());
125             else
126                 d->widgetType = Auto;
127         } else
128             d->widgetType = d->widgetType_property;
129         createEditor();
130     }
131 }
132 
133 void
createEditor()134 KexiDBAutoField::createEditor()
135 {
136     if (subwidget()) {
137         delete(QWidget *)subwidget();
138     }
139 
140     QWidget *newSubwidget;
141     //qDebug() << "widgetType:" << d->widgetType;
142     switch (d->widgetType) {
143     case Text:
144     case Double: //! @todo setup validator
145     case Integer: //! @todo setup validator
146     case Date:
147     case Time:
148     case DateTime: {
149         KexiDBLineEdit *le = new KexiDBLineEdit(this);
150         newSubwidget = le;
151         le->setFrame(false);
152         break;
153     }
154     case MultiLineText:
155         newSubwidget = new KexiDBTextEdit(this);
156         break;
157     case Boolean:
158         newSubwidget = new KexiDBCheckBox(dataSource(), this);
159         break;
160     case Image:
161         newSubwidget = new KexiDBImageBox(designMode(), this);
162         break;
163     case ComboBox: {
164         KexiDBComboBox *cbox = new KexiDBComboBox(this);
165         newSubwidget = cbox;
166         cbox->setDesignMode(designMode());
167         break;
168     }
169     default:
170         newSubwidget = 0;
171         changeText(d->caption);
172         break;
173     }
174 
175     //qDebug() << newSubwidget;
176     setSubwidget(newSubwidget);   //this will also allow to declare subproperties, see KFormDesigner::WidgetWithSubpropertiesInterface
177     if (newSubwidget) {
178         newSubwidget->setObjectName(
179             QString::fromLatin1("KexiDBAutoField_") + newSubwidget->metaObject()->className());
180         KexiDataItemInterface *iface = dynamic_cast<KexiDataItemInterface*>(newSubwidget);
181         if (iface) {
182             iface->setParentDataItemInterface(this);
183         }
184         KexiFormDataItemInterface *formIface = dynamic_cast<KexiFormDataItemInterface*>(newSubwidget);
185         if (formIface) {
186             formIface->setColumnInfo(d->conn, columnInfo()); //needed at least by KexiDBImageBox
187             formIface->setVisibleColumnInfo(visibleColumnInfo()); //needed at least by KexiDBComboBox
188         }
189         newSubwidget->setProperty("dataSource", dataSource()); //needed at least by KexiDBImageBox
190         KFormDesigner::DesignTimeDynamicChildWidgetHandler::childWidgetAdded(this);
191         newSubwidget->show();
192         d->label->setBuddy(newSubwidget);
193         if (d->focusPolicyChanged) {//if focusPolicy is changed at top level, editor inherits it
194             newSubwidget->setFocusPolicy(focusPolicy());
195         } else {//if focusPolicy is not changed at top level, inherit it from editor
196             QWidget::setFocusPolicy(newSubwidget->focusPolicy());
197         }
198         setFocusProxy(newSubwidget); //ok?
199         if (parentWidget())
200             newSubwidget->setPalette(qApp->palette());
201         copyPropertiesToEditor();
202     }
203 
204     setLabelPosition(labelPosition());
205 }
206 
copyPropertiesToEditor()207 void KexiDBAutoField::copyPropertiesToEditor()
208 {
209     //qDebug() << subwidget();
210     if (subwidget()) {
211 //  qDebug() << "base col: " <<  d->baseColor.name() <<
212 //   "; text col: " << d->textColor.name();
213         QPalette p(subwidget()->palette());
214         p.setBrush(QPalette::Base, d->baseBrush);
215         if (d->widgetType == Boolean)
216             p.setBrush(QPalette::Foreground, d->textBrush);
217         else
218             p.setBrush(QPalette::Text, d->textBrush);
219         subwidget()->setPalette(p);
220     }
221 }
222 
223 void
setLabelPosition(LabelPosition position)224 KexiDBAutoField::setLabelPosition(LabelPosition position)
225 {
226     d->lblPosition = position;
227     if (d->layout) {
228         QBoxLayout *lyr = d->layout;
229         d->layout = 0;
230         delete lyr;
231     }
232 
233     if (subwidget())
234         subwidget()->show();
235     //! \todo support right-to-left layout where positions are inverted
236     if (position == Top || position == Left) {
237         Qt::Alignment align = d->label->alignment();
238         if (position == Top) {
239             d->layout = (QBoxLayout*) new QVBoxLayout(this);
240             align |= Qt::AlignVertical_Mask;
241             align ^= Qt::AlignVertical_Mask;
242             align |= Qt::AlignTop;
243         } else {
244             d->layout = (QBoxLayout*) new QHBoxLayout(this);
245             align |= Qt::AlignVertical_Mask;
246             align ^= Qt::AlignVertical_Mask;
247             align |= Qt::AlignVCenter;
248         }
249         d->label->setAlignment(align);
250         if (d->widgetType == Boolean
251                 || (d->widgetType == Auto && fieldTypeInternal() == KDbField::InvalidType && !designMode())) {
252             d->label->hide();
253         } else {
254             d->label->show();
255         }
256         d->layout->addWidget(d->label, 0, position == Top ? Qt::AlignLeft : QFlags<Qt::AlignmentFlag>(0));
257         if (position == Left && d->widgetType != Boolean)
258             d->layout->addSpacing(KexiDBAutoField_SPACING);
259         d->layout->addWidget(subwidget(), 1);
260         KexiSubwidgetInterface *subwidgetInterface = dynamic_cast<KexiSubwidgetInterface*>(subwidget());
261         if (subwidgetInterface) {
262             if (subwidgetInterface->appendStretchRequired(this))
263                 d->layout->addStretch(0);
264             if (subwidgetInterface->subwidgetStretchRequired(this)) {
265                 QSizePolicy sizePolicy(subwidget()->sizePolicy());
266                 if (position == Left) {
267                     sizePolicy.setHorizontalPolicy(QSizePolicy::Minimum);
268                     d->label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
269                 } else {
270                     sizePolicy.setVerticalPolicy(QSizePolicy::Minimum);
271                     d->label->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
272                 }
273                 subwidget()->setSizePolicy(sizePolicy);
274             }
275         }
276     } else {
277         d->layout = (QBoxLayout*) new QHBoxLayout(this);
278         d->label->hide();
279         d->layout->addWidget(subwidget());
280     }
281     //a hack to force layout to be refreshed (any better idea for this?)
282     resize(size() + QSize(1, 0));
283     resize(size() - QSize(1, 0));
284     KexiDBAutoField* autoField = dynamic_cast<KexiDBAutoField*>(subwidget());
285     if (autoField) {
286         //needed for KexiDBComboBox
287         autoField->setLabelPosition(position);
288     }
289 }
290 
291 void
setInvalidState(const QString & text)292 KexiDBAutoField::setInvalidState(const QString &text)
293 {
294     // Widget with an invalid dataSource is just a QLabel
295     if (designMode())
296         return;
297     d->widgetType = Auto;
298     createEditor();
299     setFocusPolicy(Qt::NoFocus);
300     if (subwidget())
301         subwidget()->setFocusPolicy(Qt::NoFocus);
302 //! @todo or set this to editor's text?
303     d->label->setText(text);
304 }
305 
306 bool
isReadOnly() const307 KexiDBAutoField::isReadOnly() const
308 {
309     KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>((QWidget*)subwidget());
310     if (iface)
311         return iface->isReadOnly();
312     else
313         return false;
314 }
315 
316 void
setReadOnly(bool readOnly)317 KexiDBAutoField::setReadOnly(bool readOnly)
318 {
319     KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>((QWidget*)subwidget());
320     if (iface)
321         iface->setReadOnly(readOnly);
322 }
323 
324 void
setValueInternal(const QVariant & add,bool removeOld)325 KexiDBAutoField::setValueInternal(const QVariant& add, bool removeOld)
326 {
327     KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>((QWidget*)subwidget());
328     if (iface)
329         iface->setValue(KexiDataItemInterface::originalValue(), add, removeOld);
330 }
331 
332 QVariant
value()333 KexiDBAutoField::value()
334 {
335     KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>((QWidget*)subwidget());
336     if (iface)
337         return iface->value();
338     return QVariant();
339 }
340 
341 bool
valueIsNull()342 KexiDBAutoField::valueIsNull()
343 {
344     KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>((QWidget*)subwidget());
345     if (iface)
346         return iface->valueIsNull();
347     return true;
348 }
349 
350 bool
valueIsEmpty()351 KexiDBAutoField::valueIsEmpty()
352 {
353     KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>((QWidget*)subwidget());
354     if (iface)
355         return iface->valueIsEmpty();
356     return true;
357 }
358 
359 bool
valueIsValid()360 KexiDBAutoField::valueIsValid()
361 {
362     KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>((QWidget*)subwidget());
363     if (iface)
364         return iface->valueIsValid();
365     return true;
366 }
367 
368 bool
valueChanged()369 KexiDBAutoField::valueChanged()
370 {
371     KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>((QWidget*)subwidget());
372     //qDebug() << KexiDataItemInterface::originalValue();
373     if (iface)
374         return iface->valueChanged();
375     return false;
376 }
377 
378 void
installListener(KexiDataItemChangesListener * listener)379 KexiDBAutoField::installListener(KexiDataItemChangesListener* listener)
380 {
381     KexiFormDataItemInterface::installListener(listener);
382     KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>((QWidget*)subwidget());
383     if (iface)
384         iface->installListener(listener);
385 }
386 
widgetType() const387 KexiDBAutoField::WidgetType KexiDBAutoField::widgetType() const
388 {
389     return d->widgetType_property;
390 }
391 
labelPosition() const392 KexiDBAutoField::LabelPosition KexiDBAutoField::labelPosition() const
393 {
394     return d->lblPosition;
395 }
396 
caption() const397 QString KexiDBAutoField::caption() const
398 {
399     return d->caption;
400 }
401 
hasAutoCaption() const402 bool KexiDBAutoField::hasAutoCaption() const
403 {
404     return d->autoCaption;
405 }
406 
editor() const407 QWidget* KexiDBAutoField::editor() const
408 {
409     return subwidget();
410 }
411 
label() const412 QLabel* KexiDBAutoField::label() const
413 {
414     return d->label;
415 }
416 
fieldTypeInternal() const417 int KexiDBAutoField::fieldTypeInternal() const
418 {
419     return d->fieldTypeInternal;
420 }
421 
fieldCaptionInternal() const422 QString KexiDBAutoField::fieldCaptionInternal() const
423 {
424     return d->fieldCaptionInternal;
425 }
426 
427 bool
cursorAtStart()428 KexiDBAutoField::cursorAtStart()
429 {
430     KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>((QWidget*)subwidget());
431     if (iface)
432         return iface->cursorAtStart();
433     return false;
434 }
435 
436 bool
cursorAtEnd()437 KexiDBAutoField::cursorAtEnd()
438 {
439     KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>((QWidget*)subwidget());
440     if (iface)
441         return iface->cursorAtEnd();
442     return false;
443 }
444 
445 void
clear()446 KexiDBAutoField::clear()
447 {
448     KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>((QWidget*)subwidget());
449     if (iface)
450         iface->clear();
451 }
452 
453 void
setFieldTypeInternal(int kexiDBFieldType)454 KexiDBAutoField::setFieldTypeInternal(int kexiDBFieldType)
455 {
456     d->fieldTypeInternal = (KDbField::Type)kexiDBFieldType;
457     KDbField::Type fieldType;
458     //find real fied type to use
459     if (d->fieldTypeInternal == KDbField::InvalidType) {
460         if (visibleColumnInfo())
461             fieldType = KDbField::Text;
462         else
463             fieldType = KDbField::InvalidType;
464     } else
465         fieldType = d->fieldTypeInternal;
466 
467     const WidgetType newWidgetType = KexiDBAutoField::widgetTypeForFieldType(fieldType);
468 
469     if (d->widgetType != newWidgetType) {
470         d->widgetType = newWidgetType;
471         createEditor();
472     }
473     setFieldCaptionInternal(d->fieldCaptionInternal);
474 }
475 
476 void
setFieldCaptionInternal(const QString & text)477 KexiDBAutoField::setFieldCaptionInternal(const QString& text)
478 {
479     d->fieldCaptionInternal = text;
480     //change text only if autocaption is set and no columnInfo is available
481     KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>((QWidget*)subwidget());
482     if ((!iface || !iface->columnInfo()) && d->autoCaption) {
483         changeText(d->fieldCaptionInternal);
484     }
485 }
486 
487 void
setColumnInfo(KDbConnection * conn,KDbQueryColumnInfo * cinfo)488 KexiDBAutoField::setColumnInfo(KDbConnection *conn, KDbQueryColumnInfo* cinfo)
489 {
490     KexiFormDataItemInterface::setColumnInfo(conn, cinfo);
491     d->conn = conn;
492     setColumnInfoInternal(cinfo, cinfo);
493 }
494 
setColumnInfoInternal(KDbQueryColumnInfo * cinfo,KDbQueryColumnInfo * visibleColumnInfo)495 void KexiDBAutoField::setColumnInfoInternal(KDbQueryColumnInfo *cinfo,
496                                             KDbQueryColumnInfo *visibleColumnInfo)
497 {
498     // change widget type depending on field type
499     if (d->widgetType_property == Auto) {
500         WidgetType newWidgetType = Auto;
501         KDbField::Type fieldType;
502         if (cinfo)
503             fieldType = visibleColumnInfo->field()->type();
504         else if (dataSource().isEmpty())
505             fieldType = KDbField::InvalidType;
506         else
507             fieldType = KDbField::Text;
508 
509         if (fieldType != KDbField::InvalidType) {
510             newWidgetType = KexiDBAutoField::widgetTypeForFieldType(fieldType);
511         }
512         if (d->widgetType != newWidgetType || newWidgetType == Auto) {
513             d->widgetType = newWidgetType;
514             createEditor();
515         }
516     }
517     // update label's text
518     changeText((cinfo && d->autoCaption) ? cinfo->captionOrAliasOrName() : d->caption);
519 
520     KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>((QWidget*)subwidget());
521     if (iface)
522         iface->setColumnInfo(d->conn, visibleColumnInfo);
523 }
524 
525 //static
526 KexiDBAutoField::WidgetType
widgetTypeForFieldType(KDbField::Type type)527 KexiDBAutoField::widgetTypeForFieldType(KDbField::Type type)
528 {
529     switch (type) {
530     case KDbField::Integer:
531     case KDbField::ShortInteger:
532     case KDbField::BigInteger:
533         return Integer;
534     case  KDbField::Boolean:
535         return Boolean;
536     case KDbField::Float:
537     case KDbField::Double:
538         return Double;
539     case KDbField::Date:
540         return Date;
541     case KDbField::DateTime:
542         return DateTime;
543     case KDbField::Time:
544         return Time;
545     case KDbField::Text:
546         return Text;
547     case KDbField::LongText:
548         return MultiLineText;
549     case KDbField::Enum:
550         return ComboBox;
551     case KDbField::InvalidType:
552         return Auto;
553     case KDbField::BLOB:
554         return Image;
555     default:
556         break;
557     }
558     return Text;
559 }
560 
561 void
changeText(const QString & text,bool beautify)562 KexiDBAutoField::changeText(const QString &text, bool beautify)
563 {
564     QString realText;
565     bool unbound = false;
566     if (d->autoCaption && (d->widgetType == Auto || dataSource().isEmpty())) {
567         if (designMode())
568             realText = futureI18nc2("Unbound Auto Field", "%1 (unbound)", objectName());
569         else
570             realText.clear();
571         unbound = true;
572     } else {
573         if (beautify) {
574             /*! @todo look at appendColonToAutoLabels setting [bool]
575               @todo look at makeFirstCharacterUpperCaseInCaptions setting [bool]
576               (see doc/dev/settings.txt) */
577             if (!text.isEmpty()) {
578                 realText = text[0].toUpper() + text.mid(1);
579                 if (d->widgetType != Boolean) {
580 //! @todo ":" suffix looks weird for checkbox; remove this condition when [x] is displayed _after_ label
581 //! @todo support right-to-left layout where position of ":" is inverted
582                     realText += ": ";
583                 }
584             }
585         } else
586             realText = text;
587     }
588 
589     if (unbound) {
590         d->label->setAlignment(Qt::AlignCenter);
591         d->label->setWordWrap(true);
592     } else {
593         d->label->setAlignment(Qt::AlignCenter);
594     }
595     if (d->widgetType == Boolean) {
596         static_cast<QCheckBox*>((QWidget*)subwidget())->setText(realText);
597     } else {
598         d->label->setText(realText);
599     }
600 }
601 
602 void
setCaption(const QString & caption)603 KexiDBAutoField::setCaption(const QString &caption)
604 {
605     d->caption = caption;
606     if (!d->autoCaption && !caption.isEmpty())
607         changeText(d->caption);
608 }
609 
610 void
setAutoCaption(bool autoCaption)611 KexiDBAutoField::setAutoCaption(bool autoCaption)
612 {
613     d->autoCaption = autoCaption;
614     if (d->autoCaption) {
615         if (columnInfo()) {
616             changeText(columnInfo()->captionOrAliasOrName());
617         } else {
618             changeText(d->fieldCaptionInternal);
619         }
620     } else
621         changeText(d->caption);
622 }
623 
624 void
setDataSource(const QString & ds)625 KexiDBAutoField::setDataSource(const QString &ds)
626 {
627     KexiFormDataItemInterface::setDataSource(ds);
628     if (ds.isEmpty()) {
629         setColumnInfo(d->conn, nullptr);
630     }
631 }
632 
633 QSize
sizeHint() const634 KexiDBAutoField::sizeHint() const
635 {
636     if (d->lblPosition == NoLabel)
637         return subwidget() ? subwidget()->sizeHint() : QWidget::sizeHint();
638 
639     QSize s1(0, 0);
640     if (subwidget())
641         s1 = subwidget()->sizeHint();
642     QSize s2(d->label->sizeHint());
643     if (d->lblPosition == Top)
644         return QSize(qMax(s1.width(), s2.width()), s1.height() + KexiDBAutoField_SPACING + s2.height());
645 
646     //left
647     return QSize(s1.width() + KexiDBAutoField_SPACING + s2.width(), qMax(s1.height(), s2.height()));
648 }
649 
650 void
setFocusPolicy(Qt::FocusPolicy policy)651 KexiDBAutoField::setFocusPolicy(Qt::FocusPolicy policy)
652 {
653     d->focusPolicyChanged = true;
654     QWidget::setFocusPolicy(policy);
655     d->label->setFocusPolicy(policy);
656     if (subwidget())
657         subwidget()->setFocusPolicy(policy);
658 }
659 
660 void
updateInformationAboutUnboundField()661 KexiDBAutoField::updateInformationAboutUnboundField()
662 {
663     if ((d->autoCaption && (dataSource().isEmpty() || dataSourcePluginId().isEmpty()))
664             || (!d->autoCaption && d->caption.isEmpty())) {
665         d->label->setText(futureI18nc2("Unbound Auto Field", "%1 (unbound)", objectName()));
666     }
667 }
668 
669 void
paletteChange(const QPalette & oldPal)670 KexiDBAutoField::paletteChange(const QPalette& oldPal)
671 {
672     Q_UNUSED(oldPal);
673     d->label->setPalette(palette());
674 }
675 
unsetPalette()676 void KexiDBAutoField::unsetPalette()
677 {
678     setPalette(QPalette());
679 }
680 
681 // ===== methods below are just proxies for the internal editor or label =====
682 
paletteForegroundColor() const683 QColor KexiDBAutoField::paletteForegroundColor() const
684 {
685 //! @todo how about brush?
686     return d->textBrush.color();
687 }
688 
setPaletteForegroundColor(const QColor & color)689 void KexiDBAutoField::setPaletteForegroundColor(const QColor & color)
690 {
691 //! @todo how about brush?
692     d->textBrush.setColor(color);
693     copyPropertiesToEditor();
694 }
695 
paletteBackgroundColor() const696 QColor KexiDBAutoField::paletteBackgroundColor() const
697 {
698 //! @todo how about brush?
699     return d->baseBrush.color();
700 }
701 
setPaletteBackgroundColor(const QColor & color)702 void KexiDBAutoField::setPaletteBackgroundColor(const QColor & color)
703 {
704     //qDebug();
705 //! @todo how about brush?
706     d->baseBrush.setColor(color);
707     copyPropertiesToEditor();
708 }
709 
foregroundLabelColor() const710 QColor KexiDBAutoField::foregroundLabelColor() const
711 {
712     if (d->widgetType == Boolean)
713         return paletteForegroundColor();
714 
715     return d->label->palette().color(d->label->foregroundRole());
716 }
717 
setForegroundLabelColor(const QColor & color)718 void KexiDBAutoField::setForegroundLabelColor(const QColor & color)
719 {
720     if (d->widgetType == Boolean)
721         setPaletteForegroundColor(color);
722     else {
723         QPalette pal(d->label->palette());
724         pal.setColor(d->label->foregroundRole(), color);
725         d->label->setPalette(pal);
726         pal = palette();
727         pal.setColor(foregroundRole(), color);
728         setPalette(pal);
729     }
730 }
731 
backgroundLabelColor() const732 QColor KexiDBAutoField::backgroundLabelColor() const
733 {
734     if (d->widgetType == Boolean)
735         return paletteBackgroundColor();
736 
737     return d->label->palette().color(d->label->backgroundRole());
738 }
739 
setBackgroundLabelColor(const QColor & color)740 void KexiDBAutoField::setBackgroundLabelColor(const QColor & color)
741 {
742     if (d->widgetType == Boolean)
743         setPaletteBackgroundColor(color);
744     else {
745         QPalette pal(d->label->palette());
746         pal.setColor(d->label->backgroundRole(), color);
747         d->label->setPalette(pal);
748         pal = palette();
749         pal.setColor(backgroundRole(), color);
750         setPalette(pal);
751     }
752 }
753 
property(const char * name) const754 QVariant KexiDBAutoField::property(const char * name) const
755 {
756     bool ok;
757     QVariant val = KFormDesigner::WidgetWithSubpropertiesInterface::subproperty(name, &ok);
758     if (ok)
759         return val;
760     return QWidget::property(name);
761 }
762 
setProperty(const char * name,const QVariant & value)763 bool KexiDBAutoField::setProperty(const char * name, const QVariant & value)
764 {
765     bool ok = KFormDesigner::WidgetWithSubpropertiesInterface::setSubproperty(name, value);
766     if (ok)
767         return true;
768     return QWidget::setProperty(name, value);
769 }
770 
eventFilter(QObject * o,QEvent * e)771 bool KexiDBAutoField::eventFilter(QObject *o, QEvent *e)
772 {
773     if (o == d->label && d->label->buddy() && e->type() == QEvent::MouseButtonRelease) {
774         //focus label's buddy when user clicked the label
775         d->label->buddy()->setFocus();
776     }
777     return QWidget::eventFilter(o, e);
778 }
779 
setDisplayDefaultValue(QWidget * widget,bool displayDefaultValue)780 void KexiDBAutoField::setDisplayDefaultValue(QWidget* widget, bool displayDefaultValue)
781 {
782     KexiFormDataItemInterface::setDisplayDefaultValue(widget, displayDefaultValue);
783     KexiFormDataItemInterface *formIface = dynamic_cast<KexiFormDataItemInterface*>(subwidget());
784     if (formIface)
785         formIface->setDisplayDefaultValue(subwidget(), displayDefaultValue);
786 }
787 
moveCursorToEnd()788 void KexiDBAutoField::moveCursorToEnd()
789 {
790     KexiDataItemInterface *iface = dynamic_cast<KexiDataItemInterface*>((QWidget*)subwidget());
791     if (iface)
792         iface->moveCursorToEnd();
793 }
794 
moveCursorToStart()795 void KexiDBAutoField::moveCursorToStart()
796 {
797     KexiDataItemInterface *iface = dynamic_cast<KexiDataItemInterface*>((QWidget*)subwidget());
798     if (iface)
799         iface->moveCursorToStart();
800 }
801 
selectAll()802 void KexiDBAutoField::selectAll()
803 {
804     KexiDataItemInterface *iface = dynamic_cast<KexiDataItemInterface*>((QWidget*)subwidget());
805     if (iface)
806         iface->selectAll();
807 }
808 
keyPressed(QKeyEvent * ke)809 bool KexiDBAutoField::keyPressed(QKeyEvent *ke)
810 {
811     KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>((QWidget*)subwidget());
812     if (iface && iface->keyPressed(ke))
813         return true;
814     return false;
815 }
816