diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index cd1ff99eae..619f83ea47 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -112,6 +112,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_chat_status_unaccessible" = "group is inaccessible"; "lng_chat_status_members#one" = "{count} member"; "lng_chat_status_members#other" = "{count} members"; +"lng_chat_status_members_demical#one" = "{count_decimal} member"; +"lng_chat_status_members_demical#other" = "{count_decimal} members"; "lng_chat_status_online#one" = "{count} online"; "lng_chat_status_online#other" = "{count} online"; "lng_chat_status_members_online" = "{members_count}, {online_count}"; @@ -119,11 +121,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_channel_status" = "channel"; "lng_group_status" = "group"; -"lng_channel_members_link#one" = "{count} member"; -"lng_channel_members_link#other" = "{count} members"; -"lng_channel_admins_link#one" = "{count} administrator"; -"lng_channel_admins_link#other" = "{count} administrators"; - "lng_channel_views#one" = "{count_short}"; "lng_channel_views#other" = "{count_short}"; @@ -1973,6 +1970,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_polls_votes_count#other" = "{count} votes"; "lng_polls_votes_count_short#one" = "{count_short} vote"; "lng_polls_votes_count_short#other" = "{count_short} votes"; +"lng_polls_votes_count_demical#one" = "{count_decimal} vote"; +"lng_polls_votes_count_demical#other" = "{count_decimal} votes"; "lng_polls_votes_none" = "No votes"; "lng_polls_retract" = "Retract vote"; "lng_polls_stop" = "Stop poll"; diff --git a/Telegram/SourceFiles/boxes/confirm_box.cpp b/Telegram/SourceFiles/boxes/confirm_box.cpp index 8045fe5027..4a2e10bba7 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_box.cpp @@ -790,7 +790,7 @@ ConfirmInviteBox::ConfirmInviteBox( const auto status = [&] { if (_participants.empty() || _participants.size() >= count) { if (count > 0) { - return lng_chat_status_members(lt_count, count); + return lng_chat_status_members_demical(lt_count_decimal, count); } else { return lang(_isChannel ? lng_channel_status diff --git a/Telegram/SourceFiles/boxes/peer_list_box.cpp b/Telegram/SourceFiles/boxes/peer_list_box.cpp index ba729bfbb5..8da8f15228 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_box.cpp @@ -382,7 +382,7 @@ void PeerListRow::refreshStatus() { if (!chat->amIn()) { setStatusText(lang(lng_chat_status_unaccessible)); } else if (chat->count > 0) { - setStatusText(lng_chat_status_members(lt_count, chat->count)); + setStatusText(lng_chat_status_members_demical(lt_count_decimal, chat->count)); } else { setStatusText(lang(lng_group_status)); } diff --git a/Telegram/SourceFiles/codegen/lang/generator.cpp b/Telegram/SourceFiles/codegen/lang/generator.cpp index 62b9e81bf1..83b1579f9d 100644 --- a/Telegram/SourceFiles/codegen/lang/generator.cpp +++ b/Telegram/SourceFiles/codegen/lang/generator.cpp @@ -126,6 +126,13 @@ enum LangKey : int {\n"; QString lang(LangKey key);\n\ \n"; + // Plural Type Map. + std::map pluralType { + { kPluralTag, QString("None") }, + { kPluralShortTag, QString("Short") }, + { kPluralDecimalSeparationTag, QString("DecimalSeparation") } + }; + for (auto &entry : langpack_.entries) { auto isPlural = !entry.keyBase.isEmpty(); auto &key = entry.key; @@ -136,12 +143,11 @@ QString lang(LangKey key);\n\ auto nonPluralTagFound = false; for (auto &tagData : entry.tags) { auto &tag = tagData.tag; - auto isPluralTag = isPlural && (tag == kPluralTag || tag == kPluralShortTag); + auto isPluralTag = isPlural && (pluralType.find(tag) != pluralType.end()); genericParams.push_back("lngtag_" + tag + ", " + (isPluralTag ? "float64 " : "const ResultString &") + tag + "__val"); params.push_back("lngtag_" + tag + ", " + (isPluralTag ? "float64 " : "const QString &") + tag + "__val"); if (isPluralTag) { - const auto isShortTag = (tag == kPluralShortTag) ? ("true") : ("false"); - plural = "\tauto plural = Lang::Plural(" + key + ", " + tag + "__val, " + isShortTag + ");\n"; + plural = "\tauto plural = Lang::Plural(" + key + ", " + tag + "__val, Lang::PluralType::" + pluralType[tag] + ");\n"; applyTags.push_back("\tresult = Lang::ReplaceTag::Call(std::move(result), lt_" + tag + ", Lang::StartReplacements::Call(std::move(plural.replacement)));\n"); } else { nonPluralTagFound = true; diff --git a/Telegram/SourceFiles/codegen/lang/parsed_file.cpp b/Telegram/SourceFiles/codegen/lang/parsed_file.cpp index c34c3c0096..823aa977a1 100644 --- a/Telegram/SourceFiles/codegen/lang/parsed_file.cpp +++ b/Telegram/SourceFiles/codegen/lang/parsed_file.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "codegen/lang/parsed_file.h" #include +#include #include #include #include @@ -76,6 +77,13 @@ const std::array kPluralParts = { { const QString kPluralTag = "count"; const QString kPluralShortTag = kPluralTag + "_short"; +const QString kPluralDecimalSeparationTag = kPluralTag + "_decimal"; + +const std::set pluralTypeSet { + kPluralTag, + kPluralShortTag, + kPluralDecimalSeparationTag +}; QString ComputePluralKey(const QString &base, int index) { return base + "__plural" + QString::number(index); @@ -145,7 +153,7 @@ void ParsedFile::fillPluralTags() { } } logAssert(!tags.empty()); - logAssert(tags.front().tag == kPluralTag || tags.front().tag == kPluralShortTag); + logAssert(pluralTypeSet.find(tags.front().tag) != pluralTypeSet.end()); // Set this tags list to all plural variants. for (auto j = i; j != i + kPluralPartCount; ++j) { @@ -322,7 +330,7 @@ void ParsedFile::addEntity(QString key, const QString &value) { for (auto &tag : entry.tags) { if (std::find(realEntry.tags.begin(), realEntry.tags.end(), tag) == realEntry.tags.end()) { - if (tag.tag == kPluralTag || tag.tag == kPluralShortTag) { + if (pluralTypeSet.find(tag.tag) != pluralTypeSet.end()) { realEntry.tags.insert(realEntry.tags.begin(), tag); } else { realEntry.tags.push_back(tag); diff --git a/Telegram/SourceFiles/codegen/lang/parsed_file.h b/Telegram/SourceFiles/codegen/lang/parsed_file.h index f05e202f31..e05c0a2ce5 100644 --- a/Telegram/SourceFiles/codegen/lang/parsed_file.h +++ b/Telegram/SourceFiles/codegen/lang/parsed_file.h @@ -22,6 +22,7 @@ constexpr auto kPluralPartCount = 6; extern const std::array kPluralParts; extern const QString kPluralTag; extern const QString kPluralShortTag; +extern const QString kPluralDecimalSeparationTag; QString ComputePluralKey(const QString &base, int index); struct LangPack { diff --git a/Telegram/SourceFiles/history/media/history_media_poll.cpp b/Telegram/SourceFiles/history/media/history_media_poll.cpp index 01335f7d94..ca767adaf0 100644 --- a/Telegram/SourceFiles/history/media/history_media_poll.cpp +++ b/Telegram/SourceFiles/history/media/history_media_poll.cpp @@ -810,7 +810,7 @@ TextState HistoryPoll::textState(QPoint point, StateRequest request) const { using Flag = Text::StateRequest::Flag; if (request.flags & Flag::LookupCustomTooltip) { result.customTooltipText = answer.votes - ? lng_polls_votes_count(lt_count, answer.votes) + ? lng_polls_votes_count_demical(lt_count_decimal, answer.votes) : lang(lng_polls_votes_none); } } diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp index 3835264a4c..34b9c5e18f 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp @@ -775,7 +775,7 @@ void TopBarWidget::updateOnlineDisplay() { } else if (chat->count <= 0) { text = lang(lng_group_status); } else { - text = lng_chat_status_members(lt_count, chat->count); + text = lng_chat_status_members_demical(lt_count_decimal, chat->count); } } else { const auto self = Auth().user(); @@ -788,11 +788,11 @@ void TopBarWidget::updateOnlineDisplay() { } } if (online > 0 && !onlyMe) { - auto membersCount = lng_chat_status_members(lt_count, chat->participants.size()); + auto membersCount = lng_chat_status_members_demical(lt_count_decimal, chat->participants.size()); auto onlineCount = lng_chat_status_online(lt_count, online); text = lng_chat_status_members_online(lt_members_count, membersCount, lt_online_count, onlineCount); } else if (chat->participants.size() > 0) { - text = lng_chat_status_members(lt_count, chat->participants.size()); + text = lng_chat_status_members_demical(lt_count_decimal, chat->participants.size()); } else { text = lang(lng_group_status); } @@ -814,16 +814,16 @@ void TopBarWidget::updateOnlineDisplay() { } } if (online && !onlyMe) { - auto membersCount = lng_chat_status_members(lt_count, channel->membersCount()); + auto membersCount = lng_chat_status_members_demical(lt_count_decimal, channel->membersCount()); auto onlineCount = lng_chat_status_online(lt_count, online); text = lng_chat_status_members_online(lt_members_count, membersCount, lt_online_count, onlineCount); } else if (channel->membersCount() > 0) { - text = lng_chat_status_members(lt_count, channel->membersCount()); + text = lng_chat_status_members_demical(lt_count_decimal, channel->membersCount()); } else { text = lang(lng_group_status); } } else if (channel->membersCount() > 0) { - text = lng_chat_status_members(lt_count, channel->membersCount()); + text = lng_chat_status_members_demical(lt_count_decimal, channel->membersCount()); } else { text = lang(channel->isMegagroup() ? lng_group_status : lng_channel_status); } diff --git a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp index 6b6171623f..1af0f0f621 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp @@ -802,7 +802,7 @@ object_ptr SetupChannelMembers( auto membersText = MembersCountValue( channel ) | rpl::map([](int count) { - return lng_chat_status_members(lt_count, count); + return lng_chat_status_members_demical(lt_count_decimal, count); }); auto membersCallback = [controller, channel] { controller->showSection(Info::Memento( diff --git a/Telegram/SourceFiles/info/profile/info_profile_cover.cpp b/Telegram/SourceFiles/info/profile/info_profile_cover.cpp index 795740adf2..dd7f440062 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_cover.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_cover.cpp @@ -126,7 +126,7 @@ bool SectionToggle::checkRippleStartPosition(QPoint position) const { } auto MembersStatusText(int count) { - return lng_chat_status_members(lt_count, count); + return lng_chat_status_members_demical(lt_count_decimal, count); }; auto OnlineStatusText(int count) { @@ -139,7 +139,7 @@ auto ChatStatusText(int fullCount, int onlineCount, bool isGroup) { lt_members_count, MembersStatusText(fullCount), lt_online_count, OnlineStatusText(onlineCount)); } else if (fullCount > 0) { - return lng_chat_status_members(lt_count, fullCount); + return lng_chat_status_members_demical(lt_count_decimal, fullCount); } return lang(isGroup ? lng_group_status diff --git a/Telegram/SourceFiles/info/profile/info_profile_members.cpp b/Telegram/SourceFiles/info/profile/info_profile_members.cpp index 8a333e8456..2613740a08 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_members.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_members.cpp @@ -166,7 +166,7 @@ object_ptr Members::setupTitle() { MembersCountValue( _peer ) | rpl::map([](int count) { - return lng_chat_status_members(lt_count, count); + return lng_chat_status_members_demical(lt_count_decimal, count); }) | ToUpperValue(), st::infoBlockHeaderLabel); result->setAttribute(Qt::WA_TransparentForMouseEvents); diff --git a/Telegram/SourceFiles/lang/lang_tag.cpp b/Telegram/SourceFiles/lang/lang_tag.cpp index bfb2b4162c..a4b8206059 100644 --- a/Telegram/SourceFiles/lang/lang_tag.cpp +++ b/Telegram/SourceFiles/lang/lang_tag.cpp @@ -937,7 +937,10 @@ inline QString FormatCountToShort(int64 number) { return result; } -PluralResult Plural(ushort keyBase, float64 value, bool shortCount) { +PluralResult Plural( + ushort keyBase, + float64 value, + PluralType type) { // Simplified. const auto n = qAbs(value); const auto i = qFloor(n); @@ -962,10 +965,13 @@ PluralResult Plural(ushort keyBase, float64 value, bool shortCount) { t); auto string = langpack.getValue(LangKey(keyBase + shift)); if (integer) { - if (shortCount) { - return { string, FormatCountToShort(qRound(value)) }; + const auto round = qRound(value); + if (type == PluralType::Short) { + return { string, FormatCountToShort(round) }; + } else if (type == PluralType::DecimalSeparation) { + return { string, QString("%L1").arg(round) }; } - return { string, QString::number(qRound(value)) }; + return { string, QString::number(round) }; } return { string, FormatDouble(value) }; } diff --git a/Telegram/SourceFiles/lang/lang_tag.h b/Telegram/SourceFiles/lang/lang_tag.h index 2a37b16a79..87e8ba88d3 100644 --- a/Telegram/SourceFiles/lang/lang_tag.h +++ b/Telegram/SourceFiles/lang/lang_tag.h @@ -13,11 +13,20 @@ constexpr auto kTagReplacementSize = 4; int FindTagReplacementPosition(const QString &original, ushort tag); +enum class PluralType { + None, + Short, + DecimalSeparation, +}; + struct PluralResult { QString string; QString replacement; }; -PluralResult Plural(ushort keyBase, float64 value, bool shortCount = false); +PluralResult Plural( + ushort keyBase, + float64 value, + PluralType type = PluralType::None); void UpdatePluralRules(const QString &languageId); template