File indexing completed on 2024-03-24 16:11:18

0001 /* This file is part of the KDE project
0002    Copyright (C) 2006-2016 Jarosław Staniek <staniek@kde.org>
0003 
0004    This program is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This program is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this program; see the file COPYING.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #include "KDbLookupFieldSchema.h"
0021 #include "KDb.h"
0022 #include "kdb_debug.h"
0023 
0024 #include <QDomElement>
0025 #include <QVariant>
0026 #include <QStringList>
0027 #include <QHash>
0028 
0029 #include <vector>
0030 
0031 //! @internal
0032 class Q_DECL_HIDDEN KDbLookupFieldSchemaRecordSource::Private
0033 {
0034 public:
0035     Private()
0036             : type(KDbLookupFieldSchemaRecordSource::Type::None) {
0037     }
0038     Private(const Private &other) {
0039         copy(other);
0040     }
0041 #define KDbLookupFieldSchemaRecordSourcePrivateArgs(o) std::tie(o.type, o.name, o.values)
0042     void copy(const Private &other) {
0043         KDbLookupFieldSchemaRecordSourcePrivateArgs((*this))
0044                 = KDbLookupFieldSchemaRecordSourcePrivateArgs(other);
0045     }
0046     bool operator==(const KDbLookupFieldSchemaRecordSource::Private &other) const {
0047         return KDbLookupFieldSchemaRecordSourcePrivateArgs((*this))
0048                 == KDbLookupFieldSchemaRecordSourcePrivateArgs(other);
0049     }
0050 
0051     KDbLookupFieldSchemaRecordSource::Type type;
0052     QString name;
0053     QStringList values;
0054 };
0055 
0056 //! @internal
0057 class Q_DECL_HIDDEN KDbLookupFieldSchema::Private
0058 {
0059 public:
0060     Private()
0061             : boundColumn(-1)
0062             , maxVisibleRecords(KDB_LOOKUP_FIELD_DEFAULT_MAX_VISIBLE_RECORDS)
0063             , displayWidget(KDB_LOOKUP_FIELD_DEFAULT_DISPLAY_WIDGET)
0064             , columnHeadersVisible(KDB_LOOKUP_FIELD_DEFAULT_HEADERS_VISIBLE)
0065             , limitToList(KDB_LOOKUP_FIELD_DEFAULT_LIMIT_TO_LIST) {
0066     }
0067     Private(const Private &other) {
0068         copy(other);
0069     }
0070 #define KDbLookupFieldSchemaPrivateArgs(o) std::tie(o.recordSource, o.boundColumn, o.visibleColumns, \
0071                     o.columnWidths, o.maxVisibleRecords, o.displayWidget, \
0072                     o.columnHeadersVisible, o.limitToList)
0073     void copy(const Private &other) {
0074         KDbLookupFieldSchemaPrivateArgs((*this)) = KDbLookupFieldSchemaPrivateArgs(other);
0075     }
0076     bool operator==(const KDbLookupFieldSchema::Private &other) const {
0077         return KDbLookupFieldSchemaPrivateArgs((*this)) == KDbLookupFieldSchemaPrivateArgs(other);
0078     }
0079 
0080     KDbLookupFieldSchemaRecordSource recordSource;
0081     int boundColumn;
0082     QList<int> visibleColumns;
0083     QList<int> columnWidths;
0084     int maxVisibleRecords;
0085     DisplayWidget displayWidget;
0086     bool columnHeadersVisible;
0087     bool limitToList;
0088 };
0089 
0090 //! Cache
0091 class LookupFieldSchemaStatic
0092 {
0093 public:
0094     LookupFieldSchemaStatic()
0095      : typeNames({
0096             QString(), // no type
0097             QLatin1String("table"),
0098             QLatin1String("query"),
0099             QLatin1String("sql"),
0100             QLatin1String("valuelist"),
0101             QLatin1String("fieldlist")})
0102     {
0103         typesForNames.insert(QLatin1String("table"), KDbLookupFieldSchemaRecordSource::Type::Table);
0104         typesForNames.insert(QLatin1String("query"), KDbLookupFieldSchemaRecordSource::Type::Query);
0105         typesForNames.insert(QLatin1String("sql"), KDbLookupFieldSchemaRecordSource::Type::SQLStatement);
0106         typesForNames.insert(QLatin1String("valuelist"), KDbLookupFieldSchemaRecordSource::Type::ValueList);
0107         typesForNames.insert(QLatin1String("fieldlist"), KDbLookupFieldSchemaRecordSource::Type::KDbFieldList);
0108     }
0109     const std::vector<QString> typeNames;
0110     QHash<QString, KDbLookupFieldSchemaRecordSource::Type> typesForNames;
0111 private:
0112     Q_DISABLE_COPY(LookupFieldSchemaStatic)
0113 };
0114 
0115 Q_GLOBAL_STATIC(LookupFieldSchemaStatic, KDb_lookupFieldSchemaStatic)
0116 
0117 //----------------------------
0118 
0119 KDbLookupFieldSchemaRecordSource::KDbLookupFieldSchemaRecordSource()
0120         : d(new Private)
0121 {
0122 }
0123 
0124 KDbLookupFieldSchemaRecordSource::KDbLookupFieldSchemaRecordSource(const KDbLookupFieldSchemaRecordSource& other)
0125         : d(new Private(*other.d))
0126 {
0127 }
0128 
0129 KDbLookupFieldSchemaRecordSource::~KDbLookupFieldSchemaRecordSource()
0130 {
0131     delete d;
0132 }
0133 
0134 KDbLookupFieldSchemaRecordSource::Type KDbLookupFieldSchemaRecordSource::type() const
0135 {
0136     return d->type;
0137 }
0138 
0139 void KDbLookupFieldSchemaRecordSource::setType(Type type)
0140 {
0141     d->type = type;
0142 }
0143 
0144 QString KDbLookupFieldSchemaRecordSource::name() const
0145 {
0146     return d->name;
0147 }
0148 
0149 void KDbLookupFieldSchemaRecordSource::setName(const QString& name)
0150 {
0151     d->name = name;
0152     d->values.clear();
0153 }
0154 
0155 QString KDbLookupFieldSchemaRecordSource::typeName() const
0156 {
0157     Q_ASSERT(size_t(d->type) < KDb_lookupFieldSchemaStatic->typeNames.size());
0158     return KDb_lookupFieldSchemaStatic->typeNames[static_cast<int>(d->type)];
0159 }
0160 
0161 void KDbLookupFieldSchemaRecordSource::setTypeByName(const QString& typeName)
0162 {
0163     setType(KDb_lookupFieldSchemaStatic->typesForNames.value(typeName, Type::None));
0164 }
0165 
0166 QStringList KDbLookupFieldSchemaRecordSource::values() const
0167 {
0168     return d->values;
0169 }
0170 
0171 void KDbLookupFieldSchemaRecordSource::setValues(const QStringList& values)
0172 {
0173     d->name.clear();
0174     d->values = values;
0175 }
0176 
0177 KDbLookupFieldSchemaRecordSource& KDbLookupFieldSchemaRecordSource::operator=(const KDbLookupFieldSchemaRecordSource & other)
0178 {
0179     if (this != &other) {
0180         *d = *other.d;
0181     }
0182     return *this;
0183 }
0184 
0185 bool KDbLookupFieldSchemaRecordSource::operator==(const KDbLookupFieldSchemaRecordSource &other) const
0186 {
0187     return *d == *other.d;
0188 }
0189 
0190 QDebug operator<<(QDebug dbg, const KDbLookupFieldSchemaRecordSource& source)
0191 {
0192     dbg.nospace() << "LookupFieldSchemaRecordSource TYPE:";
0193     dbg.space() << source.typeName();
0194     dbg.space() << "NAME:";
0195     dbg.space() << source.name();
0196     dbg.space() << "VALUES:";
0197     dbg.space() << source.values().join(QLatin1String("|")) << '\n';
0198     return dbg.nospace();
0199 }
0200 
0201 //----------------------------
0202 
0203 KDbLookupFieldSchema::KDbLookupFieldSchema()
0204         : d(new Private)
0205 {
0206 }
0207 
0208 KDbLookupFieldSchema::KDbLookupFieldSchema(const KDbLookupFieldSchema &schema)
0209 : d(new Private(*schema.d))
0210 {
0211 }
0212 
0213 KDbLookupFieldSchema::~KDbLookupFieldSchema()
0214 {
0215     delete d;
0216 }
0217 
0218 static bool setBoundColumn(KDbLookupFieldSchema *lookup, const QVariant &val)
0219 {
0220     if (val.isNull()) {
0221         lookup->setBoundColumn(-1);
0222     }
0223     else {
0224         bool ok;
0225         const int ival = val.toInt(&ok);
0226         if (!ok)
0227             return false;
0228         lookup->setBoundColumn(ival);
0229     }
0230     return true;
0231 }
0232 
0233 static bool setVisibleColumns(KDbLookupFieldSchema *lookup, const QVariant &val)
0234 {
0235     QList<QVariant> variantList;
0236     if (val.canConvert(QVariant::Int)) {
0237     //! @todo Remove this case: it's for backward compatibility with Kexi's 1.1.2 table designer GUI
0238     //!       supporting only single lookup column.
0239         variantList.append(val);
0240     }
0241     else {
0242         variantList = val.toList();
0243     }
0244     QList<int> visibleColumns;
0245     foreach(const QVariant& variant, variantList) {
0246         bool ok;
0247         const int ival = variant.toInt(&ok);
0248         if (!ok) {
0249             return false;
0250         }
0251         visibleColumns.append(ival);
0252     }
0253     lookup->setVisibleColumns(visibleColumns);
0254     return true;
0255 }
0256 
0257 static bool setColumnWidths(KDbLookupFieldSchema *lookup, const QVariant &val)
0258 {
0259     QList<int> widths;
0260     foreach(const QVariant& variant, val.toList()) {
0261         bool ok;
0262         const int ival = variant.toInt(&ok);
0263         if (!ok)
0264             return false;
0265         widths.append(ival);
0266     }
0267     lookup->setColumnWidths(widths);
0268     return true;
0269 }
0270 
0271 static bool setDisplayWidget(KDbLookupFieldSchema *lookup, const QVariant &val)
0272 {
0273     bool ok;
0274     const uint ival = val.toUInt(&ok);
0275     if (!ok || ival > static_cast<uint>(KDbLookupFieldSchema::DisplayWidget::ListBox)) {
0276         return false;
0277     }
0278     lookup->setDisplayWidget(static_cast<KDbLookupFieldSchema::DisplayWidget>(ival));
0279     return true;
0280 }
0281 
0282 KDbLookupFieldSchemaRecordSource KDbLookupFieldSchema::recordSource() const
0283 {
0284     return d->recordSource;
0285 }
0286 
0287 void KDbLookupFieldSchema::setRecordSource(const KDbLookupFieldSchemaRecordSource& recordSource)
0288 {
0289     d->recordSource = recordSource;
0290 }
0291 
0292 void KDbLookupFieldSchema::setMaxVisibleRecords(int count)
0293 {
0294     if (count == 0)
0295         d->maxVisibleRecords = KDB_LOOKUP_FIELD_DEFAULT_MAX_VISIBLE_RECORDS;
0296     else if (count > KDB_LOOKUP_FIELD_LIMIT_MAX_VISIBLE_RECORDS)
0297         d->maxVisibleRecords = KDB_LOOKUP_FIELD_LIMIT_MAX_VISIBLE_RECORDS;
0298     else
0299         d->maxVisibleRecords = count;
0300 }
0301 
0302 QDebug operator<<(QDebug dbg, const KDbLookupFieldSchema& lookup)
0303 {
0304     dbg.nospace() << "LookupFieldSchema(";
0305     dbg.space() << lookup.recordSource();
0306     dbg.space() << "boundColumn:";
0307     dbg.space() << lookup.boundColumn();
0308     dbg.space() << "visibleColumns:";
0309 
0310     bool first = true;
0311     foreach(int visibleColumn, lookup.visibleColumns()) {
0312         if (first) {
0313             first = false;
0314             dbg.nospace();
0315         }
0316         else
0317             dbg.nospace() << ';';
0318         dbg.nospace() << visibleColumn;
0319     }
0320     dbg.space() << "maxVisibleRecords:";
0321     dbg.space() << lookup.maxVisibleRecords();
0322     dbg.space() << "displayWidget:";
0323     dbg.space() << (lookup.displayWidget() == KDbLookupFieldSchema::DisplayWidget::ComboBox
0324                         ? "ComboBox"
0325                         : "ListBox");
0326     dbg.space() << "columnHeadersVisible:";
0327     dbg.space() << lookup.columnHeadersVisible();
0328     dbg.space() << "limitToList:";
0329     dbg.space() << lookup.limitToList();
0330     dbg.space() << "columnWidths:";
0331 
0332     first = true;
0333     const QList<int> columnWidths(lookup.columnWidths());
0334     for (int width : columnWidths) {
0335         if (first)
0336             first = false;
0337         else
0338             dbg.nospace() << ';';
0339         dbg.space() << width;
0340     }
0341     dbg.nospace() << ')';
0342     return dbg.space();
0343 }
0344 
0345 /* static */
0346 KDbLookupFieldSchema *KDbLookupFieldSchema::loadFromDom(const QDomElement& lookupEl)
0347 {
0348     KDbLookupFieldSchema *lookupFieldSchema = new KDbLookupFieldSchema();
0349     KDbLookupFieldSchemaRecordSource recordSource;
0350     for (QDomNode node = lookupEl.firstChild(); !node.isNull(); node = node.nextSibling()) {
0351         QDomElement el = node.toElement();
0352         const QByteArray name(el.tagName().toLatin1());
0353         if (name == "row-source") {
0354             /*<row-source>
0355               empty
0356               | <type>table|query|sql|valuelist|fieldlist</type> #required because there can be
0357                                                                  #table and query with the same name
0358                                                                  #"fieldlist" (basically a list of
0359                                                                  #column names of a table/query,
0360                                                                  #"Field List" as in MSA)
0361               <name>string</name> #table/query name, etc. or KDbSQL SELECT QUERY
0362               <values><value>...</value> #for "valuelist" type
0363                 <value>...</value>
0364               </values>
0365              </row-source> */
0366             for (el = el.firstChild().toElement(); !el.isNull(); el = el.nextSibling().toElement()) {
0367                 const QByteArray childName(el.tagName().toLatin1());
0368                 if (childName == "type") {
0369                     recordSource.setTypeByName(el.text());
0370                 }
0371                 else if (childName == "name") {
0372                     recordSource.setName(el.text());
0373 //! @todo handle fieldlist (retrieve from external table or so?), use KDbLookupFieldSchemaRecordSource::setValues()
0374                 }
0375             }
0376         } else if (name == "bound-column") {
0377             /* <bound-column>
0378                 <number>number</number> #in later implementation there can be more columns
0379                </bound-column> */
0380             bool ok;
0381             const QVariant val = KDb::loadPropertyValueFromDom(el.firstChild(), &ok);
0382             if (!ok || !::setBoundColumn(lookupFieldSchema, val)) {
0383                 delete lookupFieldSchema;
0384                 return nullptr;
0385             }
0386         } else if (name == "visible-column") {
0387             /* <visible-column> #a column that has to be visible in the combo box
0388               <number>number 1</number>
0389               <number>number 2</number>
0390               [..]
0391                </visible-column> */
0392             QVariantList list;
0393             for (QDomNode childNode = el.firstChild(); !childNode.isNull();
0394                  childNode = childNode.nextSibling())
0395             {
0396                 bool ok;
0397                 const QVariant val = KDb::loadPropertyValueFromDom(childNode, &ok);
0398                 if (!ok) {
0399                     delete lookupFieldSchema;
0400                     return nullptr;
0401                 }
0402                 list.append(val);
0403             }
0404             if (!::setVisibleColumns(lookupFieldSchema, list)) {
0405                 delete lookupFieldSchema;
0406                 return nullptr;
0407             }
0408         } else if (name == "column-widths") {
0409             /* <column-widths> #column widths, -1 means 'default'
0410                 <number>int</number>
0411                 ...
0412                 <number>int</number>
0413                </column-widths> */
0414             QVariantList columnWidths;
0415             for (el = el.firstChild().toElement(); !el.isNull(); el = el.nextSibling().toElement()) {
0416                 bool ok;
0417                 QVariant val = KDb::loadPropertyValueFromDom(el, &ok);
0418                 if (!ok) {
0419                     delete lookupFieldSchema;
0420                     return nullptr;
0421                 }
0422                 columnWidths.append(val);
0423             }
0424             if (!::setColumnWidths(lookupFieldSchema, columnWidths)) {
0425                 delete lookupFieldSchema;
0426                 return nullptr;
0427             }
0428         } else if (name == "show-column-headers") {
0429             /* <show-column-headers>
0430                 <bool>true/false</bool>
0431                </show-column-headers> */
0432             bool ok;
0433             const QVariant val = KDb::loadPropertyValueFromDom(el.firstChild(), &ok);
0434             if (!ok) {
0435                 delete lookupFieldSchema;
0436                 return nullptr;
0437             }
0438             if (val.type() == QVariant::Bool)
0439                 lookupFieldSchema->setColumnHeadersVisible(val.toBool());
0440         } else if (name == "list-rows") {
0441             /* <list-rows>
0442                 <number>1..100</number>
0443                </list-rows> */
0444             bool ok;
0445             const QVariant val = KDb::loadPropertyValueFromDom(el.firstChild(), &ok);
0446             if (!ok) {
0447                 delete lookupFieldSchema;
0448                 return nullptr;
0449             }
0450             if (val.type() == QVariant::Int)
0451                 lookupFieldSchema->setMaxVisibleRecords(val.toInt());
0452         } else if (name == "limit-to-list") {
0453             /* <limit-to-list>
0454                 <bool>true/false</bool>
0455                </limit-to-list> */
0456             bool ok;
0457             const QVariant val = KDb::loadPropertyValueFromDom(el.firstChild(), &ok);
0458             if (!ok) {
0459                 delete lookupFieldSchema;
0460                 return nullptr;
0461             }
0462             if (val.type() == QVariant::Bool)
0463                 lookupFieldSchema->setLimitToList(val.toBool());
0464         }
0465         else if (name == "display-widget") {
0466             const QByteArray displayWidgetName(el.text().toLatin1());
0467             if (displayWidgetName == "combobox") {
0468                 lookupFieldSchema->setDisplayWidget(KDbLookupFieldSchema::DisplayWidget::ComboBox);
0469             }
0470             else if (displayWidgetName == "listbox") {
0471                 lookupFieldSchema->setDisplayWidget(KDbLookupFieldSchema::DisplayWidget::ListBox);
0472             }
0473         }
0474     }
0475     lookupFieldSchema->setRecordSource(recordSource);
0476     return lookupFieldSchema;
0477 }
0478 
0479 void KDbLookupFieldSchema::saveToDom(QDomDocument *doc, QDomElement *parentEl)
0480 {
0481     if (!doc || !parentEl) {
0482         return;
0483     }
0484     QDomElement lookupColumnEl, recordSourceEl, recordSourceTypeEl, nameEl;
0485     if (!recordSource().name().isEmpty()) {
0486         lookupColumnEl = doc->createElement(QLatin1String("lookup-column"));
0487         parentEl->appendChild(lookupColumnEl);
0488 
0489         recordSourceEl = doc->createElement(QLatin1String("row-source"));
0490         lookupColumnEl.appendChild(recordSourceEl);
0491 
0492         recordSourceTypeEl = doc->createElement(QLatin1String("type"));
0493         recordSourceEl.appendChild(recordSourceTypeEl);
0494         recordSourceTypeEl.appendChild(doc->createTextNode(recordSource().typeName()));   //can be empty
0495 
0496         nameEl = doc->createElement(QLatin1String("name"));
0497         recordSourceEl.appendChild(nameEl);
0498         nameEl.appendChild(doc->createTextNode(recordSource().name()));
0499     }
0500 
0501     const QStringList& values(recordSource().values());
0502     if (!values.isEmpty()) {
0503         QDomElement valuesEl(doc->createElement(QLatin1String("values")));
0504         recordSourceEl.appendChild(valuesEl);
0505         for (QStringList::ConstIterator it = values.constBegin(); it != values.constEnd(); ++it) {
0506             QDomElement valueEl(doc->createElement(QLatin1String("value")));
0507             valuesEl.appendChild(valueEl);
0508             valueEl.appendChild(doc->createTextNode(*it));
0509         }
0510     }
0511 
0512     if (boundColumn() >= 0) {
0513         KDb::saveNumberElementToDom(doc, &lookupColumnEl,
0514                                           QLatin1String("bound-column"), boundColumn());
0515     }
0516 
0517     QList<int> visibleColumns(this->visibleColumns());
0518     if (!visibleColumns.isEmpty()) {
0519         QDomElement visibleColumnEl(doc->createElement(QLatin1String("visible-column")));
0520         lookupColumnEl.appendChild(visibleColumnEl);
0521         foreach(int visibleColumn, visibleColumns) {
0522             QDomElement numberEl(doc->createElement(QLatin1String("number")));
0523             visibleColumnEl.appendChild(numberEl);
0524             numberEl.appendChild(doc->createTextNode(QString::number(visibleColumn)));
0525         }
0526     }
0527 
0528     const QList<int> columnWidths(this->columnWidths());
0529     if (!columnWidths.isEmpty()) {
0530         QDomElement columnWidthsEl(doc->createElement(QLatin1String("column-widths")));
0531         lookupColumnEl.appendChild(columnWidthsEl);
0532         foreach(int columnWidth, columnWidths) {
0533             QDomElement columnWidthEl(doc->createElement(QLatin1String("number")));
0534             columnWidthsEl.appendChild(columnWidthEl);
0535             columnWidthEl.appendChild(doc->createTextNode(QString::number(columnWidth)));
0536         }
0537     }
0538 
0539     if (columnHeadersVisible() != KDB_LOOKUP_FIELD_DEFAULT_HEADERS_VISIBLE)
0540         KDb::saveBooleanElementToDom(doc, &lookupColumnEl,
0541                                            QLatin1String("show-column-headers"),
0542                                            columnHeadersVisible());
0543     if (maxVisibleRecords() != KDB_LOOKUP_FIELD_DEFAULT_MAX_VISIBLE_RECORDS)
0544         KDb::saveNumberElementToDom(doc, &lookupColumnEl,
0545                                           QLatin1String("list-rows"),
0546                                           maxVisibleRecords());
0547     if (limitToList() != KDB_LOOKUP_FIELD_DEFAULT_LIMIT_TO_LIST)
0548         KDb::saveBooleanElementToDom(doc, &lookupColumnEl,
0549                                            QLatin1String("limit-to-list"),
0550                                            limitToList());
0551 
0552     if (displayWidget() != KDB_LOOKUP_FIELD_DEFAULT_DISPLAY_WIDGET) {
0553         QDomElement displayWidgetEl(doc->createElement(QLatin1String("display-widget")));
0554         lookupColumnEl.appendChild(displayWidgetEl);
0555         displayWidgetEl.appendChild(
0556             doc->createTextNode(
0557                 QLatin1String((displayWidget() == DisplayWidget::ListBox) ? "listbox" : "combobox")));
0558     }
0559 }
0560 
0561 void KDbLookupFieldSchema::getProperties(QMap<QByteArray, QVariant> *values) const
0562 {
0563     values->clear();
0564     KDb::getProperties(this, values);
0565 }
0566 
0567 bool KDbLookupFieldSchema::setProperty(const QByteArray& propertyName, const QVariant& value)
0568 {
0569     bool ok;
0570     if (   "rowSource" == propertyName
0571         || "rowSourceType" == propertyName
0572         || "rowSourceValues" == propertyName)
0573     {
0574         KDbLookupFieldSchemaRecordSource recordSource(this->recordSource());
0575         if ("rowSource" == propertyName)
0576             recordSource.setName(value.toString());
0577         else if ("rowSourceType" == propertyName)
0578             recordSource.setTypeByName(value.toString());
0579         else if ("rowSourceValues" == propertyName) {
0580             recordSource.setValues(value.toStringList());
0581         } else {
0582             kdbCritical() << "impl. error: unsupported property" << propertyName;
0583         }
0584         this->setRecordSource(recordSource);
0585     }
0586     else if ("boundColumn" == propertyName) {
0587         if (!::setBoundColumn(this, value)) {
0588             return false;
0589         }
0590     }
0591     else if ("visibleColumn" == propertyName) {
0592         if (!::setVisibleColumns(this, value)) {
0593             return false;
0594         }
0595     } else if ("columnWidths" == propertyName) {
0596         if (!::setColumnWidths(this, value)) {
0597             return false;
0598         }
0599     } else if ("showColumnHeaders" == propertyName) {
0600         setColumnHeadersVisible(value.toBool());
0601     } else if ("listRows" == propertyName) {
0602         const int ival = value.toInt(&ok);
0603         if (!ok)
0604             return false;
0605         setMaxVisibleRecords(ival);
0606     } else if ("limitToList" == propertyName) {
0607         setLimitToList(value.toBool());
0608     } else if ("displayWidget" == propertyName) {
0609         if (!::setDisplayWidget(this, value)) {
0610             return false;
0611         }
0612     }
0613     return true;
0614 }
0615 
0616 bool KDbLookupFieldSchema::setProperties(const QMap<QByteArray, QVariant>& values)
0617 {
0618     QMap<QByteArray, QVariant>::ConstIterator it;
0619     KDbLookupFieldSchemaRecordSource recordSource(this->recordSource());
0620     bool ok;
0621     bool updateRecordSource = false;
0622     if ((it = values.find("rowSource")) != values.constEnd()) {
0623         recordSource.setName(it.value().toString());
0624         updateRecordSource = true;
0625     }
0626     if ((it = values.find("rowSourceType")) != values.constEnd()) {
0627         recordSource.setTypeByName(it.value().toString());
0628         updateRecordSource = true;
0629     }
0630     if ((it = values.find("rowSourceValues")) != values.constEnd()) {
0631         if (!it.value().isNull()) {
0632             recordSource.setValues(it.value().toStringList());
0633             updateRecordSource = true;
0634         }
0635     }
0636     if (updateRecordSource) {
0637         setRecordSource(recordSource);
0638     }
0639     if ((it = values.find("boundColumn")) != values.constEnd()) {
0640         if (!::setBoundColumn(this, it.value())) {
0641             return false;
0642         }
0643     }
0644     if ((it = values.find("visibleColumn")) != values.constEnd()) {
0645         if (!::setVisibleColumns(this, it.value())) {
0646             return false;
0647         }
0648     }
0649     if ((it = values.find("columnWidths")) != values.constEnd()) {
0650         if (!::setColumnWidths(this, it.value())) {
0651             return false;
0652         }
0653     }
0654     if ((it = values.find("showColumnHeaders")) != values.constEnd()) {
0655         setColumnHeadersVisible(it.value().toBool());
0656     }
0657     if ((it = values.find("listRows")) != values.constEnd()) {
0658         int ival = it.value().toInt(&ok);
0659         if (!ok)
0660             return false;
0661         setMaxVisibleRecords(ival);
0662     }
0663     if ((it = values.find("limitToList")) != values.constEnd()) {
0664         setLimitToList(it.value().toBool());
0665     }
0666     if ((it = values.find("displayWidget")) != values.constEnd()) {
0667         if (!::setDisplayWidget(this, it.value())) {
0668             return false;
0669         }
0670     }
0671     return true;
0672 }
0673 
0674 
0675 int KDbLookupFieldSchema::boundColumn() const
0676 {
0677     return d->boundColumn;
0678 }
0679 
0680 void KDbLookupFieldSchema::setBoundColumn(int column)
0681 {
0682     d->boundColumn = column >= 0 ? column : -1;
0683 }
0684 
0685 QList<int> KDbLookupFieldSchema::visibleColumns() const
0686 {
0687     return d->visibleColumns;
0688 }
0689 
0690 void KDbLookupFieldSchema::setVisibleColumns(const QList<int>& list)
0691 {
0692     d->visibleColumns = list;
0693 }
0694 
0695 int KDbLookupFieldSchema::visibleColumn(int index) const
0696 {
0697     if (index >= d->visibleColumns.count()) {
0698         return -1;
0699     }
0700     return index;
0701 }
0702 
0703 QList<int> KDbLookupFieldSchema::columnWidths() const
0704 {
0705     return d->columnWidths;
0706 }
0707 
0708 void KDbLookupFieldSchema::setColumnWidths(const QList<int>& widths)
0709 {
0710     d->columnWidths = widths;
0711 }
0712 
0713 bool KDbLookupFieldSchema::columnHeadersVisible() const
0714 {
0715     return d->columnHeadersVisible;
0716 }
0717 
0718 void KDbLookupFieldSchema::setColumnHeadersVisible(bool set)
0719 {
0720     d->columnHeadersVisible = set;
0721 }
0722 
0723 int KDbLookupFieldSchema::maxVisibleRecords() const
0724 {
0725     return d->maxVisibleRecords;
0726 }
0727 
0728 bool KDbLookupFieldSchema::limitToList() const
0729 {
0730     return d->limitToList;
0731 }
0732 
0733 void KDbLookupFieldSchema::setLimitToList(bool set)
0734 {
0735     d->limitToList = set;
0736 }
0737 
0738 KDbLookupFieldSchema::DisplayWidget KDbLookupFieldSchema::displayWidget() const
0739 {
0740     return d->displayWidget;
0741 }
0742 
0743 void KDbLookupFieldSchema::setDisplayWidget(DisplayWidget widget)
0744 {
0745     d->displayWidget = widget;
0746 }
0747 
0748 KDbLookupFieldSchema& KDbLookupFieldSchema::operator=(const KDbLookupFieldSchema & other)
0749 {
0750     if (this != &other) {
0751         *d = *other.d;
0752     }
0753     return *this;
0754 }
0755 
0756 bool KDbLookupFieldSchema::operator==(const KDbLookupFieldSchema &other) const
0757 {
0758     return *d == *other.d;
0759 }