[KLF Backend][KLF Tools][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$ */
23
24#include <QtDebug>
25#include <QByteArray>
26#include <QDataStream>
27#include <QTextStream>
28
29#include "klfpobj.h"
30
31
33{
34}
36{
37}
38
40{
41}
43{
44}
45
46
47
48// -----------------------------
49
50
52{
55 foreach (QString pname, pnames) {
56 data[pname] = property(pname);
57 }
58 return data;
59}
60
62{
64 klfDbg("data="<<data) ;
65 bool allok = true;
66 for (QVariantMap::const_iterator it = data.begin(); it != data.end(); ++it) {
67 bool ok = setProperty(it.key(), it.value());
68 if (!ok) {
69 allok = false;
70 qWarning()<<KLF_FUNC_NAME<<": Can't set property "<<it.key()<<" to "<<it.value();
71 }
72 }
73 return allok;
74}
75
76
77// --------
78
80{
81 return stream << e.specification() << qint32(e.value());
82}
84{
85 QByteArray s;
86 qint32 x;
87 stream >> s >> x;
89 e.setValue(x);
90 return stream;
91}
92
93
94// -------
95
96
97
98
100 : pPropNameSpace(propNameSpace)
101{
102 // ensure the property name space exists
103 if (!pRegisteredProperties.contains(propNameSpace))
104 pRegisteredProperties[propNameSpace] = QMap<QString,int>();
105 if (!pRegisteredPropertiesMaxId.contains(propNameSpace))
106 pRegisteredPropertiesMaxId[propNameSpace] = -1;
107}
108
110{
111}
112
113
115{
116 int propId = propertyIdForName(propname);
117 if (propId < 0) {
118 qWarning("%s[%s](): Property `%s' not registered.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
119 qPrintable(propname));
120 return QVariant();
121 }
122 return property(propId);
123}
125{
126 if (propId >= 0 && propId < pProperties.size()) {
127 // all ok, return property (possibly an empty QVariant() if prop not set)
128 return pProperties[propId];
129 }
130 if (propId < 0) {
131 qWarning("%s[%s](%d): invalid property ID.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
132 propId);
133 return QVariant();
134 }
135 // property not set (or property not registered)
136 return QVariant();
137}
138
139QVariant KLFPropertizedObject::property(const QString& propname, const QVariant& defaultValue) const
140{
141 int propId = propertyIdForName(propname);
142 if (propId < 0) {
143 return defaultValue;
144 }
145 QVariant value = property(propId);
146 if (value.isValid())
147 return value;
148 return defaultValue;
149}
150
152{
153 return property(propName, QVariant()).isValid();
154}
155
157{
159 return false;
160
162}
163
164
166 const QVariant& )
167{
168 // do nothing. Subclasses may implement thier own behavior.
169}
170
171bool KLFPropertizedObject::doSetProperty(const QString& propname, const QVariant& value)
172{
173 if ( ! propertyNameRegistered(propname) ) {
174 qWarning("%s[%s](): Property `%s' not registered.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
175 qPrintable(propname));
176 return false;
177 }
178 return doSetProperty(propertyIdForName(propname), value);
179}
181{
182 if (propId >= 0 && propId < pProperties.size()) {
183 // all ok, set this property
184 QVariant oldvalue = pProperties[propId];
185 pProperties[propId] = value;
186 propertyValueChanged(propId, oldvalue, value);
187 return true;
188 }
189 if (propId < 0) {
190 qWarning("%s[%s](id=%d): invalid property ID.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
191 propId);
192 return false;
193 }
194 // maybe our properties array needs resize for properties that could have been
195 // registered after last access
196 int maxId = propertyMaxId();
197 if (propId <= maxId) {
198 pProperties.resize(maxId + 1);
199 }
200 if (propId < 0 || propId >= pProperties.size() ||
202 qWarning("%s[%s](id=%d): invalid property id.", KLF_FUNC_NAME, qPrintable(pPropNameSpace),
203 propId);
204 return false;
205 }
206 QVariant oldvalue = pProperties[propId];
207 pProperties[propId] = value;
208 propertyValueChanged(propId, oldvalue, value);
209 return true;
210}
211int KLFPropertizedObject::doLoadProperty(const QString& propname, const QVariant& value)
212{
213 klfDbg("propname="<<propname<<" value="<<value) ;
214 int propId = propertyIdForName(propname);
215 if ( propId < 0 ) {
216 // register property
217 propId = registerProperty(propname);
218 if (propId < 0)
219 return -1;
220 }
221 doSetProperty(propId, value);
222 return propId;
223}
224
226{
227 QList<int> idList;
228 int k;
229 // walk vector and a fill a QList of all set properties' ID
230 for (k = 0; k < pProperties.size(); ++k) {
231 if (pProperties[k].isValid())
232 idList << k;
233 }
234 return idList;
235}
236
238{
239 QStringList propSetList;
240 int k;
241 // walk vector and a fill a QStringList of all set properties.
242 for (k = 0; k < pProperties.size(); ++k) {
243 if (pProperties[k].isValid())
244 propSetList << propertyNameForId(k);
245 }
246 return propSetList;
247}
248
249
250
251
253{
254 QList<int> propertyList = propertyIdList();
255 QMap<QString,QVariant> properties;
256 int k;
257 // walk all properties and insert them into list
258 for (k = 0; k < propertyList.size(); ++k) {
259 properties[propertyNameForId(propertyList[k])] = property(propertyList[k]);
260 }
261 return properties;
262}
263
264bool KLFPropertizedObject::setProperty(const QString& propname, const QVariant& value)
265{
266 return doLoadProperty(propname, value) >= 0;
267}
268
270{
271 KLF_ASSERT_CONDITION(propertyIdRegistered(propId), "Property ID="<<propId<<" is not registered!",
272 return false; ) ;
273
274 return setProperty(propertyNameForId(propId), value);
275}
276
277
279{
281 klfDbg("propValues="<<propValues) ;
282
283 bool allok = true;
284 QStringList propKeys = propValues.keys();
285 int k;
286 for (k = 0; k < propKeys.size(); ++k) {
287 // bypass check, set property anyway
288 bool ok = (doLoadProperty(propKeys[k], propValues[propKeys[k]]) >= 0);
289 if (!ok) {
290 allok = false;
291 qWarning()<<KLF_FUNC_NAME<<": Failed to load property "<<propKeys[k]<<" with value "<<propValues[propKeys[k]];
292 }
293 }
294 return allok;
295}
296
297
299{
300 QByteArray data;
301 {
302 QDataStream stream(&data, QIODevice::WriteOnly);
303 stream << *this;
304 // force close of buffer in destroying stream
305 }
306 return data;
307}
308
310{
311 QDataStream stream(data);
312 stream >> *this;
313}
314
315/*
316QVariant KLFPropertizedObject::parsePropertyValue(int propId, const QString& strvalue)
317{
318 KLF_ASSERT_CONDITION(propertyIdRegistered(propId), "Property ID="<<propId<<" is not registered!",
319 return QVariant(); ) ;
320
321 return parsePropertyValue(propertyNameForId(propId), strvalue);
322}
323
324QVariant KLFPropertizedObject::parsePropertyValue(const QString& / *propName* /, const QString& / *strvalue* /)
325{
326 return QVariant();
327}
328*/
329
330
331
332
333
335{
336 QString s;
337
338 int k;
339 QList<int> props;
340 bool html = (toStringFlags & ToStringUseHtml);
341 bool quote = (toStringFlags & ToStringQuoteValues);
342 bool allprops = (toStringFlags & ToStringAllProperties);
343 bool usehtmldiv = (toStringFlags & ToStringUseHtmlDiv);
344
345 if (allprops)
346 props = registeredPropertyIdList();
347 else
348 props = propertyIdList();
349
350 if (html) {
351 if (usehtmldiv) {
352 s = QString("<div class=\"klfpobj_entry\">\n<div class=\"klfpobj_name\">%2</div>\n")
353 .arg(pPropNameSpace.toHtmlEscaped());
354 } else {
355 s = QString("<table class=\"klfpobj_tentry\">\n"
356 "<tr colspan=\"2\" class=\"klfpobj_tname\"><th>%1</th></tr>\n")
357 .arg(pPropNameSpace.toHtmlEscaped());
358 }
359 } else {
360 s = QString("%1\n").arg(pPropNameSpace);
361 }
362
363 for (k = 0; k < props.size(); ++k) {
364 QString pname = propertyNameForId(props[k]);
365 QVariant vval = property(props[k]);
366 bool isnull = !vval.isValid();
367 bool canstring = vval.canConvert(QVariant::String);
368 QString value = vval.toString();
369 if (html) {
370 if (usehtmldiv)
371 s += QString("<div class=\"klfpobj_prop_%1\"><div class=\"klfpobj_propname\">%2</div>: "
372 "<div class=\"klfpobj_propvalue\">%3</div></div>\n")
373 .arg(pname, pname, value.toHtmlEscaped());
374 else
375 s += QString(" <tr class=\"klfpobj_tprop_%1\"><td class=\"klfpobj_tpropname\">%2</td>"
376 "<td class=\"klfpobj_tpropvalue\">%3</td></tr>\n")
377 .arg(pname, pname, value.toHtmlEscaped());
378 } else {
379 if (quote) {
380 if (!isnull && canstring) {
381 value.replace("\\", "\\\\");
382 value.replace("\"", "\\\"");
383 value = '"' + value + '"';
384 } else if (!isnull) {
385 value = QString("[%1]").arg(vval.typeName());
386 } else {
387 // true null
388 value = "NULL";
389 }
390 }
391 s += QString("%1: %2\n").arg(propertyNameForId(props[k]), value);
392 }
393 }
394 s += "\n";
395 if (html) {
396 if (usehtmldiv) {
397 s += "</div>\n";
398 } else {
399 s += "</table>\n";
400 }
401 }
402
403 return s;
404}
405
406
407
409{
410 return propertyMaxId(pPropNameSpace);
411}
413{
414 return propertyIdRegistered(pPropNameSpace, propId);
415}
417{
418 return propertyNameRegistered(pPropNameSpace, propertyName);
419}
421{
422 return propertyIdForName(pPropNameSpace, propName);
423}
425{
426 return propertyNameForId(pPropNameSpace, id);
427}
429{
430 return registeredPropertyNameList(pPropNameSpace);
431}
433{
434 return registeredPropertyIdList(pPropNameSpace);
435}
437{
438 return registeredProperties(pPropNameSpace);
439}
440
441// ---- PROTECTED ----
442
444{
445 registerBuiltInProperty(pPropNameSpace, propId, name);
446}
448{
449 return registerProperty(pPropNameSpace, propName);
450}
451
452// ---- STATIC PROTECTED ----
453
455 const QString& name)
456{
457 internalRegisterProperty(pnamespace, name, propId);
458}
459int KLFPropertizedObject::registerProperty(const QString& propNameSpace, const QString& propName)
460{
461 return internalRegisterProperty(propNameSpace, propName, -1);
462}
464{
465 if ( ! pRegisteredPropertiesMaxId.contains(propNameSpace) ) {
466 qWarning("%s(): property name space `%s' does not exist!", KLF_FUNC_NAME,
467 qPrintable(propNameSpace));
468 return -1;
469 }
470 return pRegisteredPropertiesMaxId[propNameSpace];
471}
473{
474 return ( ! propertyNameForId(propNameSpace, propId).isNull() ) ;
475}
477 const QString& propertyName)
478{
479 return (propertyIdForName(propNameSpace, propertyName) != -1) ;
480}
481int KLFPropertizedObject::propertyIdForName(const QString& propNameSpace, const QString& name)
482{
483 if ( ! pRegisteredProperties.contains(propNameSpace) ) {
484 qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
485 qPrintable(propNameSpace));
486 return -1;
487 }
488 QMap<QString, int> propList = pRegisteredProperties[propNameSpace];
489 if ( ! propList.contains(name) )
490 return -1;
491 return propList.value(name);
492}
494{
495 if ( ! pRegisteredProperties.contains(propNameSpace) ) {
496 qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
497 qPrintable(propNameSpace));
498 return QString();
499 }
500 QMap<QString, int> propList = pRegisteredProperties[propNameSpace];
501 QList<QString> keyList = propList.keys(propId);
502 if (keyList.isEmpty())
503 return QString();
504 if (keyList.size() > 1) {
505 qWarning("%s: What's going on?? property Id=%d not unique in prop name space `%s'.",
506 KLF_FUNC_NAME, propId, qPrintable(propNameSpace));
507 }
508 return keyList[0];
509}
511{
512 if ( ! pRegisteredProperties.contains(propNameSpace) ) {
513 qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
514 qPrintable(propNameSpace));
515 return QStringList();
516 }
517
518 return pRegisteredProperties[propNameSpace].keys();
519}
521{
522 if ( ! pRegisteredProperties.contains(propNameSpace) ) {
523 qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
524 qPrintable(propNameSpace));
525 return QList<int>();
526 }
527
528 return pRegisteredProperties[propNameSpace].values();
529}
530
532{
533 if ( ! pRegisteredProperties.contains(propNameSpace) ) {
534 qWarning("%s: property name space `%s' does not exist!", KLF_FUNC_NAME,
535 qPrintable(propNameSpace));
536 return QMap<QString, int>();
537 }
538 return pRegisteredProperties[propNameSpace];
539}
540
541
542// ---- PRIVATE ----
543
544QMap<QString, QMap<QString, int> > KLFPropertizedObject::pRegisteredProperties =
546
547QMap<QString, int> KLFPropertizedObject::pRegisteredPropertiesMaxId = QMap<QString,int>();
548
549
550int KLFPropertizedObject::internalRegisterProperty(const QString& propNameSpace,
551 const QString& propName,
552 int propId)
553{
555 klfDbg("propNameSpace = " << propNameSpace << ", propName = " << propName << ", propId = " << propId) ;
556
557 const QMap<QString, int> propList = pRegisteredProperties[propNameSpace];
558 int propMaxId = -1;
559 if (pRegisteredPropertiesMaxId.contains(propNameSpace)) {
560 propMaxId = pRegisteredPropertiesMaxId[propNameSpace];
561 }
562 if (propId == -1) {
563 // propMaxId is maximum ID already used, so +1 gives a free ID.
564 propId = propMaxId + 1;
565 // and update propMaxId to account for the new propId...
566 propMaxId = propId;
567 } else {
568 // used the fixed propId. Update propMaxId if necessary.
569 if (propId > propMaxId) {
570 propMaxId = propId;
571 }
572 }
573 if ( propList.keys(propId).size() > 0 ) {
574 QString oldPropName = propList.keys(propId).at(0);
575 if (propName == oldPropName) {
576 return propId; // already registered, return that property ID
577 }
578 qWarning("%s[%s]: Property ID `%d' is already registered with conflicting names!\n"
579 "\told name is `%s', new is `%s'",
580 KLF_FUNC_NAME, qPrintable(propNameSpace), propId, qPrintable(oldPropName),
581 qPrintable(propName));
582 return -1;
583 }
584 // make sure property name is valid and unique
585 if (propName.isEmpty()) {
586 qWarning("%s[%s]: Cannot Register a property with empty name!", KLF_FUNC_NAME,
587 qPrintable(propNameSpace));
588 return -1;
589 }
590 if (propList.contains(propName)) {
591 qWarning("%s[%s]: Property `%s' already registered.", KLF_FUNC_NAME, qPrintable(propNameSpace),
592 qPrintable(propName));
593 return -1;
594 }
595 // name and ID are valid and unique.
596 // finally insert the property into list of known properties.
597 pRegisteredProperties[propNameSpace][propName] = propId;
598 // propMaxId was updated according to the new ID earlier in this function.
599 pRegisteredPropertiesMaxId[propNameSpace] = propMaxId;
600 return propId;
601}
602
603
605{
606 if (a.pPropNameSpace != b.pPropNameSpace)
607 return false;
609 int k;
610 for (k = 0; k < propIds.size(); ++k)
611 if (a.property(propIds[k]) != b.property(propIds[k]))
612 return false;
613
614 return true;
615}
616
617
618
620{
621 stream << allProperties();
622 return stream;
623}
625{
627 stream >> props;
628 setAllProperties(props);
629 return stream;
630}
632{
633 return obj.streamInto(stream);
634}
636{
637 return obj.streamFrom(stream);
638}
639
640
642{
643 return stream << obj.toString();
644}
645
646
647
649{
650 stream << obj.allProperties();
651 return stream;
652}
653
654
655
virtual ~KLFAbstractPropertizedObject()
Definition: klfpobj.cpp:35
virtual QVariant property(const QString &propName) const =0
get a property's value
virtual bool setAllProperties(const QMap< QString, QVariant > &data)
Convenience function to load a set of property values.
Definition: klfpobj.cpp:61
virtual bool setProperty(const QString &pname, const QVariant &value)=0
Assign a value to a property.
virtual QStringList propertyNameList() const =0
Queries what property are (or can be) set.
virtual QMap< QString, QVariant > allProperties() const
Convenience function to retrieve all properties.
Definition: klfpobj.cpp:51
int value() const
Definition: klfpobj.h:172
QByteArray specification() const
Definition: klfpobj.h:200
bool setSpecification(const QByteArray &data)
Definition: klfpobj.h:205
void setValue(int v)
Definition: klfpobj.h:176
A class that holds properties.
Definition: klfpobj.h:278
@ ToStringQuoteValues
Ensures that non-html output is machine parsable.
Definition: klfpobj.h:460
@ ToStringUseHtmlDiv
Uses <div> with CSS classes instead of a table (HTML only)
Definition: klfpobj.h:459
@ ToStringAllProperties
Include also all non-explicitely-set properties.
Definition: klfpobj.h:461
@ ToStringUseHtml
Encapsulates output in an HTML <table> and escapes strings.
Definition: klfpobj.h:458
void setAllPropertiesFromByteArray(const QByteArray &data)
Loads all properties saved by allPropertiesToByteArray()
Definition: klfpobj.cpp:309
virtual QVariant property(const QString &propName) const
Definition: klfpobj.cpp:114
QStringList propertyNameList() const
A list of properties that have been set.
Definition: klfpobj.cpp:237
virtual bool doSetProperty(const QString &propname, const QVariant &value)
Definition: klfpobj.cpp:171
QString propertyNameForId(int propId) const
See the corresponding protected static method.
Definition: klfpobj.cpp:424
bool propertyIdRegistered(int propId) const
See the corresponding protected static method.
Definition: klfpobj.cpp:412
virtual bool setAllProperties(const QMap< QString, QVariant > &propValues)
Initializes properties to given values.
Definition: klfpobj.cpp:278
QByteArray allPropertiesToByteArray() const
Saves all the properties in binary form.
Definition: klfpobj.cpp:298
KLFPropertizedObject(const QString &propertyNameSpace)
Definition: klfpobj.cpp:99
QList< int > propertyIdList() const
A list of properties that have been set.
Definition: klfpobj.cpp:225
virtual void propertyValueChanged(int propId, const QVariant &oldValue, const QVariant &newValue)
Definition: klfpobj.cpp:165
virtual bool setProperty(const QString &propname, const QVariant &value)
Sets the given property to the given value.
Definition: klfpobj.cpp:264
void registerBuiltInProperty(int propId, const QString &propName) const
Definition: klfpobj.cpp:443
QList< int > registeredPropertyIdList() const
See the corresponding protected static method.
Definition: klfpobj.cpp:432
QStringList registeredPropertyNameList() const
See the corresponding protected static method.
Definition: klfpobj.cpp:428
QMap< QString, QVariant > allProperties() const
Returns all properties that have been set.
Definition: klfpobj.cpp:252
QMap< QString, int > registeredProperties() const
See the corresponding protected static method.
Definition: klfpobj.cpp:436
virtual bool hasPropertyValue(const QString &propName) const
Tests if a property was set.
Definition: klfpobj.cpp:151
virtual QString toString(uint toStringFlags=0) const
Formats the property contents in a (human and/or parsable) string.
Definition: klfpobj.cpp:334
virtual ~KLFPropertizedObject()
Definition: klfpobj.cpp:109
int propertyMaxId() const
See the corresponding protected static method.
Definition: klfpobj.cpp:408
int registerProperty(const QString &propertyName) const
Definition: klfpobj.cpp:447
int propertyIdForName(const QString &propertyName) const
See the corresponding protected static method.
Definition: klfpobj.cpp:420
bool propertyNameRegistered(const QString &propertyName) const
See the corresponding protected static method.
Definition: klfpobj.cpp:416
QDataStream & streamFrom(QDataStream &stream)
Explicit function name for the simple "operator>>".
Definition: klfpobj.cpp:624
QDataStream & streamInto(QDataStream &stream) const
Explicit function name for the simple "operator<<".
Definition: klfpobj.cpp:619
virtual int doLoadProperty(const QString &propname, const QVariant &value)
Definition: klfpobj.cpp:211
virtual ~KLFSpecifyableType()
Definition: klfpobj.cpp:42
int propId
Definition: klfdatautil.cpp:96
#define KLF_DEBUG_BLOCK(msg)
Utility to debug the execution of a block.
#define KLF_ASSERT_CONDITION(expr, msg, failaction)
Asserting Conditions (NON-FATAL)
#define KLF_FUNC_NAME
#define klfDbg(streamableItems)
print debug stream items
#define KLF_EXPORT
Definition: klfdefs.h:41
KLF_EXPORT QDataStream & operator<<(QDataStream &stream, const KLFEnumType &e)
Definition: klfpobj.cpp:79
bool operator==(const KLFPropertizedObject &a, const KLFPropertizedObject &b)
Definition: klfpobj.cpp:604
KLF_EXPORT QDataStream & operator>>(QDataStream &stream, KLFEnumType &e)
Definition: klfpobj.cpp:83
bool isEmpty() const
int size() const
iterator begin()
bool contains(const Key &key) const
iterator end()
QList< Key > keys() const
const T value(const Key &key, const T &defaultValue) const
QList< T > values() const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const
bool isEmpty() const
QString & replace(int position, int n, QChar after)
QString toHtmlEscaped() const
bool canConvert(int targetTypeId) const
bool isValid() const
QString toString() const
const char * typeName() const
void resize(int size)
int size() const

Generated by doxygen 1.9.5