25#include "kexitableviewdata.h"
27#include <kexiutils/validator.h>
29#include <kexidb/field.h>
30#include <kexidb/queryschema.h>
31#include <kexidb/roweditbuffer.h>
32#include <kexidb/cursor.h>
33#include <kexidb/utils.h>
39#include <tqapplication.h>
41unsigned short KexiTableViewData::charTable[]=
43 #include "chartable.txt"
53 m_captionAliasOrName = m_field->captionOrName();
60 uint length, uint precision,
61 TQVariant defaultValue,
62 const TQString& caption,
const TQString& description, uint width
73 caption, description, width);
77 m_captionAliasOrName = m_field->captionOrName();
82 const TQString& caption,
const TQString& description)
88 KexiDB::Field::NoConstraints,
89 KexiDB::Field::NoOptions,
92 caption, description);
96 m_captionAliasOrName = m_field->captionOrName();
106, m_field(aColumnInfo.
field)
109 m_fieldOwned =
false;
112 if (!
columnInfo->field->caption().isEmpty()) {
113 m_captionAliasOrName = columnInfo->field->caption();
117 m_captionAliasOrName = columnInfo->alias;
119 if (m_captionAliasOrName.isEmpty())
120 m_captionAliasOrName = columnInfo->field->name();
129 m_readOnly = !columnFromMasterTable
149KexiTableViewColumn::~KexiTableViewColumn()
154 delete m_relatedData;
157void KexiTableViewColumn::init()
164 m_relatedDataEditable =
false;
165 m_headerTextVisible =
true;
171 if (!m_validator->parent())
182 delete m_relatedData;
187 KexiTableViewColumn::ListIterator it( data->
columns );
188 for (
int id = 0;it.current();++it,
id++) {
189 if (it.current()->field()->isPrimaryKey()) {
191 m_relatedDataPKeyID = id;
192 m_relatedData = data;
200 m_relatedDataEditable = set;
208bool KexiTableViewColumn::acceptsFirstChar(
const TQChar& ch)
const
215 if (ch==
'.' || ch==
',')
219 if (ch==
'+' || ((
int)ch>=
'0' && (
int)ch<=
'9'))
224 switch (visibleField->
type()) {
227 case KexiDB::Field::Date:
228 case KexiDB::Field::DateTime:
229 case KexiDB::Field::Time:
230 return (
int)ch>=
'0' && (int)ch<=
'9';
241 , KexiTableViewDataBase()
249 , KexiTableViewDataBase()
254 if (m_cursor && m_cursor->query()) {
258 m_itemSize = m_cursor->query()->fieldsExpanded( fieldsExpandedOptions ).count();
264 const KexiDB::QueryColumnInfo::Vector fields = m_cursor->query()->fieldsExpanded();
265 const uint fieldsCount = fields.count();
266 for (uint i=0;i < fieldsCount;i++) {
285 const TQValueList<TQVariant> &keys,
const TQValueList<TQVariant> &values,
288 , KexiTableViewDataBase()
290 init(keys, values, keyType, valueType);
296 const TQValueList<TQVariant> empty;
297 init(empty, empty, keyType, valueType);
300KexiTableViewData::~KexiTableViewData()
306void KexiTableViewData::init(
307 const TQValueList<TQVariant> &keys,
const TQValueList<TQVariant> &values,
311 KexiDB::Field *keyField =
new KexiDB::Field(
"key", keyType);
313 KexiTableViewColumn *keyColumn =
new KexiTableViewColumn(*keyField,
true);
317 KexiDB::Field *valueField =
new KexiDB::Field(
"value", valueType);
318 KexiTableViewColumn *valueColumn =
new KexiTableViewColumn(*valueField,
true);
321 uint cnt = TQMIN(keys.count(), values.count());
322 TQValueList<TQVariant>::ConstIterator it_keys = keys.constBegin();
323 TQValueList<TQVariant>::ConstIterator it_values = values.constBegin();
324 for (;cnt>0;++it_keys, ++it_values, cnt--) {
325 KexiTableItem *item =
new KexiTableItem(2);
326 (*item)[0] = (*it_keys);
327 (*item)[1] = (*it_values);
332void KexiTableViewData::init()
339 m_pRowEditBuffer = 0;
342 m_insertingEnabled =
true;
346 m_visibleColumnsCount=0;
347 m_visibleColumnsIDs.resize(100);
348 m_globalColumnsIDs.resize(100);
350 m_autoIncrementedColumn = -2;
355void KexiTableViewData::deleteLater()
358 TQObject::deleteLater();
370 if (m_globalColumnsIDs.size() <
columns.count()) {
371 m_globalColumnsIDs.resize( m_globalColumnsIDs.size()*2 );
374 m_visibleColumnsCount++;
375 if (m_visibleColumnsIDs.size() < m_visibleColumnsCount) {
376 m_visibleColumnsIDs.resize( m_visibleColumnsIDs.size()*2 );
378 m_visibleColumnsIDs[
columns.count()-1 ] = m_visibleColumnsCount-1;
379 m_globalColumnsIDs[ m_visibleColumnsCount-1 ] =
columns.count()-1;
382 m_visibleColumnsIDs[
columns.count()-1 ] = -1;
384 m_autoIncrementedColumn = -2;
385 if (!m_cursor || !m_cursor->query())
391 if (m_cursor && m_cursor->query() && m_cursor->query()->masterTable())
392 return m_cursor->query()->masterTable()->name();
398 if (column>=0 && column<(
int)
columns.count()) {
399 m_order = (ascending ? 1 : -1);
410 const KexiDB::Field *field = visibleLookupColumnInfo ? visibleLookupColumnInfo->field : tvcol->
field();
416 const int t = field->type();
417 if (field->isTextType())
418 cmpFunc = &KexiTableViewData::cmpStr;
420 cmpFunc = &KexiTableViewData::cmpDouble;
422 if (field->isUnsigned())
423 cmpFunc = &KexiTableViewData::cmpULongLong;
425 cmpFunc = &KexiTableViewData::cmpLongLong;
428 cmpFunc = &KexiTableViewData::cmpUInt;
430 cmpFunc = &KexiTableViewData::cmpInt;
431 else if (t == KexiDB::Field::Date)
432 cmpFunc = &KexiTableViewData::cmpDate;
433 else if (t == KexiDB::Field::Time)
434 cmpFunc = &KexiTableViewData::cmpTime;
435 else if (t == KexiDB::Field::DateTime)
436 cmpFunc = &KexiTableViewData::cmpDateTime;
441 cmpFunc = &KexiTableViewData::cmpStr;
444int KexiTableViewData::compareItems(Item item1, Item item2)
446 return ((this->*cmpFunc) (item1, item2));
450#define CMP_NULLS(item1, item2) \
451 m_leftTmp = ((KexiTableItem *)item1)->at(m_realSortedColumn); \
452 if (m_leftTmp.isNull()) \
454 m_rightTmp = ((KexiTableItem *)item2)->at(m_realSortedColumn); \
455 if (m_rightTmp.isNull()) \
458#define CAST_AND_COMPARE(casting, item1, item2) \
459 CMP_NULLS(item1, item2); \
460 if (m_leftTmp.casting() < m_rightTmp.casting()) \
462 if (m_leftTmp.casting() > m_rightTmp.casting()) \
466int KexiTableViewData::cmpInt(Item item1, Item item2)
468 CAST_AND_COMPARE(toInt, item1, item2);
471int KexiTableViewData::cmpUInt(Item item1, Item item2)
473 CAST_AND_COMPARE(toUInt, item1, item2);
476int KexiTableViewData::cmpLongLong(Item item1, Item item2)
478 CAST_AND_COMPARE(toLongLong, item1, item2);
481int KexiTableViewData::cmpULongLong(Item item1, Item item2)
483 CAST_AND_COMPARE(toULongLong, item1, item2);
486int KexiTableViewData::cmpDouble(Item item1, Item item2)
488 CAST_AND_COMPARE(toDouble, item1, item2);
491int KexiTableViewData::cmpDate(Item item1, Item item2)
493 CAST_AND_COMPARE(toDate, item1, item2);
496int KexiTableViewData::cmpDateTime(Item item1, Item item2)
498 CAST_AND_COMPARE(toDateTime, item1, item2);
501int KexiTableViewData::cmpTime(Item item1, Item item2)
503 CAST_AND_COMPARE(toDate, item1, item2);
506int KexiTableViewData::cmpStr(Item item1, Item item2)
508 CMP_NULLS(item1, item2);
509 const TQString &as =
m_leftTmp.toString();
510 const TQString &bs = m_rightTmp.toString();
512 const TQChar *a = as.unicode();
513 const TQChar *b = bs.unicode();
525 int l=TQMIN(as.length(),bs.length());
529 au = (au <= 0x17e ? charTable[au] : 0xffff);
530 bu = (bu <= 0x17e ? charTable[bu] : 0xffff);
532 while (l-- && au == bu)
537 au = (au <= 0x17e ? charTable[au] : 0xffff);
538 bu = (bu <= 0x17e ? charTable[bu] : 0xffff);
542 return m_order*(as.length()-bs.length());
544 return m_order*(au-bu);
549 CMP_NULLS(item1, item2);
550 return m_leftTmp.toByteArray().size() - m_rightTmp.toByteArray().size();
555 if (m_readOnly == set)
564 if (m_insertingEnabled == set)
566 m_insertingEnabled = set;
567 if (m_insertingEnabled)
574 if (!m_pRowEditBuffer)
577 m_pRowEditBuffer->clear();
582 TQVariant *visibleValueForLookupField)
590 kdDebug() <<
"KexiTableViewData::updateRowEditBufferRef() column #"
591 << colnum <<
" = " << newval.toString() << endl;
593 kdWarning() <<
"KexiTableViewData::updateRowEditBufferRef(): column #"
594 << colnum <<
" not found! col==0" << endl;
597 if (!m_pRowEditBuffer)
599 if (m_pRowEditBuffer->isDBAware()) {
601 kdWarning() <<
"KexiTableViewData::updateRowEditBufferRef(): column #"
602 << colnum <<
" not found!" << endl;
605 m_pRowEditBuffer->insert( *col->
columnInfo, newval);
613 if (!(col->
field())) {
614 kdDebug() <<
"KexiTableViewData::updateRowEditBufferRef(): column #" << colnum<<
" not found!" << endl;
618 const TQString colname = col->
field()->name();
619 if (colname.isEmpty()) {
620 kdDebug() <<
"KexiTableViewData::updateRowEditBufferRef(): column #" << colnum<<
" not found!" << endl;
623 m_pRowEditBuffer->insert(colname, newval);
629#define GET_VALUE if (!val) { \
631 ? m_pRowEditBuffer->at( *it_f.current()->columnInfo, true ) \
632 : m_pRowEditBuffer->at( *f ); \
640 if (!m_pRowEditBuffer)
645 KexiTableViewColumn::ListIterator it_f(
columns);
646 KexiDB::RowData::ConstIterator it_r = item.constBegin();
648 const TQVariant *val;
649 for (;it_f.current() && it_r!=item.constEnd();++it_f,++it_r,col++) {
657 m_result.msg = i18n(
"\"%1\" column requires a value to be entered.")
658 .arg(f->
captionOrName()) +
"\n\n" + Kexi::msgYouCanImproveData();
659 m_result.desc = i18n(
"The column's constraint is declared as NOT NULL.");
668 m_result.msg = i18n(
"\"%1\" column requires a value to be entered.")
669 .arg(f->
captionOrName()) +
"\n\n" + Kexi::msgYouCanImproveData();
670 m_result.desc = i18n(
"The column's constraint is declared as NOT EMPTY.");
679 if (!m_cursor->insertRow(
static_cast<KexiDB::RowData&
>(item), *m_pRowEditBuffer,
682 m_result.msg = i18n(
"Row inserting failed.") +
"\n\n"
683 + Kexi::msgYouCanImproveData();
699 if (!m_cursor->updateRow(
static_cast<KexiDB::RowData&
>(item), *m_pRowEditBuffer,
702 m_result.msg = i18n(
"Row changing failed.") +
"\n\n" + Kexi::msgYouCanImproveData();
710 KexiDB::RowEditBuffer::SimpleMap b = m_pRowEditBuffer->simpleBuffer();
711 for (KexiDB::RowEditBuffer::SimpleMap::ConstIterator it = b.constBegin();it!=b.constEnd();++it) {
713 for (KexiTableViewColumn::ListIterator it2(
columns);it2.current();++it2, i++) {
714 if (it2.current()->field()->name()==it.key()) {
715 kdDebug() << it2.current()->field()->name()<<
": "<<item[i].toString()<<
" -> "<<it.data().toString()<<endl;
722 m_pRowEditBuffer->clear();
725 emit rowRepaintRequested(item);
729bool KexiTableViewData::saveRowChanges(KexiTableItem& item,
bool repaint)
731 kdDebug() <<
"KexiTableViewData::saveRowChanges()..." << endl;
737 if (
saveRow(item,
false , repaint)) {
744bool KexiTableViewData::saveNewRow(KexiTableItem& item,
bool repaint)
746 kdDebug() <<
"KexiTableViewData::saveNewRow()..." << endl;
752 if (
saveRow(item,
true , repaint)) {
759bool KexiTableViewData::deleteRow(KexiTableItem& item,
bool repaint)
769 m_result.msg = i18n(
"Row deleting failed.");
777 if (!removeRef(&item)) {
779 kdWarning() <<
"KexiTableViewData::deleteRow(): !removeRef() - IMPL. ERROR?" << endl;
791 if (rowsToDelete.isEmpty())
795 for (TQValueList<int>::ConstIterator r_it = rowsToDelete.constBegin(); r_it!=rowsToDelete.constEnd(); ++r_it) {
796 for (; last_r<(*r_it); last_r++) {
809 if (!insert( index = TQMIN(index, count()), &item ))
814void KexiTableViewData::clearInternal()
820 const uint c = count();
821 for (uint i=0; i<c; i++) {
823#ifndef KEXI_NO_PROCESS_EVENTS
825 tqApp->processEvents( 1 );
837 res = m_cursor->deleteAllRows();
847 if (m_autoIncrementedColumn==-2) {
849 m_autoIncrementedColumn = 0;
850 KexiTableViewColumn::ListIterator it(
columns);
851 for (; it.current(); ++it, m_autoIncrementedColumn++) {
852 if (it.current()->field()->isAutoIncrement())
856 m_autoIncrementedColumn = -1;
858 return m_autoIncrementedColumn;
867 m_cursor->moveFirst();
868 for (
int i=0;!m_cursor->eof();i++) {
869 KexiTableItem *item =
new KexiTableItem(0);
870 m_cursor->storeCurrentRow(*item);
873 m_cursor->moveNext();
874#ifndef KEXI_NO_PROCESS_EVENTS
876 tqApp->processEvents( 1 );
883 return m_readOnly || (m_cursor && m_cursor->connection()->
isReadOnly());
886#include "kexitableviewdata.moc"
virtual bool isReadOnly() const
Provides database cursor functionality.
TQString captionOrName() const
bool isFPNumericType() const
void setPrimaryKey(bool p)
bool isAutoIncrement() const
bool isNumericType() const
bool isUnsigned() const
if the type has the unsigned attribute
Helper class that assigns additional information for the column in a query.
bool visible
true if this column is visible to the user (and its data is fetched by the engine)
int indexForVisibleLookupValue() const
KexiDB::QuerySchema provides information about database query.
TableSchema * masterTable() const
Connection * connection() const
@ WithInternalFieldsAndRowID
@ WithInternalFields
Like Default but internal fields (for lookup) are appended.
bool success
result of the operation, true by default
provides data for single edited database row KexiDB::RowEditBuffer provides data for single edited ro...
void setValidator(KexiUtils::Validator *v)
KexiDB::Field * field() const
bool isDBAware
true if data is stored in DB, not only in memeory
void setVisible(bool v)
Changes column visibility.
KexiTableViewData * m_data
Data that this column is assigned to.
bool visible() const
Column visibility. By default column is visible.
void setRelatedDataEditable(bool set)
KexiDB::QueryColumnInfo * visibleLookupColumnInfo
KexiDB::QueryColumnInfo * columnInfo
KexiTableViewColumn(KexiDB::Field &f, bool owner=false)
void setRelatedData(KexiTableViewData *data)
int m_realSortedColumn
real sorted column number, set by setSorting(), used by cmp*() methods
KexiTableViewColumn::List columns
KexiTableViewData()
not db-aware version
KexiDB::ResultInfo m_result
used to faster lookup columns of simple type (not dbaware)
int cmpBLOB(Item item1, Item item2)
Compare function for BLOB data (TQByteArray). Uses size as the weight.
void insertRow(KexiTableItem &item, uint index, bool repaint=false)
virtual bool deleteAllRows(bool repaint=false)
virtual void setInsertingEnabled(bool set)
bool saveRow(KexiTableItem &item, bool insert, bool repaint)
internal: for saveRowChanges() and saveNewRow()
void rowUpdated(KexiTableItem *)
Current row has been updated.
void aboutToUpdateRow(KexiTableItem *item, KexiDB::RowEditBuffer *buffer, KexiDB::ResultInfo *result)
void rowInserted(KexiTableItem *, bool repaint)
A row has been inserted.
void deleteRows(const TQValueList< int > &rowsToDelete, bool repaint=false)
virtual void setReadOnly(bool set)
void addColumn(KexiTableViewColumn *col)
bool updateRowEditBufferRef(KexiTableItem *item, int colnum, KexiTableViewColumn *col, TQVariant &newval, bool allowSignals=true, TQVariant *visibleValueForLookupField=0)
int autoIncrementedColumn()
virtual bool isReadOnly() const
void setSorting(int column, bool ascending=true)
void aboutToDeleteRow(KexiTableItem &item, KexiDB::ResultInfo *result, bool repaint)
void aboutToChangeCell(KexiTableItem *item, int colnum, TQVariant &newValue, KexiDB::ResultInfo *result)
void reloadRequested()
Displayed data needs to be reloaded in all presenters.
void clearRowEditBuffer()
void rowsDeleted(const TQValueList< int > &rowsToDelete)
Rows have been deleted.
void aboutToInsertRow(KexiTableItem *item, KexiDB::ResultInfo *result, bool repaint)
void rowDeleted()
Current row has been deleted.
TQString dbTableName() const
A validator extending TQValidator with offline-checking for value's validity.
bool isEmptyValue(Field *f, const TQVariant &v)
TQValueVector< TQVariant > RowData
structure for storing single record with type information
KEXI_DB_EXPORT void getHTMLErrorMesage(Object *obj, TQString &msg, TQString &details)