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

Complete TODO : Show more user friendly labels #1002

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
8 changes: 4 additions & 4 deletions src/libs/ui/docsetsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <registry/docsetregistry.h>
#include <registry/itemdatarole.h>
#include <registry/listmodel.h>
#include <util/readableinterval.h>

#include <QClipboard>
#include <QDateTime>
Expand All @@ -49,6 +50,7 @@

using namespace Zeal;
using namespace Zeal::WidgetUi;
using namespace Zeal::Util;

#ifdef Q_OS_WIN32
extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;
Expand Down Expand Up @@ -311,8 +313,7 @@ void DocsetsDialog::downloadCompleted()
if (file->open(QIODevice::WriteOnly))
file->write(data);

ui->lastUpdatedLabel->setText(QFileInfo(file->fileName())
.lastModified().toString(Qt::SystemLocaleShortDate));
ui->lastUpdatedLabel->setText(ReadableInterval::toReadableString(QFileInfo(file->fileName()).lastModified()));

QJsonParseError jsonError;
const QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
Expand Down Expand Up @@ -518,8 +519,7 @@ void DocsetsDialog::loadDocsetList()
return;
}

// TODO: Show more user friendly labels, like "5 hours ago"
ui->lastUpdatedLabel->setText(fi.lastModified().toString(Qt::SystemLocaleShortDate));
ui->lastUpdatedLabel->setText(ReadableInterval::toReadableString(fi.lastModified()));
processDocsetList(jsonDoc.array());
}

Expand Down
1 change: 1 addition & 0 deletions src/libs/util/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set(CMAKE_AUTOMOC OFF)
add_library(Util
plist.cpp
sqlitedatabase.cpp
readableinterval.cpp
version.cpp
)

Expand Down
87 changes: 87 additions & 0 deletions src/libs/util/readableinterval.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/****************************************************************************
**
** Copyright (C) 2015-2018 Oleg Shparber
** Copyright (C) 2013-2014 Jerzy Kozera
** Contact: https://go.zealdocs.org/l/contact
**
** This file is part of Zeal.
**
** Zeal is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Zeal is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Zeal. If not, see <https://www.gnu.org/licenses/>.
**
****************************************************************************/

#include "readableinterval.h"

#include <QStringBuilder>
#include <QStringList>

using namespace Zeal::Util;

namespace {
const qint16 SECONDSPERMINUTE = 60;
const qint16 SECONDSPERHOUR = SECONDSPERMINUTE * 60;
const qint32 SECONDSPERDAY = SECONDSPERHOUR * 24;
const qint32 SECONDSPERYEAR = SECONDSPERDAY * 365;

const qint8 MAX_FIELDS_DISPLAYED = 3;

const QString ZERO_INTERVAL_STRING = "now";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is dangerous, see static initialization order fiasco and bullet point 3 here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, it's better to avoid making translatable strings constant. Just put them inside tr() inline.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm leaving plural forms of units with a (s). Once we apply translation to this project, qt should automatically detect the quantity and append s.

http://doc.qt.io/qt-5/i18n-source-translation.html#handling-plurals

const QString PAST_INTERVAL_STRING = "ago";
const QString FUTURE_INTERVAL_STRING = "from now";
const QString YEAR = "Year";
const QString DAY = "Day";
const QString HOUR = "Hour";
const QString MIN = "Minute";
const QString SEC = "Second";
const QString JOIN_SEQ= ", ";
}

QString ReadableInterval::pluralForm(const QString &word, qint64 quantity)
{
return word + (quantity > 1 ? "s" : "");
}

QString ReadableInterval::toReadableString(const QDateTime& timestamp, const QDateTime& reference)
{
qint64 delta, year, day, hour, min, sec;
bool isPast;

delta = reference.toSecsSinceEpoch() - timestamp.toSecsSinceEpoch();

if (delta) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always try to return ASAP, and avoid unnecessary conditional blocks of code.

if (delta == 0) {
    return ZERO_INTERVAL_STRING;
}

QStingList list;
...

QStringList list;
qint8 fieldCount = 0;

isPast = delta > 0;
year = delta / SECONDSPERYEAR;
day = (delta % SECONDSPERYEAR) / SECONDSPERDAY;
hour = ((delta % SECONDSPERYEAR) % SECONDSPERDAY) / SECONDSPERHOUR;
min = (((delta % SECONDSPERYEAR) % SECONDSPERDAY) % SECONDSPERHOUR) / SECONDSPERMINUTE;
sec = (((delta % SECONDSPERYEAR) % SECONDSPERDAY) % SECONDSPERHOUR) % SECONDSPERMINUTE;

if (year && ++fieldCount <= MAX_FIELDS_DISPLAYED)
list.append(QStringLiteral("%1 %2").arg(year).arg(ReadableInterval::pluralForm(YEAR, year)));
if (day && ++fieldCount <= MAX_FIELDS_DISPLAYED)
list.append(QStringLiteral("%1 %2").arg(day).arg(ReadableInterval::pluralForm(DAY, day)));
if (hour && ++fieldCount <= MAX_FIELDS_DISPLAYED)
list.append(QStringLiteral("%1 %2").arg(hour).arg(ReadableInterval::pluralForm(HOUR, hour)));
if (min && ++fieldCount <= MAX_FIELDS_DISPLAYED)
list.append(QStringLiteral("%1 %2").arg(min).arg(ReadableInterval::pluralForm(MIN, min)));
if (sec && ++fieldCount <= MAX_FIELDS_DISPLAYED)
list.append(QStringLiteral("%1 %2").arg(sec).arg(ReadableInterval::pluralForm(SEC, sec)));
return QStringLiteral("%1 %2").arg(list.join(JOIN_SEQ), isPast ? PAST_INTERVAL_STRING : FUTURE_INTERVAL_STRING);
} else {
return ZERO_INTERVAL_STRING;
}
}
43 changes: 43 additions & 0 deletions src/libs/util/readableinterval.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/****************************************************************************
**
** Copyright (C) 2015-2018 Oleg Shparber
** Contact: https://go.zealdocs.org/l/contact
**
** This file is part of Zeal.
**
** Zeal is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Zeal is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Zeal. If not, see <https://www.gnu.org/licenses/>.
**
****************************************************************************/

#ifndef ZEAL_UTIL_READABLEINTERVAL_H
#define ZEAL_UTIL_READABLEINTERVAL_H

#include <QDateTime>

namespace Zeal {
namespace Util {

class ReadableInterval
{
public:
static QString toReadableString(const QDateTime& timestamp, const QDateTime& reference = QDateTime::currentDateTime());

private:
static QString pluralForm(const QString& word, qint64 quantity);
};

} // namespace Util
} // namespace Zeal

#endif // ZEAL_UTIL_READABLEINTERVAL_H