diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 42a39d90b..5af5973a0 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -4,9 +4,9 @@ Thanks for reporting issues of Telegram Desktop! To make it easier for us to help you please enter detailed information below. --> ### Steps to reproduce -1. -2. -3. +1. +2. +3. ### Expected behaviour Tell us what should happen @@ -22,5 +22,5 @@ Tell us what happens instead ### Logs Insert logs here (if necessary) -You can type "debugmode" in settings and then see ~/.TelegramDesktop/DebugLogs/log_...txt for log files. -Type "debugmode" in settings again to disable logs. +You can type `debugmode` in settings and then see ~/.TelegramDesktop/DebugLogs/log_...txt for log files. +Type `debugmode` in settings again to disable logs. diff --git a/.travis.yml b/.travis.yml index 0b1724aa0..1f5333843 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ env: - BUILD_VERSION="disable_register_custom_scheme" - BUILD_VERSION="disable_crash_reports" - BUILD_VERSION="disable_network_proxy" + - BUILD_VERSION="disable_desktop_file_generation" arch: packages: diff --git a/.travis/build.sh b/.travis/build.sh index 8ecdfaa96..b31262833 100755 --- a/.travis/build.sh +++ b/.travis/build.sh @@ -79,6 +79,10 @@ prepare() { options+="\nDEFINES += TDESKTOP_DISABLE_NETWORK_PROXY" fi + if [[ $BUILD_VERSION == *"disable_desktop_file_generation"* ]]; then + options+="\nDEFINES += TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION" + fi + options+='\nINCLUDEPATH += "/usr/lib/glib-2.0/include"' options+='\nINCLUDEPATH += "/usr/lib/gtk-2.0/include"' options+='\nINCLUDEPATH += "/usr/include/opus"' diff --git a/Telegram/Patches/qtbase_5_6_0.diff b/Telegram/Patches/qtbase_5_6_0.diff index 7600ec504..dd4c477bf 100644 --- a/Telegram/Patches/qtbase_5_6_0.diff +++ b/Telegram/Patches/qtbase_5_6_0.diff @@ -400,6 +400,23 @@ index a4b5280..e2dffcb 100644 } else { LIBS += $$QMAKE_LIBS_XKBCOMMON QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XKBCOMMON +diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp +index d1bea9a..f1f808d 100644 +--- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp ++++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp +@@ -232,6 +232,12 @@ bool QComposeInputContext::checkComposeTable() + + void QComposeInputContext::commitText(uint character) const + { ++ // Crash fix when not focused widget still receives input events. ++ if (!m_focusObject) { ++ qWarning("QComposeInputContext::commitText: m_focusObject == nullptr, cannot commit text"); ++ return; ++ } ++ + QInputMethodEvent event; + event.setCommitString(QChar(character)); + QCoreApplication::sendEvent(m_focusObject, &event); diff --git a/src/plugins/platforminputcontexts/fcitx/fcitx.json b/src/plugins/platforminputcontexts/fcitx/fcitx.json new file mode 100644 index 0000000..6d2b389 @@ -11748,6 +11765,21 @@ index 9211fd1..283aabd 100644 void QWindowsXpFileDialogHelper::selectNameFilter(const QString &f) { m_data.setSelectedNameFilter(f); // Dialog cannot be updated at run-time. +diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp +index c5dff60..ce6c715 100644 +--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp ++++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp +@@ -1249,6 +1249,10 @@ QList QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const + { + QList result; + ++ // This must not happen, but there are crash reports on the next line. ++ if (e->nativeVirtualKey() > 0xFF) ++ return result; ++ + const KeyboardLayoutItem &kbItem = keyLayout[e->nativeVirtualKey()]; + if (!kbItem.exists) + return result; diff --git a/src/plugins/platforms/windows/qwindowsservices.cpp b/src/plugins/platforms/windows/qwindowsservices.cpp index cc697ba..c72234f 100644 --- a/src/plugins/platforms/windows/qwindowsservices.cpp diff --git a/Telegram/Resources/basic.style b/Telegram/Resources/basic.style index 27f407c81..36cd767e9 100644 --- a/Telegram/Resources/basic.style +++ b/Telegram/Resources/basic.style @@ -617,7 +617,7 @@ inpDefGray: flatInput(inpDefFlat) { bgColor: #f2f2f2; borderWidth: 2px; borderColor: #f2f2f2; - borderActive: #80cff9; + borderActive: #54c3f3; borderError: #ed8080; phColor: #808080; } @@ -662,6 +662,9 @@ scrollDef: flatScroll { duration: 150; hiding: 1000; } + +msgRadius: 3px; + scrollCountries: flatScroll(scrollDef) { topsh: 0px; bottomsh: -2px; @@ -729,6 +732,7 @@ btnIntroNext: flatButton(btnDefNext, btnDefBig) { overFont: font(17px); width: 300px; + radius: msgRadius; } boxShadow: sprite(363px, 50px, 15px, 15px); @@ -929,11 +933,6 @@ searchFlatInput: flatInput(inpDefGray) { phColor: #949494; phFocusColor: #a4a4a4; imgRect: sprite(227px, 21px, 24px, 24px); - - borderWidth: 2px; - borderColor: #f2f2f2; - borderActive: #80cff9; - borderError: #ed8080; } noContactsHeight: 100px; @@ -1036,8 +1035,6 @@ topBarActionSkip: 10px; activeFadeInDuration: 500; activeFadeOutDuration: 3000; -msgRadius: 3px; - msgMaxWidth: 430px; msgFont: font(fsize); msgNameFont: semiboldFont; diff --git a/Telegram/Resources/basic_types.style b/Telegram/Resources/basic_types.style index a5921d350..ca5392b13 100644 --- a/Telegram/Resources/basic_types.style +++ b/Telegram/Resources/basic_types.style @@ -66,6 +66,8 @@ flatButton { overFont: font; duration: int; cursor: cursor; + + radius: pixels; } iconedButton { diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index b834c91cc..9f87cedca 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -921,7 +921,7 @@ Copyright (c) 2014-2016 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" = "— Introducing Drafts: Seamless syncing for unsent messages on all your devices. Drafts are now visible in your chats list.\n— Completely redesigned group and user profiles.\n— Unread messages counter on the 'Scroll to bottom' button.\n\nMore about this update: {link}"; +"lng_new_version_text" = "— Fixed photo viewer to handle screen resolution change correctly\n— Fixed forwarding photos via drag-n-drop\n— Various design improvements and other bug fixes"; "lng_menu_insert_unicode" = "Insert Unicode control character"; diff --git a/Telegram/Resources/langs/lang_de.strings b/Telegram/Resources/langs/lang_de.strings index 28be399f0..5a27b31c2 100644 --- a/Telegram/Resources/langs/lang_de.strings +++ b/Telegram/Resources/langs/lang_de.strings @@ -697,7 +697,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_in_dlg_audio" = "Sprachnachricht"; "lng_in_dlg_file" = "Datei"; "lng_in_dlg_sticker" = "Sticker"; -"lng_in_dlg_sticker_emoji" = "{emoji} (Sticker)"; +"lng_in_dlg_sticker_emoji" = "{emoji} Sticker"; "lng_ban_user" = "Nutzer sperren"; "lng_delete_all_from" = "Alles von diesem Nutzer löschen"; @@ -726,7 +726,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_wont_be_notified" = "Mitglieder werden nicht benachrichtigt"; "lng_empty_history" = ""; "lng_willbe_history" = "Chat auswählen, um zu schreiben"; -"lng_message_with_from" = "[c]{from}:[/c] {message}"; "lng_from_you" = "Ich"; "lng_from_draft" = "Entwurf"; "lng_bot_description" = "Was kann dieser Bot?"; @@ -735,6 +734,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_channel_mute" = "Stumm"; "lng_channel_unmute" = "Stumm aus"; +"lng_dialogs_text_with_from" = "{from_part} {message}"; +"lng_dialogs_text_from_wrapped" = "{from}:"; +"lng_dialogs_text_media" = "{media_part} {caption}"; +"lng_dialogs_text_media_wrapped" = "{media},"; + "lng_open_this_link" = "Diesen Link öffnen?"; "lng_open_link" = "Öffnen"; @@ -880,6 +884,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_selected_upload_stop" = "Abbrechen"; "lng_selected_delete_sure_this" = "Diese Nachricht wirklich löschen?"; "lng_selected_delete_sure" = "Willst du {count:_not_used_|# Nachricht|# Nachrichten} löschen?"; +"lng_delete_photo_sure" = "Dieses Bild wirklich löschen?"; "lng_box_delete" = "Löschen"; "lng_box_leave" = "Verlassen"; @@ -916,7 +921,7 @@ Copyright (c) 2014-2016 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" = "— Entwürfe: Ungesendete Nachrichten werden als Entwurf auf all deinen Geräten synchronisiert und sind in der Chatliste erkennbar.\n— Gruppen- und Nutzerprofile wurden neu gestaltet.\n— Anzahl ungelesener Nachrichten auf dem 'Nach unten wechseln'-Knopf.\n\nMehr Infos: {link}"; +"lng_new_version_text" = "— Fehlerbehebung: Bildbetrachter sollte Änderungen der Bildschirmauflösung korrekt handhaben\n— Fehlerbehebung: Bilder per Drag’n’Drop weiterleiten\n— Verschiedene optische Verbesserungen und sonstige Fehlerbehebungen"; "lng_menu_insert_unicode" = "Unicode-Steuerzeichen einfügen"; diff --git a/Telegram/Resources/langs/lang_es.strings b/Telegram/Resources/langs/lang_es.strings index 69cfff91e..c44a14d84 100644 --- a/Telegram/Resources/langs/lang_es.strings +++ b/Telegram/Resources/langs/lang_es.strings @@ -697,7 +697,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_in_dlg_audio" = "Mensaje de voz"; "lng_in_dlg_file" = "Archivo"; "lng_in_dlg_sticker" = "Sticker"; -"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)"; +"lng_in_dlg_sticker_emoji" = "{emoji} Sticker"; "lng_ban_user" = "Suspender usuario"; "lng_delete_all_from" = "Eliminar todo lo de este usuario"; @@ -726,7 +726,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_wont_be_notified" = "Tu publicación no será notificada"; "lng_empty_history" = ""; "lng_willbe_history" = "Selecciona un chat para comenzar"; -"lng_message_with_from" = "[c]{from}:[/c] {message}"; "lng_from_you" = "Tú"; "lng_from_draft" = "Borrador"; "lng_bot_description" = "¿Qué puede hacer este bot?"; @@ -735,6 +734,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_channel_mute" = "Silenciar"; "lng_channel_unmute" = "No silenciar"; +"lng_dialogs_text_with_from" = "{from_part} {message}"; +"lng_dialogs_text_from_wrapped" = "{from}:"; +"lng_dialogs_text_media" = "{media_part} {caption}"; +"lng_dialogs_text_media_wrapped" = "{media},"; + "lng_open_this_link" = "¿Abrir este enlace?"; "lng_open_link" = "Abrir"; @@ -880,6 +884,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_selected_upload_stop" = "Detener"; "lng_selected_delete_sure_this" = "¿Quieres eliminar este mensaje?"; "lng_selected_delete_sure" = "¿Quieres eliminar {count:_not_used_|# mensaje|# mensajes}?"; +"lng_delete_photo_sure" = "¿Quieres eliminar esta foto?"; "lng_box_delete" = "Eliminar"; "lng_box_leave" = "Salir"; @@ -916,7 +921,7 @@ Copyright (c) 2014-2016 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" = "— Presentamos los borradores: sincronización para los mensajes no enviados en todos tus dispositivos. Los borradores ahora son visibles en tu lista de chats.\n— Perfiles de grupos y usuarios completamente rediseñados.\n— Contador de mensajes “no leídos” en el botón de “desplazar hacia abajo”.\n\nMás sobre esta actualización: {link}"; +"lng_new_version_text" = "— Corrección en el visor de fotos, para manejar correctamente el cambio de la resolución de la pantalla\n— Corrección en el reenvío de fotos a través de arrastrar y soltar \n— Varias mejoras de diseño y corrección de otros errores"; "lng_menu_insert_unicode" = "Insertar caracteres de control Unicode"; diff --git a/Telegram/Resources/langs/lang_it.strings b/Telegram/Resources/langs/lang_it.strings index 6234c3990..b1fc73663 100644 --- a/Telegram/Resources/langs/lang_it.strings +++ b/Telegram/Resources/langs/lang_it.strings @@ -285,7 +285,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_download_path_clear" = "Elimina tutto"; "lng_download_path_header" = "Scegli il percorso di download"; "lng_download_path_default_radio" = "Cartella Telegram in «Download»"; -"lng_download_path_temp_radio" = "Cartella temporanea, svuotata quando esci"; +"lng_download_path_temp_radio" = "Cartella temporanea, pulita quando esci"; "lng_download_path_dir_radio" = "Cartella personalizzata, pulita a mano"; "lng_download_path_choose" = "Scegli il percorso di download"; "lng_sure_clear_downloads" = "Vuoi eliminare tutti i file scaricati nella cartella temporanea? Sarà fatto automaticamente all'uscita o alla disinstallazione del programma."; @@ -418,7 +418,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_profile_add_contact" = "Aggiungi contatto"; "lng_profile_edit_contact" = "Modifica"; "lng_profile_enable_notifications" = "Notifiche"; -"lng_profile_clear_history" = "Cancella la cronologia"; +"lng_profile_clear_history" = "Cancella cronologia"; "lng_profile_delete_conversation" = "Elimina chat"; "lng_profile_clear_and_exit" = "Elimina ed esci"; "lng_profile_leave_channel" = "Lascia il canale"; @@ -697,7 +697,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_in_dlg_audio" = "Messaggio vocale"; "lng_in_dlg_file" = "File"; "lng_in_dlg_sticker" = "Sticker"; -"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)"; +"lng_in_dlg_sticker_emoji" = "{emoji} Sticker"; "lng_ban_user" = "Rimuovi utente"; "lng_delete_all_from" = "Elimina tutto da questo utente"; @@ -726,7 +726,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_wont_be_notified" = "I post non saranno notificati ai membri"; "lng_empty_history" = ""; "lng_willbe_history" = "Seleziona una chat per iniziare a chattare"; -"lng_message_with_from" = "[c]{from}:[/c] {message}"; "lng_from_you" = "Tu"; "lng_from_draft" = "Bozza"; "lng_bot_description" = "Cosa può fare questo bot?"; @@ -735,6 +734,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_channel_mute" = "Silenzia"; "lng_channel_unmute" = "Suona"; +"lng_dialogs_text_with_from" = "{from_part} {message}"; +"lng_dialogs_text_from_wrapped" = "{from}:"; +"lng_dialogs_text_media" = "{media_part} {caption}"; +"lng_dialogs_text_media_wrapped" = "{media},"; + "lng_open_this_link" = "Aprire questo link?"; "lng_open_link" = "Apri"; @@ -880,6 +884,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_selected_upload_stop" = "Arresta "; "lng_selected_delete_sure_this" = "Vuoi eliminare questo messaggio?"; "lng_selected_delete_sure" = "Vuoi eliminare {count:_not_used_|# messaggio|# messaggi}?"; +"lng_delete_photo_sure" = "Vuoi eliminare questa foto?"; "lng_box_delete" = "Elimina"; "lng_box_leave" = "Lascia"; @@ -916,7 +921,7 @@ Copyright (c) 2014-2016 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" = "— Introdotte le bozze: Sincronizzazione istantanea dei messaggi non inviati su tutti i dispositivi. Le bozze saranno visibili nella lista chat.\n— Pagina di info del gruppo e dei profili completamente ridisegnate.\n— Contatore messaggi non letti sul pulsante 'Scorri verso il basso'.\n\nPiù info su questo update: {link}"; +"lng_new_version_text" = "— Il visualizzatore delle foto ora gestisce i cambi di risoluzione dello schermo correttamente\n— Risolto l'inoltro di foto via drag-n-drop\n— Miglioramenti di design e risoluzione di problemi"; "lng_menu_insert_unicode" = "Inserisci carattere di controllo Unicode"; diff --git a/Telegram/Resources/langs/lang_ko.strings b/Telegram/Resources/langs/lang_ko.strings index e391d55b2..40d4bf50a 100644 --- a/Telegram/Resources/langs/lang_ko.strings +++ b/Telegram/Resources/langs/lang_ko.strings @@ -697,7 +697,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_in_dlg_audio" = "음성 메시지"; "lng_in_dlg_file" = "파일"; "lng_in_dlg_sticker" = "스티커"; -"lng_in_dlg_sticker_emoji" = "{emoji} (스티커)"; +"lng_in_dlg_sticker_emoji" = "{emoji} 스티커"; "lng_ban_user" = "차단하기"; "lng_delete_all_from" = "모두에게 메시지 삭제"; @@ -726,7 +726,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_wont_be_notified" = "메시지 작성시 구성원들에게 알림이 가지 않습니다."; "lng_empty_history" = ""; "lng_willbe_history" = "대화하실 방을 선택해주세요."; -"lng_message_with_from" = "[c]{from}:[/c] {message}"; "lng_from_you" = "회원님"; "lng_from_draft" = "임시저장"; "lng_bot_description" = "봇이 할 수 있는 일은 무엇일까요?"; @@ -735,6 +734,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_channel_mute" = "음소거"; "lng_channel_unmute" = "음소거 취소"; +"lng_dialogs_text_with_from" = "{from_part} {message}"; +"lng_dialogs_text_from_wrapped" = "{from}:"; +"lng_dialogs_text_media" = "{media_part} {caption}"; +"lng_dialogs_text_media_wrapped" = "{media},"; + "lng_open_this_link" = "이 링크로 이동하시겠나요?"; "lng_open_link" = "열기"; @@ -880,6 +884,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_selected_upload_stop" = "정지"; "lng_selected_delete_sure_this" = "메시지를 삭제하시겠습니까?"; "lng_selected_delete_sure" = "{count:_not_used_|# 메시지|# 메시지}를 삭제하시겠습니까?"; +"lng_delete_photo_sure" = "사진을 삭제하시겠습니까?"; "lng_box_delete" = "삭제"; "lng_box_leave" = "나가기"; @@ -916,7 +921,7 @@ Copyright (c) 2014-2016 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" = "— 임시저장을 소개합니다: 임시로 작성된 메시지 동기화. 채팅목록에 임시저장된 내역이 표시됩니다.\n— 그룹 및 구성원 프로필 디자인 리뉴얼.\n— '맨 밑으로 스크롤' 버튼에 안 읽은 메시지 카운터 표시.\n\n업데이트 자세한 내역: {link}"; +"lng_new_version_text" = "— 해상도 변경에 따라 사진 뷰어가 정상적으로 표시되도록 수정\n— 드래그앤드롭으로 사진 전송 수정\n— 디자인 및 버그 수정"; "lng_menu_insert_unicode" = "유니코드 문자를 입력하세요."; diff --git a/Telegram/Resources/langs/lang_nl.strings b/Telegram/Resources/langs/lang_nl.strings index a347a232a..a3ccbc221 100644 --- a/Telegram/Resources/langs/lang_nl.strings +++ b/Telegram/Resources/langs/lang_nl.strings @@ -697,7 +697,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_in_dlg_audio" = "Spraakbericht"; "lng_in_dlg_file" = "Bestand"; "lng_in_dlg_sticker" = "Sticker"; -"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)"; +"lng_in_dlg_sticker_emoji" = "{emoji} Sticker"; "lng_ban_user" = "Blacklist gebruiker"; "lng_delete_all_from" = "Verwijder alles van gebruiker"; @@ -726,7 +726,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_wont_be_notified" = "Geen berichtgeving voor leden"; "lng_empty_history" = ""; "lng_willbe_history" = "Kies een chat om te beginnen"; -"lng_message_with_from" = "[c]{from}:[/c] {message}"; "lng_from_you" = "Jij"; "lng_from_draft" = "Concept"; "lng_bot_description" = "Wat kan deze bot? "; @@ -735,6 +734,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_channel_mute" = "Geluid uit"; "lng_channel_unmute" = "Geluid aan"; +"lng_dialogs_text_with_from" = "{from_part} {message}"; +"lng_dialogs_text_from_wrapped" = "{from}:"; +"lng_dialogs_text_media" = "{media_part} {caption}"; +"lng_dialogs_text_media_wrapped" = "{media},"; + "lng_open_this_link" = "Link openen?"; "lng_open_link" = "Openen"; @@ -880,6 +884,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_selected_upload_stop" = "Stoppen"; "lng_selected_delete_sure_this" = "Wil je dit bericht verwijderen?"; "lng_selected_delete_sure" = "Wil je {count:_not_used_|# bericht|# berichten} verwijderen?"; +"lng_delete_photo_sure" = "Wil je deze foto verwijderen?"; "lng_box_delete" = "Verwijder"; "lng_box_leave" = "Verlaat"; @@ -916,7 +921,7 @@ Copyright (c) 2014-2016 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" = "— Concepten: Synchroniseer conceptberichten over al je apparaten. Concepten zijn vanaf nu zichtbaar in het hoofdscherm.\n— Nieuw design voor profielen van groepen en gebruikers.\n— Aantal ongelezen berichten in de 'Scroll naar beneden'-knop.\n\nMeer over deze update: {link}"; +"lng_new_version_text" = "— Probleem met foto-weergave opgelost\n— Probleem met doorsturen via slepen opgelost\n— Diverse designverbeteringen en andere opgeloste problemen"; "lng_menu_insert_unicode" = "Unicode-besturingsteken invoegen"; diff --git a/Telegram/Resources/langs/lang_pt_BR.strings b/Telegram/Resources/langs/lang_pt_BR.strings index c1dba84ff..26a4c1491 100644 --- a/Telegram/Resources/langs/lang_pt_BR.strings +++ b/Telegram/Resources/langs/lang_pt_BR.strings @@ -697,7 +697,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_in_dlg_audio" = "Mensagem de voz"; "lng_in_dlg_file" = "Arquivo"; "lng_in_dlg_sticker" = "Sticker"; -"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)"; +"lng_in_dlg_sticker_emoji" = "{emoji} Sticker"; "lng_ban_user" = "Banir Usuário"; "lng_delete_all_from" = "Apagar tudo deste usuário"; @@ -726,7 +726,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_wont_be_notified" = "Os membros não serão notificados quando você postar"; "lng_empty_history" = ""; "lng_willbe_history" = "Selecione um chat para começar a conversar"; -"lng_message_with_from" = "[c]{from}:[/c] {message}"; "lng_from_you" = "Você"; "lng_from_draft" = "Rascunho"; "lng_bot_description" = "O que esse bot pode fazer?"; @@ -735,6 +734,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_channel_mute" = "Silenciar"; "lng_channel_unmute" = "Restaurar Som"; +"lng_dialogs_text_with_from" = "{from_part} {message}"; +"lng_dialogs_text_from_wrapped" = "{from}:"; +"lng_dialogs_text_media" = "{media_part} {caption}"; +"lng_dialogs_text_media_wrapped" = "{media},"; + "lng_open_this_link" = "Abrir este link?"; "lng_open_link" = "Abrir"; @@ -880,6 +884,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_selected_upload_stop" = "Parar"; "lng_selected_delete_sure_this" = "Você deseja apagar essa mensagem?"; "lng_selected_delete_sure" = "Você deseja apagar {count:_not_used_|# mensagem|# mensagens}?"; +"lng_delete_photo_sure" = "Você deseja apagar essa foto?"; "lng_box_delete" = "Apagar"; "lng_box_leave" = "Sair"; @@ -916,7 +921,7 @@ Copyright (c) 2014-2016 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" = "— Introduzindo os rascunhos: Sincronização entre todos os seus dispositivos para mensagens não enviadas. Os rascunhos agora são visíveis em sua lista de conversas.\n— Perfis de usuários e grupos completamente redesenhados.\n— Contador de mensagens não lidas no botão “Rolar para baixo”.\n\nMais sobre essa atualização em: {link}"; +"lng_new_version_text" = "— O visualizador de fotos agora maneja corretamente a mudança de resolução da tela\n— O bug ao encaminhar fotos arrastando e soltando foi resolvido. \n— Várias melhorias de design e outras resoluções de bugs"; "lng_menu_insert_unicode" = "Inserir caractere de controle Unicode"; diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 1a71484ad..b3f7cf3e2 100644 --- a/Telegram/Resources/winrc/Telegram.rc +++ b/Telegram/Resources/winrc/Telegram.rc @@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,9,54,0 - PRODUCTVERSION 0,9,54,0 + FILEVERSION 0,9,56,0 + PRODUCTVERSION 0,9,56,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -51,10 +51,10 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Telegram Messenger LLP" - VALUE "FileVersion", "0.9.54.0" + VALUE "FileVersion", "0.9.56.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.9.54.0" + VALUE "ProductVersion", "0.9.56.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index ff3c99beb..1cdd13d51 100644 --- a/Telegram/Resources/winrc/Updater.rc +++ b/Telegram/Resources/winrc/Updater.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,9,54,0 - PRODUCTVERSION 0,9,54,0 + FILEVERSION 0,9,56,0 + PRODUCTVERSION 0,9,56,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,10 +43,10 @@ BEGIN BEGIN VALUE "CompanyName", "Telegram Messenger LLP" VALUE "FileDescription", "Telegram Updater" - VALUE "FileVersion", "0.9.54.0" + VALUE "FileVersion", "0.9.56.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.9.54.0" + VALUE "ProductVersion", "0.9.56.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index b9387b86b..f26bbb6e3 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -780,10 +780,6 @@ void AppClass::regPhotoUpdate(const PeerId &peer, const FullMsgId &msgId) { photoUpdates.insert(msgId, peer); } -void AppClass::clearPhotoUpdates() { - photoUpdates.clear(); -} - bool AppClass::isPhotoUpdating(const PeerId &peer) { for (QMap::iterator i = photoUpdates.begin(), e = photoUpdates.end(); i != e; ++i) { if (i.value() == peer) { @@ -1049,10 +1045,10 @@ void AppClass::checkMapVersion() { if (Local::oldMapVersion() < AppVersion) { if (Local::oldMapVersion()) { QString versionFeatures; - if ((cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 9054) { - versionFeatures = QString::fromUtf8("\xe2\x80\x94 Photo viewer handles screen resolution change\n\xe2\x80\x94 Forward photo by drag-n-drop fixed\n\xe2\x80\x94 Some design improvements and bug fixes"); + if ((cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 9055) { + versionFeatures = QString::fromUtf8("\xe2\x80\x94 Main window position and size are saved between the launches in Windows\n\xe2\x80\x94 Dock and top bar hiding fixed in OS X\n\xe2\x80\x94 Various design improvements and other bug fixes"); // versionFeatures = langNewVersionText(); - } else if (Local::oldMapVersion() < 9050) { + } else if (Local::oldMapVersion() < 9056) { versionFeatures = langNewVersionText(); } else { versionFeatures = lang(lng_new_version_minor).trimmed(); diff --git a/Telegram/SourceFiles/application.h b/Telegram/SourceFiles/application.h index b7d595eed..4b6023131 100644 --- a/Telegram/SourceFiles/application.h +++ b/Telegram/SourceFiles/application.h @@ -159,7 +159,6 @@ public: FileUploader *uploader(); void uploadProfilePhoto(const QImage &tosend, const PeerId &peerId); void regPhotoUpdate(const PeerId &peer, const FullMsgId &msgId); - void clearPhotoUpdates(); bool isPhotoUpdating(const PeerId &peer); void cancelPhotoUpdate(const PeerId &peer); diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index deaeed2f4..68d7dbbd0 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -24,7 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #define BETA_VERSION_MACRO (0ULL) -constexpr int AppVersion = 9054; -constexpr str_const AppVersionStr = "0.9.54"; -constexpr bool AppAlphaVersion = true; +constexpr int AppVersion = 9056; +constexpr str_const AppVersionStr = "0.9.56"; +constexpr bool AppAlphaVersion = false; constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO; diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index 1d0791bc0..61b78c8e8 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -2307,21 +2307,34 @@ void ReplyKeyboard::resize(int width, int height) { for (ButtonRow &row : _rows) { int s = row.size(); - int widthForText = _width - ((s - 1) * _st->buttonSkip()); + int widthForButtons = _width - ((s - 1) * _st->buttonSkip()); + int widthForText = widthForButtons; int widthOfText = 0; + int maxMinButtonWidth = 0; for_const (const Button &button, row) { widthOfText += qMax(button.text.maxWidth(), 1); - widthForText -= _st->minButtonWidth(button.type); + int minButtonWidth = _st->minButtonWidth(button.type); + widthForText -= minButtonWidth; + accumulate_max(maxMinButtonWidth, minButtonWidth); } bool exact = (widthForText == widthOfText); + bool enough = (widthForButtons - s * maxMinButtonWidth) >= widthOfText; float64 x = 0; for (Button &button : row) { int buttonw = qMax(button.text.maxWidth(), 1); - float64 textw = exact ? buttonw : (widthForText / float64(s)); - float64 minw = _st->minButtonWidth(button.type); - float64 w = minw + textw; - accumulate_max(w, 2 * float64(_st->buttonPadding())); + float64 textw = buttonw, minw = _st->minButtonWidth(button.type); + float64 w = textw; + if (exact) { + w += minw; + } else if (enough) { + w = (widthForButtons / float64(s)); + textw = w - minw; + } else { + textw = (widthForText / float64(s)); + w = minw + textw; + accumulate_max(w, 2 * float64(_st->buttonPadding())); + } int rectx = static_cast(std::floor(x)); int rectw = static_cast(std::floor(x + w)) - rectx; @@ -2359,10 +2372,14 @@ void ReplyKeyboard::setStyle(StylePtr &&st) { int ReplyKeyboard::naturalWidth() const { auto result = 0; - for_const (const auto &row, _rows) { + for_const (auto &row, _rows) { + auto maxMinButtonWidth = 0; + for_const (auto &button, row) { + accumulate_max(maxMinButtonWidth, _st->minButtonWidth(button.type)); + } auto rowMaxButtonWidth = 0; - for_const (const auto &button, row) { - accumulate_max(rowMaxButtonWidth, qMax(button.text.maxWidth(), 1) + _st->minButtonWidth(button.type)); + for_const (auto &button, row) { + accumulate_max(rowMaxButtonWidth, qMax(button.text.maxWidth(), 1) + maxMinButtonWidth); } auto rowSize = row.size(); @@ -4897,9 +4914,9 @@ public: protected: void onClickImpl() const override { - if (HistoryMedia *media = _item->getMedia()) { - if (DocumentData *document = media->getDocument()) { - if (StickerData *sticker = document->sticker()) { + if (auto media = _item->getMedia()) { + if (auto document = media->getDocument()) { + if (auto sticker = document->sticker()) { if (sticker->set.type() != mtpc_inputStickerSetEmpty && App::main()) { App::main()->stickersBox(sticker->set); } @@ -4921,13 +4938,15 @@ HistorySticker::HistorySticker(HistoryItem *parent, DocumentData *document) : Hi , _data(document) , _emoji(_data->sticker()->alt) { _data->thumb->load(); - if (EmojiPtr e = emojiFromText(_emoji)) { + if (auto e = emojiFromText(_emoji)) { _emoji = emojiString(e); } } void HistorySticker::initDimensions() { - if (!_packLink && _data->sticker() && _data->sticker()->set.type() != mtpc_inputStickerSetEmpty) { + auto sticker = _data->sticker(); + + if (!_packLink && sticker && sticker->set.type() != mtpc_inputStickerSetEmpty) { _packLink = ClickHandlerPtr(new StickerClickHandler(_parent)); } _pixw = _data->dimensions.width(); @@ -4971,6 +4990,9 @@ int HistorySticker::resizeGetHeight(int width) { // return new height } void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const { + auto sticker = _data->sticker(); + if (!sticker) return; + if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return; _data->checkSticker(); @@ -4992,16 +5014,16 @@ void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, u if (rtl()) usex = _width - usex - usew; if (selected) { - if (_data->sticker()->img->isNull()) { + if (sticker->img->isNull()) { p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (_minh - _pixh) / 2), _data->thumb->pixBlurredColored(st::msgStickerOverlay, _pixw, _pixh)); } else { - p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (_minh - _pixh) / 2), _data->sticker()->img->pixColored(st::msgStickerOverlay, _pixw, _pixh)); + p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (_minh - _pixh) / 2), sticker->img->pixColored(st::msgStickerOverlay, _pixw, _pixh)); } } else { - if (_data->sticker()->img->isNull()) { + if (sticker->img->isNull()) { p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (_minh - _pixh) / 2), _data->thumb->pixBlurred(_pixw, _pixh)); } else { - p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (_minh - _pixh) / 2), _data->sticker()->img->pix(_pixw, _pixh)); + p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (_minh - _pixh) / 2), sticker->img->pix(_pixw, _pixh)); } } diff --git a/Telegram/SourceFiles/history/field_autocomplete.cpp b/Telegram/SourceFiles/history/field_autocomplete.cpp index 7bc693a7f..c62e7637e 100644 --- a/Telegram/SourceFiles/history/field_autocomplete.cpp +++ b/Telegram/SourceFiles/history/field_autocomplete.cpp @@ -507,9 +507,9 @@ bool FieldAutocomplete::eventFilter(QObject *obj, QEvent *e) { return _inner->chooseSelected(ChooseMethod::ByEnter); } } - if (moderate && ev->key() >= Qt::Key_1 && ev->key() <= Qt::Key_9) { + if (moderate && ((ev->key() >= Qt::Key_1 && ev->key() <= Qt::Key_9) || ev->key() == Qt::Key_Q)) { bool handled = false; - emit moderateKeyActivate(ev->key() - Qt::Key_1, &handled); + emit moderateKeyActivate(ev->key(), &handled); return handled; } } diff --git a/Telegram/SourceFiles/history/field_autocomplete.h b/Telegram/SourceFiles/history/field_autocomplete.h index 596034aaa..4dd85260b 100644 --- a/Telegram/SourceFiles/history/field_autocomplete.h +++ b/Telegram/SourceFiles/history/field_autocomplete.h @@ -85,7 +85,7 @@ signals: void botCommandChosen(QString command, FieldAutocomplete::ChooseMethod method) const; void stickerChosen(DocumentData *sticker, FieldAutocomplete::ChooseMethod method) const; - void moderateKeyActivate(int index, bool *outHandled) const; + void moderateKeyActivate(int key, bool *outHandled) const; public slots: diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index fecb23487..c0c23cef0 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -1471,6 +1471,10 @@ void HistoryInner::keyPressEvent(QKeyEvent *e) { _widget->onListEscapePressed(); } else if (e == QKeySequence::Copy && !_selected.isEmpty()) { copySelectedText(); +#ifdef Q_OS_MAC + } else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) { + setToClipboard(getSelectedText(), QClipboard::FindBuffer); +#endif // Q_OS_MAC } else if (e == QKeySequence::Delete) { int32 selectedForForward, selectedForDelete; getSelectionState(selectedForForward, selectedForDelete); @@ -2481,12 +2485,22 @@ void BotKeyboard::leaveEvent(QEvent *e) { clearSelection(); } -bool BotKeyboard::moderateKeyActivate(int index) { +bool BotKeyboard::moderateKeyActivate(int key) { if (auto item = App::histItemById(_wasForMsgId)) { if (auto markup = item->Get()) { - if (!markup->rows.isEmpty() && index >= 0 && index < markup->rows.front().size()) { - App::activateBotCommand(item, 0, index); - return true; + if (key >= Qt::Key_1 && key <= Qt::Key_9) { + int index = (key - Qt::Key_1); + if (!markup->rows.isEmpty() && index >= 0 && index < markup->rows.front().size()) { + App::activateBotCommand(item, 0, index); + return true; + } + } else if (key == Qt::Key_Q) { + if (auto user = item->history()->peer->asUser()) { + if (user->botInfo && item->from() == user) { + App::sendBotCommand(user, user, qsl("/translate")); + return true; + } + } } } } diff --git a/Telegram/SourceFiles/lang.cpp b/Telegram/SourceFiles/lang.cpp index 6f4fd78e8..59b648bf6 100644 --- a/Telegram/SourceFiles/lang.cpp +++ b/Telegram/SourceFiles/lang.cpp @@ -46,8 +46,8 @@ LangString langCounted(ushort key0, ushort tag, float64 value) { // current lang return lang(LangKey(key0)).tag(tag, sv); } -#define NEW_VER_TAG lt_link -#define NEW_VER_TAG_VALUE "https://telegram.org/blog/drafts" +//#define NEW_VER_TAG lt_link +//#define NEW_VER_TAG_VALUE "https://telegram.org/blog/drafts" QString langNewVersionText() { #ifdef NEW_VER_TAG diff --git a/Telegram/SourceFiles/layout.cpp b/Telegram/SourceFiles/layout.cpp index 54a7d259d..2dcd973d7 100644 --- a/Telegram/SourceFiles/layout.cpp +++ b/Telegram/SourceFiles/layout.cpp @@ -215,3 +215,23 @@ style::sprite documentCorner(int32 colorIndex) { RoundCorners documentCorners(int32 colorIndex) { return RoundCorners(DocBlueCorners + (colorIndex & 3)); } + +bool documentIsValidMediaFile(const QString &filepath) { + static StaticNeverFreedPointer> validMediaTypes(([] { + std_::unique_ptr> result = std_::make_unique>(); + *result = qsl("\ +webm mkv flv vob ogv ogg drc gif gifv mng avi mov qt wmv yuv rm rmvb asf amv mp4 m4p \ +m4v mpg mp2 mpeg mpe mpv m2v svi 3gp 3g2 mxf roq nsv f4v f4p f4a f4b wma divx evo mk3d \ +mka mks mcf m2p ps ts m2ts ifo aaf avchd cam dat dsh dvr-ms m1v fla flr sol wrap smi swf \ +wtv 8svx 16svx iff aiff aif aifc au bwf cdda raw wav flac la pac m4a ape ofr ofs off rka \ +shn tak tta wv brstm dts dtshd dtsma ast amr mp3 spx gsm aac mpc vqf ra ots swa vox voc \ +dwd smp aup cust mid mus sib sid ly gym vgm psf nsf mod ptb s3m xm it mt2 minipsf psflib \ +2sf dsf gsf psf2 qsf ssf usf rmj spc niff mxl xml txm ym jam mp1 mscz \ +").split(' '); + return result.release(); + })()); + + QFileInfo info(filepath); + auto parts = info.fileName().split('.', QString::SkipEmptyParts); + return !parts.isEmpty() && (validMediaTypes->indexOf(parts.back().toLower()) >= 0); +} diff --git a/Telegram/SourceFiles/layout.h b/Telegram/SourceFiles/layout.h index 86e6298e2..7ac05fdeb 100644 --- a/Telegram/SourceFiles/layout.h +++ b/Telegram/SourceFiles/layout.h @@ -81,6 +81,7 @@ style::color documentOverColor(int32 colorIndex); style::color documentSelectedColor(int32 colorIndex); style::sprite documentCorner(int32 colorIndex); RoundCorners documentCorners(int32 colorIndex); +bool documentIsValidMediaFile(const QString &filepath); class PaintContextBase { public: diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 45846a9be..10688692c 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1542,7 +1542,11 @@ void MainWidget::audioPlayProgress(const AudioMsgId &audioId) { DocumentData *audio = audioId.audio(); QString filepath = audio->filepath(DocumentData::FilePathResolveSaveFromData); if (!filepath.isEmpty()) { - psOpenFile(filepath); + if (documentIsValidMediaFile(filepath)) { + psOpenFile(filepath); + } else { + psShowInFolder(filepath); + } } } diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index d8bbb5de4..cc0020b74 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -599,6 +599,10 @@ void MainWindow::setupIntro(bool anim) { cSetDialogsReceived(false); if (intro && !intro->isHidden() && !main) return; + if (_mediaView) { + _mediaView->clearData(); + } + QPixmap bg = anim ? grabInner() : QPixmap(); clearWidgets(); @@ -925,13 +929,26 @@ void MainWindow::layerHidden() { setInnerFocus(); } +void MainWindow::onReActivate() { + if (auto w = App::wnd()) { + if (auto f = QApplication::focusWidget()) { + f->clearFocus(); + } + w->windowHandle()->requestActivate(); + w->activate(); + if (auto f = QApplication::focusWidget()) { + f->clearFocus(); + } + w->setInnerFocus(); + } +} + void MainWindow::hideMediaview() { if (_mediaView && !_mediaView->isHidden()) { _mediaView->hide(); #if defined Q_OS_LINUX32 || defined Q_OS_LINUX64 - if (App::wnd()) { - App::wnd()->activateWindow(); - } + onReActivate(); + QTimer::singleShot(200, this, SLOT(onReActivate())); #endif } } diff --git a/Telegram/SourceFiles/mainwindow.h b/Telegram/SourceFiles/mainwindow.h index 5a7826c61..32926621b 100644 --- a/Telegram/SourceFiles/mainwindow.h +++ b/Telegram/SourceFiles/mainwindow.h @@ -282,6 +282,8 @@ public slots: void onLogoutSure(); void updateGlobalMenu(); // for OS X top menu + void onReActivate(); + void notifyUpdateAllPhotos(); void app_activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button); diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index dae547c5f..ba722e41d 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -497,6 +497,28 @@ void MediaView::step_radial(uint64 ms, bool timer) { } } +void MediaView::clearData() { + if (!isHidden()) { + hide(); + } + if (!_animations.isEmpty()) { + _animations.clear(); + _a_state.stop(); + } + if (!_animOpacities.isEmpty()) _animOpacities.clear(); + delete _gif; + _gif = nullptr; + delete _menu; + _menu = nullptr; + _history = _migrated = nullptr; + _peer = _from = nullptr; + _user = nullptr; + _photo = _additionalChatPhoto = nullptr; + _doc = nullptr; + _saveMsgText.clear(); + _caption.clear(); +} + MediaView::~MediaView() { deleteAndMark(_gif); deleteAndMark(_menu); @@ -818,6 +840,7 @@ void MediaView::onCopy() { void MediaView::showPhoto(PhotoData *photo, HistoryItem *context) { _history = context ? context->history() : nullptr; + _migrated = nullptr; if (_history) { if (_history->peer->migrateFrom()) { _migrated = App::history(_history->peer->migrateFrom()->id); @@ -825,8 +848,6 @@ void MediaView::showPhoto(PhotoData *photo, HistoryItem *context) { _migrated = _history; _history = App::history(_history->peer->migrateTo()->id); } - } else { - _migrated = nullptr; } _additionalChatPhoto = nullptr; _firstOpenedPeerPhoto = false; @@ -937,6 +958,7 @@ void MediaView::showPhoto(PhotoData *photo, PeerData *context) { void MediaView::showDocument(DocumentData *doc, HistoryItem *context) { _photo = 0; _history = context ? context->history() : nullptr; + _migrated = nullptr; if (_history) { if (_history->peer->migrateFrom()) { _migrated = App::history(_history->peer->migrateFrom()->id); @@ -944,8 +966,6 @@ void MediaView::showDocument(DocumentData *doc, HistoryItem *context) { _migrated = _history; _history = App::history(_history->peer->migrateTo()->id); } - } else { - _migrated = 0; } _additionalChatPhoto = nullptr; _saveMsgStarted = 0; @@ -1679,7 +1699,7 @@ void MediaView::preloadData(int32 delta) { int indexInOverview = _index; bool indexOfMigratedItem = _msgmigrated; if (_index < 0) { - if (_overview != OverviewChatPhotos) return; + if (_overview != OverviewChatPhotos || !_history) return; indexInOverview = _history->overview[OverviewChatPhotos].size(); indexOfMigratedItem = false; } diff --git a/Telegram/SourceFiles/mediaview.h b/Telegram/SourceFiles/mediaview.h index 904e4bd41..0830fd582 100644 --- a/Telegram/SourceFiles/mediaview.h +++ b/Telegram/SourceFiles/mediaview.h @@ -74,6 +74,8 @@ public: void clipCallback(Media::Clip::Notification notification); PeerData *ui_getPeerForMouseAction(); + void clearData(); + ~MediaView(); // ClickHandlerHost interface diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index 4ad63d0bf..dfc4b7462 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -249,9 +249,9 @@ void MainWindow::psSetupTrayIcon() { trayIcon = new QSystemTrayIcon(this); QIcon icon; - QFileInfo f(_trayIconImageFile()); - if (f.exists()) { - QByteArray path = QFile::encodeName(f.absoluteFilePath()); + QFileInfo iconFile(_trayIconImageFile()); + if (iconFile.exists()) { + QByteArray path = QFile::encodeName(iconFile.absoluteFilePath()); icon = QIcon(path.constData()); } else { icon = QIcon(QPixmap::fromImage(App::wnd()->iconLarge(), Qt::ColorOnly)); @@ -303,9 +303,9 @@ void MainWindow::psUpdateWorkmode() { void MainWindow::psUpdateIndicator() { _psUpdateIndicatorTimer.stop(); _psLastIndicatorUpdate = getms(); - QFileInfo f(_trayIconImageFile()); - if (f.exists()) { - QByteArray path = QFile::encodeName(f.absoluteFilePath()), name = QFile::encodeName(f.fileName()); + QFileInfo iconFile(_trayIconImageFile()); + if (iconFile.exists()) { + QByteArray path = QFile::encodeName(iconFile.absoluteFilePath()), name = QFile::encodeName(iconFile.fileName()); name = name.mid(0, name.size() - 4); Libs::app_indicator_set_icon_full(_trayIndicator, path.constData(), name); } else { @@ -338,7 +338,7 @@ void MainWindow::psUpdateCounter() { } else if (useStatusIcon && trayIconChecked) { QFileInfo iconFile(_trayIconImageFile()); if (iconFile.exists()) { - QByteArray path = QFile::encodeName(f.absoluteFilePath()); + QByteArray path = QFile::encodeName(iconFile.absoluteFilePath()); Libs::gtk_status_icon_set_from_file(_trayIcon, path.constData()); } else { loadPixbuf(_trayIconImageGen()); @@ -347,9 +347,9 @@ void MainWindow::psUpdateCounter() { } } else if (trayIcon) { QIcon icon; - QFileInfo f(_trayIconImageFile()); - if (f.exists()) { - QByteArray path = QFile::encodeName(f.absoluteFilePath()); + QFileInfo iconFile(_trayIconImageFile()); + if (iconFile.exists()) { + QByteArray path = QFile::encodeName(iconFile.absoluteFilePath()); icon = QIcon(path.constData()); } else { int32 counter = App::histories().unreadBadge(); @@ -524,9 +524,9 @@ void MainWindow::psCreateTrayIcon() { _trayMenu = Libs::gtk_menu_new(); if (_trayMenu) { DEBUG_LOG(("Created gtk menu for appindicator!")); - QFileInfo f(_trayIconImageFile()); - if (f.exists()) { - QByteArray path = QFile::encodeName(f.absoluteFilePath()); + QFileInfo iconFile(_trayIconImageFile()); + if (iconFile.exists()) { + QByteArray path = QFile::encodeName(iconFile.absoluteFilePath()); _trayIndicator = Libs::app_indicator_new("Telegram Desktop", path.constData(), APP_INDICATOR_CATEGORY_APPLICATION_STATUS); if (_trayIndicator) { DEBUG_LOG(("Created appindicator!")); diff --git a/Telegram/SourceFiles/profile/profile_cover.cpp b/Telegram/SourceFiles/profile/profile_cover.cpp index 431d00e08..9c58ddca0 100644 --- a/Telegram/SourceFiles/profile/profile_cover.cpp +++ b/Telegram/SourceFiles/profile/profile_cover.cpp @@ -26,6 +26,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "profile/profile_userpic_button.h" #include "ui/buttons/round_button.h" #include "ui/filedialog.h" +#include "ui/flatlabel.h" +#include "ui/flatbutton.h" #include "observer_peer.h" #include "boxes/confirmbox.h" #include "boxes/contactsbox.h" @@ -34,6 +36,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "apiwrap.h" #include "mainwidget.h" #include "mainwindow.h" +#include "application.h" namespace Profile { namespace { @@ -59,8 +62,8 @@ CoverWidget::CoverWidget(QWidget *parent, PeerData *peer) : TWidget(parent) setAttribute(Qt::WA_OpaquePaintEvent); setAcceptDrops(true); - _name.setSelectable(true); - _name.setContextCopyText(lang(lng_profile_copy_fullname)); + _name->setSelectable(true); + _name->setContextCopyText(lang(lng_profile_copy_fullname)); auto observeEvents = ButtonsUpdateFlags | UpdateFlag::NameChanged @@ -68,6 +71,9 @@ CoverWidget::CoverWidget(QWidget *parent, PeerData *peer) : TWidget(parent) Notify::registerPeerObserver(observeEvents, this, &CoverWidget::notifyPeerUpdated); FileDialog::registerObserver(this, &CoverWidget::notifyFileQueryUpdated); + connect(App::app(), SIGNAL(peerPhotoDone(PeerId)), this, SLOT(onPhotoUploadStatusChanged(PeerId))); + connect(App::app(), SIGNAL(peerPhotoFail(PeerId)), this, SLOT(onPhotoUploadStatusChanged(PeerId))); + connect(_userpicButton, SIGNAL(clicked()), this, SLOT(onPhotoShow())); validatePhoto(); @@ -92,6 +98,13 @@ void CoverWidget::onPhotoShow() { } } +void CoverWidget::onCancelPhotoUpload() { + if (auto app = App::app()) { + app->cancelPhotoUpdate(_peer->id); + refreshStatusText(); + } +} + int CoverWidget::countPhotoLeft(int newWidth) const { int result = st::profilePhotoLeftMin; result += (newWidth - st::wndMinWidth) / 2; @@ -110,6 +123,9 @@ void CoverWidget::resizeToWidth(int newWidth) { int infoLeft = _userpicButton->x() + _userpicButton->width(); _statusPosition = QPoint(infoLeft + st::profileStatusLeft, _userpicButton->y() + st::profileStatusTop); + if (_cancelPhotoUpload) { + _cancelPhotoUpload->moveToLeft(_statusPosition.x() + st::profileStatusFont->width(_statusText) + st::profileStatusFont->spacew, _statusPosition.y()); + } moveAndToggleButtons(newWidth); @@ -135,8 +151,8 @@ void CoverWidget::refreshNameGeometry(int newWidth) { nameWidth -= st::profileVerifiedCheckPosition.x() + st::profileVerifiedCheck.width(); } int marginsAdd = st::profileNameLabel.margin.left() + st::profileNameLabel.margin.right(); - _name.resizeToWidth(qMin(nameWidth - marginsAdd, _name.naturalWidth()) + marginsAdd); - _name.moveToLeft(nameLeft, nameTop); + _name->resizeToWidth(qMin(nameWidth - marginsAdd, _name->naturalWidth()) + marginsAdd); + _name->moveToLeft(nameLeft, nameTop); } // A more generic solution would be allowing an optional icon button @@ -188,7 +204,7 @@ void CoverWidget::paintEvent(QPaintEvent *e) { p.drawTextLeft(_statusPosition.x(), _statusPosition.y(), width(), _statusText); if (_peer->isVerified()) { - st::profileVerifiedCheck.paint(p, QPoint(_name.x() + _name.width(), _name.y()) + st::profileVerifiedCheckPosition, width()); + st::profileVerifiedCheck.paint(p, QPoint(_name->x() + _name->width(), _name->y()) + st::profileVerifiedCheckPosition, width()); } paintDivider(p); @@ -322,11 +338,26 @@ void CoverWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) { } void CoverWidget::refreshNameText() { - _name.setText(App::peerName(_peer)); + _name->setText(App::peerName(_peer)); refreshNameGeometry(width()); } void CoverWidget::refreshStatusText() { + if (auto app = App::app()) { + if (app->isPhotoUpdating(_peer->id)) { + _statusText = lang(lng_settings_uploading_photo); + if (!_cancelPhotoUpload) { + _cancelPhotoUpload = new LinkButton(this, lang(lng_cancel), st::btnDefLink); + connect(_cancelPhotoUpload, SIGNAL(clicked()), this, SLOT(onCancelPhotoUpload())); + _cancelPhotoUpload->show(); + _cancelPhotoUpload->moveToLeft(_statusPosition.x() + st::profileStatusFont->width(_statusText) + st::profileStatusFont->spacew, _statusPosition.y()); + } + update(); + return; + } + } + + _cancelPhotoUpload.destroy(); int currentTime = unixtime(); if (_peerUser) { _statusText = App::onlineText(_peerUser, currentTime, true); @@ -477,10 +508,16 @@ void CoverWidget::showSetPhotoBox(const QImage &img) { } auto box = new PhotoCropBox(img, _peer); - connect(box, SIGNAL(closed()), this, SLOT(onPhotoUpdateStart())); + connect(box, SIGNAL(closed()), this, SLOT(onPhotoUploadStatusChanged())); Ui::showLayer(box); } +void CoverWidget::onPhotoUploadStatusChanged(PeerId peerId) { + if (!peerId || peerId == _peer->id) { + refreshStatusText(); + } +} + void CoverWidget::onAddMember() { if (_peerChat) { if (_peerChat->count >= Global::ChatSizeMax() && _peerChat->amCreator()) { diff --git a/Telegram/SourceFiles/profile/profile_cover.h b/Telegram/SourceFiles/profile/profile_cover.h index ea92fe9da..768a77349 100644 --- a/Telegram/SourceFiles/profile/profile_cover.h +++ b/Telegram/SourceFiles/profile/profile_cover.h @@ -22,7 +22,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "core/observer.h" #include "ui/filedialog.h" -#include "ui/flatlabel.h" + +class FlatLabel; +class LinkButton; namespace Ui { class RoundButton; @@ -59,6 +61,8 @@ public slots: private slots: void onPhotoShow(); + void onPhotoUploadStatusChanged(PeerId peerId = 0); + void onCancelPhotoUpload(); void onSendMessage(); void onShareContact(); @@ -114,7 +118,8 @@ private: ChildWidget _userpicButton; ChildWidget _dropArea = { nullptr }; - FlatLabel _name; + ChildWidget _name; + ChildWidget _cancelPhotoUpload = { nullptr }; QPoint _statusPosition; QString _statusText; diff --git a/Telegram/SourceFiles/pspecific_linux.cpp b/Telegram/SourceFiles/pspecific_linux.cpp index f5e880cac..6c4ad17a9 100644 --- a/Telegram/SourceFiles/pspecific_linux.cpp +++ b/Telegram/SourceFiles/pspecific_linux.cpp @@ -434,6 +434,7 @@ void psRegisterCustomScheme() { QString home(_psHomeDir()); if (home.isEmpty() || cBetaVersion()) return; // don't update desktop file for beta version + #ifndef TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION DEBUG_LOG(("App Info: placing .desktop file")); if (QDir(home + qsl(".local/")).exists()) { QString apps = home + qsl(".local/share/applications/"); @@ -480,6 +481,7 @@ void psRegisterCustomScheme() { LOG(("App Error: Could not open '%1' for write").arg(file)); } } + #endif // TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION DEBUG_LOG(("App Info: registerting for Gnome")); if (_psRunCommand("gconftool-2 -t string -s /desktop/gnome/url-handlers/tg/command " + escapeShell(escapeShell(QFile::encodeName(cExeDir() + cExeName())) + " -- %s"))) { diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index 6736da8ff..563af77fb 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -983,11 +983,21 @@ void DocumentOpenClickHandler::doOpen(DocumentData *data, ActionOnLoad action) { App::wnd()->showDocument(data, item); location.accessDisable(); } else { - psOpenFile(location.name()); + auto filepath = location.name(); + if (documentIsValidMediaFile(filepath)) { + psOpenFile(filepath); + } else { + psShowInFolder(filepath); + } } if (App::main()) App::main()->mediaMarkRead(data); - } else if (data->voice() || data->isVideo()) { - psOpenFile(location.name()); + } else if (data->voice() || data->song() || data->isVideo()) { + auto filepath = location.name(); + if (documentIsValidMediaFile(filepath)) { + psOpenFile(filepath); + } else { + psShowInFolder(filepath); + } if (App::main()) App::main()->mediaMarkRead(data); } else if (data->size < MediaViewImageSizeLimit) { if (!data->data().isEmpty() && playAnimation) { @@ -1281,8 +1291,12 @@ void DocumentData::performActionOnLoad() { psOpenFile(already, true); } } else if (_actionOnLoad == ActionOnLoadOpen || _actionOnLoad == ActionOnLoadPlayInline) { - if (voice() || isVideo()) { - psOpenFile(already); + if (voice() || song() || isVideo()) { + if (documentIsValidMediaFile(already)) { + psOpenFile(already); + } else { + psShowInFolder(already); + } if (App::main()) App::main()->mediaMarkRead(this); } else if (loc.accessEnable()) { if (showImage && QImageReader(loc.name()).canRead()) { diff --git a/Telegram/SourceFiles/ui/countryinput.cpp b/Telegram/SourceFiles/ui/countryinput.cpp index f1d8b99ef..49dd6b6d4 100644 --- a/Telegram/SourceFiles/ui/countryinput.cpp +++ b/Telegram/SourceFiles/ui/countryinput.cpp @@ -114,10 +114,16 @@ CountryInput::CountryInput(QWidget *parent, const style::countryInput &st) : QWi void CountryInput::paintEvent(QPaintEvent *e) { QPainter p(this); - p.fillRect(_inner, _st.bgColor->b); + p.setRenderHint(QPainter::HighQualityAntialiasing); + p.setBrush(_st.bgColor); + p.setPen(Qt::NoPen); + p.drawRoundedRect(_inner, st::msgRadius, st::msgRadius); + p.setRenderHint(QPainter::HighQualityAntialiasing, false); + p.drawPixmap(_arrowRect.x(), _arrowRect.top(), _arrow); - p.setFont(_st.font->f); + p.setFont(_st.font); + p.setPen(st::windowTextFg); p.drawText(rect().marginsRemoved(_st.textMrg), _text, QTextOption(_st.align)); } diff --git a/Telegram/SourceFiles/ui/flatbutton.cpp b/Telegram/SourceFiles/ui/flatbutton.cpp index 2ead5cbce..8443ba011 100644 --- a/Telegram/SourceFiles/ui/flatbutton.cpp +++ b/Telegram/SourceFiles/ui/flatbutton.cpp @@ -101,7 +101,15 @@ void FlatButton::paintEvent(QPaintEvent *e) { QRect r(0, height() - _st.height, width(), _st.height); p.setOpacity(_opacity); - p.fillRect(r, a_bg.current()); + if (_st.radius > 0) { + p.setRenderHint(QPainter::HighQualityAntialiasing); + p.setPen(Qt::NoPen); + p.setBrush(QBrush(a_bg.current())); + p.drawRoundedRect(r, _st.radius, _st.radius); + p.setRenderHint(QPainter::HighQualityAntialiasing, false); + } else { + p.fillRect(r, a_bg.current()); + } p.setFont((_state & StateOver) ? _st.overFont : _st.font); p.setRenderHint(QPainter::TextAntialiasing); diff --git a/Telegram/SourceFiles/ui/flatcheckbox.cpp b/Telegram/SourceFiles/ui/flatcheckbox.cpp index 6e082f890..8792f4b00 100644 --- a/Telegram/SourceFiles/ui/flatcheckbox.cpp +++ b/Telegram/SourceFiles/ui/flatcheckbox.cpp @@ -347,7 +347,7 @@ void Checkbox::paintEvent(QPaintEvent *e) { } else { p.setBrush(st::white); } - p.drawRoundedRect(QRectF(_checkRect).marginsRemoved(QMarginsF(_st.thickness / 2, _st.thickness / 2, _st.thickness / 2, _st.thickness / 2)), st::msgRadius - (_st.thickness / 2), st::msgRadius - (_st.thickness / 2)); + p.drawRoundedRect(QRectF(_checkRect).marginsRemoved(QMarginsF(_st.thickness / 2., _st.thickness / 2., _st.thickness / 2., _st.thickness / 2.)), st::msgRadius - (_st.thickness / 2.), st::msgRadius - (_st.thickness / 2.)); p.setRenderHint(QPainter::HighQualityAntialiasing, false); if (checked > 0) { @@ -485,9 +485,9 @@ void Radiobutton::paintEvent(QPaintEvent *e) { pen.setWidth(_st.thickness); p.setPen(pen); p.setBrush(Qt::NoBrush); - //int32 skip = qCeil(_st.thickness / 2); + //int32 skip = qCeil(_st.thickness / 2.); //p.drawEllipse(_checkRect.marginsRemoved(QMargins(skip, skip, skip, skip))); - p.drawEllipse(QRectF(_checkRect).marginsRemoved(QMarginsF(_st.thickness / 2, _st.thickness / 2, _st.thickness / 2, _st.thickness / 2))); + p.drawEllipse(QRectF(_checkRect).marginsRemoved(QMarginsF(_st.thickness / 2., _st.thickness / 2., _st.thickness / 2., _st.thickness / 2.))); if (checked > 0) { p.setPen(Qt::NoPen); diff --git a/Telegram/SourceFiles/ui/flatinput.cpp b/Telegram/SourceFiles/ui/flatinput.cpp index dbb8f3006..55e088fda 100644 --- a/Telegram/SourceFiles/ui/flatinput.cpp +++ b/Telegram/SourceFiles/ui/flatinput.cpp @@ -174,14 +174,15 @@ QRect FlatInput::getTextRect() const { void FlatInput::paintEvent(QPaintEvent *e) { Painter p(this); - p.fillRect(rect(), a_bgColor.current()); - if (_st.borderWidth) { - QBrush b(a_borderColor.current()); - p.fillRect(0, 0, width() - _st.borderWidth, _st.borderWidth, b); - p.fillRect(width() - _st.borderWidth, 0, _st.borderWidth, height() - _st.borderWidth, b); - p.fillRect(_st.borderWidth, height() - _st.borderWidth, width() - _st.borderWidth, _st.borderWidth, b); - p.fillRect(0, _st.borderWidth, _st.borderWidth, height() - _st.borderWidth, b); - } + + p.setRenderHint(QPainter::HighQualityAntialiasing); + auto pen = QPen(a_borderColor.current()); + pen.setWidth(_st.borderWidth); + p.setPen(pen); + p.setBrush(QBrush(a_bgColor.current())); + p.drawRoundedRect(QRectF(0, 0, width(), height()).marginsRemoved(QMarginsF(_st.borderWidth / 2., _st.borderWidth / 2., _st.borderWidth / 2., _st.borderWidth / 2.)), st::msgRadius - (_st.borderWidth / 2.), st::msgRadius - (_st.borderWidth / 2.)); + p.setRenderHint(QPainter::HighQualityAntialiasing, false); + if (_st.imgRect.pxWidth()) { p.drawSprite(_st.imgPos, _st.imgRect); } @@ -344,6 +345,13 @@ void FlatInput::keyPressEvent(QKeyEvent *e) { emit cancelled(); } else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) { emit submitted(ctrl && shift); +#ifdef Q_OS_MAC + } else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) { + auto selected = selectedText(); + if (!selected.isEmpty() && echoMode() == QLineEdit::Normal) { + QApplication::clipboard()->setText(selected, QClipboard::FindBuffer); + } +#endif // Q_OS_MAC } } @@ -765,11 +773,11 @@ void InputArea::startBorderAnimation() { } void InputArea::focusInEvent(QFocusEvent *e) { - _inner.setFocus(); + QTimer::singleShot(0, &_inner, SLOT(setFocus())); } void InputArea::mousePressEvent(QMouseEvent *e) { - _inner.setFocus(); + QTimer::singleShot(0, &_inner, SLOT(setFocus())); } void InputArea::contextMenuEvent(QContextMenuEvent *e) { @@ -1228,6 +1236,14 @@ void InputArea::InputAreaInner::keyPressEvent(QKeyEvent *e) { e->ignore(); } else if (f()->_customUpDown && (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down)) { e->ignore(); +#ifdef Q_OS_MAC + } else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) { + auto cursor = textCursor(); + int start = cursor.selectionStart(), end = cursor.selectionEnd(); + if (end > start) { + QApplication::clipboard()->setText(f()->getText(start, end), QClipboard::FindBuffer); + } +#endif // Q_OS_MAC } else { QTextCursor tc(textCursor()); if (enter && ctrl) { @@ -1457,11 +1473,11 @@ void InputField::startBorderAnimation() { } void InputField::focusInEvent(QFocusEvent *e) { - _inner.setFocus(); + QTimer::singleShot(0, &_inner, SLOT(setFocus())); } void InputField::mousePressEvent(QMouseEvent *e) { - _inner.setFocus(); + QTimer::singleShot(0, &_inner, SLOT(setFocus())); } void InputField::contextMenuEvent(QContextMenuEvent *e) { @@ -1943,6 +1959,14 @@ void InputField::InputFieldInner::keyPressEvent(QKeyEvent *e) { e->ignore(); } else if (f()->_customUpDown && (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down)) { e->ignore(); +#ifdef Q_OS_MAC + } else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) { + auto cursor = textCursor(); + int start = cursor.selectionStart(), end = cursor.selectionEnd(); + if (end > start) { + QApplication::clipboard()->setText(f()->getText(start, end), QClipboard::FindBuffer); + } +#endif // Q_OS_MAC } else { QTextCursor tc(textCursor()); if (enter && ctrl) { @@ -2337,6 +2361,13 @@ void MaskedInputField::keyPressEvent(QKeyEvent *e) { emit cancelled(); } else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) { emit submitted(ctrl && shift); +#ifdef Q_OS_MAC + } else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) { + auto selected = selectedText(); + if (!selected.isEmpty() && echoMode() == QLineEdit::Normal) { + QApplication::clipboard()->setText(selected, QClipboard::FindBuffer); + } +#endif // Q_OS_MAC } } diff --git a/Telegram/SourceFiles/ui/flatinput.h b/Telegram/SourceFiles/ui/flatinput.h index e121b0434..b200b76b2 100644 --- a/Telegram/SourceFiles/ui/flatinput.h +++ b/Telegram/SourceFiles/ui/flatinput.h @@ -235,6 +235,12 @@ public: bool hasFocus() const { return _inner.hasFocus(); } + void setFocus() { + _inner.setFocus(); + } + void clearFocus() { + _inner.clearFocus(); + } public slots: diff --git a/Telegram/SourceFiles/ui/flatlabel.cpp b/Telegram/SourceFiles/ui/flatlabel.cpp index 982895d90..ebacebdc8 100644 --- a/Telegram/SourceFiles/ui/flatlabel.cpp +++ b/Telegram/SourceFiles/ui/flatlabel.cpp @@ -304,6 +304,13 @@ void FlatLabel::keyPressEvent(QKeyEvent *e) { onCopySelectedText(); e->accept(); } +#ifdef Q_OS_MAC + } else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) { + auto selection = _selection.empty() ? (_contextMenu ? _savedSelection : _selection) : _selection; + if (!selection.empty()) { + QApplication::clipboard()->setText(_text.originalText(selection, _contextExpandLinksMode), QClipboard::FindBuffer); + } +#endif // Q_OS_MAC } } diff --git a/Telegram/SourceFiles/ui/flattextarea.cpp b/Telegram/SourceFiles/ui/flattextarea.cpp index 3e0d2c318..ed62bf939 100644 --- a/Telegram/SourceFiles/ui/flattextarea.cpp +++ b/Telegram/SourceFiles/ui/flattextarea.cpp @@ -1337,6 +1337,15 @@ void FlatTextarea::keyPressEvent(QKeyEvent *e) { } } else if (e->key() == Qt::Key_Search || e == QKeySequence::Find) { e->ignore(); +#ifdef Q_OS_MAC + } else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) { + auto cursor = textCursor(); + int start = cursor.selectionStart(), end = cursor.selectionEnd(); + if (end > start) { + TagList tags; + QApplication::clipboard()->setText(getTextPart(start, end, &tags), QClipboard::FindBuffer); + } +#endif // Q_OS_MAC } else { QTextCursor tc(textCursor()); if (enter && ctrl) { diff --git a/Telegram/SourceFiles/ui/popupmenu.cpp b/Telegram/SourceFiles/ui/popupmenu.cpp index d78746c87..2bbf65890 100644 --- a/Telegram/SourceFiles/ui/popupmenu.cpp +++ b/Telegram/SourceFiles/ui/popupmenu.cpp @@ -521,8 +521,9 @@ PopupMenu::~PopupMenu() { clearActions(true); delete _menu; #if defined Q_OS_LINUX32 || defined Q_OS_LINUX64 - if (App::wnd()) { - App::wnd()->activateWindow(); + if (auto w = App::wnd()) { + w->onReActivate(); + QTimer::singleShot(200, w, SLOT(onReActivate())); } #endif } diff --git a/Telegram/Telegram.xcodeproj/project.pbxproj b/Telegram/Telegram.xcodeproj/project.pbxproj index 791bb84e4..449edf2cf 100644 --- a/Telegram/Telegram.xcodeproj/project.pbxproj +++ b/Telegram/Telegram.xcodeproj/project.pbxproj @@ -2375,7 +2375,7 @@ SDKROOT = macosx; SYMROOT = ./../Mac; TDESKTOP_MAJOR_VERSION = 0.9; - TDESKTOP_VERSION = 0.9.54; + TDESKTOP_VERSION = 0.9.56; }; name = Release; }; @@ -2516,7 +2516,7 @@ SDKROOT = macosx; SYMROOT = ./../Mac; TDESKTOP_MAJOR_VERSION = 0.9; - TDESKTOP_VERSION = 0.9.54; + TDESKTOP_VERSION = 0.9.56; }; name = Debug; }; diff --git a/Telegram/build/version b/Telegram/build/version index 28606fe25..25a0b65be 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,6 +1,6 @@ -AppVersion 9054 +AppVersion 9056 AppVersionStrMajor 0.9 -AppVersionStrSmall 0.9.54 -AppVersionStr 0.9.54 -AlphaChannel 1 +AppVersionStrSmall 0.9.56 +AppVersionStr 0.9.56 +AlphaChannel 0 BetaVersion 0 diff --git a/doc/building-msvc.md b/doc/building-msvc.md index 20b1c4f48..f07e8be9f 100644 --- a/doc/building-msvc.md +++ b/doc/building-msvc.md @@ -8,7 +8,7 @@ Choose a folder for the future build, for example **D:\TBuild\**. There you will By git – in [Git Bash](http://git-scm.com/downloads) go to **/d/tbuild** and run - git clone https://github.com/telegramdesktop/tdesktop.git + git clone https://github.com/telegramdesktop/tdesktop.git or download in ZIP and extract to **D:\TBuild\**, rename **tdesktop-master** to **tdesktop** to have **D:\TBuild\tdesktop\Telegram.sln** solution @@ -45,8 +45,11 @@ Extract to **D:\TBuild\Libraries** * Open in VS2015 **D:\TBuild\Libraries\lzma\C\Util\LzmaLib\LzmaLib.dsw** > One-way upgrade – **OK** * For **Debug** and **Release** configurations - * LzmaLib Properties > General > Configuration Type = **Static library (.lib)** – **OK** + * LzmaLib Properties > General > Configuration Type = **Static library (.lib)** – **Apply** * LzmaLib Properties > Librarian > General > Target Machine = **MachineX86 (/MACHINE:X86)** – **OK** + * If you can't find **Librarian**, you forgot to click **Apply** after changing the Configuration Type. +* For **Debug** configuration + * LzmaLib Properties > C/C++ > General > Debug Information Format = **Program Database (/Zi)** - **OK** * Build Debug configuration * Build Release configuration @@ -95,7 +98,7 @@ Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu > * Install [CMake](http://www.cmake.org/) * Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu > Programs > Visual Studio 2015** menu folder), go to **D:\TBuild\Libraries\openal-soft\build\** and run - cmake -G "Visual Studio 14 2015" -D LIBTYPE:STRING=STATIC -D FORCE_STATIC_VCRT:STRING=ON .. + cmake -G "Visual Studio 14 2015" -D LIBTYPE:STRING=STATIC -D FORCE_STATIC_VCRT:STRING=ON .. * Open in VS2015 **D:\TBuild\Libraries\openal-soft\build\OpenAL.sln** and build Debug and Release configurations @@ -201,11 +204,17 @@ There go to Libraries directory and run - git clone https://chromium.googlesource.com/breakpad/breakpad - git clone https://chromium.googlesource.com/external/gyp set PATH=C:\Python27;%PATH% - cd breakpad/src/client/windows - ..\..\..\..\gyp\gyp --no-circular-check + git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git + cd depot_tools + gclient sync + cd .. + md breakpad + cd breakpad + ..\depot_tools\fetch breakpad + ..\depot_tools\gclient sync + +There's now a src folder within a src folder: D:\TBuild\Libraries\breakpad\src\src. Telegram only expects one src folder. Either via the command line or File Explorer, rename the top-level src folder and move the inner src folder one level up. This way, what was once breakpad\src\src\client is now breakpad\src\client, etc. #####Building library @@ -221,6 +230,6 @@ and run * QT5 > Qt Options > Add * Version name: **Qt 5.6.0 Win32** * Path: **D:\TBuild\Libraries\qt5_6_0\qtbase** -* Default Qt/Win version: **Qt 5.6.0 Win32** – **OK** +* Default Qt/Win version: **Qt 5.6.0 Win32** – **OK** - You may need to restart Visual Studio for this to take effect. * File > Open > Project/Solution > **D:\TBuild\tdesktop\Telegram.sln** * Build \ Build Solution (Debug and Release configurations)