diff --git a/src/TypingDisplay.cpp b/src/TypingDisplay.cpp
index 6059601d..43fabcd8 100644
--- a/src/TypingDisplay.cpp
+++ b/src/TypingDisplay.cpp
@@ -33,6 +33,14 @@ TypingDisplay::setUsers(const QStringList &uid)
text_.clear();
+ QString temp = text_ +=
+ tr("%1 and %2 are typing",
+ "Multiple users are typing. First argument is a comma separated list of potentially "
+ "multiple users. Second argument is the last user of that list. (If only one user is "
+ "typing, %1 is empty. You should still use it in your string though to silence Qt "
+ "warnings.)",
+ uid.size());
+
if (uid.isEmpty()) {
hide();
update();
@@ -40,12 +48,9 @@ TypingDisplay::setUsers(const QStringList &uid)
return;
}
- text_ = uid.join(", ");
-
- if (uid.size() == 1)
- text_ += tr(" is typing");
- else if (uid.size() > 1)
- text_ += tr(" are typing");
+ QStringList uidWithoutLast = uid;
+ uidWithoutLast.pop_back();
+ text_ = temp.arg(uidWithoutLast.join(", ")).arg(uid.back());
show();
update();
diff --git a/src/Utils.cpp b/src/Utils.cpp
index d6b092b1..a3c15c96 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -99,13 +99,13 @@ utils::descriptiveTime(const QDateTime &then)
const auto days = then.daysTo(now);
if (days == 0)
- return then.toString("HH:mm");
+ return then.time().toString(Qt::DefaultLocaleShortDate);
else if (days < 2)
- return QString("Yesterday");
- else if (days < 365)
- return then.toString("dd/MM");
+ return QString(QCoreApplication::translate("descriptiveTime", "Yesterday"));
+ else if (days < 7)
+ return then.toString("dddd");
- return then.toString("dd/MM/yy");
+ return then.date().toString(Qt::DefaultLocaleShortDate);
}
DescInfo
@@ -147,7 +147,7 @@ utils::getMessageDescription(const TimelineEvent &event,
DescInfo info;
if (sender == localUser)
- info.username = "You";
+ info.username = QCoreApplication::translate("utils", "You");
else
info.username = username;
@@ -366,16 +366,16 @@ utils::getQuoteBody(const RelatedInfo &related)
return markdownToHtml(related.quoted_body);
}
case MsgType::File: {
- return QString("sent a file.");
+ return QString(QCoreApplication::translate("utils", "sent a file."));
}
case MsgType::Image: {
- return QString("sent an image.");
+ return QString(QCoreApplication::translate("utils", "sent an image."));
}
case MsgType::Audio: {
- return QString("sent an audio file.");
+ return QString(QCoreApplication::translate("utils", "sent an audio file."));
}
case MsgType::Video: {
- return QString("sent a video");
+ return QString(QCoreApplication::translate("utils", "sent a video"));
}
default: {
return related.quoted_body;
diff --git a/src/dialogs/MemberList.cpp b/src/dialogs/MemberList.cpp
index f4167143..88a95403 100644
--- a/src/dialogs/MemberList.cpp
+++ b/src/dialogs/MemberList.cpp
@@ -97,7 +97,7 @@ MemberList::MemberList(const QString &room_id, QWidget *parent)
topLabel_->setAlignment(Qt::AlignCenter);
topLabel_->setFont(font);
- auto okBtn = new QPushButton("OK", this);
+ auto okBtn = new QPushButton(tr("OK"), this);
auto buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(15);
@@ -126,7 +126,7 @@ MemberList::MemberList(const QString &room_id, QWidget *parent)
qCritical() << e.what();
}
- auto closeShortcut = new QShortcut(QKeySequence(tr("ESC")), this);
+ auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this);
connect(closeShortcut, &QShortcut::activated, this, &MemberList::close);
connect(okBtn, &QPushButton::clicked, this, &MemberList::close);
}
diff --git a/src/dialogs/ReadReceipts.cpp b/src/dialogs/ReadReceipts.cpp
index dc4145db..5a0d98c7 100644
--- a/src/dialogs/ReadReceipts.cpp
+++ b/src/dialogs/ReadReceipts.cpp
@@ -78,13 +78,15 @@ ReceiptItem::dateFormat(const QDateTime &then) const
auto days = then.daysTo(now);
if (days == 0)
- return QString("Today %1").arg(then.toString("HH:mm"));
+ return tr("Today %1").arg(then.time().toString(Qt::DefaultLocaleShortDate));
else if (days < 2)
- return QString("Yesterday %1").arg(then.toString("HH:mm"));
- else if (days < 365)
- return then.toString("dd/MM HH:mm");
+ return tr("Yesterday %1").arg(then.time().toString(Qt::DefaultLocaleShortDate));
+ else if (days < 7)
+ return QString("%1 %2")
+ .arg(then.toString("dddd"))
+ .arg(then.time().toString(Qt::DefaultLocaleShortDate));
- return then.toString("dd/MM/yy");
+ return then.toString(Qt::DefaultLocaleShortDate);
}
ReadReceipts::ReadReceipts(QWidget *parent)
@@ -131,7 +133,7 @@ ReadReceipts::ReadReceipts(QWidget *parent)
layout->addWidget(userList_);
layout->addLayout(buttonLayout);
- auto closeShortcut = new QShortcut(QKeySequence(tr("ESC")), this);
+ auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this);
connect(closeShortcut, &QShortcut::activated, this, &ReadReceipts::close);
connect(okBtn, &QPushButton::clicked, this, &ReadReceipts::close);
}
diff --git a/src/dialogs/RoomSettings.cpp b/src/dialogs/RoomSettings.cpp
index b2344f23..1fe5904b 100644
--- a/src/dialogs/RoomSettings.cpp
+++ b/src/dialogs/RoomSettings.cpp
@@ -438,7 +438,7 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
resetErrorLabel();
});
- auto closeShortcut = new QShortcut(QKeySequence(tr("ESC")), this);
+ auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this);
connect(closeShortcut, &QShortcut::activated, this, &RoomSettings::close);
connect(okBtn, &QPushButton::clicked, this, &RoomSettings::close);
}
@@ -668,12 +668,12 @@ RoomSettings::updateAvatar()
QFile file{fileName, this};
if (format != "image") {
- displayErrorMessage(tr("The selected media is not an image"));
+ displayErrorMessage(tr("The selected file is not an image"));
return;
}
if (!file.open(QIODevice::ReadOnly)) {
- displayErrorMessage(tr("Error while reading media: %1").arg(file.errorString()));
+ displayErrorMessage(tr("Error while reading file: %1").arg(file.errorString()));
return;
}
diff --git a/src/dialogs/UserProfile.cpp b/src/dialogs/UserProfile.cpp
index b8040f9f..6aea96a8 100644
--- a/src/dialogs/UserProfile.cpp
+++ b/src/dialogs/UserProfile.cpp
@@ -183,7 +183,7 @@ UserProfile::UserProfile(QWidget *parent)
qRegisterMetaType<std::vector<DeviceInfo>>();
- auto closeShortcut = new QShortcut(QKeySequence(tr("ESC")), this);
+ auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this);
connect(closeShortcut, &QShortcut::activated, this, &UserProfile::close);
connect(okBtn, &QPushButton::clicked, this, &UserProfile::close);
}
diff --git a/src/timeline/TimelineItem.cpp b/src/timeline/TimelineItem.cpp
index e52dce7b..dd3b48c3 100644
--- a/src/timeline/TimelineItem.cpp
+++ b/src/timeline/TimelineItem.cpp
@@ -282,6 +282,7 @@ TimelineItem::TimelineItem(mtx::events::MessageType ty,
const QString &room_id,
QWidget *parent)
: QWidget(parent)
+ , message_type_(ty)
, room_id_{room_id}
{
init();
@@ -341,6 +342,7 @@ TimelineItem::TimelineItem(ImageItem *image,
const QString &room_id,
QWidget *parent)
: QWidget{parent}
+ , message_type_(mtx::events::MessageType::Image)
, room_id_{room_id}
{
init();
@@ -356,6 +358,7 @@ TimelineItem::TimelineItem(FileItem *file,
const QString &room_id,
QWidget *parent)
: QWidget{parent}
+ , message_type_(mtx::events::MessageType::File)
, room_id_{room_id}
{
init();
@@ -369,6 +372,7 @@ TimelineItem::TimelineItem(AudioItem *audio,
const QString &room_id,
QWidget *parent)
: QWidget{parent}
+ , message_type_(mtx::events::MessageType::Audio)
, room_id_{room_id}
{
init();
@@ -382,6 +386,7 @@ TimelineItem::TimelineItem(VideoItem *video,
const QString &room_id,
QWidget *parent)
: QWidget{parent}
+ , message_type_(mtx::events::MessageType::Video)
, room_id_{room_id}
{
init();
@@ -395,6 +400,7 @@ TimelineItem::TimelineItem(ImageItem *image,
const QString &room_id,
QWidget *parent)
: QWidget(parent)
+ , message_type_(mtx::events::MessageType::Image)
, room_id_{room_id}
{
setupWidgetLayout<mtx::events::RoomEvent<mtx::events::msg::Image>, ImageItem>(
@@ -426,6 +432,7 @@ TimelineItem::TimelineItem(FileItem *file,
const QString &room_id,
QWidget *parent)
: QWidget(parent)
+ , message_type_(mtx::events::MessageType::File)
, room_id_{room_id}
{
setupWidgetLayout<mtx::events::RoomEvent<mtx::events::msg::File>, FileItem>(
@@ -440,6 +447,7 @@ TimelineItem::TimelineItem(AudioItem *audio,
const QString &room_id,
QWidget *parent)
: QWidget(parent)
+ , message_type_(mtx::events::MessageType::Audio)
, room_id_{room_id}
{
setupWidgetLayout<mtx::events::RoomEvent<mtx::events::msg::Audio>, AudioItem>(
@@ -454,6 +462,7 @@ TimelineItem::TimelineItem(VideoItem *video,
const QString &room_id,
QWidget *parent)
: QWidget(parent)
+ , message_type_(mtx::events::MessageType::Video)
, room_id_{room_id}
{
setupWidgetLayout<mtx::events::RoomEvent<mtx::events::msg::Video>, VideoItem>(
@@ -470,6 +479,7 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Notice
const QString &room_id,
QWidget *parent)
: QWidget(parent)
+ , message_type_(mtx::events::MessageType::Notice)
, room_id_{room_id}
{
init();
@@ -517,6 +527,7 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Emote>
const QString &room_id,
QWidget *parent)
: QWidget(parent)
+ , message_type_(mtx::events::MessageType::Emote)
, room_id_{room_id}
{
init();
@@ -565,6 +576,7 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Text>
const QString &room_id,
QWidget *parent)
: QWidget(parent)
+ , message_type_(mtx::events::MessageType::Text)
, room_id_{room_id}
{
init();
@@ -951,4 +963,4 @@ TimelineItem::openRawMessageViewer() const
"failed to serialize event ({}, {})", room_id, event_id);
}
});
-}
\ No newline at end of file
+}
diff --git a/src/timeline/TimelineItem.h b/src/timeline/TimelineItem.h
index c0dab6b8..fe354000 100644
--- a/src/timeline/TimelineItem.h
+++ b/src/timeline/TimelineItem.h
@@ -277,7 +277,7 @@ private:
QFutureWatcher<QString> *colorGenerating_;
QString event_id_;
- mtx::events::MessageType message_type_;
+ mtx::events::MessageType message_type_ = mtx::events::MessageType::Unknown;
QString room_id_;
DescInfo descriptionMsg_;
diff --git a/src/timeline/TimelineView.cpp b/src/timeline/TimelineView.cpp
index 18b73eb0..ed783e90 100644
--- a/src/timeline/TimelineView.cpp
+++ b/src/timeline/TimelineView.cpp
@@ -306,7 +306,10 @@ TimelineView::parseEncryptedEvent(const mtx::events::EncryptedEvent<mtx::events:
dummy.origin_server_ts = e.origin_server_ts;
dummy.event_id = e.event_id;
dummy.sender = e.sender;
- dummy.content.body = "-- Encrypted Event (No keys found for decryption) --";
+ dummy.content.body =
+ tr("-- Encrypted Event (No keys found for decryption) --",
+ "Placeholder, when the message was not decrypted yet or can't be decrypted")
+ .toStdString();
try {
if (!cache::client()->inboundMegolmSessionExists(index)) {
@@ -319,7 +322,10 @@ TimelineView::parseEncryptedEvent(const mtx::events::EncryptedEvent<mtx::events:
}
} catch (const lmdb::error &e) {
nhlog::db()->critical("failed to check megolm session's existence: {}", e.what());
- dummy.content.body = "-- Decryption Error (failed to communicate with DB) --";
+ dummy.content.body = tr("-- Decryption Error (failed to communicate with DB) --",
+ "Placeholder, when the message can't be decrypted, because "
+ "the DB access failed when trying to lookup the session.")
+ .toStdString();
return {dummy, false};
}
@@ -335,7 +341,10 @@ TimelineView::parseEncryptedEvent(const mtx::events::EncryptedEvent<mtx::events:
index.sender_key,
e.what());
dummy.content.body =
- "-- Decryption Error (failed to retrieve megolm keys from db) --";
+ tr("-- Decryption Error (failed to retrieve megolm keys from db) --",
+ "Placeholder, when the message can't be decrypted, because the DB access "
+ "failed.")
+ .toStdString();
return {dummy, false};
} catch (const mtx::crypto::olm_exception &e) {
nhlog::crypto()->critical("failed to decrypt message with index ({}, {}, {}): {}",
@@ -343,7 +352,12 @@ TimelineView::parseEncryptedEvent(const mtx::events::EncryptedEvent<mtx::events:
index.session_id,
index.sender_key,
e.what());
- dummy.content.body = "-- Decryption Error (" + std::string(e.what()) + ") --";
+ dummy.content.body =
+ tr("-- Decryption Error (%1) --",
+ "Placeholder, when the message can't be decrypted. In this case, the Olm "
+ "decrytion returned an error, which is passed ad %1")
+ .arg(e.what())
+ .toStdString();
return {dummy, false};
}
@@ -365,7 +379,11 @@ TimelineView::parseEncryptedEvent(const mtx::events::EncryptedEvent<mtx::events:
if (events.size() == 1)
return {events.at(0), true};
- dummy.content.body = "-- Encrypted Event (Unknown event type) --";
+ dummy.content.body =
+ tr("-- Encrypted Event (Unknown event type) --",
+ "Placeholder, when the message was decrypted, but we couldn't parse it, because "
+ "Nheko/mtxclient don't support that event type yet")
+ .toStdString();
return {dummy, false};
}
diff --git a/src/ui/InfoMessage.cpp b/src/ui/InfoMessage.cpp
index fa575d76..27bc0a5f 100644
--- a/src/ui/InfoMessage.cpp
+++ b/src/ui/InfoMessage.cpp
@@ -2,6 +2,7 @@
#include "Config.h"
#include <QDateTime>
+#include <QLocale>
#include <QPainter>
#include <QPen>
#include <QtGlobal>
@@ -61,14 +62,14 @@ DateSeparator::DateSeparator(QDateTime datetime, QWidget *parent)
{
auto now = QDateTime::currentDateTime();
- QString fmt;
+ QString fmt = QLocale::system().dateFormat(QLocale::LongFormat);
- if (now.date().year() != datetime.date().year())
- fmt = QString("ddd d MMMM yy");
- else
- fmt = QString("ddd d MMMM");
+ if (now.date().year() == datetime.date().year()) {
+ QRegularExpression rx("[^a-zA-Z]*y+[^a-zA-Z]*");
+ fmt = fmt.remove(rx);
+ }
- msg_ = datetime.toString(fmt);
+ msg_ = datetime.date().toString(fmt);
QFontMetrics fm{font()};
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
|