oopapidocs
2.0
|
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