diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 0d539498a..e91fc9eee 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1500,8 +1500,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_mediaview_group_photo" = "Group Photo"; "lng_mediaview_channel_photo" = "Channel Photo"; "lng_mediaview_profile_photo" = "Profile Photo"; -"lng_mediaview_file_n_of_count" = "{file} {n} of {count}"; -"lng_mediaview_n_of_count" = "Photo {n} of {count}"; +"lng_mediaview_file_n_of_amount" = "{file} {n} of {amount}"; +"lng_mediaview_n_of_amount" = "Photo {n} of {amount}"; "lng_mediaview_doc_image" = "File"; "lng_mediaview_today" = "today at {time}"; "lng_mediaview_yesterday" = "yesterday at {time}"; @@ -1590,7 +1590,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_call_box_status_today" = "{time}"; "lng_call_box_status_yesterday" = "Yesterday at {time}"; "lng_call_box_status_date" = "{date} at {time}"; -"lng_call_box_status_group" = "({count}) {status}"; +"lng_call_box_status_group" = "({amount}) {status}"; "lng_call_outgoing" = "Outgoing call"; "lng_call_incoming" = "Incoming call"; @@ -2001,14 +2001,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_export_state_userpics" = "Profile pictures"; "lng_export_state_chats_list" = "Processing chats..."; "lng_export_state_chats" = "Chats"; -"lng_export_state_progress" = "{count} / {total}"; +"lng_export_state_ready_progress" = "{ready} / {total}"; "lng_export_progress" = "You can close this window now. Please don't quit Telegram until the data export is completed."; "lng_export_stop" = "Stop"; "lng_export_sure_stop" = "Are you sure you want to stop exporting your data?\n\nIf you do, you'll need to start over."; "lng_export_about_done" = "Your data was successfully exported."; "lng_export_done" = "Show my data"; "lng_export_finished" = "Data export completed."; -"lng_export_total_files" = "Total files: {count}."; +"lng_export_total_amount" = "Total files: {amount}."; "lng_export_total_size" = "Total size: {size}."; "lng_export_folder" = "Choose export folder"; "lng_export_invalid" = "Sorry, you have started a new data export, so this data export is now cancelled."; diff --git a/Telegram/SourceFiles/calls/calls_box_controller.cpp b/Telegram/SourceFiles/calls/calls_box_controller.cpp index bd83cb88b..f26edea3e 100644 --- a/Telegram/SourceFiles/calls/calls_box_controller.cpp +++ b/Telegram/SourceFiles/calls/calls_box_controller.cpp @@ -171,7 +171,14 @@ void BoxController::Row::refreshStatus() { } return lng_call_box_status_date(lt_date, langDayOfMonthFull(_date), lt_time, time); }; - setCustomStatus((_items.size() > 1) ? lng_call_box_status_group(lt_count, QString::number(_items.size()), lt_status, text()) : text()); + setCustomStatus((_items.size() > 1) + ? tr::lng_call_box_status_group( + tr::now, + lt_amount, + QString::number(_items.size()), + lt_status, + text()) + : text()); } BoxController::Row::Type BoxController::Row::ComputeType( diff --git a/Telegram/SourceFiles/codegen/lang/generator.cpp b/Telegram/SourceFiles/codegen/lang/generator.cpp index 1c6d96a13..76bc97d8b 100644 --- a/Telegram/SourceFiles/codegen/lang/generator.cpp +++ b/Telegram/SourceFiles/codegen/lang/generator.cpp @@ -107,9 +107,9 @@ bool Generator::writeHeader() { writeHeaderForwardDeclarations(); writeHeaderTagTypes(); writeHeaderKeyType(); - writeHeaderTaggedMethods(); writeHeaderInterface(); writeHeaderReactiveInterface(); + writeHeaderTaggedMethods(); return header_->finalize(); } @@ -161,34 +161,20 @@ void Generator::writeHeaderTaggedMethods() { for (auto &entry : langpack_.entries) { auto isPlural = !entry.keyBase.isEmpty(); auto &key = entry.key; - auto genericParams = QStringList(); auto params = QStringList(); - auto applyTags = QStringList(); - auto plural = QString(); + auto args = QStringList(); for (auto &tagData : entry.tags) { auto &tag = tagData.tag; auto isPluralTag = isPlural && (tag == kPluralTags[0]); - genericParams.push_back("lngtag_" + tag + (isPluralTag ? " type" : "") + ", " + (isPluralTag ? "float64 " : "const ResultString &") + tag + "__val"); - params.push_back("lngtag_" + tag + ", " + (isPluralTag ? "float64 " : "const QString &") + tag + "__val"); - if (isPluralTag) { - plural = "\tauto plural = Lang::Plural(" + key + ", " + tag + "__val, type);\n"; - applyTags.push_back("\tresult = Lang::ReplaceTag::Call(std::move(result), lt_" + tag + ", Lang::StartReplacements::Call(std::move(plural.replacement)));\n"); - } else { - applyTags.push_back("\tresult = Lang::ReplaceTag::Call(std::move(result), lt_" + tag + ", " + tag + "__val);\n"); - } + params.push_back("lngtag_" + tag + (isPluralTag ? " type" : "") + ", " + (isPluralTag ? "float64 " : "const QString &") + tag + "__val"); + args.push_back((isPluralTag ? "type" : ("lt_" + tag)) + ", " + tag + "__val"); } if (!entry.tags.empty() && (!isPlural || key == ComputePluralKey(entry.keyBase, 0))) { auto initialString = isPlural ? ("lang(LangKey(" + key + " + plural.keyShift))") : ("lang(" + getFullKey(entry) + ")"); header_->stream() << "\ -template \n\ -ResultString " << (isPlural ? entry.keyBase : key) << "__generic(" << genericParams.join(QString(", ")) << ") {\n\ -" << plural << "\ - auto result = Lang::StartReplacements::Call(" << initialString << ");\n\ -" << applyTags.join(QString()) << "\ - return result;\n\ -}\n\ -inline constexpr auto " << (isPlural ? entry.keyBase : key) << " = &" << (isPlural ? entry.keyBase : key) << "__generic;\n\ -\n"; +inline QString " << (isPlural ? entry.keyBase : key) << "(" << params.join(QString(", ")) << ") {\n\ + return tr::" << (isPlural ? entry.keyBase : key) << "(tr::now, " << args.join(QString(", ")) << ");\n\ +}\n"; } } } @@ -196,7 +182,6 @@ inline constexpr auto " << (isPlural ? entry.keyBase : key) << " = &" << (isPlur void Generator::writeHeaderInterface() { header_->pushNamespace("Lang").stream() << "\ \n\ -const char *GetKeyName(LangKey key);\n\ ushort GetTagIndex(QLatin1String tag);\n\ LangKey GetKeyIndex(QLatin1String key);\n\ bool IsTagReplaced(LangKey key, ushort tag);\n\ @@ -209,13 +194,17 @@ QString GetOriginalValue(LangKey key);\n\ void Generator::writeHeaderTagValueLookup() { header_->pushNamespace("details").stream() << "\ \n\ -template struct TagValue;\n\ +template \n\ +struct TagData;\n\ +\n\ +template \n\ +inline constexpr ushort TagValue() {\n\ + return TagData::value;\n\ +}\n\ \n"; for (auto &tag : langpack_.tags) { - if (tag.tag != kPluralTags[0]) { - header_->stream() << "template <> struct TagValue : std::integral_constant {};\n"; - } + header_->stream() << "template <> struct TagData : std::integral_constant {};\n"; } header_->popNamespace(); @@ -329,14 +318,6 @@ bool Generator::writeSource() { source_ = std::make_unique(basePath_ + ".cpp", project_); source_->include("lang/lang_keys.h").pushNamespace("Lang").pushNamespace().stream() << "\ -const char *KeyNames[kLangKeysCount] = {\n\ -\n"; - for (auto &entry : langpack_.entries) { - source_->stream() << "\"" << entry.key << "\",\n"; - } - source_->stream() << "\ -\n\ -};\n\ \n\ QChar DefaultData[] = {"; auto count = 0; @@ -381,10 +362,6 @@ int Offsets[] = {"; source_->stream() << " };\n"; source_->popNamespace().stream() << "\ \n\ -const char *GetKeyName(LangKey key) {\n\ - return (key < 0 || key >= kLangKeysCount) ? \"\" : KeyNames[key];\n\ -}\n\ -\n\ ushort GetTagIndex(QLatin1String tag) {\n\ auto size = tag.size();\n\ auto data = tag.data();\n"; diff --git a/Telegram/SourceFiles/codegen/lang/parsed_file.cpp b/Telegram/SourceFiles/codegen/lang/parsed_file.cpp index b7003a649..551c55aef 100644 --- a/Telegram/SourceFiles/codegen/lang/parsed_file.cpp +++ b/Telegram/SourceFiles/codegen/lang/parsed_file.cpp @@ -322,10 +322,16 @@ void ParsedFile::addEntity(QString key, const QString &value) { } } else { result_.entries.push_back(entry); - for (auto &pluralEntry : tagsData.entries) { + for (auto &tag : entry.tags) { + const auto plural = std::find(std::begin(kPluralTags), std::end(kPluralTags), tag.tag); + if (plural != std::end(kPluralTags)) { + logErrorBadString() << "plural tag '" << tag.tag.toStdString() << "' used in non-plural key '" << key.toStdString() << "'"; + } + } + for (auto &tagEntry : tagsData.entries) { auto taggedEntry = LangPack::Entry(); - taggedEntry.key = key + "__" + pluralEntry.key; - taggedEntry.value = pluralEntry.value; + taggedEntry.key = key + "__" + tagEntry.key; + taggedEntry.value = tagEntry.value; result_.entries.push_back(taggedEntry); } } diff --git a/Telegram/SourceFiles/export/view/export_view_content.cpp b/Telegram/SourceFiles/export/view/export_view_content.cpp index 4c5444ce5..ef4116957 100644 --- a/Telegram/SourceFiles/export/view/export_view_content.cpp +++ b/Telegram/SourceFiles/export/view/export_view_content.cpp @@ -115,7 +115,7 @@ Content ContentFromState(const ProcessingState &state) { default: Unexpected("Step in ContentFromState."); } while (result.rows.size() < 3) { - result.rows.push_back(Content::Row()); + result.rows.emplace_back(); } return result; } @@ -124,17 +124,23 @@ Content ContentFromState(const FinishedState &state) { auto result = Content(); result.rows.push_back({ Content::kDoneId, - lang(lng_export_finished), + tr::lng_export_finished(tr::now), QString(), 1. }); result.rows.push_back({ Content::kDoneId, - lng_export_total_files(lt_count, QString::number(state.filesCount)), + tr::lng_export_total_amount( + tr::now, + lt_amount, + QString::number(state.filesCount)), QString(), 1. }); result.rows.push_back({ Content::kDoneId, - lng_export_total_size(lt_size, formatSizeText(state.bytesCount)), + tr::lng_export_total_size( + tr::now, + lt_size, + formatSizeText(state.bytesCount)), QString(), 1. }); return result; diff --git a/Telegram/SourceFiles/info/info_top_bar.cpp b/Telegram/SourceFiles/info/info_top_bar.cpp index a7477ada3..13003c132 100644 --- a/Telegram/SourceFiles/info/info_top_bar.cpp +++ b/Telegram/SourceFiles/info/info_top_bar.cpp @@ -484,20 +484,23 @@ bool TopBar::computeCanDelete() const { } Ui::StringWithNumbers TopBar::generateSelectedText() const { - using Data = Ui::StringWithNumbers; using Type = Storage::SharedMediaType; const auto phrase = [&] { switch (_selectedItems.type) { - case Type::Photo: return lng_media_selected_photo__generic; - case Type::Video: return lng_media_selected_video__generic; - case Type::File: return lng_media_selected_file__generic; - case Type::MusicFile: return lng_media_selected_song__generic; - case Type::Link: return lng_media_selected_link__generic; - case Type::RoundVoiceFile: return lng_media_selected_audio__generic; + case Type::Photo: return tr::lng_media_selected_photo; + case Type::Video: return tr::lng_media_selected_video; + case Type::File: return tr::lng_media_selected_file; + case Type::MusicFile: return tr::lng_media_selected_song; + case Type::Link: return tr::lng_media_selected_link; + case Type::RoundVoiceFile: return tr::lng_media_selected_audio; } Unexpected("Type in TopBar::generateSelectedText()"); }(); - return phrase(lt_count, _selectedItems.list.size()); + return phrase( + tr::now, + lt_count, + _selectedItems.list.size(), + Ui::StringWithNumbers::FromString); } bool TopBar::selectionMode() const { diff --git a/Telegram/SourceFiles/lang/lang_values.h b/Telegram/SourceFiles/lang/lang_values.h index a27b0b139..7b35734e1 100644 --- a/Telegram/SourceFiles/lang/lang_values.h +++ b/Telegram/SourceFiles/lang/lang_values.h @@ -17,11 +17,12 @@ namespace details { inline constexpr auto kPluralCount = 6; +template +inline constexpr ushort TagValue(); + QString Current(LangKey key); rpl::producer Viewer(LangKey key); -template struct TagValue; - template Type ReplaceUnwrapTuple(Type accumulated, const Tuple &tuple) { return accumulated; @@ -63,7 +64,7 @@ struct ReplaceUnwrap { return ReplaceUnwrap::template Call( ReplaceTag::Call( std::move(accumulated), - TagValue::value, + TagValue(), value), values...); } @@ -80,7 +81,7 @@ struct Producer { Viewer(base), std::move(values)... ) | rpl::map([p = std::move(p)](auto tuple) { - return ReplaceUnwrapTuple<1>(p(std::get<0>(tuple)), tuple, TagValue::value...); + return ReplaceUnwrapTuple<1>(p(std::get<0>(tuple)), tuple, TagValue()...); }); } @@ -149,11 +150,11 @@ struct Producer { return ReplaceUnwrapTuple<7>( ReplaceTag::Call( p(select()), - type, + TagValue(), StartReplacements::Call( std::move(plural.replacement))), tuple, - TagValue::value...); + TagValue()...); }); } @@ -161,7 +162,7 @@ struct Producer { typename P, typename T = decltype(std::declval

()(QString())), typename ...Values> - static T Current( + static T Current( LangKey base, P p, lngtag_count type, @@ -171,7 +172,7 @@ struct Producer { return ReplaceUnwrap::template Call( ReplaceTag::Call( p(Lang::details::Current(LangKey(base + plural.keyShift))), - type, + TagValue(), StartReplacements::Call( std::move(plural.replacement))), values...); diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index f1579cec5..c50938a27 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -3763,9 +3763,23 @@ void OverlayWidget::updateHeader() { auto count = _fullCount ? *_fullCount : -1; if (index >= 0 && index < count && count > 1) { if (_doc) { - _headerText = lng_mediaview_file_n_of_count(lt_file, _doc->filename().isEmpty() ? lang(lng_mediaview_doc_image) : _doc->filename(), lt_n, QString::number(index + 1), lt_count, QString::number(count)); + _headerText = tr::lng_mediaview_file_n_of_amount( + tr::now, + lt_file, + (_doc->filename().isEmpty() + ? tr::lng_mediaview_doc_image(tr::now) + : _doc->filename()), + lt_n, + QString::number(index + 1), + lt_amount, + QString::number(count)); } else { - _headerText = lng_mediaview_n_of_count(lt_n, QString::number(index + 1), lt_count, QString::number(count)); + _headerText = tr::lng_mediaview_n_of_amount( + tr::now, + lt_n, + QString::number(index + 1), + lt_amount, + QString::number(count)); } } else { if (_doc) { diff --git a/Telegram/SourceFiles/ui/effects/numbers_animation.h b/Telegram/SourceFiles/ui/effects/numbers_animation.h index b93efa5fb..8e607d08e 100644 --- a/Telegram/SourceFiles/ui/effects/numbers_animation.h +++ b/Telegram/SourceFiles/ui/effects/numbers_animation.h @@ -64,6 +64,10 @@ private: }; struct StringWithNumbers { + static StringWithNumbers FromString(const QString &text) { + return { text }; + } + QString text; int offset = -1; int length = 0;