Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duration #11708

Merged
merged 2 commits into from
Jun 19, 2024
Merged

Duration #11708

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 17 additions & 29 deletions src/common/utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,46 +199,36 @@ qint64 Utility::qDateTimeToTime_t(const QDateTime &t)
}

namespace {
struct Period
constexpr struct
{
const char *name;
quint64 msec;

QString description(quint64 value) const
{
return QCoreApplication::translate("Utility", name, nullptr, value);
}
};
// QTBUG-3945 and issue #4855: QT_TRANSLATE_NOOP does not work with plural form because lupdate
// limitation unless we fake more arguments
// (it must be in the form ("context", "source", "comment", n)
#undef QT_TRANSLATE_NOOP
#define QT_TRANSLATE_NOOP(ctx, str, ...) str
Q_DECL_CONSTEXPR Period periods[] = {
{ QT_TRANSLATE_NOOP("Utility", "%n year(s)", 0, _), 365 * 24 * 3600 * 1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%n month(s)", 0, _), 30 * 24 * 3600 * 1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%n day(s)", 0, _), 24 * 3600 * 1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%n hour(s)", 0, _), 3600 * 1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%n minute(s)", 0, _), 60 * 1000LL },
{ QT_TRANSLATE_NOOP("Utility", "%n second(s)", 0, _), 1000LL },
{ nullptr, 0 }
const char *const name;
const std::chrono::milliseconds msec;
QString description(int value) const { return QCoreApplication::translate("Utility", name, nullptr, value); }
} periods[] = {
{QT_TRANSLATE_N_NOOP("Utility", "%n year(s)"), 24h * 365},
{QT_TRANSLATE_N_NOOP("Utility", "%n month(s)"), 24h * 30},
{QT_TRANSLATE_N_NOOP("Utility", "%n day(s)"), 24h},
{QT_TRANSLATE_N_NOOP("Utility", "%n hour(s)"), 1h},
{QT_TRANSLATE_N_NOOP("Utility", "%n minute(s)"), 1min},
{QT_TRANSLATE_N_NOOP("Utility", "%n second(s)"), 1s},
{nullptr, {}},
};
} // anonymous namespace

QString Utility::durationToDescriptiveString2(quint64 msecs)
QString Utility::durationToDescriptiveString2(std::chrono::milliseconds msecs)
{
int p = 0;
while (periods[p + 1].name && msecs < periods[p].msec) {
p++;
}

auto firstPart = periods[p].description(int(msecs / periods[p].msec));
const QString firstPart = periods[p].description(static_cast<int>(msecs / periods[p].msec));

if (!periods[p + 1].name) {
return firstPart;
}

quint64 secondPartNum = qRound(double(msecs % periods[p].msec) / periods[p + 1].msec);
const quint64 secondPartNum = qRound(static_cast<double>(msecs.count() % periods[p].msec.count()) / periods[p + 1].msec.count());

if (secondPartNum == 0) {
return firstPart;
Expand All @@ -247,15 +237,13 @@ QString Utility::durationToDescriptiveString2(quint64 msecs)
return QCoreApplication::translate("Utility", "%1 %2").arg(firstPart, periods[p + 1].description(secondPartNum));
}

QString Utility::durationToDescriptiveString1(quint64 msecs)
QString Utility::durationToDescriptiveString1(std::chrono::milliseconds msecs)
{
int p = 0;
while (periods[p + 1].name && msecs < periods[p].msec) {
p++;
}

quint64 amount = qRound(double(msecs) / periods[p].msec);
return periods[p].description(amount);
return periods[p].description(qRound(static_cast<double>(msecs.count()) / periods[p].msec.count()));
}

QString Utility::fileNameForGuiUse(const QString &fName)
Expand Down
6 changes: 3 additions & 3 deletions src/common/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ OCSYNC_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcUtility)

/**
* @brief Convert milliseconds duration to human readable string.
* @param quint64 msecs the milliseconds to convert to string.
* @param msecs the milliseconds to convert to string.
* @return an HMS representation of the milliseconds value.
*
* durationToDescriptiveString1 describes the duration in a single
Expand All @@ -105,8 +105,8 @@ OCSYNC_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcUtility)
* durationToDescriptiveString2 uses two units where possible, so
* "5 minutes 43 seconds" or "1 month 3 days".
*/
OCSYNC_EXPORT QString durationToDescriptiveString1(quint64 msecs);
OCSYNC_EXPORT QString durationToDescriptiveString2(quint64 msecs);
OCSYNC_EXPORT QString durationToDescriptiveString1(std::chrono::milliseconds msecs);
OCSYNC_EXPORT QString durationToDescriptiveString2(std::chrono::milliseconds msecs);

