Adds initial intermediate qt6 porting state

This commit is contained in:
torsten committed 2026-08-17 17:54:56 +02:00
1 parent 99136e9460
commit d176b5e0d7
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"