git-svn-id: svn://db.shs.com.ru/libs@161 a8b55f48-bf90-11e4-a774-851b48703e85
This commit is contained in:
@@ -24,6 +24,16 @@ bool KInterface::test(int v) {
|
||||
}
|
||||
|
||||
|
||||
CDType & KInterface::operator [](const PIDeque<int> & path_) {
|
||||
return core->k_[path_];
|
||||
}
|
||||
|
||||
|
||||
CDType & KInterface::operator [](const PIString & name_) {
|
||||
return core->k_[name_];
|
||||
}
|
||||
|
||||
|
||||
CDType & KInterface::operator [](int v) {
|
||||
return core->k_[v];
|
||||
}
|
||||
|
||||
@@ -19,6 +19,10 @@ public:
|
||||
bool test(int v);
|
||||
CDType & operator [](int v);
|
||||
const CDType operator [](int v) const;
|
||||
CDType & operator [](const PIString & name_);
|
||||
const CDType operator [](const PIString & name_) const {return (*this)[name_];}
|
||||
CDType & operator [](const PIDeque<int> & path_);
|
||||
const CDType operator [](const PIDeque<int> & path_) const {return (*this)[path_];}
|
||||
CDSection & section(int v);
|
||||
const CDSection section(int v) const;
|
||||
CDSection & section(const PIDeque<int> &path);
|
||||
|
||||
@@ -160,6 +160,16 @@ CDSection CDParser::parse(PIIODevice * d, int cdsection_type) {
|
||||
parseEnumLine(line, &cev, &type, &comment);
|
||||
//piCout << line << "=" << cev << "//" << type << comment;
|
||||
ck = CDType(cev, line, type, "", "", comment, et);
|
||||
if (type == "e") {
|
||||
if (comment.startsWith("${")) {
|
||||
comment.cutLeft(1);
|
||||
PIString en = comment.inBrackets('{', '}');
|
||||
comment.cutLeft(en.size_s() + 2).trim();
|
||||
ck.setEnumValues(sections.value(en).enumValues());
|
||||
ck.setComment(comment);
|
||||
piCout << "enum" << en << ck.enumValues();
|
||||
}
|
||||
}
|
||||
cs[cev] = ck;
|
||||
//cevalues[line] = cev;
|
||||
enum_values[line] = cev;
|
||||
|
||||
@@ -37,8 +37,7 @@ CDType::CDType(int i, const PIString & n, const PIString & t, const PIString & v
|
||||
calculated = false;
|
||||
parent = 0;
|
||||
if (type_ == "e") {
|
||||
enum_values << comment_.inBrackets('{', '}').split(",");
|
||||
piForeach(PIString &s, enum_values) s.trim();
|
||||
enum_values = parseEnumComment(comment_);
|
||||
// piCout << enum_values.size() << enum_values;
|
||||
}
|
||||
// piCout << type_.size() << type_.toUTF8();
|
||||
@@ -63,14 +62,6 @@ PIString CDType::value() const {
|
||||
}
|
||||
|
||||
|
||||
void CDType::setFormula(const PIString & f) {
|
||||
formula_ = f;
|
||||
calculated = false;
|
||||
//PIEvaluator e;
|
||||
//calculate(&e);
|
||||
}
|
||||
|
||||
|
||||
void CDType::setValue(const PIString & value_) {
|
||||
formula_ = value_;
|
||||
value_d = formula_.toDouble();
|
||||
@@ -79,6 +70,14 @@ void CDType::setValue(const PIString & value_) {
|
||||
}
|
||||
|
||||
|
||||
void CDType::setFormula(const PIString & f) {
|
||||
formula_ = f;
|
||||
calculated = false;
|
||||
//PIEvaluator e;
|
||||
//calculate(&e);
|
||||
}
|
||||
|
||||
|
||||
bool CDType::calculate(PIEvaluator * e, PIVector<const CDType * > stack) {
|
||||
if (stack.contains(this)) {
|
||||
error_ = "Circular dependencies: ";
|
||||
@@ -142,6 +141,31 @@ bool CDType::calculate(PIEvaluator * e, PIVector<const CDType * > stack) {
|
||||
}
|
||||
|
||||
|
||||
PIVector<CDType::Enumerator> CDType::parseEnumComment(PIString c) {
|
||||
PIVector<CDType::Enumerator> ret;
|
||||
if (c.isEmpty()) return ret;
|
||||
if (type_ == "e") {
|
||||
PIStringList sl = c.inBrackets('{', '}').split(",");
|
||||
int cval = 0;
|
||||
piForeach (PIString & s, sl) {
|
||||
s.trim();
|
||||
if (s.isEmpty()) continue;
|
||||
if (s[0].isDigit()) {
|
||||
int ind = s.find("-");
|
||||
if (ind > 0) {
|
||||
cval = s.left(ind).toInt();
|
||||
s.cutLeft(ind + 1).trim();
|
||||
}
|
||||
}
|
||||
ret << CDType::Enumerator(cval, s);
|
||||
++cval;
|
||||
}
|
||||
}
|
||||
piCout << c << "=" << ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//CDType::CDType(const CDType &cdt) {
|
||||
// index_ = cdt.index_;
|
||||
// name_ = cdt.name_;
|
||||
@@ -233,10 +257,11 @@ CDType & CDSection::operator [](const PIString & name_) {
|
||||
|
||||
CDType & CDSection::operator [](const PIDeque<int> & path_) {
|
||||
if (path_.isEmpty()) return null;
|
||||
CDSection & s(*this);
|
||||
CDSection * s = this;
|
||||
for (int i = 0; i < path_.size_s() - 1; ++i)
|
||||
s = s.section(path_[i]);
|
||||
return s[path_.back()];
|
||||
s = &(s->section(path_[i]));
|
||||
if (!s) return null;
|
||||
return (*s)[path_.back()];
|
||||
}
|
||||
|
||||
int CDSection::count(bool recursive) const {
|
||||
@@ -288,12 +313,19 @@ void CDSection::write(PIIODevice * d, const PIString & prefix) {
|
||||
PIMap<int, CDType>::iterator i;
|
||||
for (i = k.begin(); i != k.end(); ++i) {
|
||||
CDType & ck(i.value());
|
||||
//l.clear();
|
||||
l = PIString::fromNumber(ck.index()) + ".f = " + ck.formula() + " #s " + ck.comment() + " \n";
|
||||
l.clear(); l << ck.index() << ".f = " << ck.formula() << " #s " << ck.comment() << " \n";
|
||||
d->write(l.toUTF8());
|
||||
l.clear();
|
||||
l << ck.index() << ".v = " << ck.value() << " #" << ck.type() << " " << ck.name() << " \n";
|
||||
l.clear(); l << ck.index() << ".v = " << ck.value() << " #" << ck.type() << " " << ck.name() << " \n";
|
||||
d->write(l.toUTF8());
|
||||
if (!ck.enumValues().isEmpty()) {
|
||||
l.clear(); l << ck.index() << ".ev = {";
|
||||
//PIVector<CDType::Enumerator> el = ck.enumValues();
|
||||
piForeachC (CDType::Enumerator & e, ck.enumValues())
|
||||
l << e.first << " - " << e.second << ", ";
|
||||
l.cutRight(2);
|
||||
l << "} \n";
|
||||
d->write(l.toUTF8());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!s.isEmpty()) {
|
||||
@@ -327,7 +359,13 @@ void CDSection::read(const void * ep) {
|
||||
// piCout << "[read]" << ke->name() << ke->value() << ok;
|
||||
// PIString n = ke->getValue("v").comment();
|
||||
// PIString t = n.takeLeft(1);
|
||||
if (ok) k[kid] = CDType(kid, ke->getValue("v").comment(), ke->getValue("v").type(), ke->getValue("v").value(), ke->getValue("f").value(), ke->getValue("f").comment(), CDType::cdK);
|
||||
if (ok) {
|
||||
CDType ck = CDType(kid, ke->getValue("v").comment(), ke->getValue("v").type(), ke->getValue("v").value(), ke->getValue("f").value(), ke->getValue("f").comment(), CDType::cdK);
|
||||
PIString ev = ke->getValue("ev", "");
|
||||
if (!ev.isEmpty())
|
||||
ck.enum_values = ck.parseEnumComment(ev);
|
||||
k[kid] = ck;
|
||||
}
|
||||
}
|
||||
PIConfig::Entry & sl = e.getValue("s");
|
||||
for (int i = 0; i < sl.childCount(); ++i) {
|
||||
@@ -344,6 +382,7 @@ void CDSection::update(CDSection & v, bool keep_names) {
|
||||
PIMap<PIString, PIString> prev_k_f;
|
||||
PISet<int> used;
|
||||
PIMap<int, CDType>::iterator i;
|
||||
//piCout << "before" << k.size() << v.k.size();
|
||||
if (keep_names) {
|
||||
for (i = k.begin(); i != k.end(); ++i)
|
||||
prev_k_f[i.value().name_] = i.value().formula();
|
||||
@@ -362,6 +401,7 @@ void CDSection::update(CDSection & v, bool keep_names) {
|
||||
ck.setFormula(prev_k_f[ck.name_]);
|
||||
}
|
||||
}
|
||||
//piCout << " after" << k.size();
|
||||
for (i = v.k.begin(); i != v.k.end(); ++i) {
|
||||
if (!used.contains(i.key()))
|
||||
k[i.key()] = i.value();
|
||||
@@ -433,6 +473,7 @@ void CDSection::makePath(PIDeque<int> p) {
|
||||
tp = p;
|
||||
tp << i.key();
|
||||
i.value().path_ = tp;
|
||||
//piCout << "path for" << i.value().name() << tp;
|
||||
}
|
||||
PIMap<int, CDSection>::iterator j;
|
||||
for (j = s.begin(); j != s.end(); ++j) {
|
||||
@@ -456,3 +497,12 @@ PIVector<CDType * > CDSection::children(bool recursive) const {
|
||||
}
|
||||
|
||||
|
||||
PIVector<CDType::Enumerator> CDSection::enumValues() const {
|
||||
PIVector<CDType::Enumerator> ret;
|
||||
PIMap<int, CDType>::const_iterator i;
|
||||
for (i = k.begin(); i != k.end(); ++i)
|
||||
ret << CDType::Enumerator(i.key(), i.value().name());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ class CDType {
|
||||
friend class CDSection;
|
||||
public:
|
||||
enum cdT {cdNull, cdK, cdX, cdC};
|
||||
typedef PIPair<int, PIString> Enumerator;
|
||||
CDType();
|
||||
CDType(int i, const PIString & n, const PIString & t, const PIString & v, const PIString & f, const PIString & c, cdT cd_t);
|
||||
int index() const {return index_;}
|
||||
@@ -30,20 +31,23 @@ public:
|
||||
int toInt() const {return value_i;}
|
||||
bool toBool() const {return value_b;}
|
||||
cdT cd_type() const {return cd_type_;}
|
||||
void setFormula(const PIString & formula);
|
||||
void setValue(const PIString & value_);
|
||||
void setFormula(const PIString & formula);
|
||||
void setComment(const PIString & comment) {comment_ = comment;}
|
||||
operator double() const {return value_d;}
|
||||
const PIStringList & enumValues() const {return enum_values;}
|
||||
const PIVector<CDType::Enumerator> & enumValues() const {return enum_values;}
|
||||
void setEnumValues(const PIVector<CDType::Enumerator> & ev) {enum_values = ev;}
|
||||
const PIString & errorString() const {return error_;}
|
||||
PIDeque<int> path() const {return path_;}
|
||||
|
||||
protected:
|
||||
bool calculate(PIEvaluator * e, PIVector<const CDType * > stack = PIVector<const CDType * >());
|
||||
PIVector<CDType::Enumerator> parseEnumComment(PIString c);
|
||||
cdT cd_type_;
|
||||
int index_;
|
||||
PIString name_, type_;
|
||||
PIString value_s, formula_, comment_, error_;
|
||||
PIStringList enum_values;
|
||||
PIVector<CDType::Enumerator> enum_values;
|
||||
CDSection * parent;
|
||||
PIDeque<int> path_;
|
||||
double value_d;
|
||||
@@ -81,6 +85,7 @@ public:
|
||||
void calculate();
|
||||
void makePath(PIDeque<int> p = PIDeque<int>());
|
||||
PIVector<CDType * > children(bool recursive = true) const;
|
||||
PIVector<CDType::Enumerator> enumValues() const;
|
||||
|
||||
PIString name;
|
||||
PIString alias;
|
||||
|
||||
@@ -3,44 +3,6 @@
|
||||
#include "qvariantedit.h"
|
||||
|
||||
|
||||
QVariant::Type typeFromLetter(const QString & l) {
|
||||
if (l.isEmpty()) return QVariant::String;
|
||||
QString ft = l.left(1);
|
||||
if (ft == "l") return QVariant::StringList;
|
||||
if (ft == "b") return QVariant::Bool;
|
||||
if (ft == "n") return QVariant::Int;
|
||||
if (ft == "f") return QVariant::Double;
|
||||
if (ft == "c") return QVariant::Color;
|
||||
if (ft == "r") return QVariant::Rect;
|
||||
if (ft == "a") return QVariant::RectF;
|
||||
if (ft == "p") return QVariant::Point;
|
||||
if (ft == "v") return QVariant::PointF;
|
||||
if (ft == "e") return (QVariant::Type)qMetaTypeId<QVariantEdit::EnumType>();
|
||||
if (ft == "F") return (QVariant::Type)qMetaTypeId<QVariantEdit::FileType>();
|
||||
if (ft == "D") return (QVariant::Type)qMetaTypeId<QVariantEdit::DirType>();
|
||||
return QVariant::String;
|
||||
}
|
||||
|
||||
|
||||
QString uniqueName(QString n, const QStringList & names) {
|
||||
if (!names.contains(n))
|
||||
return n;
|
||||
QString num;
|
||||
while (!n.isEmpty()) {
|
||||
if (n.right(1)[0].isDigit()) {
|
||||
num.push_front(n.right(1));
|
||||
n.chop(1);
|
||||
} else break;
|
||||
}
|
||||
if (!n.endsWith('_')) n += '_';
|
||||
int in = num.toInt() + 1;
|
||||
QString nn = n + QString::number(in).rightJustified(3, '0');
|
||||
while (names.contains(nn))
|
||||
nn = n + QString::number(++in).rightJustified(3, '0');
|
||||
return nn;
|
||||
}
|
||||
|
||||
|
||||
QDataStream & operator <<(QDataStream & s, const QGraphicsItem * item) {
|
||||
if (!item) {
|
||||
s << int(-1);
|
||||
@@ -69,6 +31,7 @@ QDataStream & operator <<(QDataStream & s, const QGraphicsItem * item) {
|
||||
s << int(5) << (ipixmap->pixmap());
|
||||
} else {
|
||||
s << int(-1);
|
||||
return s;
|
||||
}
|
||||
s << (item->pos()) << (item->rotation()) << int(item->flags());
|
||||
return s;
|
||||
@@ -139,151 +102,3 @@ QDataStream & operator >>(QDataStream & s, QGraphicsItem *& item) {
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool PropertyStorage::isPropertyExists(const QString & _name) const {
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
if (props[i].name == _name)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PropertyStorage::addProperty(const PropertyStorage::Property & p) {
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
if (props[i].name == p.name) {
|
||||
props[i] = p;
|
||||
return;
|
||||
}
|
||||
props << p;
|
||||
}
|
||||
|
||||
|
||||
void PropertyStorage::removeProperty(const QString & _name) {
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
if (props[i].name == _name) {
|
||||
props.removeAt(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PropertyStorage::removePropertiesByFlag(int flag) {
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
if ((props[i].flags & flag) == flag) {
|
||||
props.removeAt(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PropertyStorage::updateProperties(const QList<PropertyStorage::Property> & properties_, int flag_ignore) {
|
||||
QVariantMap values;
|
||||
foreach (const PropertyStorage::Property & p, props)
|
||||
if (((p.flags & flag_ignore) != flag_ignore) || (flag_ignore == 0))
|
||||
values[p.name] = p.value;
|
||||
props = properties_;
|
||||
for (int i = 0; i < props.size(); ++i) {
|
||||
PropertyStorage::Property & p(props[i]);
|
||||
if (values.contains(p.name)) {
|
||||
QVariant pv = values[p.name];
|
||||
if (pv.userType() == p.value.userType())
|
||||
p.value = pv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PropertyStorage::Property PropertyStorage::propertyByName(const QString & name) const {
|
||||
foreach (const Property & p, props)
|
||||
if (p.name == name)
|
||||
return p;
|
||||
return Property();
|
||||
}
|
||||
|
||||
|
||||
QVariant PropertyStorage::propertyValueByName(const QString & name) const {
|
||||
foreach (const Property & p, props)
|
||||
if (p.name == name)
|
||||
return p.value;
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
void PropertyStorage::setPropertyValue(const QString & name, const QVariant & value) {
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
if (props[i].name == name) {
|
||||
props[i].value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PropertyStorage::setPropertyComment(const QString & name, const QString & comment) {
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
if (props[i].name == name) {
|
||||
props[i].comment = comment;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PropertyStorage::setPropertyFlags(const QString & name, int flags) {
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
if (props[i].name == name) {
|
||||
props[i].flags = flags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PropertyStorage::Property PropertyStorage::parsePropertyLine(QString l) {
|
||||
PropertyStorage::Property ret;
|
||||
QString pn, pc, pt("s"), pv;
|
||||
if (l.contains('#')) {
|
||||
int i = l.indexOf('#');
|
||||
pn = l.left(i).trimmed();
|
||||
pc = l.right(l.length() - i - 1).trimmed();
|
||||
} else {
|
||||
if (l.contains('(')) {
|
||||
int bs = l.indexOf('('), be = l.indexOf(')');
|
||||
if (be > 0) {
|
||||
pc = l.mid(bs + 1, be - bs - 1).trimmed();
|
||||
l.remove(bs, be - bs + 1);
|
||||
} else {
|
||||
pc = l.right(l.length() - bs - 1).trimmed();
|
||||
l = l.left(bs);
|
||||
}
|
||||
}
|
||||
pn = l.trimmed();
|
||||
}
|
||||
if (!pc.isEmpty()) {
|
||||
pt = pc.left(1);
|
||||
pc = pc.remove(0, 1).trimmed();
|
||||
}
|
||||
if (pn.contains('=')) {
|
||||
int i = pn.indexOf('=');
|
||||
pv = pn.right(pn.length() - i - 1).trimmed();
|
||||
pn.truncate(i);
|
||||
pn = pn.trimmed();
|
||||
}
|
||||
ret.name = pn;
|
||||
ret.comment = pc;
|
||||
ret.value = QVariant(typeFromLetter(pt));
|
||||
if (!pv.isEmpty()) {
|
||||
//qDebug() << "set value !" << pv;
|
||||
switch (ret.value.type()) {
|
||||
case QVariant::Bool: pv = pv.toLower(); ret.value = (pv == "on" || pv == "true" || pv == "enable" || pv == "enabled" || pv.toInt() > 0 ? true : false); break;
|
||||
case QVariant::Int: ret.value = pv.toInt(); break;
|
||||
case QVariant::UInt: ret.value = pv.toUInt(); break;
|
||||
case QVariant::LongLong: ret.value = pv.toLongLong(); break;
|
||||
case QVariant::ULongLong: ret.value = pv.toULongLong(); break;
|
||||
case QVariant::Double: ret.value = pv.toDouble(); break;
|
||||
case QVariant::Color: ret.value = QColor(pv); break;
|
||||
default: ret.value = pv; break;
|
||||
};
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
#include <QGraphicsSceneHoverEvent>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QStack>
|
||||
#include <QDebug>
|
||||
#include "chunkstream.h"
|
||||
#include "propertystorage.h"
|
||||
|
||||
|
||||
/// data:
|
||||
@@ -27,25 +26,6 @@
|
||||
/// 1100 - flag for correct move (true)
|
||||
|
||||
|
||||
inline qreal quantize(qreal x, qreal q = 10.f) {return qRound(x / q) * q;}
|
||||
inline QPointF quantize(QPointF x, qreal q = 10.f) {return QPointF(quantize(x.x(), q), quantize(x.y(), q));}
|
||||
|
||||
inline qreal distPointToLine(const QPointF & lp0, const QPointF & lp1, const QPointF & p) {
|
||||
QLineF a(lp0, lp1), b(lp0, p), c(lp1, p);
|
||||
qreal f = qAbs(a.dx()*b.dy() - a.dy()*b.dx()) / a.length(), s = b.length() + c.length() - a.length();
|
||||
return qMax(f, s);
|
||||
}
|
||||
inline QPointF nearestPointOnLine(const QPointF & lp0, const QPointF & lp1, const QPointF & p) {
|
||||
QLineF a(lp0, lp1), b(lp0, p);
|
||||
return a.pointAt(b.length() / a.length());
|
||||
}
|
||||
inline QRectF enlargedRect(const QRectF & r, qreal dx, qreal dy, qreal v) {
|
||||
return QRectF(r.left() - v + dx, r.top() - v + dy, r.width() + v+v, r.height() + v+v);
|
||||
}
|
||||
|
||||
QVariant::Type typeFromLetter(const QString & l);
|
||||
QString uniqueName(QString n, const QStringList & names);
|
||||
|
||||
QDataStream & operator <<(QDataStream & s, const QGraphicsItem * item);
|
||||
QDataStream & operator >>(QDataStream & s, QGraphicsItem *& item);
|
||||
|
||||
@@ -74,104 +54,4 @@ public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
class PropertyStorage {
|
||||
public:
|
||||
PropertyStorage() {}
|
||||
|
||||
struct Property {
|
||||
Property(const QString & n = QString(), const QString & c = QString(), const QVariant & v = QVariant(), int f = 0):
|
||||
name(n), comment(c), value(v), flags(f) {}
|
||||
QString name;
|
||||
QString comment;
|
||||
QVariant value;
|
||||
int flags;
|
||||
};
|
||||
|
||||
PropertyStorage(const QList<Property> & pl) {props = pl;}
|
||||
|
||||
typedef QList<Property>::const_iterator const_iterator;
|
||||
typedef QList<Property>::iterator iterator;
|
||||
|
||||
iterator begin() {return props.begin();}
|
||||
const_iterator begin() const {return props.begin();}
|
||||
const_iterator constBegin() const {return props.constBegin();}
|
||||
iterator end() {return props.end();}
|
||||
const_iterator end() const {return props.end();}
|
||||
const_iterator constEnd() const {return props.constEnd();}
|
||||
|
||||
int count() const {return props.count();}
|
||||
int length() const {return props.length();}
|
||||
int size() const {return props.size();}
|
||||
bool isEmpty() const {return props.isEmpty();}
|
||||
Property & first() {return props.first();}
|
||||
const Property & first() const {return props.first();}
|
||||
Property & front() {return props.front();}
|
||||
const Property & front() const {return props.front();}
|
||||
Property & last() {return props.last();}
|
||||
const Property & last() const {return props.last();}
|
||||
Property & back() {return props.back();}
|
||||
const Property & back() const {return props.back();}
|
||||
void removeFirst() {props.removeFirst();}
|
||||
void removeLast() {props.removeLast();}
|
||||
void removeAt(int i) {props.removeAt(i);}
|
||||
Property value(int i) const {return props.value(i);}
|
||||
Property value(int i, const Property & defaultValue) const {return props.value(i, defaultValue);}
|
||||
void clear() {props.clear();}
|
||||
|
||||
PropertyStorage copy() const {return PropertyStorage(*this);}
|
||||
int propertiesCount() const {return props.size();}
|
||||
QList<Property> & properties() {return props;}
|
||||
const QList<Property> & properties() const {return props;}
|
||||
const PropertyStorage & propertyStorage() const {return *this;}
|
||||
bool isPropertyExists(const QString & _name) const;
|
||||
void clearProperties() {props.clear();}
|
||||
void addProperty(const Property & p);
|
||||
void addProperty(const QString & _name, const QVariant & _def_value, const QString & _comment = QString(), int _flags = 0) {addProperty(Property(_name, _comment, _def_value, _flags));}
|
||||
void removeProperty(const QString & _name);
|
||||
void removePropertiesByFlag(int flag);
|
||||
void updateProperties(const QList<Property> & properties_, int flag_ignore = 0);
|
||||
Property propertyByName(const QString & name) const;
|
||||
QVariant propertyValueByName(const QString & name) const;
|
||||
void setPropertyValue(const QString & name, const QVariant & value);
|
||||
void setPropertyComment(const QString & name, const QString & comment);
|
||||
void setPropertyFlags(const QString & name, int flags);
|
||||
|
||||
PropertyStorage & operator <<(const PropertyStorage::Property & p) {props << p; return *this;}
|
||||
PropertyStorage & operator <<(const QList<Property> & p) {props << p; return *this;}
|
||||
PropertyStorage & operator <<(const PropertyStorage & p) {props << p.props; return *this;}
|
||||
Property & operator[](int i) {return props[i];}
|
||||
const Property & operator[](int i) const {return props[i];}
|
||||
|
||||
static Property parsePropertyLine(QString l);
|
||||
|
||||
protected:
|
||||
QList<Property> props;
|
||||
|
||||
};
|
||||
|
||||
inline QDebug operator <<(QDebug s, const PropertyStorage::Property & p) {s.nospace() << p.name << " (0x" << QString::number(p.flags, 16) << ") = " << p.value; return s.space();}
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const PropertyStorage & p) {s << p.properties(); return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, PropertyStorage & p) {s >> p.properties(); return s;}
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const PropertyStorage::Property & p) {
|
||||
ChunkStream cs; cs << cs.chunk(1, p.name) << cs.chunk(2, p.comment) << cs.chunk(3, p.value) << cs.chunk(4, p.flags);
|
||||
s << cs.data(); return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, PropertyStorage::Property & p) {
|
||||
ChunkStream cs(s);
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
case 1: p.name = cs.getData<QString>(); break;
|
||||
case 2: p.comment = cs.getData<QString>(); break;
|
||||
case 3: p.value = cs.getData<QVariant>(); break;
|
||||
case 4: p.flags = cs.getData<int>(); break;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // BLOCKBASE_H
|
||||
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
template <typename T>
|
||||
T getData() const {T ret; QDataStream s(last_data); s.setVersion(QDataStream::Qt_4_8); s >> ret; return ret;}
|
||||
template <typename T>
|
||||
T get(T & v) const {v = getData<T>();}
|
||||
void get(T & v) const {v = getData<T>();}
|
||||
private:
|
||||
void _init();
|
||||
|
||||
|
||||
148
qad_utils/propertystorage.cpp
Normal file
148
qad_utils/propertystorage.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
#include "propertystorage.h"
|
||||
#include <QColor>
|
||||
|
||||
|
||||
bool PropertyStorage::isPropertyExists(const QString & _name) const {
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
if (props[i].name == _name)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PropertyStorage::addProperty(const PropertyStorage::Property & p) {
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
if (props[i].name == p.name) {
|
||||
props[i] = p;
|
||||
return;
|
||||
}
|
||||
props << p;
|
||||
}
|
||||
|
||||
|
||||
void PropertyStorage::removeProperty(const QString & _name) {
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
if (props[i].name == _name) {
|
||||
props.removeAt(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PropertyStorage::removePropertiesByFlag(int flag) {
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
if ((props[i].flags & flag) == flag) {
|
||||
props.removeAt(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PropertyStorage::updateProperties(const QList<PropertyStorage::Property> & properties_, int flag_ignore) {
|
||||
QVariantMap values;
|
||||
foreach (const PropertyStorage::Property & p, props)
|
||||
if (((p.flags & flag_ignore) != flag_ignore) || (flag_ignore == 0))
|
||||
values[p.name] = p.value;
|
||||
props = properties_;
|
||||
for (int i = 0; i < props.size(); ++i) {
|
||||
PropertyStorage::Property & p(props[i]);
|
||||
if (values.contains(p.name)) {
|
||||
QVariant pv = values[p.name];
|
||||
if (pv.userType() == p.value.userType())
|
||||
p.value = pv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PropertyStorage::Property PropertyStorage::propertyByName(const QString & name) const {
|
||||
foreach (const Property & p, props)
|
||||
if (p.name == name)
|
||||
return p;
|
||||
return Property();
|
||||
}
|
||||
|
||||
|
||||
QVariant PropertyStorage::propertyValueByName(const QString & name) const {
|
||||
foreach (const Property & p, props)
|
||||
if (p.name == name)
|
||||
return p.value;
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
void PropertyStorage::setPropertyValue(const QString & name, const QVariant & value) {
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
if (props[i].name == name) {
|
||||
props[i].value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PropertyStorage::setPropertyComment(const QString & name, const QString & comment) {
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
if (props[i].name == name) {
|
||||
props[i].comment = comment;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PropertyStorage::setPropertyFlags(const QString & name, int flags) {
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
if (props[i].name == name) {
|
||||
props[i].flags = flags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PropertyStorage::Property PropertyStorage::parsePropertyLine(QString l) {
|
||||
PropertyStorage::Property ret;
|
||||
QString pn, pc, pt("s"), pv;
|
||||
if (l.contains('#')) {
|
||||
int i = l.indexOf('#');
|
||||
pn = l.left(i).trimmed();
|
||||
pc = l.right(l.length() - i - 1).trimmed();
|
||||
} else {
|
||||
if (l.contains('(')) {
|
||||
int bs = l.indexOf('('), be = l.indexOf(')');
|
||||
if (be > 0) {
|
||||
pc = l.mid(bs + 1, be - bs - 1).trimmed();
|
||||
l.remove(bs, be - bs + 1);
|
||||
} else {
|
||||
pc = l.right(l.length() - bs - 1).trimmed();
|
||||
l = l.left(bs);
|
||||
}
|
||||
}
|
||||
pn = l.trimmed();
|
||||
}
|
||||
if (!pc.isEmpty()) {
|
||||
pt = pc.left(1);
|
||||
pc = pc.remove(0, 1).trimmed();
|
||||
}
|
||||
if (pn.contains('=')) {
|
||||
int i = pn.indexOf('=');
|
||||
pv = pn.right(pn.length() - i - 1).trimmed();
|
||||
pn.truncate(i);
|
||||
pn = pn.trimmed();
|
||||
}
|
||||
ret.name = pn;
|
||||
ret.comment = pc;
|
||||
ret.value = QVariant(typeFromLetter(pt));
|
||||
if (!pv.isEmpty()) {
|
||||
//qDebug() << "set value !" << pv;
|
||||
switch (ret.value.type()) {
|
||||
case QVariant::Bool: pv = pv.toLower(); ret.value = (pv == "on" || pv == "true" || pv == "enable" || pv == "enabled" || pv.toInt() > 0 ? true : false); break;
|
||||
case QVariant::Int: ret.value = pv.toInt(); break;
|
||||
case QVariant::UInt: ret.value = pv.toUInt(); break;
|
||||
case QVariant::LongLong: ret.value = pv.toLongLong(); break;
|
||||
case QVariant::ULongLong: ret.value = pv.toULongLong(); break;
|
||||
case QVariant::Double: ret.value = pv.toDouble(); break;
|
||||
case QVariant::Color: ret.value = QColor(pv); break;
|
||||
default: ret.value = pv; break;
|
||||
};
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
107
qad_utils/propertystorage.h
Normal file
107
qad_utils/propertystorage.h
Normal file
@@ -0,0 +1,107 @@
|
||||
#ifndef PROPERTYSTORAGE_H
|
||||
#define PROPERTYSTORAGE_H
|
||||
|
||||
#include "qad_types.h"
|
||||
|
||||
|
||||
class PropertyStorage {
|
||||
public:
|
||||
PropertyStorage() {}
|
||||
|
||||
struct Property {
|
||||
Property(const QString & n = QString(), const QString & c = QString(), const QVariant & v = QVariant(), int f = 0):
|
||||
name(n), comment(c), value(v), flags(f) {}
|
||||
QString name;
|
||||
QString comment;
|
||||
QVariant value;
|
||||
int flags;
|
||||
};
|
||||
|
||||
PropertyStorage(const QList<Property> & pl) {props = pl;}
|
||||
|
||||
typedef QList<Property>::const_iterator const_iterator;
|
||||
typedef QList<Property>::iterator iterator;
|
||||
|
||||
iterator begin() {return props.begin();}
|
||||
const_iterator begin() const {return props.begin();}
|
||||
const_iterator constBegin() const {return props.constBegin();}
|
||||
iterator end() {return props.end();}
|
||||
const_iterator end() const {return props.end();}
|
||||
const_iterator constEnd() const {return props.constEnd();}
|
||||
|
||||
int count() const {return props.count();}
|
||||
int length() const {return props.length();}
|
||||
int size() const {return props.size();}
|
||||
bool isEmpty() const {return props.isEmpty();}
|
||||
Property & first() {return props.first();}
|
||||
const Property & first() const {return props.first();}
|
||||
Property & front() {return props.front();}
|
||||
const Property & front() const {return props.front();}
|
||||
Property & last() {return props.last();}
|
||||
const Property & last() const {return props.last();}
|
||||
Property & back() {return props.back();}
|
||||
const Property & back() const {return props.back();}
|
||||
void removeFirst() {props.removeFirst();}
|
||||
void removeLast() {props.removeLast();}
|
||||
void removeAt(int i) {props.removeAt(i);}
|
||||
Property value(int i) const {return props.value(i);}
|
||||
Property value(int i, const Property & defaultValue) const {return props.value(i, defaultValue);}
|
||||
void clear() {props.clear();}
|
||||
|
||||
PropertyStorage copy() const {return PropertyStorage(*this);}
|
||||
int propertiesCount() const {return props.size();}
|
||||
QList<Property> & properties() {return props;}
|
||||
const QList<Property> & properties() const {return props;}
|
||||
const PropertyStorage & propertyStorage() const {return *this;}
|
||||
bool isPropertyExists(const QString & _name) const;
|
||||
void clearProperties() {props.clear();}
|
||||
void addProperty(const Property & p);
|
||||
void addProperty(const QString & _name, const QVariant & _def_value, const QString & _comment = QString(), int _flags = 0) {addProperty(Property(_name, _comment, _def_value, _flags));}
|
||||
void removeProperty(const QString & _name);
|
||||
void removePropertiesByFlag(int flag);
|
||||
void updateProperties(const QList<Property> & properties_, int flag_ignore = 0);
|
||||
Property propertyByName(const QString & name) const;
|
||||
QVariant propertyValueByName(const QString & name) const;
|
||||
void setPropertyValue(const QString & name, const QVariant & value);
|
||||
void setPropertyComment(const QString & name, const QString & comment);
|
||||
void setPropertyFlags(const QString & name, int flags);
|
||||
|
||||
PropertyStorage & operator <<(const PropertyStorage::Property & p) {props << p; return *this;}
|
||||
PropertyStorage & operator <<(const QList<Property> & p) {props << p; return *this;}
|
||||
PropertyStorage & operator <<(const PropertyStorage & p) {props << p.props; return *this;}
|
||||
Property & operator[](int i) {return props[i];}
|
||||
const Property & operator[](int i) const {return props[i];}
|
||||
|
||||
static Property parsePropertyLine(QString l);
|
||||
|
||||
protected:
|
||||
QList<Property> props;
|
||||
|
||||
};
|
||||
|
||||
inline QDebug operator <<(QDebug s, const PropertyStorage::Property & p) {s.nospace() << p.name << " (0x" << QString::number(p.flags, 16) << ") = " << p.value; return s.space();}
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const PropertyStorage & p) {s << p.properties(); return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, PropertyStorage & p) {s >> p.properties(); return s;}
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const PropertyStorage::Property & p) {
|
||||
ChunkStream cs;
|
||||
cs << cs.chunk(1, p.name) << cs.chunk(2, p.comment) << cs.chunk(3, p.value) << cs.chunk(4, p.flags);
|
||||
s << cs.data();
|
||||
return s;
|
||||
}
|
||||
inline QDataStream & operator >>(QDataStream & s, PropertyStorage::Property & p) {
|
||||
ChunkStream cs(s);
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
case 1: cs.get(p.name); break;
|
||||
case 2: cs.get(p.comment); break;
|
||||
case 3: cs.get(p.value); break;
|
||||
case 4: cs.get(p.flags); break;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
#endif // PROPERTYSTORAGE_H
|
||||
117
qad_utils/qad_types.cpp
Normal file
117
qad_utils/qad_types.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
#include "qad_types.h"
|
||||
|
||||
|
||||
__QADTypesRegistrator__ __registrator__;
|
||||
|
||||
|
||||
int QAD::Enum::selectedValue() const {
|
||||
foreach (const Enumerator & e, enum_list)
|
||||
if (e.name == selected)
|
||||
return e.value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool QAD::Enum::selectValue(int v) {
|
||||
foreach (const Enumerator & e, enum_list)
|
||||
if (e.value == v) {
|
||||
selected = e.name;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool QAD::Enum::selectName(const QString & n) {
|
||||
foreach (const Enumerator & e, enum_list)
|
||||
if (e.name == n) {
|
||||
selected = e.name;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int QAD::Enum::value(const QString & n) const {
|
||||
foreach (const Enumerator & e, enum_list)
|
||||
if (e.name == n)
|
||||
return e.value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
QString QAD::Enum::name(int v) const {
|
||||
foreach (const Enumerator & e, enum_list)
|
||||
if (e.value == v)
|
||||
return e.name;
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
QList<int> QAD::Enum::values() const {
|
||||
QList<int> ret;
|
||||
foreach (const Enumerator & e, enum_list)
|
||||
ret << e.value;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QStringList QAD::Enum::names() const {
|
||||
QStringList ret;
|
||||
foreach (const Enumerator & e, enum_list)
|
||||
ret << e.name;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QAD::Enum & QAD::Enum::operator <<(const QString & v) {
|
||||
enum_list << Enumerator(enum_list.size(), v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
QAD::Enum & QAD::Enum::operator <<(const QStringList & v) {
|
||||
foreach (const QString & s, v)
|
||||
(*this) << s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QVariant::Type typeFromLetter(const QString & l) {
|
||||
if (l.isEmpty()) return QVariant::String;
|
||||
QString ft = l.left(1);
|
||||
if (ft == "l") return QVariant::StringList;
|
||||
if (ft == "b") return QVariant::Bool;
|
||||
if (ft == "n") return QVariant::Int;
|
||||
if (ft == "f") return QVariant::Double;
|
||||
if (ft == "c") return QVariant::Color;
|
||||
if (ft == "r") return QVariant::Rect;
|
||||
if (ft == "a") return QVariant::RectF;
|
||||
if (ft == "p") return QVariant::Point;
|
||||
if (ft == "v") return QVariant::PointF;
|
||||
if (ft == "e") return (QVariant::Type)qMetaTypeId<QAD::Enum>();
|
||||
if (ft == "F") return (QVariant::Type)qMetaTypeId<QAD::File>();
|
||||
if (ft == "D") return (QVariant::Type)qMetaTypeId<QAD::Dir>();
|
||||
return QVariant::String;
|
||||
}
|
||||
|
||||
|
||||
QString uniqueName(QString n, const QStringList & names) {
|
||||
if (!names.contains(n))
|
||||
return n;
|
||||
QString num;
|
||||
while (!n.isEmpty()) {
|
||||
if (n.right(1)[0].isDigit()) {
|
||||
num.push_front(n.right(1));
|
||||
n.chop(1);
|
||||
} else break;
|
||||
}
|
||||
if (!n.endsWith('_')) n += '_';
|
||||
int in = num.toInt() + 1;
|
||||
QString nn = n + QString::number(in).rightJustified(3, '0');
|
||||
while (names.contains(nn))
|
||||
nn = n + QString::number(++in).rightJustified(3, '0');
|
||||
return nn;
|
||||
}
|
||||
114
qad_utils/qad_types.h
Normal file
114
qad_utils/qad_types.h
Normal file
@@ -0,0 +1,114 @@
|
||||
#ifndef QAD_TYPES_H
|
||||
#define QAD_TYPES_H
|
||||
|
||||
#include <QPointF>
|
||||
#include <QRectF>
|
||||
#include <QLineF>
|
||||
#include <QVariant>
|
||||
#include <QStringList>
|
||||
#include <QDebug>
|
||||
#include "chunkstream.h"
|
||||
|
||||
|
||||
namespace QAD {
|
||||
|
||||
struct Enumerator {
|
||||
Enumerator(int v = 0, const QString & n = QString()): value(v), name(n) {}
|
||||
int value;
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct Enum {
|
||||
Enum(const QString & n = QString()): enum_name(n) {}
|
||||
QString toString() const {return selected;} // obsolete
|
||||
int selectedValue() const;
|
||||
QString selectedName() const {return selected;}
|
||||
bool selectValue(int v);
|
||||
bool selectName(const QString & n);
|
||||
int value(const QString & n) const;
|
||||
QString name(int v) const;
|
||||
QList<int> values() const;
|
||||
QStringList names() const;
|
||||
QString enum_name;
|
||||
QString selected;
|
||||
QList<Enumerator> enum_list;
|
||||
Enum & operator <<(const QString & v);
|
||||
Enum & operator <<(const QStringList & v);
|
||||
};
|
||||
|
||||
struct File {
|
||||
File(const QString & p = QString(), const QString & f = QString(), bool abs = false): file(p), filter(f), is_abs(abs) {}
|
||||
QString toString() const {return file;}
|
||||
QString file;
|
||||
QString filter;
|
||||
bool is_abs;
|
||||
};
|
||||
|
||||
struct Dir {
|
||||
Dir(const QString & d = QString(), bool abs = false): dir(d), is_abs(abs) {}
|
||||
QString toString() const {return dir;}
|
||||
QString dir;
|
||||
bool is_abs;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(QAD::Enumerator)
|
||||
inline QDataStream & operator <<(QDataStream & s, const QAD::Enumerator & v) {s << v.value << v.name; return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, QAD::Enumerator & v) {s >> v.value >> v.name; return s;}
|
||||
inline QDebug operator <<(QDebug s, const QAD::Enumerator & v) {s.nospace() << v.name << "(" << v.value << ")"; return s.space();}
|
||||
|
||||
Q_DECLARE_METATYPE(QAD::Enum)
|
||||
inline QDataStream & operator <<(QDataStream & s, const QAD::Enum & v) {s << v.enum_name << v.selected << v.enum_list; return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, QAD::Enum & v) {s >> v.enum_name >> v.selected >> v.enum_list; return s;}
|
||||
inline QDebug operator <<(QDebug s, const QAD::Enum & v) {s.nospace() << v.selected; return s.space();}
|
||||
|
||||
Q_DECLARE_METATYPE(QAD::File)
|
||||
inline QDataStream & operator <<(QDataStream & s, const QAD::File & v) {s << v.file << v.filter << v.is_abs; return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, QAD::File & v) {s >> v.file >> v.filter >> v.is_abs; return s;}
|
||||
inline QDebug operator <<(QDebug s, const QAD::File & v) {s.nospace() << v.file; return s.space();}
|
||||
|
||||
Q_DECLARE_METATYPE(QAD::Dir)
|
||||
inline QDataStream & operator <<(QDataStream & s, const QAD::Dir & v) {s << v.dir << v.is_abs; return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, QAD::Dir & v) {s >> v.dir >> v.is_abs; return s;}
|
||||
inline QDebug operator <<(QDebug s, const QAD::Dir & v) {s.nospace() << v.dir; return s.space();}
|
||||
|
||||
class __QADTypesRegistrator__ {
|
||||
public:
|
||||
__QADTypesRegistrator__() {
|
||||
qRegisterMetaType<QAD::Enumerator>("QAD::Enumerator");
|
||||
qRegisterMetaTypeStreamOperators<QAD::Enumerator>("QAD::Enumerator");
|
||||
|
||||
qRegisterMetaType<QAD::Enum>("QAD::Enum");
|
||||
qRegisterMetaTypeStreamOperators<QAD::Enum>("QAD::Enum");
|
||||
|
||||
qRegisterMetaType<QAD::File>("QAD::File");
|
||||
qRegisterMetaTypeStreamOperators<QAD::File>("QAD::File");
|
||||
|
||||
qRegisterMetaType<QAD::Dir>("QAD::Dir");
|
||||
qRegisterMetaTypeStreamOperators<QAD::Dir>("QAD::Dir");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline qreal quantize(qreal x, qreal q = 10.f) {return qRound(x / q) * q;}
|
||||
inline QPointF quantize(QPointF x, qreal q = 10.f) {return QPointF(quantize(x.x(), q), quantize(x.y(), q));}
|
||||
|
||||
inline qreal distPointToLine(const QPointF & lp0, const QPointF & lp1, const QPointF & p) {
|
||||
QLineF a(lp0, lp1), b(lp0, p), c(lp1, p);
|
||||
qreal f = qAbs(a.dx()*b.dy() - a.dy()*b.dx()) / a.length(), s = b.length() + c.length() - a.length();
|
||||
return qMax(f, s);
|
||||
}
|
||||
inline QPointF nearestPointOnLine(const QPointF & lp0, const QPointF & lp1, const QPointF & p) {
|
||||
QLineF a(lp0, lp1), b(lp0, p);
|
||||
return a.pointAt(b.length() / a.length());
|
||||
}
|
||||
inline QRectF enlargedRect(const QRectF & r, qreal dx, qreal dy, qreal v) {
|
||||
return QRectF(r.left() - v + dx, r.top() - v + dy, r.width() + v+v, r.height() + v+v);
|
||||
}
|
||||
|
||||
QVariant::Type typeFromLetter(const QString & l);
|
||||
QString uniqueName(QString n, const QStringList & names);
|
||||
|
||||
|
||||
#endif // QAD_TYPES_H
|
||||
@@ -3,9 +3,6 @@
|
||||
#include <QFileDialog>
|
||||
|
||||
|
||||
__QVariantEditRegistrator__ __registrator__;
|
||||
|
||||
|
||||
StringListEdit::~StringListEdit() {
|
||||
delete combo;
|
||||
delete butt_add;
|
||||
@@ -289,21 +286,21 @@ void QVariantEdit::_recreate(const QVariant & new_value) {
|
||||
default: break;
|
||||
}
|
||||
if (!_cur_edit) {
|
||||
if (new_value.canConvert<QVariantEdit::EnumType>()) {
|
||||
if (new_value.canConvert<QAD::Enum>()) {
|
||||
_enum = new EComboBox(this);
|
||||
_setEnum(new_value.value<QVariantEdit::EnumType>());
|
||||
_setEnum(new_value.value<QAD::Enum>());
|
||||
_cur_edit = _enum;
|
||||
connect(_enum, SIGNAL(currentIndexChanged(int)), this, SLOT(_changed()));
|
||||
}
|
||||
if (new_value.canConvert<QVariantEdit::FileType>()) {
|
||||
if (new_value.canConvert<QAD::File>()) {
|
||||
_path = new PathEdit(this);
|
||||
_setFile(new_value.value<QVariantEdit::FileType>());
|
||||
_setFile(new_value.value<QAD::File>());
|
||||
_cur_edit = _path;
|
||||
connect(_path, SIGNAL(valueChanged()), this, SLOT(_changed()));
|
||||
}
|
||||
if (new_value.canConvert<QVariantEdit::DirType>()) {
|
||||
if (new_value.canConvert<QAD::Dir>()) {
|
||||
_path = new PathEdit(this);
|
||||
_setDir(new_value.value<QVariantEdit::DirType>());
|
||||
_setDir(new_value.value<QAD::Dir>());
|
||||
_cur_edit = _path;
|
||||
connect(_path, SIGNAL(valueChanged()), this, SLOT(_changed()));
|
||||
}
|
||||
@@ -336,28 +333,29 @@ QVariant QVariantEdit::value() const {
|
||||
case QVariant::Time: return _date->time();
|
||||
case QVariant::DateTime: return _date->dateTime();
|
||||
default:
|
||||
if (_value.canConvert<QVariantEdit::EnumType>() && _enum) {
|
||||
QVariantEdit::EnumType ret;
|
||||
if (_value.canConvert<QAD::Enum>() && _enum) {
|
||||
QAD::Enum ret;
|
||||
for (int i = 0; i < _enum->count(); ++i)
|
||||
ret.enum_list << _enum->itemText(i);
|
||||
ret.value = _enum->currentText();
|
||||
return QVariant::fromValue<QVariantEdit::EnumType>(ret);
|
||||
ret.enum_list << QAD::Enumerator(_enum->itemData(i).toInt(), _enum->itemText(i));
|
||||
ret.enum_name = _enum->property("enum_name").toString();
|
||||
ret.selected = _enum->currentText();
|
||||
return QVariant::fromValue<QAD::Enum>(ret);
|
||||
}
|
||||
if (_value.canConvert<QVariantEdit::FileType>() && _path) {
|
||||
if (_value.canConvert<QAD::File>() && _path) {
|
||||
if (!_path->is_dir) {
|
||||
QVariantEdit::FileType ret;
|
||||
QAD::File ret;
|
||||
ret.file = _path->value();
|
||||
ret.filter = _path->filter;
|
||||
ret.is_abs = _path->is_abs;
|
||||
return QVariant::fromValue<QVariantEdit::FileType>(ret);
|
||||
return QVariant::fromValue<QAD::File>(ret);
|
||||
}
|
||||
}
|
||||
if (_value.canConvert<QVariantEdit::DirType>() && _path) {
|
||||
if (_value.canConvert<QAD::Dir>() && _path) {
|
||||
if (_path->is_dir) {
|
||||
QVariantEdit::DirType ret;
|
||||
QAD::Dir ret;
|
||||
ret.dir = _path->value();
|
||||
ret.is_abs = _path->is_abs;
|
||||
return QVariant::fromValue<QVariantEdit::DirType>(ret);
|
||||
return QVariant::fromValue<QAD::Dir>(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -377,10 +375,10 @@ void QVariantEdit::setValue(const QVariant & v) {
|
||||
if (_rect) {_rect->setValue(v.toRectF());}
|
||||
if (_point) {_point->setValue(v.toPointF());}
|
||||
if (_path) {
|
||||
if (_path->is_dir) _setDir(v.value<QVariantEdit::DirType>());
|
||||
else _setFile(v.value<QVariantEdit::FileType>());
|
||||
if (_path->is_dir) _setDir(v.value<QAD::Dir>());
|
||||
else _setFile(v.value<QAD::File>());
|
||||
}
|
||||
if (_enum) {_setEnum(v.value<QVariantEdit::EnumType>());}
|
||||
if (_enum) {_setEnum(v.value<QAD::Enum>());}
|
||||
if (_cur_edit) _cur_edit->blockSignals(false);
|
||||
}
|
||||
|
||||
@@ -414,12 +412,14 @@ void QVariantEdit::_newPath() {
|
||||
}
|
||||
|
||||
|
||||
void QVariantEdit::_setEnum(const QVariantEdit::EnumType & v) {
|
||||
void QVariantEdit::_setEnum(const QAD::Enum & v) {
|
||||
_enum->clear();
|
||||
_enum->addItems(v.enum_list);
|
||||
_enum->setProperty("enum_name", v.enum_name);
|
||||
foreach (const QAD::Enumerator & e, v.enum_list)
|
||||
_enum->addItem(e.name, QVariant(e.value));
|
||||
int i(0);
|
||||
for (i = 0; i < _enum->count(); ++i)
|
||||
if (_enum->itemText(i) == v.value) {
|
||||
if (_enum->itemText(i) == v.selected) {
|
||||
_enum->setCurrentIndex(i);
|
||||
break;
|
||||
}
|
||||
@@ -428,7 +428,7 @@ void QVariantEdit::_setEnum(const QVariantEdit::EnumType & v) {
|
||||
}
|
||||
|
||||
|
||||
void QVariantEdit::_setFile(const FileType & v) {
|
||||
void QVariantEdit::_setFile(const QAD::File & v) {
|
||||
_path->is_dir = false;
|
||||
_path->setValue(v.file);
|
||||
_path->filter = v.filter;
|
||||
@@ -436,7 +436,7 @@ void QVariantEdit::_setFile(const FileType & v) {
|
||||
}
|
||||
|
||||
|
||||
void QVariantEdit::_setDir(const DirType & v) {
|
||||
void QVariantEdit::_setDir(const QAD::Dir & v) {
|
||||
_path->is_dir = true;
|
||||
_path->setValue(v.dir);
|
||||
_path->is_abs = v.is_abs;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "colorbutton.h"
|
||||
#include "qrectedit.h"
|
||||
#include "qpointedit.h"
|
||||
#include "qad_types.h"
|
||||
#include <QCheckBox>
|
||||
#include <QDoubleSpinBox>
|
||||
|
||||
@@ -88,36 +89,15 @@ public:
|
||||
QVariant value() const;
|
||||
QSize sizeHint() const {if (_cur_edit) return _cur_edit->sizeHint(); return QWidget::sizeHint();}
|
||||
|
||||
struct EnumType {
|
||||
QString toString() const {return value;}
|
||||
QString value;
|
||||
QStringList enum_list;
|
||||
};
|
||||
|
||||
struct FileType {
|
||||
FileType(const QString & p = QString(), const QString & f = QString(), bool abs = false): file(p), filter(f), is_abs(abs) {}
|
||||
QString toString() const {return file;}
|
||||
QString file;
|
||||
QString filter;
|
||||
bool is_abs;
|
||||
};
|
||||
|
||||
struct DirType {
|
||||
DirType(const QString & d = QString(), bool abs = false): dir(d), is_abs(abs) {}
|
||||
QString toString() const {return dir;}
|
||||
QString dir;
|
||||
bool is_abs;
|
||||
};
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent * );
|
||||
void _recreate(const QVariant & new_value);
|
||||
void _delete();
|
||||
void _resize() {if (_cur_edit) _cur_edit->resize(size());}
|
||||
void _newPath();
|
||||
void _setEnum(const EnumType & v);
|
||||
void _setFile(const FileType & v);
|
||||
void _setDir(const DirType & v);
|
||||
void _setEnum(const QAD::Enum & v);
|
||||
void _setFile(const QAD::File & v);
|
||||
void _setDir(const QAD::Dir & v);
|
||||
|
||||
|
||||
QLabel * _empty;
|
||||
@@ -145,33 +125,4 @@ signals:
|
||||
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QVariantEdit::EnumType)
|
||||
inline QDataStream & operator <<(QDataStream & s, const QVariantEdit::EnumType & v) {s << v.value << v.enum_list; return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, QVariantEdit::EnumType & v) {s >> v.value >> v.enum_list; return s;}
|
||||
inline QDebug operator <<(QDebug s, const QVariantEdit::EnumType & v) {s.nospace() << v.value; return s.space();}
|
||||
|
||||
Q_DECLARE_METATYPE(QVariantEdit::FileType)
|
||||
inline QDataStream & operator <<(QDataStream & s, const QVariantEdit::FileType & v) {s << v.file << v.filter << v.is_abs; return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, QVariantEdit::FileType & v) {s >> v.file >> v.filter >> v.is_abs; return s;}
|
||||
inline QDebug operator <<(QDebug s, const QVariantEdit::FileType & v) {s.nospace() << v.file; return s.space();}
|
||||
|
||||
Q_DECLARE_METATYPE(QVariantEdit::DirType)
|
||||
inline QDataStream & operator <<(QDataStream & s, const QVariantEdit::DirType & v) {s << v.dir << v.is_abs; return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, QVariantEdit::DirType & v) {s >> v.dir >> v.is_abs; return s;}
|
||||
inline QDebug operator <<(QDebug s, const QVariantEdit::DirType & v) {s.nospace() << v.dir; return s.space();}
|
||||
|
||||
class __QVariantEditRegistrator__ {
|
||||
public:
|
||||
__QVariantEditRegistrator__() {
|
||||
qRegisterMetaType<QVariantEdit::EnumType>("QVariantEdit::EnumType");
|
||||
qRegisterMetaTypeStreamOperators<QVariantEdit::EnumType>("QVariantEdit::EnumType");
|
||||
|
||||
qRegisterMetaType<QVariantEdit::FileType>("QVariantEdit::FileType");
|
||||
qRegisterMetaTypeStreamOperators<QVariantEdit::FileType>("QVariantEdit::FileType");
|
||||
|
||||
qRegisterMetaType<QVariantEdit::DirType>("QVariantEdit::DirType");
|
||||
qRegisterMetaTypeStreamOperators<QVariantEdit::DirType>("QVariantEdit::DirType");
|
||||
}
|
||||
};
|
||||
|
||||
#endif // QVARIANTEDIT_H
|
||||
|
||||
@@ -24,7 +24,7 @@ qt4_wrap_cpp(CMOCS ${MOCS} OPTIONS -nw)
|
||||
qt4_wrap_ui(CUIS ${UIS})
|
||||
qt4_add_resources(RESS ${RES})
|
||||
add_library(${PROJECT_NAME} SHARED ${CPPS} ${CMOCS} ${CUIS} ${RESS} ${MOCS})
|
||||
set(LIBS ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${PIP_LIBRARY} qad_widgets cd_utils piqt)
|
||||
set(LIBS ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${PIP_LIBRARY} qad_utils qad_widgets cd_utils piqt)
|
||||
target_link_libraries(${PROJECT_NAME} ${LIBS})
|
||||
|
||||
if (NOT DEFINED ENV{QNX_HOST})
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "cdutils_k.h"
|
||||
#include "cdutils_core.h"
|
||||
#include "qcd_core.h"
|
||||
#include "qcd_kmodel.h"
|
||||
|
||||
using namespace CDUtils;
|
||||
|
||||
@@ -34,6 +35,7 @@ void Form::on_pushButton_4_clicked() {
|
||||
ui->treeView->loadK();
|
||||
ui->treeView->setKFile("");
|
||||
qDebug() << QCDCore::instance()->bindWindow(this);
|
||||
QCDCore::instance()->bindWidget(ui->spinRadar_Antenna_SwitchRate, K["NVA.NVA_FrameStitch"]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -59,8 +59,9 @@ void QCDCore::K_ChangedGlobal() {
|
||||
void QCDCore::slotBool(bool v) {
|
||||
QWidget * w = (QWidget*)sender();
|
||||
if (!w || updating) return;
|
||||
PIDeque<int> path = binded_widgets.value(w);
|
||||
CDCore::instance()->k()[path].setValue(PIString::fromBool(v));
|
||||
QList<PIDeque<int> > pathes = binded_widgets.values(w);
|
||||
foreach (const PIDeque<int> & path, pathes)
|
||||
CDCore::instance()->k()[path].setValue(PIString::fromBool(v));
|
||||
emit updateViewRequest();
|
||||
}
|
||||
|
||||
@@ -68,8 +69,9 @@ void QCDCore::slotBool(bool v) {
|
||||
void QCDCore::slotInt(int v) {
|
||||
QWidget * w = (QWidget*)sender();
|
||||
if (!w || updating) return;
|
||||
PIDeque<int> path = binded_widgets.value(w);
|
||||
CDCore::instance()->k()[path].setValue(PIString::fromNumber(v));
|
||||
QList<PIDeque<int> > pathes = binded_widgets.values(w);
|
||||
foreach (const PIDeque<int> & path, pathes)
|
||||
CDCore::instance()->k()[path].setValue(PIString::fromNumber(v));
|
||||
emit updateViewRequest();
|
||||
}
|
||||
|
||||
@@ -77,8 +79,9 @@ void QCDCore::slotInt(int v) {
|
||||
void QCDCore::slotDouble(double v) {
|
||||
QWidget * w = (QWidget*)sender();
|
||||
if (!w || updating) return;
|
||||
PIDeque<int> path = binded_widgets.value(w);
|
||||
CDCore::instance()->k()[path].setValue(PIString::fromNumber(v));
|
||||
QList<PIDeque<int> > pathes = binded_widgets.values(w);
|
||||
foreach (const PIDeque<int> & path, pathes)
|
||||
CDCore::instance()->k()[path].setValue(PIString::fromNumber(v));
|
||||
emit updateViewRequest();
|
||||
}
|
||||
|
||||
@@ -86,8 +89,9 @@ void QCDCore::slotDouble(double v) {
|
||||
void QCDCore::slotText(QString v) {
|
||||
QWidget * w = (QWidget*)sender();
|
||||
if (!w || updating) return;
|
||||
PIDeque<int> path = binded_widgets.value(w);
|
||||
CDCore::instance()->k()[path].setValue(Q2PIString(v));
|
||||
QList<PIDeque<int> > pathes = binded_widgets.values(w);
|
||||
foreach (const PIDeque<int> & path, pathes)
|
||||
CDCore::instance()->k()[path].setValue(Q2PIString(v));
|
||||
emit updateViewRequest();
|
||||
}
|
||||
|
||||
@@ -124,7 +128,7 @@ bool QCDCore::bindWidget(QWidget * w) {
|
||||
}
|
||||
|
||||
|
||||
bool QCDCore::bindWidget(QWidget * w, const CDType & k) {
|
||||
bool QCDCore::bindWidget(QWidget * w, const CDType k) {
|
||||
if (!w) return false;
|
||||
QString cn = w->metaObject()->className();
|
||||
bool ok = false;
|
||||
@@ -148,7 +152,8 @@ bool QCDCore::bindWidget(QWidget * w, const CDType & k) {
|
||||
bindView(w);
|
||||
}
|
||||
if (!ok) return false;
|
||||
binded_widgets[w] = k.path();
|
||||
piCout << k.name() << k.path();
|
||||
binded_widgets.insert(w, k.path());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define QCD_CORE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QMultiMap>
|
||||
#include "piobject.h"
|
||||
#include "cdutils_types.h"
|
||||
|
||||
@@ -30,7 +30,7 @@ public:
|
||||
int bindWindow(QWidget * wnd);
|
||||
int bindWidgets(QList<QWidget * > wl);
|
||||
bool bindWidget(QWidget * w);
|
||||
bool bindWidget(QWidget * w, const CDUtils::CDType & k);
|
||||
bool bindWidget(QWidget * w, const CDUtils::CDType k);
|
||||
|
||||
int unbindWindow(QWidget * wnd);
|
||||
int unbindWidgets(QList<QWidget * > wl);
|
||||
@@ -44,7 +44,7 @@ private:
|
||||
void bindView(QWidget * v);
|
||||
EVENT_HANDLER(void, K_ChangedGlobal);
|
||||
|
||||
QMap<QWidget * , PIDeque<int> > binded_widgets;
|
||||
QMultiMap<QWidget * , PIDeque<int> > binded_widgets;
|
||||
bool updating;
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -5,10 +5,20 @@
|
||||
#include <QBrush>
|
||||
#include <QColor>
|
||||
#include "qvariantedit.h"
|
||||
#include "qad_types.h"
|
||||
|
||||
|
||||
using namespace CDUtils;
|
||||
|
||||
|
||||
QList<QAD::Enumerator> CDEnum2QADEnum(const PIVector<CDType::Enumerator> & el) {
|
||||
QList<QAD::Enumerator> ret;
|
||||
piForeachC (CDType::Enumerator & e, el)
|
||||
ret << QAD::Enumerator(e.first, PI2QString(e.second));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
CDKItemModel::CDKItemModel(QObject *parent) : QAbstractItemModel(parent) {
|
||||
root = 0;
|
||||
internalRebuild();
|
||||
@@ -223,11 +233,11 @@ QVariant CDKItem::value(CDType t, int role) const {
|
||||
if (t.type() == "n") return t.toInt();
|
||||
if (t.type() == "b") return t.toBool();
|
||||
if (t.type() == "e") {
|
||||
QVariantEdit::EnumType et;
|
||||
et.enum_list = PI2QStringList(t.enumValues());
|
||||
et.value = et.enum_list.at(t.toInt());//et.enum_list.indexOf("");
|
||||
if (role == Qt::EditRole)return QVariant::fromValue<QVariantEdit::EnumType>(et);
|
||||
else return et.value;
|
||||
QAD::Enum et;
|
||||
et.enum_list = CDEnum2QADEnum(t.enumValues());
|
||||
et.selectValue(t.toInt());
|
||||
if (role == Qt::EditRole) return QVariant::fromValue<QAD::Enum>(et);
|
||||
else return et.selectedName();
|
||||
}
|
||||
return PI2QString(t.value());
|
||||
}
|
||||
@@ -296,9 +306,9 @@ void CDKDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
|
||||
void CDKDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {
|
||||
QVariantEdit *edit = static_cast<QVariantEdit*>(editor);
|
||||
QVariant v = edit->value();
|
||||
if (v.canConvert<QVariantEdit::EnumType>()) {
|
||||
QVariantEdit::EnumType et = v.value<QVariantEdit::EnumType>();
|
||||
model->setData(index, et.enum_list.indexOf(et.value), Qt::EditRole);
|
||||
if (v.canConvert<QAD::Enum>()) {
|
||||
QAD::Enum et = v.value<QAD::Enum>();
|
||||
model->setData(index, et.selectedValue(), Qt::EditRole);
|
||||
} else model->setData(index, v, Qt::EditRole);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@ namespace CDUtils {
|
||||
class CDSection;
|
||||
class CDType;
|
||||
}
|
||||
namespace QAD {
|
||||
class Enum;
|
||||
}
|
||||
class CDKItemModel;
|
||||
|
||||
class CDKItem {
|
||||
|
||||
Reference in New Issue
Block a user