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 1 commit
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
10 changes: 6 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,8 @@ void DocsetsDialog::downloadCompleted()
if (file->open(QIODevice::WriteOnly))
file->write(data);

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

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

// TODO: Show more user friendly labels, like "5 hours ago"
ui->lastUpdatedLabel->setText(fi.lastModified().toString(Qt::SystemLocaleShortDate));
ReadableInterval lastModifiedInterval(fi.lastModified());
ui->lastUpdatedLabel->setText(lastModifiedInterval.toReadableString());
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
80 changes: 80 additions & 0 deletions src/libs/util/readableinterval.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/****************************************************************************
**
** 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;

ReadableInterval::ReadableInterval(QDateTime timestamp, QDateTime reference) :
m_timestamp(timestamp),
m_reference(reference)
{
m_delta = m_reference.toSecsSinceEpoch() - m_timestamp.toSecsSinceEpoch();
}

ReadableInterval::ReadableInterval(QDateTime timestamp) :
m_timestamp(timestamp)
{
m_reference = QDateTime::currentDateTime();
m_delta = m_reference.toSecsSinceEpoch() - m_timestamp.toSecsSinceEpoch();
}

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

void ReadableInterval::computeDateTimeComponents()
{
m_isPast = m_delta > 0;
m_year = m_delta / SECONDSPERYEAR;
m_day = (m_delta % SECONDSPERYEAR) / SECONDSPERDAY;
m_hour = ((m_delta % SECONDSPERYEAR) % SECONDSPERDAY) / SECONDSPERHOUR;
m_min = (((m_delta % SECONDSPERYEAR) % SECONDSPERDAY) % SECONDSPERHOUR) / SECONDSPERMINUTE;
m_sec = (((m_delta % SECONDSPERYEAR) % SECONDSPERDAY) % SECONDSPERHOUR) % SECONDSPERMINUTE;
}

QString ReadableInterval::toReadableString()
{
if (m_delta == 0)
return ZERO_INTERVAL_STRING;
else {
QStringList list;
qint8 fieldCount = 0;
computeDateTimeComponents();
if (m_year && ++fieldCount <= MAX_FIELDS_DISPLAYED)
list.append(QStringLiteral("%1 %2").arg(m_year).arg(pluralForm(YEAR, m_year)));
if (m_day && ++fieldCount <= MAX_FIELDS_DISPLAYED)
list.append(QStringLiteral("%1 %2").arg(m_day).arg(pluralForm(DAY, m_day)));
if (m_hour && ++fieldCount <= MAX_FIELDS_DISPLAYED)
list.append(QStringLiteral("%1 %2").arg(m_hour).arg(pluralForm(HOUR, m_hour)));
if (m_min && ++fieldCount <= MAX_FIELDS_DISPLAYED)
list.append(QStringLiteral("%1 %2").arg(m_min).arg(pluralForm(MIN, m_min)));
if (m_sec && ++fieldCount <= MAX_FIELDS_DISPLAYED)
list.append(QStringLiteral("%1 %2").arg(m_sec).arg(pluralForm(SEC, m_sec)));
return QStringLiteral("%1 %2").arg(list.join(JOIN_SEQ)).arg(m_isPast ? PAST_INTERVAL_STRING : FUTURE_INTERVAL_STRING);
}
}
68 changes: 68 additions & 0 deletions src/libs/util/readableinterval.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/****************************************************************************
**
** 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:
ReadableInterval(QDateTime timestamp, QDateTime reference);
ReadableInterval(QDateTime timestamp);

QString toReadableString();
Copy link
Member

Choose a reason for hiding this comment

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

Maybe just make the whole thing a static method?


private:
void computeDateTimeComponents();
QString pluralForm(QString word, qint64 quantity);

QDateTime m_timestamp, m_reference;
qint64 m_delta, m_year, m_day, m_hour, m_min, m_sec;
bool m_isPast;

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;

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.

All these should just be constant strings in an anonymous namespace in the source file.

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

} // namespace Util
} // namespace Zeal

#endif // ZEAL_UTIL_READABLEINTERVAL_H