oopapidocs  2.0
dataobject.cpp
00001 #include <QString>
00002 #include <QMetaObject>
00003 #include <QMetaProperty>
00004 #include <QList>
00005 #include <QDebug>
00006 #include <QStringList>
00007 #include "dataobject.h"
00008 
00009 #include "qobjectwriter.h"
00010 
00011 QString DataObject::toString() const {
00012     QObjectWriter w;
00013     return w.toString(this);
00014 }
00015 
00016 
00017 DataObject::DataObject (QString name) {
00018     setObjectName(name);
00019 }
00020 
00021 
00022 DataObject& DataObject::operator=(const DataObject& other) {
00023         readFrom(other);
00024         return (*this);
00025 }
00026 
00027 DataObject::~DataObject() {}
00028 DataObject::DataObject(QObject* parent) : QObject(parent) {}
00029 
00030 /*
00031 QString DataObject::validInputs(QString propertyName) const {
00032     return propertyName + " must be " + ConstraintMgr().getConstraint(className(), propertyName)->toString();
00033 }
00034 */
00035 //start id="setproperty"
00036 bool DataObject::setProperty(const QString& propertyName, const QVariant &value) {
00037     return QObject::setProperty(propertyName.toAscii(), value);
00038 }
00039 //end
00040 bool DataObject::setProperty(const char* propName, const QVariant& qv) {
00041     return QObject::setProperty(propName, qv);
00042 }
00043 
00044 
00045 void DataObject::adoptChildren(QObject* wayward) {
00046     QObjectList children = wayward->children();
00047     foreach (QObject* obj, children) {
00048         obj->setParent(this);
00049     }
00050 }
00051 
00052 bool DataObject::equals(const QObject& left, const QObject& right, 
00053                         bool checkChildren)  {
00054     if (&left == &right)
00055         return true;
00056     if (left.objectName() != right.objectName()) return false;
00057     QStringList propnames = propertyNames(&left);
00058     foreach (const QString& propname, propnames) {
00059         QVariant qvOther = right.property(propname.toUtf8());
00060         // if propname is not one of other's properites then
00061         // property() returns an invalid variant.
00062         if (! qvOther.isValid())
00063             return false;
00064         // Temporary variables for debugging purposes
00065         if (left.property(propname.toUtf8()) != qvOther) {
00066             QString thisPropStr = left.property(propname.toUtf8()).toString();
00067             QString otherPropStr = qvOther.toString();
00068             qDebug() << QString("Prop: %1 %2 != %3").arg(propname)
00069                     .arg(left.property(propname.toUtf8()).toString())
00070                     .arg(qvOther.toString());
00071             return false;
00072         }
00073     }
00074 
00075     if (! checkChildren)
00076         return true;
00077 
00078     // Equal so far - now see if this and other have children
00079     // TODO: this should be fixed for QObjects:
00080     QList<QObject*> leftKids = left.findChildren<QObject*>(QString());
00081     QList<QObject*> rightKids = right.findChildren<QObject*>(QString());
00082 
00083     //    if (0 == thesekids  && 0 == otherkids)
00084     //      return true;  // no children
00085     if (leftKids.count() != rightKids.count())
00086         return false;    // different numbers of children
00087 
00088     // At this point both have same number of children.
00089     // Now iterate through them.
00090 
00091     QListIterator<QObject*> lit( leftKids );
00092     QListIterator<QObject*> rit( rightKids);
00093     QObject*leftChild;
00094     QObject*rightChild;
00095     while (lit.hasNext()) {
00096         leftChild = lit.next();
00097         rightChild = rit.next();
00098         // skip over grandchildren and greatgrandchildren
00099         if (leftChild->parent() != &left) continue;
00100         if (!equals(*leftChild,*rightChild, checkChildren))
00101             return false;
00102     }
00103     return true;
00104 }
00105 
00106 bool operator==(const QObject& left, const QObject& right) {
00107     return DataObject::equals(left, right, true);
00108 }
00109 
00110 //start id=readwrite
00111 bool DataObject::readFrom(const QObject& source) {
00112     bool retval = true;
00113     const QMetaObject* meta = source.metaObject();
00114     int count = meta->propertyCount();
00115     for (int i=0; i<count; ++i) {
00116         QMetaProperty metap = meta->property(i);
00117         const char* pname = metap.name();
00118         if (metap.isWritable()) {
00119             retval = setProperty(pname, source.property(pname))
00120                      && retval;
00121         }
00122     }
00123     emit dataObjectChanged(objectName());
00124     return retval;
00125 }
00126 
00127 
00128 QString DataObject::className() const
00129 {
00130     QVariant qv = property("className");
00131     if (!qv.isNull()) {
00132         return qv.toString();
00133     }
00134     return metaObject()->className();
00135 }
00136 
00137 
00138 //end
00139 
00140 QStringList DataObject::propertyNames() const {
00141     return propertyNames(this);
00142 }
00143 
00144 QStringList DataObject::propertyNames(const QObject* that) {
00145     QStringList retval;
00146     const QMetaObject* meta = that->metaObject();
00147     for (int i=0; i<meta->propertyCount(); ++i) {
00148         retval += meta->property(i).name();
00149     }
00150     return retval;
00151 }
00152 
00153 uint DataObject::numProperties() const {
00154     return propertyNames().count();
00155 }
00156 
00157 QMetaProperty DataObject::metaProperty(const QString& propname) const {
00158     const QMetaObject* meta = this->metaObject();
00159     int i = meta->indexOfProperty(propname.toAscii());
00160     return meta->property(i);
00161 }
00162 
00163 QMetaProperty DataObject::metaProperty(int i) const {
00164     return metaObject()->property(i);
00165 }
00166 QVariant DataObject::property ( QString name ) const {
00167     return QObject::property(name.toAscii());
00168 }
00169 
00170 QVariant DataObject::property (const char* name ) const {
00171     return QObject::property(name);
00172 }
00173 
00174 DataObject* DataObject::clone( bool deep ) const  {
00175     DataObject* retval = new DataObject(); /* TODO:
00176         Rewrite this method to use a template to create
00177         a new instance of the same type */
00178 
00179     writeTo(*retval);
00180     if (deep) {
00181         foreach (DataObject* child, findChildren<DataObject*>()) {
00182             if (child->parent() == this) {
00183                 DataObject* childClone = child->clone(deep);
00184                 childClone->setParent(retval);
00185             }
00186         }
00187     }
00188     return retval;
00189 }
00190 
00191 //start id=readwrite
00192 bool DataObject::writeTo(QObject& dest) const {
00193     bool result = true;
00194     foreach (const QString &propname, propertyNames()) {
00195         if (metaProperty(propname).isWritable()) {
00196             QVariant val = property(propname);
00197             result = dest.setProperty(propname.toAscii(), val) && result;
00198         }
00199     }
00200     return result;
00201 }
00202 //end
 All Classes Namespaces Functions Enumerations