[KLF Application][KLF Tools][KLF Backend][KLF Home]
KLatexFormula Project

src/klftools/klfpobj.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   file klfpobj.cpp
00003  *   This file is part of the KLatexFormula Project.
00004  *   Copyright (C) 2010 by Philippe Faist
00005  *   philippe.faist at bluewin.ch
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; if not, write to the                         *
00019  *   Free Software Foundation, Inc.,                                       *
00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00021  ***************************************************************************/
00022 /* $Id: klfpobj.cpp 442 2010-08-13 17:34:38Z philippe $ */
00023 
00024 #include <QDebug>
00025 #include <QByteArray>
00026 #include <QDataStream>
00027 #include <QTextStream>
00028 #include <QTextDocument>  // Qt::escape()
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     // all ok, return property (possibly an empty QVariant() if prop not set)
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   // property not set (or property not registered)
00064   return QVariant();
00065 }
00066 
00067 
00068 void KLFPropertizedObject::propertyValueChanged(int , const QVariant& ,
00069                                                 const QVariant& )
00070 {
00071   // do nothing. Subclasses may implement thier own behavior.
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     // all ok, set this property
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   // maybe our properties array needs resize for properties that could have been
00098   // registered after last access
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     // register property
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   // walk vector and a fill a QList of all set properties' ID
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   // walk vector and a fill a QStringList of all set properties.
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   // walk all properties and insert them into list
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     // force close of buffer in destroying stream
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           // true null
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 // ----  PROTECTED  ----
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 //  ----  STATIC PROTECTED  ----
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 //  ----  PRIVATE  ----
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     // propMaxId is maximum ID already used, so +1 gives a free ID.
00421     propId = propMaxId + 1;
00422     // and update propMaxId to account for the new propId...
00423     propMaxId = propId;
00424   } else {
00425     // used the fixed propId. Update propMaxId if necessary.
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; // already registered, return that property ID
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   // make sure property name is valid and unique
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   // name and ID are valid and unique.
00451   // finally insert the property into list of known properties.
00452   pRegisteredProperties[propNameSpace][propName] = propId;
00453   // propMaxId was updated according to the new ID earlier in this function.
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 

Generated by doxygen 1.7.3