kexi
kexidataprovider.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kexidataprovider.h"
00021
00022 #include <qwidget.h>
00023 #include <qobjectlist.h>
00024
00025 #include <kdebug.h>
00026 #include <klocale.h>
00027
00028 #include <widget/tableview/kexitableitem.h>
00029 #include <widget/tableview/kexitableviewdata.h>
00030 #include <widget/tableview/kexicomboboxbase.h>
00031 #include <kexidb/queryschema.h>
00032 #include <kexiutils/utils.h>
00033
00034 #include "widgets/kexidbform.h"
00035
00036 KexiFormDataProvider::KexiFormDataProvider()
00037 : KexiDataItemChangesListener()
00038 , m_mainWidget(0)
00039 , m_duplicatedItems(0)
00040 , m_disableFillDuplicatedDataItems(false)
00041 {
00042 }
00043
00044 KexiFormDataProvider::~KexiFormDataProvider()
00045 {
00046 delete m_duplicatedItems;
00047 }
00048
00049 void KexiFormDataProvider::setMainDataSourceWidget(QWidget* mainWidget)
00050 {
00051 m_mainWidget = mainWidget;
00052 m_dataItems.clear();
00053 m_usedDataSources.clear();
00054 m_fieldNumbersForDataItems.clear();
00055 if (!m_mainWidget)
00056 return;
00057
00058
00059 QObjectList *l = m_mainWidget->queryList( "QWidget" );
00060 QObjectListIt it( *l );
00061 QObject *obj;
00062 QDict<char> tmpSources;
00063 for ( ; (obj = it.current()) != 0; ++it ) {
00064 KexiFormDataItemInterface* const formDataItem = dynamic_cast<KexiFormDataItemInterface*>(obj);
00065 if (!formDataItem)
00066 continue;
00067 if (formDataItem->parentInterface())
00068 continue;
00069 #if 0
00070 KexiDBForm *dbForm = KexiUtils::findParent<KexiDBForm>(obj, "KexiDBForm"); //form's surface...
00071 if (dbForm!=m_mainWidget)
00072 continue;
00073 #else
00074
00075 if (KexiUtils::findParent<KexiDBForm>(obj, "KexiDBSubForm"))
00076 continue;
00077 #endif
00078 QString dataSource( formDataItem->dataSource().lower() );
00079 if (dataSource.isEmpty())
00080 continue;
00081 kexipluginsdbg << obj->name() << endl;
00082 m_dataItems.append( formDataItem );
00083 formDataItem->installListener( this );
00084 tmpSources.replace( dataSource, (char*)1 );
00085 }
00086 delete l;
00087
00088
00089 for (QDictIterator<char> it(tmpSources); it.current(); ++it) {
00090 m_usedDataSources += it.currentKey();
00091 }
00092 }
00093
00094 void KexiFormDataProvider::fillDataItems(KexiTableItem& row, bool cursorAtNewRow)
00095 {
00096 kexipluginsdbg << "KexiFormDataProvider::fillDataItems() cnt=" << row.count() << endl;
00097 for (KexiFormDataItemInterfaceToIntMap::ConstIterator it = m_fieldNumbersForDataItems.constBegin();
00098 it!=m_fieldNumbersForDataItems.constEnd(); ++it)
00099 {
00100 KexiFormDataItemInterface *itemIface = it.key();
00101 if (!itemIface->columnInfo()) {
00102 kexipluginsdbg << "KexiFormDataProvider::fillDataItems(): itemIface->columnInfo() == 0" << endl;
00103 continue;
00104 }
00105
00106 int indexForVisibleLookupValue = itemIface->columnInfo()->indexForVisibleLookupValue();
00107 if (indexForVisibleLookupValue<0 && indexForVisibleLookupValue>=(int)row.count())
00108 indexForVisibleLookupValue = -1;
00109 const QVariant value(row.at(it.data()));
00110 QVariant visibleLookupValue;
00111 if (indexForVisibleLookupValue!=-1)
00112 visibleLookupValue = row.at(indexForVisibleLookupValue);
00113 kexipluginsdbg << "fill data of '" << itemIface->dataSource() << "' at idx=" << it.data()
00114 << " data=" << value << (indexForVisibleLookupValue!=-1
00115 ? QString(" SPECIAL: indexForVisibleLookupValue=%1 visibleValue=%2")
00116 .arg(indexForVisibleLookupValue).arg(visibleLookupValue.toString())
00117 : QString::null)
00118 << endl;
00119 const bool displayDefaultValue = cursorAtNewRow && (value.isNull() && visibleLookupValue.isNull())
00120 && !itemIface->columnInfo()->field->defaultValue().isNull()
00121 && !itemIface->columnInfo()->field->isAutoIncrement();
00122 itemIface->setValue(
00123 displayDefaultValue ? itemIface->columnInfo()->field->defaultValue() : value,
00124 QVariant(), false,
00126 indexForVisibleLookupValue==-1 ? 0 : &visibleLookupValue
00127 );
00128
00129 if (itemIface->hasDisplayedDefaultValue() != displayDefaultValue)
00130 itemIface->setDisplayDefaultValue( dynamic_cast<QWidget*>(itemIface), displayDefaultValue );
00131 }
00132 }
00133
00134 void KexiFormDataProvider::fillDuplicatedDataItems(
00135 KexiFormDataItemInterface* item, const QVariant& value)
00136 {
00137 if (m_disableFillDuplicatedDataItems)
00138 return;
00139 if (!m_duplicatedItems) {
00140
00141
00142 QMap<KexiDB::Field*,int> tmpDuplicatedItems;
00143 QMapIterator<KexiDB::Field*,int> it_dup;
00144 for (QPtrListIterator<KexiFormDataItemInterface> it(m_dataItems); it.current(); ++it) {
00145 if (!it.current()->columnInfo() || !it.current()->columnInfo()->field)
00146 continue;
00147 kdDebug() << " ** " << it.current()->columnInfo()->field->name() << endl;
00148 it_dup = tmpDuplicatedItems.find( it.current()->columnInfo()->field );
00149 uint count;
00150 if (it_dup==tmpDuplicatedItems.end())
00151 count = 0;
00152 else
00153 count = it_dup.data();
00154 tmpDuplicatedItems.insert( it.current()->columnInfo()->field, ++count );
00155 }
00156 m_duplicatedItems = new QPtrDict<char>(101);
00157 for (it_dup = tmpDuplicatedItems.begin(); it_dup!=tmpDuplicatedItems.end(); ++it_dup) {
00158 if (it_dup.data() > 1) {
00159 m_duplicatedItems->insert( it_dup.key(), (char*)1 );
00160 kexipluginsdbg << "duplicated item: " << static_cast<KexiDB::Field*>(it_dup.key())->name()
00161 << " (" << it_dup.data() << " times)" << endl;
00162 }
00163 }
00164 }
00165 if (item->columnInfo() && m_duplicatedItems->find( item->columnInfo()->field )) {
00166 for (QPtrListIterator<KexiFormDataItemInterface> it(m_dataItems); it.current(); ++it) {
00167 if (it.current()!=item && item->columnInfo()->field == it.current()->columnInfo()->field) {
00168 kexipluginsdbg << "- setting a copy of value for item '"
00169 << dynamic_cast<QObject*>(it.current())->name() << "' == " << value << endl;
00170 it.current()->setValue( value );
00171 }
00172 }
00173 }
00174 }
00175
00176 void KexiFormDataProvider::valueChanged(KexiDataItemInterface* item)
00177 {
00178 Q_UNUSED( item );
00179 }
00180
00181 bool KexiFormDataProvider::cursorAtNewRow() const
00182 {
00183 return false;
00184 }
00185
00186 void KexiFormDataProvider::invalidateDataSources( const QDict<char>& invalidSources,
00187 KexiDB::QuerySchema* query)
00188 {
00189
00190
00191 KexiDB::QueryColumnInfo::Vector fieldsExpanded;
00192
00193
00194 if (query) {
00195 fieldsExpanded = query->fieldsExpanded( KexiDB::QuerySchema::WithInternalFields );
00196
00197 QMap<KexiDB::QueryColumnInfo*,int> columnsOrder( query->columnsOrder() );
00198 for (QMapConstIterator<KexiDB::QueryColumnInfo*,int> it = columnsOrder.constBegin(); it!=columnsOrder.constEnd(); ++it) {
00199 kexipluginsdbg << "query->columnsOrder()[ " << it.key()->field->name() << " ] = " << it.data() << endl;
00200 }
00201 for (QPtrListIterator<KexiFormDataItemInterface> it(m_dataItems); it.current(); ++it) {
00202 KexiFormDataItemInterface *item = it.current();
00203 KexiDB::QueryColumnInfo* ci = query->columnInfo( it.current()->dataSource() );
00204 int index = ci ? columnsOrder[ ci ] : -1;
00205 kexipluginsdbg << "query->columnsOrder()[ " << (ci ? ci->field->name() : "") << " ] = " << index
00206 << " (dataSource: " << item->dataSource() << ", name=" << dynamic_cast<QObject*>(item)->name() << ")" << endl;
00207 if (index!=-1 && !m_fieldNumbersForDataItems[ item ])
00208 m_fieldNumbersForDataItems.insert( item, index );
00209
00210
00211
00212
00213 }
00214 }
00215 else {
00216
00217 }
00218
00219 #if 0 //moved down
00220
00221 foreach(QValueList<uint>::ConstIterator, it, invalidSources) {
00222
00223
00224
00225
00226
00227
00228
00229 KexiFormDataItemInterface *item = m_dataItems.at( *it );
00230 if (item)
00231 item->setInvalidState( QString::fromLatin1("#") + i18n("NAME") + QString::fromLatin1("?") );
00232 m_dataItems.remove(*it);
00233 kexipluginsdbg << "invalidateDataSources(): " << (*it) << " -> " << -1 << endl;
00234
00235 }
00236 #endif
00237
00238
00239
00240
00241
00242
00243 #if 0
00244
00245 KexiFormDataItemInterfaceToIntMap newFieldNumbersForDataItems;
00246 foreach(KexiFormDataItemInterfaceToIntMap::ConstIterator, it, m_fieldNumbersForDataItems) {
00247 bool ok;
00248 const int newIndex = newIndices.at( it.data(), &ok );
00249 if (ok && newIndex!=-1) {
00250 kexipluginsdbg << "invalidateDataSources(): " << it.key()->dataSource() << ": " << it.data() << " -> " << newIndex << endl;
00251 newFieldNumbersForDataItems.replace(it.key(), newIndex);
00252 }
00253 else {
00254 kexipluginsdbg << "invalidateDataSources(): removing " << it.key()->dataSource() << endl;
00255 m_dataItems.remove(it.key());
00256 it.key()->setInvalidState( QString::fromLatin1("#") + i18n("NAME") + QString::fromLatin1("?") );
00257 }
00258 }
00259 #endif
00260
00261
00262
00263 QDict<char> tmpUsedDataSources(1013);
00264
00265 if (query)
00266 query->debug();
00267
00268
00269
00270
00271
00272
00273 m_disableFillDuplicatedDataItems = true;
00274
00275 for (QPtrListIterator<KexiFormDataItemInterface> it(m_dataItems); it.current();) {
00276 KexiFormDataItemInterface * item = it.current();
00277 if (invalidSources[ item->dataSource().lower() ]) {
00278 item->setInvalidState( QString::fromLatin1("#") + i18n("NAME") + QString::fromLatin1("?") );
00279 m_dataItems.remove(item);
00280 continue;
00281 }
00282 uint fieldNumber = m_fieldNumbersForDataItems[ item ];
00283 if (query) {
00284 KexiDB::QueryColumnInfo *ci = fieldsExpanded[fieldNumber];
00285 item->setColumnInfo(ci);
00286 kexipluginsdbg << "- item=" << dynamic_cast<QObject*>(item)->name()
00287 << " dataSource=" << item->dataSource()
00288 << " field=" << ci->field->name() << endl;
00289 const int indexForVisibleLookupValue = ci->indexForVisibleLookupValue();
00290 if (-1 != indexForVisibleLookupValue && indexForVisibleLookupValue < (int)fieldsExpanded.count()) {
00291
00292 KexiDB::QueryColumnInfo *visibleColumnInfo = fieldsExpanded[ indexForVisibleLookupValue ];
00293 if (visibleColumnInfo) {
00294 item->setVisibleColumnInfo( visibleColumnInfo );
00295 if (dynamic_cast<KexiComboBoxBase*>(item) && m_mainWidget
00296 && dynamic_cast<KexiComboBoxBase*>(item)->internalEditor()) {
00297
00298
00299 dynamic_cast<KexiComboBoxBase*>(item)->internalEditor()->installEventFilter(m_mainWidget);
00300 }
00301 kexipluginsdbg << " ALSO SET visibleColumn=" << visibleColumnInfo->debugString()
00302 << "\n at position " << indexForVisibleLookupValue << endl;
00303 }
00304 }
00305 }
00306 tmpUsedDataSources.replace( item->dataSource().lower(), (char*)1 );
00307 ++it;
00308 }
00309 m_disableFillDuplicatedDataItems = false;
00310 m_usedDataSources.clear();
00311 foreach_list(QDictIterator<char>, it, tmpUsedDataSources) {
00312 m_usedDataSources += it.currentKey();
00313 }
00314 }
|