Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

common.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 #include "common.h"
00021 #include "datacache.h"
00022 
00023 /* OPIE */
00024 #include <opie2/odebug.h>
00025 #include <qpe/timestring.h>
00026 using namespace Opie::Core;
00027 
00028 /* QT */
00029 #include <qstring.h>
00030 #include <qheader.h>
00031 #include <qvector.h>
00032 #include <qdatetime.h>
00033 
00034 /* STD */
00035 #include <assert.h>
00036 #include <stdlib.h>
00037 
00038 static const int del_flag = 0x1;
00039 static const int new_flag = 0x2;
00040 
00041 /* Helper function */
00042 
00043 int parseNextNumber(QString *q) {
00044     QChar c;
00045     uint i;
00046     int result = 0;
00047 
00048     bool found_digits = FALSE;
00049     for(i = 0; i < q->length(); i++) {
00050         c = q->at(i);
00051         if (c.isDigit()) {
00052             if (found_digits)
00053                 result *= 10;
00054             found_digits = TRUE;
00055             result += c.digitValue();
00056         } else {
00057             if (found_digits)
00058                 break;
00059             /* just skip this char */
00060         }
00061     }
00062     /* now truncate q */
00063     if (found_digits)
00064         q->remove(0, i);
00065     return result;
00066 }
00067 
00087 int QStringVector::compareItems(Item a, Item b)
00088 {
00089     QString *qa = (QString *)a;
00090     QString *qb = (QString *)b;
00091 
00092     return QString::compare(*qa, *qb);
00093 }
00094 
00101 TVVariantPrivate::TVVariantPrivate()
00102 {
00103     typ = TVVariant::Invalid;
00104 }
00105 
00106 TVVariantPrivate::TVVariantPrivate( TVVariantPrivate *d)
00107 {
00108     switch(d->typ)
00109     {
00110         case TVVariant::Invalid:
00111             break;
00112         case TVVariant::String:
00113             value.ptr = new QString(*((QString *)d->value.ptr));
00114             break;
00115         case TVVariant::Date:
00116             value.ptr = new QDate(*((QDate *)d->value.ptr));
00117             break;
00118         case TVVariant::Time:
00119             value.ptr = new QTime(*((QTime *)d->value.ptr));
00120             break;
00121         case TVVariant::Int:
00122             value.i = d->value.i;
00123             break;
00124         default:
00125             ASSERT( 0 );
00126     }
00127 
00128     typ = d->typ;
00129 }
00130 
00131 TVVariantPrivate::~TVVariantPrivate()
00132 {
00133     clear();
00134 }
00135 
00136 void TVVariantPrivate::clear()
00137 {
00138     switch( typ )
00139     {
00140         case TVVariant::String:
00141             delete (QString *)value.ptr;
00142             break;
00143         case TVVariant::Date:
00144             delete (QDate *)value.ptr;
00145             break;
00146         case TVVariant::Time:
00147             delete (QTime *)value.ptr;
00148             break;
00149         case TVVariant::Invalid:
00150         case TVVariant::Int:
00151             break;
00152     }
00153 
00154     typ = TVVariant::Invalid;
00155 }
00156 
00162 TVVariant::TVVariant()
00163 {
00164     d = new TVVariantPrivate;
00165 }
00166 
00167 TVVariant::~TVVariant()
00168 {
00169     if (d->deref())
00170         delete d;
00171 }
00172 
00173 TVVariant::TVVariant(const TVVariant& p)
00174 {
00175     d = new TVVariantPrivate;
00176     *this = p;
00177 }
00178 
00179 TVVariant::TVVariant(QDataStream& s)
00180 {
00181     d = new TVVariantPrivate;
00182     s >> *this;
00183 }
00184 
00185 TVVariant::TVVariant(const QString &val)
00186 {
00187     d = new TVVariantPrivate;
00188     d->typ = String;
00189     d->value.ptr = new QString(val);
00190 }
00191 
00192 TVVariant::TVVariant(const QDate &val)
00193 {
00194     d = new TVVariantPrivate;
00195     d->typ = Date;
00196     d->value.ptr = new QDate(val);
00197 }
00198 
00199 TVVariant::TVVariant(const QTime &val)
00200 {
00201     d = new TVVariantPrivate;
00202     d->typ = Time;
00203     d->value.ptr = new QTime(val);
00204 }
00205 
00206 TVVariant::TVVariant( int val )
00207 {
00208     d = new TVVariantPrivate;
00209     d->typ = Int;
00210     d->value.i = val;
00211 }
00212 
00213 TVVariant& TVVariant::operator=(const TVVariant& variant )
00214 {
00215     TVVariant& other = (TVVariant&) variant;
00216 
00217     other.d->ref();
00218     if ( d->deref() )
00219     delete d;
00220 
00221     d = other.d;
00222 
00223     return *this;
00224 }
00225 
00226 void TVVariant::detach()
00227 {
00228     if (d->count == 1)
00229     return;
00230 
00231     d->deref();
00232     d = new TVVariantPrivate(d);
00233 }
00234 
00235 const QString TVVariant::typeName() const
00236 {
00237     return typeToName(d->typ);
00238 }
00239 
00240 void TVVariant::clear()
00241 {
00242     if (d->count > 1)
00243     {
00244         d->deref();
00245         d = new TVVariantPrivate;
00246         return;
00247     }
00248 
00249     d->clear();
00250 }
00251 
00252 const QString TVVariant::typeToName(KeyType typ)
00253 {
00254     switch(typ) {
00255         case String:
00256             return QString("String");
00257         case Date:
00258             return QString("Date");
00259         case Time:
00260             return QString("Time");
00261         case Int:
00262             return QString("Int");
00263         case Invalid:
00264         default:
00265             return QString("Invalid");
00266     }
00267     return QString("Invalid");
00268 }
00269 
00270 TVVariant::KeyType TVVariant::nameToType(const QString &name)
00271 {
00272     if(!qstrcmp("String", name))
00273         return String;
00274     if(!qstrcmp("Date", name))
00275         return Date;
00276     if(!qstrcmp("Time", name))
00277         return Time;
00278     if(!qstrcmp("Int", name))
00279         return Int;
00280 
00281     return Invalid;
00282 }
00283 
00284 void TVVariant::load(QDataStream &s )
00285 {
00286     KeyType t;
00287     s >> t;
00288 
00289     d->typ = t;
00290     switch(t) {
00291         case Invalid:
00292             d->typ = t;
00293             break;
00294         case String:
00295             {
00296                 QString *x = new QString;
00297                 s >> *x;
00298                 d->value.ptr = x;
00299             }
00300             break;
00301         case Time:
00302             {
00303                 QTime *x = new QTime;
00304                 s >> *x;
00305                 d->value.ptr = x;
00306             }
00307             break;
00308         case Date:
00309             {
00310                 QDate *x = new QDate;
00311                 s >> *x;
00312                 d->value.ptr = x;
00313             }
00314             break;
00315         case Int:
00316             {
00317                 int x;
00318                 s >> x;
00319                 d->value.i = x;
00320             }
00321       break;
00322         default:
00323       ofatal << "Unrecognized data type" << oendl;
00324     }
00325 }
00326 
00327 void TVVariant::save( QDataStream &s ) const
00328 {
00329     s << type();
00330 
00331     switch( d->typ ) {
00332         case String:
00333             s << *((QString *)d->value.ptr);
00334             break;
00335         case Date:
00336             s << *((QDate *)d->value.ptr);
00337             break;
00338         case Time:
00339             s << *((QTime *)d->value.ptr);
00340             break;
00341         case Int:
00342             s << d->value.i;
00343             break;
00344         case Invalid:
00345             break;
00346     }
00347 }
00348 
00349 QDataStream& operator>>(QDataStream& s, TVVariant& p)
00350 {
00351     p.load( s );
00352     return s;
00353 }
00354 
00355 QDataStream& operator<<(QDataStream &s, const TVVariant& p)
00356 {
00357     p.save( s );
00358     return s;
00359 }
00360 
00361 QDataStream& operator>> (QDataStream &s, TVVariant::KeyType& p)
00362 {
00363     Q_UINT8 u = 0;
00364     s >> u;
00365     p = (TVVariant::KeyType) u;
00366 
00367     return s;
00368 }
00369 
00370 QDataStream& operator<< (QDataStream& s, const TVVariant::KeyType& p)
00371 {
00372     s << (Q_UINT8)p;
00373     return s;
00374 }
00375 
00376 const QString TVVariant::toString() const
00377 {
00378     switch(d->typ) {
00379         case String:
00380             return *((QString*)d->value.ptr);
00381         case Date:
00382             return ((QDate*)d->value.ptr)->toString();
00383         case Time:
00384             return ((QTime*)d->value.ptr)->toString();
00385         case Int:
00386                 return QString::number(d->value.i);
00387         case Invalid:
00388         default:
00389             return QString::null;
00390     }
00391     return QString::null;
00392 }
00393 
00394 // TODO DO, this properly, */
00395 int TVVariant::toInt() const
00396 {
00397     if(d->typ == Int)
00398         return d->value.i;
00399 
00400     if(d->typ == String) {
00401       QString tmpq(*(QString *)d->value.ptr);
00402         return parseNextNumber(&tmpq);
00403     }
00404 
00405     return 0;
00406 }
00407 
00408 const QDate TVVariant::toDate() const
00409 {
00410     if(d->typ == Date)
00411         return *((QDate *)d->value.ptr);
00412 
00413     if(d->typ == String) {
00414         QString q = toString();
00415 
00416         /* date format is day mon d yyyy */
00417         /* ignore the first three letters, read the next
00418            three for month.. etc */
00419 
00420         int day = parseNextNumber(&q);
00421         int month = parseNextNumber(&q);
00422         int year = parseNextNumber(&q);
00423         if (!QDate::isValid(year, month, day))
00424             return QDate();
00425         return QDate(year, month, day);
00426     }
00427 
00428 
00429     return QDate();
00430 }
00431 
00432 const QTime TVVariant::toTime() const
00433 {
00434     if(d->typ == Time)
00435         return *((QTime *)d->value.ptr);
00436 
00437     if(d->typ == String) {
00438         QString q = toString();
00439         int hour = parseNextNumber(&q);
00440         int minute = parseNextNumber(&q);
00441         int second = parseNextNumber(&q);
00442         int msecond = parseNextNumber(&q);
00443         if (!QTime::isValid(hour, minute, second, msecond))
00444             return QTime();
00445         return QTime(hour, minute, second, msecond);
00446     }
00447 
00448     return QTime();
00449 }
00450 
00451 #define TV_VARIANT_AS( f ) Q##f& TVVariant::as##f() { \
00452     if ( d->typ != f ) \
00453         *this = TVVariant( to##f() ); \
00454     else \
00455         detach(); \
00456     return *((Q##f*)d->value.ptr); }
00457 
00458 TV_VARIANT_AS(String)
00459 TV_VARIANT_AS(Date)
00460 TV_VARIANT_AS(Time)
00461 
00462 #undef TV_VARIANT_AS
00463 
00464 int& TVVariant::asInt()
00465 {
00466     detach();
00467     if (d->typ != Int) {
00468         d->value.i = toInt();
00469         d->typ = Int;
00470     }
00471     return d->value.i;
00472 }
00473 
00479 bool TVVariant::canCast(KeyType t) const
00480 {
00481     if(d->typ == t)
00482         return TRUE;
00483 
00484     if(t == String)
00485         return TRUE;
00486 
00487     if(t == Int) {
00488         if (d->typ == Date)
00489             return TRUE;
00490         if (d->typ == Time)
00491             return TRUE;
00492         if (d->typ == String)
00493             return TRUE;
00494     }
00495 
00496     return FALSE;
00497 }
00498 
00499 bool TVVariant::operator==( const TVVariant &v ) const
00500 {
00501     switch(d->typ) {
00502         case String:
00503             return v.toString() == toString();
00504         case Date:
00505             return v.toDate() == toDate();
00506         case Time:
00507             return v.toTime() == toTime();
00508         case Int:
00509             return v.toInt() == toInt();
00510         case Invalid:
00511             break;
00512     }
00513 
00514     return FALSE;
00515 }
00516 
00517 bool TVVariant::operator!=( const TVVariant &v ) const
00518 {
00519     return !( v == *this);
00520 }
00521 
00522 bool TVVariant::operator<( const TVVariant &v ) const
00523 {
00524     switch(d->typ) {
00525         case String:
00526             return toString().lower() < v.toString().lower();
00527         case Date:
00528             return toDate() < v.toDate();
00529         case Time:
00530             return toTime() < v.toTime();
00531         case Int:
00532             return toInt() < v.toInt();
00533         case Invalid:
00534         default:
00535             break;
00536     }
00537     return FALSE;
00538 }
00539 
00540 bool TVVariant::operator>( const TVVariant &v ) const
00541 {
00542     switch(d->typ) {
00543         case String:
00544             return toString().lower() > v.toString().lower();
00545         case Date:
00546             return toDate() > v.toDate();
00547         case Time:
00548             return toTime() > v.toTime();
00549         case Int:
00550             return toInt() > v.toInt();
00551         case Invalid:
00552         default:
00553             break;
00554     }
00555     return FALSE;
00556 }
00557 
00559 bool TVVariant::closer(TVVariant n, TVVariant o)
00560 {
00561     /* Nothing is close to an invalid, so nothing can be closer */
00562     if(d->typ == Invalid)
00563         return FALSE;
00564 
00565     /* can't be closer if of different type */
00566     if(n.type() != type())
00567         return FALSE;
00568 
00569     /* if new shares type, and old doesn't, then new is closer */
00570     if(o.type() != type())
00571         return TRUE;
00572 
00573     switch(type()){
00574         case String: {
00575             /* case for strings is close is a substring.. closer is
00576              * earlier alphabetically */
00577             QString qs1 = n.toString().lower();
00578             QString qs2 = o.toString().lower();
00579             QString qsv = toString().lower();
00580 
00581             if (!qs1.startsWith(qsv))
00582                 return FALSE;
00583 
00584             /* contains sub-str, if later than is not closer */
00585             if(QString::compare(qs1, qs2) > 0)
00586                 return FALSE;
00587             return TRUE;
00588         }
00589         case Int: {
00590             /* case for int is smallest absolute difference */
00591             int i1 = n.toInt();
00592             int i2 = o.toInt();
00593             int iv = toInt();
00594 
00595             int diff1 = (i1 - iv);
00596             if (diff1 < 0)
00597                 diff1 = -diff1;
00598             int diff2 = (i2 - iv);
00599             if (diff2 < 0)
00600                 diff2 = -diff2;
00601 
00602             if (diff1 < diff2)
00603                 return TRUE;
00604             return FALSE;
00605         }
00606         case Date: {
00607             QDate i1 = n.toDate();
00608             QDate i2 = o.toDate();
00609             QDate iv = toDate();
00610 
00611             /* definition of closer is the least difference in days */
00612             int diff1 = i1.daysTo(iv);
00613             if (diff1 < 0)
00614                 diff1 = -diff1;
00615             int diff2 = i2.daysTo(iv);
00616             if (diff2 < 0)
00617                 diff2 = -diff2;
00618 
00619             if (diff1 < diff2)
00620                 return TRUE;
00621             return FALSE;
00622         }
00623         case Time: {
00624             QTime i1 = n.toTime();
00625             QTime i2 = o.toTime();
00626             QTime iv = toTime();
00627 
00628             /* definition of closer is the least difference in days */
00629             int diff1 = i1.msecsTo(iv);
00630             if (diff1 < 0)
00631                 diff1 = -diff1;
00632             int diff2 = i2.msecsTo(iv);
00633             if (diff2 < 0)
00634                 diff2 = -diff2;
00635             if (diff1 < diff2)
00636                 return TRUE;
00637             return FALSE;
00638         }
00639         default:
00640             /* don't know how to do 'closer' on this type, hence never closer
00641              * or even close */
00642             break;
00643     }
00644     return FALSE;
00645 }
00646 
00648 bool TVVariant::close(TVVariant n)
00649 {
00650     /* Nothing is close to an invalid, so nothing can be closer */
00651     if(type() == Invalid)
00652         return FALSE;
00653 
00654     /* can't be close if of different type */
00655     if(n.type() != type())
00656         return FALSE;
00657 
00658     switch(type()){
00659         case String: {
00660             /* case for strings is close is a substring.. closer is
00661              * earlier alphabetically */
00662             QString qs1 = n.toString().lower();
00663             QString qsv = toString().lower();
00664 
00665             if (!qs1.startsWith(qsv))
00666                 return FALSE;
00667             return TRUE;
00668         }
00669         case Int:
00670         case Date:
00671         case Time:
00672             return TRUE;
00673         default:
00674             /* don't know how to do 'closer' on this type, hence never closer
00675              * or even close */
00676             break;
00677     }
00678     return FALSE;
00679 }
00680 
00688 Key::Key() : kname(), kexample(), kflags(0) { }
00689 
00690 Key::Key(QString name, TVVariant example, int flags) :
00691     kname(name), kexample(example), kflags(flags) { }
00692 
00693 Key::Key(const Key &other)
00694 {
00695   kname = other.kname;
00696   kexample = other.kexample;
00697   kflags = other.kflags;
00698 }
00699 
00700 Key& Key::operator=(const Key& key)
00701 {
00702     kname = key.kname;
00703     kexample = key.kexample;
00704     kflags = key.kflags;
00705     return *this;
00706 }
00707 
00708 QString Key::name() const
00709 {
00710     return QString(kname);
00711 }
00712 
00713 TVVariant Key::example() const
00714 {
00715     return TVVariant(kexample);
00716 }
00717 
00718 TVVariant::KeyType Key::type() const
00719 {
00720     return kexample.type();
00721 }
00722 
00723 void Key::setName(const QString &name)
00724 {
00725     kname = QString(name);
00726 }
00727 
00728 void Key::setExample(const TVVariant &e)
00729 {
00730     kexample = TVVariant(e);
00731 }
00732 
00733 int Key::flags() const
00734 {
00735     return kflags;
00736 }
00737 
00738 void Key::setFlags(int fl)
00739 {
00740     kflags = fl;
00741 }
00742 
00743 bool Key::delFlag() const
00744 {
00745     if(kflags & del_flag)
00746         return TRUE;
00747     return FALSE;
00748 }
00749 
00750 bool Key::newFlag() const
00751 {
00752     if(kflags & new_flag)
00753         return TRUE;
00754     return FALSE;
00755 }
00756 
00757 void Key::setDelFlag(bool v)
00758 {
00759     if(delFlag() != v)
00760         kflags = kflags ^ del_flag;
00761 }
00762 
00763 void Key::setNewFlag(bool v)
00764 {
00765     if(newFlag() != v)
00766         kflags = kflags ^ new_flag;
00767 }
00768 
00780 KeyList::KeyList() : QIntDict<Key>(20)
00781 {
00782     setAutoDelete(TRUE);
00783 }
00784 
00785 /* Should be deep copy, but isn't */
00786 KeyList::KeyList(const KeyList &k) : QIntDict<Key>(k)
00787 {
00788     KeyListIterator it(k);
00789   while(it.current()) {
00790     replace(it.currentKey(), new Key(*it.current()));
00791     ++it;
00792   }
00793 
00794     setAutoDelete(TRUE);
00795 }
00796 
00800 KeyList::~KeyList() {
00801 }
00802 
00803 /* Do a comparision base on Keys */
00804 bool KeyList::operator!=(const KeyList &other)
00805 {
00806     KeyListIterator it(*this);
00807 
00808     if (other.getNumFields() != getNumFields())
00809   return TRUE;
00810 
00811     while(it.current()) {
00812   //it.currentKey(), it.current();
00813   if (other.getKeyName(it.currentKey()) != getKeyName(it.currentKey()))
00814       return TRUE;
00815   if (other.getKeyType(it.currentKey()) != getKeyType(it.currentKey()))
00816       return TRUE;
00817   ++it;
00818     }
00819     return FALSE;
00820 }
00821 
00825 int KeyList::getNumFields() const
00826 {
00827     return count();
00828 }
00829 
00836 int KeyList::addKey(QString name, TVVariant example)
00837 {
00838     int i = count();
00839     while(find(i) && (i > -1))
00840         i--;
00841     replace(i, new Key(name, example, 0));
00842     return i;
00843 }
00844 
00845 int KeyList::addKey(QString name, TVVariant::KeyType type)
00846 {
00847     /* generate a valid type for the example? */
00848     TVVariant e = TVVariant("0");
00849     switch(type) {
00850         case TVVariant::String:
00851             return addKey(name, TVVariant("<undefined>").asString());
00852             break;
00853         case TVVariant::Date:
00854             return addKey(name, TVVariant(QDate::currentDate()).asDate());
00855             break;
00856         case TVVariant::Time:
00857             return addKey(name, TVVariant(QTime(0,0,0)).toTime());
00858             break;
00859         case TVVariant::Int:
00860             return addKey(name, TVVariant(0).toInt());
00861             break;
00862         default:
00863             owarn << "KeyList::addKey() Cannot make default value for type " << type << ", Key not added." << oendl;
00864             break;
00865     }
00866     return -1;
00867 }
00868 
00869 void KeyList::setKeyFlags(int i, int flag)
00870 {
00871     if(find(i))
00872         find(i)->setFlags(flag);
00873 }
00874 
00875 int KeyList::getKeyFlags(int i) const
00876 {
00877     if(find(i))
00878         return find(i)->flags();
00879     return 0;
00880 }
00881 
00882 bool KeyList::checkNewFlag(int i) const
00883 {
00884     if (find(i))
00885         return find(i)->newFlag();
00886     return false;
00887 }
00888 
00889 void KeyList::setNewFlag(int i, bool f)
00890 {
00891     if(!find(i))
00892         return;
00893     find(i)->setNewFlag(f);
00894 }
00895 
00896 bool KeyList::checkDeleteFlag(int i) const
00897 {
00898     if (find(i))
00899         return find(i)->delFlag();
00900     return false;
00901 }
00902 
00903 void KeyList::setDeleteFlag(int i, bool f)
00904 {
00905     if(!find(i))
00906         return;
00907     find(i)->setDelFlag(f);
00908 }
00909 
00913 QString KeyList::getKeyName(int i) const
00914 {
00915     if (find (i))
00916         return find(i)->name();
00917     return QString();
00918 }
00919 
00920 void KeyList::setKeyName(int i, const QString &n)
00921 {
00922     if(find(i))
00923         find(i)->setName(n);
00924 }
00925 
00929 TVVariant::KeyType KeyList::getKeyType(int i) const
00930 {
00931     if(find(i))
00932         return find(i)->type();
00933     return TVVariant::Invalid;
00934 }
00935 
00936 void KeyList::setKeyType(int i, TVVariant::KeyType t)
00937 {
00938     if(!find(i))
00939         return;
00940     switch(t) {
00941         case TVVariant::String:
00942             find(i)->setExample(TVVariant(QString("default")));
00943             return;
00944         case TVVariant::Int:
00945             find(i)->setExample(TVVariant(int(0)));
00946             return;
00947         case TVVariant::Date:
00948             find(i)->setExample(TVVariant(QDate::currentDate()));
00949             return;
00950         case TVVariant::Time:
00951             find(i)->setExample(TVVariant(QTime(0,0,0,0)));
00952             return;
00953         default:
00954             break;
00955     }
00956     return;
00957 }
00958 
00959 TVVariant KeyList::getKeyExample(int i) const
00960 {
00961     if(find(i))
00962         return find(i)->example();
00963     return TVVariant();
00964 }
00965 
00966 void KeyList::setKeyExample(int i, TVVariant example)
00967 {
00968     if(find(i))
00969         find(i)->setExample(example);
00970 }
00971 
00975 int KeyList::getKeyIndex(QString q) const
00976 {
00977     KeyListIterator it(*this);
00978 
00979     while(it.current()) {
00980         if(it.current()->name() == q)
00981             return it.currentKey();
00982         ++it;
00983     }
00984     return -1;
00985 }
00986 
00987 bool KeyList::validIndex(int i) const
00988 {
00989     if(!find(i))
00990         return FALSE;
00991     if(find(i)->delFlag())
00992         return FALSE;
00993     return TRUE;
00994 }
00995 
00996 QDataStream &operator<<( QDataStream &s, const KeyList &k)
00997 {
00998     s << k.getNumFields();
00999 
01000     KeyListIterator it(k);
01001 
01002     while(it.current()) {
01003         s << (Q_UINT16)it.currentKey();
01004         s << it.current()->name();
01005         s << it.current()->example();
01006         s << (Q_UINT16)it.current()->flags();
01007         ++it;
01008     }
01009     return s;
01010 }
01011 
01012 QDataStream &operator>>( QDataStream &s, KeyList &k)
01013 {
01014     int i;
01015     int size;
01016     int index = 0;
01017     int flags = 0;
01018     TVVariant type = TVVariant();
01019     QString name;
01020 
01021     s >> size;
01022 
01023     for (i=0; i < size; i++) {
01024         s >> (Q_UINT16 &)index;
01025         s >> name;
01026         s >> type;
01027         s >> (Q_UINT16 &)flags;
01028         k.replace(index, new Key(name, type, flags));
01029     }
01030     return s;
01031 }
01032 
01046 DataElem::DataElem(DBStore *c) : values(20)
01047 {
01048     int size;
01049     contained = c;
01050     size = c->getNumFields();
01051     values.setAutoDelete(TRUE);
01052 }
01053 
01057 DataElem::~DataElem() {
01058 }
01059 
01060 
01061 
01062 QDataStream &operator<<( QDataStream &s, const DataElem &d)
01063 {
01064     int size = d.getNumFields();
01065 
01066     s << size; /* redundent data but makes streaming easier */
01067     KeyList k = d.getKeys();
01068 
01069     KeyListIterator it(k);
01070 
01071     while(it.current()) {
01072         s << (Q_UINT16)it.currentKey();
01073         s << d.getField(it.currentKey());
01074         ++it;
01075     }
01076     return s;
01077 }
01078 
01079 QDataStream &operator>>( QDataStream &s, DataElem &d)
01080 {
01081     int i;
01082     int size;
01083     TVVariant t;
01084     Q_UINT16 index = 0;
01085 
01086     s >> size; /* redundent data but makes streaming easier */
01087     if (size != d.getNumFields()) {
01088         owarn << "DataSize mis-match" << oendl;
01089         return s; /* sanity check failed.. don't load */
01090     }
01091 
01092     for(i = 0; i < size; i++) {
01093         s >> index;
01094         s >> t;
01095         d.setField(index, t);
01096     }
01097     return s;
01098 }
01099 
01101 int DataElem::getNumFields() const
01102 {
01103     return contained->getNumFields();
01104 }
01105 
01106 KeyList DataElem::getKeys() const
01107 {
01108     return *(contained->getKeys());
01109 }
01110 
01118 bool DataElem::hasValidValue(int i) const
01119 {
01120     if(!values.find(i))
01121         return FALSE;
01122     if(!contained->getKeys()->validIndex(i))
01123         return FALSE;
01124     return values.find(i)->isValid();
01125 }
01126 
01134 bool DataElem::hasValidValue(QString qs) const
01135 {
01136     int i = contained->getKeyIndex(qs);
01137     return hasValidValue(i);
01138 }
01139 
01141 TVVariant::KeyType DataElem::getFieldType(int i) const
01142 {
01143     return contained->getKeyType(i);
01144 }
01145 
01147 TVVariant::KeyType DataElem::getFieldType(QString qs) const
01148 {
01149     int i = contained->getKeyIndex(qs);
01150     return contained->getKeyType(i);
01151 }
01152 
01157 TVVariant DataElem::getField(int i) const
01158 {
01159     if(hasValidValue(i))
01160         return TVVariant(*values.find(i));
01161     return TVVariant();
01162 }
01163 
01168 TVVariant DataElem::getField(QString qs) const
01169 {
01170     int i = contained->getKeyIndex(qs);
01171     return getField(i);
01172 }
01173 
01181 void DataElem::setField(int i, QString q)
01182 {
01183     /* from the type of the field, parse q and store */
01184     TVVariant::KeyType kt = contained->getKeyType(i);
01185 
01186     TVVariant t = TVVariant(q);
01187 
01188     switch(kt) {
01189         case TVVariant::Int: {
01190             t.asInt();
01191             setField(i, t);
01192       return;
01193         }
01194         case TVVariant::String: {
01195             t.asString();
01196             setField(i, t);
01197             return;
01198         }
01199         case TVVariant::Date: {
01200             t.asDate();
01201             setField(i, t);
01202             return;
01203         }
01204         case TVVariant::Time: {
01205             t.asTime();
01206             setField(i, t);
01207             return;
01208         }
01209         default:
01210             owarn << "DataElem::setField(" << i << ", " << q << ") No valid type found" << oendl;
01211     }
01212 }
01213 
01221 void DataElem::setField(int i, TVVariant value)
01222 {
01223     if (value.isValid()) {
01224         values.remove(i);
01225         values.replace(i, new TVVariant(value));
01226     }
01227 }
01228 
01236 void DataElem::setField(QString qs, QString q)
01237 {
01238     /* from the type of the field, parse q and store */
01239     int i = contained->getKeyIndex(qs);
01240     setField(i, qs);
01241 }
01242 
01250 void DataElem::setField(QString qs, TVVariant value)
01251 {
01252     int i = contained->getKeyIndex(qs);
01253     setField(i, value);
01254 }
01255 
01256 void DataElem::unsetField(int i) {
01257     values.remove(i);
01258 }
01259 
01260 void DataElem::unsetField(QString qs)
01261 {
01262     int i = contained->getKeyIndex(qs);
01263     unsetField(i);
01264 }
01265 
01269 QString DataElem::toQString() const
01270 {
01271     /* lets make an attempt at this function */
01272     int i;
01273     QString scratch = "";
01274 
01275     QIntDictIterator<TVVariant> it(values);
01276 
01277     while (it.current()) {
01278       i = it.currentKey();
01279         if(hasValidValue(i)) {
01280             scratch += "<B>" + contained->getKeyName(i) + ":</B> ";
01281             scratch += getField(i).toString();
01282             scratch += "<br>";
01283         }
01284         ++it;
01285     }
01286     return scratch;
01287 }
01288 
01290 QString DataElem::toQString(int i) const
01291 {
01292     if(hasValidValue(i)) {
01293         return getField(i).toString();
01294     }
01295     return "";
01296 }
01298 QString DataElem::toSortableQString(int i) const
01299 {
01300     QString scratch = "";
01301     if(hasValidValue(i)) {
01302         switch (contained->getKeyType(i)) {
01303             case TVVariant::String: {
01304                 scratch += getField(i).toString();
01305                 break;
01306             }
01307             case TVVariant::Int: {
01308                 scratch.sprintf("%08d", getField(i).toInt());
01309                 break;
01310             }
01311             case TVVariant::Date: {
01312                 static QDate epochD(1800, 1, 1);
01313                 scratch.sprintf("%08d",
01314                                 epochD.daysTo(getField(i).toDate()));
01315                 break;
01316             }
01317             case TVVariant::Time: {
01318                 static QTime epochT(0, 0, 0);
01319                 scratch.sprintf("%08d",
01320                                 epochT.msecsTo(getField(i).toTime()));
01321                 break;
01322             }
01323             default:
01324                 scratch += "Unknown type";
01325                 break;
01326         }
01327     }
01328     return scratch;
01329 }
01330 
01331 /* compare functions */
01332 
01333 bool DataElem::lessThan(int i, TVVariant v) const
01334 {
01335     if (!hasValidValue(i)) return FALSE;
01336 
01337     if (getField(i).type() != v.type())
01338         return FALSE;
01339 
01340     return (getField(i) < v);
01341 }
01342 
01343 bool DataElem::moreThan(int i, TVVariant v) const
01344 {
01345     if (!hasValidValue(i)) return FALSE;
01346 
01347     if (getField(i).type() != v.type())
01348         return FALSE;
01349 
01350     return (getField(i) > v);
01351 }
01352 
01353 bool DataElem::equalTo(int i, TVVariant v) const
01354 {
01355     if (!hasValidValue(i)) return FALSE;
01356 
01357     if (getField(i).type() != v.type())
01358         return FALSE;
01359 
01360     return (getField(i) == v);
01361 }
01362 
01363 bool DataElem::contains(int i, TVVariant v) const
01364 {
01365     if (!hasValidValue(i)) return FALSE;
01366 
01367     if (getField(i).type() != v.type())
01368         return FALSE;
01369 
01370     switch(getField(i).type()) {
01371         case TVVariant::String: {
01372             QString qs1 = getField(i).toString().lower();
01373             QString qs2 = v.toString().lower();
01374             if (qs1.contains(qs2) > 0) return TRUE;
01375             break;
01376         }
01377             /* meaningless for ints */
01378             /* meaningless for time */
01379             /* meaningless for dates */
01380         case TVVariant::Int:
01381         case TVVariant::Time:
01382         case TVVariant::Date:
01383             break;
01384         default:
01385             owarn << "Tried to compare unknown data type" << oendl;
01386     }
01387     return FALSE;
01388 }
01389 
01390 bool DataElem::startsWith(int i, TVVariant v) const
01391 {
01392     if (!hasValidValue(i)) return FALSE;
01393 
01394     if (getField(i).type() != v.type())
01395         return FALSE;
01396 
01397     switch(getField(i).type()) {
01398         case TVVariant::String: {
01399             QString qs1 = getField(i).toString().lower();
01400             QString qs2 = v.toString().lower();
01401             return qs1.startsWith(qs2);
01402         }
01403             /* meaningless for ints */
01404             /* meaningless for time */
01405             /* meaningless for dates */
01406         case TVVariant::Int:
01407         case TVVariant::Time:
01408         case TVVariant::Date:
01409             return FALSE;
01410         default:
01411             owarn << "Tried to compare unknown data type" << oendl;
01412     }
01413     return FALSE;
01414 }
01415 
01416 bool DataElem::endsWith(int i, TVVariant v) const
01417 {
01418     if (!hasValidValue(i)) return FALSE;
01419 
01420     if (getField(i).type() != v.type())
01421         return FALSE;
01422 
01423     switch(getField(i).type()) {
01424         case TVVariant::String: {
01425             QString qs1 = getField(i).toString().lower();
01426             QString qs2 = v.toString().lower();
01427             return qs1.startsWith(qs2);
01428         }
01429             /* meaningless for ints */
01430             /* meaningless for time */
01431             /* meaningless for dates */
01432         case TVVariant::Int:
01433         case TVVariant::Time:
01434         case TVVariant::Date:
01435             return FALSE;
01436         default:
01437             owarn << "Tried to compare unknown data type" << oendl;
01438     }
01439     return FALSE;
01440 }
01441 
01454 bool DataElem::closer(DataElem*d1, DataElem *d2, TVVariant target, int column)
01455 {
01456     int type;
01457 
01458     if(!d1) return FALSE;
01459 
01460     if (!d1->hasValidValue(column)) return FALSE;
01461 
01462     if(!target.isValid()) return FALSE;
01463 
01464     type = d1->getField(column).type();
01465 
01466     if(d2) {
01467         if (type != d2->getField(column).type()) {
01468                 /* can't do compare */
01469                 owarn << "Tried to compare two incompatable types" << oendl;
01470                 return FALSE;
01471         }
01472         return target.closer(d1->getField(column), d2->getField(column));
01473     }
01474     return target.close(d1->getField(column));
01475 }

Generated on Sat Nov 5 16:17:08 2005 for OPIE by  doxygen 1.4.2