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 <QDebug>
00025 #include <QByteArray>
00026 #include <QDataStream>
00027 #include <QTextStream>
00028 #include <QTextDocument>
00029
00030 #include "klfpobj.h"
00031
00032 KLFPropertizedObject::KLFPropertizedObject(const QString& propNameSpace)
00033 : pPropNameSpace(propNameSpace)
00034 {
00035 }
00036
00037 KLFPropertizedObject::~KLFPropertizedObject()
00038 {
00039 }
00040
00041
00042 QVariant KLFPropertizedObject::property(const QString& propname) const
00043 {
00044 int propId = propertyIdForName(propname);
00045 if (propId < 0) {
00046 qWarning("%s[%s](): Property `%s' not registered.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
00047 qPrintable(propname));
00048 return QVariant();
00049 }
00050 return property(propId);
00051 }
00052 QVariant KLFPropertizedObject::property(int propId) const
00053 {
00054 if (propId >= 0 && propId < pProperties.size()) {
00055
00056 return pProperties[propId];
00057 }
00058 if (propId < 0) {
00059 qWarning("%s[%s](%d): invalid property ID.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
00060 propId);
00061 return QVariant();
00062 }
00063
00064 return QVariant();
00065 }
00066
00067
00068 void KLFPropertizedObject::propertyValueChanged(int , const QVariant& ,
00069 const QVariant& )
00070 {
00071
00072 }
00073
00074 void KLFPropertizedObject::setProperty(const QString& propname, const QVariant& value)
00075 {
00076 if ( ! propertyNameRegistered(propname) ) {
00077 qWarning("%s[%s](): Property `%s' not registered.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
00078 qPrintable(propname));
00079 return;
00080 }
00081 setProperty(propertyIdForName(propname), value);
00082 }
00083 void KLFPropertizedObject::setProperty(int propId, const QVariant& value)
00084 {
00085 if (propId >= 0 && propId < pProperties.size()) {
00086
00087 QVariant oldvalue = pProperties[propId];
00088 pProperties[propId] = value;
00089 propertyValueChanged(propId, oldvalue, value);
00090 return;
00091 }
00092 if (propId < 0) {
00093 qWarning("%s[%s](id=%d): invalid property ID.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
00094 propId);
00095 return;
00096 }
00097
00098
00099 int maxId = propertyMaxId();
00100 if (propId <= maxId) {
00101 pProperties.resize(maxId + 1);
00102 }
00103 if (propId < 0 || propId >= pProperties.size() ||
00104 ! propertyIdRegistered(propId) ) {
00105 qWarning("%s[%s](id=%d): invalid property id.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
00106 propId);
00107 return;
00108 }
00109 QVariant oldvalue = pProperties[propId];
00110 pProperties[propId] = value;
00111 propertyValueChanged(propId, oldvalue, value);
00112 }
00113 int KLFPropertizedObject::loadProperty(const QString& propname, const QVariant& value)
00114 {
00115 int propId = propertyIdForName(propname);
00116 if ( propId < 0 ) {
00117
00118 propId = registerProperty(propname);
00119 if (propId < 0)
00120 return -1;
00121 }
00122 setProperty(propId, value);
00123 return propId;
00124 }
00125
00126 QList<int> KLFPropertizedObject::propertyIdList() const
00127 {
00128 QList<int> idList;
00129 int k;
00130
00131 for (k = 0; k < pProperties.size(); ++k) {
00132 if (pProperties[k].isValid())
00133 idList << k;
00134 }
00135 return idList;
00136 }
00137
00138 QStringList KLFPropertizedObject::propertyNameList() const
00139 {
00140 QStringList propSetList;
00141 int k;
00142
00143 for (k = 0; k < pProperties.size(); ++k) {
00144 if (pProperties[k].isValid())
00145 propSetList << propertyNameForId(k);
00146 }
00147 return propSetList;
00148 }
00149
00150
00151
00152
00153 QMap<QString,QVariant> KLFPropertizedObject::allProperties() const
00154 {
00155 QList<int> propertyList = propertyIdList();
00156 QMap<QString,QVariant> properties;
00157 int k;
00158
00159 for (k = 0; k < propertyList.size(); ++k) {
00160 properties[propertyNameForId(propertyList[k])] = property(propertyList[k]);
00161 }
00162 return properties;
00163 }
00164
00165 void KLFPropertizedObject::setAllProperties(const QMap<QString, QVariant>& propValues)
00166 {
00167 QStringList propKeys = propValues.keys();
00168 int k;
00169 for (k = 0; k < propKeys.size(); ++k) {
00170 loadProperty(propKeys[k], propValues[propKeys[k]]);
00171 }
00172 }
00173
00174
00175 QByteArray KLFPropertizedObject::allPropertiesToByteArray() const
00176 {
00177 QByteArray data;
00178 {
00179 QDataStream stream(&data, QIODevice::WriteOnly);
00180 stream << *this;
00181
00182 }
00183 return data;
00184 }
00185
00186 void KLFPropertizedObject::setAllPropertiesFromByteArray(const QByteArray& data)
00187 {
00188 QDataStream stream(data);
00189 stream >> *this;
00190 }
00191
00192
00193
00194 QString KLFPropertizedObject::toString(uint toStringFlags) const
00195 {
00196 QString s;
00197
00198 int k;
00199 QList<int> props;
00200 bool html = (toStringFlags & ToStringUseHtml);
00201 bool quote = (toStringFlags & ToStringQuoteValues);
00202 bool allprops = (toStringFlags & ToStringAllProperties);
00203 bool usehtmldiv = (toStringFlags & ToStringUseHtmlDiv);
00204
00205 if (allprops)
00206 props = registeredPropertyIdList();
00207 else
00208 props = propertyIdList();
00209
00210 if (html) {
00211 if (usehtmldiv) {
00212 s = QString("<div class=\"klfpobj_entry\">\n<div class=\"klfpobj_name\">%2</div>\n")
00213 .arg(Qt::escape(pPropNameSpace));
00214 } else {
00215 s = QString("<table class=\"klfpobj_tentry\">\n"
00216 "<tr colspan=\"2\" class=\"klfpobj_tname\"><th>%1</th></tr>\n")
00217 .arg(Qt::escape(pPropNameSpace));
00218 }
00219 } else {
00220 s = QString("%1\n").arg(pPropNameSpace);
00221 }
00222
00223 for (k = 0; k < props.size(); ++k) {
00224 QString pname = propertyNameForId(props[k]);
00225 QVariant vval = property(props[k]);
00226 bool isnull = !vval.isValid();
00227 bool canstring = vval.canConvert(QVariant::String);
00228 QString value = vval.toString();
00229 if (html) {
00230 if (usehtmldiv)
00231 s += QString("<div class=\"klfpobj_prop_%1\"><div class=\"klfpobj_propname\">%2</div>: "
00232 "<div class=\"klfpobj_propvalue\">%3</div></div>\n")
00233 .arg(pname, pname, Qt::escape(value));
00234 else
00235 s += QString(" <tr class=\"klfpobj_tprop_%1\"><td class=\"klfpobj_tpropname\">%2</td>"
00236 "<td class=\"klfpobj_tpropvalue\">%3</td></tr>\n")
00237 .arg(pname, pname, Qt::escape(value));
00238 } else {
00239 if (quote) {
00240 if (!isnull && canstring) {
00241 value.replace("\\", "\\\\");
00242 value.replace("\"", "\\\"");
00243 value = '"' + value + '"';
00244 } else if (!isnull) {
00245 value = QString("[%1]").arg(vval.typeName());
00246 } else {
00247
00248 value = "NULL";
00249 }
00250 }
00251 s += QString("%1: %2\n").arg(propertyNameForId(props[k]), value);
00252 }
00253 }
00254 s += "\n";
00255 if (html) {
00256 if (usehtmldiv) {
00257 s += "</div>\n";
00258 } else {
00259 s += "</table>\n";
00260 }
00261 }
00262
00263 return s;
00264 }
00265
00266
00267
00268 int KLFPropertizedObject::propertyMaxId() const
00269 {
00270 return propertyMaxId(pPropNameSpace);
00271 }
00272 bool KLFPropertizedObject::propertyIdRegistered(int propId) const
00273 {
00274 return propertyIdRegistered(pPropNameSpace, propId);
00275 }
00276 bool KLFPropertizedObject::propertyNameRegistered(const QString& propertyName) const
00277 {
00278 return propertyNameRegistered(pPropNameSpace, propertyName);
00279 }
00280 int KLFPropertizedObject::propertyIdForName(const QString& propName) const
00281 {
00282 return propertyIdForName(pPropNameSpace, propName);
00283 }
00284 QString KLFPropertizedObject::propertyNameForId(int id) const
00285 {
00286 return propertyNameForId(pPropNameSpace, id);
00287 }
00288 QStringList KLFPropertizedObject::registeredPropertyNameList() const
00289 {
00290 return registeredPropertyNameList(pPropNameSpace);
00291 }
00292 QList<int> KLFPropertizedObject::registeredPropertyIdList() const
00293 {
00294 return registeredPropertyIdList(pPropNameSpace);
00295 }
00296 QMap<QString, int> KLFPropertizedObject::registeredProperties() const
00297 {
00298 return registeredProperties(pPropNameSpace);
00299 }
00300
00301
00302
00303 void KLFPropertizedObject::registerBuiltInProperty(int propId, const QString& name) const
00304 {
00305 registerBuiltInProperty(pPropNameSpace, propId, name);
00306 }
00307 int KLFPropertizedObject::registerProperty(const QString& propName) const
00308 {
00309 return registerProperty(pPropNameSpace, propName);
00310 }
00311
00312
00313
00314 void KLFPropertizedObject::registerBuiltInProperty(const QString& pnamespace, int propId,
00315 const QString& name)
00316 {
00317 internalRegisterProperty(pnamespace, name, propId);
00318 }
00319 int KLFPropertizedObject::registerProperty(const QString& propNameSpace, const QString& propName)
00320 {
00321 return internalRegisterProperty(propNameSpace, propName, -1);
00322 }
00323 int KLFPropertizedObject::propertyMaxId(const QString& propNameSpace)
00324 {
00325 if ( ! pRegisteredPropertiesMaxId.contains(propNameSpace) ) {
00326 qWarning("%s(): property name space `%s' does not exist!", KLF_FUNC_NAME,
00327 qPrintable(propNameSpace));
00328 return -1;
00329 }
00330 return pRegisteredPropertiesMaxId[propNameSpace];
00331 }
00332 bool KLFPropertizedObject::propertyIdRegistered(const QString& propNameSpace, int propId)
00333 {
00334 return ( ! propertyNameForId(propNameSpace, propId).isNull() ) ;
00335 }
00336 bool KLFPropertizedObject::propertyNameRegistered(const QString& propNameSpace,
00337 const QString& propertyName)
00338 {
00339 return (propertyIdForName(propNameSpace, propertyName) != -1) ;
00340 }
00341 int KLFPropertizedObject::propertyIdForName(const QString& propNameSpace, const QString& name)
00342 {
00343 if ( ! pRegisteredProperties.contains(propNameSpace) ) {
00344 qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
00345 qPrintable(propNameSpace));
00346 return -1;
00347 }
00348 QMap<QString, int> propList = pRegisteredProperties[propNameSpace];
00349 if ( ! propList.contains(name) )
00350 return -1;
00351 return propList.value(name);
00352 }
00353 QString KLFPropertizedObject::propertyNameForId(const QString& propNameSpace, int propId)
00354 {
00355 if ( ! pRegisteredProperties.contains(propNameSpace) ) {
00356 qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
00357 qPrintable(propNameSpace));
00358 return QString();
00359 }
00360 QMap<QString, int> propList = pRegisteredProperties[propNameSpace];
00361 QList<QString> keyList = propList.keys(propId);
00362 if (keyList.isEmpty())
00363 return QString();
00364 if (keyList.size() > 1) {
00365 qWarning("%s: What's going on?? property Id=%d not unique in prop name space `%s'.",
00366 KLF_FUNC_NAME, propId, qPrintable(propNameSpace));
00367 }
00368 return keyList[0];
00369 }
00370 QStringList KLFPropertizedObject::registeredPropertyNameList(const QString& propNameSpace)
00371 {
00372 if ( ! pRegisteredProperties.contains(propNameSpace) ) {
00373 qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
00374 qPrintable(propNameSpace));
00375 return QStringList();
00376 }
00377
00378 return pRegisteredProperties[propNameSpace].keys();
00379 }
00380 QList<int> KLFPropertizedObject::registeredPropertyIdList(const QString& propNameSpace)
00381 {
00382 if ( ! pRegisteredProperties.contains(propNameSpace) ) {
00383 qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
00384 qPrintable(propNameSpace));
00385 return QList<int>();
00386 }
00387
00388 return pRegisteredProperties[propNameSpace].values();
00389 }
00390
00391 QMap<QString, int> KLFPropertizedObject::registeredProperties(const QString& propNameSpace)
00392 {
00393 if ( ! pRegisteredProperties.contains(propNameSpace) ) {
00394 qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
00395 qPrintable(propNameSpace));
00396 return QMap<QString, int>();
00397 }
00398 return pRegisteredProperties[propNameSpace];
00399 }
00400
00401
00402
00403
00404 QMap<QString, QMap<QString, int> > KLFPropertizedObject::pRegisteredProperties =
00405 QMap<QString, QMap<QString, int> >();
00406
00407 QMap<QString, int> KLFPropertizedObject::pRegisteredPropertiesMaxId = QMap<QString,int>();
00408
00409
00410 int KLFPropertizedObject::internalRegisterProperty(const QString& propNameSpace,
00411 const QString& propName,
00412 int propId)
00413 {
00414 const QMap<QString, int> propList = pRegisteredProperties[propNameSpace];
00415 int propMaxId = -1;
00416 if (pRegisteredPropertiesMaxId.contains(propNameSpace)) {
00417 propMaxId = pRegisteredPropertiesMaxId[propNameSpace];
00418 }
00419 if (propId == -1) {
00420
00421 propId = propMaxId + 1;
00422
00423 propMaxId = propId;
00424 } else {
00425
00426 if (propId > propMaxId)
00427 propMaxId = propId;
00428 }
00429 if ( propList.keys(propId).size() > 0 ) {
00430 QString oldPropName = propList.keys(propId).at(0);
00431 if (propName == oldPropName)
00432 return propId;
00433 qWarning("%s[%s]: Property ID `%d' is already registered with conflicting names!\n"
00434 "\told name is `%s', new is `%s'",
00435 KLF_FUNC_NAME, qPrintable(propNameSpace), propId, qPrintable(oldPropName),
00436 qPrintable(propName));
00437 return -1;
00438 }
00439
00440 if (propName.isEmpty()) {
00441 qWarning("%s[%s]: Cannot Register a property with empty name!", KLF_FUNC_NAME,
00442 qPrintable(propNameSpace));
00443 return -1;
00444 }
00445 if (propList.contains(propName)) {
00446 qWarning("%s[%s]: Property `%s' already registered.", KLF_FUNC_NAME, qPrintable(propNameSpace),
00447 qPrintable(propName));
00448 return -1;
00449 }
00450
00451
00452 pRegisteredProperties[propNameSpace][propName] = propId;
00453
00454 pRegisteredPropertiesMaxId[propNameSpace] = propMaxId;
00455 return propId;
00456 }
00457
00458
00459 bool operator==(const KLFPropertizedObject& a, const KLFPropertizedObject& b)
00460 {
00461 if (a.pPropNameSpace != b.pPropNameSpace)
00462 return false;
00463 QList<int> propIds = a.registeredPropertyIdList();
00464 int k;
00465 for (k = 0; k < propIds.size(); ++k)
00466 if (a.property(propIds[k]) != b.property(propIds[k]))
00467 return false;
00468
00469 return true;
00470 }
00471
00472
00473
00474 QDataStream& operator<<(QDataStream& stream, const KLFPropertizedObject& obj)
00475 {
00476 stream << obj.allProperties();
00477 return stream;
00478 }
00479 QDataStream& operator>>(QDataStream& stream, KLFPropertizedObject& obj)
00480 {
00481 QMap<QString,QVariant> props;
00482 stream >> props;
00483 obj.setAllProperties(props);
00484 return stream;
00485 }
00486
00487
00488 QTextStream& operator<<(QTextStream& stream, const KLFPropertizedObject& obj)
00489 {
00490 return stream << obj.toString();
00491 }
00492
00493
00494
00495 QDebug& operator<<(QDebug& stream, const KLFPropertizedObject& obj)
00496 {
00497 stream << obj.allProperties();
00498 return stream;
00499 }
00500