diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index ea8584385..c701638d1 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -750,6 +750,8 @@ PRIVATE kotato/settings_menu.h kotato/settings.cpp kotato/settings.h + kotato/kotato_lang.cpp + kotato/kotato_lang.h kotato/kotato_version.h lang/lang_cloud_manager.cpp lang/lang_cloud_manager.h diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 6c7c4ac85..65659e47b 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2847,282 +2847,4 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_mac_touchbar_favorite_stickers" = "Favorite stickers"; -// Kotatogram keys - -"ktg_intro_about" = "Welcome to unofficial messaging app\nbased on Telegram Desktop."; -"ktg_about_text1" = "Experimental unofficial {tdesktop_link} fork."; -"ktg_about_text1_tdesktop" = "Telegram Desktop"; -"ktg_about_text3" = "Visit {channel_link} or {faq_link} for more info."; -"ktg_about_text3_channel" = "Kotatogram channel"; -"ktg_new_version" = "Kotatogram Desktop has been updated to {version} (TD {td_version})\n\nFull version history is available here:\n{link}"; - -// Replaces -"ktg_open_from_tray" = "Open Kotatogram"; -"ktg_quit_from_tray" = "Quit Kotatogram"; -"ktg_tray_icon_text" = "Kotatogram is still running here,\nyou can change this from settings page.\nIf this icon disappears from tray menu,\nyou can drag it here from hidden icons."; -"ktg_error_start_minimized_passcoded" = "You have set a local passcode, so Kotatogram Desktop can't be launched minimised; it will ask you to enter your passcode before it can start working."; -"ktg_proxy_unsupported" = "Your Kotatogram Desktop version doesn't support this proxy type or the proxy link is invalid. Please update Kotatogram Desktop to the latest version."; -"ktg_update_telegram" = "Update Kotatogram"; -"ktg_settings_auto_start" = "Launch Kotatogram when system starts"; -"ktg_settings_add_sendto" = "Place Kotatogram in \"Send to\" menu"; -"ktg_theme_no_desktop" = "Sorry, this theme doesn't include a version for Kotatogram Desktop."; -"ktg_download_path_default_radio" = "Kotatogram folder in system «Downloads»"; -"ktg_passcode_about" = "When a local passcode is set, a lock icon appears at the top of your chats list. Click it to lock the app.\n\nNote: if you forget your local passcode, you'll need to relogin in Kotatogram Desktop."; -"ktg_message_unsupported" = "This message is not supported by your version of Kotatogram Desktop. Please update to the latest version in Settings, or install it from {link}"; -"ktg_bot_share_location_unavailable" = "Sorry, location sharing is currently unavailable in Kotatogram Desktop."; -"ktg_theme_editor_need_unlock" = "You need to unlock Kotatogram to save your theme."; -"ktg_payments_not_supported" = "Sorry, Kotatogram Desktop doesn't support payments yet. Please use one of our mobile apps to do this."; -"ktg_no_mic_permission" = "Kotatogram needs access to your microphone so that you can make calls and record voice messages."; -"ktg_passport_app_out_of_date" = "Sorry, your Telegram app is out of date and can't handle this request. Please update Kotatogram."; -"ktg_export_progress" = "You can close this window now. Please don't quit Kotatogram until the data export is completed."; -"ktg_language_not_ready_about" = "Unfortunately, this custom language pack ({lang_name}) doesn't contain data for Kotatogram Desktop. You can contribute to this language pack using the {link}."; -"ktg_outdated_soon" = "Otherwise, Kotatogram Desktop will stop updating on {date}."; -"ktg_outdated_now" = "So that Kotatogram Desktop can update to newer versions."; -"ktg_mac_menu_show" = "Show Kotatogram"; - -"ktg_settings_kotato" = "Kotatogram Settings"; - -"ktg_settings_chats" = "Chats"; - -"ktg_settings_sticker_height" = "Sticker height: {pixels}px"; -"ktg_settings_sticker_scale_both" = "Apply to sticker width"; -"ktg_settings_sticker_scale_both_about" = "When enabled, sticker maximum width will be changed along with sticker height."; - -"ktg_settings_emoji_outline" = "Big emoji outline"; - -"ktg_settings_disable_up_edit" = "Disable edit by Up key"; - -"ktg_settings_auto_scroll_unfocused" = "Unfocused auto-scroll"; - -"ktg_settings_always_show_scheduled" = "Always show scheduled"; -"ktg_settings_chat_list_compact" = "Compact chat list"; - -"ktg_fonts_title" = "Fonts"; -"ktg_settings_fonts" = "Change application fonts"; -"ktg_fonts_reset" = "Reset"; -"ktg_fonts_about" = "You will need to restart app to apply and see changes."; - -"ktg_fonts_main" = "Main font"; -"ktg_fonts_semibold" = "Semibold font"; -"ktg_fonts_semibold_is_bold" = "Bold font face"; -"ktg_fonts_monospaced" = "Monospaced font"; -"ktg_fonts_use_system_font" = "Use system font"; -"ktg_fonts_use_original_metrics" = "Use Open Sans height"; - -"ktg_settings_network" = "Network"; -"ktg_settings_net_speed_boost" = "Upload speed boost"; - -"ktg_net_speed_boost_title" = "Upload speed boost"; -"ktg_net_speed_boost_desc" = "Warning: changing this parameter to high values on slow networks can make even worse. Use at your own risk.\n\nYou'll need to restart app to save changes."; - -"ktg_net_speed_boost_default" = "Disabled"; -"ktg_net_speed_boost_slight" = "Slight"; -"ktg_net_speed_boost_medium" = "Medium"; -"ktg_net_speed_boost_big" = "Big"; - -"ktg_settings_telegram_sites_autologin" = "Auto-login on Telegram sites"; - -"ktg_settings_system" = "System"; -"ktg_settings_qt_scale" = "Qt scaling engine"; -"ktg_settings_gtk_integration" = "GTK integration"; - -"ktg_settings_file_dialog_type" = "File chooser dialog"; -"ktg_file_dialog_type_default" = "Default"; -"ktg_file_dialog_disabled_on_build" = "Disabled on build time"; -"ktg_file_dialog_disabled_by_option" = "Disabled by option"; - -"ktg_settings_other" = "Other"; -"ktg_profile_copy_id" = "Copy ID"; -"ktg_profile_bot_id" = "Bot ID"; -"ktg_profile_user_id" = "User ID"; -"ktg_profile_group_id" = "Group ID"; -"ktg_profile_supergroup_id" = "Supergroup ID"; -"ktg_profile_channel_id" = "Channel ID"; - -"ktg_settings_show_phone_number" = "Show phone in drawer"; - -"ktg_settings_call_confirm" = "Confirm before calling"; -"ktg_call_sure" = "Are you sure you want to call this user?"; -"ktg_call_button" = "Call"; - -"ktg_settings_ffmpeg_multithread" = "Multithread video decoding"; -"ktg_settings_ffmpeg_multithread_about" = "When enabled, CPU and RAM consumption is higher, video decodes faster. When disabled, CPU and RAM consumption is lower, video decodes slower. The more CPU cores you have, the more RAM consumption you have when this option is enabled. You can set exact number of threads in the JSON configuration file."; -"ktg_settings_external_video_player" = "External video player"; -"ktg_settings_external_video_player_about" = "When this option is enabled, autoplay is force-disabled and system video player is used to play videos."; - -"ktg_user_status_unaccessible" = "account inaccessible"; - -"ktg_settings_show_json_settings" = "Show settings file"; -"ktg_settings_restart" = "Restart Kotatogram"; - -"ktg_copy_btn_callback" = "Copy callback data"; - -"ktg_pinned_message_show" = "Show pinned message"; -"ktg_pinned_message_hide" = "Hide pinned message"; - -"ktg_settings_adaptive_bubbles" = "Adaptive bubbles"; - -"ktg_settings_disable_sound_from_tray" = "Disable sound"; -"ktg_settings_enable_sound_from_tray" = "Enable sound"; - -"ktg_settings_recent_stickers_limit#one" = "Recent stickers: show {count} sticker"; -"ktg_settings_recent_stickers_limit#other" = "Recent stickers: show {count} stickers"; -"ktg_settings_recent_stickers_limit_none" = "Recent stickers: hide all"; - -"ktg_filters_default" = "Default folder"; -"ktg_filters_context_edit_all" = "Edit folders"; -"ktg_filters_context_make_default" = "Make folder default"; -"ktg_filters_context_reset_default" = "Reset default folder"; - -"ktg_settings_filters" = "Folders"; -"ktg_settings_filters_only_unmuted_counter" = "Do not count muted chats"; -"ktg_settings_filters_hide_edit" = "Hide Edit button"; -"ktg_settings_filters_hide_folder_names" = "Compact folders"; -"ktg_settings_filters_hide_all" = "Hide \"All chats\" folder"; - -"ktg_settings_top_bar_mute" = "Mute in profile top bar"; - -"ktg_settings_messages" = "Messages"; - -"ktg_hide_pinned_message" = "Hide"; - -"ktg_stickers_copy_title" = "Copy name"; -"ktg_stickers_title_copied" = "Sticker pack name copied to clipboard."; - -"ktg_context_show_messages_from" = "User messages"; - -"ktg_settings_userpic_rounding" = "Profile pictures rounding"; - -"ktg_settings_userpic_rounding_none" = "Square"; -"ktg_settings_userpic_rounding_small" = "Small"; -"ktg_settings_userpic_rounding_big" = "Big"; -"ktg_settings_userpic_rounding_full" = "Circle"; - -"ktg_settings_userpic_rounding_desc" = "You'll need to restart app to save changes."; - -"ktg_settings_tray_icon" = "Tray icon"; - -"ktg_settings_tray_icon_default" = "Default"; -"ktg_settings_tray_icon_blue" = "Blue"; -"ktg_settings_tray_icon_green" = "Green"; -"ktg_settings_tray_icon_orange" = "Orange"; -"ktg_settings_tray_icon_red" = "Red"; -"ktg_settings_tray_icon_legacy" = "Legacy"; - -"ktg_settings_tray_icon_desc" = "If you don't like any of these icons, you can place icon.png in your profile folder, but you'll need to restart app to see it.\n\nIcons below don't require restart."; - -"ktg_settings_disable_tray_counter" = "Disable tray icon counter"; -"ktg_settings_use_telegram_panel_icon" = "Ask the system for telegram icon"; - -"ktg_local_storage_limit_days#one" = "{count} day"; -"ktg_local_storage_limit_days#other" = "{count} days"; - -"ktg_settings_chat_id" = "Chat ID in profile"; -"ktg_settings_chat_id_desc" = "You can choose desired format here.\n\nTelegram API uses IDs as-is, but Bot API adds minus in the beginning for groups, and -100 for channels and supergroups to fit it in one field.\n\nIf you have profile panel opened, re-open it to see changes."; -"ktg_settings_chat_id_disable" = "Hide"; -"ktg_settings_chat_id_telegram" = "Telegram API"; -"ktg_settings_chat_id_bot" = "Bot API"; - -"ktg_message_id" = "Message ID: {id}"; -"ktg_emoji_panel_hover" = "Emoji panel on hover"; - -"ktg_settings_monospace_large_bubbles" = "Expand bubbles with monospace"; - -"ktg_bot_id_copied" = "Bot ID copied to clipboard."; -"ktg_user_id_copied" = "User ID copied to clipboard."; -"ktg_group_id_copied" = "Group ID copied to clipboard."; -"ktg_supergroup_id_copied" = "Supergroup ID copied to clipboard."; -"ktg_channel_id_copied" = "Channel ID copied to clipboard."; - -"ktg_phone_copied" = "Phone copied to clipboard."; -"ktg_mention_copied" = "Username copied to clipboard."; - -"ktg_status_mutual_contact" = "mutual contact"; -"ktg_status_contact" = "contact"; -"ktg_status_non_contact" = "non-contact"; -"ktg_supergroup_status" = "supergroup"; - -"ktg_group_status_not_in" = "not a member"; -"ktg_channel_status_not_in" = "not subscribed"; -"ktg_group_status_owner" = "is owner"; -"ktg_group_status_admin" = "is admin"; -"ktg_too_many_accounts_warning" = "Warning! Using too many accounts at the same time is not recommended due to higher memory comsumption and possible crashes because of it.\n\nYou sure you want to add a new account?"; -"ktg_account_add_anyway" = "Add anyway"; - -"ktg_media_selected_gif#one" = "{count} GIF"; -"ktg_media_selected_gif#other" = "{count} GIFs"; -"ktg_media_type_gif" = "GIFs"; -"ktg_profile_gif#one" = "{count} GIF"; -"ktg_profile_gif#other" = "{count} GIFs"; -"ktg_media_gif_empty" = "No GIFs here yet"; - -"ktg_rights_chat_send_stickers" = "Send stickers"; -"ktg_rights_chat_send_gif" = "Send GIFs"; -"ktg_rights_chat_send_games" = "Send games"; -"ktg_rights_chat_use_inline" = "Use inline bots"; - -"ktg_admin_log_banned_send_stickers" = "Send stickers"; -"ktg_admin_log_banned_send_gif" = "Send GIFs"; -"ktg_admin_log_banned_send_games" = "Send games"; -"ktg_admin_log_banned_use_inline" = "Use inline bots"; - -"ktg_forward_go_to_chat" = "Go to chat"; - -"ktg_settings_forward" = "Forward"; -"ktg_settings_forward_retain_selection" = "Retain selection after forward"; -"ktg_settings_forward_chat_on_click" = "Open chat on click"; -"ktg_settings_forward_chat_on_click_description" = "You can hold Ctrl to select multiple chats regardless of this option."; - -"ktg_forward_menu_quoted" = "Quoted"; -"ktg_forward_menu_unquoted" = "Unquoted with captions"; -"ktg_forward_menu_uncaptioned" = "Unquoted without captions"; - -"ktg_forward_menu_default_albums" = "Preserve albums"; -"ktg_forward_menu_group_all_media" = "Group all media"; -"ktg_forward_menu_separate_messages" = "Separate messages"; - -"ktg_forward_subtitle_unquoted" = "unquoted"; -"ktg_forward_subtitle_uncaptioned" = "uncaptioned"; - -"ktg_forward_subtitle_group_all_media" = "as albums"; -"ktg_forward_subtitle_separate_messages" = "one by one"; - -"ktg_profile_mention_user" = "Mention user"; - -"ktg_filters_exclude_not_owned" = "Not owned"; -"ktg_filters_exclude_not_admin" = "Not administrated"; -"ktg_filters_exclude_owned" = "Owned"; -"ktg_filters_exclude_admin" = "Administrated"; -"ktg_filters_exclude_not_recent" = "Not opened in this session"; -"ktg_filters_exclude_filtered" = "From other folders"; - -"ktg_filters_create_cloud" = "Create cloud folder"; -"ktg_filters_create_local" = "Create local folder"; - -"ktg_filters_description" = "Cloud folders are synced between all your Telegram apps, but local folders have more features to offer."; - -"ktg_filters_new_cloud" = "New cloud folder"; -"ktg_filters_new_local" = "New local folder"; - -"ktg_filters_edit_cloud" = "Edit cloud folder"; -"ktg_filters_edit_local" = "Edit local folder"; - -"ktg_filters_local" = "local folder"; -"ktg_filters_cloud" = "cloud folder"; - -"ktg_filters_cloud_limit" = "Sorry, you can't create more cloud folders. You can create local folder instead."; - -"ktg_filters_hide_folder" = "Hide folder"; -"ktg_filters_hide_button" = "Hide button"; - -"ktg_filters_hide_all_chats_toast" = "\"All Chats\" folder is hidden.\nYou can enable it back in Kotatogram Settings."; -"ktg_filters_hide_edit_toast" = "Edit button is hidden.\nYou can enable it back in Kotatogram Settings."; - -"ktg_mute_for_selected_time" = "For selected time"; - -"ktg_send_preview" = "Send preview"; -"ktg_send_silent_preview" = "Send preview silent"; -"ktg_reminder_preview" = "Remind with preview"; -"ktg_schedule_preview" = "Send preview scheduled"; - // Keys finished diff --git a/Telegram/Resources/langs/rewrites/en.json b/Telegram/Resources/langs/rewrites/en.json index 8a9e07c38..f72ede861 100644 --- a/Telegram/Resources/langs/rewrites/en.json +++ b/Telegram/Resources/langs/rewrites/en.json @@ -227,5 +227,6 @@ "ktg_send_silent_preview": "Send preview silent", "ktg_reminder_preview": "Remind with preview", "ktg_schedule_preview": "Send preview scheduled", + "ktg_language_reloaded": "Kotatogram-specific language strings were reloaded.", "dummy_last_string": "" } diff --git a/Telegram/Resources/langs/rewrites/ru.json b/Telegram/Resources/langs/rewrites/ru.json index 07407a5ca..080856de9 100644 --- a/Telegram/Resources/langs/rewrites/ru.json +++ b/Telegram/Resources/langs/rewrites/ru.json @@ -227,5 +227,6 @@ "ktg_send_silent_preview": "Отправить превью тихо", "ktg_reminder_preview": "Напомнить с помощью превью", "ktg_schedule_preview": "Отправить превью позже", + "ktg_language_reloaded": "Языковые строки Kotatogram были перезагружены.", "dummy_last_string": "" } diff --git a/Telegram/SourceFiles/boxes/about_box.cpp b/Telegram/SourceFiles/boxes/about_box.cpp index 9f3605af5..066294e80 100644 --- a/Telegram/SourceFiles/boxes/about_box.cpp +++ b/Telegram/SourceFiles/boxes/about_box.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/about_box.h" #include "kotato/kotato_version.h" +#include "kotato/kotato_lang.h" #include "lang/lang_keys.h" #include "lang/lang_instance.h" #include "mainwidget.h" @@ -29,11 +30,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace { rpl::producer Text1() { - return tr::ktg_about_text1( - lt_tdesktop_link, - tr::ktg_about_text1_tdesktop( - ) | Ui::Text::ToLink("https://desktop.telegram.org/"), - Ui::Text::WithEntities); + return rktre("ktg_about_text1", { + "tdesktop_link", + Ui::Text::Link(ktr("ktg_about_text1_tdesktop"), "https://desktop.telegram.org/") + }); } rpl::producer Text2() { @@ -65,12 +65,13 @@ rpl::producer Text3() { channelLink = "https://t.me/kotatogram"; } - return tr::ktg_about_text3( - lt_channel_link, - tr::ktg_about_text3_channel() | Ui::Text::ToLink(channelLink), - lt_faq_link, - tr::lng_about_text3_faq() | Ui::Text::ToLink(telegramFaqLink()), - Ui::Text::WithEntities); + return rktre("ktg_about_text3", { + "channel_link", + Ui::Text::Link(ktr("ktg_about_text3_channel"), channelLink) + }, { + "faq_link", + Ui::Text::Link(tr::lng_about_text3_faq(tr::now), telegramFaqLink()) + }); } } // namespace diff --git a/Telegram/SourceFiles/boxes/connection_box.cpp b/Telegram/SourceFiles/boxes/connection_box.cpp index db9b281c7..e235d660e 100644 --- a/Telegram/SourceFiles/boxes/connection_box.cpp +++ b/Telegram/SourceFiles/boxes/connection_box.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/connection_box.h" +#include "kotato/kotato_lang.h" #include "boxes/confirm_box.h" #include "lang/lang_keys.h" #include "storage/localstorage.h" @@ -1139,7 +1140,7 @@ void ProxiesBoxController::ShowApplyConfirmation( } else { Ui::show(Box( (proxy.status() == ProxyData::Status::Unsupported - ? tr::ktg_proxy_unsupported(tr::now) + ? ktr("ktg_proxy_unsupported") : tr::lng_proxy_invalid(tr::now)))); } } diff --git a/Telegram/SourceFiles/boxes/download_path_box.cpp b/Telegram/SourceFiles/boxes/download_path_box.cpp index b30aa7857..64568ecee 100644 --- a/Telegram/SourceFiles/boxes/download_path_box.cpp +++ b/Telegram/SourceFiles/boxes/download_path_box.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/download_path_box.h" +#include "kotato/kotato_lang.h" #include "lang/lang_keys.h" #include "core/file_utilities.h" #include "ui/widgets/checkbox.h" @@ -25,7 +26,7 @@ DownloadPathBox::DownloadPathBox( , _path(Core::App().settings().downloadPath()) , _pathBookmark(Core::App().settings().downloadPathBookmark()) , _group(std::make_shared>(typeFromPath(_path))) -, _default(this, _group, Directory::Downloads, tr::ktg_download_path_default_radio(tr::now), st::defaultBoxCheckbox) +, _default(this, _group, Directory::Downloads, ktr("ktg_download_path_default_radio"), st::defaultBoxCheckbox) , _temp(this, _group, Directory::Temp, tr::lng_download_path_temp_radio(tr::now), st::defaultBoxCheckbox) , _dir(this, _group, Directory::Custom, tr::lng_download_path_dir_radio(tr::now), st::defaultBoxCheckbox) , _pathLink(this, QString(), st::boxLinkButton) { diff --git a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp index 03450ad4a..9b44e4e3a 100644 --- a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp +++ b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/filters/edit_filter_box.h" +#include "kotato/kotato_lang.h" #include "boxes/filters/edit_filter_chats_list.h" #include "chat_helpers/emoji_suggestions_widget.h" #include "ui/layers/generic_box.h" @@ -302,7 +303,7 @@ void FilterChatsPreview::paintEvent(QPaintEvent *e) { const auto flags = user->flags(); if (user->isInaccessible()) { - statuses << tr::ktg_user_status_unaccessible(tr::now); + statuses << ktr("ktg_user_status_unaccessible"); } else { if (user->isSupport()) { statuses << tr::lng_status_support(tr::now); @@ -310,11 +311,11 @@ void FilterChatsPreview::paintEvent(QPaintEvent *e) { if (user->isBot()) { statuses << tr::lng_status_bot(tr::now); } else if (flags & UserDataFlag::MutualContact) { - statuses << tr::ktg_status_mutual_contact(tr::now); + statuses << ktr("ktg_status_mutual_contact"); } else if (flags & UserDataFlag::Contact) { - statuses << tr::ktg_status_contact(tr::now); + statuses << ktr("ktg_status_contact"); } else { - statuses << tr::ktg_status_non_contact(tr::now); + statuses << ktr("ktg_status_non_contact"); } } } else if (history->peer->isChat()) { @@ -322,16 +323,16 @@ void FilterChatsPreview::paintEvent(QPaintEvent *e) { const auto chat = history->peer->asChat(); if (!chat->amIn()) { - statuses << tr::ktg_group_status_not_in(tr::now); + statuses << ktr("ktg_group_status_not_in"); } else if (chat->amCreator()) { - statuses << tr::ktg_group_status_owner(tr::now); + statuses << ktr("ktg_group_status_owner"); } else if (chat->hasAdminRights()) { - statuses << tr::ktg_group_status_admin(tr::now); + statuses << ktr("ktg_group_status_admin"); } } else if (history->peer->isChannel()) { if (history->peer->isMegagroup()) { - statuses << tr::ktg_supergroup_status(tr::now); + statuses << ktr("ktg_supergroup_status"); } else { statuses << tr::lng_channel_status(tr::now); } @@ -339,12 +340,12 @@ void FilterChatsPreview::paintEvent(QPaintEvent *e) { const auto channel = history->peer->asChannel(); if (!channel->amIn()) { statuses << (channel->isMegagroup() - ? tr::ktg_group_status_not_in(tr::now) - : tr::ktg_channel_status_not_in(tr::now)); + ? ktr("ktg_group_status_not_in") + : ktr("ktg_channel_status_not_in")); } else if (channel->amCreator()) { - statuses << tr::ktg_group_status_owner(tr::now); + statuses << ktr("ktg_group_status_owner"); } else if (channel->hasAdminRights()) { - statuses << tr::ktg_group_status_admin(tr::now); + statuses << ktr("ktg_group_status_admin"); } } @@ -603,13 +604,13 @@ void EditFilterBox( Fn doneCallback) { const auto creating = filter.title().isEmpty(); const auto isLocal = filter.isLocal(); - box->setTitle(creating + box->setTitle(rpl::single(creating ? (isLocal - ? tr::ktg_filters_new_local() - : tr::ktg_filters_new_cloud()) + ? ktr("ktg_filters_new_local") + : ktr("ktg_filters_new_cloud")) : (isLocal - ? tr::ktg_filters_edit_local() - : tr::ktg_filters_edit_cloud())); + ? ktr("ktg_filters_edit_local") + : ktr("ktg_filters_edit_cloud")))); box->setCloseByOutsideClick(false); using State = rpl::variable; @@ -689,7 +690,7 @@ void EditFilterBox( const auto checkboxDefault = content->add( object_ptr( box, - tr::ktg_filters_default(tr::now), + ktr("ktg_filters_default"), (creating ? false : isCurrent), st::defaultBoxCheckbox), style::margins( diff --git a/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.cpp b/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.cpp index d9d6c41db..1e0199619 100644 --- a/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.cpp +++ b/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/filters/edit_filter_chats_list.h" +#include "kotato/kotato_lang.h" #include "history/history.h" #include "window/window_session_controller.h" #include "lang/lang_keys.h" @@ -252,12 +253,12 @@ auto TypeController::rowSelectionChanges() const case Flag::NoMuted: return tr::lng_filters_type_no_muted(tr::now); case Flag::NoArchived: return tr::lng_filters_type_no_archived(tr::now); case Flag::NoRead: return tr::lng_filters_type_no_read(tr::now); - case Flag::Owned: return tr::ktg_filters_exclude_not_owned(tr::now); - case Flag::Admin: return tr::ktg_filters_exclude_not_admin(tr::now); - case Flag::NotOwned: return tr::ktg_filters_exclude_owned(tr::now); - case Flag::NotAdmin: return tr::ktg_filters_exclude_admin(tr::now); - case Flag::Recent: return tr::ktg_filters_exclude_not_recent(tr::now); - case Flag::NoFilter: return tr::ktg_filters_exclude_filtered(tr::now); + case Flag::Owned: return ktr("ktg_filters_exclude_not_owned"); + case Flag::Admin: return ktr("ktg_filters_exclude_not_admin"); + case Flag::NotOwned: return ktr("ktg_filters_exclude_owned"); + case Flag::NotAdmin: return ktr("ktg_filters_exclude_admin"); + case Flag::Recent: return ktr("ktg_filters_exclude_not_recent"); + case Flag::NoFilter: return ktr("ktg_filters_exclude_filtered"); } Unexpected("Flag in TypeName."); } diff --git a/Telegram/SourceFiles/boxes/local_storage_box.cpp b/Telegram/SourceFiles/boxes/local_storage_box.cpp index 864d4e6f1..3b67d0487 100644 --- a/Telegram/SourceFiles/boxes/local_storage_box.cpp +++ b/Telegram/SourceFiles/boxes/local_storage_box.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/local_storage_box.h" +#include "kotato/kotato_lang.h" #include "ui/wrap/vertical_layout.h" #include "ui/wrap/slide_wrap.h" #include "ui/widgets/labels.h" @@ -116,7 +117,7 @@ QString TimeLimitText(size_type limit) { : (weeks > 0) ? tr::lng_local_storage_limit_weeks(tr::now, lt_count, weeks) : (limit > 0) - ? tr::ktg_local_storage_limit_days(tr::now, lt_count, days) + ? ktr("ktg_local_storage_limit_days", days, { "count", QString::number(days) }) : tr::lng_local_storage_limit_never(tr::now); } diff --git a/Telegram/SourceFiles/boxes/mute_settings_box.cpp b/Telegram/SourceFiles/boxes/mute_settings_box.cpp index cb6e83e51..f02ea044a 100644 --- a/Telegram/SourceFiles/boxes/mute_settings_box.cpp +++ b/Telegram/SourceFiles/boxes/mute_settings_box.cpp @@ -7,6 +7,7 @@ Copyright (C) 2017, Nicholas Guriev */ #include "boxes/mute_settings_box.h" +#include "kotato/kotato_lang.h" #include "lang/lang_keys.h" #include "base/event_filter.h" #include "main/main_session.h" @@ -96,7 +97,7 @@ void MuteSettingsBox::prepare() { for (const auto hours : { kCustomFor, kForeverHours }) { const auto text = [&] { if (hours == kCustomFor) { - return tr::ktg_mute_for_selected_time(tr::now); + return ktr("ktg_mute_for_selected_time"); } else { return tr::lng_mute_duration_forever(tr::now); } diff --git a/Telegram/SourceFiles/boxes/passcode_box.cpp b/Telegram/SourceFiles/boxes/passcode_box.cpp index 9efd469dd..f5aa0a7e3 100644 --- a/Telegram/SourceFiles/boxes/passcode_box.cpp +++ b/Telegram/SourceFiles/boxes/passcode_box.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/passcode_box.h" +#include "kotato/kotato_lang.h" #include "base/bytes.h" #include "lang/lang_keys.h" #include "boxes/confirm_box.h" @@ -193,7 +194,7 @@ void PasscodeBox::prepare() { ? *_cloudFields.customDescription : _cloudPwd ? tr::lng_cloud_password_about(tr::now) - : tr::ktg_passcode_about(tr::now))); + : ktr("ktg_passcode_about"))); _aboutHeight = _about.countHeight(st::boxWidth - st::boxPadding.left() * 1.5); const auto onlyCheck = onlyCheckCurrent(); if (onlyCheck) { diff --git a/Telegram/SourceFiles/boxes/peer_list_box.cpp b/Telegram/SourceFiles/boxes/peer_list_box.cpp index 3dbc8c4ee..eb9df8e64 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_box.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/peer_list_box.h" +#include "kotato/kotato_lang.h" #include "main/main_session.h" #include "mainwidget.h" #include "ui/widgets/multi_select.h" @@ -482,7 +483,7 @@ void PeerListRow::refreshStatus() { if (_isSavedMessagesChat) { setStatusText(tr::lng_saved_forward_here(tr::now)); } else if (user->isInaccessible()) { - setStatusText(tr::ktg_user_status_unaccessible(tr::now)); + setStatusText(ktr("ktg_user_status_unaccessible")); } else { auto time = base::unixtime::now(); setStatusText(Data::OnlineText(user, time)); @@ -502,9 +503,9 @@ void PeerListRow::refreshStatus() { } } else if (peer()->isMegagroup()) { if (peer()->asChannel()->membersCountKnown()) { - setStatusText(tr::ktg_supergroup_status(tr::now) + ", " + tr::lng_chat_status_members(tr::now, lt_count_decimal, peer()->asChannel()->membersCount())); + setStatusText(ktr("ktg_supergroup_status") + ", " + tr::lng_chat_status_members(tr::now, lt_count_decimal, peer()->asChannel()->membersCount())); } else { - setStatusText(tr::ktg_supergroup_status(tr::now)); + setStatusText(ktr("ktg_supergroup_status")); } } else if (peer()->isChannel()) { if (peer()->asChannel()->membersCountKnown()) { diff --git a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp index 24730d67f..c68f9c1ea 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/peers/edit_participants_box.h" +#include "kotato/kotato_lang.h" #include "boxes/peer_list_controllers.h" #include "boxes/peers/edit_participant_box.h" #include "boxes/peers/add_participants_box.h" @@ -1472,7 +1473,7 @@ base::unique_qptr ParticipantsBoxController::rowContextMenu( _navigation->showPeerInfo(participant); })); } result->addAction( - tr::ktg_context_show_messages_from(tr::now), + ktr("ktg_context_show_messages_from"), crl::guard(this, [=] { App::searchByHashtag(QString(), _peer, user); })); if (_role == Role::Kicked) { if (_peer->isMegagroup() @@ -1493,7 +1494,7 @@ base::unique_qptr ParticipantsBoxController::rowContextMenu( if (const auto openedPeer = mainwidget->peer()) { if (openedPeer->canWrite()) { result->addAction( - tr::ktg_profile_mention_user(tr::now), + ktr("ktg_profile_mention_user"), crl::guard(this, [=] { mainwidget->mentionUser(user); })); } } diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp index 90f983df7..92768405b 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/peers/edit_peer_permissions_box.h" +#include "kotato/kotato_lang.h" #include "lang/lang_keys.h" #include "data/data_channel.h" #include "data/data_chat.h" @@ -107,24 +108,24 @@ void ApplyDependencies( std::vector> RestrictionLabels() { const auto langKeys = { - tr::lng_rights_chat_send_text, - tr::lng_rights_chat_send_media, - tr::ktg_rights_chat_send_stickers, - tr::ktg_rights_chat_send_gif, - tr::ktg_rights_chat_send_games, - tr::ktg_rights_chat_use_inline, - tr::lng_rights_chat_send_links, - tr::lng_rights_chat_send_polls, - tr::lng_rights_chat_add_members, - tr::lng_rights_group_pin, - tr::lng_rights_group_info, + tr::lng_rights_chat_send_text(tr::now), + tr::lng_rights_chat_send_media(tr::now), + ktr("ktg_rights_chat_send_stickers"), + ktr("ktg_rights_chat_send_gif"), + ktr("ktg_rights_chat_send_games"), + ktr("ktg_rights_chat_use_inline"), + tr::lng_rights_chat_send_links(tr::now), + tr::lng_rights_chat_send_polls(tr::now), + tr::lng_rights_chat_add_members(tr::now), + tr::lng_rights_group_pin(tr::now), + tr::lng_rights_group_info(tr::now), }; std::vector> vector; const auto restrictions = Data::ListOfRestrictions(); auto i = 0; for (const auto &key : langKeys) { - vector.emplace_back(restrictions[i++], key(tr::now)); + vector.emplace_back(restrictions[i++], key); } return vector; } diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index 2a3882b3b..243cd6e37 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/share_box.h" #include "dialogs/dialogs_indexed_list.h" +#include "kotato/kotato_lang.h" #include "lang/lang_keys.h" #include "mainwindow.h" #include "mainwidget.h" @@ -480,7 +481,7 @@ void ShareBox::createButtons() { if (_hasSelected) { if (_descriptor.goToChatCallback && _inner->selected().size() == 1) { const auto singleChat = _inner->selected().at(0); - addLeftButton(tr::ktg_forward_go_to_chat(), [=] { goToChat(singleChat); }); + addLeftButton(rktr("ktg_forward_go_to_chat"), [=] { goToChat(singleChat); }); } const auto send = addButton(tr::lng_share_confirm(), [=] { @@ -524,20 +525,20 @@ bool ShareBox::showMenu(not_null button) { button->installEventFilter(_menu); if (!cForwardQuoted()) { - _menu->addAction(tr::ktg_forward_menu_quoted(tr::now), [=] { + _menu->addAction(ktr("ktg_forward_menu_quoted"), [=] { cSetForwardQuoted(true); updateAdditionalTitle(); }); } if (cForwardQuoted() || !cForwardCaptioned()) { - _menu->addAction(tr::ktg_forward_menu_unquoted(tr::now), [=] { + _menu->addAction(ktr("ktg_forward_menu_unquoted"), [=] { cSetForwardQuoted(false); cSetForwardCaptioned(true); updateAdditionalTitle(); }); } if (cForwardQuoted() || cForwardCaptioned()) { - _menu->addAction(tr::ktg_forward_menu_uncaptioned(tr::now), [=] { + _menu->addAction(ktr("ktg_forward_menu_uncaptioned"), [=] { cSetForwardQuoted(false); cSetForwardCaptioned(false); updateAdditionalTitle(); @@ -546,20 +547,20 @@ bool ShareBox::showMenu(not_null button) { if (_descriptor.hasMedia) { _menu->addSeparator(); if (!cForwardAlbumsAsIs()) { - _menu->addAction(tr::ktg_forward_menu_default_albums(tr::now), [=] { + _menu->addAction(ktr("ktg_forward_menu_default_albums"), [=] { cSetForwardAlbumsAsIs(true); updateAdditionalTitle(); }); } if (cForwardAlbumsAsIs() || !cForwardGrouped()) { - _menu->addAction(tr::ktg_forward_menu_group_all_media(tr::now), [=] { + _menu->addAction(ktr("ktg_forward_menu_group_all_media"), [=] { cSetForwardAlbumsAsIs(false); cSetForwardGrouped(true); updateAdditionalTitle(); }); } if (cForwardAlbumsAsIs() || cForwardGrouped()) { - _menu->addAction(tr::ktg_forward_menu_separate_messages(tr::now), [=] { + _menu->addAction(ktr("ktg_forward_menu_separate_messages"), [=] { cSetForwardAlbumsAsIs(false); cSetForwardGrouped(false); updateAdditionalTitle(); @@ -584,8 +585,8 @@ void ShareBox::updateAdditionalTitle() { if (!cForwardQuoted()) { result += (cForwardCaptioned() - ? tr::ktg_forward_subtitle_unquoted(tr::now) - : tr::ktg_forward_subtitle_uncaptioned(tr::now)); + ? ktr("ktg_forward_subtitle_unquoted") + : ktr("ktg_forward_subtitle_uncaptioned")); } if (_descriptor.hasMedia && !cForwardAlbumsAsIs()) { @@ -593,8 +594,8 @@ void ShareBox::updateAdditionalTitle() { result += ", "; } result += (cForwardGrouped() - ? tr::ktg_forward_subtitle_group_all_media(tr::now) - : tr::ktg_forward_subtitle_separate_messages(tr::now)); + ? ktr("ktg_forward_subtitle_group_all_media") + : ktr("ktg_forward_subtitle_separate_messages")); } setAdditionalTitle(rpl::single(result)); diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index 7a93f2bdd..9e53bfa7f 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/sticker_set_box.h" +#include "kotato/kotato_lang.h" #include "data/data_document.h" #include "data/data_session.h" #include "data/data_file_origin.h" @@ -255,7 +256,7 @@ void StickerSetBox::copyTitle() { _inner->title( ) | rpl::start_with_next([](const TextWithEntities &value) { QGuiApplication::clipboard()->setText(value.text); - Ui::show(Box(tr::ktg_stickers_title_copied(tr::now))); + Ui::show(Box(ktr("ktg_stickers_title_copied"))); }, lifetime()); } @@ -380,7 +381,7 @@ bool StickerSetBox::showMenu(not_null button) { }); button->installEventFilter(_menu); - _menu->addAction(tr::ktg_stickers_copy_title(tr::now), [=] { copyTitle(); }); + _menu->addAction(ktr("ktg_stickers_copy_title"), [=] { copyTitle(); }); if (!_inner->shortName().isEmpty()) { _menu->addAction(tr::lng_stickers_share_pack(tr::now), [=] { copyStickersLink(); }); diff --git a/Telegram/SourceFiles/calls/calls_box_controller.cpp b/Telegram/SourceFiles/calls/calls_box_controller.cpp index 6ff9075e9..6e828bb23 100644 --- a/Telegram/SourceFiles/calls/calls_box_controller.cpp +++ b/Telegram/SourceFiles/calls/calls_box_controller.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "calls/calls_box_controller.h" +#include "kotato/kotato_lang.h" #include "lang/lang_keys.h" #include "ui/effects/ripple_animation.h" #include "ui/widgets/labels.h" @@ -385,7 +386,7 @@ void BoxController::rowActionClicked(not_null row) { Assert(user != nullptr); if (cConfirmBeforeCall()) { - Ui::show(Box(tr::ktg_call_sure(tr::now), tr::ktg_call_button(tr::now), [=] { + Ui::show(Box(ktr("ktg_call_sure"), ktr("ktg_call_button"), [=] { Ui::hideLayer(); Core::App().calls().startOutgoingCall(user, false); })); diff --git a/Telegram/SourceFiles/calls/calls_instance.cpp b/Telegram/SourceFiles/calls/calls_instance.cpp index c32ea6b1f..56fd9a6d1 100644 --- a/Telegram/SourceFiles/calls/calls_instance.cpp +++ b/Telegram/SourceFiles/calls/calls_instance.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "calls/calls_instance.h" +#include "kotato/kotato_lang.h" #include "calls/calls_call.h" #include "calls/group/calls_group_common.h" #include "calls/group/calls_choose_join_as.h" @@ -691,7 +692,7 @@ void Instance::requestPermissionOrFail(Platform::PermissionType type, Fn if (inGroupCall()) { _currentGroupCall->hangup(); } - Ui::show(Box(tr::ktg_no_mic_permission(tr::now), tr::lng_menu_settings(tr::now), crl::guard(this, [=] { + Ui::show(Box(ktr("ktg_no_mic_permission"), tr::lng_menu_settings(tr::now), crl::guard(this, [=] { Platform::OpenSystemSettingsForPermission(type); Ui::hideLayer(); }))); diff --git a/Telegram/SourceFiles/chat_helpers/send_context_menu.cpp b/Telegram/SourceFiles/chat_helpers/send_context_menu.cpp index c73a443aa..7b323b673 100644 --- a/Telegram/SourceFiles/chat_helpers/send_context_menu.cpp +++ b/Telegram/SourceFiles/chat_helpers/send_context_menu.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "chat_helpers/send_context_menu.h" +#include "kotato/kotato_lang.h" #include "api/api_common.h" #include "base/event_filter.h" #include "boxes/abstract_box.h" @@ -80,16 +81,16 @@ FillMenuResult FillSendPreviewMenu( } if (defaultSend && now != Type::Scheduled && now != Type::ScheduledToUser) { - menu->addAction(tr::ktg_send_preview(tr::now), defaultSend); + menu->addAction(ktr("ktg_send_preview"), defaultSend); } if (silent && now != Type::Reminder) { - menu->addAction(tr::ktg_send_silent_preview(tr::now), silent); + menu->addAction(ktr("ktg_send_silent_preview"), silent); } if (schedule && now != Type::SilentOnly) { menu->addAction( (now == Type::Reminder - ? tr::ktg_reminder_preview(tr::now) - : tr::ktg_schedule_preview(tr::now)), + ? ktr("ktg_reminder_preview") + : ktr("ktg_schedule_preview")), schedule); } return FillMenuResult::Success; diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index 215d501ee..9799d3154 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "core/application.h" +#include "kotato/kotato_lang.h" #include "data/data_photo.h" #include "data/data_document.h" #include "data/data_session.h" @@ -62,6 +63,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/gl/gl_detection.h" #include "ui/image/image.h" #include "ui/text/text_options.h" +#include "ui/toast/toast.h" #include "ui/emoji_config.h" #include "ui/effects/animations.h" #include "storage/serialize_common.h" @@ -215,8 +217,7 @@ void Application::run() { _notifications = std::make_unique(); startLocalStorage(); - Lang::GetInstance().fillDefaultJson(); - Lang::GetInstance().fillFromJson(); + Kotato::Lang::Load(Lang::GetInstance().baseId(), Lang::GetInstance().id()); if (!cQtScale()) { ValidateScale(); @@ -1154,6 +1155,13 @@ void Application::startShortcuts() { request->check(Command::Close) && request->handle([=] { return closeActiveWindow(); }); + request->check(Command::ReloadLang) && request->handle([=] { + Kotato::Lang::Load( + Lang::GetInstance().baseId(), + Lang::GetInstance().id()); + Ui::Toast::Show(ktr("ktg_language_reloaded")); + return true; + }); }, _lifetime); } diff --git a/Telegram/SourceFiles/core/changelogs.cpp b/Telegram/SourceFiles/core/changelogs.cpp index c905a587f..2eac72601 100644 --- a/Telegram/SourceFiles/core/changelogs.cpp +++ b/Telegram/SourceFiles/core/changelogs.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "core/changelogs.h" +#include "kotato/kotato_lang.h" #include "kotato/kotato_version.h" #include "storage/localstorage.h" #include "lang/lang_keys.h" @@ -203,14 +204,10 @@ void Changelogs::addKotatoLogs() { channelLink = "https://t.me/kotatogram"; } - const auto text = tr::ktg_new_version( - tr::now, - lt_version, - QString::fromLatin1(AppKotatoVersionStr), - lt_td_version, - QString::fromLatin1(AppVersionStr), - lt_link, - channelLink); + const auto text = ktr("ktg_new_version", + { "version", QString::fromLatin1(AppKotatoVersionStr) }, + { "td_version", QString::fromLatin1(AppVersionStr) }, + { "link", channelLink }); addLocalLog(text.trimmed()); } diff --git a/Telegram/SourceFiles/core/shortcuts.cpp b/Telegram/SourceFiles/core/shortcuts.cpp index 5f8e2927c..b94218ffc 100644 --- a/Telegram/SourceFiles/core/shortcuts.cpp +++ b/Telegram/SourceFiles/core/shortcuts.cpp @@ -100,6 +100,7 @@ const auto CommandByName = base::flat_map{ { qsl("save_draft") , Command::SaveDraft }, { qsl("jump_to_date") , Command::JumpToDate }, + { qsl("reload_lang") , Command::ReloadLang }, { qsl("pinned_1") , Command::ChatPinned1 }, { qsl("pinned_2") , Command::ChatPinned2 }, @@ -161,6 +162,7 @@ const auto CommandNames = base::flat_map{ { Command::SaveDraft , qsl("save_draft") }, { Command::JumpToDate , qsl("jump_to_date") }, + { Command::ReloadLang , qsl("reload_lang") }, { Command::ChatPinned1 , qsl("pinned_1") }, { Command::ChatPinned2 , qsl("pinned_2") }, diff --git a/Telegram/SourceFiles/core/shortcuts.h b/Telegram/SourceFiles/core/shortcuts.h index 606763246..279aebc9d 100644 --- a/Telegram/SourceFiles/core/shortcuts.h +++ b/Telegram/SourceFiles/core/shortcuts.h @@ -64,6 +64,7 @@ enum class Command { SaveDraft, JumpToDate, + ReloadLang, }; [[maybe_unused]] constexpr auto kShowFolder = { diff --git a/Telegram/SourceFiles/data/data_cloud_themes.cpp b/Telegram/SourceFiles/data/data_cloud_themes.cpp index 59f364fc1..09e48e939 100644 --- a/Telegram/SourceFiles/data/data_cloud_themes.cpp +++ b/Telegram/SourceFiles/data/data_cloud_themes.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "data/data_cloud_themes.h" +#include "kotato/kotato_lang.h" #include "window/themes/window_theme.h" #include "window/themes/window_theme_preview.h" #include "window/themes/window_theme_editor_box.h" @@ -150,7 +151,7 @@ void CloudThemes::resolve( }).fail([=](const MTP::Error &error) { if (error.type() == qstr("THEME_FORMAT_INVALID")) { controller->show(Box( - tr::ktg_theme_no_desktop(tr::now))); + ktr("ktg_theme_no_desktop"))); } }).send(); } @@ -175,7 +176,7 @@ void CloudThemes::showPreview( cloud)); } else { controller->show(Box( - tr::ktg_theme_no_desktop(tr::now))); + ktr("ktg_theme_no_desktop"))); } } diff --git a/Telegram/SourceFiles/data/data_peer_values.cpp b/Telegram/SourceFiles/data/data_peer_values.cpp index 6516e4b4a..829c6dca7 100644 --- a/Telegram/SourceFiles/data/data_peer_values.cpp +++ b/Telegram/SourceFiles/data/data_peer_values.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "data/data_peer_values.h" +#include "kotato/kotato_lang.h" #include "lang/lang_keys.h" #include "data/data_channel.h" #include "data/data_chat.h" @@ -46,7 +47,7 @@ int OnlinePhraseChangeInSeconds(TimeId online, TimeId now) { std::optional OnlineTextSpecial(not_null user) { if (user->isInaccessible()) { - return tr::ktg_user_status_unaccessible(tr::now); + return ktr("ktg_user_status_unaccessible"); } else if (user->isNotificationsUser()) { return tr::lng_status_service_notifications(tr::now); } else if (user->isSupport()) { diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index 38a2e0d2e..664cd5117 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "dialogs/dialogs_widget.h" +#include "kotato/kotato_lang.h" #include "dialogs/dialogs_inner_widget.h" #include "dialogs/dialogs_search_from_controllers.h" #include "dialogs/dialogs_key.h" @@ -574,7 +575,7 @@ void Widget::checkUpdateStatus() { if (_updateTelegram) return; _updateTelegram.create( this, - tr::ktg_update_telegram(tr::now), + ktr("ktg_update_telegram"), st::dialogsUpdateButton, st::dialogsInstallUpdate, st::dialogsInstallUpdateOver); diff --git a/Telegram/SourceFiles/export/view/export_view_progress.cpp b/Telegram/SourceFiles/export/view/export_view_progress.cpp index 7cb7c0c16..a0b4b3ae5 100644 --- a/Telegram/SourceFiles/export/view/export_view_progress.cpp +++ b/Telegram/SourceFiles/export/view/export_view_progress.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "export/view/export_view_progress.h" +#include "kotato/kotato_lang.h" #include "ui/effects/animations.h" #include "ui/widgets/labels.h" #include "ui/widgets/buttons.h" @@ -263,7 +264,7 @@ ProgressWidget::ProgressWidget( _about = _body->add( object_ptr( this, - tr::ktg_export_progress(tr::now), + ktr("ktg_export_progress"), st::exportAboutLabel), st::exportAboutPadding); diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index a9dd1cea7..6dceb378f 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "facades.h" +#include "kotato/kotato_lang.h" #include "api/api_bot.h" #include "info/info_memento.h" #include "core/click_handler_types.h" @@ -146,7 +147,7 @@ void activateBotCommand( case ButtonType::RequestLocation: { hideSingleUseKeyboard(msg); Ui::show(Box( - tr::ktg_bot_share_location_unavailable(tr::now))); + ktr("ktg_bot_share_location_unavailable"))); } break; case ButtonType::RequestPhone: { diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp index 54dbb0cde..a3047515e 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/admin_log/history_admin_log_item.h" +#include "kotato/kotato_lang.h" #include "history/admin_log/history_admin_log_inner.h" #include "history/view/history_view_element.h" #include "history/history_location_manager.h" @@ -155,6 +156,26 @@ const auto CollectChanges = [](auto &phraseMap, auto plusFlags, auto minusFlags) return withPrefix(plusFlags & ~minusFlags, '+') + withPrefix(minusFlags & ~plusFlags, kMinus); }; +const auto CollectChangesKtg = [](auto &phraseMap, auto &ktgPhraseMap, auto plusFlags, auto minusFlags) { + auto withPrefix = [&ktgPhraseMap, &phraseMap](auto flags, QChar prefix) { + auto result = QString(); + for (auto &phrase : ktgPhraseMap) { + if (flags & phrase.first) { + result.append('\n' + (prefix + ktr(phrase.second))); + } + } + + for (auto &phrase : phraseMap) { + if (flags & phrase.first) { + result.append('\n' + (prefix + phrase.second(tr::now))); + } + } + return result; + }; + const auto kMinus = QChar(0x2212); + return withPrefix(plusFlags & ~minusFlags, '+') + withPrefix(minusFlags & ~plusFlags, kMinus); +}; + TextWithEntities GenerateAdminChangeText( not_null channel, const TextWithEntities &user, @@ -206,17 +227,19 @@ QString GenerateBannedChangeText( { Flag::ViewMessages, tr::lng_admin_log_banned_view_messages }, { Flag::SendMessages, tr::lng_admin_log_banned_send_messages }, { Flag::SendMedia, tr::lng_admin_log_banned_send_media }, - { Flag::SendStickers, tr::ktg_admin_log_banned_send_stickers }, - { Flag::SendGifs, tr::ktg_admin_log_banned_send_gif }, - { Flag::SendInline, tr::ktg_admin_log_banned_use_inline }, - { Flag::SendGames, tr::ktg_admin_log_banned_send_games }, { Flag::EmbedLinks, tr::lng_admin_log_banned_embed_links }, { Flag::SendPolls, tr::lng_admin_log_banned_send_polls }, { Flag::ChangeInfo, tr::lng_admin_log_admin_change_info }, { Flag::InviteUsers, tr::lng_admin_log_admin_invite_users }, { Flag::PinMessages, tr::lng_admin_log_admin_pin_messages }, }; - return CollectChanges(phraseMap, prevRights.flags, newRights.flags); + static auto ktgPhraseMap = std::map{ + { Flag::SendStickers, "ktg_admin_log_banned_send_stickers" }, + { Flag::SendGifs, "ktg_admin_log_banned_send_gif" }, + { Flag::SendInline, "ktg_admin_log_banned_use_inline" }, + { Flag::SendGames, "ktg_admin_log_banned_send_games" }, + }; + return CollectChangesKtg(phraseMap, ktgPhraseMap, prevRights.flags, newRights.flags); } TextWithEntities GenerateBannedChangeText( diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index ecaab7c3c..29c6aa425 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history_inner_widget.h" #include +#include "kotato/kotato_lang.h" #include "core/file_utilities.h" #include "core/crash_reports.h" #include "core/click_handler_types.h" @@ -1594,7 +1595,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { } const auto peer = item->history()->peer; if (peer->isChat() || peer->isMegagroup()) { - _menu->addAction(tr::ktg_context_show_messages_from(tr::now), [=] { + _menu->addAction(ktr("ktg_context_show_messages_from"), [=] { App::searchByHashtag(QString(), peer, item->from()->asUser()); }); } diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 7631968a0..3d91090d1 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/history_item.h" +#include "kotato/kotato_lang.h" #include "lang/lang_keys.h" #include "mainwidget.h" #include "layout.h" @@ -68,7 +69,7 @@ not_null CreateUnsupportedMessage( PeerId from) { const auto siteLink = qsl("https://kotatogram.github.io"); auto text = TextWithEntities{ - tr::ktg_message_unsupported(tr::now, lt_link, siteLink) + ktr("ktg_message_unsupported", { "link", siteLink }) }; TextUtilities::ParseEntities(text, Ui::ItemTextNoMonoOptions().flags); text.entities.push_front( diff --git a/Telegram/SourceFiles/history/history_item_components.cpp b/Telegram/SourceFiles/history/history_item_components.cpp index 8555da322..56b3fafb7 100644 --- a/Telegram/SourceFiles/history/history_item_components.cpp +++ b/Telegram/SourceFiles/history/history_item_components.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/history_item_components.h" +#include "kotato/kotato_lang.h" #include "lang/lang_keys.h" #include "ui/effects/ripple_animation.h" #include "ui/image/image.h" @@ -428,7 +429,7 @@ QString ReplyMarkupClickHandler::copyToClipboardContextItemText() const { return button ? ((button->type == Type::Url || button->type == Type::Auth) ? tr::lng_context_copy_link(tr::now) - : tr::ktg_copy_btn_callback(tr::now)) + : ktr("ktg_copy_btn_callback")) : QString(); } diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 00e226423..7576f45b7 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/history_widget.h" +#include "kotato/kotato_lang.h" #include "api/api_editing.h" #include "api/api_bot.h" #include "api/api_sending.h" @@ -5574,20 +5575,20 @@ void HistoryWidget::contextMenuEvent(QContextMenuEvent *e) { _menu = base::make_unique_q(this); if (!cForwardQuoted()) { - _menu->addAction(tr::ktg_forward_menu_quoted(tr::now), [=] { + _menu->addAction(ktr("ktg_forward_menu_quoted"), [=] { cSetForwardQuoted(true); updateForwardingTexts(); }); } if (cForwardQuoted() || !cForwardCaptioned()) { - _menu->addAction(tr::ktg_forward_menu_unquoted(tr::now), [=] { + _menu->addAction(ktr("ktg_forward_menu_unquoted"), [=] { cSetForwardQuoted(false); cSetForwardCaptioned(true); updateForwardingTexts(); }); } if (cForwardQuoted() || cForwardCaptioned()) { - _menu->addAction(tr::ktg_forward_menu_uncaptioned(tr::now), [=] { + _menu->addAction(ktr("ktg_forward_menu_uncaptioned"), [=] { cSetForwardQuoted(false); cSetForwardCaptioned(false); updateForwardingTexts(); @@ -5596,20 +5597,20 @@ void HistoryWidget::contextMenuEvent(QContextMenuEvent *e) { if (hasMediaToGroup && count > 1) { _menu->addSeparator(); if (!cForwardAlbumsAsIs()) { - _menu->addAction(tr::ktg_forward_menu_default_albums(tr::now), [=] { + _menu->addAction(ktr("ktg_forward_menu_default_albums"), [=] { cSetForwardAlbumsAsIs(true); updateForwardingTexts(); }); } if (cForwardAlbumsAsIs() || !cForwardGrouped()) { - _menu->addAction(tr::ktg_forward_menu_group_all_media(tr::now), [=] { + _menu->addAction(ktr("ktg_forward_menu_group_all_media"), [=] { cSetForwardAlbumsAsIs(false); cSetForwardGrouped(true); updateForwardingTexts(); }); } if (cForwardAlbumsAsIs() || cForwardGrouped()) { - _menu->addAction(tr::ktg_forward_menu_separate_messages(tr::now), [=] { + _menu->addAction(ktr("ktg_forward_menu_separate_messages"), [=] { cSetForwardAlbumsAsIs(false); cSetForwardGrouped(false); updateForwardingTexts(); @@ -7066,13 +7067,13 @@ void HistoryWidget::updateForwardingTexts() { + (cForwardQuoted() ? QString() : qsl(", ") + (cForwardCaptioned() - ? tr::ktg_forward_subtitle_unquoted(tr::now) - : tr::ktg_forward_subtitle_uncaptioned(tr::now))) + ? ktr("ktg_forward_subtitle_unquoted") + : ktr("ktg_forward_subtitle_uncaptioned"))) + (cForwardAlbumsAsIs() || !hasMediaToGroup ? QString() : qsl(", ") + (cForwardGrouped() - ? tr::ktg_forward_subtitle_group_all_media(tr::now) - : tr::ktg_forward_subtitle_separate_messages(tr::now)))); + ? ktr("ktg_forward_subtitle_group_all_media") + : ktr("ktg_forward_subtitle_separate_messages")))); } } _toForwardFrom.setText(st::msgNameStyle, from, Ui::NameTextOptions()); diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index ab7d0167d..3c1e11fdd 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/view/history_view_element.h" +#include "kotato/kotato_lang.h" #include "history/view/history_view_service_message.h" #include "history/view/history_view_message.h" #include "history/history_item_components.h" @@ -241,7 +242,7 @@ QString DateTooltipText(not_null view) { } } if (const auto msgId = view->data()->fullId().msg) { - dateText += '\n' + tr::ktg_message_id(tr::now, lt_id, QString::number(msgId)); + dateText += '\n' + ktr("ktg_message_id", {"id", QString::number(msgId)}); } return dateText; } 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 77ea5019c..05420caf0 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include #include +#include "kotato/kotato_lang.h" #include "history/history.h" #include "history/view/history_view_send_action.h" #include "boxes/add_contact_box.h" @@ -222,7 +223,7 @@ void TopBarWidget::call() { if (const auto peer = _activeChat.key.peer()) { if (const auto user = peer->asUser()) { if (cConfirmBeforeCall()) { - Ui::show(Box(tr::ktg_call_sure(tr::now), tr::ktg_call_button(tr::now), [=] { + Ui::show(Box(ktr("ktg_call_sure"), ktr("ktg_call_button"), [=] { Ui::hideLayer(); Core::App().calls().startOutgoingCall(user, false); })); diff --git a/Telegram/SourceFiles/history/view/media/history_view_call.cpp b/Telegram/SourceFiles/history/view/media/history_view_call.cpp index b127e05ec..3f5d3ed05 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_call.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_call.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/view/media/history_view_call.h" +#include "kotato/kotato_lang.h" #include "boxes/confirm_box.h" #include "lang/lang_keys.h" #include "ui/text/format_values.h" @@ -62,7 +63,7 @@ QSize Call::countOptimalSize() { _link = std::make_shared([=] { if (user) { if (cConfirmBeforeCall()) { - Ui::show(Box(tr::ktg_call_sure(tr::now), tr::ktg_call_button(tr::now), [=] { + Ui::show(Box(ktr("ktg_call_sure"), ktr("ktg_call_button"), [=] { Ui::hideLayer(); Core::App().calls().startOutgoingCall(user, video); })); diff --git a/Telegram/SourceFiles/info/info_top_bar.cpp b/Telegram/SourceFiles/info/info_top_bar.cpp index 8f841dc37..873f236ae 100644 --- a/Telegram/SourceFiles/info/info_top_bar.cpp +++ b/Telegram/SourceFiles/info/info_top_bar.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include #include +#include "kotato/kotato_lang.h" #include "lang/lang_keys.h" #include "lang/lang_numbers_animation.h" #include "info/info_wrap_widget.h" @@ -483,11 +484,17 @@ bool TopBar::computeCanDelete() const { Ui::StringWithNumbers TopBar::generateSelectedText() const { using Type = Storage::SharedMediaType; + if (_selectedItems.type == Type::GIF) { + return Ui::StringWithNumbers::FromString( + ktr("ktg_media_selected_gif", + _selectedItems.list.size(), + { "count", QString::number(_selectedItems.list.size()) })); + } + const auto phrase = [&] { switch (_selectedItems.type) { case Type::Photo: return tr::lng_media_selected_photo; case Type::Video: return tr::lng_media_selected_video; - case Type::GIF: return tr::ktg_media_selected_gif; 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; @@ -584,7 +591,7 @@ rpl::producer TitleValue( case Section::MediaType::Video: return tr::lng_media_type_videos(); case Section::MediaType::GIF: - return tr::ktg_media_type_gif(); + return rktr("ktg_media_type_gif"); case Section::MediaType::MusicFile: return tr::lng_media_type_songs(); case Section::MediaType::File: @@ -628,7 +635,7 @@ rpl::producer TitleValue( case Section::SettingsType::Calls: return tr::lng_settings_section_call_settings(); case Section::SettingsType::Kotato: - return tr::ktg_settings_kotato(); + return rktr("ktg_settings_kotato"); } Unexpected("Bad settings type in Info::TitleValue()"); diff --git a/Telegram/SourceFiles/info/info_wrap_widget.cpp b/Telegram/SourceFiles/info/info_wrap_widget.cpp index 336d54cd6..e8737fe90 100644 --- a/Telegram/SourceFiles/info/info_wrap_widget.cpp +++ b/Telegram/SourceFiles/info/info_wrap_widget.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "info/info_wrap_widget.h" +#include "kotato/kotato_lang.h" #include "info/profile/info_profile_widget.h" #include "info/profile/info_profile_values.h" #include "info/media/info_media_widget.h" @@ -487,7 +488,7 @@ void WrapWidget::addProfileCallsButton() { : st::infoTopBarCall)) )->addClickHandler([=] { if (cConfirmBeforeCall()) { - Ui::show(Box(tr::ktg_call_sure(tr::now), tr::ktg_call_button(tr::now), [=] { + Ui::show(Box(ktr("ktg_call_sure"), ktr("ktg_call_button"), [=] { Ui::hideLayer(); Core::App().calls().startOutgoingCall(user, false); })); diff --git a/Telegram/SourceFiles/info/media/info_media_buttons.h b/Telegram/SourceFiles/info/media/info_media_buttons.h index 682ce6625..93d25f7ad 100644 --- a/Telegram/SourceFiles/info/media/info_media_buttons.h +++ b/Telegram/SourceFiles/info/media/info_media_buttons.h @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include #include +#include "kotato/kotato_lang.h" #include "lang/lang_keys.h" #include "storage/storage_shared_media.h" #include "info/info_memento.h" @@ -31,7 +32,6 @@ inline tr::phrase MediaTextPhrase(Type type) { switch (type) { case Type::Photo: return tr::lng_profile_photos; case Type::Video: return tr::lng_profile_videos; - case Type::GIF: return tr::ktg_profile_gif; case Type::File: return tr::lng_profile_files; case Type::MusicFile: return tr::lng_profile_songs; case Type::Link: return tr::lng_profile_shared_links; @@ -41,8 +41,12 @@ inline tr::phrase MediaTextPhrase(Type type) { }; inline auto MediaText(Type type) { - return [phrase = MediaTextPhrase(type)](int count) { - return phrase(tr::now, lt_count, count); + return [type](int count) { + if (type == Type::GIF) { + return ktr("ktg_profile_gif", count, { "count", QString::number(count) }); + } else { + return MediaTextPhrase(type)(tr::now, lt_count, count); + } }; } diff --git a/Telegram/SourceFiles/info/media/info_media_empty_widget.cpp b/Telegram/SourceFiles/info/media/info_media_empty_widget.cpp index 0f47032a6..6ade371ba 100644 --- a/Telegram/SourceFiles/info/media/info_media_empty_widget.cpp +++ b/Telegram/SourceFiles/info/media/info_media_empty_widget.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "info/media/info_media_empty_widget.h" +#include "kotato/kotato_lang.h" #include "ui/widgets/labels.h" #include "styles/style_info.h" #include "lang/lang_keys.h" @@ -57,7 +58,7 @@ void EmptyWidget::setSearchQuery(const QString &query) { case Type::Video: return tr::lng_media_video_empty(tr::now); case Type::GIF: - return tr::ktg_media_gif_empty(tr::now); + return ktr("ktg_media_gif_empty"); case Type::MusicFile: return query.isEmpty() ? tr::lng_media_song_empty(tr::now) diff --git a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp index 7a98a0f34..37f9d1567 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "info/profile/info_profile_actions.h" +#include "kotato/kotato_lang.h" #include "data/data_peer_values.h" #include "data/data_session.h" #include "data/data_folder.h" @@ -277,18 +278,18 @@ object_ptr DetailsFiller::setupInfo() { }); auto idInfo = addInfoOneLineInline( (user->isBot() - ? tr::ktg_profile_bot_id() - : tr::ktg_profile_user_id()), + ? rktr("ktg_profile_bot_id") + : rktr("ktg_profile_user_id")), std::move(idDrawableText), - tr::ktg_profile_copy_id(tr::now)); + ktr("ktg_profile_copy_id")); idInfo->setClickHandlerFilter([user](auto&&...) { const auto idText = IDString(user); if (!idText.isEmpty()) { QGuiApplication::clipboard()->setText(idText); Ui::Toast::Show(user->isBot() - ? tr::ktg_bot_id_copied(tr::now) - : tr::ktg_user_id_copied(tr::now)); + ? ktr("ktg_bot_id_copied") + : ktr("ktg_user_id_copied")); } return false; }); @@ -324,7 +325,7 @@ object_ptr DetailsFiller::setupInfo() { const auto phoneText = user->phone(); if (!phoneText.isEmpty()) { QGuiApplication::clipboard()->setText(App::formatPhone(phoneText)); - Ui::Toast::Show(tr::ktg_phone_copied(tr::now)); + Ui::Toast::Show(ktr("ktg_phone_copied")); } return false; }); @@ -351,7 +352,7 @@ object_ptr DetailsFiller::setupInfo() { const auto usernameText = user->userName(); if (!usernameText.isEmpty()) { QGuiApplication::clipboard()->setText('@' + usernameText); - Ui::Toast::Show(tr::ktg_mention_copied(tr::now)); + Ui::Toast::Show(ktr("ktg_mention_copied")); } return false; }); @@ -372,22 +373,22 @@ object_ptr DetailsFiller::setupInfo() { }); auto idInfo = addInfoOneLineInline( (_peer->isChat() - ? tr::ktg_profile_group_id() + ? rktr("ktg_profile_group_id") : _peer->isMegagroup() - ? tr::ktg_profile_supergroup_id() - : tr::ktg_profile_channel_id()), + ? rktr("ktg_profile_supergroup_id") + : rktr("ktg_profile_channel_id")), std::move(idDrawableText), - tr::ktg_profile_copy_id(tr::now)); + ktr("ktg_profile_copy_id")); idInfo->setClickHandlerFilter([peer = _peer](auto&&...) { const auto idText = IDString(peer); if (!idText.isEmpty()) { QGuiApplication::clipboard()->setText(idText); Ui::Toast::Show(peer->isChat() - ? tr::ktg_group_id_copied(tr::now) + ? ktr("ktg_group_id_copied") : peer->isMegagroup() - ? tr::ktg_supergroup_id_copied(tr::now) - : tr::ktg_channel_id_copied(tr::now)); + ? ktr("ktg_supergroup_id_copied") + : ktr("ktg_channel_id_copied")); } return false; }); diff --git a/Telegram/SourceFiles/intro/intro_code.cpp b/Telegram/SourceFiles/intro/intro_code.cpp index a2d288e64..fa8d78695 100644 --- a/Telegram/SourceFiles/intro/intro_code.cpp +++ b/Telegram/SourceFiles/intro/intro_code.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "intro/intro_code.h" +#include "kotato/kotato_lang.h" #include "lang/lang_keys.h" #include "intro/intro_signup.h" #include "intro/intro_password_check.h" @@ -352,7 +353,7 @@ void CodeWidget::gotPassword(const MTPaccount_Password &result) { close(); }; Ui::show(Box( - tr::ktg_passport_app_out_of_date(tr::now), + ktr("ktg_passport_app_out_of_date"), tr::lng_menu_update(tr::now), callback)); return; diff --git a/Telegram/SourceFiles/intro/intro_start.cpp b/Telegram/SourceFiles/intro/intro_start.cpp index 9d86a7197..86cf0376f 100644 --- a/Telegram/SourceFiles/intro/intro_start.cpp +++ b/Telegram/SourceFiles/intro/intro_start.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "intro/intro_start.h" +#include "kotato/kotato_lang.h" #include "lang/lang_keys.h" #include "intro/intro_qr.h" #include "intro/intro_phone.h" @@ -25,7 +26,7 @@ StartWidget::StartWidget( : Step(parent, account, data, true) { setMouseTracking(true); setTitleText(rpl::single(qsl("Kotatogram Desktop"))); - setDescriptionText(tr::ktg_intro_about()); + setDescriptionText(rktr("ktg_intro_about")); show(); } diff --git a/Telegram/SourceFiles/kotato/customboxes/fonts_box.cpp b/Telegram/SourceFiles/kotato/customboxes/fonts_box.cpp index d6e4a25c3..42e46fb5c 100644 --- a/Telegram/SourceFiles/kotato/customboxes/fonts_box.cpp +++ b/Telegram/SourceFiles/kotato/customboxes/fonts_box.cpp @@ -7,6 +7,7 @@ https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL */ #include "kotato/customboxes/fonts_box.h" +#include "kotato/kotato_lang.h" #include "base/platform/base_platform_info.h" #include "ui/widgets/checkbox.h" #include "ui/widgets/buttons.h" @@ -19,23 +20,23 @@ https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL #include "app.h" FontsBox::FontsBox(QWidget* parent) -: _useSystemFont(this, tr::ktg_fonts_use_system_font(tr::now), cUseSystemFont()) -, _useOriginalMetrics(this, tr::ktg_fonts_use_original_metrics(tr::now), cUseOriginalMetrics()) -, _mainFontName(this, st::defaultInputField, tr::ktg_fonts_main()) -, _semiboldFontName(this, st::defaultInputField, tr::ktg_fonts_semibold()) -, _semiboldIsBold(this, tr::ktg_fonts_semibold_is_bold(tr::now), cSemiboldFontIsBold()) -, _monospacedFontName(this, st::defaultInputField, tr::ktg_fonts_monospaced()) +: _useSystemFont(this, ktr("ktg_fonts_use_system_font"), cUseSystemFont()) +, _useOriginalMetrics(this, ktr("ktg_fonts_use_original_metrics"), cUseOriginalMetrics()) +, _mainFontName(this, st::defaultInputField, rktr("ktg_fonts_main")) +, _semiboldFontName(this, st::defaultInputField, rktr("ktg_fonts_semibold")) +, _semiboldIsBold(this, ktr("ktg_fonts_semibold_is_bold"), cSemiboldFontIsBold()) +, _monospacedFontName(this, st::defaultInputField, rktr("ktg_fonts_monospaced")) , _about(st::boxWidth - st::boxPadding.left() * 1.5) { } void FontsBox::prepare() { - setTitle(tr::ktg_fonts_title()); + setTitle(rktr("ktg_fonts_title")); addButton(tr::lng_settings_save(), [=] { save(); }); addButton(tr::lng_cancel(), [=] { closeBox(); }); - addLeftButton(tr::ktg_fonts_reset(), [=] { resetToDefault(); }); + addLeftButton(rktr("ktg_fonts_reset"), [=] { resetToDefault(); }); if (!cMainFont().isEmpty()) { _mainFontName->setText(cMainFont()); @@ -49,7 +50,7 @@ void FontsBox::prepare() { _monospacedFontName->setText(cMonospaceFont()); } - _about.setText(st::fontsBoxTextStyle, tr::ktg_fonts_about(tr::now)); + _about.setText(st::fontsBoxTextStyle, ktr("ktg_fonts_about")); _aboutHeight = _about.countHeight(st::boxWidth - st::boxPadding.left() * 1.5); setDimensions(st::boxWidth, _useSystemFont->height() diff --git a/Telegram/SourceFiles/kotato/customboxes/unpin_box.cpp b/Telegram/SourceFiles/kotato/customboxes/unpin_box.cpp index 285d45388..63ad9bba1 100644 --- a/Telegram/SourceFiles/kotato/customboxes/unpin_box.cpp +++ b/Telegram/SourceFiles/kotato/customboxes/unpin_box.cpp @@ -7,6 +7,7 @@ https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL */ #include "kotato/customboxes/unpin_box.h" +#include "kotato/kotato_lang.h" #include "lang/lang_keys.h" #include "apiwrap.h" #include "history/history_widget.h" @@ -30,7 +31,7 @@ UnpinMessageBox::UnpinMessageBox( } void UnpinMessageBox::prepare() { - addLeftButton(tr::ktg_hide_pinned_message(), [this] { hideMessage(); }); + addLeftButton(rktr("ktg_hide_pinned_message"), [this] { hideMessage(); }); addButton(tr::lng_pinned_unpin(), [this] { unpinMessage(); }); addButton(tr::lng_cancel(), [this] { closeBox(); }); diff --git a/Telegram/SourceFiles/kotato/kotato_lang.cpp b/Telegram/SourceFiles/kotato/kotato_lang.cpp new file mode 100644 index 000000000..edbec05f8 --- /dev/null +++ b/Telegram/SourceFiles/kotato/kotato_lang.cpp @@ -0,0 +1,294 @@ +/* +This file is part of Kotatogram Desktop, +the unofficial app based on Telegram Desktop. + +For license and copyright information please follow this link: +https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL +*/ +#include "kotato/kotato_lang.h" + +#include "base/parse_helper.h" +#include "lang/lang_tag.h" + +#include +#include +#include +#include + +namespace Kotato { +namespace Lang { +namespace { + +const auto kDefaultLanguage = qsl("en"); +const std::vector kPostfixes = { + "#zero", + "#one", + "#two", + "#few", + "#many", + "#other" +}; + +QString BaseLangCode; +QString LangCode; + +QMap DefaultValues; +QMap CurrentValues; + +rpl::event_stream<> LangChanges; + +QString LangDir() { + return cWorkingDir() + "tdata/ktg_lang/"; +} + +void ParseLanguageData( + const QString &langCode, + bool isDefault) { + const auto filename = isDefault + ? qsl(":/ktg_lang/%1.json").arg(langCode) + : LangDir() + (qsl("%1.json").arg(langCode)); + + QFile file(filename); + if (!file.exists()) { + return; + } + if (!file.open(QIODevice::ReadOnly)) { + LOG(("Kotato::Lang Info: file %1 could not be read.").arg(filename)); + return; + } + auto error = QJsonParseError{ 0, QJsonParseError::NoError }; + const auto document = QJsonDocument::fromJson( + base::parse::stripComments(file.readAll()), + &error); + file.close(); + + if (error.error != QJsonParseError::NoError) { + LOG(("Kotato::Lang Info: file %1 has failed to parse. Error: %2" + ).arg(filename + ).arg(error.errorString())); + return; + } else if (!document.isObject()) { + LOG(("Kotato::Lang Info: file %1 has failed to parse. Error: object expected" + ).arg(filename)); + return; + } + + const auto applyValue = [&](const QString &name, const QString &translation) { + if (langCode == kDefaultLanguage) { + DefaultValues.insert(name, translation); + } else { + CurrentValues.insert(name, translation); + } + }; + + const auto langKeys = document.object(); + const auto keyList = langKeys.keys(); + + for (auto i = keyList.constBegin(), e = keyList.constEnd(); i != e; ++i) { + const auto key = *i; + if (key.startsWith("dummy_")) { + continue; + } + + const auto value = langKeys.constFind(key); + + if ((*value).isString()) { + + applyValue(key, (*value).toString()); + + } else if ((*value).isObject()) { + + const auto keyPlurals = (*value).toObject(); + const auto pluralList = keyPlurals.keys(); + + for (auto pli = pluralList.constBegin(), ple = pluralList.constEnd(); pli != ple; ++pli) { + const auto plural = *pli; + const auto pluralValue = keyPlurals.constFind(plural); + + if (!(*pluralValue).isString()) { + LOG(("Kotato::Lang Info: wrong value for key %1 in %2 in file %3, string expected") + .arg(plural).arg(key).arg(filename)); + continue; + } + + const auto name = QString(key + "#" + plural); + const auto translation = (*pluralValue).toString(); + + applyValue(name, translation); + } + } else { + LOG(("Kotato::Lang Info: wrong value for key %1 in file %2, string or object expected") + .arg(key).arg(filename)); + } + } +} + +void UnpackDefault() { + const auto langDir = LangDir(); + if (!QDir().exists(langDir)) QDir().mkpath(langDir); + + const auto langs = QDir(":/ktg_lang").entryList(QStringList() << "*.json", QDir::Files); + auto neededLangs = QStringList() << kDefaultLanguage << LangCode << BaseLangCode; + neededLangs.removeDuplicates(); + + for (auto language : langs) { + language.chop(5); + if (!neededLangs.contains(language)) { + continue; + } + + const auto path = langDir + language + ".default.json"; + auto input = QFile(qsl(":/ktg_lang/%1.json").arg(language)); + auto output = QFile(path); + if (input.open(QIODevice::ReadOnly)) { + auto inputData = input.readAll(); + if (output.open(QIODevice::WriteOnly)) { + output.write(inputData); + output.close(); + } + input.close(); + } + } +} + +} // namespace + +void Load(const QString &baseLangCode, const QString &langCode) { + BaseLangCode = baseLangCode; + if (BaseLangCode.endsWith("-raw")) { + BaseLangCode.chop(4); + } + + LangCode = langCode.isEmpty() ? baseLangCode : langCode; + if (LangCode.endsWith("-raw")) { + LangCode.chop(4); + } + + DefaultValues.clear(); + CurrentValues.clear(); + + if (BaseLangCode != kDefaultLanguage) { + ParseLanguageData(kDefaultLanguage, true); + ParseLanguageData(kDefaultLanguage, false); + } + + ParseLanguageData(BaseLangCode, true); + ParseLanguageData(BaseLangCode, false); + + if (LangCode != BaseLangCode) { + ParseLanguageData(LangCode, true); + ParseLanguageData(LangCode, false); + } + + UnpackDefault(); + LangChanges.fire({}); +} + +QString Translate(const QString &key, Var var1, Var var2, Var var3, Var var4) { + auto phrase = (CurrentValues.contains(key) && !CurrentValues.value(key).isEmpty()) + ? CurrentValues.value(key) + : DefaultValues.value(key); + + for (const auto &v : { var1, var2, var3, var4 }) { + if (!v.key.isEmpty()) { + auto skipNext = false; + const auto key = qsl("{%1}").arg(v.key); + const auto neededLength = phrase.length() - key.length(); + for (auto i = 0; i <= neededLength; i++) { + if (skipNext) { + skipNext = false; + continue; + } + + if (phrase.at(i) == QChar('\\')) { + skipNext = true; + } else if (phrase.at(i) == QChar('{') && phrase.mid(i, key.length()) == key) { + phrase.replace(i, key.length(), v.value); + break; + } + } + } + } + + return phrase; +} + +QString Translate(const QString &key, float64 value, Var var1, Var var2, Var var3, Var var4) { + const auto shift = ::Lang::PluralShift(value); + return Translate(key + kPostfixes.at(shift), var1, var2, var3); +} + +TextWithEntities TranslateWithEntities(const QString &key, EntVar var1, EntVar var2, EntVar var3, EntVar var4) { + TextWithEntities phrase = { + (CurrentValues.contains(key) && !CurrentValues.value(key).isEmpty()) + ? CurrentValues.value(key) + : DefaultValues.value(key) + }; + + for (const auto &v : { var1, var2, var3, var4 }) { + if (!v.key.isEmpty()) { + auto skipNext = false; + const auto key = qsl("{%1}").arg(v.key); + const auto neededLength = phrase.text.length() - key.length(); + for (auto i = 0; i <= neededLength; i++) { + if (skipNext) { + skipNext = false; + continue; + } + + if (phrase.text.at(i) == QChar('\\')) { + skipNext = true; + } else if (phrase.text.at(i) == QChar('{') && phrase.text.mid(i, key.length()) == key) { + phrase.text.replace(i, key.length(), v.value.text); + const auto endOld = i + key.length(); + const auto endNew = i + v.value.text.length(); + + // Shift existing entities + if (endNew > endOld) { + const auto diff = endNew - endOld; + for (auto &entity : phrase.entities) { + if (entity.offset() > endOld) { + entity.shiftRight(diff); + } else if (entity.offset() <= i && entity.offset() + entity.length() >= endOld) { + entity.extendToRight(diff); + } + } + } else if (endNew < endOld) { + const auto diff = endOld - endNew; + for (auto &entity : phrase.entities) { + if (entity.offset() > endNew) { + entity.shiftLeft(diff); + } else if (entity.offset() <= i && entity.offset() + entity.length() >= endNew) { + entity.shrinkFromRight(diff); + } + } + } + + // Add new entities + for (auto entity : v.value.entities) { + phrase.entities.append(EntityInText( + entity.type(), + entity.offset() + i, + entity.length(), + entity.data())); + } + break; + } + } + } + } + + return phrase; +} + +TextWithEntities TranslateWithEntities(const QString &key, float64 value, EntVar var1, EntVar var2, EntVar var3, EntVar var4) { + const auto shift = ::Lang::PluralShift(value); + return TranslateWithEntities(key + kPostfixes.at(shift), var1, var2, var3, var4); +} + +rpl::producer<> Events() { + return LangChanges.events(); +} + +} // namespace Lang +} // namespace Kotato diff --git a/Telegram/SourceFiles/kotato/kotato_lang.h b/Telegram/SourceFiles/kotato/kotato_lang.h new file mode 100644 index 000000000..195e25ae0 --- /dev/null +++ b/Telegram/SourceFiles/kotato/kotato_lang.h @@ -0,0 +1,166 @@ +/* +This file is part of Kotatogram Desktop, +the unofficial app based on Telegram Desktop. + +For license and copyright information please follow this link: +https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL +*/ +#pragma once + +namespace Kotato { +namespace Lang { + +struct Var { + Var() {}; + Var(const QString &k, const QString &v) { + key = k; + value = v; + } + + QString key; + QString value; +}; + +struct EntVar { + EntVar() {}; + EntVar(const QString &k, TextWithEntities v) { + key = k; + value = v; + } + + QString key; + TextWithEntities value; +}; + +void Load(const QString &baseLangCode, const QString &langCode); + +QString Translate( + const QString &key, + Var var1 = Var(), + Var var2 = Var(), + Var var3 = Var(), + Var var4 = Var()); +QString Translate( + const QString &key, + float64 value, + Var var1 = Var(), + Var var2 = Var(), + Var var3 = Var(), + Var var4 = Var()); + +TextWithEntities TranslateWithEntities( + const QString &key, + EntVar var1 = EntVar(), + EntVar var2 = EntVar(), + EntVar var3 = EntVar(), + EntVar var4 = EntVar()); +TextWithEntities TranslateWithEntities( + const QString &key, + float64 value, + EntVar var1 = EntVar(), + EntVar var2 = EntVar(), + EntVar var3 = EntVar(), + EntVar var4 = EntVar()); + +rpl::producer<> Events(); + +} // namespace Lang +} // namespace Kotato + +// Shorthands + +inline QString ktr( + const QString &key, + ::Kotato::Lang::Var var1 = ::Kotato::Lang::Var(), + ::Kotato::Lang::Var var2 = ::Kotato::Lang::Var(), + ::Kotato::Lang::Var var3 = ::Kotato::Lang::Var(), + ::Kotato::Lang::Var var4 = ::Kotato::Lang::Var()) { + return ::Kotato::Lang::Translate(key, var1, var2, var3, var4); +} + +inline QString ktr( + const QString &key, + float64 value, + ::Kotato::Lang::Var var1 = ::Kotato::Lang::Var(), + ::Kotato::Lang::Var var2 = ::Kotato::Lang::Var(), + ::Kotato::Lang::Var var3 = ::Kotato::Lang::Var(), + ::Kotato::Lang::Var var4 = ::Kotato::Lang::Var()) { + return ::Kotato::Lang::Translate(key, value, var1, var2, var3, var4); +} + +inline TextWithEntities ktre( + const QString &key, + ::Kotato::Lang::EntVar var1 = ::Kotato::Lang::EntVar(), + ::Kotato::Lang::EntVar var2 = ::Kotato::Lang::EntVar(), + ::Kotato::Lang::EntVar var3 = ::Kotato::Lang::EntVar(), + ::Kotato::Lang::EntVar var4 = ::Kotato::Lang::EntVar()) { + return ::Kotato::Lang::TranslateWithEntities(key, var1, var2, var3, var4); +} + +inline TextWithEntities ktre( + const QString &key, + float64 value, + ::Kotato::Lang::EntVar var1 = ::Kotato::Lang::EntVar(), + ::Kotato::Lang::EntVar var2 = ::Kotato::Lang::EntVar(), + ::Kotato::Lang::EntVar var3 = ::Kotato::Lang::EntVar(), + ::Kotato::Lang::EntVar var4 = ::Kotato::Lang::EntVar()) { + return ::Kotato::Lang::TranslateWithEntities(key, value, var1, var2, var3, var4); +} + +inline rpl::producer rktr( + const QString &key, + ::Kotato::Lang::Var var1 = ::Kotato::Lang::Var(), + ::Kotato::Lang::Var var2 = ::Kotato::Lang::Var(), + ::Kotato::Lang::Var var3 = ::Kotato::Lang::Var(), + ::Kotato::Lang::Var var4 = ::Kotato::Lang::Var()) { + return rpl::single( + ::Kotato::Lang::Translate(key, var1, var2, var3, var4) + ) | rpl::then( + ::Kotato::Lang::Events() | rpl::map( + [=]{ return ::Kotato::Lang::Translate(key, var1, var2, var3, var4); }) + ); +} + +inline rpl::producer rktr( + const QString &key, + float64 value, + ::Kotato::Lang::Var var1 = ::Kotato::Lang::Var(), + ::Kotato::Lang::Var var2 = ::Kotato::Lang::Var(), + ::Kotato::Lang::Var var3 = ::Kotato::Lang::Var(), + ::Kotato::Lang::Var var4 = ::Kotato::Lang::Var()) { + return rpl::single( + ::Kotato::Lang::Translate(key, value, var1, var2, var3, var4) + ) | rpl::then( + ::Kotato::Lang::Events() | rpl::map( + [=]{ return ::Kotato::Lang::Translate(key, value, var1, var2, var3, var4); }) + ); +} + +inline rpl::producer rktre( + const QString &key, + ::Kotato::Lang::EntVar var1 = ::Kotato::Lang::EntVar(), + ::Kotato::Lang::EntVar var2 = ::Kotato::Lang::EntVar(), + ::Kotato::Lang::EntVar var3 = ::Kotato::Lang::EntVar(), + ::Kotato::Lang::EntVar var4 = ::Kotato::Lang::EntVar()) { + return rpl::single( + ::Kotato::Lang::TranslateWithEntities(key, var1, var2, var3, var4) + ) | rpl::then( + ::Kotato::Lang::Events() | rpl::map( + [=]{ return ::Kotato::Lang::TranslateWithEntities(key, var1, var2, var3, var4); }) + ); +} + +inline rpl::producer rktre( + const QString &key, + float64 value, + ::Kotato::Lang::EntVar var1 = ::Kotato::Lang::EntVar(), + ::Kotato::Lang::EntVar var2 = ::Kotato::Lang::EntVar(), + ::Kotato::Lang::EntVar var3 = ::Kotato::Lang::EntVar(), + ::Kotato::Lang::EntVar var4 = ::Kotato::Lang::EntVar()) { + return rpl::single( + ::Kotato::Lang::TranslateWithEntities(key, value, var1, var2, var3, var4) + ) | rpl::then( + ::Kotato::Lang::Events() | rpl::map( + [=]{ return ::Kotato::Lang::TranslateWithEntities(key, value, var1, var2, var3, var4); }) + ); +} diff --git a/Telegram/SourceFiles/kotato/settings_menu.cpp b/Telegram/SourceFiles/kotato/settings_menu.cpp index fc075c65e..836e595c1 100644 --- a/Telegram/SourceFiles/kotato/settings_menu.cpp +++ b/Telegram/SourceFiles/kotato/settings_menu.cpp @@ -7,6 +7,7 @@ https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL */ #include "kotato/settings_menu.h" +#include "kotato/kotato_lang.h" #include "base/platform/base_platform_info.h" #include "settings/settings_common.h" #include "settings/settings_chat.h" @@ -46,7 +47,7 @@ QString FileDialogTypeLabel(int value) { const auto typedValue = Platform::FileDialog::ImplementationType(value); switch (typedValue) { case Platform::FileDialog::ImplementationType::Default: - return tr::ktg_file_dialog_type_default(tr::now); + return ktr("ktg_file_dialog_type_default"); } return Platform::FileDialog::ImplementationTypeLabel(typedValue); } @@ -59,16 +60,16 @@ QString FileDialogTypeDescription(int value) { QString NetBoostLabel(int boost) { switch (boost) { case 0: - return tr::ktg_net_speed_boost_default(tr::now); + return ktr("ktg_net_speed_boost_default"); case 1: - return tr::ktg_net_speed_boost_slight(tr::now); + return ktr("ktg_net_speed_boost_slight"); case 2: - return tr::ktg_net_speed_boost_medium(tr::now); + return ktr("ktg_net_speed_boost_medium"); case 3: - return tr::ktg_net_speed_boost_big(tr::now); + return ktr("ktg_net_speed_boost_big"); default: Unexpected("Boost in Settings::NetBoostLabel."); @@ -79,16 +80,16 @@ QString NetBoostLabel(int boost) { QString UserpicRoundingLabel(int rounding) { switch (rounding) { case 0: - return tr::ktg_settings_userpic_rounding_none(tr::now); + return ktr("ktg_settings_userpic_rounding_none"); case 1: - return tr::ktg_settings_userpic_rounding_small(tr::now); + return ktr("ktg_settings_userpic_rounding_small"); case 2: - return tr::ktg_settings_userpic_rounding_big(tr::now); + return ktr("ktg_settings_userpic_rounding_big"); case 3: - return tr::ktg_settings_userpic_rounding_full(tr::now); + return ktr("ktg_settings_userpic_rounding_full"); default: Unexpected("Rounding in Settings::UserpicRoundingLabel."); @@ -99,22 +100,22 @@ QString UserpicRoundingLabel(int rounding) { QString TrayIconLabel(int icon) { switch (icon) { case 0: - return tr::ktg_settings_tray_icon_default(tr::now); + return ktr("ktg_settings_tray_icon_default"); case 1: - return tr::ktg_settings_tray_icon_blue(tr::now); + return ktr("ktg_settings_tray_icon_blue"); case 2: - return tr::ktg_settings_tray_icon_green(tr::now); + return ktr("ktg_settings_tray_icon_green"); case 3: - return tr::ktg_settings_tray_icon_orange(tr::now); + return ktr("ktg_settings_tray_icon_orange"); case 4: - return tr::ktg_settings_tray_icon_red(tr::now); + return ktr("ktg_settings_tray_icon_red"); case 5: - return tr::ktg_settings_tray_icon_legacy(tr::now); + return ktr("ktg_settings_tray_icon_legacy"); default: Unexpected("Icon in Settings::TrayIconLabel."); @@ -125,13 +126,13 @@ QString TrayIconLabel(int icon) { QString ChatIdLabel(int option) { switch (option) { case 0: - return tr::ktg_settings_chat_id_disable(tr::now); + return ktr("ktg_settings_chat_id_disable"); case 1: - return tr::ktg_settings_chat_id_telegram(tr::now); + return ktr("ktg_settings_chat_id_telegram"); case 2: - return tr::ktg_settings_chat_id_bot(tr::now); + return ktr("ktg_settings_chat_id_bot"); default: Unexpected("Option in Settings::ChatIdLabel."); @@ -143,7 +144,7 @@ QString ChatIdLabel(int option) { #define SettingsMenuCSwitch(LangKey, Option) AddButton( \ container, \ - tr::LangKey(), \ + rktr(#LangKey), \ st::settingsButton \ )->toggleOn( \ rpl::single(c##Option()) \ @@ -157,7 +158,7 @@ QString ChatIdLabel(int option) { #define SettingsMenuCFilterSwitch(LangKey, Option) AddButton( \ container, \ - tr::LangKey(), \ + rktr(#LangKey), \ st::settingsButton \ )->toggleOn( \ rpl::single(c##Option()) \ @@ -173,7 +174,7 @@ QString ChatIdLabel(int option) { #define SettingsMenuSwitch(LangKey, Option) AddButton( \ container, \ - tr::LangKey(), \ + rktr(#LangKey), \ st::settingsButton \ )->toggleOn( \ rpl::single(Option()) \ @@ -189,7 +190,7 @@ void SetupKotatoChats( not_null controller, not_null container) { AddSkip(container); - AddSubsectionTitle(container, tr::ktg_settings_chats()); + AddSubsectionTitle(container, rktr("ktg_settings_chats")); const auto recentStickersLimitLabel = container->add( object_ptr( @@ -204,10 +205,10 @@ void SetupKotatoChats( const auto updateRecentStickersLimitLabel = [=](int value) { if (value == 0) { recentStickersLimitLabel->setText( - tr::ktg_settings_recent_stickers_limit_none(tr::now)); + ktr("ktg_settings_recent_stickers_limit_none")); } else { recentStickersLimitLabel->setText( - tr::ktg_settings_recent_stickers_limit(tr::now, lt_count_decimal, value)); + ktr("ktg_settings_recent_stickers_limit", value, { "count", QString::number(value) })); } }; const auto updateRecentStickersLimitHeight = [=](int value) { @@ -229,7 +230,7 @@ void SetupKotatoChats( AddButton( container, - tr::ktg_settings_chat_list_compact(), + rktr("ktg_settings_chat_list_compact"), st::settingsButton )->toggleOn( rpl::single(DialogListLines() == 1) @@ -243,7 +244,7 @@ void SetupKotatoChats( AddButton( container, - tr::ktg_settings_always_show_scheduled(), + rktr("ktg_settings_always_show_scheduled"), st::settingsButton )->toggleOn( rpl::single(cAlwaysShowScheduled()) @@ -260,7 +261,7 @@ void SetupKotatoChats( AddButton( container, - tr::ktg_settings_fonts(), + rktr("ktg_settings_fonts"), st::settingsButton )->addClickHandler([=] { Ui::show(Box()); @@ -268,13 +269,13 @@ void SetupKotatoChats( AddButtonWithLabel( container, - tr::ktg_settings_userpic_rounding(), + rktr("ktg_settings_userpic_rounding"), rpl::single(UserpicRoundingLabel(cUserpicCornersType())), st::settingsButton )->addClickHandler([=] { Ui::show(Box<::Kotato::RadioBox>( - tr::ktg_settings_userpic_rounding(tr::now), - tr::ktg_settings_userpic_rounding_desc(tr::now), + ktr("ktg_settings_userpic_rounding"), + ktr("ktg_settings_userpic_rounding_desc"), cUserpicCornersType(), 4, UserpicRoundingLabel, @@ -290,7 +291,7 @@ void SetupKotatoChats( void SetupKotatoMessages(not_null container) { AddDivider(container); AddSkip(container); - AddSubsectionTitle(container, tr::ktg_settings_messages()); + AddSubsectionTitle(container, rktr("ktg_settings_messages")); const auto stickerHeightLabel = container->add( object_ptr( @@ -305,7 +306,7 @@ void SetupKotatoMessages(not_null container) { const auto updateStickerHeightLabel = [=](int value) { const auto pixels = QString::number(value); stickerHeightLabel->setText( - tr::ktg_settings_sticker_height(tr::now, lt_pixels, pixels)); + ktr("ktg_settings_sticker_height", { "pixels", pixels })); }; const auto updateStickerHeight = [=](int value) { updateStickerHeightLabel(value); @@ -323,7 +324,7 @@ void SetupKotatoMessages(not_null container) { container->add( object_ptr( container, - tr::ktg_settings_sticker_scale_both(tr::now), + ktr("ktg_settings_sticker_scale_both"), StickerScaleBoth(), st::settingsCheckbox), st::settingsCheckboxPadding @@ -336,12 +337,12 @@ void SetupKotatoMessages(not_null container) { }, container->lifetime()); AddSkip(container); - AddDividerText(container, tr::ktg_settings_sticker_scale_both_about()); + AddDividerText(container, rktr("ktg_settings_sticker_scale_both_about")); AddSkip(container); auto adaptiveBubblesButton = AddButton( container, - tr::ktg_settings_adaptive_bubbles(), + rktr("ktg_settings_adaptive_bubbles"), st::settingsButton ); @@ -350,7 +351,7 @@ void SetupKotatoMessages(not_null container) { container, CreateButton( container, - tr::ktg_settings_monospace_large_bubbles(), + rktr("ktg_settings_monospace_large_bubbles"), st::settingsButton))); adaptiveBubblesButton->toggleOn( @@ -386,28 +387,28 @@ void SetupKotatoMessages(not_null container) { void SetupKotatoForward(not_null container) { AddDivider(container); AddSkip(container); - AddSubsectionTitle(container, tr::ktg_settings_forward()); + AddSubsectionTitle(container, rktr("ktg_settings_forward")); SettingsMenuCSwitch(ktg_settings_forward_retain_selection, ForwardRetainSelection); SettingsMenuCSwitch(ktg_settings_forward_chat_on_click, ForwardChatOnClick); AddSkip(container); - AddDividerText(container, tr::ktg_settings_forward_chat_on_click_description()); + AddDividerText(container, rktr("ktg_settings_forward_chat_on_click_description")); } void SetupKotatoNetwork(not_null container) { AddSkip(container); - AddSubsectionTitle(container, tr::ktg_settings_network()); + AddSubsectionTitle(container, rktr("ktg_settings_network")); AddButtonWithLabel( container, - tr::ktg_settings_net_speed_boost(), + rktr("ktg_settings_net_speed_boost"), rpl::single(NetBoostLabel(cNetSpeedBoost())), st::settingsButton )->addClickHandler([=] { Ui::show(Box<::Kotato::RadioBox>( - tr::ktg_net_speed_boost_title(tr::now), - tr::ktg_net_speed_boost_desc(tr::now), + ktr("ktg_net_speed_boost_title"), + ktr("ktg_net_speed_boost_desc"), cNetSpeedBoost(), 4, NetBoostLabel, @@ -427,7 +428,7 @@ void SetupKotatoFolders( not_null container) { AddDivider(container); AddSkip(container); - AddSubsectionTitle(container, tr::ktg_settings_filters()); + AddSubsectionTitle(container, rktr("ktg_settings_filters")); SettingsMenuCFilterSwitch(ktg_settings_filters_only_unmuted_counter, UnmutedFilterCounterOnly); SettingsMenuCFilterSwitch(ktg_settings_filters_hide_all, HideFilterAllChats); @@ -442,13 +443,13 @@ void SetupKotatoSystem( not_null container) { AddDivider(container); AddSkip(container); - AddSubsectionTitle(container, tr::ktg_settings_system()); + AddSubsectionTitle(container, rktr("ktg_settings_system")); const auto qtScaleToggled = Ui::CreateChild>( container.get()); AddButton( container, - tr::ktg_settings_qt_scale(), + rktr("ktg_settings_qt_scale"), st::settingsButton )->toggleOn( qtScaleToggled->events_starting_with_copy(cQtScale()) @@ -477,7 +478,7 @@ void SetupKotatoSystem( container.get()); AddButton( container, - tr::ktg_settings_gtk_integration(), + rktr("ktg_settings_gtk_integration"), st::settingsButton )->toggleOn( gtkIntegrationToggled->events_starting_with_copy(cGtkIntegration()) @@ -513,12 +514,12 @@ void SetupKotatoSystem( AddButtonWithLabel( container, - tr::ktg_settings_file_dialog_type(), + rktr("ktg_settings_file_dialog_type"), fileDialogTypeText, st::settingsButton )->addClickHandler([=] { Ui::show(Box<::Kotato::RadioBox>( - tr::ktg_settings_file_dialog_type(tr::now), + ktr("ktg_settings_file_dialog_type"), int(FileDialogType()), int(Platform::FileDialog::ImplementationType::Count), FileDialogTypeLabel, @@ -561,7 +562,7 @@ void SetupKotatoSystem( AddButton( container, - tr::ktg_settings_disable_tray_counter(), + rktr("ktg_settings_disable_tray_counter"), st::settingsButton )->toggleOn( rpl::single(cDisableTrayCounter()) @@ -577,7 +578,7 @@ void SetupKotatoSystem( if (Platform::IsLinux()) { AddButton( container, - tr::ktg_settings_use_telegram_panel_icon(), + rktr("ktg_settings_use_telegram_panel_icon"), st::settingsButton )->toggleOn( rpl::single(cUseTelegramPanelIcon()) @@ -601,13 +602,13 @@ void SetupKotatoSystem( AddButtonWithLabel( container, - tr::ktg_settings_tray_icon(), + rktr("ktg_settings_tray_icon"), trayIconText, st::settingsButton )->addClickHandler([=] { Ui::show(Box<::Kotato::RadioBox>( - tr::ktg_settings_tray_icon(tr::now), - tr::ktg_settings_tray_icon_desc(tr::now), + ktr("ktg_settings_tray_icon"), + ktr("ktg_settings_tray_icon_desc"), cCustomAppIcon(), 6, TrayIconLabel, @@ -624,14 +625,14 @@ void SetupKotatoSystem( void SetupKotatoOther(not_null container) { AddDivider(container); AddSkip(container); - AddSubsectionTitle(container, tr::ktg_settings_other()); + AddSubsectionTitle(container, rktr("ktg_settings_other")); SettingsMenuCSwitch(ktg_settings_show_phone_number, ShowPhoneInDrawer); const auto chatIdButton = container->add( object_ptr