init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Close stale issues and PRs / stale (push) Successful in 13s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Close stale issues and PRs / stale (push) Successful in 13s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
This commit is contained in:
90
Telegram/SourceFiles/ui/text/format_song_document_name.cpp
Normal file
90
Telegram/SourceFiles/ui/text/format_song_document_name.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "ui/text/format_song_document_name.h"
|
||||
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_session.h"
|
||||
#include "history/history_item_helpers.h"
|
||||
#include "history/history_item.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
|
||||
#include <QtCore/QLocale>
|
||||
|
||||
namespace Ui::Text {
|
||||
|
||||
FormatSongName FormatSongNameFor(not_null<DocumentData*> document) {
|
||||
const auto song = document->song();
|
||||
|
||||
return FormatSongName(
|
||||
document->filename(),
|
||||
song ? song->title : QString(),
|
||||
song ? song->performer : QString());
|
||||
}
|
||||
|
||||
TextWithEntities FormatDownloadsName(not_null<DocumentData*> document) {
|
||||
return document->isVideoFile()
|
||||
? Bold(tr::lng_in_dlg_video(tr::now))
|
||||
: document->isVoiceMessage()
|
||||
? Bold(tr::lng_in_dlg_audio(tr::now))
|
||||
: document->isVideoMessage()
|
||||
? Bold(tr::lng_in_dlg_video_message(tr::now))
|
||||
: document->sticker()
|
||||
? Bold(document->sticker()->alt.isEmpty()
|
||||
? tr::lng_in_dlg_sticker(tr::now)
|
||||
: tr::lng_in_dlg_sticker_emoji(
|
||||
tr::now,
|
||||
lt_emoji,
|
||||
document->sticker()->alt))
|
||||
: FormatSongNameFor(document).textWithEntities();
|
||||
}
|
||||
|
||||
FormatSongName FormatVoiceName(
|
||||
not_null<DocumentData*> document,
|
||||
FullMsgId contextId) {
|
||||
if (const auto item = document->owner().message(contextId)) {
|
||||
const auto name = (!item->out() || item->isPost())
|
||||
? item->fromOriginal()->name()
|
||||
: tr::lng_from_you(tr::now);
|
||||
const auto date = [item] {
|
||||
const auto parsed = ItemDateTime(item);
|
||||
const auto date = parsed.date();
|
||||
const auto time = QLocale().toString(
|
||||
parsed.time(),
|
||||
QLocale::ShortFormat);
|
||||
const auto today = QDateTime::currentDateTime().date();
|
||||
if (date == today) {
|
||||
return tr::lng_player_message_today(
|
||||
tr::now,
|
||||
lt_time,
|
||||
time);
|
||||
} else if (date.addDays(1) == today) {
|
||||
return tr::lng_player_message_yesterday(
|
||||
tr::now,
|
||||
lt_time,
|
||||
time);
|
||||
}
|
||||
return tr::lng_player_message_date(
|
||||
tr::now,
|
||||
lt_date,
|
||||
langDayOfMonthFull(date),
|
||||
lt_time,
|
||||
time);
|
||||
};
|
||||
auto result = FormatSongName(QString(), date(), name);
|
||||
result.setNoDash(true);
|
||||
return result;
|
||||
} else if (document->isVideoMessage()) {
|
||||
return FormatSongName(QString(), tr::lng_media_round(tr::now), {});
|
||||
} else {
|
||||
return FormatSongName(QString(), tr::lng_media_audio(tr::now), {});
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Ui::Text
|
||||
26
Telegram/SourceFiles/ui/text/format_song_document_name.h
Normal file
26
Telegram/SourceFiles/ui/text/format_song_document_name.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/text/format_song_name.h"
|
||||
|
||||
class DocumentData;
|
||||
|
||||
namespace Ui::Text {
|
||||
|
||||
[[nodiscard]] FormatSongName FormatSongNameFor(
|
||||
not_null<DocumentData*> document);
|
||||
|
||||
[[nodiscard]] TextWithEntities FormatDownloadsName(
|
||||
not_null<DocumentData*> document);
|
||||
|
||||
[[nodiscard]] FormatSongName FormatVoiceName(
|
||||
not_null<DocumentData*> document,
|
||||
FullMsgId contextId);
|
||||
|
||||
} // namespace Ui::Text
|
||||
82
Telegram/SourceFiles/ui/text/format_song_name.cpp
Normal file
82
Telegram/SourceFiles/ui/text/format_song_name.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "ui/text/format_song_name.h"
|
||||
|
||||
namespace Ui::Text {
|
||||
|
||||
namespace {
|
||||
|
||||
FormatSongName::ComposedName ComputeComposedName(
|
||||
const QString &filename,
|
||||
const QString &songTitle,
|
||||
const QString &songPerformer) {
|
||||
const auto unknown = u"Unknown Track"_q;
|
||||
if (songTitle.isEmpty() && songPerformer.isEmpty()) {
|
||||
return {
|
||||
.title = filename.isEmpty() ? unknown : filename,
|
||||
.performer = QString(),
|
||||
};
|
||||
}
|
||||
|
||||
if (songPerformer.isEmpty()) {
|
||||
return {
|
||||
.title = songTitle,
|
||||
.performer = QString(),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
.title = (songTitle.isEmpty() ? unknown : songTitle),
|
||||
.performer = songPerformer,
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FormatSongName::FormatSongName(
|
||||
const QString &filename,
|
||||
const QString &songTitle,
|
||||
const QString &songPerformer)
|
||||
: _composedName(ComputeComposedName(filename, songTitle, songPerformer)) {
|
||||
}
|
||||
|
||||
FormatSongName::ComposedName FormatSongName::composedName() const {
|
||||
return _composedName;
|
||||
}
|
||||
|
||||
QString FormatSongName::string() const {
|
||||
const auto &[title, performer] = _composedName;
|
||||
const auto dash = (title.isEmpty() || performer.isEmpty())
|
||||
? QString()
|
||||
: _noDash
|
||||
? QString(' ')
|
||||
: QString::fromUtf8(" \xe2\x80\x93 ");
|
||||
return performer + dash + title;
|
||||
}
|
||||
|
||||
void FormatSongName::setNoDash(bool noDash) {
|
||||
_noDash = noDash;
|
||||
}
|
||||
|
||||
TextWithEntities FormatSongName::textWithEntities(
|
||||
bool boldOnlyPerformer) const {
|
||||
TextWithEntities result;
|
||||
result.text = string();
|
||||
if (!boldOnlyPerformer || !_composedName.performer.isEmpty()) {
|
||||
result.entities.push_back({
|
||||
EntityType::Semibold,
|
||||
0,
|
||||
_composedName.performer.isEmpty()
|
||||
? int(result.text.size())
|
||||
: int(_composedName.performer.size()),
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace Ui::Text
|
||||
37
Telegram/SourceFiles/ui/text/format_song_name.h
Normal file
37
Telegram/SourceFiles/ui/text/format_song_name.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Ui::Text {
|
||||
|
||||
class FormatSongName final {
|
||||
public:
|
||||
struct ComposedName {
|
||||
QString title;
|
||||
QString performer;
|
||||
};
|
||||
|
||||
FormatSongName(
|
||||
const QString &filename,
|
||||
const QString &songTitle,
|
||||
const QString &songPerformer);
|
||||
|
||||
[[nodiscard]] ComposedName composedName() const;
|
||||
[[nodiscard]] QString string() const;
|
||||
[[nodiscard]] TextWithEntities textWithEntities(
|
||||
bool boldOnlyPerformer = false) const;
|
||||
|
||||
void setNoDash(bool noDash);
|
||||
|
||||
private:
|
||||
const ComposedName _composedName;
|
||||
bool _noDash = false;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui::Text
|
||||
544
Telegram/SourceFiles/ui/text/format_values.cpp
Normal file
544
Telegram/SourceFiles/ui/text/format_values.cpp
Normal file
@@ -0,0 +1,544 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "ui/text/format_values.h"
|
||||
|
||||
#include "base/unixtime.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "countries/countries_instance.h"
|
||||
|
||||
#include <QtCore/QLocale>
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
constexpr auto kSecondsInYear = 365 * 24 * 60 * 60; // 31536000
|
||||
|
||||
[[nodiscard]] QString FormatTextWithReadyAndTotal(
|
||||
tr::phrase<lngtag_ready, lngtag_total, lngtag_mb> phrase,
|
||||
qint64 ready,
|
||||
qint64 total) {
|
||||
QString readyStr, totalStr, mb;
|
||||
if (total >= 1024 * 1024) { // more than 1 mb
|
||||
const qint64 readyTenthMb = (ready * 10 / (1024 * 1024));
|
||||
const qint64 totalTenthMb = (total * 10 / (1024 * 1024));
|
||||
readyStr = QString::number(readyTenthMb / 10)
|
||||
+ '.'
|
||||
+ QString::number(readyTenthMb % 10);
|
||||
totalStr = QString::number(totalTenthMb / 10)
|
||||
+ '.'
|
||||
+ QString::number(totalTenthMb % 10);
|
||||
mb = u"MB"_q;
|
||||
} else if (total >= 1024) {
|
||||
qint64 readyKb = (ready / 1024), totalKb = (total / 1024);
|
||||
readyStr = QString::number(readyKb);
|
||||
totalStr = QString::number(totalKb);
|
||||
mb = u"KB"_q;
|
||||
} else {
|
||||
readyStr = QString::number(ready);
|
||||
totalStr = QString::number(total);
|
||||
mb = u"B"_q;
|
||||
}
|
||||
return phrase(tr::now, lt_ready, readyStr, lt_total, totalStr, lt_mb, mb);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
QString FormatSizeText(qint64 size) {
|
||||
if (size >= 1024 * 1024) { // more than 1 mb
|
||||
const qint64 sizeTenthMb = (size * 10 / (1024 * 1024));
|
||||
return QString::number(sizeTenthMb / 10)
|
||||
+ '.'
|
||||
+ QString::number(sizeTenthMb % 10) + u" MB"_q;
|
||||
}
|
||||
if (size >= 1024) {
|
||||
const qint64 sizeTenthKb = (size * 10 / 1024);
|
||||
return QString::number(sizeTenthKb / 10)
|
||||
+ '.'
|
||||
+ QString::number(sizeTenthKb % 10) + u" KB"_q;
|
||||
}
|
||||
return QString::number(size) + u" B"_q;
|
||||
}
|
||||
|
||||
QString FormatDownloadText(qint64 ready, qint64 total) {
|
||||
return FormatTextWithReadyAndTotal(
|
||||
tr::lng_save_downloaded,
|
||||
ready,
|
||||
total);
|
||||
}
|
||||
|
||||
QString FormatProgressText(qint64 ready, qint64 total) {
|
||||
return FormatTextWithReadyAndTotal(
|
||||
tr::lng_media_save_progress,
|
||||
ready,
|
||||
total);
|
||||
}
|
||||
|
||||
QString FormatDateTime(QDateTime date) {
|
||||
const auto now = QDateTime::currentDateTime();
|
||||
if (date.date() == now.date()) {
|
||||
return tr::lng_mediaview_today(
|
||||
tr::now,
|
||||
lt_time,
|
||||
QLocale().toString(date.time(), QLocale::ShortFormat));
|
||||
} else if (date.date().addDays(1) == now.date()) {
|
||||
return tr::lng_mediaview_yesterday(
|
||||
tr::now,
|
||||
lt_time,
|
||||
QLocale().toString(date.time(), QLocale::ShortFormat));
|
||||
} else {
|
||||
return tr::lng_mediaview_date_time(
|
||||
tr::now,
|
||||
lt_date,
|
||||
QLocale().toString(date.date(), QLocale::ShortFormat),
|
||||
lt_time,
|
||||
QLocale().toString(date.time(), QLocale::ShortFormat));
|
||||
}
|
||||
}
|
||||
|
||||
QString FormatDateTimeSavedFrom(QDateTime dateTime) {
|
||||
const auto current = QDate::currentDate();
|
||||
const auto date = dateTime.date();
|
||||
const auto timeStr = QLocale().toString(
|
||||
dateTime.time(),
|
||||
QLocale::ShortFormat);
|
||||
|
||||
if (date == current) {
|
||||
return tr::lng_mediaview_today(tr::now, lt_time, timeStr);
|
||||
} else if (date == current.addDays(-1)) {
|
||||
return tr::lng_mediaview_yesterday(tr::now, lt_time, timeStr);
|
||||
}
|
||||
const auto diff = std::abs(
|
||||
base::unixtime::now() - base::unixtime::serialize(dateTime));
|
||||
const auto dateStr = (diff < kSecondsInYear)
|
||||
? tr::lng_month_day(
|
||||
tr::now,
|
||||
lt_month,
|
||||
Lang::MonthSmall(date.month())(tr::now),
|
||||
lt_day,
|
||||
QString::number(date.day()))
|
||||
: langDayOfMonthFull(date);
|
||||
|
||||
return tr::lng_mediaview_date_time(
|
||||
tr::now,
|
||||
lt_date,
|
||||
dateStr,
|
||||
lt_time,
|
||||
timeStr);
|
||||
}
|
||||
|
||||
QString FormatDurationText(qint64 duration) {
|
||||
qint64 hours = (duration / 3600), minutes = (duration % 3600) / 60, seconds = duration % 60;
|
||||
return (hours ? QString::number(hours) + ':' : QString()) + (minutes >= 10 ? QString() : QString('0')) + QString::number(minutes) + ':' + (seconds >= 10 ? QString() : QString('0')) + QString::number(seconds);
|
||||
}
|
||||
|
||||
QString FormatDurationWords(qint64 duration) {
|
||||
if (duration > 59) {
|
||||
auto minutes = (duration / 60);
|
||||
auto minutesCount = tr::lng_duration_minsec_minutes(tr::now, lt_count, minutes);
|
||||
auto seconds = (duration % 60);
|
||||
auto secondsCount = tr::lng_duration_minsec_seconds(tr::now, lt_count, seconds);
|
||||
return tr::lng_duration_minutes_seconds(tr::now, lt_minutes_count, minutesCount, lt_seconds_count, secondsCount);
|
||||
}
|
||||
return tr::lng_seconds(tr::now, lt_count, duration);
|
||||
}
|
||||
|
||||
QString FormatDurationWordsSlowmode(qint64 duration) {
|
||||
if (duration > 59) {
|
||||
auto minutes = (duration / 60);
|
||||
auto minutesCount = tr::lng_duration_minsec_minutes(tr::now, lt_count, minutes);
|
||||
auto seconds = (duration % 60);
|
||||
auto secondsCount = tr::lng_duration_minsec_seconds(tr::now, lt_count, seconds);
|
||||
return tr::lng_duration_minutes_seconds(tr::now, lt_minutes_count, minutesCount, lt_seconds_count, secondsCount);
|
||||
}
|
||||
return tr::lng_slowmode_seconds(tr::now, lt_count, duration);
|
||||
}
|
||||
|
||||
QString FormatDurationAndSizeText(qint64 duration, qint64 size) {
|
||||
return tr::lng_duration_and_size(tr::now, lt_duration, FormatDurationText(duration), lt_size, FormatSizeText(size));
|
||||
}
|
||||
|
||||
QString FormatGifAndSizeText(qint64 size) {
|
||||
return tr::lng_duration_and_size(tr::now, lt_duration, u"GIF"_q, lt_size, FormatSizeText(size));
|
||||
}
|
||||
|
||||
QString FormatPlayedText(qint64 played, qint64 duration) {
|
||||
return tr::lng_duration_played(tr::now, lt_played, FormatDurationText(played), lt_duration, FormatDurationText(duration));
|
||||
}
|
||||
|
||||
QString FillAmountAndCurrency(
|
||||
int64 amount,
|
||||
const QString ¤cy,
|
||||
bool forceStripDotZero) {
|
||||
// std::abs doesn't work on that one :/
|
||||
Expects(amount != std::numeric_limits<int64>::min());
|
||||
|
||||
if (currency == kCreditsCurrency) {
|
||||
return QChar(0x2B50) + Lang::FormatCountDecimal(std::abs(amount));
|
||||
}
|
||||
|
||||
const auto rule = LookupCurrencyRule(currency);
|
||||
const auto prefix = (amount < 0)
|
||||
? QString::fromUtf8("\xe2\x88\x92")
|
||||
: QString();
|
||||
const auto value = std::abs(amount) / std::pow(10., rule.exponent);
|
||||
const auto name = (*rule.international)
|
||||
? QString::fromUtf8(rule.international)
|
||||
: currency;
|
||||
auto result = prefix;
|
||||
if (rule.left) {
|
||||
result.append(name);
|
||||
if (rule.space) result.append(' ');
|
||||
}
|
||||
const auto precision = ((!rule.stripDotZero && !forceStripDotZero)
|
||||
|| std::floor(value) != value)
|
||||
? rule.exponent
|
||||
: 0;
|
||||
result.append(FormatWithSeparators(
|
||||
value,
|
||||
precision,
|
||||
rule.decimal,
|
||||
rule.thousands));
|
||||
if (!rule.left) {
|
||||
if (rule.space) result.append(' ');
|
||||
result.append(name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CurrencyRule LookupCurrencyRule(const QString ¤cy) {
|
||||
static const auto kRules = std::vector<std::pair<QString, CurrencyRule>>{
|
||||
{ u"AED"_q, { "", ',', '.', true, true } },
|
||||
{ u"AFN"_q, {} },
|
||||
{ u"ALL"_q, { "", '.', ',', false } },
|
||||
{ u"AMD"_q, { "", ',', '.', false, true } },
|
||||
{ u"ARS"_q, { "", '.', ',', true, true } },
|
||||
{ u"AUD"_q, { "AU$" } },
|
||||
{ u"AZN"_q, { "", ' ', ',', false, true } },
|
||||
{ u"BAM"_q, { "", '.', ',', false, true } },
|
||||
{ u"BDT"_q, { "", ',', '.', true, true } },
|
||||
{ u"BGN"_q, { "", ' ', ',', false, true } },
|
||||
{ u"BHD"_q, { "", ',', '.', true, true, 3 } },
|
||||
{ u"BND"_q, { "", '.', ',' } },
|
||||
{ u"BOB"_q, { "", '.', ',', true, true } },
|
||||
{ u"BRL"_q, { "R$", '.', ',', true, true } },
|
||||
{ u"BYN"_q, { "", ' ', ',', false, true } },
|
||||
{ u"CAD"_q, { "CA$" } },
|
||||
{ u"CHF"_q, { "", '\'', '.', false, true } },
|
||||
{ u"CLP"_q, { "", '.', ',', true, true, 0 } },
|
||||
{ u"CNY"_q, { "\x43\x4E\xC2\xA5" } },
|
||||
{ u"COP"_q, { "", '.', ',', true, true } },
|
||||
{ u"CRC"_q, { "", '.', ',' } },
|
||||
{ u"CZK"_q, { "", ' ', ',', false, true } },
|
||||
{ u"DKK"_q, { "", '\0', ',', false, true } },
|
||||
{ u"DOP"_q, {} },
|
||||
{ u"DZD"_q, { "", ',', '.', true, true } },
|
||||
{ u"EGP"_q, { "", ',', '.', true, true } },
|
||||
{ u"ETB"_q, {} },
|
||||
{ u"EUR"_q, { "\xE2\x82\xAC", ' ', ',', false, true } },
|
||||
{ u"GBP"_q, { "\xC2\xA3" } },
|
||||
{ u"GEL"_q, { "", ' ', ',', false, true } },
|
||||
{ u"GHS"_q, {} },
|
||||
{ u"GTQ"_q, {} },
|
||||
{ u"HKD"_q, { "HK$" } },
|
||||
{ u"HNL"_q, { "", ',', '.', true, true } },
|
||||
{ u"HRK"_q, { "", '.', ',', false, true } },
|
||||
{ u"HUF"_q, { "", ' ', ',', false, true } },
|
||||
{ u"IDR"_q, { "", '.', ',' } },
|
||||
{ u"ILS"_q, { "\xE2\x82\xAA", ',', '.', true, true } },
|
||||
{ u"INR"_q, { "\xE2\x82\xB9" } },
|
||||
{ u"IQD"_q, { "", ',', '.', true, true, 3 } },
|
||||
{ u"IRR"_q, { "", ',', '/', false, true } },
|
||||
{ u"ISK"_q, { "", '.', ',', false, true, 0 } },
|
||||
{ u"JMD"_q, {} },
|
||||
{ u"JOD"_q, { "", ',', '.', true, false, 3 } },
|
||||
{ u"JPY"_q, { "\xC2\xA5", ',', '.', true, false, 0 } },
|
||||
{ u"KES"_q, {} },
|
||||
{ u"KGS"_q, { "", ' ', '-', false, true } },
|
||||
{ u"KRW"_q, { "\xE2\x82\xA9", ',', '.', true, false, 0 } },
|
||||
{ u"KZT"_q, { "", ' ', '-' } },
|
||||
{ u"LBP"_q, { "", ',', '.', true, true } },
|
||||
{ u"LKR"_q, { "", ',', '.', true, true } },
|
||||
{ u"MAD"_q, { "", ',', '.', true, true } },
|
||||
{ u"MDL"_q, { "", ',', '.', false, true } },
|
||||
{ u"MMK"_q, {} },
|
||||
{ u"MNT"_q, { "", ' ', ',' } },
|
||||
{ u"MOP"_q, {} },
|
||||
{ u"MUR"_q, {} },
|
||||
{ u"MVR"_q, { "", ',', '.', false, true } },
|
||||
{ u"MXN"_q, { "MX$" } },
|
||||
{ u"MYR"_q, {} },
|
||||
{ u"MZN"_q, {} },
|
||||
{ u"NGN"_q, {} },
|
||||
{ u"NIO"_q, { "", ',', '.', true, true } },
|
||||
{ u"NOK"_q, { "", ' ', ',', true, true } },
|
||||
{ u"NPR"_q, {} },
|
||||
{ u"NZD"_q, { "NZ$" } },
|
||||
{ u"PAB"_q, { "", ',', '.', true, true } },
|
||||
{ u"PEN"_q, { "", ',', '.', true, true } },
|
||||
{ u"PHP"_q, {} },
|
||||
{ u"PKR"_q, {} },
|
||||
{ u"PLN"_q, { "", ' ', ',', false, true } },
|
||||
{ u"PYG"_q, { "", '.', ',', true, true, 0 } },
|
||||
{ u"QAR"_q, { "", ',', '.', true, true } },
|
||||
{ u"RON"_q, { "", '.', ',', false, true } },
|
||||
{ u"RSD"_q, { "", '.', ',', false, true } },
|
||||
{ u"RUB"_q, { "", ' ', ',', false, true } },
|
||||
{ u"SAR"_q, { "", ',', '.', true, true } },
|
||||
{ u"SEK"_q, { "", '.', ',', false, true } },
|
||||
{ u"SGD"_q, {} },
|
||||
{ u"SYP"_q, { "", ',', '.', true, true } },
|
||||
{ u"THB"_q, { "\xE0\xB8\xBF" } },
|
||||
{ u"TJS"_q, { "", ' ', ';', false, true } },
|
||||
{ u"TRY"_q, { "", '.', ',', false, true } },
|
||||
{ u"TTD"_q, {} },
|
||||
{ u"TWD"_q, { "NT$" } },
|
||||
{ u"TZS"_q, {} },
|
||||
{ u"UAH"_q, { "", ' ', ',', false } },
|
||||
{ u"UGX"_q, { "", ',', '.', true, false, 0 } },
|
||||
{ u"USD"_q, { "$" } },
|
||||
{ u"UYU"_q, { "", '.', ',', true, true } },
|
||||
{ u"UZS"_q, { "", ' ', ',', false, true } },
|
||||
{ u"VEF"_q, { "", '.', ',', true, true } },
|
||||
{ u"VND"_q, { "\xE2\x82\xAB", '.', ',', false, true, 0 } },
|
||||
{ u"YER"_q, { "", ',', '.', true, true } },
|
||||
{ u"ZAR"_q, { "", ',', '.', true, true } },
|
||||
|
||||
//{ u"VUV"_q, { "", ',', '.', false, false, 0 } },
|
||||
//{ u"WST"_q, {} },
|
||||
//{ u"XAF"_q, { "FCFA", ',', '.', false, false, 0 } },
|
||||
//{ u"XCD"_q, {} },
|
||||
//{ u"XOF"_q, { "CFA", ' ', ',', false, false, 0 } },
|
||||
//{ u"XPF"_q, { "", ',', '.', false, false, 0 } },
|
||||
//{ u"ZMW"_q, {} },
|
||||
//{ u"ANG"_q, {} },
|
||||
//{ u"RWF"_q, { "", ' ', ',', true, true, 0 } },
|
||||
//{ u"PGK"_q, {} },
|
||||
//{ u"TOP"_q, {} },
|
||||
//{ u"SBD"_q, {} },
|
||||
//{ u"SCR"_q, {} },
|
||||
//{ u"SHP"_q, {} },
|
||||
//{ u"SLL"_q, {} },
|
||||
//{ u"SOS"_q, {} },
|
||||
//{ u"SRD"_q, {} },
|
||||
//{ u"STD"_q, {} },
|
||||
//{ u"SVC"_q, {} },
|
||||
//{ u"SZL"_q, {} },
|
||||
//{ u"AOA"_q, {} },
|
||||
//{ u"AWG"_q, {} },
|
||||
//{ u"BBD"_q, {} },
|
||||
//{ u"BIF"_q, { "", ',', '.', false, false, 0 } },
|
||||
//{ u"BMD"_q, {} },
|
||||
//{ u"BSD"_q, {} },
|
||||
//{ u"BWP"_q, {} },
|
||||
//{ u"BZD"_q, {} },
|
||||
//{ u"CDF"_q, { "", ',', '.', false } },
|
||||
//{ u"CVE"_q, { "", ',', '.', true, false, 0 } },
|
||||
//{ u"DJF"_q, { "", ',', '.', false, false, 0 } },
|
||||
//{ u"FJD"_q, {} },
|
||||
//{ u"FKP"_q, {} },
|
||||
//{ u"GIP"_q, {} },
|
||||
//{ u"GMD"_q, { "", ',', '.', false } },
|
||||
//{ u"GNF"_q, { "", ',', '.', false, false, 0 } },
|
||||
//{ u"GYD"_q, {} },
|
||||
//{ u"HTG"_q, {} },
|
||||
//{ u"KHR"_q, { "", ',', '.', false } },
|
||||
//{ u"KMF"_q, { "", ',', '.', false, false, 0 } },
|
||||
//{ u"KYD"_q, {} },
|
||||
//{ u"LAK"_q, { "", ',', '.', false } },
|
||||
//{ u"LRD"_q, {} },
|
||||
//{ u"LSL"_q, { "", ',', '.', false } },
|
||||
//{ u"MGA"_q, { "", ',', '.', true, false, 0 } },
|
||||
//{ u"MKD"_q, { "", '.', ',', false, true } },
|
||||
//{ u"MWK"_q, {} },
|
||||
//{ u"NAD"_q, {} },
|
||||
//{ u"CLF"_q, { "", ',', '.', true, false, 4 } },
|
||||
//{ u"KWD"_q, { "", ',', '.', true, false, 3 } },
|
||||
//{ u"LYD"_q, { "", ',', '.', true, false, 3 } },
|
||||
//{ u"OMR"_q, { "", ',', '.', true, false, 3 } },
|
||||
//{ u"TND"_q, { "", ',', '.', true, false, 3 } },
|
||||
//{ u"UYI"_q, { "", ',', '.', true, false, 0 } },
|
||||
//{ u"MRO"_q, { "", ',', '.', true, false, 1 } },
|
||||
};
|
||||
static const auto kRulesMap = [] {
|
||||
// flat_multi_map_pair_type lacks some required constructors :(
|
||||
auto &&list = kRules | ranges::views::transform([](auto &&pair) {
|
||||
return base::flat_multi_map_pair_type<QString, CurrencyRule>(
|
||||
pair.first,
|
||||
pair.second);
|
||||
});
|
||||
return base::flat_map<QString, CurrencyRule>(begin(list), end(list));
|
||||
}();
|
||||
const auto i = kRulesMap.find(currency);
|
||||
return (i != end(kRulesMap)) ? i->second : CurrencyRule{};
|
||||
}
|
||||
|
||||
[[nodiscard]] QString FormatWithSeparators(
|
||||
double amount,
|
||||
int precision,
|
||||
char decimal,
|
||||
char thousands) {
|
||||
Expects(decimal != 0);
|
||||
|
||||
// Thanks https://stackoverflow.com/a/5058949
|
||||
struct FormattingHelper : std::numpunct<char> {
|
||||
FormattingHelper(char decimal, char thousands)
|
||||
: decimal(decimal)
|
||||
, thousands(thousands) {
|
||||
}
|
||||
|
||||
char do_decimal_point() const override { return decimal; }
|
||||
char do_thousands_sep() const override { return thousands; }
|
||||
std::string do_grouping() const override { return "\3"; }
|
||||
|
||||
char decimal = '.';
|
||||
char thousands = ',';
|
||||
};
|
||||
|
||||
auto stream = std::ostringstream();
|
||||
stream.imbue(std::locale(
|
||||
stream.getloc(),
|
||||
new FormattingHelper(decimal, thousands ? thousands : '?')));
|
||||
stream.precision(precision);
|
||||
stream << std::fixed << amount;
|
||||
auto result = QString::fromStdString(stream.str());
|
||||
if (!thousands) {
|
||||
result.replace('?', QString());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QString FormatImageSizeText(const QSize &size) {
|
||||
return QString::number(size.width())
|
||||
+ QChar(215)
|
||||
+ QString::number(size.height());
|
||||
}
|
||||
|
||||
QString FormatPhone(QString phone) {
|
||||
if (phone.isEmpty()) {
|
||||
return QString();
|
||||
}
|
||||
if (phone.at(0) == '0') {
|
||||
return phone;
|
||||
}
|
||||
phone = phone.remove(QChar::Space);
|
||||
return Countries::Instance().format({
|
||||
.phone = (phone.at(0) == '+') ? phone.mid(1) : phone,
|
||||
}).formatted;
|
||||
}
|
||||
|
||||
QString FormatTTL(float64 ttl) {
|
||||
if (ttl < 86400) {
|
||||
return tr::lng_hours(tr::now, lt_count, int(ttl / 3600));
|
||||
} else if (ttl < 86400 * 7) {
|
||||
return tr::lng_days(tr::now, lt_count, int(ttl / (86400)));
|
||||
} else if (ttl < 86400 * 31) {
|
||||
const auto days = int(ttl / 86400);
|
||||
if ((int(ttl) % 7) == 0) {
|
||||
return tr::lng_weeks(tr::now, lt_count, int(days / 7));
|
||||
} else {
|
||||
return tr::lng_weeks(tr::now, lt_count, int(days / 7))
|
||||
+ ' '
|
||||
+ tr::lng_days(tr::now, lt_count, int(days % 7));
|
||||
}
|
||||
} else if (ttl <= (86400 * 31) * 11) {
|
||||
return tr::lng_months(tr::now, lt_count, int(ttl / (86400 * 31)));
|
||||
} else {
|
||||
return tr::lng_years({}, lt_count, std::round(ttl / (86400 * 365)));
|
||||
}
|
||||
}
|
||||
|
||||
QString FormatTTLAfter(float64 ttl) {
|
||||
return (ttl <= 3600 * 23)
|
||||
? tr::lng_settings_ttl_after_hours(tr::now, lt_count, int(ttl / 3600))
|
||||
: (ttl <= (86400) * 6)
|
||||
? tr::lng_settings_ttl_after_days(
|
||||
tr::now,
|
||||
lt_count,
|
||||
int(ttl / (86400)))
|
||||
: (ttl <= (86400 * 7) * 3)
|
||||
? tr::lng_settings_ttl_after_weeks(
|
||||
tr::now,
|
||||
lt_count,
|
||||
int(ttl / (86400 * 7)))
|
||||
: (ttl <= (86400 * 31) * 11)
|
||||
? tr::lng_settings_ttl_after_months(
|
||||
tr::now,
|
||||
lt_count,
|
||||
int(ttl / (86400 * 31)))
|
||||
: tr::lng_settings_ttl_after_years(
|
||||
tr::now,
|
||||
lt_count,
|
||||
std::round(ttl / (86400 * 365)));
|
||||
}
|
||||
|
||||
QString FormatTTLTiny(float64 ttl) {
|
||||
return (ttl <= 3600 * 9)
|
||||
? tr::lng_hours_tiny(tr::now, lt_count, int(ttl / 3600))
|
||||
: (ttl <= (86400) * 6)
|
||||
? tr::lng_days_tiny(tr::now, lt_count, int(ttl / (86400)))
|
||||
: (ttl <= (86400 * 7) * 3)
|
||||
? tr::lng_weeks_tiny(tr::now, lt_count, int(ttl / (86400 * 7)))
|
||||
: (ttl <= (86400 * 31) * 11)
|
||||
? tr::lng_months_tiny({}, lt_count, int(ttl / (86400 * 31)))
|
||||
: (ttl <= 86400 * 366)
|
||||
? tr::lng_years_tiny({}, lt_count, std::round(ttl / (86400 * 365)))
|
||||
: QString();
|
||||
}
|
||||
|
||||
QString FormatMuteFor(float64 sec) {
|
||||
return (sec <= 60)
|
||||
? tr::lng_seconds(tr::now, lt_count, sec)
|
||||
: (sec <= 60 * 59)
|
||||
? tr::lng_minutes(tr::now, lt_count, int(sec / 60))
|
||||
: FormatTTL(sec);
|
||||
}
|
||||
|
||||
QString FormatMuteForTiny(float64 sec) {
|
||||
return (sec <= 60)
|
||||
? QString()
|
||||
: (sec <= 60 * 59)
|
||||
? tr::lng_minutes_tiny(tr::now, lt_count, std::round(sec / 60))
|
||||
: (sec <= 3600 * 23)
|
||||
? tr::lng_hours_tiny(tr::now, lt_count, std::round(sec / 3600))
|
||||
: (sec <= 86400 * 6)
|
||||
? tr::lng_days_tiny(tr::now, lt_count, std::round(sec / 86400))
|
||||
: (sec <= (86400 * 7) * 3)
|
||||
? tr::lng_weeks_tiny(tr::now, lt_count, std::round(sec / (86400 * 7)))
|
||||
: (sec <= (86400 * 31) * 11)
|
||||
? tr::lng_months_tiny({}, lt_count, std::round(sec / (86400 * 31)))
|
||||
: (sec <= 86400 * 366)
|
||||
? tr::lng_years_tiny({}, lt_count, std::round(sec / (86400 * 365)))
|
||||
: QString();
|
||||
}
|
||||
|
||||
QString FormatResetCloudPasswordIn(float64 sec) {
|
||||
return (sec >= 3600) ? FormatTTL(sec) : FormatDurationText(sec);
|
||||
}
|
||||
|
||||
QString FormatDialogsDate(const QDateTime &lastTime) {
|
||||
// Show all dates that are in the last 20 hours in time format.
|
||||
constexpr int kRecentlyInSeconds = 20 * 3600;
|
||||
|
||||
const auto now = QDateTime::currentDateTime();
|
||||
const auto nowDate = now.date();
|
||||
const auto lastDate = lastTime.date();
|
||||
|
||||
if ((lastDate == nowDate)
|
||||
|| (std::abs(lastTime.secsTo(now)) < kRecentlyInSeconds)) {
|
||||
return QLocale().toString(lastTime.time(), QLocale::ShortFormat);
|
||||
} else if (std::abs(lastDate.daysTo(nowDate)) < 7) {
|
||||
return langDayOfWeek(lastDate);
|
||||
} else {
|
||||
return QLocale().toString(lastDate, QLocale::ShortFormat);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
60
Telegram/SourceFiles/ui/text/format_values.h
Normal file
60
Telegram/SourceFiles/ui/text/format_values.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Ui {
|
||||
|
||||
inline constexpr auto FileStatusSizeReady = 0xFFFFFFF0LL;
|
||||
inline constexpr auto FileStatusSizeLoaded = 0xFFFFFFF1LL;
|
||||
inline constexpr auto FileStatusSizeFailed = 0xFFFFFFF2LL;
|
||||
|
||||
inline const QString kCreditsCurrency = u"XTR"_q;
|
||||
|
||||
[[nodiscard]] QString FormatSizeText(qint64 size);
|
||||
[[nodiscard]] QString FormatDownloadText(qint64 ready, qint64 total);
|
||||
[[nodiscard]] QString FormatProgressText(qint64 ready, qint64 total);
|
||||
[[nodiscard]] QString FormatDateTime(QDateTime date);
|
||||
[[nodiscard]] QString FormatDateTimeSavedFrom(QDateTime date);
|
||||
[[nodiscard]] QString FormatDurationText(qint64 duration);
|
||||
[[nodiscard]] QString FormatDurationWords(qint64 duration);
|
||||
[[nodiscard]] QString FormatDurationWordsSlowmode(qint64 duration);
|
||||
[[nodiscard]] QString FormatDurationAndSizeText(qint64 duration, qint64 size);
|
||||
[[nodiscard]] QString FormatGifAndSizeText(qint64 size);
|
||||
[[nodiscard]] QString FormatPlayedText(qint64 played, qint64 duration);
|
||||
[[nodiscard]] QString FormatImageSizeText(const QSize &size);
|
||||
[[nodiscard]] QString FormatPhone(QString phone);
|
||||
[[nodiscard]] QString FormatTTL(float64 ttl);
|
||||
[[nodiscard]] QString FormatTTLAfter(float64 ttl);
|
||||
[[nodiscard]] QString FormatTTLTiny(float64 ttl);
|
||||
[[nodiscard]] QString FormatMuteFor(float64 sec);
|
||||
[[nodiscard]] QString FormatMuteForTiny(float64 sec);
|
||||
[[nodiscard]] QString FormatResetCloudPasswordIn(float64 sec);
|
||||
[[nodiscard]] QString FormatDialogsDate(const QDateTime &lastTime);
|
||||
|
||||
struct CurrencyRule {
|
||||
const char *international = "";
|
||||
char thousands = ',';
|
||||
char decimal = '.';
|
||||
bool left = true;
|
||||
bool space = false;
|
||||
int exponent = 2;
|
||||
bool stripDotZero = false;
|
||||
};
|
||||
|
||||
[[nodiscard]] QString FillAmountAndCurrency(
|
||||
int64 amount,
|
||||
const QString ¤cy,
|
||||
bool forceStripDotZero = false);
|
||||
[[nodiscard]] CurrencyRule LookupCurrencyRule(const QString ¤cy);
|
||||
[[nodiscard]] QString FormatWithSeparators(
|
||||
double amount,
|
||||
int precision,
|
||||
char decimal,
|
||||
char thousands);
|
||||
|
||||
} // namespace Ui
|
||||
122
Telegram/SourceFiles/ui/text/text_lottie_custom_emoji.cpp
Normal file
122
Telegram/SourceFiles/ui/text/text_lottie_custom_emoji.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "ui/text/text_lottie_custom_emoji.h"
|
||||
|
||||
#include "lottie/lottie_icon.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
|
||||
namespace Ui::Text {
|
||||
|
||||
LottieCustomEmoji::LottieCustomEmoji(Lottie::IconDescriptor &&descriptor)
|
||||
: LottieCustomEmoji(std::move(descriptor), nullptr) {
|
||||
}
|
||||
|
||||
LottieCustomEmoji::LottieCustomEmoji(
|
||||
Lottie::IconDescriptor &&descriptor,
|
||||
Fn<void()> repaint)
|
||||
: _entityData(!descriptor.name.isEmpty()
|
||||
? descriptor.name
|
||||
: !descriptor.path.isEmpty()
|
||||
? descriptor.path
|
||||
: (Unexpected("LottieCustomEmoji: descriptor.name or descriptor.path"),
|
||||
QString()))
|
||||
, _width(descriptor.sizeOverride.width())
|
||||
, _icon(Lottie::MakeIcon(std::move(descriptor)))
|
||||
, _repaint(std::move(repaint)) {
|
||||
if (!_width && _icon && _icon->valid()) {
|
||||
_width = _icon->width();
|
||||
startAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
int LottieCustomEmoji::width() {
|
||||
return _width;
|
||||
}
|
||||
|
||||
QString LottieCustomEmoji::entityData() {
|
||||
return _entityData;
|
||||
}
|
||||
|
||||
void LottieCustomEmoji::paint(QPainter &p, const Context &context) {
|
||||
if (!_icon || !_icon->valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto paused = context.paused
|
||||
|| context.internal.forceFirstFrame
|
||||
|| context.internal.overrideFirstWithLastFrame;
|
||||
|
||||
if (paused) {
|
||||
const auto frame = context.internal.forceLastFrame
|
||||
? _icon->framesCount() - 1
|
||||
: 0;
|
||||
_icon->jumpTo(frame, _repaint);
|
||||
} else if (!_icon->animating()) {
|
||||
startAnimation();
|
||||
}
|
||||
|
||||
_icon->paint(
|
||||
p,
|
||||
context.position.x(),
|
||||
context.position.y(),
|
||||
context.textColor);
|
||||
}
|
||||
|
||||
void LottieCustomEmoji::unload() {
|
||||
if (_icon) {
|
||||
_icon->jumpTo(0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
bool LottieCustomEmoji::ready() {
|
||||
return _icon && _icon->valid();
|
||||
}
|
||||
|
||||
bool LottieCustomEmoji::readyInDefaultState() {
|
||||
return _icon && _icon->valid() && _icon->frameIndex() == 0;
|
||||
}
|
||||
|
||||
void LottieCustomEmoji::startAnimation() {
|
||||
if (!_icon || !_icon->valid() || _icon->framesCount() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
_icon->animate(
|
||||
_repaint,
|
||||
0,
|
||||
_icon->framesCount() - 1);
|
||||
}
|
||||
|
||||
QString LottieEmojiData(Lottie::IconDescriptor descriptor) {
|
||||
return !descriptor.name.isEmpty()
|
||||
? descriptor.name
|
||||
: !descriptor.path.isEmpty()
|
||||
? descriptor.path
|
||||
: QString();
|
||||
}
|
||||
|
||||
TextWithEntities LottieEmoji(Lottie::IconDescriptor descriptor) {
|
||||
return SingleCustomEmoji(LottieEmojiData(std::move(descriptor)));
|
||||
}
|
||||
|
||||
MarkedContext LottieEmojiContext(Lottie::IconDescriptor descriptor) {
|
||||
auto customEmojiFactory = [descriptor = std::move(descriptor)](
|
||||
QStringView data,
|
||||
const MarkedContext &context
|
||||
) mutable -> std::unique_ptr<CustomEmoji> {
|
||||
if (data == LottieEmojiData(descriptor)) {
|
||||
return std::make_unique<LottieCustomEmoji>(
|
||||
std::move(descriptor),
|
||||
context.repaint);
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
return { .customEmojiFactory = std::move(customEmojiFactory) };
|
||||
}
|
||||
|
||||
} // namespace Ui::Text
|
||||
47
Telegram/SourceFiles/ui/text/text_lottie_custom_emoji.h
Normal file
47
Telegram/SourceFiles/ui/text/text_lottie_custom_emoji.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/text/text_custom_emoji.h"
|
||||
|
||||
namespace Lottie {
|
||||
struct IconDescriptor;
|
||||
class Icon;
|
||||
} // namespace Lottie
|
||||
|
||||
namespace Ui::Text {
|
||||
|
||||
class LottieCustomEmoji final : public CustomEmoji {
|
||||
public:
|
||||
explicit LottieCustomEmoji(Lottie::IconDescriptor &&descriptor);
|
||||
LottieCustomEmoji(
|
||||
Lottie::IconDescriptor &&descriptor,
|
||||
Fn<void()> repaint);
|
||||
|
||||
int width() override;
|
||||
QString entityData() override;
|
||||
void paint(QPainter &p, const Context &context) override;
|
||||
void unload() override;
|
||||
bool ready() override;
|
||||
bool readyInDefaultState() override;
|
||||
|
||||
private:
|
||||
void startAnimation();
|
||||
|
||||
QString _entityData;
|
||||
int _width = 0;
|
||||
std::unique_ptr<Lottie::Icon> _icon;
|
||||
Fn<void()> _repaint;
|
||||
|
||||
};
|
||||
|
||||
[[nodiscard]] QString LottieEmojiData(Lottie::IconDescriptor);
|
||||
[[nodiscard]] TextWithEntities LottieEmoji(Lottie::IconDescriptor);
|
||||
[[nodiscard]] MarkedContext LottieEmojiContext(Lottie::IconDescriptor);
|
||||
|
||||
} // namespace Ui::Text
|
||||
153
Telegram/SourceFiles/ui/text/text_options.cpp
Normal file
153
Telegram/SourceFiles/ui/text/text_options.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "ui/text/text_options.h"
|
||||
|
||||
#include "styles/style_window.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
TextParseOptions HistoryTextOptions = {
|
||||
TextParseLinks
|
||||
| TextParseMentions
|
||||
| TextParseHashtags
|
||||
| TextParseMultiline
|
||||
| TextParseMarkdown, // flags
|
||||
0, // maxw
|
||||
0, // maxh
|
||||
Qt::LayoutDirectionAuto, // dir
|
||||
};
|
||||
|
||||
TextParseOptions HistoryBotOptions = {
|
||||
TextParseLinks
|
||||
| TextParseMentions
|
||||
| TextParseHashtags
|
||||
| TextParseBotCommands
|
||||
| TextParseMultiline
|
||||
| TextParseMarkdown, // flags
|
||||
0, // maxw
|
||||
0, // maxh
|
||||
Qt::LayoutDirectionAuto, // dir
|
||||
};
|
||||
|
||||
TextParseOptions HistoryServiceOptions = {
|
||||
TextParseLinks
|
||||
| TextParseMentions
|
||||
//| TextParseMultiline
|
||||
| TextParseHashtags
|
||||
| TextParseMarkdown, // flags
|
||||
0, // maxw
|
||||
0, // maxh
|
||||
Qt::LayoutDirectionAuto, // lang-dependent
|
||||
};
|
||||
|
||||
TextParseOptions HistoryTextNoMonoOptions = {
|
||||
TextParseLinks
|
||||
| TextParseMentions
|
||||
| TextParseHashtags
|
||||
| TextParseMultiline, // flags
|
||||
0, // maxw
|
||||
0, // maxh
|
||||
Qt::LayoutDirectionAuto, // dir
|
||||
};
|
||||
|
||||
TextParseOptions HistoryBotNoMonoOptions = {
|
||||
TextParseLinks
|
||||
| TextParseMentions
|
||||
| TextParseHashtags
|
||||
| TextParseBotCommands
|
||||
| TextParseMultiline, // flags
|
||||
0, // maxw
|
||||
0, // maxh
|
||||
Qt::LayoutDirectionAuto, // dir
|
||||
};
|
||||
|
||||
TextParseOptions TextNameOptions = {
|
||||
0, // flags
|
||||
4096, // maxw
|
||||
1, // maxh
|
||||
Qt::LayoutDirectionAuto, // lang-dependent
|
||||
};
|
||||
|
||||
TextParseOptions TextDialogOptions = {
|
||||
TextParseColorized | TextParseMarkdown, // flags
|
||||
0, // maxw is style-dependent
|
||||
1, // maxh
|
||||
Qt::LayoutDirectionAuto, // lang-dependent
|
||||
};
|
||||
|
||||
TextParseOptions WebpageTitleOptions = {
|
||||
TextParseMultiline, // flags
|
||||
0, // maxw
|
||||
0, // maxh
|
||||
Qt::LayoutDirectionAuto, // dir
|
||||
};
|
||||
|
||||
TextParseOptions WebpageDescriptionOptions = {
|
||||
TextParseLinks
|
||||
| TextParseMentions
|
||||
| TextParseHashtags
|
||||
| TextParseMultiline
|
||||
| TextParseMarkdown, // flags
|
||||
0, // maxw
|
||||
0, // maxh
|
||||
Qt::LayoutDirectionAuto, // dir
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
void InitTextOptions() {
|
||||
TextDialogOptions.maxw = st::columnMaximalWidthLeft * 2;
|
||||
WebpageTitleOptions.maxh = st::webPageTitleFont->height * 2;
|
||||
WebpageTitleOptions.maxw
|
||||
= WebpageDescriptionOptions.maxw
|
||||
= st::msgMaxWidth
|
||||
- st::msgPadding.left()
|
||||
- st::messageQuoteStyle.padding.left()
|
||||
- st::messageQuoteStyle.padding.right()
|
||||
- st::msgPadding.right();
|
||||
}
|
||||
|
||||
const TextParseOptions &ItemTextDefaultOptions() {
|
||||
return HistoryTextOptions;
|
||||
}
|
||||
|
||||
const TextParseOptions &ItemTextBotDefaultOptions() {
|
||||
return HistoryBotOptions;
|
||||
}
|
||||
|
||||
const TextParseOptions &ItemTextNoMonoOptions() {
|
||||
return HistoryTextNoMonoOptions;
|
||||
}
|
||||
|
||||
const TextParseOptions &ItemTextBotNoMonoOptions() {
|
||||
return HistoryBotNoMonoOptions;
|
||||
}
|
||||
|
||||
const TextParseOptions &ItemTextServiceOptions() {
|
||||
return HistoryServiceOptions;
|
||||
}
|
||||
|
||||
const TextParseOptions &WebpageTextTitleOptions() {
|
||||
return WebpageTitleOptions;
|
||||
}
|
||||
|
||||
const TextParseOptions &WebpageTextDescriptionOptions() {
|
||||
return WebpageDescriptionOptions;
|
||||
}
|
||||
|
||||
const TextParseOptions &NameTextOptions() {
|
||||
return TextNameOptions;
|
||||
}
|
||||
|
||||
const TextParseOptions &DialogTextOptions() {
|
||||
return TextDialogOptions;
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
28
Telegram/SourceFiles/ui/text/text_options.h
Normal file
28
Telegram/SourceFiles/ui/text/text_options.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
struct TextParseOptions;
|
||||
|
||||
namespace Ui {
|
||||
|
||||
void InitTextOptions();
|
||||
|
||||
const TextParseOptions &ItemTextDefaultOptions();
|
||||
const TextParseOptions &ItemTextBotDefaultOptions();
|
||||
const TextParseOptions &ItemTextNoMonoOptions();
|
||||
const TextParseOptions &ItemTextBotNoMonoOptions();
|
||||
const TextParseOptions &ItemTextServiceOptions();
|
||||
|
||||
const TextParseOptions &WebpageTextTitleOptions();
|
||||
const TextParseOptions &WebpageTextDescriptionOptions();
|
||||
|
||||
const TextParseOptions &NameTextOptions();
|
||||
const TextParseOptions &DialogTextOptions();
|
||||
|
||||
} // namespace Ui
|
||||
Reference in New Issue
Block a user