46 #include <QMetaObject> 48 #include <QMapIterator> 54 EnumTxt::SubEnumEntry::SubEnumEntry(
const EnumTxt& subEnum, uint bitMask, uint factor,
bool isLocalOwn)
58 _bitPos =
log2( factor | 1);
59 _isLocalOwn = isLocalOwn;
67 _txtStore = arnNullptr;
68 _subEnumTab = arnNullptr;
71 setupFromMetaObject();
73 setupSubEnum( initSubEnum);
79 _metaObj = arnNullptr;
80 _txtStore = arnNullptr;
81 _subEnumTab = arnNullptr;
83 _name =
name.toUtf8();
94 void EnumTxt::setTxtRefAny(
const char* txt,
int enumVal, quint16 nameSpace)
96 _enumTxtTab.insert( EnumTxtKey( enumVal, nameSpace, _isFlag), txt);
102 if (_metaObj && nameSpace > 0)
103 setTxtRefAny( txt, enumVal, nameSpace);
109 if (_metaObj && nameSpace == 0)
return;
112 _txtStore =
new QList<QByteArray>;
114 int idx = _txtStore->size();
115 *_txtStore += QByteArray( txt);
117 setTxtRefAny( _txtStore->at( idx).constData(), enumVal, nameSpace);
123 const char* txt = _enumTxtTab.value( EnumTxtKey( enumVal, nameSpace, _isFlag), arnNullptr);
125 *isFound = (txt != arnNullptr);
126 return txt ? txt :
"";
132 setTxt( txt.toUtf8().constData(), enumVal, nameSpace);
138 return QString::fromUtf8(
getTxt( enumVal, nameSpace, isFound));
144 EnumTxtKey keyStart( _isFlag ? 1 : uint(INT_MIN), nameSpace, _isFlag);
145 EnumTxtKey keyStop( _isFlag ? UINT_MAX : uint(INT_MAX), nameSpace, _isFlag);
147 QMap<EnumTxtKey,const char*>::const_iterator i = _enumTxtTab.lowerBound( keyStart);
148 for (; i != _enumTxtTab.end(); ++i) {
149 const EnumTxtKey& keyStored = i.key();
150 if (keyStop < keyStored)
break;
152 if (qstrcmp( i.value(), txt) == 0) {
153 if (isFound) *isFound =
true;
154 return int(keyStored._enumVal);
158 if (isFound) *isFound =
false;
165 return getEnumVal( txt.toUtf8().constData(), defaultVal, nameSpace, isFound);
172 foreach (
const SubEnumEntry& entry, *_subEnumTab) {
173 bool isFound =
false;
174 int enumVal = entry._subEnum->getEnumVal( txt, -1, nameSpace, &isFound);
176 subEnumVal = enumVal << entry._bitPos;
177 bitMask = entry._bitMask;
189 return getSubEnumVal( txt.toUtf8().constData(), subEnumVal, bitMask, nameSpace);
195 if (!_isFlag)
return;
197 EnumTxtKey keyStart( 1, nameSpace, _isFlag);
198 EnumTxtKey keyStop( UINT_MAX, nameSpace, _isFlag);
201 QMap<EnumTxtKey,const char*>::const_iterator i = _enumTxtTab.lowerBound( keyStart);
202 for (; i != _enumTxtTab.end(); ++i) {
203 const EnumTxtKey& keyStored = i.key();
204 if (keyStop < keyStored)
break;
206 uint enumValStored = keyStored._enumVal;
207 bool isSubEnum = (_subEnumMask & enumValStored) != 0;
212 QByteArray enumValTxt;
213 if (keyStored._isSingleBit) {
215 bitNum =
log2( enumValStored);
216 enumValTxt =
"B" + QByteArray::number( bitNum);
220 enumValTxt =
numToStr( enumValStored);
224 if ((nameSpace > 0) || neverHumanize) {
228 enumTxt =
humanize( QString::fromUtf8( i.value())).toUtf8();
231 xsm.
add( enumValTxt, enumTxt);
238 if (!_subEnumTab)
return;
241 foreach (
const SubEnumEntry& entry, *_subEnumTab) {
242 uint bitMask = entry._bitMask;
243 uchar bitPos = entry._bitPos;
244 QByteArray enumValTxt =
"SE" +
numToStr( bitMask);
246 enumValTxt +=
":B" + QByteArray::number( bitPos);
247 QByteArray subEnumName =
getTxt( bitMask, nameSpace);
248 xsm.
add( enumValTxt, subEnumName);
251 entry._subEnum->addEnumSetTo( xsmSub, nameSpace, neverHumanize);
252 for (
int i = 0; i < xsmSub.
size(); ++i) {
253 int enumVal = xsmSub.
keyRef( i).toInt();
254 uint enumValMasked = enumVal & (bitMask >> bitPos);
255 enumValTxt =
"E" +
numToStr( enumValMasked) + (enumVal < 0 ?
"-" :
"");
264 if (!_isFlag)
return;
273 if (!_isFlag)
return QString();
277 return QString::fromUtf8( xsm.
toXString());
283 if (!_subEnumTab)
return;
286 foreach (
const SubEnumEntry& entry, *_subEnumTab) {
287 uint bitMask = entry._bitMask;
288 uchar bitPos = entry._bitPos;
289 QByteArray enumValTxt =
numToStr( bitMask);
290 QByteArray subEnumName =
getTxt( bitMask, nameSpace);
291 xsm.
add( enumValTxt, subEnumName);
294 entry._subEnum->addEnumSetTo( xsmSub, nameSpace, neverHumanize);
295 for (
int i = 0; i < xsmSub.
size(); ++i) {
296 int enumVal = xsmSub.
keyRef( i).toInt();
297 uint subEnumVal = (enumVal << bitPos) & bitMask;
307 if (!_isFlag)
return QString();
315 if (!_isFlag)
return QStringList();
317 uint maxBitVal = (UINT_MAX >> 1) + 1;
318 EnumTxtKey keyStart( 1, nameSpace, _isFlag);
319 EnumTxtKey keyStop( maxBitVal, nameSpace, _isFlag);
322 QMap<EnumTxtKey,const char*>::const_iterator i = _enumTxtTab.lowerBound( keyStart);
323 for (; i != _enumTxtTab.end(); ++i) {
324 const EnumTxtKey& keyStored = i.key();
325 if (keyStop < keyStored)
break;
327 uint enumValStored = keyStored._enumVal;
328 if (_subEnumMask & enumValStored)
331 if (uint( val) & enumValStored) {
332 retVal += QString::fromUtf8( i.value());
336 foreach (
const SubEnumEntry& entry, *_subEnumTab) {
337 int subEnum = (uint( val) & entry._bitMask) >> entry._bitPos;
338 QString etxt = entry._subEnum->getTxtString( subEnum, nameSpace);
339 if (etxt.isEmpty()) {
340 subEnum |= -1 & ~(entry._bitMask >> entry._bitPos);
341 etxt = entry._subEnum->getTxtString( subEnum, nameSpace);
342 if (etxt.isEmpty()) {
356 if (!_isFlag)
return 0;
364 if (!_isFlag)
return 0;
366 uint maxBitVal = (UINT_MAX >> 1) + 1;
367 EnumTxtKey keyStart( 1, nameSpace, _isFlag);
368 EnumTxtKey keyStop( maxBitVal, nameSpace, _isFlag);
371 QMap<EnumTxtKey,const char*>::iterator i = _enumTxtTab.lowerBound( keyStart);
372 for (; i != _enumTxtTab.end(); ++i) {
373 const EnumTxtKey& keyStored = i.key();
374 if (keyStop < keyStored)
break;
376 uint enumValStored = keyStored._enumVal;
377 if (_subEnumMask & enumValStored)
380 if (flagStrings.contains( QString::fromUtf8( i.value())))
381 retVal |= enumValStored;
384 foreach (
const SubEnumEntry& entry, *_subEnumTab) {
385 EnumTxtKey keyStart( uint(INT_MIN), nameSpace,
false);
386 EnumTxtKey keyStop( uint(INT_MAX), nameSpace,
false);
387 QMap<EnumTxtKey,const char*>::const_iterator j = entry._subEnum->_enumTxtTab.lowerBound( keyStart);
388 for (; j != entry._subEnum->_enumTxtTab.end(); ++j) {
389 const EnumTxtKey& keyStored = j.key();
390 if (keyStop < keyStored)
break;
392 QString enumTxtStr = QString::fromUtf8( j.value());
393 if (flagStrings.contains( enumTxtStr)) {
394 retVal &= ~entry._bitMask;
395 retVal |= (keyStored._enumVal << entry._bitPos) & entry._bitMask;
408 EnumTxtKey keyStart( _isFlag ? 1 : uint(INT_MIN), nameSpace, _isFlag);
409 EnumTxtKey keyStop( _isFlag ? UINT_MAX : uint(INT_MAX), nameSpace, _isFlag);
411 QMap<EnumTxtKey,const char*>::const_iterator i = _enumTxtTab.lowerBound( keyStart);
412 for (; i != _enumTxtTab.end(); ++i) {
413 const EnumTxtKey& keyStored = i.key();
414 if (keyStop < keyStored)
break;
416 int enumValStored = int(keyStored._enumVal);
418 if ((nameSpace > 0) || neverHumanize) {
422 enumTxt =
humanize( QString::fromUtf8( i.value())).toUtf8();
424 xsm.
add(QByteArray::number( enumValStored), enumTxt);
433 return QString::fromUtf8( xsm.
toXString());
453 addSubEnumAny( subEnum, bitMask, factor,
false);
457 void EnumTxt::addSubEnumAny(
const EnumTxt& subEnum, uint bitMask, uint factor,
bool isLocalOwn)
459 if (subEnum.
isFlag())
return;
462 _subEnumTab =
new QList<SubEnumEntry>;
463 SubEnumEntry entry( subEnum, bitMask, factor, isLocalOwn);
464 *_subEnumTab += entry;
465 _subEnumMask |= bitMask;
471 if (toNameSpace == 0)
return;
472 if (toNameSpace == fromNameSpace)
return;
479 for (
int i = 0; i < xsmFrom.
size(); ++i) {
480 const QByteArray& enumValKey = xsmFrom.
keyRef( i);
481 if (xsmTo.
indexOf( enumValKey) < 0) {
482 int enumVal = enumValKey.toInt();
483 const char* enumTxt =
getTxt( enumVal, fromNameSpace);
485 if ((fromNameSpace > 0) || neverHumanize) {
486 setTxtRefAny( enumTxt, enumVal, toNameSpace);
489 QByteArray enumTxtHuman =
humanize( QString::fromUtf8( enumTxt)).toUtf8();
490 setTxt( enumTxtHuman.constData(), enumVal, toNameSpace);
500 bool wasDigit =
false;
501 bool wasUpper =
false;
502 bool wasLower =
false;
503 bool wasWantSpace =
false;
504 bool wasSpace =
false;
506 for (
int i = 0; i < txt.size(); ++i) {
508 bool isDigit = c.isDigit();
509 bool isUpper = c.isUpper();
510 bool isLower = c.isLower();
511 bool wantSpace =
false;
520 else if ((i >= 2) && wasUpper && isLower && !wasWantSpace)
521 retVal.insert( retVal.size() - 1,
' ');
522 else if (wasLower && isUpper)
524 else if (!wasDigit && isDigit && !wasSpace)
526 else if (wasDigit && !isDigit)
534 wasSpace = c.isSpace();
538 wasWantSpace = wantSpace;
547 if (!initTxt)
return;
549 for (
int i = 0; (initTxt[i].
enumTxt || initTxt[i].
enumVal || initTxt[i].
ns); ++i) {
550 if (initTxt[i].enumTxt)
551 setTxtRef( initTxt[i].enumTxt, initTxt[i].enumVal, initTxt[i].ns);
558 void EnumTxt::setupSubEnum(
const _InitSubEnum* initSubEnum)
560 if (!initSubEnum)
return;
562 for (
int i = 0; initSubEnum[i].enumTxtClass; ++i) {
563 addSubEnum( *initSubEnum[i].enumTxtClass, initSubEnum[i].mask, initSubEnum[i].factor);
576 if (_metaObj)
return;
580 _txtStore = arnNullptr;
583 for (
int i = 0; i < _subEnumTab->size(); ++i) {
584 const SubEnumEntry& entry =_subEnumTab->at( i);
585 if (entry._isLocalOwn) {
586 delete entry._subEnum;
590 _subEnumTab = arnNullptr;
601 if (_metaObj)
return false;
606 _name =
name.toUtf8();
607 int nKeys = xsm.
size();
608 for (
int i = 0; i < nKeys; ++i) {
609 const char* txt = xsm.
valueRef( i).constData();
627 if (_metaObj)
return false;
633 _name =
name.toUtf8();
635 EnumTxt* subEnumTxt = arnNullptr;
638 int nLoop = xsm.
size() + 1;
639 for (
int i = 0; i < nLoop; ++i) {
640 QByteArray key = xsm.
keyRef( i);
641 QByteArray itemTxt = xsm.
valueRef( i);
642 QChar c = key.isEmpty() ?
' ' : key.at( 0);
646 int numLen = key.size() - 1;
647 bool isNeg = key.endsWith(
'-');
649 int enumVal =
strToNum( key.mid( 1, numLen), &isOk);
651 enumVal |= isNeg ? (-1 & ~(subeMask >> subePos)) : 0;
652 subEnumTxt->
setTxt( itemTxt.constData(), enumVal, 0);
655 addSubEnumAny( *subEnumTxt, subeMask, 1 << subePos,
true);
656 subEnumTxt = arnNullptr;
663 setTxt( itemTxt.constData(), enumValue, 0);
665 else if (c.isDigit()) {
666 uint enumValue =
strToNum( key, &isOk);
668 setTxt( itemTxt.constData(), enumValue, 0);
670 else if (key.startsWith(
"SE")) {
671 QList<QByteArray> seParts = key.mid( 2).split(
':');
672 subeMask =
strToNum( seParts.at( 0), &isOk);
674 subePos = seParts.size() > 1 ?
strToBitpos( seParts.at( 1), &isOk) : 0;
676 setTxt( itemTxt.constData(), subeMask, 0);
677 QString subEnumName = QString::fromUtf8( itemTxt.constData(), itemTxt.size());
678 subEnumTxt =
new EnumTxt(
false, subEnumName);
697 if (!_subEnumTab)
return 0;
698 return _subEnumTab->size();
706 uint bitMask = _subEnumTab->at( idx)._bitMask;
715 const SubEnumEntry& entry = _subEnumTab->at( idx);
716 bitMask = entry._bitMask;
717 bitPos = entry._bitPos;
726 return _subEnumTab->at( idx)._subEnum;
732 return _name.constData();
738 if (!_metaObj || _metaObj->enumeratorCount() < 1)
return 0;
740 QMetaEnum metaEnum = _metaObj->enumerator(0);
741 return metaEnum.keyCount();
748 return QByteArray::number( num);
750 return "0x" + QByteArray::number( num, 16);
756 if (str.startsWith(
"0x")) {
757 return str.mid( 2).toInt( isOk, 16);
760 return str.toInt( isOk);
767 if (str.startsWith(
"B")) {
768 return str.mid( 1).toInt( isOk);
770 if (isOk) *isOk =
false;
775 void EnumTxt::setupFromMetaObject()
777 if (!_metaObj || _metaObj->enumeratorCount() < 1)
return;
779 QMetaEnum metaEnum = _metaObj->enumerator(0);
780 int nKeys = metaEnum.keyCount();
781 for (
int i = 0; i < nKeys; ++i) {
782 int enumVal = metaEnum.value(i);
783 setTxtRefAny( metaEnum.key(i), enumVal, 0);
788 EnumTxt::EnumTxtKey::EnumTxtKey( uint enumVal, quint16 nameSpace,
bool isFlag)
791 _nameSpace = nameSpace;
793 _isSingleBit = isFlag ?
isPower2( enumVal ) : false;
797 bool EnumTxt::EnumTxtKey::operator <(
const EnumTxt::EnumTxtKey& other)
const 799 if (_isFlag != other._isFlag) qWarning() <<
"ERROR EnumKey isFlag diff !!!";
800 if (_nameSpace < other._nameSpace)
return true;
801 if (_nameSpace > other._nameSpace)
return false;
803 if (_isSingleBit != other._isSingleBit)
return _isSingleBit;
804 return _enumVal < other._enumVal;
807 return int(_enumVal) < int(other._enumVal);
QStringList flagsToStringList(int val, quint16 nameSpace=0) const
returns string list for enum flags
QString getEnumSet(quint16 nameSpace=0, bool neverHumanize=false) const
returns the enum set string
int indexOf(const char *key, int from=0) const
static uchar strToBitpos(const QByteArray &str, bool *isOk=arnNullptr)
void addSubEnumPlainTo(Arn::XStringMap &xsm, quint16 nameSpace=0, bool neverHumanize=false) const
Adds all sub enum plain and shifted to a XStringMap.
void setTxt(const char *txt, int enumVal, quint16 nameSpace)
Set an additional text for an enum val in a namespace.
QStringList values(const char *keyPrefix=arnNullptr) const
void addEnumSetTo(Arn::XStringMap &xsm, quint16 nameSpace=0, bool neverHumanize=false) const
Adds enum set to a XStringMap.
int flagsFromStringList(const QStringList &flagStrings, quint16 nameSpace=0)
returns enum flags from string list
QStringList getBasicTextList(quint16 nameSpace=0, bool neverHumanize=false) const
returns a string list containing the most basic texts
QString flagsToString(int val, quint16 nameSpace=0) const
returns text string for enum flags
bool isFlag() const
Returns true if this is a flag usage.
QString getBitSet(quint16 nameSpace=0, bool neverHumanize=false) const
returns the bit set string for enum flags
Container class with string representation for serialized data.
bool getSubEnumVal(const char *txt, int &subEnumVal, uint &bitMask, quint16 nameSpace=0) const
Returns the shifted enum value and the mask for a subEnum text in a namespace.
void addEnumSet(Arn::XStringMap &xsm, quint16 nameSpace=0, bool neverHumanize=false) const
void addBitSetTo(Arn::XStringMap &xsm, quint16 nameSpace=0, bool neverHumanize=false) const
Adds bit set for enum flags to a XStringMap.
int enumCount() const
returns number of enumerators in the enum (class)
void addFlagsTo(Arn::XStringMap &xsm, const IncludeMode &incMode, quint16 nameSpace=0, bool neverHumanize=false) const
Adds enum flags to a XStringMap.
static QByteArray numToStr(uint num)
void addSubEnum(const EnumTxt &subEnum, uint bitMask, uint factor)
Adds an other EnumTxt as a subEnum to this flag EnumTxt.
const QByteArray & keyRef(int i) const
int subEnumCount() const
Returns number of subEnums in this bitSet (class)
void setTxtString(const QString &txt, int enumVal, quint16 nameSpace)
Set an additional text for an enum val in a namespace.
const QByteArray & valueRef(int i) const
void clear(bool freeMem=false)
const EnumTxt * subEnumAt(int idx) const
Returns a pointer to a SubEnum.
void setTxtRef(const char *txt, int enumVal, quint16 nameSpace)
QByteArray toXString() const
bool loadBitSet(const Arn::XStringMap &xsm, const QString &name=QString())
Loads the instance by an bit set (flags) XStringMap.
void addSubEnumTo(Arn::XStringMap &xsm, quint16 nameSpace=0, bool neverHumanize=false) const
Adds sub enum flags to a XStringMap.
int getEnumVal(const char *txt, int defaultVal=0, quint16 nameSpace=0, bool *isFound=arnNullptr) const
Returns the enum value for a text in a namespace.
const char * name() const
returns the name of the enum (class)
void clear()
Clear this dynamic instance to its starting state.
QString getTxtString(int enumVal, quint16 nameSpace=0, bool *isFound=arnNullptr) const
Returns the text for a enum value in a namespace.
bool subEnumPropAt(int idx, uint &bitMask, uchar &bitPos) const
Returns the properties of a SubEnum.
QString subEnumNameAt(int idx, quint16 nameSpace=0) const
Returns the name of a SubEnum.
const char * getTxt(int enumVal, quint16 nameSpace=0, bool *isFound=arnNullptr) const
Returns the text for a enum value in a namespace.
XStringMap & add(const char *key, const QByteArray &val)
static uint strToNum(const QByteArray &str, bool *isOk=arnNullptr)
static QString humanize(const QString &txt)
returns the humanized text
int flagsFromString(const QString &flagString, quint16 nameSpace=0)
returns enum flags from string
EnumTxt(const QMetaObject *metaObj, bool isFlag, const _InitEnumTxt *initTxt, const _InitSubEnum *initSubEnum, const char *name)
bool loadEnumSet(const Arn::XStringMap &xsm, const QString &name=QString())
Loads the instance by an enum set XStringMap.
void setMissingTxt(quint16 toNameSpace, quint16 fromNameSpace=0, bool neverHumanize=false)
Copies missing enum texts from one namespace to another.