00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <QtDebug>
00025 #include <QByteArray>
00026 #include <QDataStream>
00027 #include <QTextStream>
00028
00029 #include "klfpobj.h"
00030
00031
00032 KLFAbstractPropertizedObject::KLFAbstractPropertizedObject()
00033 {
00034 }
00035 KLFAbstractPropertizedObject::~KLFAbstractPropertizedObject()
00036 {
00037 }
00038
00039 KLFSpecifyableType::KLFSpecifyableType()
00040 {
00041 }
00042 KLFSpecifyableType::~KLFSpecifyableType()
00043 {
00044 }
00045
00046
00047
00048
00049
00050
00051 QMap<QString,QVariant> KLFAbstractPropertizedObject::allProperties() const
00052 {
00053 QMap<QString,QVariant> data;
00054 QStringList pnames = propertyNameList();
00055 foreach (QString pname, pnames) {
00056 data[pname] = property(pname);
00057 }
00058 return data;
00059 }
00060
00061 bool KLFAbstractPropertizedObject::setAllProperties(const QMap<QString,QVariant>& data)
00062 {
00063 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00064 klfDbg("data="<<data) ;
00065 bool allok = true;
00066 for (QVariantMap::const_iterator it = data.begin(); it != data.end(); ++it) {
00067 bool ok = setProperty(it.key(), it.value());
00068 if (!ok) {
00069 allok = false;
00070 qWarning()<<KLF_FUNC_NAME<<": Can't set property "<<it.key()<<" to "<<it.value();
00071 }
00072 }
00073 return allok;
00074 }
00075
00076
00077
00078
00079 KLF_EXPORT QDataStream& operator<<(QDataStream& stream, const KLFEnumType& e)
00080 {
00081 return stream << e.specification() << qint32(e.value());
00082 }
00083 KLF_EXPORT QDataStream& operator>>(QDataStream& stream, KLFEnumType& e)
00084 {
00085 QByteArray s;
00086 qint32 x;
00087 stream >> s >> x;
00088 e.setSpecification(s);
00089 e.setValue(x);
00090 return stream;
00091 }
00092
00093
00094
00095
00096
00097
00098
00099 KLFPropertizedObject::KLFPropertizedObject(const QString& propNameSpace)
00100 : pPropNameSpace(propNameSpace)
00101 {
00102
00103 if (!pRegisteredProperties.contains(propNameSpace))
00104 pRegisteredProperties[propNameSpace] = QMap<QString,int>();
00105 if (!pRegisteredPropertiesMaxId.contains(propNameSpace))
00106 pRegisteredPropertiesMaxId[propNameSpace] = -1;
00107 }
00108
00109 KLFPropertizedObject::~KLFPropertizedObject()
00110 {
00111 }
00112
00113
00114 QVariant KLFPropertizedObject::property(const QString& propname) const
00115 {
00116 int propId = propertyIdForName(propname);
00117 if (propId < 0) {
00118 qWarning("%s[%s](): Property `%s' not registered.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
00119 qPrintable(propname));
00120 return QVariant();
00121 }
00122 return property(propId);
00123 }
00124 QVariant KLFPropertizedObject::property(int propId) const
00125 {
00126 if (propId >= 0 && propId < pProperties.size()) {
00127
00128 return pProperties[propId];
00129 }
00130 if (propId < 0) {
00131 qWarning("%s[%s](%d): invalid property ID.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
00132 propId);
00133 return QVariant();
00134 }
00135
00136 return QVariant();
00137 }
00138
00139 QVariant KLFPropertizedObject::property(const QString& propname, const QVariant& defaultValue) const
00140 {
00141 int propId = propertyIdForName(propname);
00142 if (propId < 0) {
00143 return defaultValue;
00144 }
00145 QVariant value = property(propId);
00146 if (value.isValid())
00147 return value;
00148 return defaultValue;
00149 }
00150
00151 bool KLFPropertizedObject::hasPropertyValue(const QString& propName) const
00152 {
00153 return property(propName, QVariant()).isValid();
00154 }
00155
00156 bool KLFPropertizedObject::hasPropertyValue(int propId) const
00157 {
00158 if (!propertyIdRegistered(propId))
00159 return false;
00160
00161 return hasPropertyValue(propertyNameForId(propId));
00162 }
00163
00164
00165 void KLFPropertizedObject::propertyValueChanged(int , const QVariant& ,
00166 const QVariant& )
00167 {
00168
00169 }
00170
00171 bool KLFPropertizedObject::doSetProperty(const QString& propname, const QVariant& value)
00172 {
00173 if ( ! propertyNameRegistered(propname) ) {
00174 qWarning("%s[%s](): Property `%s' not registered.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
00175 qPrintable(propname));
00176 return false;
00177 }
00178 return doSetProperty(propertyIdForName(propname), value);
00179 }
00180 bool KLFPropertizedObject::doSetProperty(int propId, const QVariant& value)
00181 {
00182 if (propId >= 0 && propId < pProperties.size()) {
00183
00184 QVariant oldvalue = pProperties[propId];
00185 pProperties[propId] = value;
00186 propertyValueChanged(propId, oldvalue, value);
00187 return true;
00188 }
00189 if (propId < 0) {
00190 qWarning("%s[%s](id=%d): invalid property ID.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
00191 propId);
00192 return false;
00193 }
00194
00195
00196 int maxId = propertyMaxId();
00197 if (propId <= maxId) {
00198 pProperties.resize(maxId + 1);
00199 }
00200 if (propId < 0 || propId >= pProperties.size() ||
00201 ! propertyIdRegistered(propId) ) {
00202 qWarning("%s[%s](id=%d): invalid property id.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
00203 propId);
00204 return false;
00205 }
00206 QVariant oldvalue = pProperties[propId];
00207 pProperties[propId] = value;
00208 propertyValueChanged(propId, oldvalue, value);
00209 return true;
00210 }
00211 int KLFPropertizedObject::doLoadProperty(const QString& propname, const QVariant& value)
00212 {
00213 klfDbg("propname="<<propname<<" value="<<value) ;
00214 int propId = propertyIdForName(propname);
00215 if ( propId < 0 ) {
00216
00217 propId = registerProperty(propname);
00218 if (propId < 0)
00219 return -1;
00220 }
00221 doSetProperty(propId, value);
00222 return propId;
00223 }
00224
00225 QList<int> KLFPropertizedObject::propertyIdList() const
00226 {
00227 QList<int> idList;
00228 int k;
00229
00230 for (k = 0; k < pProperties.size(); ++k) {
00231 if (pProperties[k].isValid())
00232 idList << k;
00233 }
00234 return idList;
00235 }
00236
00237 QStringList KLFPropertizedObject::propertyNameList() const
00238 {
00239 QStringList propSetList;
00240 int k;
00241
00242 for (k = 0; k < pProperties.size(); ++k) {
00243 if (pProperties[k].isValid())
00244 propSetList << propertyNameForId(k);
00245 }
00246 return propSetList;
00247 }
00248
00249
00250
00251
00252 QMap<QString,QVariant> KLFPropertizedObject::allProperties() const
00253 {
00254 QList<int> propertyList = propertyIdList();
00255 QMap<QString,QVariant> properties;
00256 int k;
00257
00258 for (k = 0; k < propertyList.size(); ++k) {
00259 properties[propertyNameForId(propertyList[k])] = property(propertyList[k]);
00260 }
00261 return properties;
00262 }
00263
00264 bool KLFPropertizedObject::setProperty(const QString& propname, const QVariant& value)
00265 {
00266 return doLoadProperty(propname, value) >= 0;
00267 }
00268
00269 bool KLFPropertizedObject::setProperty(int propId, const QVariant& value)
00270 {
00271 KLF_ASSERT_CONDITION(propertyIdRegistered(propId), "Property ID="<<propId<<" is not registered!",
00272 return false; ) ;
00273
00274 return setProperty(propertyNameForId(propId), value);
00275 }
00276
00277
00278 bool KLFPropertizedObject::setAllProperties(const QMap<QString, QVariant>& propValues)
00279 {
00280 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00281 klfDbg("propValues="<<propValues) ;
00282
00283 bool allok = true;
00284 QStringList propKeys = propValues.keys();
00285 int k;
00286 for (k = 0; k < propKeys.size(); ++k) {
00287
00288 bool ok = (doLoadProperty(propKeys[k], propValues[propKeys[k]]) >= 0);
00289 if (!ok) {
00290 allok = false;
00291 qWarning()<<KLF_FUNC_NAME<<": Failed to load property "<<propKeys[k]<<" with value "<<propValues[propKeys[k]];
00292 }
00293 }
00294 return allok;
00295 }
00296
00297
00298 QByteArray KLFPropertizedObject::allPropertiesToByteArray() const
00299 {
00300 QByteArray data;
00301 {
00302 QDataStream stream(&data, QIODevice::WriteOnly);
00303 stream << *this;
00304
00305 }
00306 return data;
00307 }
00308
00309 void KLFPropertizedObject::setAllPropertiesFromByteArray(const QByteArray& data)
00310 {
00311 QDataStream stream(data);
00312 stream >> *this;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 QString KLFPropertizedObject::toString(uint toStringFlags) const
00335 {
00336 QString s;
00337
00338 int k;
00339 QList<int> props;
00340 bool html = (toStringFlags & ToStringUseHtml);
00341 bool quote = (toStringFlags & ToStringQuoteValues);
00342 bool allprops = (toStringFlags & ToStringAllProperties);
00343 bool usehtmldiv = (toStringFlags & ToStringUseHtmlDiv);
00344
00345 if (allprops)
00346 props = registeredPropertyIdList();
00347 else
00348 props = propertyIdList();
00349
00350 if (html) {
00351 if (usehtmldiv) {
00352 s = QString("<div class=\"klfpobj_entry\">\n<div class=\"klfpobj_name\">%2</div>\n")
00353 .arg(pPropNameSpace.toHtmlEscaped());
00354 } else {
00355 s = QString("<table class=\"klfpobj_tentry\">\n"
00356 "<tr colspan=\"2\" class=\"klfpobj_tname\"><th>%1</th></tr>\n")
00357 .arg(pPropNameSpace.toHtmlEscaped());
00358 }
00359 } else {
00360 s = QString("%1\n").arg(pPropNameSpace);
00361 }
00362
00363 for (k = 0; k < props.size(); ++k) {
00364 QString pname = propertyNameForId(props[k]);
00365 QVariant vval = property(props[k]);
00366 bool isnull = !vval.isValid();
00367 bool canstring = vval.canConvert(QVariant::String);
00368 QString value = vval.toString();
00369 if (html) {
00370 if (usehtmldiv)
00371 s += QString("<div class=\"klfpobj_prop_%1\"><div class=\"klfpobj_propname\">%2</div>: "
00372 "<div class=\"klfpobj_propvalue\">%3</div></div>\n")
00373 .arg(pname, pname, value.toHtmlEscaped());
00374 else
00375 s += QString(" <tr class=\"klfpobj_tprop_%1\"><td class=\"klfpobj_tpropname\">%2</td>"
00376 "<td class=\"klfpobj_tpropvalue\">%3</td></tr>\n")
00377 .arg(pname, pname, value.toHtmlEscaped());
00378 } else {
00379 if (quote) {
00380 if (!isnull && canstring) {
00381 value.replace("\\", "\\\\");
00382 value.replace("\"", "\\\"");
00383 value = '"' + value + '"';
00384 } else if (!isnull) {
00385 value = QString("[%1]").arg(vval.typeName());
00386 } else {
00387
00388 value = "NULL";
00389 }
00390 }
00391 s += QString("%1: %2\n").arg(propertyNameForId(props[k]), value);
00392 }
00393 }
00394 s += "\n";
00395 if (html) {
00396 if (usehtmldiv) {
00397 s += "</div>\n";
00398 } else {
00399 s += "</table>\n";
00400 }
00401 }
00402
00403 return s;
00404 }
00405
00406
00407
00408 int KLFPropertizedObject::propertyMaxId() const
00409 {
00410 return propertyMaxId(pPropNameSpace);
00411 }
00412 bool KLFPropertizedObject::propertyIdRegistered(int propId) const
00413 {
00414 return propertyIdRegistered(pPropNameSpace, propId);
00415 }
00416 bool KLFPropertizedObject::propertyNameRegistered(const QString& propertyName) const
00417 {
00418 return propertyNameRegistered(pPropNameSpace, propertyName);
00419 }
00420 int KLFPropertizedObject::propertyIdForName(const QString& propName) const
00421 {
00422 return propertyIdForName(pPropNameSpace, propName);
00423 }
00424 QString KLFPropertizedObject::propertyNameForId(int id) const
00425 {
00426 return propertyNameForId(pPropNameSpace, id);
00427 }
00428 QStringList KLFPropertizedObject::registeredPropertyNameList() const
00429 {
00430 return registeredPropertyNameList(pPropNameSpace);
00431 }
00432 QList<int> KLFPropertizedObject::registeredPropertyIdList() const
00433 {
00434 return registeredPropertyIdList(pPropNameSpace);
00435 }
00436 QMap<QString, int> KLFPropertizedObject::registeredProperties() const
00437 {
00438 return registeredProperties(pPropNameSpace);
00439 }
00440
00441
00442
00443 void KLFPropertizedObject::registerBuiltInProperty(int propId, const QString& name) const
00444 {
00445 registerBuiltInProperty(pPropNameSpace, propId, name);
00446 }
00447 int KLFPropertizedObject::registerProperty(const QString& propName) const
00448 {
00449 return registerProperty(pPropNameSpace, propName);
00450 }
00451
00452
00453
00454 void KLFPropertizedObject::registerBuiltInProperty(const QString& pnamespace, int propId,
00455 const QString& name)
00456 {
00457 internalRegisterProperty(pnamespace, name, propId);
00458 }
00459 int KLFPropertizedObject::registerProperty(const QString& propNameSpace, const QString& propName)
00460 {
00461 return internalRegisterProperty(propNameSpace, propName, -1);
00462 }
00463 int KLFPropertizedObject::propertyMaxId(const QString& propNameSpace)
00464 {
00465 if ( ! pRegisteredPropertiesMaxId.contains(propNameSpace) ) {
00466 qWarning("%s(): property name space `%s' does not exist!", KLF_FUNC_NAME,
00467 qPrintable(propNameSpace));
00468 return -1;
00469 }
00470 return pRegisteredPropertiesMaxId[propNameSpace];
00471 }
00472 bool KLFPropertizedObject::propertyIdRegistered(const QString& propNameSpace, int propId)
00473 {
00474 return ( ! propertyNameForId(propNameSpace, propId).isNull() ) ;
00475 }
00476 bool KLFPropertizedObject::propertyNameRegistered(const QString& propNameSpace,
00477 const QString& propertyName)
00478 {
00479 return (propertyIdForName(propNameSpace, propertyName) != -1) ;
00480 }
00481 int KLFPropertizedObject::propertyIdForName(const QString& propNameSpace, const QString& name)
00482 {
00483 if ( ! pRegisteredProperties.contains(propNameSpace) ) {
00484 qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
00485 qPrintable(propNameSpace));
00486 return -1;
00487 }
00488 QMap<QString, int> propList = pRegisteredProperties[propNameSpace];
00489 if ( ! propList.contains(name) )
00490 return -1;
00491 return propList.value(name);
00492 }
00493 QString KLFPropertizedObject::propertyNameForId(const QString& propNameSpace, int propId)
00494 {
00495 if ( ! pRegisteredProperties.contains(propNameSpace) ) {
00496 qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
00497 qPrintable(propNameSpace));
00498 return QString();
00499 }
00500 QMap<QString, int> propList = pRegisteredProperties[propNameSpace];
00501 QList<QString> keyList = propList.keys(propId);
00502 if (keyList.isEmpty())
00503 return QString();
00504 if (keyList.size() > 1) {
00505 qWarning("%s: What's going on?? property Id=%d not unique in prop name space `%s'.",
00506 KLF_FUNC_NAME, propId, qPrintable(propNameSpace));
00507 }
00508 return keyList[0];
00509 }
00510 QStringList KLFPropertizedObject::registeredPropertyNameList(const QString& propNameSpace)
00511 {
00512 if ( ! pRegisteredProperties.contains(propNameSpace) ) {
00513 qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
00514 qPrintable(propNameSpace));
00515 return QStringList();
00516 }
00517
00518 return pRegisteredProperties[propNameSpace].keys();
00519 }
00520 QList<int> KLFPropertizedObject::registeredPropertyIdList(const QString& propNameSpace)
00521 {
00522 if ( ! pRegisteredProperties.contains(propNameSpace) ) {
00523 qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
00524 qPrintable(propNameSpace));
00525 return QList<int>();
00526 }
00527
00528 return pRegisteredProperties[propNameSpace].values();
00529 }
00530
00531 QMap<QString, int> KLFPropertizedObject::registeredProperties(const QString& propNameSpace)
00532 {
00533 if ( ! pRegisteredProperties.contains(propNameSpace) ) {
00534 qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
00535 qPrintable(propNameSpace));
00536 return QMap<QString, int>();
00537 }
00538 return pRegisteredProperties[propNameSpace];
00539 }
00540
00541
00542
00543
00544 QMap<QString, QMap<QString, int> > KLFPropertizedObject::pRegisteredProperties =
00545 QMap<QString, QMap<QString, int> >();
00546
00547 QMap<QString, int> KLFPropertizedObject::pRegisteredPropertiesMaxId = QMap<QString,int>();
00548
00549
00550 int KLFPropertizedObject::internalRegisterProperty(const QString& propNameSpace,
00551 const QString& propName,
00552 int propId)
00553 {
00554 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00555 klfDbg("propNameSpace = " << propNameSpace << ", propName = " << propName << ", propId = " << propId) ;
00556
00557 const QMap<QString, int> propList = pRegisteredProperties[propNameSpace];
00558 int propMaxId = -1;
00559 if (pRegisteredPropertiesMaxId.contains(propNameSpace)) {
00560 propMaxId = pRegisteredPropertiesMaxId[propNameSpace];
00561 }
00562 if (propId == -1) {
00563
00564 propId = propMaxId + 1;
00565
00566 propMaxId = propId;
00567 } else {
00568
00569 if (propId > propMaxId) {
00570 propMaxId = propId;
00571 }
00572 }
00573 if ( propList.keys(propId).size() > 0 ) {
00574 QString oldPropName = propList.keys(propId).at(0);
00575 if (propName == oldPropName) {
00576 return propId;
00577 }
00578 qWarning("%s[%s]: Property ID `%d' is already registered with conflicting names!\n"
00579 "\told name is `%s', new is `%s'",
00580 KLF_FUNC_NAME, qPrintable(propNameSpace), propId, qPrintable(oldPropName),
00581 qPrintable(propName));
00582 return -1;
00583 }
00584
00585 if (propName.isEmpty()) {
00586 qWarning("%s[%s]: Cannot Register a property with empty name!", KLF_FUNC_NAME,
00587 qPrintable(propNameSpace));
00588 return -1;
00589 }
00590 if (propList.contains(propName)) {
00591 qWarning("%s[%s]: Property `%s' already registered.", KLF_FUNC_NAME, qPrintable(propNameSpace),
00592 qPrintable(propName));
00593 return -1;
00594 }
00595
00596
00597 pRegisteredProperties[propNameSpace][propName] = propId;
00598
00599 pRegisteredPropertiesMaxId[propNameSpace] = propMaxId;
00600 return propId;
00601 }
00602
00603
00604 bool operator==(const KLFPropertizedObject& a, const KLFPropertizedObject& b)
00605 {
00606 if (a.pPropNameSpace != b.pPropNameSpace)
00607 return false;
00608 QList<int> propIds = a.registeredPropertyIdList();
00609 int k;
00610 for (k = 0; k < propIds.size(); ++k)
00611 if (a.property(propIds[k]) != b.property(propIds[k]))
00612 return false;
00613
00614 return true;
00615 }
00616
00617
00618
00619 QDataStream& KLFPropertizedObject::streamInto(QDataStream& stream) const
00620 {
00621 stream << allProperties();
00622 return stream;
00623 }
00624 QDataStream& KLFPropertizedObject::streamFrom(QDataStream& stream)
00625 {
00626 QMap<QString,QVariant> props;
00627 stream >> props;
00628 setAllProperties(props);
00629 return stream;
00630 }
00631 QDataStream& operator<<(QDataStream& stream, const KLFPropertizedObject& obj)
00632 {
00633 return obj.streamInto(stream);
00634 }
00635 QDataStream& operator>>(QDataStream& stream, KLFPropertizedObject& obj)
00636 {
00637 return obj.streamFrom(stream);
00638 }
00639
00640
00641 QTextStream& operator<<(QTextStream& stream, const KLFPropertizedObject& obj)
00642 {
00643 return stream << obj.toString();
00644 }
00645
00646
00647
00648 QDebug& operator<<(QDebug& stream, const KLFPropertizedObject& obj)
00649 {
00650 stream << obj.allProperties();
00651 return stream;
00652 }
00653
00654
00655