Adds initial intermediate qt6 porting state
This commit is contained in:
11247 files changed
+1891537
No files matched your search
@@ -0,0 +1,61 @@
|
||||
#
|
||||
# CMake Script für ngltools
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
SET(ngltools_SRCS
|
||||
ngltools_bitset.h
|
||||
ngltools_convert.cpp
|
||||
ngltools_convert.h
|
||||
ngltools_dtg.cpp
|
||||
ngltools_dtg.h
|
||||
ngltools_export.h
|
||||
ngltools_filesystem.cpp
|
||||
ngltools_filesystem.h
|
||||
ngltools_helpevent.cpp
|
||||
ngltools_helpevent.h
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(ALL ngltools SHARED ${ngltools_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(ngltools
|
||||
PUBLIC
|
||||
Qt5::Core
|
||||
)
|
||||
|
||||
# Smoke test for ngltools DTG conversion utilities
|
||||
IF(BUILD_TESTING)
|
||||
find_package(Qt6 COMPONENTS Test Core QUIET)
|
||||
if (Qt6_FOUND)
|
||||
set(_QTTEST_TARGET Qt6::Test)
|
||||
set(_QTCORE_TARGET Qt6::Core)
|
||||
else()
|
||||
find_package(Qt5 COMPONENTS Test Core REQUIRED)
|
||||
set(_QTTEST_TARGET Qt5::Test)
|
||||
set(_QTCORE_TARGET Qt5::Core)
|
||||
endif()
|
||||
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/NGLToolsQtSmokeTest.cpp)
|
||||
if(TARGET ngltools)
|
||||
add_executable(ngltools_qt_smoke tests/NGLToolsQtSmokeTest.cpp)
|
||||
target_link_libraries(ngltools_qt_smoke PRIVATE ngltools ${_QTTEST_TARGET} ${_QTCORE_TARGET})
|
||||
else()
|
||||
# Build the smoke test as a standalone executable using the dtg implementation
|
||||
# when the ngltools library target is not available in this configuration.
|
||||
add_executable(ngltools_qt_smoke tests/NGLToolsQtSmokeTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ngltools_dtg.cpp)
|
||||
target_include_directories(ngltools_qt_smoke PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(ngltools_qt_smoke PRIVATE ${_QTTEST_TARGET} ${_QTCORE_TARGET})
|
||||
endif()
|
||||
add_test(NAME NGLToolsQtSmoke COMMAND ngltools_qt_smoke)
|
||||
endif()
|
||||
ENDIF()
|
||||
NGL_TARGET_COMPILE_DEFINITIONS(ngltools PUBLIC BUILD_BASE_PATH="${CMAKE_BINARY_DIR}")
|
||||
NGL_TARGET_COMPILE_DEFINITIONS(ngltools PUBLIC INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(ngltools
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
)
|
||||
NGL_INSTALL_TARGET(ngltools)
|
||||
@@ -0,0 +1,100 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace NGL {
|
||||
template<class T>
|
||||
class BitSet {
|
||||
public:
|
||||
BitSet(T bitset = T())
|
||||
: mBitSet(bitset)
|
||||
, mSize(sizeof(T)*8)
|
||||
{}
|
||||
BitSet(const BitSet<T> &other)
|
||||
: mBitSet(other.mBitSet)
|
||||
, mSize(other.mSize)
|
||||
{}
|
||||
BitSet &operator=(const BitSet<T> &other)
|
||||
{
|
||||
if(this == &other)
|
||||
return *this;
|
||||
mBitSet = other.mBitSet;
|
||||
mSize = other.mSize;
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const BitSet<T> &other) const
|
||||
{
|
||||
return (mBitSet == other.mBitSet && mSize == other.mSize);
|
||||
}
|
||||
bool setBit(unsigned int bitNum)
|
||||
{
|
||||
if(bitNum >= mSize)
|
||||
return false;
|
||||
mBitSet |= getBit(bitNum);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool clearBit(unsigned int bitNum)
|
||||
{
|
||||
if(bitNum >= mSize)
|
||||
return false;
|
||||
mBitSet &= ~(getBit(bitNum));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool at(unsigned int bitNum) const
|
||||
{
|
||||
if(bitNum >= sizeof(T) * 8)
|
||||
return false;
|
||||
T compVal = getBit(bitNum);
|
||||
return ((mBitSet & compVal) == compVal);
|
||||
}
|
||||
|
||||
bool operator[] (unsigned int bitNum) const
|
||||
{
|
||||
return at(bitNum);
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
|
||||
bool resize(size_t newSize)
|
||||
{
|
||||
if(newSize >= sizeof(T) * 8)
|
||||
return false;
|
||||
for(unsigned int i = mSize; i < newSize; ++i)
|
||||
clearBit(i);
|
||||
mSize = newSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
fill(false);
|
||||
}
|
||||
|
||||
void fill(bool bBitsSet)
|
||||
{
|
||||
if(bBitsSet)
|
||||
mBitSet = ~T();
|
||||
else
|
||||
mBitSet = T();
|
||||
}
|
||||
|
||||
T operator()() const { return mBitSet; }
|
||||
|
||||
protected:
|
||||
static T getBit(unsigned int bitNum_)
|
||||
{
|
||||
T bitNum = bitNum_;
|
||||
const T one = 1;
|
||||
return (one << bitNum);
|
||||
}
|
||||
|
||||
T mBitSet;
|
||||
size_t mSize;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
#include "ngltools_convert.h"
|
||||
|
||||
#include <QVector>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
QByteArray quoteForTelnet(const QVector<QString> &sl)
|
||||
{
|
||||
QVector<QByteArray> tmp;
|
||||
tmp.reserve(sl.size());
|
||||
for (const QString &s : sl)
|
||||
tmp += s.toUtf8();
|
||||
return quoteForTelnet(tmp);
|
||||
}
|
||||
|
||||
QByteArray quoteForTelnet(const QVector<QByteArray> &sl)
|
||||
{
|
||||
QByteArray cmd;
|
||||
for (QByteArray s : sl)
|
||||
{
|
||||
s.replace('\"', "\\\"");
|
||||
if (s.contains(' '))
|
||||
s = '"' + s + '"';
|
||||
if (s.isEmpty())
|
||||
s = "\"\"";
|
||||
cmd += s + ' ';
|
||||
}
|
||||
cmd += '\n';
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
QVector<QByteArray> parseFromTelnet(const QByteArray &ba, const int iStart)
|
||||
{
|
||||
QVector<QByteArray> ret;
|
||||
const char *p = ba.constData() + iStart;
|
||||
const int iLen = ba.length();
|
||||
const char *p_end = ba.constData() + iLen;
|
||||
if (iLen <= iStart)
|
||||
return ret;
|
||||
char quoteEndChar = '"';
|
||||
|
||||
while (p < p_end && *p)
|
||||
{
|
||||
while (isspace(*p))
|
||||
++p;
|
||||
if (*p && p < p_end)
|
||||
{
|
||||
bool escaped = false;
|
||||
bool bQuoted = (*p == '\"') || (*p == '{');
|
||||
if (bQuoted)
|
||||
{
|
||||
quoteEndChar = (*p == '\"') ? '\"' : '}';
|
||||
++p;
|
||||
}
|
||||
const char *start = p;
|
||||
while (true)
|
||||
{
|
||||
while (p < p_end && *p != (bQuoted ? quoteEndChar : ' '))
|
||||
++p;
|
||||
if (bQuoted)
|
||||
{
|
||||
|
||||
if (* (p - 1) == '\\')
|
||||
{
|
||||
++p;
|
||||
escaped = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
QByteArray result = QByteArray(start, p - start).trimmed();
|
||||
if (escaped)
|
||||
{
|
||||
if (quoteEndChar == '}')
|
||||
{
|
||||
result = result.replace("\\{", "{");
|
||||
result = result.replace("\\}", "}");
|
||||
}
|
||||
else
|
||||
result = result.replace("\\\"", "\"");
|
||||
}
|
||||
ret += result;
|
||||
++p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ngltools_export.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
NGLTOOLS_EXPORT QByteArray quoteForTelnet(const QVector<QString> &sl);
|
||||
NGLTOOLS_EXPORT QByteArray quoteForTelnet(const QVector<QByteArray> &sl);
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT QVector<QByteArray> parseFromTelnet(const QByteArray &ba, const int iStart = 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
#include "ngltools_dtg.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QDateTime>
|
||||
#include <QTimeZone>
|
||||
|
||||
namespace DTG
|
||||
{
|
||||
|
||||
static char s_timezone = 'Z';
|
||||
static char s_userDefinedTimezone = s_timezone;
|
||||
static char s_exerciseDefaultTimezone = s_timezone;
|
||||
int timezone2Hours(char tz, bool *bOk)
|
||||
{
|
||||
if (!isTimezoneValid(tz))
|
||||
{
|
||||
if (bOk)
|
||||
*bOk = false;
|
||||
return 0;
|
||||
}
|
||||
if (bOk)
|
||||
*bOk = true;
|
||||
if (tz < 'J')
|
||||
return tz - 'A' + 1;
|
||||
if (tz < 'N')
|
||||
return tz - 'A';
|
||||
if (tz < 'Z')
|
||||
return 'Z' - tz - 13;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timezone2Secs(char tz, bool *bOk)
|
||||
{
|
||||
return 3600 * timezone2Hours(tz, bOk) ;
|
||||
}
|
||||
|
||||
|
||||
bool setTimezone(char tz, bool bUserDefinedZone)
|
||||
{
|
||||
if (!isTimezoneValid(tz))
|
||||
{
|
||||
|
||||
if (!(tz == 0 && bUserDefinedZone))
|
||||
return false;
|
||||
}
|
||||
if (bUserDefinedZone)
|
||||
s_userDefinedTimezone = tz;
|
||||
else
|
||||
s_exerciseDefaultTimezone = tz;
|
||||
|
||||
s_timezone = s_userDefinedTimezone != 0 ? s_userDefinedTimezone : s_exerciseDefaultTimezone;
|
||||
return true;
|
||||
}
|
||||
|
||||
char timezone()
|
||||
{
|
||||
return s_timezone;
|
||||
}
|
||||
char timezoneUserDefined()
|
||||
{
|
||||
return s_userDefinedTimezone;
|
||||
}
|
||||
char timezoneExerciseDefault()
|
||||
{
|
||||
return s_exerciseDefaultTimezone;
|
||||
}
|
||||
|
||||
bool isTimezoneValid(char tz)
|
||||
{
|
||||
tz = toupper(tz);
|
||||
return !(tz < 'A' || tz == 'J' || tz > 'Z');
|
||||
}
|
||||
|
||||
|
||||
|
||||
static DateTimeType s_dateTimeType = DDMMYYYY_Z_HHMMSS;
|
||||
static DisplayFormat s_defaultDisplayFormat = Long;
|
||||
|
||||
|
||||
void setDateTimeType(DateTimeType dtType)
|
||||
{
|
||||
s_dateTimeType = dtType;
|
||||
}
|
||||
|
||||
DateTimeType dateTimeType()
|
||||
{
|
||||
return s_dateTimeType;
|
||||
}
|
||||
|
||||
void setDefaultDisplayFormat(DisplayFormat dtFormat)
|
||||
{
|
||||
s_defaultDisplayFormat = dtFormat;
|
||||
}
|
||||
|
||||
DisplayFormat defaultDisplayFormat()
|
||||
{
|
||||
return s_defaultDisplayFormat;
|
||||
}
|
||||
|
||||
QString toString(const QDateTime &dt, DisplayFormat format, DateTimeType type)
|
||||
{
|
||||
if (format == Default)
|
||||
format = s_defaultDisplayFormat;
|
||||
static const QDateTime dtNull = QDateTime::fromSecsSinceEpoch(0);
|
||||
if (!dt.isValid() || dt == dtNull)
|
||||
return QString();
|
||||
|
||||
const QDateTime dateTime = dt.toUTC().addSecs(timezone2Hours(s_timezone) * 3600);
|
||||
QString ret;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DTG:
|
||||
{
|
||||
|
||||
|
||||
|
||||
QString str1;
|
||||
|
||||
if (format == Long)
|
||||
str1 = dateTime.toString(QLatin1String("dd hhmmss"));
|
||||
else if (format == TurboLong)
|
||||
str1 = dateTime.toString(QLatin1String("dd hhmmss.z"));
|
||||
else
|
||||
{
|
||||
ret = dateTime.toString(QLatin1String("ddhhmm")) + QLatin1Char(s_timezone);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
const int month = dateTime.date().month() - 1;
|
||||
const int year = dateTime.date().year() - 2000;
|
||||
ret = QStringLiteral("%1 %2 %3 %4")
|
||||
.arg(str1)
|
||||
.arg(QLatin1Char(s_timezone))
|
||||
.arg(months().at(month))
|
||||
.arg(year, 2, 10, QLatin1Char('0'));
|
||||
}
|
||||
break;
|
||||
case DDMMYYYY_HHMMSS_Z:
|
||||
{
|
||||
if (format == Long)
|
||||
ret = dateTime.toString(QLatin1String("dd.MM.yyyy HH:mm:ss")) + QLatin1Char(s_timezone);
|
||||
else
|
||||
ret = dateTime.toString(QLatin1String("dd.MM HH:mm")) + QLatin1Char(s_timezone);
|
||||
|
||||
}
|
||||
break;
|
||||
case DDMMYYYY_Z_HHMMSS:
|
||||
if (format == Long)
|
||||
ret = dateTime.toString(QLatin1String("dd.MM.yyyy "))
|
||||
+ QLatin1Char(s_timezone)
|
||||
+ dateTime.toString(QLatin1String(" HH:mm:ss"));
|
||||
else
|
||||
ret = dateTime.toString(QLatin1String("dd.MM "))
|
||||
+ QLatin1Char(s_timezone)
|
||||
+ dateTime.toString(QLatin1String(" HH:mm"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString toStringMSec(qint64 msecSinceEpoch, DisplayFormat format)
|
||||
{
|
||||
if (msecSinceEpoch <= 0)
|
||||
return QString();
|
||||
return toString(QDateTime::fromMSecsSinceEpoch(msecSinceEpoch), format);
|
||||
}
|
||||
|
||||
|
||||
static bool check24(const QChar *input, int *output)
|
||||
{
|
||||
const int i1 = input[0].unicode() - '0';
|
||||
const int i2 = input[1].unicode() - '0';
|
||||
if (i1 > 2)
|
||||
return false;
|
||||
if (i1 == 2 && i2 > 5)
|
||||
return false;
|
||||
if (output)
|
||||
*output = i1 * 10 + i2;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool check31(const QChar *input, int *output = nullptr)
|
||||
{
|
||||
const int i1 = input[0].unicode() - '0';
|
||||
const int i2 = input[1].unicode() - '0';
|
||||
if (i1 > 3)
|
||||
return false;
|
||||
if (i1 == 3 && i2 > 1)
|
||||
return false;
|
||||
if (output)
|
||||
*output = i1 * 10 + i2;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool check60(const QChar *input, int *output)
|
||||
{
|
||||
const int i1 = input[0].unicode() - '0';
|
||||
const int i2 = input[1].unicode() - '0';
|
||||
if (i1 > 5)
|
||||
return false;
|
||||
if (output)
|
||||
*output = i1 * 10 + i2;
|
||||
return true;
|
||||
}
|
||||
|
||||
static DTGValidation validate18(const QString &input, QDateTime &dt)
|
||||
{
|
||||
int hh, mm, ss;
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
if (!input[i].isDigit())
|
||||
return Invalid;
|
||||
}
|
||||
if (!check31(&input.data() [0]))
|
||||
return Invalid;
|
||||
|
||||
if (input[2] != QLatin1Char(' '))
|
||||
return Invalid;
|
||||
|
||||
if (input.length() == 7)
|
||||
{
|
||||
for (int i = 3; i < 7; ++i)
|
||||
{
|
||||
if (!input[i].isDigit())
|
||||
return Invalid;
|
||||
}
|
||||
return Intermediate;
|
||||
}
|
||||
for (int i = 3; i < 9; ++i)
|
||||
{
|
||||
if (!input[i].isDigit())
|
||||
return Invalid;
|
||||
}
|
||||
if (!check24(&input.data() [3], &hh))
|
||||
return Invalid;
|
||||
if (!check60(&input.data() [5], &mm))
|
||||
return Invalid;
|
||||
if (!check60(&input.data() [7], &ss))
|
||||
return Invalid;
|
||||
|
||||
if (input[9] != QLatin1Char(' '))
|
||||
return Invalid;
|
||||
|
||||
const QChar c = input[10];
|
||||
if (c < QLatin1Char('A') || c > QLatin1Char('Z'))
|
||||
return Invalid;
|
||||
if (c == QLatin1Char('J'))
|
||||
{
|
||||
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
const QString mon = input.mid(12, 3);
|
||||
int month = months().indexOf(mon);
|
||||
if (month < 0)
|
||||
{
|
||||
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
for (int i = 16; i < 18; ++i)
|
||||
{
|
||||
if (!input[i].isDigit())
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
|
||||
const int day = input.left(2).toInt();
|
||||
const int year = input.mid(16, 2).toInt() + 2000;
|
||||
dt = QDateTime(QDate(year, month + 1, day), QTime(hh, mm, ss), QTimeZone::utc());
|
||||
if (!dt.isValid())
|
||||
{
|
||||
|
||||
return Invalid;
|
||||
}
|
||||
dt = dt.addSecs(-timezone2Hours(c.toLatin1()) * 3600);
|
||||
|
||||
|
||||
return Acceptable;
|
||||
}
|
||||
|
||||
static DTGValidation validate7(const QString &input, QDateTime &dt)
|
||||
{
|
||||
int hh, mm;
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
if (!input[i].isDigit())
|
||||
return Invalid;
|
||||
}
|
||||
if (!check31(&input.data() [0]))
|
||||
return Invalid;
|
||||
if (!check24(&input.data() [2], &hh))
|
||||
return Invalid;
|
||||
if (!check60(&input.data() [4], &mm))
|
||||
return Invalid;
|
||||
|
||||
|
||||
const QChar c = input[6];
|
||||
if (c < QLatin1Char('A') || c > QLatin1Char('Z'))
|
||||
return Invalid;
|
||||
if (c == QLatin1Char('J'))
|
||||
{
|
||||
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
|
||||
const int day = input.left(2).toInt();
|
||||
const QDate curDate = QDate::currentDate();
|
||||
dt = QDateTime(QDate(curDate.year(), curDate.month(), day), QTime(hh, mm), QTimeZone::utc());
|
||||
if (!dt.isValid())
|
||||
{
|
||||
|
||||
return Invalid;
|
||||
}
|
||||
dt = dt.addSecs(-timezone2Hours(c.toLatin1()) * 3600);
|
||||
|
||||
|
||||
return Acceptable;
|
||||
}
|
||||
|
||||
QDateTime fromDTGString(const QString &str, bool *bOk)
|
||||
{
|
||||
if (bOk)
|
||||
*bOk = false;
|
||||
|
||||
QDateTime dt;
|
||||
if (str.length() == 7)
|
||||
{
|
||||
DTGValidation state = validate7(str, dt);
|
||||
if (state == Acceptable && bOk)
|
||||
*bOk = true;
|
||||
}
|
||||
else if (str.length() == 18)
|
||||
{
|
||||
DTGValidation state = validate18(str, dt);
|
||||
if (state == Acceptable && bOk)
|
||||
*bOk = true;
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
|
||||
DTGValidation validateString(const QString &str, QDateTime &dt)
|
||||
{
|
||||
const int len = str.length();
|
||||
if (len == 7 || len == 18)
|
||||
{
|
||||
|
||||
if (len == 18 || (str[2] == QLatin1Char(' ')))
|
||||
return validate18(str, dt);
|
||||
return validate7(str, dt);
|
||||
}
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
QStringList months()
|
||||
{
|
||||
return {
|
||||
QLatin1String("jan"), QLatin1String("feb"), QLatin1String("mar"),
|
||||
QLatin1String("apr"), QLatin1String("may"), QLatin1String("jun"),
|
||||
QLatin1String("jul"), QLatin1String("aug"), QLatin1String("sep"),
|
||||
QLatin1String("oct"), QLatin1String("nov"), QLatin1String("dec")
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
#include <QStringList>
|
||||
#include "ngltools_export.h"
|
||||
|
||||
class QDateTime;
|
||||
|
||||
|
||||
namespace DTG
|
||||
{
|
||||
|
||||
|
||||
|
||||
enum DateTimeType
|
||||
{
|
||||
DTG = 1,
|
||||
DDMMYYYY_HHMMSS_Z = 2,
|
||||
DDMMYYYY_Z_HHMMSS = 4
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
enum DisplayFormat
|
||||
{
|
||||
Short,
|
||||
Long,
|
||||
TurboLong,
|
||||
Default
|
||||
};
|
||||
|
||||
enum DTGValidation
|
||||
{
|
||||
Invalid,
|
||||
Intermediate,
|
||||
Acceptable
|
||||
};
|
||||
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT void setDateTimeType(DateTimeType dtType);
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT DateTimeType dateTimeType();
|
||||
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT void setDefaultDisplayFormat(DisplayFormat dtFormat);
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT DisplayFormat defaultDisplayFormat();
|
||||
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT QString toString(const QDateTime &dt, DisplayFormat format = Default, DateTimeType = dateTimeType());
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT QString toStringMSec(qint64 msecSinceEpoch, DisplayFormat format = Default);
|
||||
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT QDateTime fromDTGString(const QString &str, bool *bOk = nullptr);
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT DTGValidation validateString(const QString &str, QDateTime &dt);
|
||||
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT bool setTimezone(char tz, bool bUserDefinedZone);
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT char timezone();
|
||||
NGLTOOLS_EXPORT char timezoneUserDefined();
|
||||
NGLTOOLS_EXPORT char timezoneExerciseDefault();
|
||||
|
||||
NGLTOOLS_EXPORT bool isTimezoneValid(char tz);
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT int timezone2Hours(char tz, bool *bOk = nullptr);
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT int timezone2Secs(char tz, bool *bOk = nullptr);
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT QStringList months();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NGLTOOLS_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define NGLTOOLS_EXPORT
|
||||
# else
|
||||
# ifdef WIN32
|
||||
# ifdef MAKE_NGLTOOLS_LIB
|
||||
# define NGLTOOLS_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define NGLTOOLS_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
# else
|
||||
# define NGLTOOLS_EXPORT __attribute__((visibility("default")))
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
@@ -0,0 +1,290 @@
|
||||
|
||||
|
||||
|
||||
#include "ngltools_filesystem.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QSettings>
|
||||
#include <utility>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
|
||||
bool removeDirContentsRecursively(const QString &d, bool bAlsoDeleteBaseDir)
|
||||
{
|
||||
|
||||
QDir dir(d);
|
||||
if (!dir.exists())
|
||||
return false;
|
||||
|
||||
bool success = true;
|
||||
const QFileInfoList list = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries);
|
||||
for (const QFileInfo &fi : list)
|
||||
{
|
||||
bool ret = false;
|
||||
if (fi.isDir())
|
||||
{
|
||||
ret = removeDirContentsRecursively(fi.absoluteFilePath());
|
||||
if (!ret)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = dir.rmdir(fi.absoluteFilePath());
|
||||
if (!ret)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (fi.isFile() || fi.isSymLink())
|
||||
{
|
||||
ret = dir.remove(fi.fileName());
|
||||
if (!ret)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
success &= ret;
|
||||
}
|
||||
if (bAlsoDeleteBaseDir)
|
||||
success &= dir.rmpath(d);
|
||||
return success;
|
||||
}
|
||||
|
||||
bool copyDirContentsToDir(const QString &source, const QString &destination, bool sourceIsRelative)
|
||||
{
|
||||
QString srcPath(source);
|
||||
|
||||
if (sourceIsRelative)
|
||||
{
|
||||
QVector<QString> pathsToSearch = directories(FileType::ConfigFile);
|
||||
pathsToSearch.append(directories(FileType::ProjectConfigFile));
|
||||
for (const QString &basePath : std::as_const(pathsToSearch))
|
||||
{
|
||||
QString absolutePath = basePath + QLatin1Char('/') + source;
|
||||
if (QDir(absolutePath).exists())
|
||||
{
|
||||
srcPath = absolutePath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (srcPath.isEmpty())
|
||||
return false;
|
||||
}
|
||||
|
||||
QDir srcDir(srcPath);
|
||||
QDir dstDir(destination);
|
||||
|
||||
if (!dstDir.exists())
|
||||
{
|
||||
bool succ = dstDir.mkdir(destination);
|
||||
if (!succ)
|
||||
return false;
|
||||
}
|
||||
|
||||
const QFileInfoList dirList = srcDir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot);
|
||||
for (const QFileInfo &fi : dirList)
|
||||
{
|
||||
|
||||
if (!dstDir.exists())
|
||||
{
|
||||
bool succ = dstDir.mkdir(fi.fileName());
|
||||
if (!succ)
|
||||
return false;
|
||||
}
|
||||
bool succ = copyDirContentsToDir(fi.filePath(), dstDir.absolutePath() + QLatin1Char('/') + fi.fileName());
|
||||
if (!succ)
|
||||
return false;
|
||||
}
|
||||
|
||||
const QFileInfoList fileList = srcDir.entryInfoList(QDir::Files | QDir::Hidden);
|
||||
for (const QFileInfo &fi : fileList)
|
||||
{
|
||||
QString targetFileName = dstDir.absolutePath() + QLatin1Char('/') + fi.fileName();
|
||||
QFile targetFile(targetFileName);
|
||||
if (targetFile.exists())
|
||||
targetFile.remove();
|
||||
bool succ = QFile::copy(fi.absoluteFilePath(), targetFileName);
|
||||
if (!succ)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
qint64 getDirectorySize(const QString &dir)
|
||||
{
|
||||
QDir d(dir);
|
||||
qint64 ret = QFileInfo(dir).size();
|
||||
|
||||
const QFileInfoList dirList = d.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot);
|
||||
const QFileInfoList fileList = d.entryInfoList(QDir::Files | QDir::Hidden);
|
||||
|
||||
for (const QFileInfo &fi : dirList)
|
||||
ret += getDirectorySize(fi.absoluteFilePath());
|
||||
|
||||
for (const QFileInfo &fi : fileList)
|
||||
ret += fi.size();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool isAppInBuildBasePath()
|
||||
{
|
||||
bool ret = false;
|
||||
#ifdef BUILD_BASE_PATH
|
||||
const QString bbp(QString::fromLocal8Bit(BUILD_BASE_PATH));
|
||||
if (!bbp.isEmpty())
|
||||
ret = QCoreApplication::applicationDirPath().startsWith(bbp);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString projectConfigFileName()
|
||||
{
|
||||
return QLatin1String("lts-cc.conf");
|
||||
}
|
||||
|
||||
QString findProjectConfigFile()
|
||||
{
|
||||
return findFile(FileType::ProjectConfigFile, projectConfigFileName());
|
||||
}
|
||||
|
||||
static QString searchFileInDir(const QString &path, const QString &filename, bool bRecursive)
|
||||
{
|
||||
if (QFile::exists(path + QLatin1Char('/') + filename))
|
||||
return path + QLatin1Char('/') + filename;
|
||||
|
||||
if (!bRecursive)
|
||||
return QString();
|
||||
|
||||
const QDir d(path);
|
||||
const QStringList entryList = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
|
||||
for (const QString &entry : entryList)
|
||||
{
|
||||
const QString foundPath = searchFileInDir(path + QLatin1Char('/') + entry, filename, bRecursive);
|
||||
if (!foundPath.isEmpty())
|
||||
return foundPath;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString findFile(FileType fileType, const QString &filename)
|
||||
{
|
||||
const QFileInfo fi(filename);
|
||||
if (fi.isAbsolute())
|
||||
return fi.exists() ? filename : QString();
|
||||
const bool bRecursive = (fileType == FileType::ConfigFile);
|
||||
const QVector<QString> pathsToSearch = directories(fileType);
|
||||
for (const QString &path : pathsToSearch)
|
||||
{
|
||||
const QString foundPath = searchFileInDir(path, filename, bRecursive);
|
||||
if (!foundPath.isEmpty())
|
||||
return foundPath;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QVector<QString> directories(FileType fileType)
|
||||
{
|
||||
QVector<QString> pathsToSearch;
|
||||
switch (fileType)
|
||||
{
|
||||
case FileType::ProjectConfigFile:
|
||||
{
|
||||
#ifdef BUILD_BASE_PATH
|
||||
const QString bbp(QString::fromLocal8Bit(BUILD_BASE_PATH));
|
||||
if (!bbp.isEmpty())
|
||||
{
|
||||
|
||||
|
||||
|
||||
if (QCoreApplication::applicationDirPath().startsWith(bbp))
|
||||
pathsToSearch += bbp;
|
||||
}
|
||||
#endif
|
||||
pathsToSearch += QDir::homePath();
|
||||
#ifdef Q_OS_UNIX
|
||||
pathsToSearch += QLatin1String("/etc");
|
||||
#else
|
||||
pathsToSearch += QStringLiteral("C:/Rheinmetall/Lts/");
|
||||
pathsToSearch += QCoreApplication::applicationDirPath();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case FileType::ConfigFile:
|
||||
{
|
||||
#ifdef BUILD_BASE_PATH
|
||||
const QString bbp(QString::fromLocal8Bit(BUILD_BASE_PATH));
|
||||
if (!bbp.isEmpty())
|
||||
{
|
||||
|
||||
|
||||
|
||||
if (QCoreApplication::applicationDirPath().startsWith(bbp))
|
||||
pathsToSearch += bbp + QLatin1String("/share/Lts");
|
||||
}
|
||||
#endif
|
||||
pathsToSearch += QCoreApplication::applicationDirPath() + QLatin1String("/share/Lts");
|
||||
pathsToSearch += QCoreApplication::applicationDirPath() + QLatin1String("/../share/Lts");
|
||||
pathsToSearch += QDir::homePath() + QLatin1String("/share/Lts");
|
||||
#ifdef INSTALL_PREFIX
|
||||
pathsToSearch += QString::fromLocal8Bit(INSTALL_PREFIX) + QLatin1String("/share/Lts");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
return pathsToSearch;
|
||||
}
|
||||
QString findServiceXmlFile(const QString &serviceShortName)
|
||||
{
|
||||
return findFile(FileType::ConfigFile, serviceShortName + QLatin1String(".xml"));
|
||||
}
|
||||
|
||||
QString directory(FileType fileType, const QString &subdir)
|
||||
{
|
||||
const QVector<QString> pathsToSearch = directories(fileType);
|
||||
QFileInfo fi;
|
||||
for (const QString &path : pathsToSearch)
|
||||
{
|
||||
fi.setFile(path + QLatin1Char('/') + subdir);
|
||||
if (fi.isDir() && fi.exists() && fi.isReadable())
|
||||
return fi.absoluteFilePath() + QLatin1Char('/');
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString postgresExecutablePath(const QString &psqlProgram, QString &errStr)
|
||||
{
|
||||
errStr.clear();
|
||||
#ifdef Q_OS_LINUX
|
||||
return QStringLiteral("/usr/bin/") + psqlProgram;
|
||||
#else
|
||||
static QString s_postgresBinariesPath;
|
||||
if (s_postgresBinariesPath.isEmpty())
|
||||
{
|
||||
QSettings s(QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\PostgreSQL\\Installations"), QSettings::NativeFormat);
|
||||
const QStringList installations = s.childGroups();
|
||||
if (installations.isEmpty())
|
||||
{
|
||||
errStr = QStringLiteral("Could not find a valid PostgreSQL windows installation...");
|
||||
return psqlProgram;
|
||||
}
|
||||
if (installations.size() > 1)
|
||||
errStr = QStringLiteral("More than one PostgreSQL windows installation found - using the first one: %1").arg(installations.first());
|
||||
s.beginGroup(installations.first());
|
||||
const QString baseDir = s.value(QStringLiteral("Base Directory")).toString();
|
||||
if (baseDir.isEmpty() || !QDir(baseDir).exists())
|
||||
{
|
||||
errStr = QStringLiteral("Could not find a valid PostgreSQL windows installation... - Base Directory is empty or does not exist (%1)").arg(baseDir);
|
||||
return psqlProgram;
|
||||
}
|
||||
s_postgresBinariesPath = baseDir + QStringLiteral("/bin/");
|
||||
}
|
||||
return s_postgresBinariesPath + psqlProgram + QStringLiteral(".exe");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ngltools_export.h"
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QVector>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
NGLTOOLS_EXPORT bool removeDirContentsRecursively(const QString &d, bool bAlsoDeleteBaseDir = false);
|
||||
NGLTOOLS_EXPORT bool copyDirContentsToDir(const QString &source, const QString &destination, bool sourceIsRelative = false);
|
||||
NGLTOOLS_EXPORT qint64 getDirectorySize(const QString &dir);
|
||||
|
||||
|
||||
enum class FileType
|
||||
{
|
||||
ProjectConfigFile,
|
||||
ConfigFile
|
||||
};
|
||||
|
||||
NGLTOOLS_EXPORT bool isAppInBuildBasePath();
|
||||
NGLTOOLS_EXPORT QString projectConfigFileName();
|
||||
NGLTOOLS_EXPORT QString findProjectConfigFile();
|
||||
NGLTOOLS_EXPORT QString findFile(FileType fileType, const QString &filename);
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT QString findServiceXmlFile(const QString &serviceShortName);
|
||||
|
||||
NGLTOOLS_EXPORT QVector<QString> directories(FileType fileType);
|
||||
|
||||
NGLTOOLS_EXPORT QString directory(FileType fileType, const QString &subdir);
|
||||
|
||||
|
||||
NGLTOOLS_EXPORT QString postgresExecutablePath(const QString &psqlProgram, QString &errStr);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
|
||||
#include "ngltools_helpevent.h"
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
QEvent::Type NGLHelpEvent::sHelpEventId = (QEvent::Type)(-1);
|
||||
|
||||
void NGLHelpEvent::sendHelpEvent(const QString &helpContext)
|
||||
{
|
||||
NGLHelpEvent he(helpContext);
|
||||
QCoreApplication::sendEvent(qApp, &he);
|
||||
}
|
||||
|
||||
QEvent::Type NGLHelpEvent::helpEventId()
|
||||
{
|
||||
if(sHelpEventId < 0)
|
||||
sHelpEventId = (QEvent::Type)(QEvent::registerEventType());
|
||||
return sHelpEventId;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtCore/QString>
|
||||
#include "ngltools_export.h"
|
||||
|
||||
|
||||
|
||||
class NGLTOOLS_EXPORT NGLHelpEvent : public QEvent
|
||||
{
|
||||
protected:
|
||||
|
||||
|
||||
explicit NGLHelpEvent(const QString &helpContext)
|
||||
: QEvent(helpEventId())
|
||||
, mHelpContext(helpContext)
|
||||
{}
|
||||
public:
|
||||
|
||||
|
||||
QString helpContext() const { return mHelpContext; }
|
||||
|
||||
|
||||
static void sendHelpEvent(const QString &helpContext);
|
||||
|
||||
|
||||
static QEvent::Type helpEventId();
|
||||
|
||||
protected:
|
||||
QString mHelpContext;
|
||||
static QEvent::Type sHelpEventId;
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
#include <QObject>
|
||||
#include <QtTest>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "ngltools_dtg.h"
|
||||
|
||||
class NGLToolsQtSmokeTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void testDTG()
|
||||
{
|
||||
QDateTime now = QDateTime::currentDateTimeUtc();
|
||||
QString s = DTG::toString(now, DTG::Default, DTG::DTG);
|
||||
QVERIFY(!s.isEmpty());
|
||||
bool ok = false;
|
||||
QDateTime parsed = DTG::fromDTGString(s, &ok);
|
||||
QVERIFY(ok);
|
||||
QVERIFY(parsed.isValid());
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(NGLToolsQtSmokeTest)
|
||||
#include "NGLToolsQtSmokeTest.moc"
|
||||
Reference in new issue
Block a user