// Check if we got a commit hash
if (!QString(GIT_HEAD).isEmpty()) {
buildInfo.commitHash = GIT_HEAD;
- QDateTime date;
-#if QT_VERSION >= 0x050800
- date.setSecsSinceEpoch(GIT_COMMIT_DATE);
-#else
- // toSecsSinceEpoch() was added in Qt 5.8. Manually downconvert to seconds for now.
- // See https://doc.qt.io/qt-5/qdatetime.html#toMSecsSinceEpoch
- // Warning generated if not converting the 1000 to a qint64 first.
- date.setMSecsSinceEpoch(GIT_COMMIT_DATE * (qint64)1000);
-#endif
- buildInfo.commitDate = date.toString();
+ // Set to Unix epoch, wrapped as a string for backwards-compatibility
+ buildInfo.commitDate = QString::number(GIT_COMMIT_DATE);
}
else if (!QString(DIST_HASH).contains("Format")) {
buildInfo.commitHash = DIST_HASH;
+ // Leave as Unix epoch if set as Unix epoch, but don't force this for
+ // backwards-compatibility with existing packaging/release tools that might set strings.
buildInfo.commitDate = QString(DIST_DATE);
}
return matches || (invertedRuleFound && !normalRuleFound);
}
}
+
+
+QString tryFormatUnixEpoch(const QString &possibleEpochDate)
+{
+ // Does the string resemble a Unix epoch? Parse as 64-bit time
+ qint64 secsSinceEpoch = possibleEpochDate.toLongLong();
+ if (secsSinceEpoch == 0) {
+ // Parsing either failed, or '0' was sent. No need to distinguish; either way, it's not
+ // useful as epoch.
+ // See https://doc.qt.io/qt-5/qstring.html#toLongLong
+ return possibleEpochDate;
+ }
+
+ // Time checks out, parse it
+ QDateTime date;
+#if QT_VERSION >= 0x050800
+ date.setSecsSinceEpoch(secsSinceEpoch);
+#else
+ // toSecsSinceEpoch() was added in Qt 5.8. Manually downconvert to seconds for now.
+ // See https://doc.qt.io/qt-5/qdatetime.html#toMSecsSinceEpoch
+ date.setMSecsSinceEpoch(secsSinceEpoch * 1000);
+#endif
+
+ // Return the localized date/time
+ return date.toString();
+}
*/
bool scopeMatch(const QString &string, const QString &scopeRule,
const bool &isRegEx = false, const bool &isCaseSensitive = false);
+
+/**
+ * Try to localize a given date/time in seconds from Unix epoch, pass through string if invalid
+ *
+ * Allows compatibility with date/time fields that may or may not be in Unix epoch format,
+ * localizing if possible, leaving alone if not.
+ *
+ * @param possibleEpochDate Date/time that might be in seconds since Unix epoch format
+ * @return Localized date/time if parse succeeded, otherwise the source string
+ */
+QString tryFormatUnixEpoch(const QString &possibleEpochDate);
void CoreSessionEventProcessor::handleCtcpVersion(CtcpEvent *e)
{
- e->setReply(QString("Quassel IRC %1 (built on %2) -- https://www.quassel-irc.org")
- .arg(Quassel::buildInfo().plainVersionString).arg(Quassel::buildInfo().commitDate));
+ // Deliberately do not translate project name
+ e->setReply(QString("Quassel IRC %1 (version date %2) -- https://www.quassel-irc.org")
+ .arg(Quassel::buildInfo().plainVersionString)
+ .arg(Quassel::buildInfo().commitDate.isEmpty() ?
+ "unknown" : tryFormatUnixEpoch(Quassel::buildInfo().commitDate)));
}
#include "aboutdata.h"
#include "icon.h"
#include "quassel.h"
+#include "util.h"
AboutDlg::AboutDlg(QWidget *parent)
: QDialog(parent)
ui.setupUi(this);
ui.quasselLogo->setPixmap(QPixmap{":/pics/quassel-64.svg"}); // don't let the icon theme affect our logo here
- ui.versionLabel->setText(QString(tr("<b>Version:</b> %1<br><b>Version date:</b> %2<br><b>Protocol version:</b> %3"))
- .arg(Quassel::buildInfo().fancyVersionString)
- .arg(Quassel::buildInfo().commitDate)
- .arg(Quassel::buildInfo().protocolVersion));
+ QString versionDate;
+ if (Quassel::buildInfo().commitDate.isEmpty()) {
+ // This shouldn't happen, but sometimes the packaging environment cannot set a proper
+ // date/time. Add a fallback just in case.
+ versionDate = QString("<i>%1</i>").arg(tr("Unknown date"));
+ }
+ else {
+ versionDate = tryFormatUnixEpoch(Quassel::buildInfo().commitDate);
+ }
+ ui.versionLabel->setText(QString(tr("<b>Version:</b> %1<br>"
+ "<b>Version date:</b> %2<br>"
+ "<b>Protocol version:</b> %3"))
+ .arg(Quassel::buildInfo().fancyVersionString)
+ .arg(versionDate)
+ .arg(Quassel::buildInfo().protocolVersion));
ui.aboutTextBrowser->setHtml(about());
ui.authorTextBrowser->setHtml(authors());
ui.contributorTextBrowser->setHtml(contributors());
#include "bufferwidget.h"
#include "client.h"
#include "icon.h"
+#include "util.h"
CoreInfoDlg::CoreInfoDlg(QWidget *parent) : QDialog(parent) {
ui.setupUi(this);
} else {
ui.labelCoreVersion->setText(coreInfo["quasselVersion"].toString());
// "BuildDate" for compatibility
- ui.labelCoreVersionDate->setText(coreInfo["quasselBuildDate"].toString());
+ if (coreInfo["quasselBuildDate"].toString().isEmpty()) {
+ ui.labelCoreVersionDate->setText(QString("<i>%1</i>").arg(tr("Unknown date")));
+ }
+ else {
+ ui.labelCoreVersionDate->setText(
+ tryFormatUnixEpoch(coreInfo["quasselBuildDate"].toString()));
+ }
ui.labelClientCount->setNum(coreInfo["sessionConnectedClients"].toInt());
}
#include "client.h"
#include "coresessionwidget.h"
+#include "util.h"
CoreSessionWidget::CoreSessionWidget(QWidget *parent)
ui.sessionGroup->setTitle(map["remoteAddress"].toString());
ui.labelLocation->setText(map["location"].toString());
ui.labelClient->setText(map["clientVersion"].toString());
- ui.labelVersionDate->setText(map["clientVersionDate"].toString());
+ if (map["clientVersionDate"].toString().isEmpty()) {
+ ui.labelVersionDate->setText(QString("<i>%1</i>").arg(tr("Unknown date")));
+ }
+ else {
+ ui.labelVersionDate->setText(tryFormatUnixEpoch(map["clientVersionDate"].toString()));
+ }
ui.labelUptime->setText(map["connectedSince"].toDateTime().toLocalTime().toString(Qt::DateFormat::SystemLocaleShortDate));
if (map["location"].toString().isEmpty()) {
ui.labelLocation->hide();
// Determined from Git
#define GIT_HEAD "@GIT_HEAD@"
#define GIT_DESCRIBE "@GIT_DESCRIBE@"
+// Unix epoch in seconds
#define GIT_COMMIT_DATE @GIT_COMMIT_DATE@
// Will be substituted in official tarballs
#define DIST_HASH "$Format:%H$"
+// Unix epoch in seconds
#define DIST_DATE "$Format:%at$"