00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "kexitableviewdata.h"
00026
00027 #include <kexiutils/validator.h>
00028
00029 #include <kexidb/field.h>
00030 #include <kexidb/queryschema.h>
00031 #include <kexidb/roweditbuffer.h>
00032 #include <kexidb/cursor.h>
00033 #include <kexidb/utils.h>
00034 #include <kexi.h>
00035
00036 #include <kdebug.h>
00037 #include <klocale.h>
00038
00039 #include <qapplication.h>
00040
00041 unsigned short KexiTableViewData::charTable[]=
00042 {
00043 #include "chartable.txt"
00044 };
00045
00046 KexiTableViewColumn::KexiTableViewColumn(KexiDB::Field& f, bool owner)
00047 : columnInfo(0)
00048 , visibleLookupColumnInfo(0)
00049 , m_field(&f)
00050 {
00051 isDBAware = false;
00052 m_fieldOwned = owner;
00053 m_captionAliasOrName = m_field->captionOrName();
00054 init();
00055 }
00056
00057 KexiTableViewColumn::KexiTableViewColumn(const QString& name, KexiDB::Field::Type ctype,
00058 uint cconst,
00059 uint options,
00060 uint length, uint precision,
00061 QVariant defaultValue,
00062 const QString& caption, const QString& description, uint width
00063 )
00064 : columnInfo(0)
00065 , visibleLookupColumnInfo(0)
00066 {
00067 m_field = new KexiDB::Field(
00068 name, ctype,
00069 cconst,
00070 options,
00071 length, precision,
00072 defaultValue,
00073 caption, description, width);
00074
00075 isDBAware = false;
00076 m_fieldOwned = true;
00077 m_captionAliasOrName = m_field->captionOrName();
00078 init();
00079 }
00080
00081 KexiTableViewColumn::KexiTableViewColumn(const QString& name, KexiDB::Field::Type ctype, const QString& caption,
00082 const QString& description)
00083 : columnInfo(0)
00084 , visibleLookupColumnInfo(0)
00085 {
00086 m_field = new KexiDB::Field(
00087 name, ctype,
00088 KexiDB::Field::NoConstraints,
00089 KexiDB::Field::NoOptions,
00090 0, 0,
00091 QVariant(),
00092 caption, description);
00093
00094 isDBAware = false;
00095 m_fieldOwned = true;
00096 m_captionAliasOrName = m_field->captionOrName();
00097 init();
00098 }
00099
00100
00101 KexiTableViewColumn::KexiTableViewColumn(
00102 const KexiDB::QuerySchema &query, KexiDB::QueryColumnInfo& aColumnInfo,
00103 KexiDB::QueryColumnInfo* aVisibleLookupColumnInfo)
00104 : columnInfo(&aColumnInfo)
00105 , visibleLookupColumnInfo(aVisibleLookupColumnInfo)
00106 , m_field(aColumnInfo.field)
00107 {
00108 isDBAware = true;
00109 m_fieldOwned = false;
00110
00111
00112 if (!columnInfo->field->caption().isEmpty()) {
00113 m_captionAliasOrName = columnInfo->field->caption();
00114 }
00115 else {
00116
00117 m_captionAliasOrName = columnInfo->alias;
00118
00119 if (m_captionAliasOrName.isEmpty())
00120 m_captionAliasOrName = columnInfo->field->name();
00121
00122 }
00123 init();
00124
00125
00126 m_readOnly = (query.masterTable()!=columnInfo->field->table())
00127 || (query.connection() && query.connection()->isReadOnly());
00128
00129
00130
00131
00132
00133 }
00134
00135 KexiTableViewColumn::KexiTableViewColumn(bool)
00136 : columnInfo(0)
00137 , visibleLookupColumnInfo(0)
00138 , m_field(0)
00139 {
00140 isDBAware = false;
00141 init();
00142 }
00143
00144 KexiTableViewColumn::~KexiTableViewColumn()
00145 {
00146 if (m_fieldOwned)
00147 delete m_field;
00148 setValidator( 0 );
00149 delete m_relatedData;
00150 }
00151
00152 void KexiTableViewColumn::init()
00153 {
00154 m_relatedData = 0;
00155 m_readOnly = false;
00156 m_visible = true;
00157 m_data = 0;
00158 m_validator = 0;
00159 m_relatedDataEditable = false;
00160 m_headerTextVisible = true;
00161 }
00162
00163 void KexiTableViewColumn::setValidator( KexiUtils::Validator* v )
00164 {
00165 if (m_validator) {
00166 if (!m_validator->parent())
00167 delete m_validator;
00168 }
00169 m_validator = v;
00170 }
00171
00172 void KexiTableViewColumn::setRelatedData(KexiTableViewData *data)
00173 {
00174 if (isDBAware)
00175 return;
00176 if (m_relatedData)
00177 delete m_relatedData;
00178 m_relatedData = 0;
00179 if (!data)
00180 return;
00181
00182 KexiTableViewColumn::ListIterator it( data->columns );
00183 for (int id = 0;it.current();++it, id++) {
00184 if (it.current()->field()->isPrimaryKey()) {
00185
00186 m_relatedDataPKeyID = id;
00187 m_relatedData = data;
00188 return;
00189 }
00190 }
00191 }
00192
00193 void KexiTableViewColumn::setRelatedDataEditable(bool set)
00194 {
00195 m_relatedDataEditable = set;
00196 }
00197
00198 bool KexiTableViewColumn::acceptsFirstChar(const QChar& ch) const
00199 {
00200
00201
00202 KexiDB::Field *visibleField = visibleLookupColumnInfo
00203 ? visibleLookupColumnInfo->field : m_field;
00204 if (visibleField->isNumericType()) {
00205 if (ch=='.' || ch==',')
00206 return visibleField->isFPNumericType();
00207 if (ch=='-')
00208 return !visibleField->isUnsigned();
00209 if (ch=='+' || (ch>='0' && ch<='9'))
00210 return true;
00211 return false;
00212 }
00213
00214 switch (visibleField->type()) {
00215 case KexiDB::Field::Boolean:
00216 return false;
00217 case KexiDB::Field::Date:
00218 case KexiDB::Field::DateTime:
00219 case KexiDB::Field::Time:
00220 return ch>='0' && ch<='9';
00221 default:;
00222 }
00223 return true;
00224 }
00225
00226
00227
00228
00229 KexiTableViewData::KexiTableViewData()
00230 : QObject()
00231 , KexiTableViewDataBase()
00232 {
00233 init();
00234 }
00235
00236
00237 KexiTableViewData::KexiTableViewData(KexiDB::Cursor *c)
00238 : QObject()
00239 , KexiTableViewDataBase()
00240 {
00241 init();
00242 m_cursor = c;
00243 m_containsROWIDInfo = m_cursor->containsROWIDInfo();
00244 if (m_cursor && m_cursor->query()) {
00245 const KexiDB::QuerySchema::FieldsExpandedOptions fieldsExpandedOptions
00246 = m_containsROWIDInfo ? KexiDB::QuerySchema::WithInternalFieldsAndRowID
00247 : KexiDB::QuerySchema::WithInternalFields;
00248 m_itemSize = m_cursor->query()->fieldsExpanded( fieldsExpandedOptions ).count();
00249 }
00250 else
00251 m_itemSize = columns.count()+(m_containsROWIDInfo?1:0);
00252
00253
00254 const KexiDB::QueryColumnInfo::Vector fields = m_cursor->query()->fieldsExpanded();
00255 const uint fieldsCount = fields.count();
00256 for (uint i=0;i < fieldsCount;i++) {
00257 KexiDB::QueryColumnInfo *ci = fields[i];
00258 if (ci->visible) {
00259 KexiDB::QueryColumnInfo *visibleLookupColumnInfo = 0;
00260 if (ci->indexForVisibleLookupValue() != -1) {
00261
00262 visibleLookupColumnInfo = m_cursor->query()->expandedOrInternalField( ci->indexForVisibleLookupValue() );
00263
00264
00265
00266
00267 }
00268 KexiTableViewColumn* col = new KexiTableViewColumn(*m_cursor->query(), *ci, visibleLookupColumnInfo);
00269 addColumn( col );
00270 }
00271 }
00272 }
00273
00274 KexiTableViewData::KexiTableViewData(
00275 const QValueList<QVariant> &keys, const QValueList<QVariant> &values,
00276 KexiDB::Field::Type keyType, KexiDB::Field::Type valueType)
00277 : QObject()
00278 , KexiTableViewDataBase()
00279 {
00280 init(keys, values, keyType, valueType);
00281 }
00282
00283 KexiTableViewData::KexiTableViewData(
00284 KexiDB::Field::Type keyType, KexiDB::Field::Type valueType)
00285 {
00286 const QValueList<QVariant> empty;
00287 init(empty, empty, keyType, valueType);
00288 }
00289
00290 KexiTableViewData::~KexiTableViewData()
00291 {
00292 emit destroying();
00293 clearInternal();
00294 }
00295
00296 void KexiTableViewData::init(
00297 const QValueList<QVariant> &keys, const QValueList<QVariant> &values,
00298 KexiDB::Field::Type keyType, KexiDB::Field::Type valueType)
00299 {
00300 init();
00301 KexiDB::Field *keyField = new KexiDB::Field("key", keyType);
00302 keyField->setPrimaryKey(true);
00303 KexiTableViewColumn *keyColumn = new KexiTableViewColumn(*keyField, true);
00304 keyColumn->setVisible(false);
00305 addColumn(keyColumn);
00306
00307 KexiDB::Field *valueField = new KexiDB::Field("value", valueType);
00308 KexiTableViewColumn *valueColumn = new KexiTableViewColumn(*valueField, true);
00309 addColumn(valueColumn);
00310
00311 uint cnt = QMIN(keys.count(), values.count());
00312 QValueList<QVariant>::ConstIterator it_keys = keys.constBegin();
00313 QValueList<QVariant>::ConstIterator it_values = values.constBegin();
00314 for (;cnt>0;++it_keys, ++it_values, cnt--) {
00315 KexiTableItem *item = new KexiTableItem(2);
00316 (*item)[0] = (*it_keys);
00317 (*item)[1] = (*it_values);
00318 append( item );
00319 }
00320 }
00321
00322 void KexiTableViewData::init()
00323 {
00324 m_sortedColumn = 0;
00325 m_realSortedColumn = 0;
00326
00327 m_order = 0;
00328 m_type = 1;
00329 m_pRowEditBuffer = 0;
00330 m_cursor = 0;
00331 m_readOnly = false;
00332 m_insertingEnabled = true;
00333
00334 setAutoDelete(true);
00335 columns.setAutoDelete(true);
00336 m_visibleColumnsCount=0;
00337 m_visibleColumnsIDs.resize(100);
00338 m_globalColumnsIDs.resize(100);
00339
00340 m_autoIncrementedColumn = -2;
00341 m_containsROWIDInfo = false;
00342 m_itemSize = 0;
00343 }
00344
00345 void KexiTableViewData::deleteLater()
00346 {
00347 m_cursor = 0;
00348 QObject::deleteLater();
00349 }
00350
00351 void KexiTableViewData::addColumn( KexiTableViewColumn* col )
00352 {
00353
00354
00355
00356
00357
00358 columns.append( col );
00359 col->m_data = this;
00360 if (m_globalColumnsIDs.size() < columns.count()) {
00361 m_globalColumnsIDs.resize( m_globalColumnsIDs.size()*2 );
00362 }
00363 if (col->visible()) {
00364 m_visibleColumnsCount++;
00365 if (m_visibleColumnsIDs.size() < m_visibleColumnsCount) {
00366 m_visibleColumnsIDs.resize( m_visibleColumnsIDs.size()*2 );
00367 }
00368 m_visibleColumnsIDs[ columns.count()-1 ] = m_visibleColumnsCount-1;
00369 m_globalColumnsIDs[ m_visibleColumnsCount-1 ] = columns.count()-1;
00370 }
00371 else {
00372 m_visibleColumnsIDs[ columns.count()-1 ] = -1;
00373 }
00374 m_autoIncrementedColumn = -2;
00375 if (!m_cursor || !m_cursor->query())
00376 m_itemSize = columns.count()+(m_containsROWIDInfo?1:0);
00377 }
00378
00379 QString KexiTableViewData::dbTableName() const
00380 {
00381 if (m_cursor && m_cursor->query() && m_cursor->query()->masterTable())
00382 return m_cursor->query()->masterTable()->name();
00383 return QString::null;
00384 }
00385
00386 void KexiTableViewData::setSorting(int column, bool ascending)
00387 {
00388 if (column>=0 && column<(int)columns.count()) {
00389 m_order = (ascending ? 1 : -1);
00390 }
00391 else {
00392 m_order = 0;
00393 m_sortedColumn = -1;
00394 m_realSortedColumn = -1;
00395 return;
00396 }
00397
00398 const KexiTableViewColumn *tvcol = columns.at(column);
00399 KexiDB::QueryColumnInfo* visibleLookupColumnInfo = tvcol->visibleLookupColumnInfo;
00400 const KexiDB::Field *field = visibleLookupColumnInfo ? visibleLookupColumnInfo->field : tvcol->field();
00401 m_sortedColumn = column;
00402 m_realSortedColumn = tvcol->columnInfo->indexForVisibleLookupValue()!=-1
00403 ? tvcol->columnInfo->indexForVisibleLookupValue() : m_sortedColumn;
00404
00405
00406 const int t = field->type();
00407 if (field->isTextType())
00408 cmpFunc = &KexiTableViewData::cmpStr;
00409 else if (KexiDB::Field::isFPNumericType(t))
00410 cmpFunc = &KexiTableViewData::cmpDouble;
00411 else if (t==KexiDB::Field::BigInteger) {
00412 if (field->isUnsigned())
00413 cmpFunc = &KexiTableViewData::cmpULongLong;
00414 else
00415 cmpFunc = &KexiTableViewData::cmpLongLong;
00416 }
00417 else if (t == KexiDB::Field::Integer && field->isUnsigned())
00418 cmpFunc = &KexiTableViewData::cmpUInt;
00419 else if (t == KexiDB::Field::Boolean || KexiDB::Field::isNumericType(t))
00420 cmpFunc = &KexiTableViewData::cmpInt;
00421 else if (t == KexiDB::Field::Date)
00422 cmpFunc = &KexiTableViewData::cmpDate;
00423 else if (t == KexiDB::Field::Time)
00424 cmpFunc = &KexiTableViewData::cmpTime;
00425 else if (t == KexiDB::Field::DateTime)
00426 cmpFunc = &KexiTableViewData::cmpDateTime;
00427 else if (t == KexiDB::Field::BLOB)
00429 cmpFunc = &KexiTableViewData::cmpBLOB;
00430 else
00431 cmpFunc = &KexiTableViewData::cmpStr;
00432 }
00433
00434 int KexiTableViewData::compareItems(Item item1, Item item2)
00435 {
00436 return ((this->*cmpFunc) (item1, item2));
00437 }
00438
00440 #define CMP_NULLS(item1, item2) \
00441 m_leftTmp = ((KexiTableItem *)item1)->at(m_realSortedColumn); \
00442 if (m_leftTmp.isNull()) \
00443 return -m_order; \
00444 m_rightTmp = ((KexiTableItem *)item2)->at(m_realSortedColumn); \
00445 if (m_rightTmp.isNull()) \
00446 return m_order
00447
00448 #define CAST_AND_COMPARE(casting, item1, item2) \
00449 CMP_NULLS(item1, item2); \
00450 if (m_leftTmp.casting() < m_rightTmp.casting()) \
00451 return -m_order; \
00452 if (m_leftTmp.casting() > m_rightTmp.casting()) \
00453 return m_order; \
00454 return 0
00455
00456 int KexiTableViewData::cmpInt(Item item1, Item item2)
00457 {
00458 CAST_AND_COMPARE(toInt, item1, item2);
00459 }
00460
00461 int KexiTableViewData::cmpUInt(Item item1, Item item2)
00462 {
00463 CAST_AND_COMPARE(toUInt, item1, item2);
00464 }
00465
00466 int KexiTableViewData::cmpLongLong(Item item1, Item item2)
00467 {
00468 CAST_AND_COMPARE(toLongLong, item1, item2);
00469 }
00470
00471 int KexiTableViewData::cmpULongLong(Item item1, Item item2)
00472 {
00473 CAST_AND_COMPARE(toULongLong, item1, item2);
00474 }
00475
00476 int KexiTableViewData::cmpDouble(Item item1, Item item2)
00477 {
00478 CAST_AND_COMPARE(toDouble, item1, item2);
00479 }
00480
00481 int KexiTableViewData::cmpDate(Item item1, Item item2)
00482 {
00483 CAST_AND_COMPARE(toDate, item1, item2);
00484 }
00485
00486 int KexiTableViewData::cmpDateTime(Item item1, Item item2)
00487 {
00488 CAST_AND_COMPARE(toDateTime, item1, item2);
00489 }
00490
00491 int KexiTableViewData::cmpTime(Item item1, Item item2)
00492 {
00493 CAST_AND_COMPARE(toDate, item1, item2);
00494 }
00495
00496 int KexiTableViewData::cmpStr(Item item1, Item item2)
00497 {
00498 CMP_NULLS(item1, item2);
00499 const QString &as = m_leftTmp.toString();
00500 const QString &bs = m_rightTmp.toString();
00501
00502 const QChar *a = as.unicode();
00503 const QChar *b = bs.unicode();
00504
00505 if ( a == b )
00506 return 0;
00507 if ( a == 0 )
00508 return -1;
00509 if ( b == 0 )
00510 return 1;
00511
00512 unsigned short au;
00513 unsigned short bu;
00514
00515 int l=QMIN(as.length(),bs.length());
00516
00517 au = a->unicode();
00518 bu = b->unicode();
00519 au = (au <= 0x17e ? charTable[au] : 0xffff);
00520 bu = (bu <= 0x17e ? charTable[bu] : 0xffff);
00521
00522 while (l-- && au == bu)
00523 {
00524 a++,b++;
00525 au = a->unicode();
00526 bu = b->unicode();
00527 au = (au <= 0x17e ? charTable[au] : 0xffff);
00528 bu = (bu <= 0x17e ? charTable[bu] : 0xffff);
00529 }
00530
00531 if ( l==-1 )
00532 return m_order*(as.length()-bs.length());
00533
00534 return m_order*(au-bu);
00535 }
00536
00537 int KexiTableViewData::cmpBLOB(Item item1, Item item2)
00538 {
00539 CMP_NULLS(item1, item2);
00540 return m_leftTmp.toByteArray().size() - m_rightTmp.toByteArray().size();
00541 }
00542
00543 void KexiTableViewData::setReadOnly(bool set)
00544 {
00545 if (m_readOnly == set)
00546 return;
00547 m_readOnly = set;
00548 if (m_readOnly)
00549 setInsertingEnabled(false);
00550 }
00551
00552 void KexiTableViewData::setInsertingEnabled(bool set)
00553 {
00554 if (m_insertingEnabled == set)
00555 return;
00556 m_insertingEnabled = set;
00557 if (m_insertingEnabled)
00558 setReadOnly(false);
00559 }
00560
00561 void KexiTableViewData::clearRowEditBuffer()
00562 {
00563
00564 if (!m_pRowEditBuffer)
00565 m_pRowEditBuffer = new KexiDB::RowEditBuffer(isDBAware());
00566 else
00567 m_pRowEditBuffer->clear();
00568 }
00569
00570 bool KexiTableViewData::updateRowEditBufferRef(KexiTableItem *item,
00571 int colnum, KexiTableViewColumn* col, QVariant& newval, bool allowSignals,
00572 QVariant *visibleValueForLookupField)
00573 {
00574 m_result.clear();
00575 if (allowSignals)
00576 emit aboutToChangeCell(item, colnum, newval, &m_result);
00577 if (!m_result.success)
00578 return false;
00579
00580 kdDebug() << "KexiTableViewData::updateRowEditBufferRef() column #"
00581 << colnum << " = " << newval.toString() << endl;
00582 if (!col) {
00583 kdWarning() << "KexiTableViewData::updateRowEditBufferRef(): column #"
00584 << colnum << " not found! col==0" << endl;
00585 return false;
00586 }
00587 if (!m_pRowEditBuffer)
00588 m_pRowEditBuffer = new KexiDB::RowEditBuffer(isDBAware());
00589 if (m_pRowEditBuffer->isDBAware()) {
00590 if (!(col->columnInfo)) {
00591 kdWarning() << "KexiTableViewData::updateRowEditBufferRef(): column #"
00592 << colnum << " not found!" << endl;
00593 return false;
00594 }
00595 m_pRowEditBuffer->insert( *col->columnInfo, newval);
00596
00597 if (col->visibleLookupColumnInfo && visibleValueForLookupField) {
00598
00599 m_pRowEditBuffer->insert( *col->visibleLookupColumnInfo, *visibleValueForLookupField);
00600 }
00601 return true;
00602 }
00603 if (!(col->field())) {
00604 kdDebug() << "KexiTableViewData::updateRowEditBufferRef(): column #" << colnum<<" not found!" << endl;
00605 return false;
00606 }
00607
00608 const QString colname = col->field()->name();
00609 if (colname.isEmpty()) {
00610 kdDebug() << "KexiTableViewData::updateRowEditBufferRef(): column #" << colnum<<" not found!" << endl;
00611 return false;
00612 }
00613 m_pRowEditBuffer->insert(colname, newval);
00614 return true;
00615 }
00616
00617
00618
00619 #define GET_VALUE if (!val) { \
00620 val = m_cursor \
00621 ? m_pRowEditBuffer->at( *it_f.current()->columnInfo, true ) \
00622 : m_pRowEditBuffer->at( *f ); \
00623 if (!val) \
00624 val = &(*it_r); \
00625 }
00626
00628 bool KexiTableViewData::saveRow(KexiTableItem& item, bool insert, bool repaint)
00629 {
00630 if (!m_pRowEditBuffer)
00631 return true;
00632
00633
00634
00635 KexiTableViewColumn::ListIterator it_f(columns);
00636 KexiDB::RowData::ConstIterator it_r = item.constBegin();
00637 int col = 0;
00638 const QVariant *val;
00639 for (;it_f.current() && it_r!=item.constEnd();++it_f,++it_r,col++) {
00640 KexiDB::Field *f = it_f.current()->field();
00641 val = 0;
00642 if (f->isNotNull()) {
00643 GET_VALUE;
00644
00645 if (val->isNull() && !f->isAutoIncrement()) {
00646
00647 m_result.msg = i18n("\"%1\" column requires a value to be entered.")
00648 .arg(f->captionOrName()) + "\n\n" + Kexi::msgYouCanImproveData();
00649 m_result.desc = i18n("The column's constraint is declared as NOT NULL.");
00650 m_result.column = col;
00651 return false;
00652 }
00653 }
00654 if (f->isNotEmpty()) {
00655 GET_VALUE;
00656 if (!f->isAutoIncrement() && (val->isNull() || KexiDB::isEmptyValue( f, *val ))) {
00657
00658 m_result.msg = i18n("\"%1\" column requires a value to be entered.")
00659 .arg(f->captionOrName()) + "\n\n" + Kexi::msgYouCanImproveData();
00660 m_result.desc = i18n("The column's constraint is declared as NOT EMPTY.");
00661 m_result.column = col;
00662 return false;
00663 }
00664 }
00665 }
00666
00667 if (m_cursor) {
00668 if (insert) {
00669 if (!m_cursor->insertRow( static_cast<KexiDB::RowData&>(item), *m_pRowEditBuffer,
00670 m_containsROWIDInfo ))
00671 {
00672 m_result.msg = i18n("Row inserting failed.") + "\n\n"
00673 + Kexi::msgYouCanImproveData();
00674 KexiDB::getHTMLErrorMesage(m_cursor, &m_result);
00675
00676
00677
00678
00679
00680
00681
00682
00683 return false;
00684 }
00685 }
00686 else {
00687
00688
00689 if (!m_cursor->updateRow( static_cast<KexiDB::RowData&>(item), *m_pRowEditBuffer,
00690 m_containsROWIDInfo))
00691 {
00692 m_result.msg = i18n("Row changing failed.") + "\n\n" + Kexi::msgYouCanImproveData();
00694 KexiDB::getHTMLErrorMesage(m_cursor, m_result.desc);
00695 return false;
00696 }
00697 }
00698 }
00699 else {
00700 KexiDB::RowEditBuffer::SimpleMap b = m_pRowEditBuffer->simpleBuffer();
00701 for (KexiDB::RowEditBuffer::SimpleMap::ConstIterator it = b.constBegin();it!=b.constEnd();++it) {
00702 uint i=0;
00703 for (KexiTableViewColumn::ListIterator it2(columns);it2.current();++it2, i++) {
00704 if (it2.current()->field()->name()==it.key()) {
00705 kdDebug() << it2.current()->field()->name()<< ": "<<item[i].toString()<<" -> "<<it.data().toString()<<endl;
00706 item[i] = it.data();
00707 }
00708 }
00709 }
00710 }
00711
00712 m_pRowEditBuffer->clear();
00713
00714 if (repaint)
00715 emit rowRepaintRequested(item);
00716 return true;
00717 }
00718
00719 bool KexiTableViewData::saveRowChanges(KexiTableItem& item, bool repaint)
00720 {
00721 kdDebug() << "KexiTableViewData::saveRowChanges()..." << endl;
00722 m_result.clear();
00723 emit aboutToUpdateRow(&item, m_pRowEditBuffer, &m_result);
00724 if (!m_result.success)
00725 return false;
00726
00727 if (saveRow(item, false , repaint)) {
00728 emit rowUpdated(&item);
00729 return true;
00730 }
00731 return false;
00732 }
00733
00734 bool KexiTableViewData::saveNewRow(KexiTableItem& item, bool repaint)
00735 {
00736 kdDebug() << "KexiTableViewData::saveNewRow()..." << endl;
00737 m_result.clear();
00738 emit aboutToInsertRow(&item, &m_result, repaint);
00739 if (!m_result.success)
00740 return false;
00741
00742 if (saveRow(item, true , repaint)) {
00743 emit rowInserted(&item, repaint);
00744 return true;
00745 }
00746 return false;
00747 }
00748
00749 bool KexiTableViewData::deleteRow(KexiTableItem& item, bool repaint)
00750 {
00751 m_result.clear();
00752 emit aboutToDeleteRow(item, &m_result, repaint);
00753 if (!m_result.success)
00754 return false;
00755
00756 if (m_cursor) {
00757 m_result.success = false;
00758 if (!m_cursor->deleteRow( static_cast<KexiDB::RowData&>(item), m_containsROWIDInfo )) {
00759 m_result.msg = i18n("Row deleting failed.");
00760
00761 KexiDB::getHTMLErrorMesage(m_cursor, &m_result);
00762 m_result.success = false;
00763 return false;
00764 }
00765 }
00766
00767 if (!removeRef(&item)) {
00768
00769 kdWarning() << "KexiTableViewData::deleteRow(): !removeRef() - IMPL. ERROR?" << endl;
00770 m_result.success = false;
00771 return false;
00772 }
00773 emit rowDeleted();
00774 return true;
00775 }
00776
00777 void KexiTableViewData::deleteRows( const QValueList<int> &rowsToDelete, bool repaint )
00778 {
00779 Q_UNUSED( repaint );
00780
00781 if (rowsToDelete.isEmpty())
00782 return;
00783 int last_r=0;
00784 first();
00785 for (QValueList<int>::ConstIterator r_it = rowsToDelete.constBegin(); r_it!=rowsToDelete.constEnd(); ++r_it) {
00786 for (; last_r<(*r_it); last_r++) {
00787 next();
00788 }
00789 remove();
00790 last_r++;
00791 }
00792
00793
00794 emit rowsDeleted( rowsToDelete );
00795 }
00796
00797 void KexiTableViewData::insertRow(KexiTableItem& item, uint index, bool repaint)
00798 {
00799 if (!insert( index = QMIN(index, count()), &item ))
00800 return;
00801 emit rowInserted(&item, index, repaint);
00802 }
00803
00804
00805 void KexiTableViewData::clearInternal()
00806 {
00807 clearRowEditBuffer();
00808
00809
00810
00811 const uint c = count();
00812 for (uint i=0; i<c; i++) {
00813 removeLast();
00814 #ifndef KEXI_NO_PROCESS_EVENTS
00815 if (i % 1000 == 0)
00816 qApp->processEvents( 1 );
00817 #endif
00818 }
00819 }
00820
00821 bool KexiTableViewData::deleteAllRows(bool repaint)
00822 {
00823 clearInternal();
00824
00825 bool res = true;
00826 if (m_cursor) {
00827
00828 res = m_cursor->deleteAllRows();
00829 }
00830
00831 if (repaint)
00832 emit reloadRequested();
00833 return res;
00834 }
00835
00836 int KexiTableViewData::autoIncrementedColumn()
00837 {
00838 if (m_autoIncrementedColumn==-2) {
00839
00840 m_autoIncrementedColumn = 0;
00841 KexiTableViewColumn::ListIterator it(columns);
00842 for (; it.current(); ++it, m_autoIncrementedColumn++) {
00843 if (it.current()->field()->isAutoIncrement())
00844 break;
00845 }
00846 if (!it.current())
00847 m_autoIncrementedColumn = -1;
00848 }
00849 return m_autoIncrementedColumn;
00850 }
00851
00852 void KexiTableViewData::preloadAllRows()
00853 {
00854 if (!m_cursor)
00855 return;
00856
00857
00858 m_cursor->moveFirst();
00859 for (int i=0;!m_cursor->eof();i++) {
00860 KexiTableItem *item = new KexiTableItem(0);
00861 m_cursor->storeCurrentRow(*item);
00862
00863 append( item );
00864 m_cursor->moveNext();
00865 #ifndef KEXI_NO_PROCESS_EVENTS
00866 if ((i % 1000) == 0)
00867 qApp->processEvents( 1 );
00868 #endif
00869 }
00870 }
00871
00872 bool KexiTableViewData::isReadOnly() const
00873 {
00874 return m_readOnly || (m_cursor && m_cursor->connection()->isReadOnly());
00875 }
00876
00877 #include "kexitableviewdata.moc"