kexi

lookupfieldschema.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2006-2007 Jaroslaw Staniek <js@iidea.pl>
00003 
00004    This program is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this program; see the file COPYING.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "lookupfieldschema.h"
00021 #include "utils.h"
00022 
00023 #include <qdom.h>
00024 #include <qvariant.h>
00025 #include <kdebug.h>
00026 
00027 using namespace KexiDB;
00028 
00029 
00030 LookupFieldSchema::RowSource::RowSource()
00031 : m_type(NoType)
00032 , m_values(0)
00033 {
00034 }
00035 
00036 LookupFieldSchema::RowSource::~RowSource()
00037 {
00038     delete m_values;
00039 }
00040 
00041 void LookupFieldSchema::RowSource::setName(const QString& name)
00042 {
00043     m_name = name;
00044     if (m_values)
00045         m_values->clear();
00046 }
00047 
00048 QString LookupFieldSchema::RowSource::typeName() const
00049 {
00050     switch (m_type) {
00051     case Table: return "table";
00052     case Query: return "query";
00053     case SQLStatement: return "sql";
00054     case ValueList: return "valuelist";
00055     case FieldList: return "fieldlist";
00056     default:;
00057     }
00058     return QString::null;
00059 }
00060 
00061 void LookupFieldSchema::RowSource::setTypeByName( const QString& typeName )
00062 {
00063     if (typeName=="table")
00064         setType( Table );
00065     else if (typeName=="query")
00066         setType( Query );
00067     else if (typeName=="sql")
00068         setType( SQLStatement );
00069     else if (typeName=="valuelist")
00070         setType( ValueList );
00071     else if (typeName=="fieldlist")
00072         setType( FieldList );
00073     else
00074         setType( NoType );
00075 }
00076 
00077 QStringList LookupFieldSchema::RowSource::values() const
00078 {
00079     return m_values ? *m_values : QStringList();
00080 }
00081 
00082 void LookupFieldSchema::RowSource::setValues(const QStringList& values)
00083 {
00084     m_name = QString::null;
00085     if (m_values)
00086         *m_values = values;
00087     else
00088         m_values = new QStringList(values);
00089 }
00090 
00091 QString LookupFieldSchema::RowSource::debugString() const
00092 {
00093     return QString("rowSourceType:'%1' rowSourceName:'%2' rowSourceValues:'%3'\n")
00094         .arg(typeName()).arg(name()).arg(m_values ? m_values->join("|") : QString::null);
00095 }
00096 
00097 void LookupFieldSchema::RowSource::debug() const
00098 {
00099     KexiDBDbg << debugString() << endl;
00100 }
00101 
00102 //---------------------------------------
00103 
00104 LookupFieldSchema::LookupFieldSchema()
00105  : m_boundColumn(-1)
00106  , m_maximumListRows(KEXIDB_LOOKUP_FIELD_DEFAULT_LIST_ROWS)
00107  , m_displayWidget(KEXIDB_LOOKUP_FIELD_DEFAULT_DISPLAY_WIDGET)
00108  , m_columnHeadersVisible(KEXIDB_LOOKUP_FIELD_DEFAULT_HEADERS_VISIBLE)
00109  , m_limitToList(KEXIDB_LOOKUP_FIELD_DEFAULT_LIMIT_TO_LIST)
00110 {
00111 }
00112 
00113 LookupFieldSchema::~LookupFieldSchema()
00114 {
00115 }
00116 
00117 void LookupFieldSchema::setMaximumListRows(uint rows)
00118 {
00119     if (rows==0)
00120         m_maximumListRows = KEXIDB_LOOKUP_FIELD_DEFAULT_LIST_ROWS;
00121     else if (rows>KEXIDB_LOOKUP_FIELD_MAX_LIST_ROWS)
00122         m_maximumListRows = KEXIDB_LOOKUP_FIELD_MAX_LIST_ROWS;
00123     else
00124         m_maximumListRows = rows;
00125 }
00126 
00127 QString LookupFieldSchema::debugString() const
00128 {
00129     QString columnWidthsStr;
00130     foreach (QValueList<int>::ConstIterator, it, m_columnWidths) {
00131         if (!columnWidthsStr.isEmpty())
00132             columnWidthsStr.append(";");
00133         columnWidthsStr.append( QString::number(*it) );
00134     }
00135 
00136     QString visibleColumnsString;
00137     foreach (QValueList<uint>::ConstIterator, it, m_visibleColumns) {
00138         if (!visibleColumnsString.isEmpty())
00139             visibleColumnsString.append(";");
00140         visibleColumnsString.append(QString::number(*it));
00141     }
00142 
00143     return QString("LookupFieldSchema( %1\n"
00144         " boundColumn:%2 visibleColumns:%3 maximumListRows:%4 displayWidget:%5\n"
00145         " columnHeadersVisible:%6 limitToList:%7\n"
00146         " columnWidths:%8 )")
00147         .arg(m_rowSource.debugString())
00148         .arg(m_boundColumn).arg(visibleColumnsString).arg(m_maximumListRows)
00149         .arg( m_displayWidget==ComboBox ? "ComboBox" : "ListBox")
00150         .arg(m_columnHeadersVisible).arg(m_limitToList)
00151         .arg(columnWidthsStr);
00152 }
00153 
00154 void LookupFieldSchema::debug() const
00155 {
00156     KexiDBDbg << debugString() << endl;
00157 }
00158 
00159 /* static */
00160 LookupFieldSchema *LookupFieldSchema::loadFromDom(const QDomElement& lookupEl)
00161 {
00162     LookupFieldSchema *lookupFieldSchema = new LookupFieldSchema();
00163     for (QDomNode node = lookupEl.firstChild(); !node.isNull(); node = node.nextSibling()) {
00164         QDomElement el = node.toElement();
00165         QString name( el.tagName() );
00166         if (name=="row-source") {
00167             /*<row-source>
00168                 empty
00169                 | <type>table|query|sql|valuelist|fieldlist</type>  #required because there can be table and query with the same name
00170                                     "fieldlist" (basically a list of column names of a table/query,
00171                                               "Field List" as in MSA)
00172                 <name>string</name> #table/query name, etc. or KEXISQL SELECT QUERY
00173                 <values><value>...</value> #for "valuelist" type
00174                     <value>...</value>
00175                 </values>
00176              </row-source> */
00177             for (el = el.firstChild().toElement(); !el.isNull(); el=el.nextSibling().toElement()) {
00178                 if (el.tagName()=="type")
00179                     lookupFieldSchema->rowSource().setTypeByName( el.text() );
00180                 else if (el.tagName()=="name")
00181                     lookupFieldSchema->rowSource().setName( el.text() );
00183             }
00184         }
00185         else if (name=="bound-column") {
00186             /* <bound-column>
00187                 <number>number</number> #in later implementation there can be more columns
00188                </bound-column> */
00189             const QVariant val = KexiDB::loadPropertyValueFromDom( el.firstChild() );
00190             if (val.type()==QVariant::Int)
00191                 lookupFieldSchema->setBoundColumn( val.toInt() );
00192         }
00193         else if (name=="visible-column") {
00194             /* <visible-column> #a column that has to be visible in the combo box
00195                 <number>number 1</number>
00196                 <number>number 2</number>
00197                 [..]
00198                </visible-column> */
00199             QValueList<uint> list;
00200             for (QDomNode childNode = el.firstChild(); !childNode.isNull(); childNode = childNode.nextSibling()) {
00201                 const QVariant val = KexiDB::loadPropertyValueFromDom( childNode );
00202                 if (val.type()==QVariant::Int)
00203                     list.append( val.toUInt() );
00204             }
00205             lookupFieldSchema->setVisibleColumns( list );
00206         }
00207         else if (name=="column-widths") {
00208             /* <column-widths> #column widths, -1 means 'default'
00209                 <number>int</number>
00210                 ...
00211                 <number>int</number>
00212                </column-widths> */
00213             QVariant val;
00214             QValueList<int> columnWidths;
00215             for (el = el.firstChild().toElement(); !el.isNull(); el=el.nextSibling().toElement()) {
00216                 QVariant val = KexiDB::loadPropertyValueFromDom( el );
00217                 if (val.type()==QVariant::Int)
00218                     columnWidths.append(val.toInt());
00219             }
00220             lookupFieldSchema->setColumnWidths( columnWidths );
00221         }
00222         else if (name=="show-column-headers") {
00223             /* <show-column-headers>
00224                 <bool>true/false</bool>
00225                </show-column-headers> */
00226             const QVariant val = KexiDB::loadPropertyValueFromDom( el.firstChild() );
00227             if (val.type()==QVariant::Bool)
00228                 lookupFieldSchema->setColumnHeadersVisible( val.toBool() );
00229         }
00230         else if (name=="list-rows") {
00231             /* <list-rows>
00232                 <number>1..100</number>
00233                </list-rows> */
00234             const QVariant val = KexiDB::loadPropertyValueFromDom( el.firstChild() );
00235             if (val.type()==QVariant::Int)
00236                 lookupFieldSchema->setMaximumListRows( val.toUInt() );
00237         }
00238         else if (name=="limit-to-list") {
00239             /* <limit-to-list>
00240                 <bool>true/false</bool>
00241                </limit-to-list> */
00242             const QVariant val = KexiDB::loadPropertyValueFromDom( el.firstChild() );
00243             if (val.type()==QVariant::Bool)
00244                 lookupFieldSchema->setLimitToList( val.toBool() );
00245         }
00246         else if (name=="display-widget") {
00247             if (el.text()=="combobox")
00248                 lookupFieldSchema->setDisplayWidget( LookupFieldSchema::ComboBox );
00249             else if (el.text()=="listbox")
00250                 lookupFieldSchema->setDisplayWidget( LookupFieldSchema::ListBox );
00251         }
00252     }
00253     return lookupFieldSchema;
00254 }
00255 
00256 /* static */
00257 void LookupFieldSchema::saveToDom(LookupFieldSchema& lookupSchema, QDomDocument& doc, QDomElement& parentEl)
00258 {
00259     QDomElement lookupColumnEl, rowSourceEl, rowSourceTypeEl, nameEl;
00260     if (!lookupSchema.rowSource().name().isEmpty()) {
00261         lookupColumnEl = doc.createElement("lookup-column");
00262         parentEl.appendChild( lookupColumnEl );
00263 
00264         rowSourceEl = doc.createElement("row-source");
00265         lookupColumnEl.appendChild( rowSourceEl );
00266 
00267         rowSourceTypeEl = doc.createElement("type");
00268         rowSourceEl.appendChild( rowSourceTypeEl );
00269         rowSourceTypeEl.appendChild( doc.createTextNode(lookupSchema.rowSource().typeName()) ); //can be empty
00270 
00271         nameEl = doc.createElement("name");
00272         rowSourceEl.appendChild( nameEl );
00273         nameEl.appendChild( doc.createTextNode(lookupSchema.rowSource().name()) );
00274     }
00275 
00276     const QStringList& values( lookupSchema.rowSource().values() );
00277     if (!values.isEmpty()) {
00278         QDomElement valuesEl( doc.createElement("values") );
00279         rowSourceEl.appendChild( valuesEl );
00280         for (QStringList::ConstIterator it = values.constBegin(); it!=values.constEnd(); ++it) {
00281             QDomElement valueEl( doc.createElement("value") );
00282             valuesEl.appendChild( valueEl );
00283             valueEl.appendChild( doc.createTextNode(*it) );
00284         }
00285     }
00286 
00287     if (lookupSchema.boundColumn()>=0)
00288         KexiDB::saveNumberElementToDom(doc, lookupColumnEl, "bound-column", lookupSchema.boundColumn());
00289 
00290     QValueList<uint> visibleColumns(lookupSchema.visibleColumns());
00291     if (!visibleColumns.isEmpty()) {
00292         QDomElement visibleColumnEl( doc.createElement("visible-column") );
00293         lookupColumnEl.appendChild( visibleColumnEl );
00294         foreach (QValueList<uint>::ConstIterator, it, visibleColumns) {
00295             QDomElement numberEl( doc.createElement("number") );
00296             visibleColumnEl.appendChild( numberEl );
00297             numberEl.appendChild( doc.createTextNode( QString::number(*it) ) );
00298         }
00299     }
00300 
00301     const QValueList<int> columnWidths(lookupSchema.columnWidths());
00302     if (!columnWidths.isEmpty()) {
00303         QDomElement columnWidthsEl( doc.createElement("column-widths") );
00304         lookupColumnEl.appendChild( columnWidthsEl );
00305         for (QValueList<int>::ConstIterator it = columnWidths.constBegin(); it!=columnWidths.constEnd(); ++it) {
00306             QDomElement columnWidthEl( doc.createElement("number") );
00307             columnWidthsEl.appendChild( columnWidthEl );
00308             columnWidthEl.appendChild( doc.createTextNode( QString::number(*it) ) );
00309         }
00310     }
00311 
00312     if (lookupSchema.columnHeadersVisible()!=KEXIDB_LOOKUP_FIELD_DEFAULT_HEADERS_VISIBLE)
00313         KexiDB::saveBooleanElementToDom(doc, lookupColumnEl, "show-column-headers", lookupSchema.columnHeadersVisible());
00314     if (lookupSchema.maximumListRows()!=KEXIDB_LOOKUP_FIELD_DEFAULT_LIST_ROWS)
00315         KexiDB::saveNumberElementToDom(doc, lookupColumnEl, "list-rows", lookupSchema.maximumListRows());
00316     if (lookupSchema.limitToList()!=KEXIDB_LOOKUP_FIELD_DEFAULT_LIMIT_TO_LIST)
00317         KexiDB::saveBooleanElementToDom(doc, lookupColumnEl, "limit-to-list", lookupSchema.limitToList());
00318     
00319     if (lookupSchema.displayWidget()!=KEXIDB_LOOKUP_FIELD_DEFAULT_DISPLAY_WIDGET) {
00320         QDomElement displayWidgetEl( doc.createElement("display-widget") );
00321         lookupColumnEl.appendChild( displayWidgetEl );
00322         displayWidgetEl.appendChild( 
00323             doc.createTextNode( (lookupSchema.displayWidget()==ListBox) ? "listbox" : "combobox" ) );
00324     }
00325 }
00326 
00327 //static
00328 bool LookupFieldSchema::setProperty( 
00329     LookupFieldSchema& lookup, const QCString& propertyName, const QVariant& value )
00330 {
00331     bool ok;
00332     if ("rowSource" == propertyName || "rowSourceType" == propertyName || "rowSourceValues" == propertyName) {
00333         LookupFieldSchema::RowSource rowSource( lookup.rowSource() );
00334         if ("rowSource" == propertyName)
00335             rowSource.setName(value.toString());
00336         else if ("rowSourceType" == propertyName)
00337             rowSource.setTypeByName(value.toString());
00338         else if ("rowSourceValues" == propertyName)
00339             rowSource.setValues(value.toStringList());
00340         lookup.setRowSource(rowSource);
00341     }
00342     else if ("boundColumn" == propertyName ) {
00343         const int ival = value.toInt(&ok);
00344         if (!ok)
00345             return false;
00346         lookup.setBoundColumn( ival );
00347     }
00348     else if ("visibleColumn" == propertyName ) {
00349         QValueList<QVariant> variantList;
00350         if (value.type()==QVariant::Int) {
00353             variantList.append( value.toInt() );
00354         }
00355         else {
00356             variantList = value.toList();
00357         }
00358         QValueList<uint> visibleColumns;
00359         foreach (QValueList<QVariant>::ConstIterator, it, variantList) {
00360             const uint ival = (*it).toUInt(&ok);
00361             if (!ok)
00362                 return false;
00363             visibleColumns.append( ival );
00364         }
00365         lookup.setVisibleColumns( visibleColumns );
00366     }
00367     else if ("columnWidths" == propertyName ) {
00368         QValueList<QVariant> variantList( value.toList() );
00369         QValueList<int> widths;
00370         foreach (QValueList<QVariant>::ConstIterator, it, variantList) {
00371             const uint ival = (*it).toInt(&ok);
00372             if (!ok)
00373                 return false;
00374             widths.append( ival );
00375         }
00376         lookup.setColumnWidths( widths );
00377     }
00378     else if ("showColumnHeaders" == propertyName ) {
00379         lookup.setColumnHeadersVisible( value.toBool() );
00380     }
00381     else if ("listRows" == propertyName ) {
00382         lookup.setMaximumListRows( value.toBool() );
00383     }
00384     else if ("limitToList" == propertyName ) {
00385         lookup.setLimitToList( value.toBool() );
00386     }
00387     else if ("displayWidget" == propertyName ) {
00388         const uint ival = value.toUInt(&ok);
00389         if (!ok || ival > LookupFieldSchema::ListBox)
00390             return false;
00391         lookup.setDisplayWidget((LookupFieldSchema::DisplayWidget)ival);
00392     }
00393     return true;
00394 }
KDE Home | KDE Accessibility Home | Description of Access Keys