/**
* @brief hasDarkSystray - determines whether the systray is dark or light.
Expand Down
2 changes: 1 addition & 1 deletion src/gui/folderstatusmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ namespace {
.arg(s1, s2)
.arg(currentFile)
.arg(totalFileCount)
.arg(Utility::durationToDescriptiveString1(progress.totalProgress().estimatedEta));
.arg(Utility::durationToDescriptiveString1(std::chrono::milliseconds(progress.totalProgress().estimatedEta)));

} else {
//: Example text: "12 MB of 345 MB, file 6 of 7"
Expand Down
4 changes: 2 additions & 2 deletions src/gui/owncloudgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,7 @@ void ownCloudGui::slotUpdateProgress(Folder *folder, const ProgressInfo &progres
msg = tr("Syncing %1 of %2 (%3 left)")
.arg(currentFile)
.arg(totalFileCount)
.arg(Utility::durationToDescriptiveString2(progress.totalProgress().estimatedEta));
.arg(Utility::durationToDescriptiveString2(std::chrono::milliseconds(progress.totalProgress().estimatedEta)));
} else {
msg = tr("Syncing %1 of %2")
.arg(currentFile)
Expand All @@ -791,7 +791,7 @@ void ownCloudGui::slotUpdateProgress(Folder *folder, const ProgressInfo &progres
QString msg;
if (progress.trustEta()) {
msg = tr("Syncing %1 (%2 left)")
.arg(totalSizeStr, Utility::durationToDescriptiveString2(progress.totalProgress().estimatedEta));
.arg(totalSizeStr, Utility::durationToDescriptiveString2(std::chrono::milliseconds(progress.totalProgress().estimatedEta)));
} else {
msg = tr("Syncing %1")
.arg(totalSizeStr);
Expand Down
2 changes: 1 addition & 1 deletion src/libsync/syncengine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ bool SyncEngine::checkErrorBlacklisting(SyncFileItem &item)
} else {
item._status = SyncFileItem::BlacklistedError;

auto waitSecondsStr = Utility::durationToDescriptiveString1(1000 * waitSeconds);
auto waitSecondsStr = Utility::durationToDescriptiveString1(std::chrono::seconds(waitSeconds));
item._errorString = tr("%1 (skipped due to earlier error, trying again in %2)").arg(entry._errorString, waitSecondsStr);

if (entry._errorCategory == SyncJournalErrorBlacklistRecord::Category::InsufficientRemoteStorage) {
Expand Down
60 changes: 29 additions & 31 deletions test/testutility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "common/filesystembase.h"
#include "common/utility.h"

using namespace std::chrono_literals;

using namespace OCC::Utility;

namespace OCC {
Expand Down Expand Up @@ -67,38 +69,34 @@ private Q_SLOTS:
QLocale::setDefault(QLocale(QStringLiteral("C")));
//NOTE: in order for the plural to work we would need to load the english translation

quint64 sec = 1000;
quint64 hour = 3600 * sec;

QDateTime current = QDateTime::currentDateTimeUtc();

QCOMPARE(durationToDescriptiveString2(0), QString::fromLatin1("0 second(s)"));
QCOMPARE(durationToDescriptiveString2(5), QString::fromLatin1("0 second(s)"));
QCOMPARE(durationToDescriptiveString2(1000), QString::fromLatin1("1 second(s)"));
QCOMPARE(durationToDescriptiveString2(1005), QString::fromLatin1("1 second(s)"));
QCOMPARE(durationToDescriptiveString2(56123), QString::fromLatin1("56 second(s)"));
QCOMPARE(durationToDescriptiveString2(90 * sec), QString::fromLatin1("1 minute(s) 30 second(s)"));
QCOMPARE(durationToDescriptiveString2(3 * hour), QString::fromLatin1("3 hour(s)"));
QCOMPARE(durationToDescriptiveString2(3 * hour + 20 * sec), QString::fromLatin1("3 hour(s)"));
QCOMPARE(durationToDescriptiveString2(3 * hour + 70 * sec), QString::fromLatin1("3 hour(s) 1 minute(s)"));
QCOMPARE(durationToDescriptiveString2(3 * hour + 100 * sec), QString::fromLatin1("3 hour(s) 2 minute(s)"));
QCOMPARE(durationToDescriptiveString2(current.msecsTo(current.addYears(4).addMonths(5).addDays(2).addSecs(23 * 60 * 60))),
const QDateTime current = QDateTime::currentDateTimeUtc();

QCOMPARE(durationToDescriptiveString2(0ms), QString::fromLatin1("0 second(s)"));
QCOMPARE(durationToDescriptiveString2(5ms), QString::fromLatin1("0 second(s)"));
QCOMPARE(durationToDescriptiveString2(1s), QString::fromLatin1("1 second(s)"));
QCOMPARE(durationToDescriptiveString2(1005ms), QString::fromLatin1("1 second(s)"));
QCOMPARE(durationToDescriptiveString2(56123ms), QString::fromLatin1("56 second(s)"));
QCOMPARE(durationToDescriptiveString2(90s), QString::fromLatin1("1 minute(s) 30 second(s)"));
QCOMPARE(durationToDescriptiveString2(3h), QString::fromLatin1("3 hour(s)"));
QCOMPARE(durationToDescriptiveString2(3h + 20s), QString::fromLatin1("3 hour(s)"));
QCOMPARE(durationToDescriptiveString2(3h + 70s), QString::fromLatin1("3 hour(s) 1 minute(s)"));
QCOMPARE(durationToDescriptiveString2(3h + 100s), QString::fromLatin1("3 hour(s) 2 minute(s)"));
QCOMPARE(durationToDescriptiveString2(current.addYears(4).addMonths(5).addDays(2).addSecs(23 * 60 * 60) - current),
QString::fromLatin1("4 year(s) 5 month(s)"));
QCOMPARE(durationToDescriptiveString2(current.msecsTo(current.addDays(2).addSecs(23 * 60 * 60))), QString::fromLatin1("2 day(s) 23 hour(s)"));

QCOMPARE(durationToDescriptiveString1(0), QString::fromLatin1("0 second(s)"));
QCOMPARE(durationToDescriptiveString1(5), QString::fromLatin1("0 second(s)"));
QCOMPARE(durationToDescriptiveString1(1000), QString::fromLatin1("1 second(s)"));
QCOMPARE(durationToDescriptiveString1(1005), QString::fromLatin1("1 second(s)"));
QCOMPARE(durationToDescriptiveString1(56123), QString::fromLatin1("56 second(s)"));
QCOMPARE(durationToDescriptiveString1(90 * sec), QString::fromLatin1("2 minute(s)"));
QCOMPARE(durationToDescriptiveString1(3 * hour), QString::fromLatin1("3 hour(s)"));
QCOMPARE(durationToDescriptiveString1(3 * hour + 20 * sec), QString::fromLatin1("3 hour(s)"));
QCOMPARE(durationToDescriptiveString1(3 * hour + 70 * sec), QString::fromLatin1("3 hour(s)"));
QCOMPARE(durationToDescriptiveString1(3 * hour + 100 * sec), QString::fromLatin1("3 hour(s)"));
QCOMPARE(
durationToDescriptiveString1(current.msecsTo(current.addYears(4).addMonths(5).addDays(2).addSecs(23 * 60 * 60))), QString::fromLatin1("4 year(s)"));
QCOMPARE(durationToDescriptiveString1(current.msecsTo(current.addDays(2).addSecs(23 * 60 * 60))), QString::fromLatin1("3 day(s)"));
QCOMPARE(durationToDescriptiveString2(current.addDays(2).addSecs(23 * 60 * 60) - current), QString::fromLatin1("2 day(s) 23 hour(s)"));

QCOMPARE(durationToDescriptiveString1(0s), QString::fromLatin1("0 second(s)"));
QCOMPARE(durationToDescriptiveString1(5ms), QString::fromLatin1("0 second(s)"));
QCOMPARE(durationToDescriptiveString1(1s), QString::fromLatin1("1 second(s)"));
QCOMPARE(durationToDescriptiveString1(1005ms), QString::fromLatin1("1 second(s)"));
QCOMPARE(durationToDescriptiveString1(56123ms), QString::fromLatin1("56 second(s)"));
QCOMPARE(durationToDescriptiveString1(90s), QString::fromLatin1("2 minute(s)"));
QCOMPARE(durationToDescriptiveString1(3h), QString::fromLatin1("3 hour(s)"));
QCOMPARE(durationToDescriptiveString1(3h + 20s), QString::fromLatin1("3 hour(s)"));
QCOMPARE(durationToDescriptiveString1(3h + 70s), QString::fromLatin1("3 hour(s)"));
QCOMPARE(durationToDescriptiveString1(3h + 100s), QString::fromLatin1("3 hour(s)"));
QCOMPARE(durationToDescriptiveString1(current.addYears(4).addMonths(5).addDays(2).addSecs(23 * 60 * 60) - current), QString::fromLatin1("4 year(s)"));
QCOMPARE(durationToDescriptiveString1(current.addDays(2).addSecs(23 * 60 * 60) - current), QString::fromLatin1("3 day(s)"));
}

void testTimeAgo()
Expand Down
80 changes: 40 additions & 40 deletions translations/client_en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3930,42 +3930,42 @@ Are you sure you want to proceed?</source>
<context>
<name>QObject</name>
<message>
<location filename="../src/common/utility.cpp" line="321"/>
<location filename="../src/common/utility.cpp" line="309"/>
<source>in the future</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
<location filename="../src/common/utility.cpp" line="316"/>
<location filename="../src/common/utility.cpp" line="304"/>
<source>%n day(s) ago</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
<translation>
<numerusform>%n day ago</numerusform>
<numerusform>%n days ago</numerusform>
</translation>
</message>
<message numerus="yes">
<location filename="../src/common/utility.cpp" line="326"/>
<location filename="../src/common/utility.cpp" line="314"/>
<source>%n hour(s) ago</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
<translation>
<numerusform>%n hour ago</numerusform>
<numerusform>%n hours ago</numerusform>
</translation>
</message>
<message>
<location filename="../src/common/utility.cpp" line="332"/>
<location filename="../src/common/utility.cpp" line="320"/>
<source>now</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/common/utility.cpp" line="334"/>
<location filename="../src/common/utility.cpp" line="322"/>
<source>less than a minute ago</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
<location filename="../src/common/utility.cpp" line="338"/>
<location filename="../src/common/utility.cpp" line="326"/>
<source>%n minute(s) ago</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
<translation>
<numerusform>%n minute ago</numerusform>
<numerusform>%n minutes ago</numerusform>
</translation>
</message>
<message>
Expand Down Expand Up @@ -4174,55 +4174,55 @@ Are you sure you want to proceed?</source>
<context>
<name>Utility</name>
<message numerus="yes">
<location filename="../src/common/utility.cpp" line="218"/>
<location filename="../src/common/utility.cpp" line="208"/>
<source>%n year(s)</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
<translation>
<numerusform>%n year</numerusform>
<numerusform>%n years</numerusform>
</translation>
</message>
<message numerus="yes">
<location filename="../src/common/utility.cpp" line="219"/>
<location filename="../src/common/utility.cpp" line="209"/>
<source>%n month(s)</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
<translation>
<numerusform>%n month</numerusform>
<numerusform>%n months</numerusform>
</translation>
</message>
<message numerus="yes">
<location filename="../src/common/utility.cpp" line="220"/>
<location filename="../src/common/utility.cpp" line="210"/>
<source>%n day(s)</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
<translation>
<numerusform>%n day</numerusform>
<numerusform>%n days</numerusform>
</translation>
</message>
<message numerus="yes">
<location filename="../src/common/utility.cpp" line="221"/>
<location filename="../src/common/utility.cpp" line="211"/>
<source>%n hour(s)</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
<translation>
<numerusform>%n hour</numerusform>
<numerusform>%n hours</numerusform>
</translation>
</message>
<message numerus="yes">
<location filename="../src/common/utility.cpp" line="222"/>
<location filename="../src/common/utility.cpp" line="212"/>
<source>%n minute(s)</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
<translation>
<numerusform>%n minute</numerusform>
<numerusform>%n minutes</numerusform>
</translation>
</message>
<message numerus="yes">
<location filename="../src/common/utility.cpp" line="223"/>
<location filename="../src/common/utility.cpp" line="213"/>
<source>%n second(s)</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
<translation>
<numerusform>%n second</numerusform>
<numerusform>%n seconds</numerusform>
</translation>
</message>
<message>
<location filename="../src/common/utility.cpp" line="247"/>
<location filename="../src/common/utility.cpp" line="237"/>
<source>%1 %2</source>
<translation type="unfinished"></translation>
</message>
Expand Down
Loading