/* This file is part of the KDE project Copyright (C) 2006-2007 Jaroslaw Staniek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "lookupfieldschema.h" #include "utils.h" #include #include #include using namespace KexiDB; LookupFieldSchema::RowSource::RowSource() : m_type(NoType) , m_values(0) { } LookupFieldSchema::RowSource::~RowSource() { delete m_values; } void LookupFieldSchema::RowSource::setName(const TQString& name) { m_name = name; if (m_values) m_values->clear(); } TQString LookupFieldSchema::RowSource::typeName() const { switch (m_type) { case Table: return "table"; case Query: return "query"; case SQLStatement: return "sql"; case ValueList: return "valuelist"; case FieldList: return "fieldlist"; default:; } return TQString(); } void LookupFieldSchema::RowSource::setTypeByName( const TQString& typeName ) { if (typeName=="table") setType( Table ); else if (typeName=="query") setType( Query ); else if (typeName=="sql") setType( SQLStatement ); else if (typeName=="valuelist") setType( ValueList ); else if (typeName=="fieldlist") setType( FieldList ); else setType( NoType ); } TQStringList LookupFieldSchema::RowSource::values() const { return m_values ? *m_values : TQStringList(); } void LookupFieldSchema::RowSource::setValues(const TQStringList& values) { m_name = TQString(); if (m_values) *m_values = values; else m_values = new TQStringList(values); } TQString LookupFieldSchema::RowSource::debugString() const { return TQString("rowSourceType:'%1' rowSourceName:'%2' rowSourceValues:'%3'\n") .arg(typeName()).arg(name()).arg(m_values ? m_values->join("|") : TQString()); } void LookupFieldSchema::RowSource::debug() const { KexiDBDbg << debugString() << endl; } //--------------------------------------- LookupFieldSchema::LookupFieldSchema() : m_boundColumn(-1) , m_maximumListRows(KEXIDB_LOOKUP_FIELD_DEFAULT_LIST_ROWS) , m_displayWidget(KEXIDB_LOOKUP_FIELD_DEFAULT_DISPLAY_WIDGET) , m_columnHeadersVisible(KEXIDB_LOOKUP_FIELD_DEFAULT_HEADERS_VISIBLE) , m_limitToList(KEXIDB_LOOKUP_FIELD_DEFAULT_LIMIT_TO_LIST) { } LookupFieldSchema::~LookupFieldSchema() { } void LookupFieldSchema::setMaximumListRows(uint rows) { if (rows==0) m_maximumListRows = KEXIDB_LOOKUP_FIELD_DEFAULT_LIST_ROWS; else if (rows>KEXIDB_LOOKUP_FIELD_MAX_LIST_ROWS) m_maximumListRows = KEXIDB_LOOKUP_FIELD_MAX_LIST_ROWS; else m_maximumListRows = rows; } TQString LookupFieldSchema::debugString() const { TQString columnWidthsStr; foreach (TQValueList::ConstIterator, it, m_columnWidths) { if (!columnWidthsStr.isEmpty()) columnWidthsStr.append(";"); columnWidthsStr.append( TQString::number(*it) ); } TQString visibleColumnsString; foreach (TQValueList::ConstIterator, it, m_visibleColumns) { if (!visibleColumnsString.isEmpty()) visibleColumnsString.append(";"); visibleColumnsString.append(TQString::number(*it)); } return TQString("LookupFieldSchema( %1\n" " boundColumn:%2 visibleColumns:%3 maximumListRows:%4 displayWidget:%5\n" " columnHeadersVisible:%6 limitToList:%7\n" " columnWidths:%8 )") .arg(m_rowSource.debugString()) .arg(m_boundColumn).arg(visibleColumnsString).arg(m_maximumListRows) .arg( m_displayWidget==ComboBox ? "ComboBox" : "ListBox") .arg(m_columnHeadersVisible).arg(m_limitToList) .arg(columnWidthsStr); } void LookupFieldSchema::debug() const { KexiDBDbg << debugString() << endl; } /* static */ LookupFieldSchema *LookupFieldSchema::loadFromDom(const TQDomElement& lookupEl) { LookupFieldSchema *lookupFieldSchema = new LookupFieldSchema(); for (TQDomNode node = lookupEl.firstChild(); !node.isNull(); node = node.nextSibling()) { TQDomElement el = node.toElement(); TQString name( el.tagName() ); if (name=="row-source") { /* empty | table|query|sql|valuelist|fieldlist #required because there can be table and query with the same name "fieldlist" (basically a list of column names of a table/query, "Field List" as in MSA) string #table/query name, etc. or KEXISQL SELECT TQUERY ... #for "valuelist" type ... */ for (el = el.firstChild().toElement(); !el.isNull(); el=el.nextSibling().toElement()) { if (el.tagName()=="type") lookupFieldSchema->rowSource().setTypeByName( el.text() ); else if (el.tagName()=="name") lookupFieldSchema->rowSource().setName( el.text() ); //! @todo handle fieldlist (retrieve from external table or so?), use lookupFieldSchema.rowSource().setValues() } } else if (name=="bound-column") { /* number #in later implementation there can be more columns */ const TQVariant val = KexiDB::loadPropertyValueFromDom( el.firstChild() ); if (val.type()==TQVariant::Int) lookupFieldSchema->setBoundColumn( val.toInt() ); } else if (name=="visible-column") { /* #a column that has to be visible in the combo box number 1 number 2 [..] */ TQValueList list; for (TQDomNode childNode = el.firstChild(); !childNode.isNull(); childNode = childNode.nextSibling()) { const TQVariant val = KexiDB::loadPropertyValueFromDom( childNode ); if (val.type()==TQVariant::Int) list.append( val.toUInt() ); } lookupFieldSchema->setVisibleColumns( list ); } else if (name=="column-widths") { /* #column widths, -1 means 'default' int ... int */ TQVariant val; TQValueList columnWidths; for (el = el.firstChild().toElement(); !el.isNull(); el=el.nextSibling().toElement()) { TQVariant val = KexiDB::loadPropertyValueFromDom( el ); if (val.type()==TQVariant::Int) columnWidths.append(val.toInt()); } lookupFieldSchema->setColumnWidths( columnWidths ); } else if (name=="show-column-headers") { /* true/false */ const TQVariant val = KexiDB::loadPropertyValueFromDom( el.firstChild() ); if (val.type()==TQVariant::Bool) lookupFieldSchema->setColumnHeadersVisible( val.toBool() ); } else if (name=="list-rows") { /* 1..100 */ const TQVariant val = KexiDB::loadPropertyValueFromDom( el.firstChild() ); if (val.type()==TQVariant::Int) lookupFieldSchema->setMaximumListRows( val.toUInt() ); } else if (name=="limit-to-list") { /* true/false */ const TQVariant val = KexiDB::loadPropertyValueFromDom( el.firstChild() ); if (val.type()==TQVariant::Bool) lookupFieldSchema->setLimitToList( val.toBool() ); } else if (name=="display-widget") { if (el.text()=="combobox") lookupFieldSchema->setDisplayWidget( LookupFieldSchema::ComboBox ); else if (el.text()=="listbox") lookupFieldSchema->setDisplayWidget( LookupFieldSchema::ListBox ); } } return lookupFieldSchema; } /* static */ void LookupFieldSchema::saveToDom(LookupFieldSchema& lookupSchema, TQDomDocument& doc, TQDomElement& parentEl) { TQDomElement lookupColumnEl, rowSourceEl, rowSourceTypeEl, nameEl; if (!lookupSchema.rowSource().name().isEmpty()) { lookupColumnEl = doc.createElement("lookup-column"); parentEl.appendChild( lookupColumnEl ); rowSourceEl = doc.createElement("row-source"); lookupColumnEl.appendChild( rowSourceEl ); rowSourceTypeEl = doc.createElement("type"); rowSourceEl.appendChild( rowSourceTypeEl ); rowSourceTypeEl.appendChild( doc.createTextNode(lookupSchema.rowSource().typeName()) ); //can be empty nameEl = doc.createElement("name"); rowSourceEl.appendChild( nameEl ); nameEl.appendChild( doc.createTextNode(lookupSchema.rowSource().name()) ); } const TQStringList& values( lookupSchema.rowSource().values() ); if (!values.isEmpty()) { TQDomElement valuesEl( doc.createElement("values") ); rowSourceEl.appendChild( valuesEl ); for (TQStringList::ConstIterator it = values.constBegin(); it!=values.constEnd(); ++it) { TQDomElement valueEl( doc.createElement("value") ); valuesEl.appendChild( valueEl ); valueEl.appendChild( doc.createTextNode(*it) ); } } if (lookupSchema.boundColumn()>=0) KexiDB::saveNumberElementToDom(doc, lookupColumnEl, "bound-column", lookupSchema.boundColumn()); TQValueList visibleColumns(lookupSchema.visibleColumns()); if (!visibleColumns.isEmpty()) { TQDomElement visibleColumnEl( doc.createElement("visible-column") ); lookupColumnEl.appendChild( visibleColumnEl ); foreach (TQValueList::ConstIterator, it, visibleColumns) { TQDomElement numberEl( doc.createElement("number") ); visibleColumnEl.appendChild( numberEl ); numberEl.appendChild( doc.createTextNode( TQString::number(*it) ) ); } } const TQValueList columnWidths(lookupSchema.columnWidths()); if (!columnWidths.isEmpty()) { TQDomElement columnWidthsEl( doc.createElement("column-widths") ); lookupColumnEl.appendChild( columnWidthsEl ); for (TQValueList::ConstIterator it = columnWidths.constBegin(); it!=columnWidths.constEnd(); ++it) { TQDomElement columnWidthEl( doc.createElement("number") ); columnWidthsEl.appendChild( columnWidthEl ); columnWidthEl.appendChild( doc.createTextNode( TQString::number(*it) ) ); } } if (lookupSchema.columnHeadersVisible()!=KEXIDB_LOOKUP_FIELD_DEFAULT_HEADERS_VISIBLE) KexiDB::saveBooleanElementToDom(doc, lookupColumnEl, "show-column-headers", lookupSchema.columnHeadersVisible()); if (lookupSchema.maximumListRows()!=KEXIDB_LOOKUP_FIELD_DEFAULT_LIST_ROWS) KexiDB::saveNumberElementToDom(doc, lookupColumnEl, "list-rows", lookupSchema.maximumListRows()); if (lookupSchema.limitToList()!=KEXIDB_LOOKUP_FIELD_DEFAULT_LIMIT_TO_LIST) KexiDB::saveBooleanElementToDom(doc, lookupColumnEl, "limit-to-list", lookupSchema.limitToList()); if (lookupSchema.displayWidget()!=KEXIDB_LOOKUP_FIELD_DEFAULT_DISPLAY_WIDGET) { TQDomElement displayWidgetEl( doc.createElement("display-widget") ); lookupColumnEl.appendChild( displayWidgetEl ); displayWidgetEl.appendChild( doc.createTextNode( (lookupSchema.displayWidget()==ListBox) ? "listbox" : "combobox" ) ); } } //static bool LookupFieldSchema::setProperty( LookupFieldSchema& lookup, const TQCString& propertyName, const TQVariant& value ) { bool ok; if ("rowSource" == propertyName || "rowSourceType" == propertyName || "rowSourceValues" == propertyName) { LookupFieldSchema::RowSource rowSource( lookup.rowSource() ); if ("rowSource" == propertyName) rowSource.setName(value.toString()); else if ("rowSourceType" == propertyName) rowSource.setTypeByName(value.toString()); else if ("rowSourceValues" == propertyName) rowSource.setValues(value.toStringList()); lookup.setRowSource(rowSource); } else if ("boundColumn" == propertyName ) { const int ival = value.toInt(&ok); if (!ok) return false; lookup.setBoundColumn( ival ); } else if ("visibleColumn" == propertyName ) { TQValueList variantList; if (value.type()==TQVariant::Int) { //! @todo Remove this case: it's for backward compatibility with Kexi's 1.1.2 table designer GUI //! supporting only single lookup column. variantList.append( value.toInt() ); } else { variantList = value.toList(); } TQValueList visibleColumns; foreach (TQValueList::ConstIterator, it, variantList) { const uint ival = (*it).toUInt(&ok); if (!ok) return false; visibleColumns.append( ival ); } lookup.setVisibleColumns( visibleColumns ); } else if ("columnWidths" == propertyName ) { TQValueList variantList( value.toList() ); TQValueList widths; foreach (TQValueList::ConstIterator, it, variantList) { const uint ival = (*it).toInt(&ok); if (!ok) return false; widths.append( ival ); } lookup.setColumnWidths( widths ); } else if ("showColumnHeaders" == propertyName ) { lookup.setColumnHeadersVisible( value.toBool() ); } else if ("listRows" == propertyName ) { lookup.setMaximumListRows( value.toBool() ); } else if ("limitToList" == propertyName ) { lookup.setLimitToList( value.toBool() ); } else if ("displayWidget" == propertyName ) { const uint ival = value.toUInt(&ok); if (!ok || ival > LookupFieldSchema::ListBox) return false; lookup.setDisplayWidget((LookupFieldSchema::DisplayWidget)ival); } return true; }