Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members  

PropertyList.cpp

00001 // ***************************************************************************
00002 //                          PropertyList.cpp  -  description
00003 //                             -------------------
00004 //    begin                : Thu Oct 5 2000
00005 //    Copyright (C) 2000 Stephan Beal & Rusty Ballinger
00006 //                       stephan@wanderinghorse.net & rusty@sgi.com
00007 // This class is 95% code by Rusty, simply remodelled by Stephan for a slightly
00008 // more heirarchical approach. Gawd Bless Rusty.
00009 // ***************************************************************************
00010 // *                                                                         *
00011 // *   This program is free software; you can redistribute it and/or modify  *
00012 // *   it under the terms of the GNU General Public License as published by  *
00013 // *   the Free Software Foundation; either version 2 of the License, or     *
00014 // *   (at your option) any later version.                                   *
00015 // *                                                                         *
00016 // ***************************************************************************
00017 
00018 #include <qcolor.h>
00019 #include <qregexp.h>
00020 #include <fun/ConfigFile.h>
00021 #include <iostream>
00022 #include <qsize.h>
00023 #include <fun/SerialTree.h>
00024 #include <fun/Serializer.h>
00025 #include <fun/Deserializer.h>
00026 
00027 #include "PropertyList.h"
00028 
00029 namespace fun {
00030 
00031         INSTANTIATOR(PropertyList);
00032         INSTANTIATOR(KeyValuePair);
00033 
00034         PropertyList::PropertyList() : QObject(), Serializable()
00035         {
00036         }
00037 
00038         PropertyList::~PropertyList()
00039         {
00040         }
00041 
00042         void PropertyList::serialize(Serializer &ser) const
00043         {
00044                 Serializable::serialize(ser);
00045                 ser.setSerializableClass("PropertyList");
00046                 for( QValueList<QString>::ConstIterator it = order.begin(); it != order.end(); ++it )
00047                 {
00048                         Entry *e = data.find(*it);
00049                         if( e == NULL ) continue;
00050                         ser.putSerializable( "property", KeyValuePair( *it, e->val, e->cmnt) );
00051                 }
00052         }
00053 
00054         void PropertyList::deserialize(const Deserializer &ser)
00055         {
00056                 Serializable::deserialize(ser);
00057                 QString _k;
00058                 QString _v;
00059                 int i = 0;
00060                 QPtrList<Serializable> tl;
00061                 ser.getSerializables("property", tl, "KeyValuePair");
00062                 KeyValuePair *p = 0;
00063                 for(QPtrListIterator<Serializable> it(tl); it.current(); ++it)
00064                 {
00065                         p = dynamic_cast<KeyValuePair *>(it.current());
00066                         if(!p) continue; // bad?
00067                         set( p->key(), p->val() );
00068                         setComment( p->key(), p->comment() );
00069                 }
00070 
00071         }
00072 
00073         bool
00074         PropertyList::isSet(const QString &key) const
00075         {
00076                 return data.find(key) != NULL;
00077         }
00078 
00079         QString
00080         PropertyList::getString(const QString &key, QString defaultVal) const
00081         {
00082                 if( key.isEmpty() || key.isNull() ) return defaultVal;
00083                 Entry *e = data.find(key);
00084                 return e ? e->val : defaultVal;
00085         }
00086 
00087         QString
00088         PropertyList::get(const QString &key, QString defaultVal) const
00089         {
00090                 return getString( key, defaultVal );
00091         }
00092 
00093 
00094         bool
00095         PropertyList::isInt(const QString &key) const
00096         {
00097                 Entry *e = data.find(key);
00098                 if(!e) return false;
00099                 bool ok;
00100                 e->val.toInt(&ok);
00101                 return ok;
00102         }
00103 
00104         int
00105         PropertyList::getInt(const QString &key, int defaultVal) const
00106         {
00107                 Entry *e = data.find(key);
00108                 if(!e) return defaultVal;
00109                 bool ok;
00110                 int rv = e->val.toInt(&ok);
00111                 return ok ? rv : defaultVal;
00112         }
00113 
00114         bool
00115         PropertyList::isBool(const QString &key) const
00116         {
00117                 Entry *e = data.find(key);
00118                 if(!e) return false;
00119                 return isBool(e->val);
00120         }
00121 
00122         bool
00123         PropertyList::getBool(const QString &key, bool defaultVal) const
00124         {
00125                 Entry *e = data.find(key);
00126                 if(!e) return defaultVal;
00127                 bool ret = false; //boolTable.find( e->val );
00128                 if ( e->val.find( QRegExp("^true"),FALSE) >=0 ) return  true;
00129                 if ( e->val.find( QRegExp("^false"),FALSE) >=0 ) return  false;
00130                 if ( e->val.find( QRegExp("^1")) >=0 ) return  true;
00131                 if ( e->val.find( QRegExp("^0")) >=0 ) return  false;
00132                 if ( e->val.find( QRegExp("^on"),FALSE) >=0 ) return  true;
00133                 if ( e->val.find( QRegExp("^off"),FALSE) >=0 ) return  false;
00134                 if ( e->val.find( QRegExp("^y"),FALSE) >=0 ) return  true;
00135                 if ( e->val.find( QRegExp("^n"),FALSE) >=0 ) return  false;
00136                 //  if ( boolTable.find( e->val ) ) ret = boolTable[e->val];
00137                 //  //const bool ok = isBool( key ); //boolTable.find( key.data() );
00138                 //debug( "PropertyList::getBool( %s, %d ) returning %d from e->val of %s", key.data(), defaultVal, ret,e->val.data() );
00139                 return ret;
00140         }
00141 
00142         bool
00143         PropertyList::isDouble(const QString &key) const
00144         {
00145                 Entry *e = data.find(key);
00146                 if(!e) return false;
00147                 bool ok;
00148                 e->val.toDouble(&ok);
00149                 return ok;
00150         }
00151 
00152         double
00153         PropertyList::getDouble(const QString &key, double defaultVal) const
00154         {
00155                 Entry *e = data.find(key);
00156                 if(!e) return defaultVal;
00157                 bool ok;
00158                 double rv = e->val.toDouble(&ok);
00159                 return ok ? rv : defaultVal;
00160         }
00161 
00162         bool
00163         PropertyList::isColor(const QString &key) const
00164         {
00165                 Entry *e = data.find(key);
00166                 if(!e) return false;
00167                 QColor tc(e->val);
00168                 return tc.isValid();  //  XXX is this correct?
00169         }
00170 
00171         QColor
00172         PropertyList::getColor(const QString &key, QColor defaultVal) const
00173         {
00174                 Entry *e = data.find(key);
00175                 if(!e) return defaultVal;
00176                 QString colorstring = e->val;
00177                 if( colorstring.length() == 6 ) // assume RRGGBB, though this would also be the case for some color names :/
00178                 {
00179                         colorstring.insert( 0, '#' );
00180                 }
00181                 QColor tc(colorstring);
00182                 return tc.isValid() ? tc : defaultVal;
00183         }
00184 
00185         void
00186         PropertyList::set(const QString &key, const QString &val, const QString &comment )
00187         {
00188                 if( key.isNull() || key.isEmpty() ) return; // added by stephan, to avoid a crash which happens when null-keyed items are serialized.
00189                 Entry *e = data.find(key);
00190                 bool localChange = false;
00191                 if(e == NULL)
00192                 {
00193                         e = new Entry;
00194                         data.replace(key, e);
00195                         order.append(key);
00196                         changed = true;
00197                         localChange = true;
00198                 }
00199                 if(e->val != val)
00200                 {
00201                         e->val = val;
00202                         changed = true;
00203                         localChange = true;
00204                 }
00205                 setComment( key, comment );
00206                 // todo: localChange = true if comment is actually changed. it's currently broken, but no code has relied on that feature.
00207                 if ( ! localChange ) return;
00208                 emit signalChange( key );
00209         }
00210 
00211         void
00212         PropertyList::set(const QString &key, int val)
00213         {
00214                 QString ts;
00215                 set(key, ts.setNum(val));
00216         }
00217 
00218         void
00219         PropertyList::set(const QString &key, bool val)
00220         {
00221                 QString ts(val ? "true" : "false");
00222                 set(key, ts);
00223                 //debug( "PropertyList::set( %s, BOOlEAN[%s] )", key.data(), ts.data() );
00224         }
00225 
00226         void
00227         PropertyList::set(const QString &key, double val)
00228         {
00229                 QString ts;
00230                 set(key, ts.setNum(val));
00231         }
00232 
00233         void
00234         PropertyList::set(const QString &key, const QColor &val)
00235         {
00236                 QString ts;
00237                 set(key, ts.sprintf("#%02x%02x%02x", val.red(), val.green(), val.blue()));
00238         }
00239 
00240         void
00241         PropertyList::unset(const QString &key)
00242         {
00243                 if(data.remove(key)) changed = true;
00244                 if ( changed ) emit signalChange( key );
00245         }
00246 
00247         void
00248         PropertyList::setComment(const QString &key, const QString &comment)
00249         {
00250                 Entry *e = data.find(key);
00251                 if(e == NULL)
00252                 {
00253                         e = new Entry;
00254                         data.replace(key, e);
00255                         order.append(key);
00256                         changed = true;
00257                 }
00258                 if(e->cmnt != comment)
00259                 {
00260                         e->cmnt = comment;
00261                         changed = true;
00262                 }
00263         }
00264 
00265         QString
00266         PropertyList::getComment(const QString &key) const
00267         {
00268                 Entry *e = data.find(key);
00269                 return e ? e->cmnt : QString();
00270         }
00271 
00272 
00273 
00274 
00275         bool
00276         PropertyList::mergeIn( const PropertyList *config )
00277         {
00278                 if ( ! config ) return false;
00279                 //debug( "PropertyList::mergeIn()" );
00280                 const QValueList<QString> keys = ((PropertyList *)config)->keys();
00281                 QVStringList::ConstIterator it;
00282                 for( it = keys.begin(); it != keys.end(); ++it )
00283                 {
00284                         set( (*it), config->get( (*it) ) );
00285                         setComment( (*it), config->getComment( (*it) ) );
00286                 }
00287 
00288                 //  for(QValueList<QString>::ConstIterator it = order.begin(); it != order.end(); ++it)
00289                 //  {
00290                 //      Entry *e = data.find(*it);
00291                 //XXX assert(e)?
00292                 //      os << *it << " = " << ts << endl;
00293                 //  }
00294                 return true;
00295 
00296         }
00297 
00298         const QValueList<QString> &PropertyList::keys()
00299         {
00300                 return order;
00301         }
00302 
00303         void PropertyList::slotEmitUpdate()
00304         {
00305                 emit signalChange( QString() );
00306         }
00307 
00308         void
00309         PropertyList::set( const QString &key, const QPoint &val )
00310         {
00311                 QString ts;
00312                 ts.sprintf( "%d,%d", val.x(), val.y() );
00313                 set( key, ts );
00314         }
00315 
00316 
00317         QPoint
00318         PropertyList::getPoint( const QString &key, const QPoint &dflt )
00319         {
00320                 QString ts = getString( key, QString().sprintf("%d,%d",dflt.x(), dflt.y()) );
00321                 if( ts.isEmpty() ) return dflt;
00322                 int i = ts.find( "," );
00323                 if( i < 1 || i >= ts.length()-1 ) i = ts.find( "x" ); // just for convenience
00324                 if( i < 1 || i >= ts.length()-1 ) return dflt;
00325                 int x = ts.left( i ).toInt();
00326                 int y = ts.right( ts.length()-1 - i ).toInt();
00327                 //CERR << "getPoint( "<<key<<" ) == "<<x<<","<<y<<endl;
00328                 return QPoint( x, y );
00329         }
00330 
00331 
00332         QSize
00333         PropertyList::getSize( const QString &key, const QSize &dflt )
00334         {
00335                 QPoint p = getPoint( key, QPoint(dflt.width(),dflt.height()) );
00336                 return QSize( p.x(), p.y() );
00337         }
00338 
00339         void
00340         PropertyList::set( const QString &key, const QSize &val )
00341         {
00342                 set( key, QPoint( val.width(), val.height() ) );
00343                 return;
00344         }
00345 
00346         //********************************************************************************
00347         //********************************************************************************
00348         //********************************************************************************
00349 
00350         KeyValuePair::KeyValuePair( QString key, QString value, QString comment )
00351         {
00352                 k = key;
00353                 v = value;
00354                 c = comment;
00355         }
00356 
00357         KeyValuePair::~KeyValuePair()
00358         {
00359         }
00360         QString KeyValuePair::key() { return k; }
00361         QString KeyValuePair::val() { return v; }
00362         QString KeyValuePair::comment() { return c; }
00363 
00364         void 
00365         KeyValuePair::deserialize(const Deserializer &ser) 
00366         { 
00367                 Serializable::deserialize(ser);
00368                 k = ser.getString( "key", QString() );
00369                 v = ser.getString( "value", QString() );
00370                 c = ser.getString( "comment", QString() );
00371         }
00372         void 
00373         KeyValuePair::serialize(Serializer &ser) const 
00374         { 
00375                 ser.setSerializableClass("KeyValuePair" );
00376                 ser.putString( "key", k );
00377                 ser.putString( "value", v );
00378                 ser.putString( "comment", c );
00379         }
00380 
00381 
00382 }; // namespace fun

Generated on Mon Aug 11 14:06:55 2003 for libfunutil by doxygen1.2.18