/* PIQt - PIP <-> Qt convertions Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef PIQT_H #define PIQT_H #include "pimathmatrix.h" #include "pipropertystorage.h" #include "piqt_macros.h" #include "qad_types.h" #include #include #include #include #include #include #include #include #if QT_VERSION_MAJOR == 5 # if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) # define PIQT_HAS_GEOPOSITION # endif #endif #if QT_VERSION_MAJOR == 6 # if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) # define PIQT_HAS_GEOPOSITION # endif #endif #ifdef PIQT_HAS_GEOPOSITION class QGeoCoordinate; class PIGeoPosition; #endif #include "qad_piqt_export.h" QAD_PIQT_EXPORT QVariant PI2QVariant(const PIVariant & v); QAD_PIQT_EXPORT PIVariant Q2PIVariant(const QVariant & v); // inline QString PI2QString(const PIString & v) {return QString::fromLocal8Bit(v.data());} inline QString PI2QString(const PIString & v) { if (v.isEmpty()) return QString(); return QString::fromUtf8(v.dataUTF8()); } #if PIP_VERSION >= PIP_MAKE_VERSION(2, 38, 0) inline QString PI2QString(const PIConstChars & v) { if (v.isEmpty()) return QString(); return QString::fromLatin1(v.data(), v.length()); } #endif // inline PIString Q2PIString(const QString & v) {return PIString(v.toLocal8Bit().data());} inline PIString Q2PIString(const QString & v) { if (v.isEmpty()) return PIString(); auto qba = v.toUtf8(); return PIString::fromUTF8(qba.constData(), qba.size()); } inline QStringList PI2QStringList(const PIStringList & v) { if (v.isEmpty()) return QStringList(); QStringList ret; for (const auto & s: v) ret << PI2QString(s); return ret; } inline PIStringList Q2PIStringList(const QStringList & v) { if (v.isEmpty()) return PIStringList(); PIStringList ret; ret.reserve(v.size()); for (const auto & s: v) ret << Q2PIString(s); return ret; } inline QByteArray PI2QByteArray(const PIByteArray & v) { if (v.isEmpty()) return QByteArray(); return QByteArray((const char *)(v.data()), v.size_s()); } inline PIByteArray Q2PIByteArray(const QByteArray & v) { if (v.isEmpty()) return PIByteArray(); return PIByteArray(v.constData(), v.size()); } inline QPointF PI2QVector2(const PIMathVectorT2d & v) { return QPointF(v[0], v[1]); } inline QVector3D PI2QVector3(const PIMathVectorT3d & v) { return QVector3D(v[0], v[1], v[2]); } inline PIMathVectorT2d Q2PIVector2(const QPointF & v) { return PIMathVectorT2d({double(v.x()), double(v.y())}); } inline PIMathVectorT3d Q2PIVector3(const QVector3D & v) { return PIMathVectorT3d({double(v.x()), double(v.y()), double(v.z())}); } template inline QGenericMatrix PI2QMathMatrixT(const PIMathMatrixT & v) { QGenericMatrix ret; for (int r = 0; r < Rows; ++r) for (int c = 0; c < Cols; ++c) ret(r, c) = v[r][c]; return ret; } template inline PIMathMatrixT Q2PIMathMatrixT(const QGenericMatrix & v) { PIMathMatrixT ret; for (int r = 0; r < Rows; ++r) for (int c = 0; c < Cols; ++c) ret[r][c] = v(r, c); return ret; } inline PIMathMatrixT<4, 4, float> Q2PIMathMatrixT(const QMatrix4x4 & v) { PIMathMatrixT<4, 4, float> ret; for (int r = 0; r < 4; ++r) for (int c = 0; c < 4; ++c) ret[r][c] = v(r, c); return ret; } inline PIMathVectorT2d Q2PIMathVectorT(const QVector2D & v) { return PIMathVectorT2d({v[0], v[1]}); } inline PIMathVectorT2d Q2PIMathVectorT(const QPointF & v) { return PIMathVectorT2d({v.x(), v.y()}); } inline PIMathVectorT3d Q2PIMathVectorT(const QVector3D & v) { return PIMathVectorT3d({v[0], v[1], v[2]}); } inline PIMathVectorT4d Q2PIMathVectorT(const QVector4D & v) { return PIMathVectorT4d({v[0], v[1], v[2], v[3]}); } template inline PIMathVectorT Q2PIMathVectorT(const QGenericMatrix<1, Size, Type> & v) { PIMathVectorT ret; for (int i = 0; i < Size; ++i) ret[i] = v(i, 0); return ret; } template inline PIMathVectorT Q2PIMathVectorT(const QGenericMatrix & v) { PIMathVectorT ret; for (int i = 0; i < Size; ++i) ret[i] = v(0, i); return ret; } inline QPointF PI2QPoint(const PIPointd & v) { return QPointF(v.x, v.y); } inline PIPointd Q2PIPoint(const QPointF & v) { return PIPointd(v.x(), v.y()); } inline QRectF PI2QRect(const PIRectd & v) { return QRectF(v.left(), v.bottom(), v.width(), v.height()); } inline PIRectd Q2PIRect(const QRectF & v) { return PIRectd(v.left(), v.top(), v.width(), v.height()); } inline QLineF PI2QLine(const PILined & v) { return QLineF(PI2QPoint(v.p0), PI2QPoint(v.p1)); } inline PILined Q2PILine(const QLineF & v) { return PILined(Q2PIPoint(v.p1()), Q2PIPoint(v.p2())); } inline QAD::MathVector PI2QMathVector(const PIMathVectord & v) { QVector q = QVector(v.size()); memcpy(q.data(), v.data(), q.size() * sizeof(double)); return QAD::MathVector(q); } inline PIMathVectord Q2PIMathVector(const QAD::MathVector & v) { PIMathVectord p = PIMathVectord(v.v.size()); memcpy(p.data(), v.v.data(), p.size() * sizeof(double)); return p; } inline QAD::MathMatrix PI2QMathMatrix(const PIMathMatrixd & v) { PIVector> p = v.toVectors(); QVector> q = QVector>(p.size()); for (int i = 0; i < q.size(); ++i) { q[i].resize(p[i].size()); memcpy(q[i].data(), p[i].data(), q[i].size() * sizeof(double)); } return QAD::MathMatrix(q); } inline PIMathMatrixd Q2PIMathMatrix(const QAD::MathMatrix & v) { PIVector> p = PIVector>(v.m.size()); for (int i = 0; i < v.m.size(); ++i) { p[i].resize(v.m[i].size()); memcpy(p[i].data(), v.m[i].data(), p[i].size() * sizeof(double)); } return PIMathMatrixd(p); } inline QDate PI2QDate(const PIDate & v) { return QDate(v.year, v.month, v.day); } inline QTime PI2QTime(const PITime & v) { return QTime(v.hours, v.minutes, v.seconds, v.milliseconds); } inline QDateTime PI2QDateTime(const PIDateTime & v) { return QDateTime(PI2QDate(v.date()), PI2QTime(v.time())); } inline PIDate Q2PIDate(const QDate & v) { return PIDate(v.year(), v.month(), v.day()); } inline PITime Q2PITime(const QTime & v) { return PITime(v.hour(), v.minute(), v.second(), v.msec()); } inline PIDateTime Q2PIDateTime(const QDateTime & v) { return PIDateTime(Q2PIDate(v.date()), Q2PITime(v.time())); } inline QColor PI2QColor(const PIVariantTypes::Color & v) { return QColor::fromRgba(v.rgba); } inline PIVariantTypes::Color Q2PIColor(const QColor & v) { return PIVariantTypes::Color(v.rgba()); } template inline QVector PI2QVector(const PIVector & v) { QVector ret; ret.reserve(v.size_s()); for (int i = 0; i < v.size_s(); ++i) ret << v[i]; return ret; } #if QT_VERSION_MAJOR == 5 template inline PIVector Q2PIVector(const QVector & v) { if (v.isEmpty()) return PIVector(); return PIVector(v.constData(), (size_t)v.size()); } #endif template inline PIVector Q2PIVector(const QList & v) { if (v.isEmpty()) return PIVector(); PIVector ret; ret.reserve(v.size()); for (const auto & i: v) ret << i; return ret; } template inline QMap PI2QMap(const PIMap & v) { QMap ret; auto it = v.makeIterator(); while (it.hasNext()) { it.next(); ret[it.key()] = it.value(); } return ret; } template inline PIMap Q2PIMap(const QMap & v) { PIMap ret; ret.reserve((size_t)v.size()); QMapIterator it(v); while (it.hasNext()) { it.next(); ret[it.key()] = it.value(); } return ret; } inline PIPropertyStorage Q2PIPropertyStorage(const PropertyStorage & props) { PIPropertyStorage ret; for (const auto & p: props) ret.addProperty(Q2PIString(p.name), Q2PIVariant(p.value), Q2PIString(p.comment), p.flags); return ret; } inline PropertyStorage PI2QPropertyStorage(const PIPropertyStorage & props) { PropertyStorage ret; for (const auto & p: props) ret.addProperty(PI2QString(p.name), PI2QVariant(p.value), PI2QString(p.comment), p.flags); return ret; } QAD_PIQT_EXPORT QAD::Enum PI2QADEnum(const PIVariantTypes::Enum & el); QAD_PIQT_EXPORT QAD::File PI2QADFile(const PIVariantTypes::File & v); QAD_PIQT_EXPORT QAD::Dir PI2QADDir(const PIVariantTypes::Dir & v); QAD_PIQT_EXPORT QAD::IODevice PI2QADIODevice(const PIVariantTypes::IODevice & v); QAD_PIQT_EXPORT PIVariantTypes::Enum QAD2PIEnum(const QAD::Enum & el); QAD_PIQT_EXPORT PIVariantTypes::File QAD2PIFile(const QAD::File & v); QAD_PIQT_EXPORT PIVariantTypes::Dir QAD2PIDir(const QAD::Dir & v); QAD_PIQT_EXPORT PIVariantTypes::IODevice QAD2PIIODevice(const QAD::IODevice & v); // inline PIVariant QString2PIVariant(const QString & v) {return PIVariant::readFromString(QString2PIString(v));} #ifdef PIQT_HAS_GEOPOSITION QAD_PIQT_EXPORT QGeoCoordinate PI2QGeoPosition(const PIGeoPosition & v); QAD_PIQT_EXPORT PIGeoPosition Q2PIGeoPosition(const QGeoCoordinate & v); #endif template class __PIQtConverter { public: __PIQtConverter(const From & v): val(v) {} template operator To() { return To(); } From val; }; template inline __PIQtConverter __PIQtConvert(const From & f) { return __PIQtConverter(f); } #define _PIQt_CONVERT(ft, tt, ftc, tfc) \ template<> \ template<> \ inline __PIQtConverter::operator tt() { \ return ftc(val); \ } \ template<> \ template<> \ inline __PIQtConverter::operator ft() { \ return tfc(val); \ } #define _PIQt_CONVERT_S(t) _PIQt_CONVERT(PI##t, Q##t, PI2Q##t, Q2PI##t) _PIQt_CONVERT_S(String) _PIQt_CONVERT_S(ByteArray) _PIQt_CONVERT_S(Time) _PIQt_CONVERT_S(Date) _PIQt_CONVERT_S(DateTime) _PIQt_CONVERT(PIMathVectorT2d, QPointF, PI2QVector2, Q2PIVector2) _PIQt_CONVERT(PIMathVectorT3d, QVector3D, PI2QVector3, Q2PIVector3) #define piqt __PIQtConvert #define qtpi __PIQtConvert #ifndef PIP_BINARY_STREAM inline PIByteArray & operator<<(PIByteArray & s, const QString & v) { s << Q2PIString(v); return s; } inline PIByteArray & operator>>(PIByteArray & s, QString & v) { PIString t; s >> t; v = PI2QString(t); return s; } inline PIByteArray & operator<<(PIByteArray & s, const QStringList & v) { s << Q2PIStringList(v); return s; } inline PIByteArray & operator>>(PIByteArray & s, QStringList & v) { PIStringList t; s >> t; v = PI2QStringList(t); return s; } template inline PIByteArray & operator<<(PIByteArray & s, const QVector & v) { s << PIVector(v.constData(), (size_t)v.size()); return s; } template inline PIByteArray & operator>>(PIByteArray & s, QVector & v) { PIVector t; s >> t; v.resize(t.size_s()); for (int i = 0; i < t.size_s(); ++i) v[i] = t[i]; return s; } template inline PIByteArray & operator<<(PIByteArray & s, const QMap & v) { PIMap t; t.reserve(v.size()); QMapIterator it(v); while (it.hasNext()) { it.next(); t[it.key()] = it.value(); } s << t; return s; } template inline PIByteArray & operator>>(PIByteArray & s, QMap & v) { v.clear(); PIMap t; s >> t; auto it = t.makeIterator(); while (it.hasNext()) { it.next(); v[it.key()] = it.value(); } return s; } inline PIByteArray & operator<<(PIByteArray & s, const QPolygonF & v) { s << (QVector)v; return s; } inline PIByteArray & operator>>(PIByteArray & s, QPolygonF & v) { QVector t; s >> t; v = t; return s; } inline PIByteArray & operator<<(PIByteArray & s, const QByteArray & v) { s << Q2PIByteArray(v); return s; } inline PIByteArray & operator>>(PIByteArray & s, QByteArray & v) { PIByteArray t; s >> t; v = PI2QByteArray(t); return s; } inline PIByteArray & operator<<(PIByteArray & s, const QDate & v) { s << Q2PIDate(v); return s; } inline PIByteArray & operator>>(PIByteArray & s, QDate & v) { PIDate t; s >> t; v = PI2QDate(t); return s; } inline PIByteArray & operator<<(PIByteArray & s, const QTime & v) { s << Q2PITime(v); return s; } inline PIByteArray & operator>>(PIByteArray & s, QTime & v) { PITime t; s >> t; v = PI2QTime(t); return s; } inline PIByteArray & operator<<(PIByteArray & s, const QDateTime & v) { s << Q2PIDateTime(v); return s; } inline PIByteArray & operator>>(PIByteArray & s, QDateTime & v) { PIDateTime t; s >> t; v = PI2QDateTime(t); return s; } inline PIByteArray & operator<<(PIByteArray & s, const QVariant & v) { s << Q2PIVariant(v); return s; } inline PIByteArray & operator>>(PIByteArray & s, QVariant & v) { PIVariant t; s >> t; v = PI2QVariant(t); return s; } inline PIByteArray & operator<<(PIByteArray & s, const PropertyStorage & v) { s << Q2PIPropertyStorage(v); return s; } inline PIByteArray & operator>>(PIByteArray & s, PropertyStorage & v) { PIPropertyStorage t; s >> t; v = PI2QPropertyStorage(t); return s; } inline PIByteArray & operator<<(PIByteArray & s, const QColor & v) { s << Q2PIColor(v); return s; } inline PIByteArray & operator>>(PIByteArray & s, QColor & v) { PIVariantTypes::Color t; s >> t; v = PI2QColor(t); return s; } inline PIByteArray & operator<<(PIByteArray & s, const QAD::Enum & v) { s << QAD2PIEnum(v); return s; } inline PIByteArray & operator>>(PIByteArray & s, QAD::Enum & v) { PIVariantTypes::Enum t; s >> t; v = PI2QADEnum(t); return s; } inline PIByteArray & operator<<(PIByteArray & s, const QAD::File & v) { s << QAD2PIFile(v); return s; } inline PIByteArray & operator>>(PIByteArray & s, QAD::File & v) { PIVariantTypes::File t; s >> t; v = PI2QADFile(t); return s; } inline PIByteArray & operator<<(PIByteArray & s, const QAD::Dir & v) { s << QAD2PIDir(v); return s; } inline PIByteArray & operator>>(PIByteArray & s, QAD::Dir & v) { PIVariantTypes::Dir t; s >> t; v = PI2QADDir(t); return s; } inline PIByteArray & operator<<(PIByteArray & s, const QAD::IODevice & v) { s << QAD2PIIODevice(v); return s; } inline PIByteArray & operator>>(PIByteArray & s, QAD::IODevice & v) { PIVariantTypes::IODevice t; s >> t; v = PI2QADIODevice(t); return s; } inline PIByteArray & operator<<(PIByteArray & s, const QImage & v) { QByteArray ba; QBuffer buf(&ba); v.save(&buf, "png"); s << Q2PIByteArray(ba); return s; } inline PIByteArray & operator>>(PIByteArray & s, QImage & v) { PIByteArray pba; s >> pba; QByteArray ba = PI2QByteArray(pba); if (!v.loadFromData(ba, "png")) v = QImage(); return s; } #else template inline PIBinaryStream

& operator<<(PIBinaryStream

& s, const QVector & v) { s << PIVector(v.constData(), (size_t)v.size()); return s; } template inline PIBinaryStream

& operator>>(PIBinaryStream

& s, QVector & v) { PIVector t; s >> t; v.resize(t.size_s()); for (int i = 0; i < t.size_s(); ++i) v[i] = t[i]; return s; } template inline PIBinaryStream

& operator<<(PIBinaryStream

& s, const QMap & v) { PIMap t; t.reserve(v.size()); QMapIterator it(v); while (it.hasNext()) { it.next(); t[it.key()] = it.value(); } s << t; return s; } template inline PIBinaryStream

& operator>>(PIBinaryStream

& s, QMap & v) { v.clear(); PIMap t; s >> t; auto it = t.makeIterator(); while (it.hasNext()) { it.next(); v[it.key()] = it.value(); } return s; } BINARY_STREAM_WRITE(QString) { s << Q2PIString(v); return s; } BINARY_STREAM_READ(QString) { PIString t; s >> t; v = PI2QString(t); return s; } BINARY_STREAM_WRITE(QStringList) { s << Q2PIStringList(v); return s; } BINARY_STREAM_READ(QStringList) { PIStringList t; s >> t; v = PI2QStringList(t); return s; } BINARY_STREAM_WRITE(QPolygonF) { s << (QVector)v; return s; } BINARY_STREAM_READ(QPolygonF) { QVector t; s >> t; v = t; return s; } BINARY_STREAM_WRITE(QByteArray) { s << Q2PIByteArray(v); return s; } BINARY_STREAM_READ(QByteArray) { PIByteArray t; s >> t; v = PI2QByteArray(t); return s; } BINARY_STREAM_WRITE(QDate) { s << Q2PIDate(v); return s; } BINARY_STREAM_READ(QDate) { PIDate t; s >> t; v = PI2QDate(t); return s; } BINARY_STREAM_WRITE(QTime) { s << Q2PITime(v); return s; } BINARY_STREAM_READ(QTime) { PITime t; s >> t; v = PI2QTime(t); return s; } BINARY_STREAM_WRITE(QDateTime) { s << Q2PIDateTime(v); return s; } BINARY_STREAM_READ(QDateTime) { PIDateTime t; s >> t; v = PI2QDateTime(t); return s; } BINARY_STREAM_WRITE(QVariant) { s << Q2PIVariant(v); return s; } BINARY_STREAM_READ(QVariant) { PIVariant t; s >> t; v = PI2QVariant(t); return s; } BINARY_STREAM_WRITE(PropertyStorage) { s << Q2PIPropertyStorage(v); return s; } BINARY_STREAM_READ(PropertyStorage) { PIPropertyStorage t; s >> t; v = PI2QPropertyStorage(t); return s; } BINARY_STREAM_WRITE(QColor) { s << Q2PIColor(v); return s; } BINARY_STREAM_READ(QColor) { PIVariantTypes::Color t; s >> t; v = PI2QColor(t); return s; } BINARY_STREAM_WRITE(QAD::Enum) { s << QAD2PIEnum(v); return s; } BINARY_STREAM_READ(QAD::Enum) { PIVariantTypes::Enum t; s >> t; v = PI2QADEnum(t); return s; } BINARY_STREAM_WRITE(QAD::File) { s << QAD2PIFile(v); return s; } BINARY_STREAM_READ(QAD::File) { PIVariantTypes::File t; s >> t; v = PI2QADFile(t); return s; } BINARY_STREAM_WRITE(QAD::Dir) { s << QAD2PIDir(v); return s; } BINARY_STREAM_READ(QAD::Dir) { PIVariantTypes::Dir t; s >> t; v = PI2QADDir(t); return s; } BINARY_STREAM_WRITE(QAD::IODevice) { s << QAD2PIIODevice(v); return s; } BINARY_STREAM_READ(QAD::IODevice) { PIVariantTypes::IODevice t; s >> t; v = PI2QADIODevice(t); return s; } BINARY_STREAM_WRITE(QImage) { QByteArray ba; QBuffer buf(&ba); v.save(&buf, "png"); s << Q2PIByteArray(ba); return s; } BINARY_STREAM_READ(QImage) { PIByteArray pba; s >> pba; QByteArray ba = PI2QByteArray(pba); if (!v.loadFromData(ba, "png")) v = QImage(); return s; } #endif /// PIP with QByteArray template QByteArray piqSerialize(const T & value) { PIByteArray ret; ret << value; return PI2QByteArray(ret); } template T piqDeserialize(const QByteArray & data) { T ret; if (!data.isEmpty()) { PIByteArray ba = Q2PIByteArray(data); ba >> ret; } return ret; } /// PICout with Qt inline PICout operator<<(PICout s, const QVariant & v) { s << Q2PIVariant(v); return s; } inline PICout operator<<(PICout s, const QByteArray & v) { s << Q2PIByteArray(v); return s; } inline PICout operator<<(PICout s, const QString & v) { s << Q2PIString(v); return s; } inline PICout operator<<(PICout s, const QStringList & v) { s << Q2PIStringList(v); return s; } #if QT_VERSION_MAJOR == 5 template inline PICout operator<<(PICout s, const QVector & v) { s << Q2PIVector(v); return s; } #endif template inline PICout operator<<(PICout s, const QList & v) { s << Q2PIVector(v); return s; } template inline PICout operator<<(PICout s, const QMap & v) { s << Q2PIMap(v); return s; } inline PICout operator<<(PICout s, const QTime & v) { s << Q2PITime(v); return s; } inline PICout operator<<(PICout s, const QDate & v) { s << Q2PIDate(v); return s; } inline PICout operator<<(PICout s, const QDateTime & v) { s << Q2PIDateTime(v); return s; } inline PICout operator<<(PICout s, const QPoint & v) { s << Q2PIPoint(v); return s; } inline PICout operator<<(PICout s, const QPointF & v) { s << Q2PIPoint(v); return s; } inline PICout operator<<(PICout s, const QLine & v) { s << Q2PILine(v); return s; } inline PICout operator<<(PICout s, const QLineF & v) { s << Q2PILine(v); return s; } inline PICout operator<<(PICout s, const QRect & v) { s << Q2PIRect(v); return s; } inline PICout operator<<(PICout s, const QRectF & v) { s << Q2PIRect(v); return s; } inline PICout operator<<(PICout s, const QColor & v) { s << Q2PIColor(v); return s; } inline PICout operator<<(PICout s, const QVector2D & v) { s << PIMathVectorT2d({v[0], v[1]}); return s; } inline PICout operator<<(PICout s, const QVector3D & v) { s << PIMathVectorT3d({v[0], v[1], v[2]}); return s; } inline PICout operator<<(PICout s, const QVector4D & v) { s << PIMathVectorT4d({v[0], v[1], v[2], v[3]}); return s; } template inline PICout operator<<(PICout s, const QGenericMatrix & v) { s << Q2PIMathMatrixT(v); return s; } inline PICout operator<<(PICout s, const QMatrix4x4 & v) { s << Q2PIMathMatrixT(v); return s; } #ifdef PIQT_HAS_GEOPOSITION inline PICout operator<<(PICout s, const QGeoCoordinate & v) { s << Q2PIGeoPosition(v); return s; } #endif #endif // PIQT_H