From 5c3ba8460a9784acb784337a2c11b5175fd7c011 Mon Sep 17 00:00:00 2001 From: "Javier S. Pedro" Date: Wed, 1 May 2013 02:42:50 +0200 Subject: rewrite date/time formatting --- board.cpp | 81 +++++++++++++++++++++++++++++++++---------------------- board.h | 14 ++++++++-- forummodel.cpp | 7 ++--- forummodel.h | 2 +- qml/ForumPage.qml | 2 +- topicmodel.cpp | 7 +++-- 6 files changed, 72 insertions(+), 41 deletions(-) diff --git a/board.cpp b/board.cpp index 8f7c0cb..329626f 100644 --- a/board.cpp +++ b/board.cpp @@ -226,41 +226,58 @@ QString Board::parseSmilies(QString text) const return text; } -QString Board::renderHumanDate(const QDateTime &dateTime, bool monthOnly) -{ - QDate date = dateTime.toLocalTime().date(); - QDate today = QDate::currentDate(); - if (date == today) { - return tr("Today"); - } else if (date.daysTo(today) == 1) { - return tr("Yesterday"); - } else if (date.daysTo(today) < 5) { - return QDate::longDayName(date.dayOfWeek(), QDate::StandaloneFormat); - } else if (monthOnly && date.daysTo(today) < date.daysInYear()) { - return QDate::longMonthName(date.month(), QDate::StandaloneFormat); - } else if (monthOnly) { - return QString::number(date.year()); - } else { - return date.toString(Qt::DefaultLocaleShortDate); - } -} - -QString Board::renderHumanDateTime(const QDateTime &dateTime) +QString Board::formatDateTime(const QDateTime &dateTime, DateTimePrecisionOptions precision) const { const QDateTime now = QDateTime::currentDateTime(); - QDateTime localDateTime = dateTime.toLocalTime(); - const int secs = localDateTime.secsTo(now); - if (secs < 1) { - return tr("Just now"); - } else if (secs < 60) { - return tr("%n second(s) ago", 0, secs); - } else if (secs < 3600) { - int mins = (secs + 10) / 60; // + 10 to round a bit - return tr("%n minute(s) ago", 0, mins); - } else if (localDateTime.daysTo(now) < 1) { - return localDateTime.time().toString(Qt::DefaultLocaleShortDate); + const QDateTime ldt = dateTime.toLocalTime(); + const int secs = ldt.secsTo(now); + const int days = ldt.daysTo(now); + + if (precision & RelativeTime) { + if (secs < 1) { + return tr("Just now"); + } else if (secs < 60) { + return tr("%n second(s) ago", 0, secs); + } else if (secs < 3600) { + int mins = (secs + 10) / 60; // + 10 to round a bit + return tr("%n minute(s) ago", 0, mins); + } + // Fall through + } + if (precision & (TodayYesterday | RelativeDate)) { + if (precision & ShowTime) { + const QString time = ldt.time().toString(Qt::DefaultLocaleShortDate); + if (days < 1) { + return tr("Today %1").arg(time); + } else if (days <= 1) { + return tr("Yesterday %1").arg(time); + } + } else { + if (days < 1) { + return tr("Today"); + } else if (days <= 1) { + return tr("Yesterday"); + } + } + } + if (precision & RelativeDate) { + if (days < 7) { + const int dayOfWeek = ldt.date().dayOfWeek(); + QString name = QDate::longDayName(dayOfWeek, QDate::StandaloneFormat); + name[0] = name[0].toUpper(); + return name; + } else if (days < 30) { + return tr("%n week(s) ago", 0, days / 7); + } else if (days < 365) { + return tr("%n month(s) ago", 0, days / 30); + } else { + return tr("%n year(s) ago", 0, days / 365); + } + } + if (precision & ShowTime) { + return ldt.toString(Qt::DefaultLocaleShortDate); } else { - return localDateTime.toString(Qt::DefaultLocaleShortDate); + return ldt.date().toString(Qt::DefaultLocaleShortDate); } } diff --git a/board.h b/board.h index c38bd48..0cab052 100644 --- a/board.h +++ b/board.h @@ -22,6 +22,7 @@ class Board : public QObject Q_PROPERTY(bool loggedIn READ loggedIn NOTIFY loggedInChanged) Q_PROPERTY(int rootForumId READ rootForumId CONSTANT) Q_ENUMS(TopicType) + Q_FLAGS(DateTimePrecisionOptions) public: explicit Board(QObject *parent = 0); @@ -34,6 +35,14 @@ public: Announcement = 2 }; + enum DateTimePrecisionOption { + ShowTime = 1 << 0, + RelativeTime = 1 << 1, // "n second(s) ago" instead of "Today HH:MM" + TodayYesterday = 1 << 2, // "Today", "Yesterday" and "Today HH:MM" if ShowTime + RelativeDate = 1 << 3 // "n week(s) ago", incompatible with ShowTime + }; + Q_DECLARE_FLAGS(DateTimePrecisionOptions, DateTimePrecisionOption) + static const QLatin1String CURRENT_DB_VERSION; bool busy() const; @@ -68,8 +77,7 @@ public: QString bbcodeToRichText(QString text) const; QString parseSmilies(QString text) const; - Q_INVOKABLE QString renderHumanDate(const QDateTime& dateTime, bool monthOnly = false); - Q_INVOKABLE QString renderHumanDateTime(const QDateTime& dateTime); + Q_INVOKABLE QString formatDateTime(const QDateTime& dateTime, DateTimePrecisionOptions precision) const; public slots: void cancelAllActions(); @@ -139,6 +147,8 @@ private: QRegExp _smilieRegexp; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(Board::DateTimePrecisionOptions) + inline bool Board::busy() const { return !_queue.empty(); diff --git a/forummodel.cpp b/forummodel.cpp index 73482e4..193df46 100644 --- a/forummodel.cpp +++ b/forummodel.cpp @@ -18,7 +18,7 @@ ForumModel::ForumModel(QObject *parent) : roles[TopicTypeRole] = QByteArray("topicType"); roles[LastReplyTimeRole] = QByteArray("lastReplyTime"); roles[NumRepliesRole] = QByteArray("numReplies"); - roles[HumanDateRole] = QByteArray("humanDate"); + roles[RelativeDateRole] = QByteArray("relativeDate"); roles[UnreadRole] = QByteArray("unread"); setRoleNames(roles); } @@ -99,14 +99,15 @@ QVariant ForumModel::data(const QModelIndex &index, int role) const return _data[row].last_reply_time; case NumRepliesRole: return _data[row].num_replies; - case HumanDateRole: + case RelativeDateRole: switch (_data[row].type) { case Board::Announcement: return tr("Announcement"); case Board::Sticky: return tr("Sticky"); default: - return _board->renderHumanDate(_data[row].last_reply_time, true); + return _board->formatDateTime(_data[row].last_reply_time, + Board::RelativeDate); } case UnreadRole: return _data[row].unread; diff --git a/forummodel.h b/forummodel.h index 10afa86..4d55c3f 100644 --- a/forummodel.h +++ b/forummodel.h @@ -24,7 +24,7 @@ public: TopicTypeRole, LastReplyTimeRole, NumRepliesRole, - HumanDateRole, + RelativeDateRole, UnreadRole }; diff --git a/qml/ForumPage.qml b/qml/ForumPage.qml index e2e263f..b3dc40c 100644 --- a/qml/ForumPage.qml +++ b/qml/ForumPage.qml @@ -54,7 +54,7 @@ Page { forumId: forumPage.forumId } - section.property: "humanDate" + section.property: "relativeDate" section.criteria: ViewSection.FullString section.delegate: GroupHeader { width: parent.width diff --git a/topicmodel.cpp b/topicmodel.cpp index 36fc4c0..abfd04b 100644 --- a/topicmodel.cpp +++ b/topicmodel.cpp @@ -132,9 +132,12 @@ QVariant TopicModel::data(const QModelIndex &index, int role) const case DateTimeRole: return _data[row].time; case HumanDateRole: - return _board->renderHumanDate(_data[row].time); + return _board->formatDateTime(_data[row].time, + Board::RelativeDate); case HumanTimeRole: - return _board->renderHumanDateTime(_data[row].time); + return _board->formatDateTime(_data[row].time, + Board::ShowTime | Board::RelativeTime | + Board::TodayYesterday); case UnreadRole: return _firstUnread >= 0 && row >= _firstUnread; } -- cgit v1.2.3