[KLF Application][KLF Tools][KLF Backend][KLF Home]
KLatexFormula Project
klfpobj.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * file klfpobj.cpp
3  * This file is part of the KLatexFormula Project.
4  * Copyright (C) 2011 by Philippe Faist
5  * philippe.faist at bluewin.ch
6  * *
7  * This program is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program; if not, write to the *
19  * Free Software Foundation, Inc., *
20  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21  ***************************************************************************/
22 /* $Id: klfpobj.cpp 603 2011-02-26 23:14:55Z phfaist $ */
23 
24 #include <QDebug>
25 #include <QByteArray>
26 #include <QDataStream>
27 #include <QTextStream>
28 #include <QTextDocument> // Qt::escape()
29 
30 #include "klfpobj.h"
31 
33  : pPropNameSpace(propNameSpace)
34 {
35 }
36 
38 {
39 }
40 
41 
43 {
44  int propId = propertyIdForName(propname);
45  if (propId < 0) {
46  qWarning("%s[%s](): Property `%s' not registered.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
47  qPrintable(propname));
48  return QVariant();
49  }
50  return property(propId);
51 }
53 {
54  if (propId >= 0 && propId < pProperties.size()) {
55  // all ok, return property (possibly an empty QVariant() if prop not set)
56  return pProperties[propId];
57  }
58  if (propId < 0) {
59  qWarning("%s[%s](%d): invalid property ID.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
60  propId);
61  return QVariant();
62  }
63  // property not set (or property not registered)
64  return QVariant();
65 }
66 
67 
69  const QVariant& )
70 {
71  // do nothing. Subclasses may implement thier own behavior.
72 }
73 
74 void KLFPropertizedObject::setProperty(const QString& propname, const QVariant& value)
75 {
76  if ( ! propertyNameRegistered(propname) ) {
77  qWarning("%s[%s](): Property `%s' not registered.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
78  qPrintable(propname));
79  return;
80  }
81  setProperty(propertyIdForName(propname), value);
82 }
84 {
85  if (propId >= 0 && propId < pProperties.size()) {
86  // all ok, set this property
87  QVariant oldvalue = pProperties[propId];
88  pProperties[propId] = value;
89  propertyValueChanged(propId, oldvalue, value);
90  return;
91  }
92  if (propId < 0) {
93  qWarning("%s[%s](id=%d): invalid property ID.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
94  propId);
95  return;
96  }
97  // maybe our properties array needs resize for properties that could have been
98  // registered after last access
99  int maxId = propertyMaxId();
100  if (propId <= maxId) {
101  pProperties.resize(maxId + 1);
102  }
103  if (propId < 0 || propId >= pProperties.size() ||
104  ! propertyIdRegistered(propId) ) {
105  qWarning("%s[%s](id=%d): invalid property id.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
106  propId);
107  return;
108  }
109  QVariant oldvalue = pProperties[propId];
110  pProperties[propId] = value;
111  propertyValueChanged(propId, oldvalue, value);
112 }
113 int KLFPropertizedObject::loadProperty(const QString& propname, const QVariant& value)
114 {
115  int propId = propertyIdForName(propname);
116  if ( propId < 0 ) {
117  // register property
118  propId = registerProperty(propname);
119  if (propId < 0)
120  return -1;
121  }
122  setProperty(propId, value);
123  return propId;
124 }
125 
127 {
128  QList<int> idList;
129  int k;
130  // walk vector and a fill a QList of all set properties' ID
131  for (k = 0; k < pProperties.size(); ++k) {
132  if (pProperties[k].isValid())
133  idList << k;
134  }
135  return idList;
136 }
137 
139 {
140  QStringList propSetList;
141  int k;
142  // walk vector and a fill a QStringList of all set properties.
143  for (k = 0; k < pProperties.size(); ++k) {
144  if (pProperties[k].isValid())
145  propSetList << propertyNameForId(k);
146  }
147  return propSetList;
148 }
149 
150 
151 
152 
154 {
155  QList<int> propertyList = propertyIdList();
156  QMap<QString,QVariant> properties;
157  int k;
158  // walk all properties and insert them into list
159  for (k = 0; k < propertyList.size(); ++k) {
160  properties[propertyNameForId(propertyList[k])] = property(propertyList[k]);
161  }
162  return properties;
163 }
164 
166 {
167  QStringList propKeys = propValues.keys();
168  int k;
169  for (k = 0; k < propKeys.size(); ++k) {
170  loadProperty(propKeys[k], propValues[propKeys[k]]);
171  }
172 }
173 
174 
176 {
177  QByteArray data;
178  {
179  QDataStream stream(&data, QIODevice::WriteOnly);
180  stream << *this;
181  // force close of buffer in destroying stream
182  }
183  return data;
184 }
185 
187 {
188  QDataStream stream(data);
189  stream >> *this;
190 }
191 
192 
193 
194 QString KLFPropertizedObject::toString(uint toStringFlags) const
195 {
196  QString s;
197 
198  int k;
199  QList<int> props;
200  bool html = (toStringFlags & ToStringUseHtml);
201  bool quote = (toStringFlags & ToStringQuoteValues);
202  bool allprops = (toStringFlags & ToStringAllProperties);
203  bool usehtmldiv = (toStringFlags & ToStringUseHtmlDiv);
204 
205  if (allprops)
206  props = registeredPropertyIdList();
207  else
208  props = propertyIdList();
209 
210  if (html) {
211  if (usehtmldiv) {
212  s = QString("<div class=\"klfpobj_entry\">\n<div class=\"klfpobj_name\">%2</div>\n")
213  .arg(Qt::escape(pPropNameSpace));
214  } else {
215  s = QString("<table class=\"klfpobj_tentry\">\n"
216  "<tr colspan=\"2\" class=\"klfpobj_tname\"><th>%1</th></tr>\n")
217  .arg(Qt::escape(pPropNameSpace));
218  }
219  } else {
220  s = QString("%1\n").arg(pPropNameSpace);
221  }
222 
223  for (k = 0; k < props.size(); ++k) {
224  QString pname = propertyNameForId(props[k]);
225  QVariant vval = property(props[k]);
226  bool isnull = !vval.isValid();
227  bool canstring = vval.canConvert(QVariant::String);
228  QString value = vval.toString();
229  if (html) {
230  if (usehtmldiv)
231  s += QString("<div class=\"klfpobj_prop_%1\"><div class=\"klfpobj_propname\">%2</div>: "
232  "<div class=\"klfpobj_propvalue\">%3</div></div>\n")
233  .arg(pname, pname, Qt::escape(value));
234  else
235  s += QString(" <tr class=\"klfpobj_tprop_%1\"><td class=\"klfpobj_tpropname\">%2</td>"
236  "<td class=\"klfpobj_tpropvalue\">%3</td></tr>\n")
237  .arg(pname, pname, Qt::escape(value));
238  } else {
239  if (quote) {
240  if (!isnull && canstring) {
241  value.replace("\\", "\\\\");
242  value.replace("\"", "\\\"");
243  value = '"' + value + '"';
244  } else if (!isnull) {
245  value = QString("[%1]").arg(vval.typeName());
246  } else {
247  // true null
248  value = "NULL";
249  }
250  }
251  s += QString("%1: %2\n").arg(propertyNameForId(props[k]), value);
252  }
253  }
254  s += "\n";
255  if (html) {
256  if (usehtmldiv) {
257  s += "</div>\n";
258  } else {
259  s += "</table>\n";
260  }
261  }
262 
263  return s;
264 }
265 
266 
267 
269 {
270  return propertyMaxId(pPropNameSpace);
271 }
273 {
274  return propertyIdRegistered(pPropNameSpace, propId);
275 }
277 {
278  return propertyNameRegistered(pPropNameSpace, propertyName);
279 }
281 {
282  return propertyIdForName(pPropNameSpace, propName);
283 }
285 {
286  return propertyNameForId(pPropNameSpace, id);
287 }
289 {
290  return registeredPropertyNameList(pPropNameSpace);
291 }
293 {
294  return registeredPropertyIdList(pPropNameSpace);
295 }
297 {
298  return registeredProperties(pPropNameSpace);
299 }
300 
301 // ---- PROTECTED ----
302 
304 {
305  registerBuiltInProperty(pPropNameSpace, propId, name);
306 }
308 {
309  return registerProperty(pPropNameSpace, propName);
310 }
311 
312 // ---- STATIC PROTECTED ----
313 
315  const QString& name)
316 {
317  internalRegisterProperty(pnamespace, name, propId);
318 }
319 int KLFPropertizedObject::registerProperty(const QString& propNameSpace, const QString& propName)
320 {
321  return internalRegisterProperty(propNameSpace, propName, -1);
322 }
324 {
325  if ( ! pRegisteredPropertiesMaxId.contains(propNameSpace) ) {
326  qWarning("%s(): property name space `%s' does not exist!", KLF_FUNC_NAME,
327  qPrintable(propNameSpace));
328  return -1;
329  }
330  return pRegisteredPropertiesMaxId[propNameSpace];
331 }
333 {
334  return ( ! propertyNameForId(propNameSpace, propId).isNull() ) ;
335 }
337  const QString& propertyName)
338 {
339  return (propertyIdForName(propNameSpace, propertyName) != -1) ;
340 }
341 int KLFPropertizedObject::propertyIdForName(const QString& propNameSpace, const QString& name)
342 {
343  if ( ! pRegisteredProperties.contains(propNameSpace) ) {
344  qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
345  qPrintable(propNameSpace));
346  return -1;
347  }
348  QMap<QString, int> propList = pRegisteredProperties[propNameSpace];
349  if ( ! propList.contains(name) )
350  return -1;
351  return propList.value(name);
352 }
354 {
355  if ( ! pRegisteredProperties.contains(propNameSpace) ) {
356  qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
357  qPrintable(propNameSpace));
358  return QString();
359  }
360  QMap<QString, int> propList = pRegisteredProperties[propNameSpace];
361  QList<QString> keyList = propList.keys(propId);
362  if (keyList.isEmpty())
363  return QString();
364  if (keyList.size() > 1) {
365  qWarning("%s: What's going on?? property Id=%d not unique in prop name space `%s'.",
366  KLF_FUNC_NAME, propId, qPrintable(propNameSpace));
367  }
368  return keyList[0];
369 }
371 {
372  if ( ! pRegisteredProperties.contains(propNameSpace) ) {
373  qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
374  qPrintable(propNameSpace));
375  return QStringList();
376  }
377 
378  return pRegisteredProperties[propNameSpace].keys();
379 }
381 {
382  if ( ! pRegisteredProperties.contains(propNameSpace) ) {
383  qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
384  qPrintable(propNameSpace));
385  return QList<int>();
386  }
387 
388  return pRegisteredProperties[propNameSpace].values();
389 }
390 
392 {
393  if ( ! pRegisteredProperties.contains(propNameSpace) ) {
394  qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
395  qPrintable(propNameSpace));
396  return QMap<QString, int>();
397  }
398  return pRegisteredProperties[propNameSpace];
399 }
400 
401 
402 // ---- PRIVATE ----
403 
404 QMap<QString, QMap<QString, int> > KLFPropertizedObject::pRegisteredProperties =
406 
407 QMap<QString, int> KLFPropertizedObject::pRegisteredPropertiesMaxId = QMap<QString,int>();
408 
409 
410 int KLFPropertizedObject::internalRegisterProperty(const QString& propNameSpace,
411  const QString& propName,
412  int propId)
413 {
414  const QMap<QString, int> propList = pRegisteredProperties[propNameSpace];
415  int propMaxId = -1;
416  if (pRegisteredPropertiesMaxId.contains(propNameSpace)) {
417  propMaxId = pRegisteredPropertiesMaxId[propNameSpace];
418  }
419  if (propId == -1) {
420  // propMaxId is maximum ID already used, so +1 gives a free ID.
421  propId = propMaxId + 1;
422  // and update propMaxId to account for the new propId...
423  propMaxId = propId;
424  } else {
425  // used the fixed propId. Update propMaxId if necessary.
426  if (propId > propMaxId)
427  propMaxId = propId;
428  }
429  if ( propList.keys(propId).size() > 0 ) {
430  QString oldPropName = propList.keys(propId).at(0);
431  if (propName == oldPropName)
432  return propId; // already registered, return that property ID
433  qWarning("%s[%s]: Property ID `%d' is already registered with conflicting names!\n"
434  "\told name is `%s', new is `%s'",
435  KLF_FUNC_NAME, qPrintable(propNameSpace), propId, qPrintable(oldPropName),
436  qPrintable(propName));
437  return -1;
438  }
439  // make sure property name is valid and unique
440  if (propName.isEmpty()) {
441  qWarning("%s[%s]: Cannot Register a property with empty name!", KLF_FUNC_NAME,
442  qPrintable(propNameSpace));
443  return -1;
444  }
445  if (propList.contains(propName)) {
446  qWarning("%s[%s]: Property `%s' already registered.", KLF_FUNC_NAME, qPrintable(propNameSpace),
447  qPrintable(propName));
448  return -1;
449  }
450  // name and ID are valid and unique.
451  // finally insert the property into list of known properties.
452  pRegisteredProperties[propNameSpace][propName] = propId;
453  // propMaxId was updated according to the new ID earlier in this function.
454  pRegisteredPropertiesMaxId[propNameSpace] = propMaxId;
455  return propId;
456 }
457 
458 
460 {
461  if (a.pPropNameSpace != b.pPropNameSpace)
462  return false;
463  QList<int> propIds = a.registeredPropertyIdList();
464  int k;
465  for (k = 0; k < propIds.size(); ++k)
466  if (a.property(propIds[k]) != b.property(propIds[k]))
467  return false;
468 
469  return true;
470 }
471 
472 
473 
475 {
476  stream << obj.allProperties();
477  return stream;
478 }
480 {
482  stream >> props;
483  obj.setAllProperties(props);
484  return stream;
485 }
486 
487 
489 {
490  return stream << obj.toString();
491 }
492 
493 
494 
495 QDebug& operator<<(QDebug& stream, const KLFPropertizedObject& obj)
496 {
497  stream << obj.allProperties();
498  return stream;
499 }
500 
canConvert(Type t)
A class that holds properties.
Definition: klfpobj.h:86
QStringList propertyNameList() const
A list of properties that have been set.
Definition: klfpobj.cpp:138
contains(const Key &key)
values()
QDataStream & operator<<(QDataStream &stream, const KLFPropertizedObject &obj)
Definition: klfpobj.cpp:474
QList< int > propertyIdList() const
A list of properties that have been set.
Definition: klfpobj.cpp:126
virtual ~KLFPropertizedObject()
Definition: klfpobj.cpp:37
int propertyMaxId() const
See the corresponding protected static method.
Definition: klfpobj.cpp:268
virtual void setProperty(const QString &propname, const QVariant &value)
Definition: klfpobj.cpp:74
void registerBuiltInProperty(int propId, const QString &propName) const
Definition: klfpobj.cpp:303
QList< int > registeredPropertyIdList() const
See the corresponding protected static method.
Definition: klfpobj.cpp:292
int propId
Definition: klfutil.cpp:251
Include also all non-explicitely-set properties.
Definition: klfpobj.h:166
replace(int position, int n, const QString &after)
virtual QString toString(uint toStringFlags=0) const
Formats the property contents in a (human and/or parsable) string.
Definition: klfpobj.cpp:194
int registerProperty(const QString &propertyName) const
Definition: klfpobj.cpp:307
bool propertyIdRegistered(int propId) const
See the corresponding protected static method.
Definition: klfpobj.cpp:272
resize(int size)
void setAllPropertiesFromByteArray(const QByteArray &data)
Loads all properties saved by allPropertiesToByteArray()
Definition: klfpobj.cpp:186
virtual int loadProperty(const QString &propname, const QVariant &value)
Definition: klfpobj.cpp:113
int propertyIdForName(const QString &propertyName) const
See the corresponding protected static method.
Definition: klfpobj.cpp:280
#define KLF_FUNC_NAME
QMap< QString, QVariant > allProperties() const
Returns all properties that have been set.
Definition: klfpobj.cpp:153
Uses <div> with CSS classes instead of a table (HTML only)
Definition: klfpobj.h:164
QStringList registeredPropertyNameList() const
See the corresponding protected static method.
Definition: klfpobj.cpp:288
QDataStream & operator>>(QDataStream &stream, KLFPropertizedObject &obj)
Definition: klfpobj.cpp:479
QMap< QString, int > registeredProperties() const
See the corresponding protected static method.
Definition: klfpobj.cpp:296
bool propertyNameRegistered(const QString &propertyName) const
See the corresponding protected static method.
Definition: klfpobj.cpp:276
QByteArray allPropertiesToByteArray() const
Saves all the properties in binary form.
Definition: klfpobj.cpp:175
Encapsulates output in an HTML <table> and escapes strings.
Definition: klfpobj.h:163
virtual void propertyValueChanged(int propId, const QVariant &oldValue, const QVariant &newValue)
Definition: klfpobj.cpp:68
void setAllProperties(const QMap< QString, QVariant > &propValues)
Initializes properties to given values.
Definition: klfpobj.cpp:165
virtual QVariant property(const QString &propName) const
Definition: klfpobj.cpp:42
friend bool operator==(const KLFPropertizedObject &a, const KLFPropertizedObject &b)
Definition: klfpobj.cpp:459
QString propertyNameForId(int propId) const
See the corresponding protected static method.
Definition: klfpobj.cpp:284
KLFPropertizedObject(const QString &propertyNameSpace)
Definition: klfpobj.cpp:32
Ensures that non-html output is machine parsable.
Definition: klfpobj.h:165
value(const Key &key)

Generated by doxygen 1.8.11