From 42defb3516a8b7f06c7b0fbc832332a4e60c0f86 Mon Sep 17 00:00:00 2001 From: Tobias Markmann Date: Fri, 29 Jul 2016 22:59:54 +0200 Subject: Enable better date formatting in the UI This adds the ability to provide more specific date formatting via the Translator interface. The default translator will use Boost's formatting capabilities. The QtTranslator use more localized and better readable formatting. Test-Information: Tested with Qt 5.5.1 on OS X 10.11.6. Checked that tooltips and presence text in new chat views show the new formatting. Change-Id: I90ff5ab8b31fb41f2dcbea2c40b8846c534c355f diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp index e36728a..41a34b9 100644 --- a/Swift/Controllers/Chat/ChatController.cpp +++ b/Swift/Controllers/Chat/ChatController.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include #include @@ -33,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -74,7 +74,7 @@ ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQ } Idle::ref idle; if (theirPresence && (idle = theirPresence->getPayload())) { - startMessage += str(format(QT_TRANSLATE_NOOP("", ", who has been idle since %1%")) % dateTimeToLocalString(idle->getSince())); + startMessage += str(format(QT_TRANSLATE_NOOP("", ", who has been idle since %1%")) % Swift::Translator::getInstance()->ptimeToHumanReadableString(idle->getSince())); } startMessage += ": " + statusShowTypeToFriendlyName(theirPresence ? theirPresence->getShow() : StatusShow::None); if (theirPresence && !theirPresence->getStatus().empty()) { @@ -466,7 +466,7 @@ std::string ChatController::getStatusChangeString(std::shared_ptr pres } Idle::ref idle; if ((idle = presence->getPayload())) { - response += str(format(QT_TRANSLATE_NOOP("", " and has been idle since %1%")) % dateTimeToLocalString(idle->getSince())); + response += str(format(QT_TRANSLATE_NOOP("", " and has been idle since %1%")) % Swift::Translator::getInstance()->ptimeToHumanReadableString(idle->getSince())); } if (!response.empty()) { diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp index a54c89e..b339bd0 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.cpp +++ b/Swift/Controllers/Chat/ChatControllerBase.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/Swift/Controllers/Roster/ContactRosterItem.cpp b/Swift/Controllers/Roster/ContactRosterItem.cpp index 0ad023a..71c5f8e 100644 --- a/Swift/Controllers/Roster/ContactRosterItem.cpp +++ b/Swift/Controllers/Roster/ContactRosterItem.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -34,7 +35,7 @@ StatusShow::Type ContactRosterItem::getSimplifiedStatusShow() const { switch (presence_ ? presence_->getShow() : StatusShow::None) { case StatusShow::Online: return StatusShow::Online; case StatusShow::Away: return StatusShow::Away; - case StatusShow::XA: return StatusShow::Away; + case StatusShow::XA: return StatusShow::Away; case StatusShow::FFC: return StatusShow::Online; case StatusShow::DND: return StatusShow::DND; case StatusShow::None: return StatusShow::None; @@ -48,22 +49,41 @@ std::string ContactRosterItem::getStatusText() const { } std::string ContactRosterItem::getIdleText() const { - Idle::ref idle = presence_ ? presence_->getPayload() : Idle::ref(); - if (!idle || idle->getSince().is_not_a_date_time()) { + boost::posix_time::ptime idleTime = getIdle(); + if (idleTime.is_not_a_date_time()) { return ""; } else { - return dateTimeToLocalString(idle->getSince()); + return dateTimeToLocalString(idleTime); + } +} + +boost::posix_time::ptime ContactRosterItem::getIdle() const { + Idle::ref idle = presence_ ? presence_->getPayload() : Idle::ref(); + if (idle) { + return idle->getSince(); + } + else { + return boost::posix_time::not_a_date_time; } } std::string ContactRosterItem::getOfflineSinceText() const { + boost::posix_time::ptime offlineSince = getOfflineSince(); + if (!offlineSince.is_not_a_date_time()) { + return dateTimeToLocalString(offlineSince); + } + return ""; +} + +boost::posix_time::ptime ContactRosterItem::getOfflineSince() const { + boost::posix_time::ptime offlineSince = boost::posix_time::not_a_date_time; if (presence_ && presence_->getType() == Presence::Unavailable) { boost::optional delay = presence_->getTimestamp(); if (delay) { - return dateTimeToLocalString(*delay); + offlineSince = delay.get(); } } - return ""; + return offlineSince; } void ContactRosterItem::setAvatarPath(const boost::filesystem::path& path) { diff --git a/Swift/Controllers/Roster/ContactRosterItem.h b/Swift/Controllers/Roster/ContactRosterItem.h index 2ffec09..37c3840 100644 --- a/Swift/Controllers/Roster/ContactRosterItem.h +++ b/Swift/Controllers/Roster/ContactRosterItem.h @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -27,6 +26,8 @@ namespace Swift { class GroupRosterItem; +class Presence; + class ContactRosterItem : public RosterItem { public: enum Feature { @@ -49,7 +50,9 @@ class ContactRosterItem : public RosterItem { StatusShow::Type getSimplifiedStatusShow() const; std::string getStatusText() const; std::string getIdleText() const; + boost::posix_time::ptime getIdle() const; std::string getOfflineSinceText() const; + boost::posix_time::ptime getOfflineSince() const; void setAvatarPath(const boost::filesystem::path& path); const boost::filesystem::path& getAvatarPath() const; const JID& getJID() const; @@ -82,7 +85,6 @@ class ContactRosterItem : public RosterItem { private: JID jid_; JID displayJID_; - boost::posix_time::ptime lastAvailableTime_; boost::filesystem::path avatarPath_; std::shared_ptr presence_; std::vector groups_; diff --git a/Swift/Controllers/Translator.cpp b/Swift/Controllers/Translator.cpp index b62fd28..f03c533 100644 --- a/Swift/Controllers/Translator.cpp +++ b/Swift/Controllers/Translator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Isode Limited. + * Copyright (c) 2011-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -8,12 +8,18 @@ #include +#include + namespace Swift { static struct DefaultTranslator : public Translator { virtual std::string translate(const std::string& text, const std::string&) { return text; } + + virtual std::string ptimeToHumanReadableString(const boost::posix_time::ptime& time) { + return dateTimeToLocalString(time); + } } defaultTranslator; Translator* Translator::translator = &defaultTranslator; diff --git a/Swift/Controllers/Translator.h b/Swift/Controllers/Translator.h index 5c52e9f..f37e059 100644 --- a/Swift/Controllers/Translator.h +++ b/Swift/Controllers/Translator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Isode Limited. + * Copyright (c) 2011-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -8,6 +8,8 @@ #include +#include + namespace Swift { class Translator { public: @@ -15,6 +17,8 @@ namespace Swift { virtual std::string translate(const std::string& text, const std::string& context) = 0; + virtual std::string ptimeToHumanReadableString(const boost::posix_time::ptime& time) = 0; + static void setInstance(Translator* translator); static Translator* getInstance() { diff --git a/Swift/QtUI/QtTranslator.h b/Swift/QtUI/QtTranslator.h index cdb259f..92abf77 100644 --- a/Swift/QtUI/QtTranslator.h +++ b/Swift/QtUI/QtTranslator.h @@ -7,9 +7,12 @@ #pragma once #include +#include #include +#include + class QtTranslator : public Swift::Translator { public: QtTranslator() { @@ -22,4 +25,13 @@ class QtTranslator : public Swift::Translator { return std::string(QCoreApplication::translate(context.c_str(), text.c_str(), 0, QCoreApplication::UnicodeUTF8).toUtf8()); #endif } + + virtual std::string ptimeToHumanReadableString(const boost::posix_time::ptime& time) { + return Q2PSTRING(QDateTime::fromTime_t(posixTimeToTimeT(time)).toString(Qt::SystemLocaleLongDate)); + } + + private: + static std::time_t posixTimeToTimeT(boost::posix_time::ptime pt) { + return std::time_t((pt - boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_seconds()); + } }; diff --git a/Swift/QtUI/Roster/RosterTooltip.cpp b/Swift/QtUI/Roster/RosterTooltip.cpp index 8ecd276..8d467fd 100644 --- a/Swift/QtUI/Roster/RosterTooltip.cpp +++ b/Swift/QtUI/Roster/RosterTooltip.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -93,15 +94,17 @@ QString RosterTooltip::buildDetailedTooltip(ContactRosterItem* contact, QtScaled QString statusMessage = contact->getStatusText().empty() ? QObject::tr("(No message)") : P2QSTRING(contact->getStatusText()); - QString idleString = P2QSTRING(contact->getIdleText()); - if (!idleString.isEmpty()) { - idleString = QObject::tr("Idle since %1").arg(idleString); + boost::posix_time::ptime idleTime = contact->getIdle(); + QString idleString; + if (!idleTime.is_not_a_date_time()) { + idleString = QObject::tr("Idle since %1").arg(P2QSTRING(Swift::Translator::getInstance()->ptimeToHumanReadableString(idleTime))); idleString = htmlEscape(idleString) + "
"; } - QString lastSeen = P2QSTRING(contact->getOfflineSinceText()); - if (!lastSeen.isEmpty()) { - lastSeen = QObject::tr("Last seen %1").arg(lastSeen); + boost::posix_time::ptime lastSeenTime = contact->getOfflineSince(); + QString lastSeen; + if (!lastSeenTime.is_not_a_date_time()) { + lastSeen = QObject::tr("Last seen %1").arg(P2QSTRING(Swift::Translator::getInstance()->ptimeToHumanReadableString(lastSeenTime))); lastSeen = htmlEscape(lastSeen) + "
"; } -- cgit v0.10.2-6-g49f6