Compare commits
73 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f619afc4c6 | ||
|
|
7ad7028880 | ||
|
|
8e241e8b78 | ||
|
|
6226cf2809 | ||
|
|
7312114b75 | ||
|
|
0ff299758a | ||
|
|
de7c886008 | ||
|
|
e3aacc8072 | ||
|
|
4fc2c18f58 | ||
|
|
8a8e101cd0 | ||
|
|
c10dee11e8 | ||
|
|
4e5c4a462b | ||
|
|
bc7139d67a | ||
|
|
bf0bf908c2 | ||
|
|
dd005d9027 | ||
|
|
670a725c53 | ||
|
|
af28e3b0d7 | ||
|
|
ca90b8b8fd | ||
|
|
7b7b9db20b | ||
|
|
96dbb38aaa | ||
|
|
1b7777e3a0 | ||
|
|
5480a63beb | ||
|
|
cbf040b4dc | ||
|
|
8eb7f1f1aa | ||
|
|
8d28d0691f | ||
|
|
7dd24a30b5 | ||
|
|
1725927aea | ||
|
|
50ea4e316e | ||
|
|
734b426518 | ||
|
|
232d3dcb54 | ||
|
|
eaf1e2b18e | ||
|
|
4b7e5750ec | ||
|
|
d4af14041c | ||
|
|
b736d45bc4 | ||
|
|
7f7318c0bf | ||
|
|
0e2c282476 | ||
|
|
891d200e2d | ||
|
|
647ea44881 | ||
|
|
2c81014188 | ||
|
|
6c4943de97 | ||
|
|
f1d97fb92c | ||
|
|
26b05cf844 | ||
|
|
155cd8ce42 | ||
|
|
330fc35800 | ||
|
|
570cd9bdfa | ||
|
|
cd3c5e4ade | ||
|
|
38f94c63e9 | ||
|
|
34ab04cbe6 | ||
|
|
6b242a982b | ||
|
|
0d0307e175 | ||
|
|
835b1801bc | ||
|
|
5444b8166c | ||
|
|
c94a88e154 | ||
|
|
b185af6f0c | ||
|
|
8504bbb9d5 | ||
|
|
b2f1177661 | ||
|
|
6746d4ba2d | ||
|
|
0f7567970c | ||
|
|
7b7df23e3b | ||
|
|
252a6f9d5a | ||
|
|
a1adf2dae6 | ||
|
|
f4d1cdf14d | ||
|
|
22d905b39c | ||
|
|
58bbc3f537 | ||
|
|
03a59b04be | ||
|
|
2028116e22 | ||
|
|
244361b5c6 | ||
|
|
7e680624a0 | ||
|
|
3304ad7222 | ||
|
|
4384c80961 | ||
|
|
15befa98c4 | ||
|
|
b7ea15b83d | ||
|
|
3915957612 |
@@ -9,33 +9,35 @@ UPSTREAM="$REPO/upstream"
|
||||
EXTERNAL="$REPO/external"
|
||||
CACHE="$HOME/travisCacheDir"
|
||||
|
||||
QT_WAS_BUILT="0"
|
||||
|
||||
QT_VERSION=5.6.2
|
||||
|
||||
XKB_PATH="$BUILD/libxkbcommon"
|
||||
XKB_CACHE_VERSION="2"
|
||||
XKB_CACHE_VERSION="3"
|
||||
|
||||
QT_PATH="$BUILD/qt"
|
||||
QT_CACHE_VERSION="2"
|
||||
QT_CACHE_VERSION="3"
|
||||
QT_PATCH="$UPSTREAM/Telegram/Patches/qtbase_${QT_VERSION//\./_}.diff"
|
||||
|
||||
BREAKPAD_PATH="$BUILD/breakpad"
|
||||
BREAKPAD_CACHE_VERSION="2"
|
||||
BREAKPAD_CACHE_VERSION="3"
|
||||
|
||||
GYP_PATH="$BUILD/gyp"
|
||||
GYP_CACHE_VERSION="2"
|
||||
GYP_CACHE_VERSION="3"
|
||||
GYP_PATCH="$UPSTREAM/Telegram/Patches/gyp.diff"
|
||||
|
||||
VA_PATH="$BUILD/libva"
|
||||
VA_CACHE_VERSION="2"
|
||||
VA_CACHE_VERSION="3"
|
||||
|
||||
VDPAU_PATH="$BUILD/libvdpau"
|
||||
VDPAU_CACHE_VERSION="1"
|
||||
VDPAU_CACHE_VERSION="3"
|
||||
|
||||
FFMPEG_PATH="$BUILD/ffmpeg"
|
||||
FFMPEG_CACHE_VERSION="2"
|
||||
FFMPEG_CACHE_VERSION="3"
|
||||
|
||||
OPENAL_PATH="$BUILD/openal-soft"
|
||||
OPENAL_CACHE_VERSION="2"
|
||||
OPENAL_CACHE_VERSION="3"
|
||||
|
||||
GYP_DEFINES=""
|
||||
|
||||
@@ -57,6 +59,8 @@ run() {
|
||||
build() {
|
||||
mkdir -p "$EXTERNAL"
|
||||
|
||||
BUILD_VERSION_DATA=$(echo $BUILD_VERSION | cut -d'-' -f 1)
|
||||
|
||||
# libxkbcommon
|
||||
getXkbCommon
|
||||
|
||||
@@ -84,6 +88,11 @@ build() {
|
||||
# Guideline Support Library
|
||||
getGSL
|
||||
|
||||
if [ "$QT_WAS_BUILT" == "1" ]; then
|
||||
error_msg "Qt was built, please restart the job :("
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Configure the build
|
||||
if [[ $BUILD_VERSION == *"disable_autoupdate"* ]]; then
|
||||
GYP_DEFINES+=",TDESKTOP_DISABLE_AUTOUPDATE"
|
||||
@@ -205,7 +214,7 @@ buildVa() {
|
||||
rm -rf *
|
||||
|
||||
cd "$EXTERNAL"
|
||||
git clone git://anongit.freedesktop.org/git/libva
|
||||
git clone https://github.com/01org/libva
|
||||
|
||||
cd "$EXTERNAL/libva"
|
||||
./autogen.sh --prefix=$VA_PATH --enable-static
|
||||
@@ -511,6 +520,7 @@ getCustomQt() {
|
||||
}
|
||||
|
||||
buildCustomQt() {
|
||||
QT_WAS_BUILT="1"
|
||||
info_msg "Downloading and building patched qt"
|
||||
|
||||
if [ -d "$EXTERNAL/qt${QT_VERSION}" ]; then
|
||||
@@ -523,8 +533,7 @@ buildCustomQt() {
|
||||
git clone git://code.qt.io/qt/qt5.git qt${QT_VERSION}
|
||||
|
||||
cd "$EXTERNAL/qt${QT_VERSION}"
|
||||
git checkout "$(echo ${QT_VERSION} | sed -e s/\..$//)"
|
||||
perl init-repository --module-subset=qtbase,qtimageformats
|
||||
perl init-repository --branch --module-subset=qtbase,qtimageformats
|
||||
git checkout v${QT_VERSION}
|
||||
cd qtbase && git checkout v${QT_VERSION} && cd ..
|
||||
cd qtimageformats && git checkout v${QT_VERSION} && cd ..
|
||||
|
||||
12
README.md
@@ -6,6 +6,8 @@ This is the complete source code and the build instructions for the alpha versio
|
||||
[](https://travis-ci.org/telegramdesktop/tdesktop)
|
||||
[](https://ci.appveyor.com/project/telegramdesktop/tdesktop)
|
||||
|
||||
[![Preview of Telegram Desktop][preview_image]][preview_image_url]
|
||||
|
||||
The source code is published under GPLv3 with OpenSSL exception, the license is available [here][license].
|
||||
|
||||
## Supported systems
|
||||
@@ -47,7 +49,9 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
|
||||
[telegram_api]: https://core.telegram.org
|
||||
[telegram_proto]: https://core.telegram.org/mtproto
|
||||
[license]: LICENSE
|
||||
[msvc]: doc/building-msvc.md
|
||||
[xcode]: doc/building-xcode.md
|
||||
[xcode_old]: doc/building-xcode-old.md
|
||||
[cmake]: doc/building-cmake.md
|
||||
[msvc]: docs/building-msvc.md
|
||||
[xcode]: docs/building-xcode.md
|
||||
[xcode_old]: docs/building-xcode-old.md
|
||||
[cmake]: docs/building-cmake.md
|
||||
[preview_image]: https://github.com/telegramdesktop/tdesktop/blob/dev/docs/assets/preview.png "Preview of Telegram Desktop"
|
||||
[preview_image_url]: https://raw.githubusercontent.com/telegramdesktop/tdesktop/dev/docs/assets/preview.png
|
||||
|
||||
@@ -462,6 +462,8 @@ changePhoneSimcardTo: notificationSampleNameFg; // change phone number box right
|
||||
mainMenuBg: windowBg; // main menu background
|
||||
mainMenuCoverBg: dialogsBgActive; // main menu top cover background
|
||||
mainMenuCoverFg: windowFgActive; // main menu top cover text
|
||||
mainMenuCloudFg: activeButtonFg;
|
||||
mainMenuCloudBg: #2785bf | activeButtonBgRipple;
|
||||
|
||||
mediaPlayerBg: windowBg; // audio file player background
|
||||
mediaPlayerActiveFg: windowBgActive; // audio file player playback progress already played part
|
||||
|
||||
BIN
Telegram/Resources/icons/menu_cloud.png
Normal file
|
After Width: | Height: | Size: 302 B |
BIN
Telegram/Resources/icons/menu_cloud@2x.png
Normal file
|
After Width: | Height: | Size: 558 B |
BIN
Telegram/Resources/icons/volume_mute.png
Normal file
|
After Width: | Height: | Size: 147 B |
BIN
Telegram/Resources/icons/volume_mute@2x.png
Normal file
|
After Width: | Height: | Size: 206 B |
@@ -496,6 +496,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_create_public_link" = "Create public link";
|
||||
"lng_profile_edit_public_link" = "Edit public link";
|
||||
"lng_profile_manage_admins" = "Manage administrators";
|
||||
"lng_profile_manage_blocklist" = "Manage blocked users";
|
||||
"lng_profile_common_groups" = "{count:_not_used_|# group|# groups} in common";
|
||||
"lng_profile_common_groups_section" = "Groups in common";
|
||||
"lng_profile_participants_section" = "Members";
|
||||
@@ -575,6 +576,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_channel_admin_sure" = "Add {user} to administrators?";
|
||||
"lng_channel_admins_too_much" = "Sorry, you have reached the limit of the administrators. Please remove one administrator first.";
|
||||
|
||||
"lng_group_blocked_list_about" = "Blocked users are removed from the group and can only come back if invited by an admin.\nInvite links don't work for them.";
|
||||
|
||||
"lng_chat_all_members_admins" = "All Members Are Admins";
|
||||
"lng_chat_about_all_admins" = "Group members can add new members, edit name and photo of the group.";
|
||||
"lng_chat_about_admins" = "Group admins can add and remove members, edit name and photo of the group.";
|
||||
@@ -654,6 +657,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_action_pinned_media_video" = "a video";
|
||||
"lng_action_pinned_media_audio" = "an audio file";
|
||||
"lng_action_pinned_media_voice" = "a voice message";
|
||||
"lng_action_pinned_media_video_message" = "a video message";
|
||||
"lng_action_pinned_media_file" = "a file";
|
||||
"lng_action_pinned_media_gif" = "a GIF animation";
|
||||
"lng_action_pinned_media_contact" = "a contact information";
|
||||
@@ -778,8 +782,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_switch_gifs" = "GIFs";
|
||||
"lng_stickers_featured_add" = "Add";
|
||||
"lng_gifs_search" = "Search GIFs";
|
||||
"lng_gifs_no_saved" = "You have no saved GIFs yet.";
|
||||
|
||||
"lng_inline_bot_no_results" = "No results";
|
||||
"lng_inline_bot_no_results" = "No results.";
|
||||
"lng_inline_bot_via" = "via {inline_bot}";
|
||||
|
||||
"lng_box_remove" = "Remove";
|
||||
@@ -806,6 +811,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_in_dlg_audio_file" = "Audio file";
|
||||
"lng_in_dlg_contact" = "Contact";
|
||||
"lng_in_dlg_audio" = "Voice message";
|
||||
"lng_in_dlg_video_message" = "Video message";
|
||||
"lng_in_dlg_file" = "File";
|
||||
"lng_in_dlg_sticker" = "Sticker";
|
||||
"lng_in_dlg_sticker_emoji" = "{emoji} Sticker";
|
||||
@@ -885,6 +891,10 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_user_action_record_audio" = "{user} is recording a voice message";
|
||||
"lng_send_action_upload_audio" = "sending a voice message";
|
||||
"lng_user_action_upload_audio" = "{user} is sending a voice message";
|
||||
"lng_send_action_record_round" = "recording a video message";
|
||||
"lng_user_action_record_round" = "{user} is recording a video message";
|
||||
"lng_send_action_upload_round" = "sending a video message";
|
||||
"lng_user_action_upload_round" = "{user} is sending a video message";
|
||||
"lng_send_action_upload_photo" = "sending a photo";
|
||||
"lng_user_action_upload_photo" = "{user} is sending a photo";
|
||||
"lng_send_action_upload_file" = "sending a file";
|
||||
@@ -1075,7 +1085,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop was updated to version {version}\n\n{changes}\n\nFull version history is available here:\n{link}";
|
||||
"lng_new_version_minor" = "— Bug fixes and other minor improvements";
|
||||
"lng_new_version_text" = "— Send MP4/MOV files as videos that will play right inside Telegram.\n— Click on the date in any chat to quickly jump to messages from a specific day.\n— Change your phone number in Settings.\n— Edit who can see your last seen time and who can add you to groups in Settings.\n— Edit your list of blocked users in Settings.\n— App now respects the \"Do Not Disturb\" setting for macOS notifications.\n— Bug fixes and other minor improvements.";
|
||||
"lng_new_version_text" = "— Improved Emoji, Stickers, and Saved GIFs panel.\n— Bug fixes and other minor improvements.";
|
||||
|
||||
"lng_menu_insert_unicode" = "Insert Unicode control character";
|
||||
|
||||
|
||||
@@ -774,12 +774,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_recent_stickers" = "Häufig genutzt";
|
||||
"lng_switch_stickers" = "Sticker";
|
||||
"lng_switch_stickers_gifs" = "GIFs & Sticker";
|
||||
"lng_switch_emoji" = "Emoji";
|
||||
"lng_switch_gifs" = "GIFs";
|
||||
"lng_stickers_featured_add" = "Hinzufügen";
|
||||
"lng_gifs_search" = "Suche GIFs";
|
||||
|
||||
"lng_saved_gifs" = "Gespeicherte GIFs";
|
||||
"lng_inline_bot_results" = "Ergebnisse von {inline_bot}";
|
||||
"lng_inline_bot_no_results" = "Keine Ergebnisse";
|
||||
"lng_inline_bot_via" = "via {inline_bot}";
|
||||
|
||||
@@ -1076,7 +1075,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop wurde aktualisiert auf Version {version}\n\n{changes}\n\nGesamter Versionsverlauf:\n{link}";
|
||||
"lng_new_version_minor" = "— Fehlerbehebungen und Softwareoptimierungen";
|
||||
"lng_new_version_text" = "— Sende MP4/MOV Dateien als Videos. Sie werden dann direkt in der App abgespielt.\n— Schnell zu einem bestimmten Datum springen: Tippe auf das Datum im Chat und springe so direkt zu einem anderen Tag.\n— Neue Einstellungen: Telefonnummer ändern, \"zuletzt gesehen\" Status und Gruppeneinladungen in den Telegram-Einstellungen.\n— Die App hält sich an die \"Nicht stören\" Einstellungen bei macOS.\n— Fehlerbehebungen und kleinere Verbesserungen.";
|
||||
"lng_new_version_text" = "— Emoji-, Sticker- und GIF-Panel wurden optimiert.\n— Fehlerbehebungen und Softwareoptimierungen";
|
||||
|
||||
"lng_menu_insert_unicode" = "Unicode-Steuerzeichen einfügen";
|
||||
|
||||
|
||||
@@ -774,12 +774,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_recent_stickers" = "Uso frecuente";
|
||||
"lng_switch_stickers" = "Stickers";
|
||||
"lng_switch_stickers_gifs" = "GIF y stickers";
|
||||
"lng_switch_emoji" = "Emoji";
|
||||
"lng_switch_gifs" = "GIF";
|
||||
"lng_stickers_featured_add" = "Añadir";
|
||||
"lng_gifs_search" = "Buscar GIF";
|
||||
|
||||
"lng_saved_gifs" = "GIF guardados";
|
||||
"lng_inline_bot_results" = "Resultados de {inline_bot}";
|
||||
"lng_inline_bot_no_results" = "Sin resultados";
|
||||
"lng_inline_bot_via" = "vía {inline_bot}";
|
||||
|
||||
@@ -1076,7 +1075,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop ha sido actualizada a la versión {version}\n\n{changes}\n\nEl historial completo está disponible aquí:\n{link}";
|
||||
"lng_new_version_minor" = "— Corrección de errores y otras mejoras menores";
|
||||
"lng_new_version_text" = "— Envía archivos MP4/MOV como videos que se reproducirán dentro de Telegram.\n— Haz clic en la fecha en cualquier chat para ir a los mensajes de un día en específico.\n— Cambia tu número de teléfono en ajustes.\n— Edita quién puede ver tu última conexión y quién puede añadirte a grupos en ajustes.\n— Edita la lista de usuarios bloqueados en ajustes.\n— La aplicación ahora respeta la opción “No molestar” en las notificaciones de macOS. \n— Corrección de errores y otras mejoras menores.";
|
||||
"lng_new_version_text" = "— Mejoras en el panel de emojis, stickers y GIF guardados.\n— Corrección de errores y otras mejoras menores.";
|
||||
|
||||
"lng_menu_insert_unicode" = "Insertar caracteres de control Unicode";
|
||||
|
||||
|
||||
@@ -774,12 +774,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_recent_stickers" = "Usati di frequente";
|
||||
"lng_switch_stickers" = "Sticker";
|
||||
"lng_switch_stickers_gifs" = "GIF e Sticker";
|
||||
"lng_switch_emoji" = "Emoji";
|
||||
"lng_switch_gifs" = "GIF";
|
||||
"lng_stickers_featured_add" = "Aggiungi";
|
||||
"lng_gifs_search" = "Cerca GIF";
|
||||
|
||||
"lng_saved_gifs" = "GIF salvate";
|
||||
"lng_inline_bot_results" = "Risultati da {inline_bot}";
|
||||
"lng_inline_bot_no_results" = "Nessun risultato";
|
||||
"lng_inline_bot_via" = "via {inline_bot}";
|
||||
|
||||
@@ -1076,7 +1075,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop si è aggiornato alla versione {version}\n\n{changes}\n\nLa cronologia degli aggiornamenti è disponibile qui:\n{link}";
|
||||
"lng_new_version_minor" = "— Risoluzione di problemi e altri miglioramenti minori";
|
||||
"lng_new_version_text" = "— Vai alla data. Quando esegui una ricerca in una chat clicca sulla data per andare al giorno selezionato.\n— Aggiunte le Impostazioni per la privacy dell'ultimo accesso e per l'invito ai gruppi.\n— Cambia il tuo numero nelle Impostazioni.\n— Modifica la lista degli utenti bloccati nelle Impostazioni.\n— Invia file MP4/MOV come video in modo che vengano aperti all'interno di Telegram.\n— L'app ora rispetta la modalità \"Non disturbare\" per le notifiche di macOS.\n— Risoluzione di problemi e altri miglioramenti minori.";
|
||||
"lng_new_version_text" = "— Miglioramenti nel pannello Emoji, Sticker e GIF salvate.\n— Risoluzione di problemi e altri miglioramenti minori.";
|
||||
|
||||
"lng_menu_insert_unicode" = "Inserisci carattere di controllo Unicode";
|
||||
|
||||
|
||||
@@ -774,12 +774,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_recent_stickers" = "자주 사용";
|
||||
"lng_switch_stickers" = "스티커";
|
||||
"lng_switch_stickers_gifs" = "GIF & 스티커";
|
||||
"lng_switch_emoji" = "이모티콘";
|
||||
"lng_switch_gifs" = "GIF";
|
||||
"lng_stickers_featured_add" = "추가";
|
||||
"lng_gifs_search" = "GIF 검색";
|
||||
|
||||
"lng_saved_gifs" = "저장된 GIF";
|
||||
"lng_inline_bot_results" = "{inline_bot} 결과";
|
||||
"lng_inline_bot_no_results" = "결과 없음";
|
||||
"lng_inline_bot_via" = "{inline_bot} 결과";
|
||||
|
||||
@@ -1076,7 +1075,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "텔레그램 데스크탑은 {version} 버전으로 업데이트 되었습니다.\n\n{changes}\n\n전체 버전 히스토리는 아래에서 확인 가능합니다:\n{link}";
|
||||
"lng_new_version_minor" = "— 버그 수정 및 일부 기능 향상";
|
||||
"lng_new_version_text" = "— 텔레그램내에서 바로 MP4/MOV 파일 재생\n— 특정날자로 이동하여 대화내역 확인\n— 설정에서 전화번호 변경\n— 개인정보 설정화면에서 마지막 접속 및 그룹 초대 허용설정\n— 설정에서 차단된 사용자 리스트 수정\n— OSX 알림설정인 \"Do Not Disturb\" 설정 반영\n— 버그 수정 및 일부 기능 향상";
|
||||
"lng_new_version_text" = "— 이모티콘, 스티커 및 GIF 저장 패널 기능 향상\n— 버그 수정 및 일부 기능 향상";
|
||||
|
||||
"lng_menu_insert_unicode" = "유니코드 문자를 입력하세요.";
|
||||
|
||||
|
||||
@@ -774,12 +774,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_recent_stickers" = "Veelgebruikt";
|
||||
"lng_switch_stickers" = "Stickers";
|
||||
"lng_switch_stickers_gifs" = "GIF's & stickers";
|
||||
"lng_switch_emoji" = "Emoji";
|
||||
"lng_switch_gifs" = "GIF's";
|
||||
"lng_stickers_featured_add" = "Toevoegen";
|
||||
"lng_gifs_search" = "GIF's zoeken";
|
||||
|
||||
"lng_saved_gifs" = "Opgeslagen GIF's";
|
||||
"lng_inline_bot_results" = "Resultaten van {inline_bot}";
|
||||
"lng_inline_bot_no_results" = "Geen resultaten";
|
||||
"lng_inline_bot_via" = "via {inline_bot}";
|
||||
|
||||
@@ -1076,7 +1075,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram is bijgewerkt naar versie {version}\n\n{changes} \n\nVolledige versiegeschiedenis is hier te vinden:\n{link}";
|
||||
"lng_new_version_minor" = "— Probleemoplossing en andere kleine verbeteringen";
|
||||
"lng_new_version_text" = "— MP4/MOV-bestanden versturen als video, deze spelen direct af in Telegram.\n— Spring naar datum. Klik op de datum in een chat om naar een specifieke dag te springen.\n— Wijzig je telefoonnummer via de instellingen.\n— Privacyinstellingen voor \"laatst gezien\" en groepsuitnodigingen.\n— Geblokkeerde gebruikers beheren via instellingen.\n— Ondersteuning voor de \"Niet storen\"-functie van macOS.\n— Probleemoplossing en andere kleine verbeteringen.";
|
||||
"lng_new_version_text" = "— Verbeterd paneel voor Emoji's, stickers en opgeslagen GIF's.\n— Probleemoplossing en andere kleine verbeteringen.";
|
||||
|
||||
"lng_menu_insert_unicode" = "Unicode-besturingsteken invoegen";
|
||||
|
||||
|
||||
@@ -774,12 +774,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_recent_stickers" = "Usados frequentemente";
|
||||
"lng_switch_stickers" = "Stickers";
|
||||
"lng_switch_stickers_gifs" = "GIFs e Stickers";
|
||||
"lng_switch_emoji" = "Emoji";
|
||||
"lng_switch_gifs" = "GIFs";
|
||||
"lng_stickers_featured_add" = "Adicionar";
|
||||
"lng_gifs_search" = "Buscar GIFs";
|
||||
|
||||
"lng_saved_gifs" = "GIFs Salvos";
|
||||
"lng_inline_bot_results" = "Resultados de {inline_bot}";
|
||||
"lng_inline_bot_no_results" = "Nenhum resultado";
|
||||
"lng_inline_bot_via" = "via {inline_bot}";
|
||||
|
||||
@@ -1076,7 +1075,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop foi atualizado para a versão {version}\n\n{changes}\n\nHistórico completo de mudanças disponível aqui:\n{link}";
|
||||
"lng_new_version_minor" = "— Resolução de bugs e outras melhorias menores";
|
||||
"lng_new_version_text" = "— Envie arquivos MP4/MOV como vídeos que serão reproduzidos dentro do Telegram.\n— Clique em uma data na conversa para pular para o dia específico.\n— Altere seu número nas Configurações.\n— Edite quem pode ver suas opções de visto por último e quem pode te adicionar em grupos nas Configurações.\n— Edite a lista de usuários bloqueados nas Configurações.\n— O aplicativo agora respeita ao \"Não Perturbe\" nas notificações do macOS.\n— Resolução de bugs e outras melhorias.";
|
||||
"lng_new_version_text" = "— Melhorias no painel de Emoji, Stickers e GIFs Salvos.\n— Resolução de bugs e outras melhorias menores";
|
||||
|
||||
"lng_menu_insert_unicode" = "Inserir caractere de controle Unicode";
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileL
|
||||
fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
|
||||
|
||||
userEmpty#200250ba id:int = User;
|
||||
user#d10d979a flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?string bot_inline_placeholder:flags.19?string = User;
|
||||
user#2e13f4c3 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?string bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
|
||||
|
||||
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
|
||||
userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileLocation = UserProfilePhoto;
|
||||
@@ -357,6 +357,8 @@ inputMessagesFilterVoice#50f5c392 = MessagesFilter;
|
||||
inputMessagesFilterMusic#3751b49e = MessagesFilter;
|
||||
inputMessagesFilterChatPhotos#3a20ecb8 = MessagesFilter;
|
||||
inputMessagesFilterPhoneCalls#80c99768 flags:# missed:flags.0?true = MessagesFilter;
|
||||
inputMessagesFilterRoundVoice#7a7c17a4 = MessagesFilter;
|
||||
inputMessagesFilterRoundVideo#b549da53 = MessagesFilter;
|
||||
|
||||
updateNewMessage#1f2b0afd message:Message pts:int pts_count:int = Update;
|
||||
updateMessageID#4e90bfd6 id:int random_id:long = Update;
|
||||
@@ -440,8 +442,9 @@ photos.photosSlice#15051f54 count:int photos:Vector<Photo> users:Vector<User> =
|
||||
photos.photo#20212ca8 photo:Photo users:Vector<User> = photos.Photo;
|
||||
|
||||
upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
|
||||
upload.fileCdnRedirect#1508485a dc_id:int file_token:bytes encryption_key:bytes encryption_iv:bytes = upload.File;
|
||||
|
||||
dcOption#5d8c6cc flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true id:int ip_address:string port:int = DcOption;
|
||||
dcOption#5d8c6cc flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true id:int ip_address:string port:int = DcOption;
|
||||
|
||||
config#cb601684 flags:# phonecalls_enabled:flags.1?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int chat_big_size:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int rating_e_decay:int stickers_recent_limit:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string disabled_features:Vector<DisabledFeature> = Config;
|
||||
|
||||
@@ -501,6 +504,8 @@ sendMessageUploadDocumentAction#aa0cd9e4 progress:int = SendMessageAction;
|
||||
sendMessageGeoLocationAction#176f8ba1 = SendMessageAction;
|
||||
sendMessageChooseContactAction#628cbc6f = SendMessageAction;
|
||||
sendMessageGamePlayAction#dd6a8f48 = SendMessageAction;
|
||||
sendMessageRecordRoundAction#88f27fbc = SendMessageAction;
|
||||
sendMessageUploadRoundAction#bb718624 = SendMessageAction;
|
||||
|
||||
contacts.found#1aa1f784 results:Vector<Peer> chats:Vector<Chat> users:Vector<User> = contacts.Found;
|
||||
|
||||
@@ -533,7 +538,7 @@ accountDaysTTL#b8d0afdf days:int = AccountDaysTTL;
|
||||
documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
|
||||
documentAttributeAnimated#11b58939 = DocumentAttribute;
|
||||
documentAttributeSticker#6319d612 flags:# mask:flags.1?true alt:string stickerset:InputStickerSet mask_coords:flags.0?MaskCoords = DocumentAttribute;
|
||||
documentAttributeVideo#5910cccb duration:int w:int h:int = DocumentAttribute;
|
||||
documentAttributeVideo#ef02ce6 flags:# round_message:flags.0?true duration:int w:int h:int = DocumentAttribute;
|
||||
documentAttributeAudio#9852f9c6 flags:# voice:flags.10?true duration:int title:flags.0?string performer:flags.1?string waveform:flags.2?bytes = DocumentAttribute;
|
||||
documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
|
||||
documentAttributeHasStickers#9801d2f7 = DocumentAttribute;
|
||||
@@ -853,6 +858,13 @@ phoneCallProtocol#a2bb35cb flags:# udp_p2p:flags.0?true udp_reflector:flags.1?tr
|
||||
|
||||
phone.phoneCall#ec82e140 phone_call:PhoneCall users:Vector<User> = phone.PhoneCall;
|
||||
|
||||
upload.cdnFileReuploadNeeded#eea8e46e request_token:bytes = upload.CdnFile;
|
||||
upload.cdnFile#a99fca4f bytes:bytes = upload.CdnFile;
|
||||
|
||||
cdnPublicKey#c982eaba dc_id:int public_key:string = CdnPublicKey;
|
||||
|
||||
cdnConfig#5725e40a public_keys:Vector<CdnPublicKey> = CdnConfig;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
@@ -1024,6 +1036,8 @@ upload.saveFilePart#b304a621 file_id:long file_part:int bytes:bytes = Bool;
|
||||
upload.getFile#e3a6cfb5 location:InputFileLocation offset:int limit:int = upload.File;
|
||||
upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool;
|
||||
upload.getWebFile#24e6818d location:InputWebFileLocation offset:int limit:int = upload.WebFile;
|
||||
upload.getCdnFile#2000bcc3 file_token:bytes offset:int limit:int = upload.CdnFile;
|
||||
upload.reuploadCdnFile#2e7a2020 file_token:bytes request_token:bytes = Bool;
|
||||
|
||||
help.getConfig#c4f9186b = Config;
|
||||
help.getNearestDc#1fb33026 = NearestDc;
|
||||
@@ -1034,6 +1048,7 @@ help.getSupport#9cdf08cd = help.Support;
|
||||
help.getAppChangelog#9010ef6f prev_app_version:string = Updates;
|
||||
help.getTermsOfService#350170f3 = help.TermsOfService;
|
||||
help.setBotUpdatesStatus#ec22cfcd pending_updates_count:int message:string = Bool;
|
||||
help.getCdnConfig#52029342 = CdnConfig;
|
||||
|
||||
channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
|
||||
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
|
||||
@@ -1082,4 +1097,4 @@ phone.discardCall#78d413a6 peer:InputPhoneCall duration:int reason:PhoneCallDisc
|
||||
phone.setCallRating#1c536a34 peer:InputPhoneCall rating:int comment:string = Updates;
|
||||
phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool;
|
||||
|
||||
// LAYER 65
|
||||
// LAYER 66
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
IgnorableNamespaces="uap uap2 uap3 rescap">
|
||||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||
ProcessorArchitecture="x64"
|
||||
ProcessorArchitecture="ARCHITECTURE"
|
||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||
Version="1.0.28.0" />
|
||||
Version="1.0.33.0" />
|
||||
<Properties>
|
||||
<DisplayName>Telegram Desktop</DisplayName>
|
||||
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>
|
||||
@@ -28,7 +28,7 @@
|
||||
<Applications>
|
||||
<Application Id="Telegram.TelegramDesktop.Store" Executable="Telegram.exe" EntryPoint="Windows.FullTrustApplication">
|
||||
<uap:VisualElements
|
||||
BackgroundColor="transparent"
|
||||
BackgroundColor="#1e94d0"
|
||||
DisplayName="Telegram Desktop"
|
||||
Square150x150Logo="Assets\logo150\logo150.png"
|
||||
Square44x44Logo="Assets\logo44\logo44.png"
|
||||
|
||||
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 852 B After Width: | Height: | Size: 640 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 816 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 4.7 KiB |
@@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,28,0
|
||||
PRODUCTVERSION 1,0,28,0
|
||||
FILEVERSION 1,0,33,0
|
||||
PRODUCTVERSION 1,0,33,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -52,10 +52,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||
VALUE "FileDescription", "Telegram Desktop"
|
||||
VALUE "FileVersion", "1.0.28.0"
|
||||
VALUE "FileVersion", "1.0.33.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2017"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "1.0.28.0"
|
||||
VALUE "ProductVersion", "1.0.33.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,28,0
|
||||
PRODUCTVERSION 1,0,28,0
|
||||
FILEVERSION 1,0,33,0
|
||||
PRODUCTVERSION 1,0,33,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -43,10 +43,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||
VALUE "FileDescription", "Telegram Desktop Updater"
|
||||
VALUE "FileVersion", "1.0.28.0"
|
||||
VALUE "FileVersion", "1.0.33.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2017"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "1.0.28.0"
|
||||
VALUE "ProductVersion", "1.0.33.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -1,795 +0,0 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "genlang.h"
|
||||
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
//Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)
|
||||
#endif
|
||||
|
||||
typedef unsigned int uint32;
|
||||
|
||||
QString layoutDirection;
|
||||
typedef QMap<QByteArray, QString> LangKeys;
|
||||
LangKeys keys;
|
||||
typedef QMap<QByteArray, ushort> LangTags;
|
||||
LangTags tags;
|
||||
typedef QMap<QByteArray, QVector<QByteArray> > LangKeysTags;
|
||||
LangKeysTags keysTags;
|
||||
typedef QVector<QByteArray> KeysOrder;
|
||||
KeysOrder keysOrder;
|
||||
KeysOrder tagsOrder;
|
||||
typedef QMap<QByteArray, QMap<QByteArray, QVector<QString> > > LangKeysCounted;
|
||||
LangKeysCounted keysCounted;
|
||||
|
||||
static const QChar TextCommand(0x0010);
|
||||
static const QChar TextCommandLangTag(0x0020);
|
||||
|
||||
bool skipWhitespaces(const char *&from, const char *end) {
|
||||
while (from < end && (*from == ' ' || *from == '\n' || *from == '\t' || *from == '\r')) {
|
||||
++from;
|
||||
}
|
||||
return (from < end);
|
||||
}
|
||||
|
||||
bool skipComment(const char *&from, const char *end) {
|
||||
if (from >= end) return false;
|
||||
if (*from == '/') {
|
||||
if (from + 1 >= end) return true;
|
||||
if (*(from + 1) == '*') {
|
||||
from += 2;
|
||||
while (from + 1 < end && (*from != '*' || *(from + 1) != '/')) {
|
||||
++from;
|
||||
}
|
||||
from += 2;
|
||||
return (from < end);
|
||||
} else if (*(from + 1) == '/') {
|
||||
from += 2;
|
||||
while (from < end && *from != '\n' && *from != '\r') {
|
||||
++from;
|
||||
}
|
||||
if (from < end) ++from;
|
||||
return true;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool skipJunk(const char *&from, const char *end) {
|
||||
const char *start;
|
||||
do {
|
||||
start = from;
|
||||
if (!skipWhitespaces(from, end)) return false;
|
||||
if (!skipComment(from, end)) throw Exception("Unexpected end of comment!");
|
||||
} while (start != from);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool _lngEquals(const QByteArray &key, int from, int len, const char *value, int size) {
|
||||
if (size != len || from + len > key.size()) return false;
|
||||
for (const char *v = key.constData() + from, *e = v + len; v != e; ++v, ++value) {
|
||||
if (*v != *value) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define LNG_EQUALS_PART(key, from, len, value) _lngEquals(key, from, len, value, sizeof(value) - 1)
|
||||
#define LNG_EQUALS_TAIL(key, from, value) _lngEquals(key, from, key.size() - from, value, sizeof(value) - 1)
|
||||
#define LNG_EQUALS(key, value) _lngEquals(key, 0, key.size(), value, sizeof(value) - 1)
|
||||
|
||||
static const int MaxCountedValues = 6;
|
||||
|
||||
void readKeyValue(const char *&from, const char *end) {
|
||||
if (!skipJunk(from, end)) return;
|
||||
|
||||
if (*from != '"') throw Exception(QString("Expected quote before key name!"));
|
||||
const char *nameStart = ++from;
|
||||
while (from < end && ((*from >= 'a' && *from <= 'z') || (*from >= 'A' && *from <= 'Z') || *from == '_' || (*from >= '0' && *from <= '9'))) {
|
||||
++from;
|
||||
}
|
||||
|
||||
if (from == nameStart) throw Exception(QString("Expected key name!"));
|
||||
QByteArray varName = QByteArray(nameStart, int(from - nameStart));
|
||||
for (const char *t = nameStart; t + 1 < from; ++t) {
|
||||
if (*t == '_') {
|
||||
if (*(t + 1) == '_') throw Exception(QString("Bad key name: %1").arg(QLatin1String(varName)));
|
||||
++t;
|
||||
}
|
||||
}
|
||||
|
||||
if (from == end || *from != '"') throw Exception(QString("Expected quote after key name in key '%1'!").arg(QLatin1String(varName)));
|
||||
++from;
|
||||
|
||||
if (!skipJunk(from, end)) throw Exception(QString("Unexpected end of file in key '%1'!").arg(QLatin1String(varName)));
|
||||
if (*from != '=') throw Exception(QString("'=' expected in key '%1'!").arg(QLatin1String(varName)));
|
||||
|
||||
if (!skipJunk(++from, end)) throw Exception(QString("Unexpected end of file in key '%1'!").arg(QLatin1String(varName)));
|
||||
if (*from != '"') throw Exception(QString("Expected string after '=' in key '%1'!").arg(QLatin1String(varName)));
|
||||
|
||||
QByteArray varValue;
|
||||
const char *start = ++from;
|
||||
QVector<QByteArray> tagsList;
|
||||
while (from < end && *from != '"') {
|
||||
if (*from == '\n') {
|
||||
throw Exception(QString("Unexpected end of string in key '%1'!").arg(QLatin1String(varName)));
|
||||
}
|
||||
if (*from == '\\') {
|
||||
if (from + 1 >= end) throw Exception(QString("Unexpected end of file in key '%1'!").arg(QLatin1String(varName)));
|
||||
if (*(from + 1) == '"' || *(from + 1) == '\\' || *(from + 1) == '{') {
|
||||
if (from > start) varValue.append(start, int(from - start));
|
||||
start = ++from;
|
||||
} else if (*(from + 1) == 'n') {
|
||||
if (from > start) varValue.append(start, int(from - start));
|
||||
|
||||
varValue.append('\n');
|
||||
|
||||
start = (++from) + 1;
|
||||
}
|
||||
} else if (*from == '{') {
|
||||
if (from > start) varValue.append(start, int(from - start));
|
||||
|
||||
const char *tagStart = ++from;
|
||||
while (from < end && ((*from >= 'a' && *from <= 'z') || (*from >= 'A' && *from <= 'Z') || *from == '_' || (*from >= '0' && *from <= '9'))) {
|
||||
++from;
|
||||
}
|
||||
if (from == tagStart) throw Exception(QString("Expected tag name in key '%1'!").arg(QLatin1String(varName)));
|
||||
QByteArray tagName = QByteArray(tagStart, int(from - tagStart));
|
||||
|
||||
if (from == end || (*from != '}' && *from != ':')) throw Exception(QString("Expected '}' or ':' after tag name in key '%1'!").arg(QLatin1String(varName)));
|
||||
|
||||
LangTags::const_iterator i = tags.constFind(tagName);
|
||||
if (i == tags.cend()) {
|
||||
i = tags.insert(tagName, tagsOrder.size());
|
||||
tagsOrder.push_back(tagName);
|
||||
}
|
||||
if (0x0020 + *i > 0x007F) throw Exception(QString("Too many different tags in key '%1'").arg(QLatin1String(varName)));
|
||||
|
||||
QString tagReplacer(4, TextCommand);
|
||||
tagReplacer[1] = TextCommandLangTag;
|
||||
tagReplacer[2] = QChar(0x0020 + *i);
|
||||
varValue.append(tagReplacer.toUtf8());
|
||||
for (int j = 0, s = tagsList.size(); j < s; ++j) {
|
||||
if (tagsList.at(j) == tagName) throw Exception(QString("Tag '%1' double used in key '%2'!").arg(QLatin1String(tagName)).arg(QLatin1String(varName)));
|
||||
}
|
||||
tagsList.push_back(tagName);
|
||||
|
||||
if (*from == ':') {
|
||||
start = ++from;
|
||||
|
||||
QVector<QString> &counted(keysCounted[varName][tagName]);
|
||||
QByteArray subvarValue;
|
||||
bool foundtag = false;
|
||||
while (from < end && *from != '"' && *from != '}') {
|
||||
if (*from == '|') {
|
||||
if (from > start) subvarValue.append(start, int(from - start));
|
||||
counted.push_back(QString::fromUtf8(subvarValue));
|
||||
subvarValue = QByteArray();
|
||||
foundtag = false;
|
||||
start = from + 1;
|
||||
}
|
||||
if (*from == '\n') {
|
||||
throw Exception(QString("Unexpected end of string inside counted tag '%1' in '%2' key!").arg(QLatin1String(tagName)).arg(QLatin1String(varName)));
|
||||
}
|
||||
if (*from == '\\') {
|
||||
if (from + 1 >= end) throw Exception(QString("Unexpected end of file inside counted tag '%1' in '%2' key!").arg(QLatin1String(tagName)).arg(QLatin1String(varName)));
|
||||
if (*(from + 1) == '"' || *(from + 1) == '\\' || *(from + 1) == '{' || *(from + 1) == '#') {
|
||||
if (from > start) subvarValue.append(start, int(from - start));
|
||||
start = ++from;
|
||||
} else if (*(from + 1) == 'n') {
|
||||
if (from > start) subvarValue.append(start, int(from - start));
|
||||
|
||||
subvarValue.append('\n');
|
||||
|
||||
start = (++from) + 1;
|
||||
}
|
||||
} else if (*from == '{') {
|
||||
throw Exception(QString("Unexpected tag inside counted tag '%1' in '%2' key!").arg(QLatin1String(tagName)).arg(QLatin1String(varName)));
|
||||
} else if (*from == '#') {
|
||||
if (foundtag) throw Exception(QString("Replacement '#' double used inside counted tag '%1' in '%2' key!").arg(QLatin1String(tagName)).arg(QLatin1String(varName)));
|
||||
foundtag = true;
|
||||
if (from > start) subvarValue.append(start, int(from - start));
|
||||
subvarValue.append(tagReplacer.toUtf8());
|
||||
start = from + 1;
|
||||
}
|
||||
++from;
|
||||
}
|
||||
if (from >= end) throw Exception(QString("Unexpected end of file inside counted tag '%1' in '%2' key!").arg(QLatin1String(tagName)).arg(QLatin1String(varName)));
|
||||
if (*from == '"') throw Exception(QString("Unexpected end of string inside counted tag '%1' in '%2' key!").arg(QLatin1String(tagName)).arg(QLatin1String(varName)));
|
||||
|
||||
if (from > start) subvarValue.append(start, int(from - start));
|
||||
counted.push_back(QString::fromUtf8(subvarValue));
|
||||
|
||||
if (counted.size() > MaxCountedValues) {
|
||||
throw Exception(QString("Too many values inside counted tag '%1' in '%2' key!").arg(QLatin1String(tagName)).arg(QLatin1String(varName)));
|
||||
}
|
||||
}
|
||||
start = from + 1;
|
||||
}
|
||||
++from;
|
||||
}
|
||||
if (from >= end) throw Exception(QString("Unexpected end of file in key '%1'!").arg(QLatin1String(varName)));
|
||||
if (from > start) varValue.append(start, int(from - start));
|
||||
|
||||
if (!skipJunk(++from, end)) throw Exception(QString("Unexpected end of file in key '%1'!").arg(QLatin1String(varName)));
|
||||
if (*from != ';') throw Exception(QString("';' expected after \"value\" in key '%1'!").arg(QLatin1String(varName)));
|
||||
|
||||
skipJunk(++from, end);
|
||||
|
||||
if (varName == "direction") {
|
||||
throw Exception(QString("Unexpected value for 'direction' in key '%1'!").arg(QLatin1String(varName)));
|
||||
} else if (!LNG_EQUALS_PART(varName, 0, 4, "lng_")) {
|
||||
throw Exception(QString("Bad key '%1'!").arg(QLatin1String(varName)));
|
||||
} else if (keys.constFind(varName) != keys.cend()) {
|
||||
throw Exception(QString("Key '%1' doubled!").arg(QLatin1String(varName)));
|
||||
} else {
|
||||
keys.insert(varName, QString::fromUtf8(varValue));
|
||||
keysTags.insert(varName, tagsList);
|
||||
keysOrder.push_back(varName);
|
||||
}
|
||||
}
|
||||
|
||||
QString escapeCpp(const QByteArray &key, QString value) {
|
||||
if (value.isEmpty()) return "QString()";
|
||||
|
||||
QString res;
|
||||
res.reserve(value.size() * 10);
|
||||
bool instr = false;
|
||||
for (const QChar *ch = value.constData(), *e = value.constData() + value.size(); ch != e; ++ch) {
|
||||
if (ch->unicode() > 0x007F) {
|
||||
if (instr) {
|
||||
res.append('"');
|
||||
instr = false;
|
||||
}
|
||||
res.append(' ').append('u').append('"').append('\\').append('x').append(QString("%1").arg(ch->unicode(), 4, 16, QChar('0'))).append('"');
|
||||
} else {
|
||||
if (ch->unicode() == '\\' || ch->unicode() == '\n' || ch->unicode() == '\r' || ch->unicode() == '"') {
|
||||
if (!instr) {
|
||||
res.append(' ').append('u').append('"');
|
||||
instr = true;
|
||||
}
|
||||
res.append('\\');
|
||||
if (ch->unicode() == '\\' || ch->unicode() == '"') {
|
||||
res.append(*ch);
|
||||
} else if (ch->unicode() == '\n') {
|
||||
res.append('n');
|
||||
} else if (ch->unicode() == '\r') {
|
||||
res.append('r');
|
||||
}
|
||||
} else if (ch->unicode() < 0x0020) {
|
||||
if (*ch == TextCommand) {
|
||||
if (ch + 3 >= e || (ch + 1)->unicode() != TextCommandLangTag || (ch + 2)->unicode() > 0x007F || (ch + 2)->unicode() < 0x0020 || *(ch + 3) != TextCommand) {
|
||||
throw Exception(QString("Bad value for key '%1'").arg(QLatin1String(key)));
|
||||
} else {
|
||||
if (instr) {
|
||||
res.append('"');
|
||||
instr = false;
|
||||
}
|
||||
res.append(' ').append('u').append('"');
|
||||
res.append('\\').append('x').append(QString("%1").arg(ch->unicode(), 2, 16, QChar('0')));
|
||||
res.append('\\').append('x').append(QString("%1").arg((ch + 1)->unicode(), 2, 16, QChar('0')));
|
||||
res.append('\\').append('x').append(QString("%1").arg((ch + 2)->unicode(), 2, 16, QChar('0')));
|
||||
res.append('\\').append('x').append(QString("%1").arg((ch + 3)->unicode(), 2, 16, QChar('0')));
|
||||
res.append('"');
|
||||
ch += 3;
|
||||
}
|
||||
} else {
|
||||
throw Exception(QString("Bad value for key '%1'").arg(QLatin1String(key)));
|
||||
}
|
||||
} else {
|
||||
if (!instr) {
|
||||
res.append(' ').append('u').append('"');
|
||||
instr = true;
|
||||
}
|
||||
res.append(*ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (instr) res.append('"');
|
||||
return "qsl(" + res.mid(1) + ")";
|
||||
}
|
||||
|
||||
void writeCppKey(QTextStream &tcpp, const QByteArray &key, const QString &val) {
|
||||
tcpp << "\t\t\tset(" << key << ", " << escapeCpp(key, val) << ");\n";
|
||||
}
|
||||
|
||||
bool genLang(const QString &lang_in, const QString &lang_out) {
|
||||
QString lang_cpp = lang_out + ".cpp", lang_h = lang_out + ".h";
|
||||
QFile f(lang_in);
|
||||
if (!f.open(QIODevice::ReadOnly)) {
|
||||
cout << "Could not open lang input file '" << lang_in.toUtf8().constData() << "'!\n";
|
||||
QCoreApplication::exit(1);
|
||||
return false;
|
||||
}
|
||||
QByteArray checkCodec = f.read(3);
|
||||
if (checkCodec.size() < 3) {
|
||||
cout << "Bad lang input file '" << lang_in.toUtf8().constData() << "'!\n";
|
||||
QCoreApplication::exit(1);
|
||||
return false;
|
||||
}
|
||||
f.seek(0);
|
||||
|
||||
QByteArray data;
|
||||
int skip = 0;
|
||||
if ((checkCodec.at(0) == '\xFF' && checkCodec.at(1) == '\xFE') || (checkCodec.at(0) == '\xFE' && checkCodec.at(1) == '\xFF') || (checkCodec.at(1) == 0)) {
|
||||
QTextStream stream(&f);
|
||||
stream.setCodec("UTF-16");
|
||||
|
||||
QString string = stream.readAll();
|
||||
if (stream.status() != QTextStream::Ok) {
|
||||
cout << "Could not read valid UTF-16 file '" << lang_in.toUtf8().constData() << "'!\n";
|
||||
QCoreApplication::exit(1);
|
||||
return false;
|
||||
}
|
||||
f.close();
|
||||
|
||||
data = string.toUtf8();
|
||||
} else if (checkCodec.at(0) == 0) {
|
||||
QByteArray tmp = "\xFE\xFF" + f.readAll(); // add fake UTF-16 BOM
|
||||
f.close();
|
||||
|
||||
QTextStream stream(&tmp);
|
||||
stream.setCodec("UTF-16");
|
||||
QString string = stream.readAll();
|
||||
if (stream.status() != QTextStream::Ok) {
|
||||
cout << "Could not read valid UTF-16 file '" << lang_in.toUtf8().constData() << "'!\n";
|
||||
QCoreApplication::exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
data = string.toUtf8();
|
||||
} else {
|
||||
data = f.readAll();
|
||||
if (checkCodec.at(0) == '\xEF' && checkCodec.at(1) == '\xBB' && checkCodec.at(2) == '\xBF') {
|
||||
skip = 3; // skip UTF-8 BOM
|
||||
}
|
||||
}
|
||||
|
||||
const char *text = data.constData() + skip, *end = text + data.size() - skip;
|
||||
try {
|
||||
while (text < end) {
|
||||
readKeyValue(text, end);
|
||||
}
|
||||
|
||||
QByteArray cppText, hText;
|
||||
{
|
||||
QTextStream tcpp(&cppText), th(&hText);
|
||||
tcpp.setCodec("ISO 8859-1");
|
||||
th.setCodec("ISO 8859-1");
|
||||
th << "\
|
||||
/*\n\
|
||||
Created from \'/Resources/langs/lang.strings\' by \'/MetaLang\' project\n\
|
||||
\n\
|
||||
WARNING! All changes made in this file will be lost!\n\
|
||||
\n\
|
||||
This file is part of Telegram Desktop,\n\
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org\n\
|
||||
\n\
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify\n\
|
||||
it under the terms of the GNU General Public License as published by\n\
|
||||
the Free Software Foundation, either version 3 of the License, or\n\
|
||||
(at your option) any later version.\n\
|
||||
\n\
|
||||
It is distributed in the hope that it will be useful,\n\
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
|
||||
GNU General Public License for more details.\n\
|
||||
\n\
|
||||
In addition, as a special exception, the copyright holders give permission\n\
|
||||
to link the code of portions of this program with the OpenSSL library.\n\
|
||||
\n\
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org\n\
|
||||
*/\n";
|
||||
th << "#pragma once\n\n";
|
||||
|
||||
for (int i = 0, l = tagsOrder.size(); i < l; ++i) {
|
||||
th << "enum lngtag_" << tagsOrder[i] << " { lt_" << tagsOrder[i] << " = " << i << " };\n";
|
||||
}
|
||||
th << "static const ushort lngtags_cnt = " << tagsOrder.size() << ";\n";
|
||||
th << "static const ushort lngtags_max_counted_values = " << MaxCountedValues << ";\n";
|
||||
th << "\n";
|
||||
|
||||
th << "enum LangKey {\n";
|
||||
for (int i = 0, l = keysOrder.size(); i < l; ++i) {
|
||||
if (keysTags[keysOrder[i]].isEmpty()) {
|
||||
th << "\t" << keysOrder[i] << (i ? "" : " = 0") << ",\n";
|
||||
} else {
|
||||
th << "\t" << keysOrder[i] << "__tagged" << (i ? "" : " = 0") << ",\n";
|
||||
QMap<QByteArray, QVector<QString> > &countedTags(keysCounted[keysOrder[i]]);
|
||||
if (!countedTags.isEmpty()) {
|
||||
for (QMap<QByteArray, QVector<QString> >::const_iterator j = countedTags.cbegin(), e = countedTags.cend(); j != e; ++j) {
|
||||
const auto &counted(*j);
|
||||
for (int k = 0, s = counted.size(); k < s; ++k) {
|
||||
th << "\t" << keysOrder[i] << "__" + j.key() + QString::number(k).toUtf8() << ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
th << "\n\tlngkeys_cnt\n";
|
||||
th << "};\n\n";
|
||||
|
||||
th << "LangString lang(LangKey key);\n\n";
|
||||
th << "LangString langOriginal(LangKey key);\n\n";
|
||||
|
||||
for (int i = 0, l = keysOrder.size(); i < l; ++i) {
|
||||
QVector<QByteArray> &tagsList(keysTags[keysOrder[i]]);
|
||||
if (tagsList.isEmpty()) continue;
|
||||
|
||||
QMap<QByteArray, QVector<QString> > &countedTags(keysCounted[keysOrder[i]]);
|
||||
th << "inline LangString " << keysOrder[i] << "(";
|
||||
for (int j = 0, s = tagsList.size(); j < s; ++j) {
|
||||
if (countedTags[tagsList[j]].isEmpty()) {
|
||||
th << "lngtag_" << tagsList[j] << ", const QString &" << tagsList[j] << "__val";
|
||||
} else {
|
||||
th << "lngtag_" << tagsList[j] << ", float64 " << tagsList[j] << "__val";
|
||||
}
|
||||
if (j + 1 < s) th << ", ";
|
||||
}
|
||||
th << ") {\n";
|
||||
th << "\treturn lang(" << keysOrder[i] << "__tagged)";
|
||||
for (int j = 0, s = tagsList.size(); j < s; ++j) {
|
||||
if (countedTags[tagsList[j]].isEmpty()) {
|
||||
th << ".tag(lt_" << tagsList[j] << ", " << tagsList[j] << "__val)";
|
||||
} else {
|
||||
th << ".tag(lt_" << tagsList[j] << ", langCounted(" << keysOrder[i] << "__" << tagsList[j] << "0, lt_" << tagsList[j] << ", " << tagsList[j] << "__val))";
|
||||
}
|
||||
}
|
||||
th << ";\n";
|
||||
th << "}\n";
|
||||
}
|
||||
|
||||
tcpp << "\
|
||||
/*\n\
|
||||
Created from \'/Resources/langs/lang.strings\' by \'/MetaLang\' project\n\
|
||||
\n\
|
||||
WARNING! All changes made in this file will be lost!\n\
|
||||
\n\
|
||||
This file is part of Telegram Desktop,\n\
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org\n\
|
||||
\n\
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify\n\
|
||||
it under the terms of the GNU General Public License as published by\n\
|
||||
the Free Software Foundation, either version 3 of the License, or\n\
|
||||
(at your option) any later version.\n\
|
||||
\n\
|
||||
It is distributed in the hope that it will be useful,\n\
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
|
||||
GNU General Public License for more details.\n\
|
||||
\n\
|
||||
In addition, as a special exception, the copyright holders give permission\n\
|
||||
to link the code of portions of this program with the OpenSSL library.\n\
|
||||
\n\
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org\n\
|
||||
*/\n";
|
||||
tcpp << "#include \"lang.h\"\n\n";
|
||||
tcpp << "namespace {\n";
|
||||
|
||||
tcpp << "\tconst char *_langKeyNames[lngkeys_cnt] = {\n";
|
||||
for (int i = 0, l = keysOrder.size(); i < l; ++i) {
|
||||
if (keysTags[keysOrder[i]].isEmpty()) {
|
||||
tcpp << "\t\t\"" << keysOrder[i] << "\",\n";
|
||||
} else {
|
||||
tcpp << "\t\t\"" << keysOrder[i] << "__tagged\",\n";
|
||||
QMap<QByteArray, QVector<QString> > &countedTags(keysCounted[keysOrder[i]]);
|
||||
if (!countedTags.isEmpty()) {
|
||||
for (QMap<QByteArray, QVector<QString> >::const_iterator j = countedTags.cbegin(), e = countedTags.cend(); j != e; ++j) {
|
||||
const auto &counted(*j);
|
||||
for (int k = 0, s = counted.size(); k < s; ++k) {
|
||||
tcpp << "\t\t\"" << keysOrder[i] << "__" + j.key() + QString::number(k).toUtf8() << "\",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tcpp << "\t};\n\n";
|
||||
|
||||
tcpp << "\tLangString _langValues[lngkeys_cnt], _langValuesOriginal[lngkeys_cnt];\n\n";
|
||||
tcpp << "\tvoid set(LangKey key, const QString &val) {\n";
|
||||
tcpp << "\t\t_langValues[key] = val;\n";
|
||||
tcpp << "\t}\n\n";
|
||||
|
||||
tcpp << "\tclass LangInit {\n";
|
||||
tcpp << "\tpublic:\n";
|
||||
tcpp << "\t\tLangInit() {\n";
|
||||
for (int i = 0, l = keysOrder.size(); i < l; ++i) {
|
||||
writeCppKey(tcpp, keysOrder[i] + (keysTags[keysOrder[i]].isEmpty() ? "" : "__tagged"), keys[keysOrder[i]]);
|
||||
|
||||
QMap<QByteArray, QVector<QString> > &countedTags(keysCounted[keysOrder[i]]);
|
||||
if (!countedTags.isEmpty()) {
|
||||
for (QMap<QByteArray, QVector<QString> >::const_iterator j = countedTags.cbegin(), e = countedTags.cend(); j != e; ++j) {
|
||||
const auto &counted(*j);
|
||||
for (int k = 0, s = counted.size(); k < s; ++k) {
|
||||
writeCppKey(tcpp, keysOrder[i] + "__" + j.key() + QString::number(k).toUtf8(), counted[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tcpp << "\t\t}\n";
|
||||
tcpp << "\t};\n\n";
|
||||
|
||||
tcpp << "\tLangInit _langInit;\n\n";
|
||||
|
||||
tcpp << "\tinline bool _lngEquals(const QByteArray &key, int from, int len, const char *value, int size) {\n";
|
||||
tcpp << "\t\tif (size != len || from + len > key.size()) return false;\n";
|
||||
tcpp << "\t\tfor (const char *v = key.constData() + from, *e = v + len; v != e; ++v, ++value) {\n";
|
||||
tcpp << "\t\t\tif (*v != *value) return false;\n";
|
||||
tcpp << "\t\t}\n";
|
||||
tcpp << "\t\treturn true;\n";
|
||||
tcpp << "\t}\n";
|
||||
|
||||
tcpp << "}\n\n";
|
||||
|
||||
tcpp << "#define LNG_EQUALS_PART(key, from, len, value) _lngEquals(key, from, len, value, sizeof(value) - 1)\n";
|
||||
tcpp << "#define LNG_EQUALS_TAIL(key, from, value) _lngEquals(key, from, key.size() - from, value, sizeof(value) - 1)\n";
|
||||
tcpp << "#define LNG_EQUALS(key, value) _lngEquals(key, 0, key.size(), value, sizeof(value) - 1)\n\n";
|
||||
|
||||
tcpp << "LangString lang(LangKey key) {\n";
|
||||
tcpp << "\treturn (key < 0 || key > lngkeys_cnt) ? QString() : _langValues[key];\n";
|
||||
tcpp << "}\n\n";
|
||||
|
||||
tcpp << "LangString langOriginal(LangKey key) {\n";
|
||||
tcpp << "\treturn (key < 0 || key > lngkeys_cnt || _langValuesOriginal[key] == qsl(\"{}\")) ? QString() : (_langValuesOriginal[key].isEmpty() ? _langValues[key] : _langValuesOriginal[key]);\n";
|
||||
tcpp << "}\n\n";
|
||||
|
||||
tcpp << "const char *langKeyName(LangKey key) {\n";
|
||||
tcpp << "\treturn (key < 0 || key > lngkeys_cnt) ? \"\" : _langKeyNames[key];\n";
|
||||
tcpp << "}\n\n";
|
||||
|
||||
tcpp << "ushort LangLoader::tagIndex(const QByteArray &tag) const {\n";
|
||||
tcpp << "\tif (tag.isEmpty()) return lngtags_cnt;\n\n";
|
||||
if (!tags.isEmpty()) {
|
||||
QString tab("\t");
|
||||
tcpp << "\tconst char *ch = tag.constData(), *e = tag.constData() + tag.size();\n";
|
||||
QByteArray current;
|
||||
int depth = current.size();
|
||||
tcpp << "\tswitch (*ch) {\n";
|
||||
for (LangTags::const_iterator i = tags.cbegin(), j = i + 1, e = tags.cend(); i != e; ++i) {
|
||||
QByteArray tag = i.key();
|
||||
while (depth > 0 && tag.mid(0, depth) != current) {
|
||||
tcpp << tab.repeated(depth + 1) << "}\n";
|
||||
current.chop(1);
|
||||
--depth;
|
||||
tcpp << tab.repeated(depth + 1) << "break;\n";
|
||||
}
|
||||
do {
|
||||
if (tag == current) break;
|
||||
|
||||
char ich = i.key().at(current.size());
|
||||
tcpp << tab.repeated(current.size() + 1) << "case '" << ich << "':\n";
|
||||
if (j == e || ich != ((j.key().size() > depth) ? j.key().at(depth) : 0)) {
|
||||
if (tag == current + ich) {
|
||||
tcpp << tab.repeated(depth + 1) << "\tif (ch + " << (depth + 1) << " == e) return lt_" << tag << ";\n";
|
||||
} else {
|
||||
tcpp << tab.repeated(depth + 1) << "\tif (LNG_EQUALS_TAIL(tag, " << (depth + 1) << ", \"" << i.key().mid(depth + 1) << "\")) return lt_" << tag << ";\n";
|
||||
}
|
||||
tcpp << tab.repeated(depth + 1) << "break;\n";
|
||||
break;
|
||||
}
|
||||
|
||||
++depth;
|
||||
current += ich;
|
||||
|
||||
bool exact = (tag == current);
|
||||
if (exact) {
|
||||
tcpp << tab.repeated(depth + 1) << "if (ch + " << depth << " == e) {\n";
|
||||
tcpp << tab.repeated(depth + 1) << "\treturn lt_" << tag << ";\n";
|
||||
tcpp << tab.repeated(depth + 1) << "}\n";
|
||||
}
|
||||
|
||||
QByteArray nexttag = j.key();
|
||||
if (exact && depth > 0 && nexttag.mid(0, depth) != current) {
|
||||
current.chop(1);
|
||||
--depth;
|
||||
tcpp << tab.repeated(depth + 1) << "break;\n";
|
||||
break;
|
||||
} else {
|
||||
tcpp << tab.repeated(depth + 1) << "if (ch + " << depth << " < e) switch (*(ch + " << depth << ")) {\n";
|
||||
}
|
||||
} while (true);
|
||||
++j;
|
||||
}
|
||||
while (QByteArray() != current) {
|
||||
tcpp << tab.repeated(depth + 1) << "}\n";
|
||||
current.chop(1);
|
||||
--depth;
|
||||
tcpp << tab.repeated(depth + 1) << "break;\n";
|
||||
}
|
||||
tcpp << "\t}\n\n";
|
||||
}
|
||||
tcpp << "\treturn lngtags_cnt;\n";
|
||||
tcpp << "}\n\n";
|
||||
|
||||
tcpp << "LangKey LangLoader::keyIndex(const QByteArray &key) const {\n";
|
||||
tcpp << "\tif (key.size() < 5 || !LNG_EQUALS_PART(key, 0, 4, \"lng_\")) return lngkeys_cnt;\n\n";
|
||||
if (!keys.isEmpty()) {
|
||||
QString tab("\t");
|
||||
tcpp << "\tconst char *ch = key.constData(), *e = key.constData() + key.size();\n";
|
||||
QByteArray current("lng_");
|
||||
int depth = current.size();
|
||||
tcpp << "\tswitch (*(ch + " << depth << ")) {\n";
|
||||
for (LangKeys::const_iterator i = keys.cbegin(), j = i + 1, e = keys.cend(); i != e; ++i) {
|
||||
QByteArray key = i.key();
|
||||
while (depth > 0 && key.mid(0, depth) != current) {
|
||||
tcpp << tab.repeated(depth - 3) << "}\n";
|
||||
current.chop(1);
|
||||
--depth;
|
||||
tcpp << tab.repeated(depth - 3) << "break;\n";
|
||||
}
|
||||
do {
|
||||
if (key == current) break;
|
||||
|
||||
char ich = i.key().at(current.size());
|
||||
tcpp << tab.repeated(current.size() - 3) << "case '" << ich << "':\n";
|
||||
if (j == e || ich != ((j.key().size() > depth) ? j.key().at(depth) : 0)) {
|
||||
if (key == current + ich) {
|
||||
tcpp << tab.repeated(depth - 3) << "\tif (ch + " << (depth + 1) << " == e) return " << key << (keysTags[key].isEmpty() ? "" : "__tagged") << ";\n";
|
||||
} else {
|
||||
tcpp << tab.repeated(depth - 3) << "\tif (LNG_EQUALS_TAIL(key, " << (depth + 1) << ", \"" << i.key().mid(depth + 1) << "\")) return " << key << (keysTags[key].isEmpty() ? "" : "__tagged") << ";\n";
|
||||
}
|
||||
tcpp << tab.repeated(depth - 3) << "break;\n";
|
||||
break;
|
||||
}
|
||||
|
||||
++depth;
|
||||
current += ich;
|
||||
|
||||
bool exact = (key == current);
|
||||
if (exact) {
|
||||
tcpp << tab.repeated(depth - 3) << "if (ch + " << depth << " == e) {\n";
|
||||
tcpp << tab.repeated(depth - 3) << "\treturn " << key << (keysTags[key].isEmpty() ? "" : "__tagged") << ";\n";
|
||||
tcpp << tab.repeated(depth - 3) << "}\n";
|
||||
}
|
||||
|
||||
QByteArray nextkey = j.key();
|
||||
if (exact && depth > 0 && nextkey.mid(0, depth) != current) {
|
||||
current.chop(1);
|
||||
--depth;
|
||||
tcpp << tab.repeated(depth - 3) << "break;\n";
|
||||
break;
|
||||
} else {
|
||||
tcpp << tab.repeated(depth - 3) << "if (ch + " << depth << " < e) switch (*(ch + " << depth << ")) {\n";
|
||||
}
|
||||
} while (true);
|
||||
++j;
|
||||
}
|
||||
while (QByteArray("lng_") != current) {
|
||||
tcpp << tab.repeated(depth - 3) << "}\n";
|
||||
current.chop(1);
|
||||
--depth;
|
||||
tcpp << tab.repeated(depth - 3) << "break;\n";
|
||||
}
|
||||
tcpp << "\t}\n\n";
|
||||
}
|
||||
tcpp << "\treturn lngkeys_cnt;\n";
|
||||
tcpp << "}\n\n";
|
||||
|
||||
tcpp << "bool LangLoader::tagReplaced(LangKey key, ushort tag) const {\n";
|
||||
if (!tags.isEmpty()) {
|
||||
tcpp << "\tswitch (key) {\n";
|
||||
for (int i = 0, l = keysOrder.size(); i < l; ++i) {
|
||||
QVector<QByteArray> &tagsList(keysTags[keysOrder[i]]);
|
||||
if (tagsList.isEmpty()) continue;
|
||||
|
||||
tcpp << "\tcase " << keysOrder[i] << "__tagged: {\n";
|
||||
tcpp << "\t\tswitch (tag) {\n";
|
||||
for (int j = 0, s = tagsList.size(); j < s; ++j) {
|
||||
tcpp << "\t\tcase lt_" << tagsList[j] << ":\n";
|
||||
}
|
||||
tcpp << "\t\t\treturn true;\n";
|
||||
tcpp << "\t\t}\n";
|
||||
tcpp << "\t} break;\n";
|
||||
}
|
||||
tcpp << "\t}\n\n";
|
||||
}
|
||||
tcpp << "\treturn false;";
|
||||
tcpp << "}\n\n";
|
||||
|
||||
tcpp << "LangKey LangLoader::subkeyIndex(LangKey key, ushort tag, ushort index) const {\n";
|
||||
tcpp << "\tif (index >= lngtags_max_counted_values) return lngkeys_cnt;\n\n";
|
||||
if (!tags.isEmpty()) {
|
||||
tcpp << "\tswitch (key) {\n";
|
||||
for (auto key : keysOrder) {
|
||||
QVector<QByteArray> &tagsList(keysTags[key]);
|
||||
if (tagsList.isEmpty()) continue;
|
||||
|
||||
QMap<QByteArray, QVector<QString> > &countedTags(keysCounted[key]);
|
||||
bool hasCounted = false;
|
||||
for (auto tag : tagsList) {
|
||||
if (!countedTags[tag].isEmpty()) {
|
||||
hasCounted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasCounted) continue;
|
||||
|
||||
tcpp << "\tcase " << key << "__tagged: {\n";
|
||||
tcpp << "\t\tswitch (tag) {\n";
|
||||
for (auto tag : tagsList) {
|
||||
if (!countedTags[tag].isEmpty()) {
|
||||
tcpp << "\t\tcase lt_" << tag << ": return LangKey(" << key << "__" << tag << "0 + index);\n";
|
||||
}
|
||||
}
|
||||
tcpp << "\t\t}\n";
|
||||
tcpp << "\t} break;\n";
|
||||
}
|
||||
tcpp << "\t}\n\n";
|
||||
}
|
||||
tcpp << "\treturn lngkeys_cnt;\n";
|
||||
tcpp << "}\n\n";
|
||||
|
||||
tcpp << "bool LangLoader::feedKeyValue(LangKey key, const QString &value) {\n";
|
||||
tcpp << "\tif (key < lngkeys_cnt) {\n";
|
||||
tcpp << "\t\t_found[key] = 1;\n";
|
||||
tcpp << "\t\tif (_langValuesOriginal[key].isEmpty()) {\n";
|
||||
tcpp << "\t\t\t_langValuesOriginal[key] = _langValues[key].isEmpty() ? qsl(\"{}\") : _langValues[key];\n";
|
||||
tcpp << "\t\t}\n";
|
||||
tcpp << "\t\t_langValues[key] = value;\n";
|
||||
tcpp << "\t\treturn true;\n";
|
||||
tcpp << "\t}\n";
|
||||
tcpp << "\treturn false;\n";
|
||||
tcpp << "}\n\n";
|
||||
}
|
||||
|
||||
QFile cpp(lang_cpp), h(lang_h);
|
||||
bool write_cpp = true, write_h = true;
|
||||
if (cpp.open(QIODevice::ReadOnly)) {
|
||||
QByteArray wasCpp = cpp.readAll();
|
||||
if (wasCpp.size() == cppText.size()) {
|
||||
if (!memcmp(wasCpp.constData(), cppText.constData(), cppText.size())) {
|
||||
write_cpp = false;
|
||||
}
|
||||
}
|
||||
cpp.close();
|
||||
}
|
||||
if (write_cpp) {
|
||||
if (!cpp.open(QIODevice::WriteOnly)) throw Exception("Could not open lang.cpp for writing!");
|
||||
if (cpp.write(cppText) != cppText.size()) throw Exception("Could not open lang.cpp for writing!");
|
||||
}
|
||||
if (h.open(QIODevice::ReadOnly)) {
|
||||
QByteArray wasH = h.readAll();
|
||||
if (wasH.size() == hText.size()) {
|
||||
if (!memcmp(wasH.constData(), hText.constData(), hText.size())) {
|
||||
write_h = false;
|
||||
}
|
||||
}
|
||||
h.close();
|
||||
}
|
||||
if (write_h) {
|
||||
if (!h.open(QIODevice::WriteOnly)) throw Exception("Could not open lang.h for writing!");
|
||||
if (h.write(hText) != hText.size()) throw Exception("Could not open lang.h for writing!");
|
||||
}
|
||||
} catch (exception &e) {
|
||||
cout << e.what() << "\n";
|
||||
QCoreApplication::exit(1);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QRegularExpression>
|
||||
#include <QtGui/QImage>
|
||||
#include <QtGui/QPainter>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::exception;
|
||||
|
||||
class Exception : public exception {
|
||||
public:
|
||||
|
||||
Exception(const QString &msg) : _msg(msg.toUtf8()) {
|
||||
}
|
||||
|
||||
virtual const char *what() const throw() {
|
||||
return _msg.constData();
|
||||
}
|
||||
virtual ~Exception() throw() {
|
||||
}
|
||||
|
||||
private:
|
||||
QByteArray _msg;
|
||||
};
|
||||
|
||||
bool genLang(const QString &lang_in, const QString &lang_out);
|
||||
|
||||
class GenLang : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GenLang(const QString &lang_in, const QString &lang_out) : QObject(0),
|
||||
_lang_in(lang_in), _lang_out(lang_out) {
|
||||
}
|
||||
|
||||
public slots :
|
||||
void run() {
|
||||
if (genLang(_lang_in, _lang_out)) {
|
||||
emit finished();
|
||||
}
|
||||
}
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
private:
|
||||
|
||||
QString _lang_in, _lang_out;
|
||||
};
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "mlmain.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
QString lang_in("lang.strings"), lang_out("lang");
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
if (string("-lang_in") == argv[i]) {
|
||||
if (++i < argc) lang_in = argv[i];
|
||||
} else if (string("-lang_out") == argv[i]) {
|
||||
if (++i < argc) lang_out = argv[i];
|
||||
}
|
||||
}
|
||||
#ifdef Q_OS_MAC
|
||||
if (QDir(QString()).absolutePath() == "/") {
|
||||
QString first = argc ? QString::fromLocal8Bit(argv[0]) : QString();
|
||||
if (!first.isEmpty()) {
|
||||
QFileInfo info(first);
|
||||
if (info.exists()) {
|
||||
QDir result(info.absolutePath() + "/../../..");
|
||||
QString basePath = result.absolutePath() + '/';
|
||||
lang_in = basePath + lang_in;
|
||||
lang_out = basePath + lang_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
QObject *taskImpl = new GenLang(lang_in, lang_out);
|
||||
|
||||
QCoreApplication a(argc, argv);
|
||||
|
||||
QObject::connect(taskImpl, SIGNAL(finished()), &a, SLOT(quit()));
|
||||
QTimer::singleShot(0, taskImpl, SLOT(run()));
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
@@ -20,7 +20,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/timer.h"
|
||||
#include "core/single_timer.h"
|
||||
#include "mtproto/sender.h"
|
||||
|
||||
namespace Api {
|
||||
|
||||
@@ -34,12 +36,9 @@ inline const MTPVector<MTPChat> *getChatsFromMessagesChats(const MTPmessages_Cha
|
||||
|
||||
} // namespace Api
|
||||
|
||||
class ApiWrap : public QObject, public RPCSender {
|
||||
Q_OBJECT
|
||||
|
||||
class ApiWrap : private MTP::Sender {
|
||||
public:
|
||||
ApiWrap(QObject *parent);
|
||||
void init();
|
||||
ApiWrap();
|
||||
|
||||
using RequestMessageDataCallback = base::lambda<void(ChannelData*, MsgId)>;
|
||||
void requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback callback);
|
||||
@@ -47,14 +46,16 @@ public:
|
||||
void requestFullPeer(PeerData *peer);
|
||||
void requestPeer(PeerData *peer);
|
||||
void requestPeers(const QList<PeerData*> &peers);
|
||||
void requestLastParticipants(ChannelData *peer, bool fromStart = true);
|
||||
void requestBots(ChannelData *peer);
|
||||
void requestLastParticipants(ChannelData *channel, bool fromStart = true);
|
||||
void requestBots(ChannelData *channel);
|
||||
void requestParticipantsCountDelayed(ChannelData *channel);
|
||||
|
||||
void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result);
|
||||
void processFullPeer(PeerData *peer, const MTPUserFull &result);
|
||||
void processFullPeer(UserData *user, const MTPUserFull &result);
|
||||
|
||||
void requestSelfParticipant(ChannelData *channel);
|
||||
void kickParticipant(PeerData *peer, UserData *user);
|
||||
void unblockParticipant(PeerData *peer, UserData *user);
|
||||
|
||||
void requestWebPageDelayed(WebPageData *page);
|
||||
void clearWebPageRequest(WebPageData *page);
|
||||
@@ -73,6 +74,7 @@ public:
|
||||
void exportInviteLink(PeerData *peer);
|
||||
void requestNotifySetting(PeerData *peer);
|
||||
|
||||
void saveDraftsToCloud();
|
||||
void saveDraftToCloudDelayed(History *history);
|
||||
bool hasUnsavedDrafts() const;
|
||||
|
||||
@@ -80,115 +82,82 @@ public:
|
||||
void handlePrivacyChange(mtpTypeId keyTypeId, const MTPVector<MTPPrivacyRule> &rules);
|
||||
int onlineTillFromStatus(const MTPUserStatus &status, int currentOnlineTill);
|
||||
|
||||
base::Observable<PeerData*> &fullPeerUpdated() {
|
||||
return _fullPeerUpdated;
|
||||
}
|
||||
|
||||
~ApiWrap();
|
||||
|
||||
signals:
|
||||
void fullPeerUpdated(PeerData *peer);
|
||||
|
||||
public slots:
|
||||
void resolveMessageDatas();
|
||||
void resolveWebPages();
|
||||
|
||||
void delayedRequestParticipantsCount();
|
||||
void saveDraftsToCloud();
|
||||
|
||||
private:
|
||||
void updatesReceived(const MTPUpdates &updates);
|
||||
|
||||
void gotMessageDatas(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req);
|
||||
struct MessageDataRequest {
|
||||
using Callbacks = QList<RequestMessageDataCallback>;
|
||||
mtpRequestId req = 0;
|
||||
mtpRequestId requestId = 0;
|
||||
Callbacks callbacks;
|
||||
};
|
||||
typedef QMap<MsgId, MessageDataRequest> MessageDataRequests;
|
||||
MessageDataRequests _messageDataRequests;
|
||||
typedef QMap<ChannelData*, MessageDataRequests> ChannelMessageDataRequests;
|
||||
ChannelMessageDataRequests _channelMessageDataRequests;
|
||||
SingleDelayedCall *_messageDataResolveDelayed;
|
||||
typedef QVector<MTPint> MessageIds;
|
||||
MessageIds collectMessageIds(const MessageDataRequests &requests);
|
||||
using MessageDataRequests = QMap<MsgId, MessageDataRequest>;
|
||||
|
||||
void updatesReceived(const MTPUpdates &updates);
|
||||
|
||||
void resolveMessageDatas();
|
||||
void gotMessageDatas(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId requestId);
|
||||
|
||||
QVector<MTPint> collectMessageIds(const MessageDataRequests &requests);
|
||||
MessageDataRequests *messageDataRequests(ChannelData *channel, bool onlyExisting = false);
|
||||
|
||||
void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req);
|
||||
void gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestId req);
|
||||
bool gotPeerFullFailed(PeerData *peer, const RPCError &err);
|
||||
typedef QMap<PeerData*, mtpRequestId> PeerRequests;
|
||||
PeerRequests _fullPeerRequests;
|
||||
void gotUserFull(UserData *user, const MTPUserFull &result, mtpRequestId req);
|
||||
void lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req);
|
||||
void resolveWebPages();
|
||||
void gotWebPages(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req);
|
||||
void gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result);
|
||||
|
||||
void gotChat(PeerData *peer, const MTPmessages_Chats &result);
|
||||
void gotUser(PeerData *peer, const MTPVector<MTPUser> &result);
|
||||
void gotChats(const MTPmessages_Chats &result);
|
||||
void gotUsers(const MTPVector<MTPUser> &result);
|
||||
bool gotPeerFailed(PeerData *peer, const RPCError &err);
|
||||
PeerData *notifySettingReceived(MTPInputNotifyPeer peer, const MTPPeerNotifySettings &settings);
|
||||
|
||||
void stickerSetDisenabled(mtpRequestId requestId);
|
||||
void stickersSaveOrder();
|
||||
|
||||
MessageDataRequests _messageDataRequests;
|
||||
QMap<ChannelData*, MessageDataRequests> _channelMessageDataRequests;
|
||||
SingleQueuedInvokation _messageDataResolveDelayed;
|
||||
|
||||
using PeerRequests = QMap<PeerData*, mtpRequestId>;
|
||||
PeerRequests _fullPeerRequests;
|
||||
PeerRequests _peerRequests;
|
||||
|
||||
void lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req);
|
||||
bool lastParticipantsFail(ChannelData *peer, const RPCError &error, mtpRequestId req);
|
||||
PeerRequests _participantsRequests, _botsRequests;
|
||||
PeerRequests _participantsRequests;
|
||||
PeerRequests _botsRequests;
|
||||
base::DelayedCallTimer _participantsCountRequestTimer;
|
||||
|
||||
typedef QPair<PeerData*, UserData*> KickRequest;
|
||||
typedef QMap<KickRequest, mtpRequestId> KickRequests;
|
||||
void kickParticipantDone(KickRequest kick, const MTPUpdates &updates, mtpRequestId req);
|
||||
bool kickParticipantFail(KickRequest kick, const RPCError &error, mtpRequestId req);
|
||||
KickRequests _kickRequests;
|
||||
|
||||
void gotSelfParticipant(ChannelData *channel, const MTPchannels_ChannelParticipant &result);
|
||||
bool gotSelfParticipantFail(ChannelData *channel, const RPCError &error);
|
||||
typedef QMap<ChannelData*, mtpRequestId> SelfParticipantRequests;
|
||||
SelfParticipantRequests _selfParticipantRequests;
|
||||
QMap<ChannelData*, mtpRequestId> _selfParticipantRequests;
|
||||
|
||||
void gotWebPages(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req);
|
||||
typedef QMap<WebPageData*, mtpRequestId> WebPagesPending;
|
||||
WebPagesPending _webPagesPending;
|
||||
SingleTimer _webPagesTimer;
|
||||
QMap<WebPageData*, mtpRequestId> _webPagesPending;
|
||||
base::Timer _webPagesTimer;
|
||||
|
||||
QMap<uint64, QPair<uint64, mtpRequestId> > _stickerSetRequests;
|
||||
void gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result);
|
||||
bool gotStickerSetFail(uint64 setId, const RPCError &error);
|
||||
|
||||
QMap<ChannelData*, mtpRequestId> _channelAmInRequests;
|
||||
void channelAmInUpdated(ChannelData *channel);
|
||||
void channelAmInDone(ChannelData *channel, const MTPUpdates &updates);
|
||||
bool channelAmInFail(ChannelData *channel, const RPCError &error);
|
||||
|
||||
QMap<UserData*, mtpRequestId> _blockRequests;
|
||||
void blockDone(UserData *user, const MTPBool &result);
|
||||
void unblockDone(UserData *user, const MTPBool &result);
|
||||
bool blockFail(UserData *user, const RPCError &error);
|
||||
|
||||
QMap<PeerData*, mtpRequestId> _exportInviteRequests;
|
||||
void exportInviteDone(PeerData *peer, const MTPExportedChatInvite &result);
|
||||
bool exportInviteFail(PeerData *peer, const RPCError &error);
|
||||
|
||||
QMap<PeerData*, mtpRequestId> _notifySettingRequests;
|
||||
void notifySettingDone(MTPInputNotifyPeer peer, const MTPPeerNotifySettings &settings);
|
||||
PeerData *notifySettingReceived(MTPInputNotifyPeer peer, const MTPPeerNotifySettings &settings);
|
||||
bool notifySettingFail(PeerData *peer, const RPCError &error);
|
||||
|
||||
QMap<History*, mtpRequestId> _draftsSaveRequestIds;
|
||||
SingleTimer _draftsSaveTimer;
|
||||
void saveCloudDraftDone(History *history, const MTPBool &result, mtpRequestId requestId);
|
||||
bool saveCloudDraftFail(History *history, const RPCError &error, mtpRequestId requestId);
|
||||
base::Timer _draftsSaveTimer;
|
||||
base::Timer _quitSavingDraftsTimer;
|
||||
|
||||
OrderedSet<mtpRequestId> _stickerSetDisenableRequests;
|
||||
void stickerSetDisenableDone(const MTPmessages_StickerSetInstallResult &result, mtpRequestId req);
|
||||
bool stickerSetDisenableFail(const RPCError &error, mtpRequestId req);
|
||||
Stickers::Order _stickersOrder;
|
||||
mtpRequestId _stickersReorderRequestId = 0;
|
||||
void stickersSaveOrder();
|
||||
void stickersReorderDone(const MTPBool &result);
|
||||
bool stickersReorderFail(const RPCError &result);
|
||||
mtpRequestId _stickersClearRecentRequestId = 0;
|
||||
void stickersClearRecentDone(const MTPBool &result);
|
||||
bool stickersClearRecentFail(const RPCError &result);
|
||||
|
||||
QMap<mtpTypeId, mtpRequestId> _privacySaveRequests;
|
||||
void savePrivacyDone(mtpTypeId keyTypeId, const MTPaccount_PrivacyRules &result);
|
||||
bool savePrivacyFail(mtpTypeId keyTypeId, const RPCError &error);
|
||||
|
||||
mtpRequestId _contactsStatusesRequestId = 0;
|
||||
void contactsStatusesDone(const MTPVector<MTPContactStatus> &result);
|
||||
bool contactsStatusesFail(const RPCError &error);
|
||||
|
||||
base::Observable<PeerData*> _fullPeerUpdated;
|
||||
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "styles/style_overview.h"
|
||||
#include "styles/style_mediaview.h"
|
||||
#include "styles/style_stickers.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_history.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "lang.h"
|
||||
@@ -191,7 +191,7 @@ namespace App {
|
||||
}
|
||||
|
||||
ApiWrap *api() {
|
||||
return main() ? main()->api() : 0;
|
||||
return AuthSession::Exists() ? &AuthSession::Current().api() : nullptr;
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -2466,7 +2466,6 @@ namespace {
|
||||
if (auto apiwrap = api()) {
|
||||
if (apiwrap->hasUnsavedDrafts()) {
|
||||
apiwrap->saveDraftsToCloud();
|
||||
QTimer::singleShot(SaveDraftBeforeQuitTimeout, QCoreApplication::instance(), SLOT(quit()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2762,12 +2761,19 @@ namespace {
|
||||
}
|
||||
|
||||
void complexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners) {
|
||||
auto overlayCorners = (radius == ImageRoundRadius::Small) ? SelectedOverlaySmallCorners : SelectedOverlayLargeCorners;
|
||||
auto overlayParts = RectPart::Full | RectPart::None;
|
||||
if (radius == ImageRoundRadius::Large) {
|
||||
complexAdjustRect(corners, rect, overlayParts);
|
||||
if (radius == ImageRoundRadius::Ellipse) {
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(p.textPalette().selectOverlay);
|
||||
p.drawEllipse(rect);
|
||||
} else {
|
||||
auto overlayCorners = (radius == ImageRoundRadius::Small) ? SelectedOverlaySmallCorners : SelectedOverlayLargeCorners;
|
||||
auto overlayParts = RectPart::Full | RectPart::None;
|
||||
if (radius == ImageRoundRadius::Large) {
|
||||
complexAdjustRect(corners, rect, overlayParts);
|
||||
}
|
||||
roundRect(p, rect, p.textPalette().selectOverlay, overlayCorners, nullptr, overlayParts);
|
||||
}
|
||||
roundRect(p, rect, p.textPalette().selectOverlay, overlayCorners, nullptr, overlayParts);
|
||||
}
|
||||
|
||||
void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners) {
|
||||
|
||||
@@ -26,8 +26,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "storage/localstorage.h"
|
||||
#include "autoupdater.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "core/task_queue.h"
|
||||
#include "messenger.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -347,10 +347,6 @@ void Application::closeApplication() {
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
}
|
||||
|
||||
void Application::onMainThreadTask() {
|
||||
base::TaskQueue::ProcessMainTasks();
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void Application::updateCheck() {
|
||||
startUpdateCheck(false);
|
||||
@@ -551,6 +547,7 @@ void adjustSingleTimers() {
|
||||
if (auto a = application()) {
|
||||
a->adjustSingleTimers();
|
||||
}
|
||||
base::Timer::Adjust();
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
@@ -51,8 +51,6 @@ public slots:
|
||||
void startApplication(); // will be done in exec()
|
||||
void closeApplication(); // will be done in aboutToQuit()
|
||||
|
||||
void onMainThreadTask();
|
||||
|
||||
private:
|
||||
typedef QPair<QLocalSocket*, QByteArray> LocalClient;
|
||||
typedef QList<LocalClient> LocalClients;
|
||||
|
||||
@@ -20,9 +20,18 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "auth_session.h"
|
||||
|
||||
#include "apiwrap.h"
|
||||
#include "messenger.h"
|
||||
#include "storage/file_download.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "platform/platform_specific.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto kAutoLockTimeoutLateMs = TimeMs(3000);
|
||||
|
||||
} // namespace
|
||||
|
||||
QByteArray AuthSessionData::serialize() const {
|
||||
auto size = sizeof(qint32) * 2;
|
||||
@@ -39,6 +48,7 @@ QByteArray AuthSessionData::serialize() const {
|
||||
stream.setVersion(QDataStream::Qt_5_1);
|
||||
stream << static_cast<qint32>(_variables.emojiPanelTab);
|
||||
stream << qint32(_variables.lastSeenWarningSeen ? 1 : 0);
|
||||
stream << qint32(_variables.tabbedSelectorSectionEnabled ? 1 : 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -57,8 +67,12 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
|
||||
stream.setVersion(QDataStream::Qt_5_1);
|
||||
qint32 emojiPanTab = static_cast<qint32>(EmojiPanelTab::Emoji);
|
||||
qint32 lastSeenWarningSeen = 0;
|
||||
qint32 tabbedSelectorSectionEnabled = 1;
|
||||
stream >> emojiPanTab;
|
||||
stream >> lastSeenWarningSeen;
|
||||
if (!stream.atEnd()) {
|
||||
stream >> tabbedSelectorSectionEnabled;
|
||||
}
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("App Error: Bad data for AuthSessionData::constructFromSerialized()"));
|
||||
return;
|
||||
@@ -71,17 +85,30 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
|
||||
case EmojiPanelTab::Gifs: _variables.emojiPanelTab = uncheckedTab; break;
|
||||
}
|
||||
_variables.lastSeenWarningSeen = (lastSeenWarningSeen == 1);
|
||||
_variables.tabbedSelectorSectionEnabled = (tabbedSelectorSectionEnabled == 1);
|
||||
}
|
||||
|
||||
AuthSession::AuthSession(UserId userId)
|
||||
: _userId(userId)
|
||||
, _autoLockTimer([this] { checkAutoLock(); })
|
||||
, _api(std::make_unique<ApiWrap>())
|
||||
, _downloader(std::make_unique<Storage::Downloader>())
|
||||
, _notifications(std::make_unique<Window::Notifications::System>(this)) {
|
||||
Expects(_userId != 0);
|
||||
_saveDataTimer.setCallback([this] {
|
||||
Local::writeUserSettings();
|
||||
});
|
||||
subscribe(Messenger::Instance().passcodedChanged(), [this] {
|
||||
_shouldLockAt = 0;
|
||||
notifications().updateAll();
|
||||
});
|
||||
}
|
||||
|
||||
bool AuthSession::Exists() {
|
||||
return (Messenger::Instance().authSession() != nullptr);
|
||||
if (auto messenger = Messenger::InstancePointer()) {
|
||||
return (messenger->authSession() != nullptr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
AuthSession &AuthSession::Current() {
|
||||
@@ -107,4 +134,34 @@ bool AuthSession::validateSelf(const MTPUser &user) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void AuthSession::saveDataDelayed(TimeMs delay) {
|
||||
Expects(this == &AuthSession::Current());
|
||||
_saveDataTimer.callOnce(delay);
|
||||
}
|
||||
|
||||
void AuthSession::checkAutoLock() {
|
||||
if (!Global::LocalPasscode() || App::passcoded()) return;
|
||||
|
||||
Messenger::Instance().checkLocalTime();
|
||||
auto now = getms(true);
|
||||
auto shouldLockInMs = Global::AutoLock() * 1000LL;
|
||||
auto idleForMs = psIdleTime();
|
||||
auto notPlayingVideoForMs = now - data().lastTimeVideoPlayedAt();
|
||||
auto checkTimeMs = qMin(idleForMs, notPlayingVideoForMs);
|
||||
if (checkTimeMs >= shouldLockInMs || (_shouldLockAt > 0 && now > _shouldLockAt + kAutoLockTimeoutLateMs)) {
|
||||
Messenger::Instance().setupPasscode();
|
||||
} else {
|
||||
_shouldLockAt = now + (shouldLockInMs - checkTimeMs);
|
||||
_autoLockTimer.callOnce(shouldLockInMs - checkTimeMs);
|
||||
}
|
||||
}
|
||||
|
||||
void AuthSession::checkAutoLockIn(TimeMs time) {
|
||||
if (_autoLockTimer.isActive()) {
|
||||
auto remain = _autoLockTimer.remainingTime();
|
||||
if (remain > 0 && remain <= time) return;
|
||||
}
|
||||
_autoLockTimer.callOnce(time);
|
||||
}
|
||||
|
||||
AuthSession::~AuthSession() = default;
|
||||
|
||||
@@ -20,6 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/timer.h"
|
||||
|
||||
namespace Storage {
|
||||
class Downloader;
|
||||
} // namespace Storage
|
||||
@@ -30,6 +32,8 @@ class System;
|
||||
} // namespace Notifications
|
||||
} // namespace Window
|
||||
|
||||
class ApiWrap;
|
||||
|
||||
enum class EmojiPanelTab {
|
||||
Emoji,
|
||||
Stickers,
|
||||
@@ -69,11 +73,24 @@ public:
|
||||
void setEmojiPanelTab(EmojiPanelTab tab) {
|
||||
_variables.emojiPanelTab = tab;
|
||||
}
|
||||
bool tabbedSelectorSectionEnabled() const {
|
||||
return _variables.tabbedSelectorSectionEnabled;
|
||||
}
|
||||
void setTabbedSelectorSectionEnabled(bool enabled) {
|
||||
_variables.tabbedSelectorSectionEnabled = enabled;
|
||||
}
|
||||
void setLastTimeVideoPlayedAt(TimeMs time) {
|
||||
_lastTimeVideoPlayedAt = time;
|
||||
}
|
||||
TimeMs lastTimeVideoPlayedAt() const {
|
||||
return _lastTimeVideoPlayedAt;
|
||||
}
|
||||
|
||||
private:
|
||||
struct Variables {
|
||||
bool lastSeenWarningSeen = false;
|
||||
EmojiPanelTab emojiPanelTab = EmojiPanelTab::Emoji;
|
||||
bool tabbedSelectorSectionEnabled = true;
|
||||
};
|
||||
|
||||
base::Variable<bool> _contactsLoaded = { false };
|
||||
@@ -81,10 +98,11 @@ private:
|
||||
base::Observable<void> _moreChatsLoaded;
|
||||
base::Observable<void> _savedGifsUpdated;
|
||||
Variables _variables;
|
||||
TimeMs _lastTimeVideoPlayedAt = 0;
|
||||
|
||||
};
|
||||
|
||||
class AuthSession final {
|
||||
class AuthSession final : private base::Subscriber {
|
||||
public:
|
||||
AuthSession(UserId userId);
|
||||
|
||||
@@ -120,13 +138,26 @@ public:
|
||||
AuthSessionData &data() {
|
||||
return _data;
|
||||
}
|
||||
void saveDataDelayed(TimeMs delay);
|
||||
|
||||
ApiWrap &api() {
|
||||
return *_api;
|
||||
}
|
||||
|
||||
void checkAutoLock();
|
||||
void checkAutoLockIn(TimeMs time);
|
||||
|
||||
~AuthSession();
|
||||
|
||||
private:
|
||||
UserId _userId = 0;
|
||||
const UserId _userId = 0;
|
||||
AuthSessionData _data;
|
||||
base::Timer _saveDataTimer;
|
||||
|
||||
TimeMs _shouldLockAt = 0;
|
||||
base::Timer _autoLockTimer;
|
||||
|
||||
const std::unique_ptr<ApiWrap> _api;
|
||||
const std::unique_ptr<Storage::Downloader> _downloader;
|
||||
const std::unique_ptr<Window::Notifications::System> _notifications;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#elif defined(_WIN32) // __APPLE__ || __linux__
|
||||
#define OS_WIN 1
|
||||
#else // __APPLE__ || __linux__ || _WIN32
|
||||
#error Please add support for your platform in core/build_config.h
|
||||
#error Please add support for your platform in base/build_config.h
|
||||
#endif // else for __APPLE__ || __linux__ || _WIN32
|
||||
|
||||
// For access to standard POSIXish features, use OS_POSIX instead of a
|
||||
@@ -48,7 +48,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#elif defined(_MSC_VER) // __clang__ || __GNUC__
|
||||
#define COMPILER_MSVC 1
|
||||
#else // _MSC_VER || __clang__ || __GNUC__
|
||||
#error Please add support for your compiler in core/build_config.h
|
||||
#error Please add support for your compiler in base/build_config.h
|
||||
#endif // else for _MSC_VER || __clang__ || __GNUC__
|
||||
|
||||
// Processor architecture detection.
|
||||
@@ -61,7 +61,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#define ARCH_CPU_X86 1
|
||||
#define ARCH_CPU_32_BITS 1
|
||||
#else
|
||||
#error Please add support for your architecture in core/build_config.h
|
||||
#error Please add support for your architecture in base/build_config.h
|
||||
#endif
|
||||
|
||||
#if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
||||
@@ -18,7 +18,7 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "core/observer.h"
|
||||
#include "base/observer.h"
|
||||
|
||||
namespace base {
|
||||
namespace internal {
|
||||
@@ -22,7 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include "core/type_traits.h"
|
||||
#include "base/type_traits.h"
|
||||
|
||||
namespace base {
|
||||
namespace internal {
|
||||
@@ -18,7 +18,7 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "core/parse_helper.h"
|
||||
#include "base/parse_helper.h"
|
||||
|
||||
namespace base {
|
||||
namespace parse {
|
||||
@@ -18,7 +18,7 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "core/qthelp_url.h"
|
||||
#include "base/qthelp_url.h"
|
||||
|
||||
namespace qthelp {
|
||||
|
||||
@@ -18,7 +18,7 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "core/runtime_composer.h"
|
||||
#include "base/runtime_composer.h"
|
||||
|
||||
struct RuntimeComposerMetadatasMap {
|
||||
QMap<uint64, RuntimeComposerMetadata*> data;
|
||||
@@ -18,7 +18,7 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "core/task_queue.h"
|
||||
#include "base/task_queue.h"
|
||||
|
||||
#include <thread>
|
||||
#include <condition_variable>
|
||||
141
Telegram/SourceFiles/base/timer.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "base/timer.h"
|
||||
|
||||
namespace base {
|
||||
namespace {
|
||||
|
||||
QObject *TimersAdjuster() {
|
||||
static QObject adjuster;
|
||||
return &adjuster;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Timer::Timer(base::lambda<void()> callback) : QObject(nullptr)
|
||||
, _callback(std::move(callback))
|
||||
, _type(Qt::PreciseTimer)
|
||||
, _adjusted(false) {
|
||||
setRepeat(Repeat::Interval);
|
||||
connect(TimersAdjuster(), &QObject::destroyed, this, [this] { adjust(); }, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void Timer::start(TimeMs timeout, Qt::TimerType type, Repeat repeat) {
|
||||
cancel();
|
||||
|
||||
_type = type;
|
||||
setRepeat(repeat);
|
||||
_adjusted = false;
|
||||
setTimeout(timeout);
|
||||
_timerId = startTimer(_timeout, _type);
|
||||
if (_timerId) {
|
||||
_next = getms(true) + _timeout;
|
||||
} else {
|
||||
_next = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Timer::cancel() {
|
||||
if (isActive()) {
|
||||
killTimer(base::take(_timerId));
|
||||
}
|
||||
}
|
||||
|
||||
TimeMs Timer::remainingTime() const {
|
||||
if (!isActive()) {
|
||||
return -1;
|
||||
}
|
||||
auto now = getms(true);
|
||||
return (_next > now) ? (_next - now) : TimeMs(0);
|
||||
}
|
||||
|
||||
void Timer::Adjust() {
|
||||
QObject emitter;
|
||||
connect(&emitter, &QObject::destroyed, TimersAdjuster(), &QObject::destroyed);
|
||||
}
|
||||
|
||||
void Timer::adjust() {
|
||||
auto remaining = remainingTime();
|
||||
if (remaining >= 0) {
|
||||
cancel();
|
||||
_timerId = startTimer(remaining, _type);
|
||||
_adjusted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Timer::setTimeout(TimeMs timeout) {
|
||||
Expects(timeout >= 0 && timeout <= std::numeric_limits<int>::max());
|
||||
_timeout = static_cast<unsigned int>(timeout);
|
||||
}
|
||||
|
||||
int Timer::timeout() const {
|
||||
return _timeout;
|
||||
}
|
||||
|
||||
void Timer::timerEvent(QTimerEvent *e) {
|
||||
if (repeat() == Repeat::Interval) {
|
||||
if (_adjusted) {
|
||||
start(_timeout, _type, repeat());
|
||||
} else {
|
||||
_next = getms(true) + _timeout;
|
||||
}
|
||||
} else {
|
||||
cancel();
|
||||
}
|
||||
|
||||
if (_callback) {
|
||||
_callback();
|
||||
}
|
||||
}
|
||||
|
||||
int DelayedCallTimer::call(TimeMs timeout, lambda_once<void()> callback, Qt::TimerType type) {
|
||||
Expects(timeout >= 0);
|
||||
if (!callback) {
|
||||
return 0;
|
||||
}
|
||||
auto timerId = startTimer(static_cast<int>(timeout), type);
|
||||
if (timerId) {
|
||||
_callbacks.emplace(timerId, std::move(callback));
|
||||
}
|
||||
return timerId;
|
||||
}
|
||||
|
||||
void DelayedCallTimer::cancel(int callId) {
|
||||
if (callId) {
|
||||
killTimer(callId);
|
||||
_callbacks.erase(callId);
|
||||
}
|
||||
}
|
||||
|
||||
void DelayedCallTimer::timerEvent(QTimerEvent *e) {
|
||||
auto timerId = e->timerId();
|
||||
killTimer(timerId);
|
||||
|
||||
auto it = _callbacks.find(timerId);
|
||||
if (it != _callbacks.end()) {
|
||||
auto callback = std::move(it->second);
|
||||
_callbacks.erase(it);
|
||||
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
115
Telegram/SourceFiles/base/timer.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/lambda.h"
|
||||
#include "base/observer.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
class Timer final : private QObject {
|
||||
public:
|
||||
Timer(base::lambda<void()> callback = base::lambda<void()>());
|
||||
|
||||
static Qt::TimerType DefaultType(TimeMs timeout) {
|
||||
constexpr auto kThreshold = TimeMs(1000);
|
||||
return (timeout > kThreshold) ? Qt::CoarseTimer : Qt::PreciseTimer;
|
||||
}
|
||||
|
||||
void setCallback(base::lambda<void()> callback) {
|
||||
_callback = std::move(callback);
|
||||
}
|
||||
|
||||
void callOnce(TimeMs timeout) {
|
||||
callOnce(timeout, DefaultType(timeout));
|
||||
}
|
||||
|
||||
void callEach(TimeMs timeout) {
|
||||
callEach(timeout, DefaultType(timeout));
|
||||
}
|
||||
|
||||
void callOnce(TimeMs timeout, Qt::TimerType type) {
|
||||
start(timeout, type, Repeat::SingleShot);
|
||||
}
|
||||
|
||||
void callEach(TimeMs timeout, Qt::TimerType type) {
|
||||
start(timeout, type, Repeat::Interval);
|
||||
}
|
||||
|
||||
bool isActive() const {
|
||||
return (_timerId != 0);
|
||||
}
|
||||
|
||||
void cancel();
|
||||
TimeMs remainingTime() const;
|
||||
|
||||
static void Adjust();
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *e) override;
|
||||
|
||||
private:
|
||||
enum class Repeat : unsigned {
|
||||
Interval = 0,
|
||||
SingleShot = 1,
|
||||
};
|
||||
void start(TimeMs timeout, Qt::TimerType type, Repeat repeat);
|
||||
void adjust();
|
||||
|
||||
void setTimeout(TimeMs timeout);
|
||||
int timeout() const;
|
||||
|
||||
void setRepeat(Repeat repeat) {
|
||||
_repeat = static_cast<unsigned>(repeat);
|
||||
}
|
||||
Repeat repeat() const {
|
||||
return static_cast<Repeat>(_repeat);
|
||||
}
|
||||
|
||||
base::lambda<void()> _callback;
|
||||
TimeMs _next = 0;
|
||||
int _timeout = 0;
|
||||
int _timerId = 0;
|
||||
|
||||
Qt::TimerType _type : 2;
|
||||
bool _adjusted : 1;
|
||||
unsigned _repeat : 1;
|
||||
|
||||
};
|
||||
|
||||
class DelayedCallTimer final : private QObject {
|
||||
public:
|
||||
int call(TimeMs timeout, lambda_once<void()> callback) {
|
||||
return call(timeout, std::move(callback), Timer::DefaultType(timeout));
|
||||
}
|
||||
|
||||
int call(TimeMs timeout, lambda_once<void()> callback, Qt::TimerType type);
|
||||
void cancel(int callId);
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *e) override;
|
||||
|
||||
private:
|
||||
std::map<int, lambda_once<void()>> _callbacks; // Better to use flatmap.
|
||||
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
@@ -18,13 +18,13 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "boxes/aboutbox.h"
|
||||
#include "boxes/about_box.h"
|
||||
|
||||
#include "lang.h"
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "autoupdater.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "application.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
@@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "boxes/abstractbox.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
|
||||
namespace Ui {
|
||||
class LinkButton;
|
||||
@@ -18,7 +18,7 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "boxes/abstractbox.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
|
||||
#include "styles/style_boxes.h"
|
||||
#include "storage/localstorage.h"
|
||||
@@ -194,7 +194,8 @@ void BoxContent::paintEvent(QPaintEvent *e) {
|
||||
}
|
||||
}
|
||||
|
||||
AbstractBox::AbstractBox(QWidget *parent, object_ptr<BoxContent> content) : LayerWidget(parent)
|
||||
AbstractBox::AbstractBox(QWidget *parent, Window::Controller *controller, object_ptr<BoxContent> content) : LayerWidget(parent)
|
||||
, _controller(controller)
|
||||
, _content(std::move(content)) {
|
||||
_content->setParent(this);
|
||||
_content->setDelegate(this);
|
||||
@@ -31,6 +31,10 @@ template <typename Widget>
|
||||
class WidgetFadeWrap;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Window {
|
||||
class Controller;
|
||||
} // namespace Window
|
||||
|
||||
class BoxLayerTitleShadow : public Ui::PlainShadow {
|
||||
public:
|
||||
BoxLayerTitleShadow(QWidget *parent);
|
||||
@@ -39,6 +43,8 @@ public:
|
||||
|
||||
class BoxContentDelegate {
|
||||
public:
|
||||
virtual Window::Controller *controller() const = 0;
|
||||
|
||||
virtual void setLayerType(bool layerType) = 0;
|
||||
virtual void setTitle(const QString &title, const QString &additional) = 0;
|
||||
|
||||
@@ -61,8 +67,6 @@ public:
|
||||
BoxContent() {
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
}
|
||||
BoxContent(QWidget*) : BoxContent() {
|
||||
}
|
||||
|
||||
bool isBoxShown() const {
|
||||
return getDelegate()->isBoxShown();
|
||||
@@ -107,6 +111,10 @@ public slots:
|
||||
protected:
|
||||
virtual void prepare() = 0;
|
||||
|
||||
Window::Controller *controller() {
|
||||
return getDelegate()->controller();
|
||||
}
|
||||
|
||||
void setLayerType(bool layerType) {
|
||||
getDelegate()->setLayerType(layerType);
|
||||
}
|
||||
@@ -165,7 +173,7 @@ private:
|
||||
object_ptr<TWidget> doTakeInnerWidget();
|
||||
|
||||
BoxContentDelegate *getDelegate() const {
|
||||
t_assert(_delegate != nullptr);
|
||||
Expects(_delegate != nullptr);
|
||||
return _delegate;
|
||||
}
|
||||
BoxContentDelegate *_delegate = nullptr;
|
||||
@@ -183,8 +191,11 @@ private:
|
||||
|
||||
class AbstractBox : public LayerWidget, public BoxContentDelegate, protected base::Subscriber {
|
||||
public:
|
||||
AbstractBox(QWidget *parent, object_ptr<BoxContent> content);
|
||||
AbstractBox(QWidget *parent, Window::Controller *controller, object_ptr<BoxContent> content);
|
||||
|
||||
Window::Controller *controller() const override {
|
||||
return _controller;
|
||||
}
|
||||
void parentResized() override;
|
||||
|
||||
void setLayerType(bool layerType) override;
|
||||
@@ -235,6 +246,7 @@ private:
|
||||
int countRealHeight() const;
|
||||
void updateSize();
|
||||
|
||||
Window::Controller *_controller = nullptr;
|
||||
int _fullHeight = 0;
|
||||
|
||||
bool _noContentMargin = false;
|
||||
@@ -18,15 +18,15 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "boxes/addcontactbox.h"
|
||||
#include "boxes/add_contact_box.h"
|
||||
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "lang.h"
|
||||
#include "messenger.h"
|
||||
#include "boxes/contactsbox.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "boxes/photocropbox.h"
|
||||
#include "boxes/contacts_box.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "boxes/photo_crop_box.h"
|
||||
#include "core/file_utilities.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
@@ -1060,7 +1060,7 @@ bool EditChannelBox::onSaveFail(const RPCError &error, mtpRequestId req) {
|
||||
if (err == qstr("CHAT_ABOUT_NOT_MODIFIED")) {
|
||||
if (_channel->setAbout(_sentDescription)) {
|
||||
if (App::api()) {
|
||||
emit App::api()->fullPeerUpdated(_channel);
|
||||
App::api()->fullPeerUpdated().notify(_channel);
|
||||
}
|
||||
}
|
||||
saveSign();
|
||||
@@ -1090,7 +1090,7 @@ void EditChannelBox::onSaveDescriptionDone(const MTPBool &result) {
|
||||
_saveDescriptionRequestId = 0;
|
||||
if (_channel->setAbout(_sentDescription)) {
|
||||
if (App::api()) {
|
||||
emit App::api()->fullPeerUpdated(_channel);
|
||||
App::api()->fullPeerUpdated().notify(_channel);
|
||||
}
|
||||
}
|
||||
saveSign();
|
||||
@@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "boxes/abstractbox.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
|
||||
class ConfirmBox;
|
||||
|
||||
@@ -18,7 +18,7 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "boxes/autolockbox.h"
|
||||
#include "boxes/autolock_box.h"
|
||||
|
||||
#include "lang.h"
|
||||
#include "storage/localstorage.h"
|
||||
@@ -52,6 +52,6 @@ void AutoLockBox::durationChanged(int seconds) {
|
||||
Local::writeUserSettings();
|
||||
Global::RefLocalPasscodeChanged().notify();
|
||||
|
||||
App::wnd()->checkAutoLock();
|
||||
AuthSession::Current().checkAutoLock();
|
||||
closeBox();
|
||||
}
|
||||
@@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "boxes/abstractbox.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
|
||||
namespace Ui {
|
||||
class Radiobutton;
|
||||
@@ -18,7 +18,7 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "boxes/backgroundbox.h"
|
||||
#include "boxes/background_box.h"
|
||||
|
||||
#include "lang.h"
|
||||
#include "mainwidget.h"
|
||||
@@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "boxes/abstractbox.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
|
||||
namespace Ui {
|
||||
class RoundCheckbox;
|
||||
@@ -270,6 +270,7 @@ contactsSearchCancel: CrossButton {
|
||||
crossPosition: point(4px, 4px);
|
||||
|
||||
duration: 150;
|
||||
loadingPeriod: 1000;
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: windowBgOver;
|
||||
}
|
||||
@@ -483,11 +484,6 @@ autoDownloadTopDelta: 10px;
|
||||
autoDownloadTitlePosition: point(23px, 18px);
|
||||
autoDownloadTitleFont: font(15px semibold);
|
||||
|
||||
editTextArea: InputField(defaultInputField) {
|
||||
textMargins: margins(1px, 26px, 1px, 4px);
|
||||
heightMax: 276px;
|
||||
}
|
||||
|
||||
confirmCaptionArea: InputField(defaultInputField) {
|
||||
textMargins: margins(1px, 26px, 1px, 4px);
|
||||
heightMax: 78px;
|
||||
|
||||
@@ -18,7 +18,7 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "boxes/calendarbox.h"
|
||||
#include "boxes/calendar_box.h"
|
||||
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "styles/style_boxes.h"
|
||||
@@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "abstractbox.h"
|
||||
#include "abstract_box.h"
|
||||
|
||||
namespace Ui {
|
||||
class IconButton;
|
||||
@@ -25,9 +25,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/effects/widget_fade_wrap.h"
|
||||
#include "boxes/confirmphonebox.h"
|
||||
#include "boxes/confirm_phone_box.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "boxes/abstractbox.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
|
||||
class ChangePhoneBox : public BoxContent {
|
||||
public:
|
||||
|
||||
@@ -18,7 +18,7 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
|
||||
#include "styles/style_boxes.h"
|
||||
#include "lang.h"
|
||||
@@ -312,25 +312,21 @@ void ConvertToSupergroupBox::convertToSupergroup() {
|
||||
void ConvertToSupergroupBox::convertDone(const MTPUpdates &updates) {
|
||||
Ui::hideLayer();
|
||||
App::main()->sentUpdatesReceived(updates);
|
||||
const QVector<MTPChat> *v = 0;
|
||||
switch (updates.type()) {
|
||||
case mtpc_updates: v = &updates.c_updates().vchats.v; break;
|
||||
case mtpc_updatesCombined: v = &updates.c_updatesCombined().vchats.v; break;
|
||||
default: LOG(("API Error: unexpected update cons %1 (ConvertToSupergroupBox::convertDone)").arg(updates.type())); break;
|
||||
}
|
||||
|
||||
PeerData *peer = 0;
|
||||
if (v && !v->isEmpty()) {
|
||||
for (int32 i = 0, l = v->size(); i < l; ++i) {
|
||||
if (v->at(i).type() == mtpc_channel) {
|
||||
peer = App::channel(v->at(i).c_channel().vid.v);
|
||||
Ui::showPeerHistory(peer, ShowAtUnreadMsgId);
|
||||
QTimer::singleShot(ReloadChannelMembersTimeout, App::api(), SLOT(delayedRequestParticipantsCount()));
|
||||
auto handleChats = [](auto &mtpChats) {
|
||||
for_const (auto &mtpChat, mtpChats.v) {
|
||||
if (mtpChat.type() == mtpc_channel) {
|
||||
auto channel = App::channel(mtpChat.c_channel().vid.v);
|
||||
Ui::showPeerHistory(channel, ShowAtUnreadMsgId);
|
||||
App::api()->requestParticipantsCountDelayed(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!peer) {
|
||||
LOG(("API Error: channel not found in updates (ProfileInner::migrateDone)"));
|
||||
};
|
||||
|
||||
switch (updates.type()) {
|
||||
case mtpc_updates: handleChats(updates.c_updates().vchats); break;
|
||||
case mtpc_updatesCombined: handleChats(updates.c_updatesCombined().vchats); break;
|
||||
default: LOG(("API Error: unexpected update cons %1 (ConvertToSupergroupBox::convertDone)").arg(updates.type())); break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "boxes/abstractbox.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
|
||||
namespace Ui {
|
||||
class Checkbox;
|
||||
@@ -18,10 +18,10 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "boxes/confirmphonebox.h"
|
||||
#include "boxes/confirm_phone_box.h"
|
||||
|
||||
#include "styles/style_boxes.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
@@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "boxes/abstractbox.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
|
||||
namespace Ui {
|
||||
@@ -18,7 +18,7 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "boxes/connectionbox.h"
|
||||
#include "boxes/connection_box.h"
|
||||
|
||||
#include "lang.h"
|
||||
#include "storage/localstorage.h"
|
||||
@@ -269,10 +269,9 @@ void AutoDownloadBox::onSave() {
|
||||
bool enabledGroups = ((cAutoDownloadAudio() & dbiadNoGroups) && !(autoDownloadAudio & dbiadNoGroups));
|
||||
cSetAutoDownloadAudio(autoDownloadAudio);
|
||||
if (enabledPrivate || enabledGroups) {
|
||||
const DocumentsData &data(App::documentsData());
|
||||
for (DocumentsData::const_iterator i = data.cbegin(), e = data.cend(); i != e; ++i) {
|
||||
if (i.value()->voice()) {
|
||||
i.value()->automaticLoadSettingsChanged();
|
||||
for (auto document : App::documentsData()) {
|
||||
if (document->voice()) {
|
||||
document->automaticLoadSettingsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -284,10 +283,9 @@ void AutoDownloadBox::onSave() {
|
||||
bool enabledGroups = ((cAutoDownloadGif() & dbiadNoGroups) && !(autoDownloadGif & dbiadNoGroups));
|
||||
cSetAutoDownloadGif(autoDownloadGif);
|
||||
if (enabledPrivate || enabledGroups) {
|
||||
const DocumentsData &data(App::documentsData());
|
||||
for (DocumentsData::const_iterator i = data.cbegin(), e = data.cend(); i != e; ++i) {
|
||||
if (i.value()->isAnimation()) {
|
||||
i.value()->automaticLoadSettingsChanged();
|
||||
for (auto document : App::documentsData()) {
|
||||
if (document->isAnimation()) {
|
||||
document->automaticLoadSettingsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "boxes/abstractbox.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
|
||||
namespace Ui {
|
||||
class InputField;
|
||||
@@ -18,7 +18,7 @@ to link the code of portions of this program with the OpenSSL library.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "boxes/contactsbox.h"
|
||||
#include "boxes/contacts_box.h"
|
||||
|
||||
#include "dialogs/dialogs_indexed_list.h"
|
||||
#include "styles/style_boxes.h"
|
||||
@@ -26,7 +26,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "styles/style_history.h"
|
||||
#include "styles/style_profile.h"
|
||||
#include "lang.h"
|
||||
#include "boxes/addcontactbox.h"
|
||||
#include "boxes/add_contact_box.h"
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "messenger.h"
|
||||
@@ -37,8 +37,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/effects/widget_slide_wrap.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "boxes/photocropbox.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "boxes/photo_crop_box.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "observer_peer.h"
|
||||
#include "apiwrap.h"
|
||||