summaryrefslogtreecommitdiff
path: root/noncore/apps/tableviewer
authormickeyl <mickeyl>2004-04-04 13:54:40 (UTC)
committer mickeyl <mickeyl>2004-04-04 13:54:40 (UTC)
commit16cf79e90b5217f8d4bfce2a0fa817ae4b73db36 (patch) (side-by-side diff)
tree0701eae15aa606a0211a2fccfde0eafdac69357c /noncore/apps/tableviewer
parent8d2d2664e5f544b8292806e617deb7a0e4170dc0 (diff)
downloadopie-16cf79e90b5217f8d4bfce2a0fa817ae4b73db36.zip
opie-16cf79e90b5217f8d4bfce2a0fa817ae4b73db36.tar.gz
opie-16cf79e90b5217f8d4bfce2a0fa817ae4b73db36.tar.bz2
convert to Opie Debugging Framework
Diffstat (limited to 'noncore/apps/tableviewer') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/tableviewer/db/common.cpp28
-rw-r--r--noncore/apps/tableviewer/db/datacache.cpp12
-rw-r--r--noncore/apps/tableviewer/db/xmlsource.cpp30
-rw-r--r--noncore/apps/tableviewer/tableviewer.cpp14
-rw-r--r--noncore/apps/tableviewer/tableviewer.pro8
-rw-r--r--noncore/apps/tableviewer/ui/tvlistview.cpp9
6 files changed, 66 insertions, 35 deletions
diff --git a/noncore/apps/tableviewer/db/common.cpp b/noncore/apps/tableviewer/db/common.cpp
index dbf9370..6e544ba 100644
--- a/noncore/apps/tableviewer/db/common.cpp
+++ b/noncore/apps/tableviewer/db/common.cpp
@@ -1,124 +1,132 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
-#include <stdlib.h>
+#include "common.h"
+#include "datacache.h"
+
+/* OPIE */
+#include <opie2/odebug.h>
+#include <qpe/timestring.h>
+using namespace Opie::Core;
+
+/* QT */
#include <qstring.h>
#include <qheader.h>
#include <qvector.h>
#include <qdatetime.h>
-#include <qpe/timestring.h>
-#include "common.h"
-#include "datacache.h"
+
+/* STD */
#include <assert.h>
+#include <stdlib.h>
static const int del_flag = 0x1;
static const int new_flag = 0x2;
/* Helper function */
int parseNextNumber(QString *q) {
QChar c;
uint i;
int result = 0;
bool found_digits = FALSE;
for(i = 0; i < q->length(); i++) {
c = q->at(i);
if (c.isDigit()) {
if (found_digits)
result *= 10;
found_digits = TRUE;
result += c.digitValue();
} else {
if (found_digits)
break;
/* just skip this char */
}
}
/* now truncate q */
if (found_digits)
q->remove(0, i);
return result;
}
/*!
\class QStringVector
\brief A Vector of QStrings that can be sorted and searched
Implmented in order to allow reverse lookup on the string name
*/
/*!
This function implements the compare function in order to allow the
searching and sorting of the QStringVector to occur
\returns an int which is either
<UL>
<LI> < 0 if the first string is smaller than the second,</LI>
<LI> > 0 if the first string is bigger then the second,</LI>
<LI> == 0 if the first string is equal to the second.</LI>
</UL>
*/
int QStringVector::compareItems(Item a, Item b)
{
QString *qa = (QString *)a;
QString *qb = (QString *)b;
return QString::compare(*qa, *qb);
}
/*!
\class TVVariant
A way of abstracting void * and keeping information on
the keytypes and behaviours in one place
*/
TVVariantPrivate::TVVariantPrivate()
{
typ = TVVariant::Invalid;
}
TVVariantPrivate::TVVariantPrivate( TVVariantPrivate *d)
{
switch(d->typ)
{
case TVVariant::Invalid:
break;
case TVVariant::String:
value.ptr = new QString(*((QString *)d->value.ptr));
break;
case TVVariant::Date:
value.ptr = new QDate(*((QDate *)d->value.ptr));
break;
case TVVariant::Time:
value.ptr = new QTime(*((QTime *)d->value.ptr));
break;
case TVVariant::Int:
value.i = d->value.i;
break;
default:
ASSERT( 0 );
}
typ = d->typ;
}
TVVariantPrivate::~TVVariantPrivate()
{
@@ -219,193 +227,193 @@ void TVVariant::detach()
{
if (d->count == 1)
return;
d->deref();
d = new TVVariantPrivate(d);
}
const QString TVVariant::typeName() const
{
return typeToName(d->typ);
}
void TVVariant::clear()
{
if (d->count > 1)
{
d->deref();
d = new TVVariantPrivate;
return;
}
d->clear();
}
const QString TVVariant::typeToName(KeyType typ)
{
switch(typ) {
case String:
return QString("String");
case Date:
return QString("Date");
case Time:
return QString("Time");
case Int:
return QString("Int");
case Invalid:
default:
return QString("Invalid");
}
return QString("Invalid");
}
TVVariant::KeyType TVVariant::nameToType(const QString &name)
{
if(!qstrcmp("String", name))
return String;
if(!qstrcmp("Date", name))
return Date;
if(!qstrcmp("Time", name))
return Time;
if(!qstrcmp("Int", name))
return Int;
return Invalid;
}
void TVVariant::load(QDataStream &s )
{
KeyType t;
s >> t;
d->typ = t;
switch(t) {
case Invalid:
d->typ = t;
break;
case String:
{
QString *x = new QString;
s >> *x;
d->value.ptr = x;
}
break;
case Time:
{
QTime *x = new QTime;
s >> *x;
d->value.ptr = x;
}
break;
case Date:
{
QDate *x = new QDate;
s >> *x;
d->value.ptr = x;
}
break;
case Int:
{
int x;
s >> x;
d->value.i = x;
}
break;
default:
- qFatal("Unrecognized data type");
+ ofatal << "Unrecognized data type" << oendl;
}
}
void TVVariant::save( QDataStream &s ) const
{
s << type();
switch( d->typ ) {
case String:
s << *((QString *)d->value.ptr);
break;
case Date:
s << *((QDate *)d->value.ptr);
break;
case Time:
s << *((QTime *)d->value.ptr);
break;
case Int:
s << d->value.i;
break;
case Invalid:
break;
}
}
QDataStream& operator>>(QDataStream& s, TVVariant& p)
{
p.load( s );
return s;
}
QDataStream& operator<<(QDataStream &s, const TVVariant& p)
{
p.save( s );
return s;
}
QDataStream& operator>> (QDataStream &s, TVVariant::KeyType& p)
{
Q_UINT8 u = 0;
s >> u;
p = (TVVariant::KeyType) u;
return s;
}
QDataStream& operator<< (QDataStream& s, const TVVariant::KeyType& p)
{
s << (Q_UINT8)p;
return s;
}
const QString TVVariant::toString() const
{
switch(d->typ) {
case String:
return *((QString*)d->value.ptr);
case Date:
return ((QDate*)d->value.ptr)->toString();
case Time:
return ((QTime*)d->value.ptr)->toString();
case Int:
return QString::number(d->value.i);
case Invalid:
default:
return QString::null;
}
return QString::null;
}
// TODO DO, this properly, */
int TVVariant::toInt() const
{
if(d->typ == Int)
return d->value.i;
if(d->typ == String) {
QString tmpq(*(QString *)d->value.ptr);
return parseNextNumber(&tmpq);
}
return 0;
}
const QDate TVVariant::toDate() const
{
if(d->typ == Date)
return *((QDate *)d->value.ptr);
if(d->typ == String) {
QString q = toString();
/* date format is day mon d yyyy */
/* ignore the first three letters, read the next
three for month.. etc */
@@ -985,193 +993,193 @@ bool KeyList::validIndex(int i) const
return FALSE;
return TRUE;
}
QDataStream &operator<<( QDataStream &s, const KeyList &k)
{
s << k.getNumFields();
KeyListIterator it(k);
while(it.current()) {
s << (Q_UINT16)it.currentKey();
s << it.current()->name();
s << it.current()->example();
s << (Q_UINT16)it.current()->flags();
++it;
}
return s;
}
QDataStream &operator>>( QDataStream &s, KeyList &k)
{
int i;
int size;
int index = 0;
int flags = 0;
TVVariant type = TVVariant();
QString name;
s >> size;
for (i=0; i < size; i++) {
s >> (Q_UINT16 &)index;
s >> name;
s >> type;
s >> (Q_UINT16 &)flags;
k.replace(index, new Key(name, type, flags));
}
return s;
}
/*!
\class DataElem
\brief A class representing a single row or element of a table in a DBStore
This class holds the data of a row in a table.
*/
/*!
Constructs a DataElem. This function needs a container because the
size, types of keys and primary key are all defined by the containing
database
*/
DataElem::DataElem(DBStore *c) : values(20)
{
int size;
contained = c;
size = c->getNumFields();
values.setAutoDelete(TRUE);
}
/*!
Destroys a DataElem and frees memory used by the DataElem
*/
DataElem::~DataElem() {
}
QDataStream &operator<<( QDataStream &s, const DataElem &d)
{
int size = d.getNumFields();
s << size; /* redundent data but makes streaming easier */
KeyList k = d.getKeys();
KeyListIterator it(k);
while(it.current()) {
s << (Q_UINT16)it.currentKey();
s << d.getField(it.currentKey());
++it;
}
return s;
}
QDataStream &operator>>( QDataStream &s, DataElem &d)
{
int i;
int size;
TVVariant t;
int index = 0;
s >> size; /* redundent data but makes streaming easier */
if (size != d.getNumFields()) {
- qWarning("DataSize mis-match");
+ owarn << "DataSize mis-match" << oendl;
return s; /* sanity check failed.. don't load */
}
for(i = 0; i < size; i++) {
s >> (Q_UINT16)index;
s >> t;
d.setField(index, t);
}
return s;
}
/*! Returns the number of possible (not valid) fields in the data element */
int DataElem::getNumFields() const
{
return contained->getNumFields();
}
KeyList DataElem::getKeys() const
{
return *(contained->getKeys());
}
/*!
This function determines whether field index i of the element has been
set yet.
\return A boolean value that is TRUE if the specfied field of this
element has been set and FALSE if the field has not yet been set
*/
bool DataElem::hasValidValue(int i) const
{
if(!values.find(i))
return FALSE;
if(!contained->getKeys()->validIndex(i))
return FALSE;
return values.find(i)->isValid();
}
/*!
This function determines whether field name qs of the element has been
set yet.
\return A boolean value that is TRUE if the specfied field of this
element has been set and FALSE if the field has not yet been set
*/
bool DataElem::hasValidValue(QString qs) const
{
int i = contained->getKeyIndex(qs);
return hasValidValue(i);
}
/*! returns the type of the field specified by index i */
TVVariant::KeyType DataElem::getFieldType(int i) const
{
return contained->getKeyType(i);
}
/*! returns the type of the field specified by name qs */
TVVariant::KeyType DataElem::getFieldType(QString qs) const
{
int i = contained->getKeyIndex(qs);
return contained->getKeyType(i);
}
/*!
returns a pointer to the data stored in field index i for this
data element, (value may not be valid)
*/
TVVariant DataElem::getField(int i) const
{
if(hasValidValue(i))
return TVVariant(*values.find(i));
return TVVariant();
}
/*!
returns a pointer to the data stored in field name qs for this
data element, (value may not be valid)
*/
TVVariant DataElem::getField(QString qs) const
{
int i = contained->getKeyIndex(qs);
return getField(i);
}
/*!
Sets the value of the elements field index i to the value represented in
the QString q.
\param i index of the field to set
\param q a string that can be parsed to get the value to be set
*/
void DataElem::setField(int i, QString q)
{
/* from the type of the field, parse q and store */
TVVariant::KeyType kt = contained->getKeyType(i);
@@ -1284,187 +1292,187 @@ QString DataElem::toQString() const
/*! formats individual fields to strings so can be displayed */
QString DataElem::toQString(int i) const
{
if(hasValidValue(i)) {
return getField(i).toString();
}
return "";
}
/*! formats individual fields to strings so can be sorted by QListView */
QString DataElem::toSortableQString(int i) const
{
QString scratch = "";
if(hasValidValue(i)) {
switch (contained->getKeyType(i)) {
case TVVariant::String: {
scratch += getField(i).toString();
break;
}
case TVVariant::Int: {
scratch.sprintf("%08d", getField(i).toInt());
break;
}
case TVVariant::Date: {
static QDate epochD(1800, 1, 1);
scratch.sprintf("%08d",
epochD.daysTo(getField(i).toDate()));
break;
}
case TVVariant::Time: {
static QTime epochT(0, 0, 0);
scratch.sprintf("%08d",
epochT.msecsTo(getField(i).toTime()));
break;
}
default:
scratch += "Unknown type";
break;
}
}
return scratch;
}
/* compare functions */
bool DataElem::lessThan(int i, TVVariant v) const
{
if (!hasValidValue(i)) return FALSE;
if (getField(i).type() != v.type())
return FALSE;
return (getField(i) < v);
}
bool DataElem::moreThan(int i, TVVariant v) const
{
if (!hasValidValue(i)) return FALSE;
if (getField(i).type() != v.type())
return FALSE;
return (getField(i) > v);
}
bool DataElem::equalTo(int i, TVVariant v) const
{
if (!hasValidValue(i)) return FALSE;
if (getField(i).type() != v.type())
return FALSE;
return (getField(i) == v);
}
bool DataElem::contains(int i, TVVariant v) const
{
if (!hasValidValue(i)) return FALSE;
if (getField(i).type() != v.type())
return FALSE;
switch(getField(i).type()) {
case TVVariant::String: {
QString qs1 = getField(i).toString().lower();
QString qs2 = v.toString().lower();
if (qs1.contains(qs2) > 0) return TRUE;
break;
}
/* meaningless for ints */
/* meaningless for time */
/* meaningless for dates */
case TVVariant::Int:
case TVVariant::Time:
case TVVariant::Date:
break;
default:
- qWarning("Tried to compare unknown data type");
+ owarn << "Tried to compare unknown data type" << oendl;
}
return FALSE;
}
bool DataElem::startsWith(int i, TVVariant v) const
{
if (!hasValidValue(i)) return FALSE;
if (getField(i).type() != v.type())
return FALSE;
switch(getField(i).type()) {
case TVVariant::String: {
QString qs1 = getField(i).toString().lower();
QString qs2 = v.toString().lower();
return qs1.startsWith(qs2);
}
/* meaningless for ints */
/* meaningless for time */
/* meaningless for dates */
case TVVariant::Int:
case TVVariant::Time:
case TVVariant::Date:
return FALSE;
default:
- qWarning("Tried to compare unknown data type");
+ owarn << "Tried to compare unknown data type" << oendl;
}
return FALSE;
}
bool DataElem::endsWith(int i, TVVariant v) const
{
if (!hasValidValue(i)) return FALSE;
if (getField(i).type() != v.type())
return FALSE;
switch(getField(i).type()) {
case TVVariant::String: {
QString qs1 = getField(i).toString().lower();
QString qs2 = v.toString().lower();
return qs1.startsWith(qs2);
}
/* meaningless for ints */
/* meaningless for time */
/* meaningless for dates */
case TVVariant::Int:
case TVVariant::Time:
case TVVariant::Date:
return FALSE;
default:
- qWarning("Tried to compare unknown data type");
+ owarn << "Tried to compare unknown data type" << oendl;
}
return FALSE;
}
/*!
Determins which of the first to parameters are closer to the third, target
parameter.
\return
<UL>
<LI>TRUE if the first element is a closer match to the target than the
second element</LI>
<LI>FALSE if the first element is not a closer match to the target than
the second element</LI>
</UL>
*/
bool DataElem::closer(DataElem*d1, DataElem *d2, TVVariant target, int column)
{
int type;
if(!d1) return FALSE;
if (!d1->hasValidValue(column)) return FALSE;
if(!target.isValid()) return FALSE;
type = d1->getField(column).type();
if(d2) {
if (type != d2->getField(column).type()) {
/* can't do compare */
- qWarning("Tried to compare two incompatable types");
+ owarn << "Tried to compare two incompatable types" << oendl;
return FALSE;
}
return target.closer(d1->getField(column), d2->getField(column));
}
return target.close(d1->getField(column));
}
diff --git a/noncore/apps/tableviewer/db/datacache.cpp b/noncore/apps/tableviewer/db/datacache.cpp
index 7c14eef..6380e1b 100644
--- a/noncore/apps/tableviewer/db/datacache.cpp
+++ b/noncore/apps/tableviewer/db/datacache.cpp
@@ -1,249 +1,257 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
/*
* This file is used to load the xml files that represent the database.
* The main requirment for said file is each data entry must contain a key,
* otherwise any other data headings are allowed.
*/
#include "datacache.h"
#include "xmlsource.h"
#include "csvsource.h"
-#include <stdlib.h>
+
+/* OPIE */
+#include <opie2/odebug.h>
+using namespace Opie::Core;
+
+/* QT */
#include <qheader.h>
+/* STD */
+#include <stdlib.h>
+
#define INIT_TABLE_SIZE 128
/*!
\class DBStore datastore.h
\brief The DBStore class is the class responsible for storing, sorting and
searching the data loaded by the application
*/
/*!
Constructs a DBStore item
*/
DBStore::DBStore()
{
name = "";
number_elems = 0;
full = false;
kRep = new KeyList();
master_table.resize(INIT_TABLE_SIZE);
table_size = INIT_TABLE_SIZE;
current_elem = 0;
archive = 0;
}
//TODO
/*!
Reinitializes the table to empty (include a resize of the master table,
which should free some memory)
*/
void DBStore::freeTable()
{
name = "";
if(archive) {
delete archive;
archive = 0;
}
kRep->clear(); /* clear the current key list */
number_elems = 0;
table_size = INIT_TABLE_SIZE;
master_table.resize(table_size);
full = false;
current_elem = 0;
}
/*!
Removes all items from the DBStore and destroys the DBStore
*/
DBStore::~DBStore()
{
freeTable();
}
/*!
This function opens the given xml file, loads it and sets up the
appropriate data structures.
\param file_name A string representing the name of the file to be opened
\return true if successful, false otherwise.
*/
bool DBStore::openSource(QIODevice *inDev, const QString &source) {
/* first check if db is already open, if contains data.. then clear */
if(number_elems > 0) {
freeTable();
}
if (source == "text/x-xml-tableviewer") {
archive = new DBXml(this);
} else if (source == "text/csv") {
archive = new DBCsv(this);
} else
return false;
return (archive->openSource(inDev));
}
bool DBStore::saveSource(QIODevice *outDev, const QString &source)
{
/* saving a new file */
if(!archive) {
if (source == "text/x-xml-tableviewer") {
archive = new DBXml(this);
} else if (source == "text/x-xml-tableviewer") {
archive = new DBCsv(this);
} else
return false;
}
/* changing file type */
if(archive->type() != source) {
delete archive;
if (source == "text/x-xml-tableviewer") {
archive = new DBXml(this);
} else if (source == "text/x-xml-tableviewer") {
archive = new DBCsv(this);
} else
return false;
}
return (archive->saveSource(outDev));
}
/*!
This function is used to add new elements to the database. If the database
has already reached the maximum allowable size this function does not alter
the database.
\param delm An already allocated and initialized data element to be added
*/
void DBStore::addItem(DataElem *delem)
{
addItemInternal(delem);
}
void DBStore::addItemInternal(DataElem *delem)
{
/* if already full, don't over fill, do a qWarning though */
if (full) {
- qWarning("Attempted to add items to already full table");
+ owarn << "Attempted to add items to already full table" << oendl;
return;
}
master_table.insert(number_elems, delem);
current_elem = number_elems;
number_elems++;
if(number_elems >= table_size) {
/* filled current table, double if we can */
table_size = table_size << 1;
/* check that the new table size is still valid, i.e. that we didn't
just shift the 1 bit of the end of the int. */
if (!table_size) {
full = true;
/* no point in doing antying else. */
return;
}
master_table.resize(table_size);
}
}
void DBStore::removeItem(DataElem *r)
{
int position = master_table.findRef(r);
if(position != -1) {
/* there is at least one item, this is it */
/* replace this with the last element, decrease the element count */
master_table.insert(position, master_table.at(--number_elems));
master_table.remove(number_elems);
delete r;
}
}
/*!
Sets the name of the database
\param n A string representing the new name of the database.
*/
void DBStore::setName(const QString &n)
{
name = n;
}
/*!
Gets the name of the database
\return A string representing the name of the database.
*/
QString DBStore::getName()
{
return name;
}
/*!
Retrieves a pointer to the key representation of the database for
other classes to use as reference.
\return a pointer to the databases key representaion
*/
KeyList *DBStore::getKeys()
{
return kRep;
}
/*!
sets the database's key representation the passed pointer
\param a pointer to a key representaton
*/
void DBStore::setKeys(KeyList *k)
{
kRep = k;
}
/*!
Sets the current element to the first element of the database
*/
void DBStore::first()
{
current_elem = 0;
}
/*!
Sets the current element to the last element of the database
*/
void DBStore::last()
{
current_elem = number_elems - 1;
}
/*!
Sets the current element to the next element of the database if
there exists an element after the current one.
*/
bool DBStore::next()
diff --git a/noncore/apps/tableviewer/db/xmlsource.cpp b/noncore/apps/tableviewer/db/xmlsource.cpp
index 94fec36..4ca6aee 100644
--- a/noncore/apps/tableviewer/db/xmlsource.cpp
+++ b/noncore/apps/tableviewer/db/xmlsource.cpp
@@ -1,297 +1,303 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#include "xmlsource.h"
-#include <qdict.h>
-#include <stdlib.h>
-#include <qtextstream.h>
#include "../xmlencodeattr.h"
+/* OPIE */
+#include <opie2/odebug.h>
+using namespace Opie::Core;
+/* QT */
+#include <qdict.h>
+#include <qtextstream.h>
+
+/* STD */
+#include <stdlib.h>
DBXml::DBXml(DBStore *d)
{
dstore = d;
}
QString DBXml::type()
{
return "xml";
}
bool DBXml::openSource(QIODevice *inDev)
{
bool ok;
DBXmlHandler h(dstore);
QTextStream tsIn(inDev);
QXmlInputSource source(tsIn);
QXmlSimpleReader reader;
reader.setContentHandler(&h);
reader.setErrorHandler(&h);
ok = reader.parse(source);
return ok;
}
bool DBXml::saveSource(QIODevice *outDev)
{
int i;
DataElem *elem;
KeyList *k;
QTextStream outstream(outDev);
outstream << "<database name=\"" << dstore->getName() << "\">" << endl;
outstream << "<header>" << endl;
k = dstore->getKeys();
KeyListIterator it(*k);
while(it.current()) {
if (!it.current()->delFlag()) {
outstream << "<key name=\"KEYID" << it.currentKey() << "\" ";
outstream << "type=\""
<< TVVariant::typeToName(it.current()->type())
<< "\">";
outstream << encodeAttr(it.current()->name()) << "</key>" << endl;
}
++it;
}
outstream << "</header>" << endl;
dstore->first();
do {
elem = dstore->getCurrentData();
if (!elem)
break;
outstream << "<record>" << endl;
it.toFirst();
while (it.current()) {
i = it.currentKey();
if (elem->hasValidValue(i)) {
outstream << "<KEYID" << i << ">";
if (dstore->getKeyType(i) == TVVariant::Date) {
// dates in files are different from displayed dates
QDate date = elem->getField(i).toDate();
outstream << date.day() << "/"
<< date.month() << "/"
<< date.year();
} else {
outstream << encodeAttr(elem->toQString(i));
}
outstream << "</KEYID" << i << ">" << endl;
}
++it;
}
outstream << "</record>" << endl;
} while(dstore->next());
outstream << "</database>" << endl;
return TRUE;
}
DBXml::~DBXml() {}
/*!
\class DBXmlHandler
\brief An Xml parser for flat tables.
An xml parser for parsing the files used by the table viewer application.
The format of the xml files can be found at the front of the file
dataparser.h
*/
/*!
Constructs a new DBXmlHandler, and sets that the table should be
constructed in the DBStore pointed to by ds.
*/
DBXmlHandler::DBXmlHandler(DBStore *ds)
{
data_store = ds;
current_keyrep = 0;
}
/*!
Destroys the DBXmlHandler
*/
DBXmlHandler::~DBXmlHandler()
{
}
QString DBXmlHandler::errorProtocol()
{
- qWarning("Error reading file");
+ owarn << "Error reading file" << oendl;
return errorProt;
}
bool DBXmlHandler::startDocument()
{
errorProt = "";
state = StateInit;
return TRUE;
}
bool DBXmlHandler::startElement(const QString&, const QString&,
const QString& qName, const QXmlAttributes& atts)
{
if (state == StateInit && qName == "database") {
// First thing it expects is a <document name="..."> tag
state = StateDocument;
data_store->setName(atts.value("name"));
return TRUE;
}
if (state == StateDocument && qName == "header") {
state = StateHeader;
if (current_keyrep) delete current_keyrep;
current_keyrep = new KeyList();
return TRUE;
}
if (state == StateHeader && qName == "key") {
/* Ok, adding a new key to our KeyList TODO */
state = StateKey;
last_key_type = TVVariant::String;
key = atts.value("name");
if (key.isEmpty()) {
- qWarning("empty key name");
+ owarn << "empty key name" << oendl;
return FALSE;
}
if(!atts.value("type").isEmpty())
last_key_type = TVVariant::nameToType(atts.value("type"));
return TRUE;
}
if (state == StateDocument && qName == "record") {
state = StateRecord;
current_data = new DataElem(data_store);
// Now expecting a <record> tag
return TRUE;
}
if (state == StateRecord) {
state = StateField;
/* the qName is the name of a key */
if (!keyIndexList[qName]) {
/* invalid key, we failed */
- qWarning("Invalid key in record");
+ owarn << "Invalid key in record" << oendl;
return FALSE;
}
keyIndex = *keyIndexList[qName];
return TRUE;
}
- qWarning("Unable to determine tag type");
+ owarn << "Unable to determine tag type" << oendl;
return FALSE;
}
bool DBXmlHandler::endElement(const QString&, const QString&,
const QString& qName)
{
switch(state) {
case StateField:
// TODO checks 'could' be done of the popped value
state = StateRecord;
break;
case StateKey:
// TODO checks 'could' be done of the popped value
state = StateHeader;
break;
case StateHeader:
data_store->setKeys(current_keyrep);
state = StateDocument;
break;
case StateRecord:
data_store->addItem(current_data);
state = StateDocument;
break;
case StateDocument:
// we are done...
break;
default:
// should only get a 'endElement' from one of the above states.
- qWarning("Invalid end tag");
+ owarn << "Invalid end tag" << oendl;
return FALSE;
break;
}
return TRUE;
}
bool DBXmlHandler::characters(const QString& ch)
{
// this is where the 'between tag' stuff happens.
// e.g. the stuff between tags.
QString ch_simplified = ch.simplifyWhiteSpace();
if (ch_simplified.isEmpty())
return TRUE;
if (state == StateKey) {
int *tmp_val = new int;
/* We just grabbed the display name of a key */
*tmp_val = current_keyrep->addKey(ch_simplified, last_key_type);
keyIndexList.insert(key, tmp_val);
return TRUE;
}
if (state == StateField) {
/* Ok, need to add data here */
current_data->setField(keyIndex, ch_simplified);
return TRUE;
}
- qWarning("Junk characters found... ignored");
+ owarn << "Junk characters found... ignored" << oendl;
return TRUE;
}
QString DBXmlHandler::errorString()
{
return "the document is not in the expected file format";
}
bool DBXmlHandler::warning(const QXmlParseException& exception)
{
errorProt += QString("warning parsing error: %1 in line %2, column %3\n" )
.arg(exception.message())
.arg(exception.lineNumber())
.arg(exception.columnNumber());
- qWarning(errorProt);
+ owarn << errorProt << oendl;
return QXmlDefaultHandler::fatalError(exception);
}
bool DBXmlHandler::error(const QXmlParseException& exception)
{
errorProt += QString("error parsing error: %1 in line %2, column %3\n" )
.arg(exception.message())
.arg(exception.lineNumber())
.arg(exception.columnNumber());
- qWarning(errorProt);
+ owarn << errorProt << oendl;
return QXmlDefaultHandler::fatalError(exception);
}
bool DBXmlHandler::fatalError(const QXmlParseException& exception)
{
errorProt += QString("fatal parsing error: %1 in line %2, column %3\n" )
.arg(exception.message())
.arg(exception.lineNumber())
.arg(exception.columnNumber());
- qWarning(errorProt);
+ owarn << errorProt << oendl;
return QXmlDefaultHandler::fatalError(exception);
}
diff --git a/noncore/apps/tableviewer/tableviewer.cpp b/noncore/apps/tableviewer/tableviewer.cpp
index 102b94c..9538cb3 100644
--- a/noncore/apps/tableviewer/tableviewer.cpp
+++ b/noncore/apps/tableviewer/tableviewer.cpp
@@ -1,387 +1,389 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
-/* local includes */
#include "tableviewer.h"
#include "ui/tvbrowseview.h"
#include "ui/tvfilterview.h"
#include "ui/tvlistview.h"
#include "ui/tveditview.h"
#include "ui/tvkeyedit.h"
#include "db/datacache.h"
-/* QPE includes */
+/* OPIE */
+#include <opie2/odebug.h>
#include <qpe/fileselector.h>
#include <qpe/resource.h>
-#include <qtoolbar.h>
+using namespace Opie::Core;
-/* QTE includes */
+/* QT */
#include <qmenubar.h>
+#include <qtoolbar.h>
#include <qpopupmenu.h>
#include <qapplication.h>
#include <qwidgetstack.h>
#include <qlayout.h>
#include <qbuffer.h>
+
/*!
\class TableViewerWindow
\brief The main window widget of the application
This is the main widget of the table viewer application.
It is the co-ordination point.
*/
/*!
Constructs a new TableViewerWindow
*/
TableViewerWindow::TableViewerWindow(QWidget *parent, const char *name, WFlags f)
: QMainWindow(parent, name, f)
{
setCaption(tr("Table Viewer"));
/* Build data */
ds = new DBStore();
doc.setType("text/x-xml-tableviewer");
doc.setName("table");
dirty = FALSE;
ts.current_column = 0;
ts.kRep = ds->getKeys();
/* build menus */
menu = new QMenuBar(this, 0);
QPopupMenu *file_menu = new QPopupMenu;
file_menu->insertItem("New", this, SLOT(newDocument()));
file_menu->insertItem("Open", this, SLOT(selectDocument()));
file_menu->insertSeparator();
file_menu->insertItem("Properties");
/* later will want to set this up to clean up first via this, SLOT(quit) */
menu->insertItem("Document", file_menu);
QPopupMenu *edit_menu = new QPopupMenu;
edit_menu->insertItem("Edit Item", this, SLOT(editItemSlot()));
edit_menu->insertItem("Edit Keys", this, SLOT(editKeysSlot()));
edit_menu->insertItem("Edit filters", this, SLOT(filterViewSlot()));
menu->insertItem("Edit", edit_menu);
QPopupMenu *view_menu = new QPopupMenu;
view_menu->insertItem("Browse View", this, SLOT(browseViewSlot()));
view_menu->insertItem("List View", this, SLOT(listViewSlot()));
menu->insertItem("View", view_menu);
QVBoxLayout *main_layout = new QVBoxLayout;
/* Build tool bar */
navigation = new QToolBar(this, "navigation");
QToolButton *newItemButton = new QToolButton(
QIconSet(Resource::loadPixmap("new")), "New Item", QString::null,
this, SLOT(newItemSlot()), navigation, "New Item");
QToolButton *editItemButton = new QToolButton(
QIconSet(Resource::loadPixmap("edit")), "Edit Item", QString::null,
this, SLOT(editItemSlot()), navigation, "Edit Item");
QToolButton *deleteItemButton = new QToolButton(
QIconSet(Resource::loadPixmap("trash")), "Delete Item",
QString::null, this,
SLOT(deleteItemSlot()), navigation, "Delete Item");
navigation->addSeparator();
QToolButton *firstItemButton = new QToolButton(
QIconSet(Resource::loadPixmap("fastback")), "First Item",
QString::null, this,
SLOT(firstItem()), navigation, "First Item");
QToolButton *previousItemButton = new QToolButton(
QIconSet(Resource::loadPixmap("back")), "Previous Item",
QString::null, this,
SLOT(previousItem()), navigation, "Previous Item");
QToolButton *nextItemButton = new QToolButton(
QIconSet(Resource::loadPixmap("forward")), "Next Item",
QString::null, this,
SLOT(nextItem()), navigation, "Next Item");
QToolButton *lastItemButton = new QToolButton(
QIconSet(Resource::loadPixmap("fastforward")), "Last Item",
QString::null, this,
SLOT(lastItem()), navigation, "Last Item");
navigation->addSeparator();
QToolButton *browseButton = new QToolButton(
QIconSet(Resource::loadPixmap("day")), "View Single Item",
QString::null, this,
SLOT(browseViewSlot()), navigation, "View Single Item");
QToolButton *listButton = new QToolButton(
QIconSet(Resource::loadPixmap("month")), "View Multiple Items",
QString::null, this,
SLOT(listViewSlot()), navigation, "View Multiple Items");
setToolBarsMovable(FALSE);
setToolBarsMovable(FALSE);
setToolBarsMovable(FALSE);
/* Build widgets */
browseView = new TVBrowseView(&ts, this, 0);
listView = new TVListView(&ts, this, 0);
filterView = new TVFilterView(&ts, this, 0);
fileSelector = new FileSelector("text/csv;text/x-xml-tableviewer",
this, "fileselector");
fileSelector->setNewVisible(FALSE);
fileSelector->setCloseVisible(FALSE);
cw = new QWidgetStack(this, 0);
cw->addWidget(listView, ListState);
cw->addWidget(browseView, BrowseState);
cw->addWidget(filterView, FilterState);
cw->addWidget(fileSelector, FileState);
current_view = FileState;
cw->raiseWidget(current_view);
fileSelector->reread();
connect(browseView, SIGNAL(searchOnKey(int,TVVariant)),
this, SLOT(searchOnKey(int,TVVariant)));
connect(browseView, SIGNAL(sortChanged(int)),
this, SLOT(setPrimaryKey(int)));
connect(fileSelector, SIGNAL(closeMe()), this, SLOT(browseViewSlot()));
connect(fileSelector, SIGNAL(fileSelected(const DocLnk&)),
this, SLOT(openDocument(const DocLnk&)));
main_layout->addWidget(menu);
main_layout->addWidget(cw);
setCentralWidget(cw);
}
/*!
Destroys the TableViewerWindow
*/
TableViewerWindow::~TableViewerWindow()
{
if(dirty)
saveDocument();
}
/*!
Opens a file dialog and loads the file specified by the dialog
*/
void TableViewerWindow::selectDocument()
{
if(dirty)
saveDocument();
current_view = FileState;
cw->raiseWidget(current_view);
fileSelector->reread();
}
void TableViewerWindow::saveDocument()
{
if(!dirty)
return;
FileManager fm;
QIODevice *dev = fm.saveFile(doc);
if(!ds->saveSource(dev, doc.type())){
- qWarning("Save unsuccessful");
+ owarn << "Save unsuccessful" << oendl;
return;
}
dev->close();
dirty = FALSE;
}
void TableViewerWindow::newDocument()
{
DocLnk nf;
nf.setType("text/x-xml-tableviewer");
nf.setName("table");
delete ds;
ds = new DBStore();
ts.current_column = 0;
ts.kRep = ds->getKeys();
browseView->reset();
listView->reset();
filterView->reset();
doc = nf;
dirty = FALSE;
current_view = BrowseState;
cw->raiseWidget(current_view);
/* now set up for editing the keys */
ts.kRep->addKey("key", TVVariant::String);
editKeysSlot();
}
void TableViewerWindow::setDocument(const QString &f)
{
openDocument(DocLnk(f, TRUE));
}
void TableViewerWindow::openDocument(const DocLnk &f)
{
if (!f.isValid())
return;
FileManager fm;
QIODevice *dev = fm.openFile(f);
doc = f;
if(ds->openSource(dev, doc.type())) {
DataElem *d;
browseView->reset();
listView->reset();
filterView->reset();
current_view = BrowseState;
cw->raiseWidget(current_view);
/* set up new table state and ensure sub widgets have a reference */
ts.current_column = 0;
ts.kRep = ds->getKeys();
browseView->rebuildKeys();
listView->rebuildKeys();
filterView->rebuildKeys();
ds->first();
/* set up the list view */
listView->clearItems();
do {
d = ds->getCurrentData();
if(d)
listView->addItem(d);
} while(ds->next());
/* Set up browse view, Will be based of structure of listView */
listView->first();
ts.current_elem = listView->getCurrentData();
browseView->rebuildData();
listView->rebuildData();
QString scratch = "Table Viewer";/* later take from constant */
scratch += " - ";
scratch += ds->getName();
setCaption(tr(scratch));
dirty = FALSE;
} else {
- qWarning(tr("could not load Document"));
+ owarn << tr("could not load Document") << oendl;
}
dev->close();
}
/*!
Moves to the first item of the current table
*/
void TableViewerWindow::firstItem()
{
listView->first();
ts.current_elem = listView->getCurrentData();
browseView->rebuildData();
}
/*!
Moves to the lat item of the current table
*/
void TableViewerWindow::lastItem()
{
listView->last();
ts.current_elem = listView->getCurrentData();
browseView->rebuildData();
}
/*!
Moves to the next item of the current table
*/
void TableViewerWindow::nextItem()
{
listView->next();
ts.current_elem = listView->getCurrentData();
browseView->rebuildData();
}
/*!
Moves to the previous item of the current table
*/
void TableViewerWindow::previousItem()
{
listView->previous();
ts.current_elem = listView->getCurrentData();
browseView->rebuildData();
}
/*!
Raises the List View. This is a mode change for the application.
*/
void TableViewerWindow::listViewSlot()
{
if(current_view == FilterState)
applyFilter();
current_view = ListState;
cw->raiseWidget(current_view);
}
void TableViewerWindow::applyFilter()
{
DataElem *d;
listView->clearItems();
ds->first();
do {
d = ds->getCurrentData();
if(d)
if(filterView->passesFilter(d))
listView->addItem(d);
} while(ds->next());
listView->first();
listView->rebuildData();
}
/*!
Raises the Browse View. This is a mode change for the application.
*/
void TableViewerWindow::browseViewSlot()
{
if(current_view == FilterState)
applyFilter();
ts.current_elem = listView->getCurrentData();
browseView->rebuildData();
current_view = BrowseState;
cw->raiseWidget(current_view);
}
/*!
Raises the List View. This is a mode change for the application.
*/
void TableViewerWindow::filterViewSlot()
{
current_view = FilterState;
cw->raiseWidget(current_view);
}
diff --git a/noncore/apps/tableviewer/tableviewer.pro b/noncore/apps/tableviewer/tableviewer.pro
index 1de23bb..564f50f 100644
--- a/noncore/apps/tableviewer/tableviewer.pro
+++ b/noncore/apps/tableviewer/tableviewer.pro
@@ -1,38 +1,38 @@
-CONFIG = qt warn_on quick-app
+CONFIG = qt warn_on quick-app
SUBDIRS = db ui
HEADERS = tableviewer.h \
xmlencodeattr.h \
ui/commonwidgets.h \
ui/tvbrowseview.h \
ui/tvlistview.h \
ui/tvfilterview.h \
ui/tveditview.h \
ui/browsekeyentry.h \
ui/filterkeyentry.h \
ui/tvkeyedit.h \
db/datacache.h \
db/common.h \
db/xmlsource.h \
db/csvsource.h
SOURCES = main.cpp \
tableviewer.cpp \
xmlencodeattr.cpp \
ui/commonwidgets.cpp \
ui/tvbrowseview.cpp \
ui/tvfilterview.cpp \
ui/browsekeyentry.cpp \
ui/filterkeyentry.cpp \
ui/tvlistview.cpp \
ui/tveditview.cpp \
ui/tvkeyedit.cpp \
db/datacache.cpp \
db/xmlsource.cpp \
db/csvsource.cpp \
db/common.cpp
INTERFACES = ui/tvkeyedit_gen.ui
TARGET = tableviewer
-INCLUDEPATH += $(OPIEDIR)/include
-DEPENDPATH += $(OPIEDIR)/include
-LIBS += -lqpe -lopiecore2
+INCLUDEPATH += $(OPIEDIR)/include
+DEPENDPATH += $(OPIEDIR)/include
+LIBS += -lqpe -lopiecore2
include ( $(OPIEDIR)/include.pro )
diff --git a/noncore/apps/tableviewer/ui/tvlistview.cpp b/noncore/apps/tableviewer/ui/tvlistview.cpp
index b10ff1d..c3e6432 100644
--- a/noncore/apps/tableviewer/ui/tvlistview.cpp
+++ b/noncore/apps/tableviewer/ui/tvlistview.cpp
@@ -1,262 +1,269 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
+
#include "tvlistview.h"
#include "../db/common.h"
+
+/* OPIE */
+#include <opie2/odebug.h>
+using namespace Opie::Core;
+
+/* QT */
#include <qtoolbutton.h>
#include <qlistview.h>
#include <qlayout.h>
void TVListViewPrivate::setColumnWidth(int column, int width)
{
if(width > 70) width = 70;
QListView::setColumnWidth(column, width);
}
void TVListViewPrivate::setSorting(int column, bool increasing)
{
emit sortChanged(column);
QListView::setSorting(column, increasing);
}
TVListViewPrivate::TVListViewPrivate(QWidget *parent, const char* name,
WFlags fl) : QListView(parent, name, fl) {
;
}
class TVListViewItem : public QListViewItem
{
public:
TVListViewItem(QListView *parent, DataElem *d);
~TVListViewItem();
QString text(int i) const
{
return data_reference->toQString(i);
}
/* Do nothing... all data for this item should be generated */
void setText(int i, const QString &)
{
;
}
QString key(int i, bool a) const
{
return data_reference->toSortableQString(i);
}
void setDataElem(DataElem *d)
{
data_reference = d;
}
DataElem *getDataElem() {
return data_reference;
}
private:
DataElem *data_reference;
};
TVListViewItem::TVListViewItem(QListView *parent, DataElem *d)
: QListViewItem(parent)
{
data_reference = d;
}
TVListViewItem::~TVListViewItem()
{
data_reference = 0;
}
TVListView::TVListView(TableState *t, QWidget* parent,
const char *name, WFlags fl ) : QWidget(parent, name, fl)
{
if (!name)
setName("TVListView");
// the next two lines need to be rationalized.
resize(318,457);
setSizePolicy(QSizePolicy((QSizePolicy::SizeType)7,
(QSizePolicy::SizeType)7, sizePolicy().hasHeightForWidth()));
setCaption(tr("List View"));
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setSpacing(0);
layout->setMargin(0);
listViewDisplay = new TVListViewPrivate(this, "listViewDisplay");
layout->addWidget(listViewDisplay);
connect(listViewDisplay, SIGNAL(currentChanged(QListViewItem*)), this,
SLOT(setCurrent(QListViewItem*)));
connect(listViewDisplay, SIGNAL(sortChanged(int)), this,
SLOT(setSorting(int)));
listViewDisplay->setShowSortIndicator(true);
it = new QListViewItemIterator(listViewDisplay);
ts = t;
}
TVListView::~TVListView()
{
}
void TVListView::addItem(DataElem *d)
{
TVListViewItem *i = new TVListViewItem(listViewDisplay, d);
delete it;
it = new QListViewItemIterator(i);
}
/* remove current (it) item */
void TVListView::removeItem()
{
QListViewItemIterator other(*it);
QListViewItemIterator tmp = *it;
(*it)++;
if (!it->current()) {
*it = tmp;
(*it)--;
if (!it->current()) {
delete it;
it = 0;
}
}
delete other.current();
}
void TVListView::clearItems()
{
/* This is ok since the destructor for TVListItem does not know about
the data_reference pointer.. and hence will leave it alone */
listViewDisplay->clear();
delete it;
it = new QListViewItemIterator(listViewDisplay);
}
void TVListView::first()
{
delete it;
it = new QListViewItemIterator(listViewDisplay);
}
void TVListView::last()
{
- qWarning("TVListView::last not yet implemented");
+ owarn << "TVListView::last not yet implemented" << oendl;
}
void TVListView::next()
{
QListViewItemIterator tmp = *it;
(*it)++;
if (!it->current()) {
*it = tmp;
}
}
void TVListView::previous()
{
QListViewItemIterator tmp = *it;
(*it)--;
if (!it->current()) {
*it = tmp;
}
}
DataElem *TVListView::getCurrentData() {
if (it->current()) {
return ((TVListViewItem *)it->current())->getDataElem();
}
return NULL;
}
/*! Now to implement the closest match function */
void TVListView::findItem(int keyId, TVVariant value)
{
QListViewItem *i;
TVListViewItem *best_so_far = NULL;
/* start at the beginning... go through till find the closest elem */
i = listViewDisplay->firstChild();
while (i) {
/* search stuff */
if(best_so_far) {
if (DataElem::closer(
((TVListViewItem *)i)->getDataElem(),
best_so_far->getDataElem(), value, keyId))
best_so_far = (TVListViewItem *)i;
} else {
if (DataElem::closer(
((TVListViewItem *)i)->getDataElem(),
NULL, value, keyId))
best_so_far = (TVListViewItem *)i;
}
i = i->itemBelow();
}
if (best_so_far) {
/* set best_so_far to current element */
delete it;
it = new QListViewItemIterator(best_so_far);
}
}
void TVListView::rebuildKeys()
{
int i;
if(!ts) return;
if(!ts->kRep) return;
i = listViewDisplay->columns();
while(i > 0)
listViewDisplay->removeColumn(--i);
KeyListIterator kit(*ts->kRep);
i = 0;
while(kit.current()) {
if(!kit.current()->delFlag()) {
listViewDisplay->addColumn(kit.current()->name());
keyIds.insert(i, kit.currentKey());
++i;
}
++kit;
}
}
void TVListView::setSorting(int column)
{
/* Without table state can't do anything */
if (ts == 0)
return;
if (keyIds[column] != ts->current_column) {
ts->current_column = keyIds[column];
}
}
void TVListView::rebuildData() {
int i;
QMap<int, int>::Iterator kit;
/* Need to set sort order */
if(!ts)